/* ============================================================================
 * 环评中心 · 项目全流程管理系统 —— 视觉设计系统
 * 结构：1 设计令牌 → 2 基础层 → 3 布局骨架 → 4 通用组件 → 5 业务组件 → 6 工具类
 * 说明：仅重构视觉层，所有既有 class 名与 DOM 结构保持不变。
 * ========================================================================== */

/* ---------- 1. 设计令牌 ---------- */
:root {
  color-scheme: light;

  /* 背景与表面 */
  --bg: #f4f6fa;
  --bg-veil-1: rgba(15, 157, 118, .07);
  --bg-veil-2: rgba(59, 111, 224, .06);
  --surface: #ffffff;
  --surface-2: #f7f9fc;
  --surface-3: #eef2f7;
  --surface-inverse: #101828;

  /* 描边 */
  --border: #e6ebf2;
  --border-strong: #d7dfea;

  /* 文本层级 */
  --text: #101828;
  --text-soft: #667085;
  --text-mute: #98a2b3;

  /* 品牌主色 */
  --primary: #0f9d76;
  --primary-dark: #0a7d5d;
  --primary-soft: #e8f7f1;
  --primary-ring: rgba(15, 157, 118, .18);
  --primary-grad: linear-gradient(135deg, #15b187 0%, #0b8a68 100%);

  /* 语义色 */
  --danger: #e5484d;
  --danger-soft: #fdecec;
  --warn: #d98107;
  --warn-soft: #fdf4e4;
  --info: #3b6fe0;
  --info-soft: #eaf0fd;
  --purple: #7a5cd6;
  --purple-soft: #f1edfc;
  --gray: #98a2b3;
  --gray-soft: #eef1f5;

  /* 表头 */
  --thead-bg: #f2f5f9;
  --thead-text: #5b6779;

  /* 框架区背景 */
  --topbar-bg: rgba(255, 255, 255, .82);
  --sidebar-bg: #fbfcfe;

  /* 阴影层级 */
  --shadow-xs: 0 1px 2px rgba(16, 24, 40, .05);
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .04);
  --shadow-md: 0 4px 12px rgba(16, 24, 40, .08), 0 2px 4px rgba(16, 24, 40, .04);
  --shadow-lg: 0 12px 32px rgba(16, 24, 40, .14), 0 4px 8px rgba(16, 24, 40, .06);
  --shadow: var(--shadow-md);

  /* 圆角 */
  --radius-xs: 6px;
  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 16px;
  --radius-xl: 20px;
  --radius-pill: 999px;

  /* 层级刻度（数值越大越靠上，全局唯一来源，避免各处硬编码 z-index 打架） */
  --z-card: 1;      /* 内容卡片 / 表格（普通内容层） */
  --z-toolbar: 10;  /* 筛选工具栏：需高于内容卡片，保证下拉面板浮在表格之上 */
  --z-topbar: 20;   /* 顶栏（吸顶） */
  --z-sidebar: 30;  /* 侧边栏（吸顶） */
  --z-panel: 60;    /* 下拉面板：只在工具栏的层叠上下文内比较，故可大于顶栏/侧边栏 */
  --z-modal: 100;   /* 弹窗 */
  --z-toast: 200;   /* 轻提示 */

  /* 字体 */
  --font-sans: "Inter", "HarmonyOS Sans SC", "MiSans", "PingFang SC", "Microsoft YaHei", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", "JetBrains Mono", "Cascadia Mono", Consolas, monospace;

  /* 间距刻度 */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;

  /* 行距与垂直节奏（统一规范 · 唯一来源，2026-09-26 起）
     —— 「关键节点进度」与「工作过程记录」及所有表单/列表一律引用下列令牌，禁止再写裸数值 */
  --lh-title: 1.4;    /* 标题 / 粗体标签行高 */
  --lh-base: 1.6;     /* 正文行高（过程记录内容、备注、说明） */
  --lh-meta: 1.5;     /* 元信息行高（日期、人名、辅助文字） */
  --gap-inline: 4px;  /* 同一段落内相邻行（如记录里"具体进度/存在问题"各行之间） */
  --gap-row: 8px;     /* 同一卡片内的行与字段之间（头部↔内容、日期↔摘要） */
  --gap-item: 12px;   /* 条目之间（记录卡片、节点项、表单字段组） */
  --gap-block: 16px;  /* 区块之间（过程记录 ↔ 节点附件 ↔ 基本信息） */
  --field-h: 40px;    /* 表单字段统一行高（日期选择 / 具体进度 / 存在问题 / 解决方案 四行等高） */
  --row-h-resolved: 23px; /* 「存在问题是否解决」行高：原 20px × 1.15（整体放大 15%） */
  --ring-size: 104px;   /* 项目概况 · 整体进度圆圈进度盘直径（窄屏由 .info-overview 局部收窄） */

  /* 布局 */
  --sidebar-w: 240px;
  --topbar-h: 62px;
  --content-max: 1480px;

  /* 动效 */
  --ease: cubic-bezier(.4, 0, .2, 1);
  --dur: .18s;
}

[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0b1017;
  --bg-veil-1: rgba(46, 196, 149, .07);
  --bg-veil-2: rgba(90, 140, 245, .06);
  --surface: #141b24;
  --surface-2: #1a232e;
  --surface-3: #212c38;
  --surface-inverse: #e8eef5;

  --border: #26313e;
  --border-strong: #35424f;

  --text: #e8eef5;
  --text-soft: #9aa8b8;
  --text-mute: #6f7d8c;

  --primary: #2ec495;
  --primary-dark: #6fdcb5;
  --primary-soft: #16352b;
  --primary-ring: rgba(46, 196, 149, .22);
  --primary-grad: linear-gradient(135deg, #2ec495 0%, #1c9d76 100%);

  --danger: #ff6b6b;
  --danger-soft: #3a1f22;
  --warn: #f0a93b;
  --warn-soft: #3a2e16;
  --info: #5aa0f2;
  --info-soft: #16293f;
  --purple: #a98cf0;
  --purple-soft: #2a2340;
  --gray: #6b7886;
  --gray-soft: #212b36;

  --thead-bg: #1b2430;
  --thead-text: #9aa8b8;

  --topbar-bg: rgba(20, 27, 36, .82);
  --sidebar-bg: #111822;

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, .3);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .34), 0 2px 6px rgba(0, 0, 0, .26);
  --shadow-md: 0 6px 18px rgba(0, 0, 0, .4), 0 2px 6px rgba(0, 0, 0, .3);
  --shadow-lg: 0 18px 44px rgba(0, 0, 0, .55), 0 6px 14px rgba(0, 0, 0, .4);
}

/* ---------- 2. 基础层 ---------- */
* { box-sizing: border-box; }
html, body { height: 100%; }

/* 常驻纵向滚动条槽位。
   表格重建（如翻页、筛选、定时刷新）时页面高度会在"高 ↔ 矮"之间跳变，
   若无此设置，滚动条会随之出现/消失，导致可用宽度变化 ~10px，
   进而让 table-layout:auto 重新计算列宽 —— 表现为表格横向抖动。
   scrollbar-gutter 让槽位始终占位，从根上切断这条连锁反应。 */
html { scrollbar-gutter: stable; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
  background-color: var(--bg);
  background-image:
    radial-gradient(1100px 520px at 12% -8%, var(--bg-veil-1), transparent 62%),
    radial-gradient(900px 480px at 96% 0%, var(--bg-veil-2), transparent 58%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-variant-numeric: tabular-nums;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

h1, h2, h3, h4 { margin: 0; letter-spacing: -.01em; }
a { color: var(--primary-dark); text-decoration: none; }
a:hover { text-decoration: underline; }

::selection { background: var(--primary-ring); color: var(--text); }

:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* 滚动条 */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border: 3px solid transparent;
  border-radius: var(--radius-pill);
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--gray); background-clip: padding-box; }

/* ---------- 3. 布局骨架 ---------- */
.app { display: flex; min-height: 100vh; }

/* 侧边栏 */
.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 18px 14px 14px;
  position: sticky;
  top: 0;
  height: 100vh;
  z-index: var(--z-sidebar);
  transition: background var(--dur) var(--ease);
}

.brand { display: flex; align-items: center; gap: 11px; padding: 2px 8px 18px; }
.brand-logo {
  display: grid; place-items: center;
  width: 38px; height: 38px; flex-shrink: 0;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-xs);
}
.brand-logo img { height: 24px; max-width: 30px; object-fit: contain; display: block; }
.brand-text { font-weight: 700; font-size: 14.5px; line-height: 1.3; white-space: nowrap; }
.brand-text small {
  display: block; font-weight: 500; color: var(--text-mute);
  font-size: 11px; letter-spacing: .06em; margin-top: 1px;
}

.side-menu { flex: 1; display: flex; flex-direction: column; gap: 3px; overflow-y: auto; padding-top: 2px; }

.menu-item {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  padding: 10px 12px;
  border-radius: var(--radius);
  cursor: pointer;
  color: var(--text-soft);
  font-size: 14px;
  font-weight: 500;
  user-select: none;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.menu-item::before {
  content: "";
  position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 3px; height: 0;
  border-radius: 0 var(--radius-pill) var(--radius-pill) 0;
  background: var(--primary);
  transition: height var(--dur) var(--ease);
}
.menu-item:hover { background: var(--surface-3); color: var(--text); }
.menu-item.active { background: var(--primary-soft); color: var(--primary-dark); font-weight: 600; }
.menu-item.active::before { height: 20px; }
.menu-item .mi-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; flex-shrink: 0; opacity: .9;
}
.menu-item .mi-icon svg { width: 18px; height: 18px; }
.menu-item.active .mi-icon { opacity: 1; }

.side-foot { padding-top: 12px; border-top: 1px solid var(--border); margin-top: 10px; }

/* 主区域 */
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.topbar {
  height: var(--topbar-h);
  background: var(--topbar-bg);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--sp-6);
  position: sticky; top: 0; z-index: var(--z-topbar);
}
.topbar-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.topbar-left h2 { font-size: 17px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-right { display: flex; align-items: center; gap: 10px; }

.user-badge {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-soft);
  padding: 5px 12px 5px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.user-badge b { color: var(--text); font-weight: 600; }

.icon-btn {
  display: inline-grid; place-items: center;
  width: 38px; height: 38px;
  background: transparent; border: 1px solid transparent; border-radius: var(--radius);
  font-size: 17px; color: var(--text-soft); cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn:hover { background: var(--surface-3); border-color: var(--border); color: var(--text); }
.icon-btn:active { transform: scale(.96); }

/* 主题图标随主题切换显隐 */
.only-light, .only-dark { display: inline-flex; align-items: center; }
.only-dark { display: none !important; }
[data-theme="dark"] .only-light { display: none !important; }
[data-theme="dark"] .only-dark { display: inline-flex !important; }

.content {
  padding: var(--sp-6);
  flex: 1;
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
}
/* 视图切换的入场反馈：仅在切换视图时播放一次（由 navigate() 临时挂 .view-enter，渲染完即摘除）。
   关键改动：原先直接写在 .content > * 上，导致任何一次对直接子级的重建都会重播动画 ——
   30 秒自动刷新一重建，整块内容就"淡入 + 上移 6px"一次，正是用户看到的周期性晃动。
   现在动画只属于"视图切换"这一语义，数据刷新不会再触发。
   注意：动画中的 transform 会生成层叠上下文，故内容层仍需显式定序（见 .toolbar / .content .card）。 */
.content.view-enter > * { animation: rise .3s var(--ease) both; }
@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
/* 内容卡片固定在内容层，保证筛选工具栏（含其下拉面板）恒在表格之上 */
.content .card { position: relative; z-index: var(--z-card); }

/* ---------- 4. 通用组件 ---------- */

/* 按钮 */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  padding: 9px 16px;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 13px; font-weight: 500; font-family: inherit;
  box-shadow: var(--shadow-xs);
  white-space: nowrap;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform .08s var(--ease);
}
.btn svg { width: 15px; height: 15px; }
.btn:hover { border-color: var(--border-strong); background: var(--surface-2); }
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: var(--primary-grad);
  border-color: transparent;
  color: #fff;
  box-shadow: 0 1px 2px rgba(11, 138, 104, .3), 0 4px 12px rgba(15, 157, 118, .18);
}
.btn-primary:hover { filter: brightness(1.05); border-color: transparent; background: var(--primary-grad); }
.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-danger:hover { filter: brightness(.95); border-color: var(--danger); background: var(--danger); }
.btn-ghost { background: transparent; box-shadow: none; border-color: transparent; color: var(--text-soft); }
.btn-ghost:hover { background: var(--surface-3); color: var(--text); border-color: transparent; }
.btn-block { width: 100%; }
.btn-sm { padding: 5px 11px; font-size: 12px; border-radius: var(--radius-sm); }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }

/* 列表刷新中的即时反馈：内容轻微降透明 + 顶部 2px 进度条。
   只在真正需要等待（无缓存首刷 / 数据过期后台拉取）时出现，缓存命中的筛选是同帧完成、看不到此态。 */
.is-busy { position: relative; opacity: .72; transition: opacity var(--dur) var(--ease); }
.is-busy::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  border-radius: 2px; background: linear-gradient(90deg, transparent, var(--primary), transparent);
  animation: listscan 900ms linear infinite; z-index: 1;
}
@keyframes listscan { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .is-busy::before { animation: none; }
}

/* 卡片 */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-5);
}
.card-title {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 15px; font-weight: 700;
  margin: 0 0 var(--sp-4);
}
.card-title > span:first-child,
.ms-section h4 > span:first-child { display: inline-flex; align-items: center; gap: 8px; }
.card-title .ico { color: var(--primary); }

.section-gap { margin-top: var(--sp-5); }

/* 网格 */
.grid { display: grid; gap: var(--sp-4); }
.grid-stats { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.grid-2 { grid-template-columns: 1.4fr 1fr; }
.grid-type-stats { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

/* 统计卡 */
.stat {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 17px 20px 18px;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.stat::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, var(--primary), rgba(15, 157, 118, .15));
}
.stat:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--border-strong); }
.stat .stat-label { color: var(--text-soft); font-size: 15px; font-weight: 700; }
.stat .stat-num {
  font-size: 32px; font-weight: 800; line-height: 1.1; margin-top: 6px;
  letter-spacing: -.02em; color: var(--text);
}
.stat.alert { background: var(--danger-soft); border-color: var(--danger); }
.stat.alert::before { background: linear-gradient(180deg, var(--danger), rgba(229, 72, 77, .15)); }
.stat.alert .stat-num { color: var(--danger); }

/* 统计卡：可点击入口（存在问题） */
.stat.clickable { cursor: pointer; }
.stat.clickable::before { background: linear-gradient(180deg, var(--danger), rgba(229, 72, 77, .15)); }
.stat-problem { background: var(--danger-soft); border-color: var(--danger); }
.stat-problem .stat-num { color: var(--danger); }
.stat.clickable:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--danger); }
.stat-hint { margin-top: 6px; font-size: 12px; font-weight: 600; color: var(--danger); opacity: .85; }

/* 存在问题汇总（按项目归并） */
.prob-project { border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 14px 16px; margin-bottom: var(--sp-4); background: var(--surface); }
.prob-project-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; padding-bottom: 8px; border-bottom: 1px dashed var(--border); }
.prob-pname { font-weight: 700; font-size: 15px; color: var(--text); }
.prob-pcode { font-size: 12px; color: var(--text-soft); background: var(--gray-soft); padding: 1px 7px; border-radius: var(--radius-sm); }
.prob-items { display: flex; flex-direction: column; gap: 10px; }
.prob-item { border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; background: var(--bg); }
.prob-item-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.prob-node { font-weight: 600; color: var(--text-soft); display: inline-flex; align-items: center; gap: 5px; }
.prob-meta { font-size: 12px; color: var(--text-soft); }
.prob-text { font-size: 13px; line-height: 1.6; margin-top: 2px; color: var(--text); }
.prob-text b { color: var(--text-soft); }
.prob-solution-exist { background: var(--primary-soft); border-left: 3px solid var(--primary); padding: 6px 10px; border-radius: var(--radius-sm); }
.prob-solution { display: flex; gap: 8px; margin-top: 8px; align-items: flex-start; }
.prob-solution-input { flex: 1; min-width: 0; min-height: 56px; resize: vertical; font: inherit; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); }
.prob-solution-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary-soft); }
/* 手动确认「存在问题是否解决」：状态须由负责人手动选择，系统不自动置位 */
.prob-resolved-row { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.prob-resolved-row .frow-label { flex: 0 0 auto; font-size: 13px; color: var(--text-soft); white-space: nowrap; }
.prob-resolved-row select { flex: 0 0 auto; width: 110px; padding: 6px 8px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); font: inherit; }
.prob-resolved-row .btn { margin-left: 2px; }

/* 报告类型统计卡 */
.type-stat {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 17px 20px 18px;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.type-stat::after {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: linear-gradient(180deg, var(--primary), rgba(15, 157, 118, .12));
}
.type-stat:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--border-strong); }
.type-stat-name { font-size: 15px; font-weight: 700; margin-bottom: 10px; }
.type-stat-nums { display: flex; align-items: baseline; gap: 18px; }
.type-stat-nums b { font-size: 27px; font-weight: 800; letter-spacing: -.02em; }
.ts-total { color: var(--text); }
.ts-prog { color: var(--primary-dark); font-size: 14px; font-weight: 500; }
.type-stat-bar {
  margin-top: 12px; height: 7px;
  background: var(--surface-3); border-radius: var(--radius-pill); overflow: hidden;
}
.type-stat-bar > span {
  display: block; height: 100%; border-radius: var(--radius-pill);
  background: var(--primary-grad);
  transition: width .5s var(--ease);
}

/* 表格 */
.table-wrap {
  overflow-x: auto;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
}
table.tbl {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
  table-layout: auto;
}
table.tbl.proj-tbl { width: 100%; }
table.tbl colgroup col { min-width: 0; }

table.tbl th,
table.tbl td {
  padding: 12px 14px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
}
table.tbl th {
  color: var(--thead-text);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: .04em;
  background: var(--thead-bg);
  white-space: nowrap;
  text-align: left;
  border-bottom: 1px solid var(--border-strong);
}
table.tbl tbody tr { transition: background var(--dur) var(--ease); }
table.tbl tbody tr:hover td { background: var(--surface-2); }
table.tbl tbody tr:last-child td { border-bottom: none; }
table.tbl td.nowrap { white-space: nowrap; }
table.tbl td:last-child { padding-right: 16px; }

/* 项目编号列：固定宽度，不随内容伸缩；其余列由 auto 布局自适应 */
table.tbl.proj-tbl th:first-child,
table.tbl.proj-tbl td:first-child {
  width: 125px; min-width: 125px; max-width: 125px;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--text-soft);
}

/* 类型 / 负责人 列（第4、5列）：单行完整显示不换行；
   table-layout:auto 下 nowrap 会自动为这两列分配足够宽度，宽度由名称/建设单位列让出 */
table.tbl.proj-tbl th:nth-child(4),
table.tbl.proj-tbl td:nth-child(4),
table.tbl.proj-tbl th:nth-child(5),
table.tbl.proj-tbl td:nth-child(5) {
  white-space: nowrap;
}

/* ===== 项目列表专属（proj-tbl--list）：仅项目列表页签，不影响「我的项目」各模块表格 ===== */
/* 排版目标（2026-10-09 视觉优化）：
   ① 行高行距舒展 —— 所有单元格单行不折行，垂直内边距 12px → 16px、行高 1.55，
      整表行高完全一致（此前「建设单位」列仅 8% 宽，长单位名被折成 2~3 行，行高忽高忽低）。
   ② 列宽重分配 —— 建设单位放宽至 12%（能显示更多字），从弹性最大的名称列让出；
      预警（徽章 94px）、操作（按钮 81px）、编号（115px）、约定完成（94px）
      在 min-width 1050px 兜底下均不被裁切。
   ③ 层次与对齐 —— 名称为视觉主锚（14.5px/500/深色），说明性字段降为弱色；
      状态/进度/约定完成/预警/操作五列整体居中，形成稳定的纵向对齐节奏。 */
table.tbl.proj-tbl--list { table-layout: fixed; min-width: 1050px; }
/* 单行 + 舒展行距：内边距 16px/12px、行高 1.55 → 行高约 57px，整表统一 */
table.tbl.proj-tbl--list th,
table.tbl.proj-tbl--list td {
  padding: 16px 12px;
  line-height: 1.55;
  vertical-align: middle;
}
table.tbl.proj-tbl--list thead th { padding: 13px 12px; line-height: 1.4; }
table.tbl.proj-tbl--list td:last-child { padding-right: 14px; }
table.tbl.proj-tbl--list .progress { min-width: 50px; }
/* 列宽（合计 100%） */
table.tbl.proj-tbl--list col:nth-child(1)  { width: 11%;    } /* 项目编号 */
table.tbl.proj-tbl--list col:nth-child(2)  { width: 14%;    } /* 项目名称（主锚，弹性列）*/
table.tbl.proj-tbl--list col:nth-child(3)  { width: 10%;    } /* 建设单位（放宽，减少折行）*/
table.tbl.proj-tbl--list col:nth-child(4)  { width: 8.5%;   } /* 类型（「规划环评」需 ≥76px）*/
table.tbl.proj-tbl--list col:nth-child(5)  { width: 6.5%;   } /* 负责人 */
table.tbl.proj-tbl--list col:nth-child(6)  { width: 7.5%;   } /* 承接人 */
table.tbl.proj-tbl--list col:nth-child(7)  { width: 9%;     } /* 状态（徽章需 ≥94px）*/
table.tbl.proj-tbl--list col:nth-child(8)  { width: 7.75%;  } /* 进度 */
table.tbl.proj-tbl--list col:nth-child(9)  { width: 9%;     } /* 约定完成（日期需 ≥94px）*/
table.tbl.proj-tbl--list col:nth-child(10) { width: 9%;     } /* 预警（徽章需 ≥94px）*/
table.tbl.proj-tbl--list col:nth-child(11) { width: 7.75%;  } /* 操作（按钮需 ≥81px）*/
/* 名称：视觉主锚（稍大字号 + 半粗 + 深色），与弱色说明字段拉开层次 */
table.tbl.proj-tbl--list td:nth-child(2) {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 14.5px; font-weight: 500; color: var(--text);
}
/* 建设单位 / 类型 / 承接人：说明性字段降为弱色，不与名称抢视线；单行省略 */
table.tbl.proj-tbl--list td:nth-child(3),
table.tbl.proj-tbl--list td:nth-child(4),
table.tbl.proj-tbl--list td:nth-child(6) {
  color: var(--text-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 进度百分比与日期：等宽数字（tabular-nums）保证纵向对齐 */
table.tbl.proj-tbl--list td:nth-child(8) .progress-label,
table.tbl.proj-tbl--list td:nth-child(9) {
  font-variant-numeric: tabular-nums;
}
/* 右半区五列整体居中：状态 / 进度 / 约定完成 / 预警 / 操作 */
table.tbl.proj-tbl--list th:nth-child(7),
table.tbl.proj-tbl--list td:nth-child(7),
table.tbl.proj-tbl--list th:nth-child(8),
table.tbl.proj-tbl--list td:nth-child(8),
table.tbl.proj-tbl--list th:nth-child(9),
table.tbl.proj-tbl--list td:nth-child(9),
table.tbl.proj-tbl--list th:nth-child(10),
table.tbl.proj-tbl--list td:nth-child(10),
table.tbl.proj-tbl--list th:nth-child(11),
table.tbl.proj-tbl--list td:nth-child(11) {
  text-align: center;
}
table.tbl.proj-tbl--list td:nth-child(8) .progress { margin: 0 auto; }

/* 分页 */
.pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: var(--sp-4);
}
.pg-info { font-size: 13px; color: var(--text-soft); }
.pg-btns { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.pg-btn {
  min-width: 34px; height: 34px; padding: 0 10px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text-soft);
  font-size: 13px; font-family: inherit; cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.pg-btn:hover:not(.disabled):not(.active) { border-color: var(--border-strong); color: var(--text); background: var(--surface-2); }
.pg-btn.active {
  background: var(--primary-grad); border-color: transparent; color: #fff; font-weight: 600;
  box-shadow: 0 1px 2px rgba(11, 138, 104, .3);
}
.pg-btn.disabled { opacity: .45; cursor: not-allowed; }
.pg-ellipsis { color: var(--text-mute); padding: 0 2px; }

/* 徽章 */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 600; line-height: 1.5;
  white-space: nowrap;
  border: 1px solid transparent;
}
.badge.s-未开始 { background: var(--gray-soft); color: var(--text-soft); }
.badge.s-进行中 { background: var(--info-soft); color: var(--info); }
.badge.s-暂缓 { background: var(--warn-soft); color: var(--warn); }
.badge.s-送审中 { background: var(--purple-soft); color: var(--purple); }
.badge.s-已完成 { background: var(--primary-soft); color: var(--primary-dark); }
.badge.s-已终止 { background: var(--danger-soft); color: var(--danger); }
.badge.b-overdue { background: var(--danger); color: #fff; }
.badge.b-ok { background: var(--primary-soft); color: var(--primary-dark); }
.badge.b-done { background: var(--primary-soft); color: var(--primary-dark); }
.badge.b-pending { background: var(--gray-soft); color: var(--text-soft); }
.badge .ico { width: 12px; height: 12px; }

/* 进度条 */
.progress {
  height: 7px; min-width: 90px;
  background: var(--surface-3);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.progress > span {
  display: block; height: 100%; border-radius: var(--radius-pill);
  background: var(--primary-grad);
  transition: width .5s var(--ease);
}
.progress.over > span { background: linear-gradient(135deg, #f2686c, var(--danger)); }
.progress-label { font-size: 12px; color: var(--text-soft); margin-top: 4px; }

/* 表单 */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 20px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field.full { grid-column: 1 / -1; }
.field label { font-size: 12.5px; font-weight: 500; color: var(--text-soft); }
.field input, .field select, .field textarea,
.filter-input, .type-search, .flt-range input, .login-form input {
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--text);
  font-size: 14px; font-family: inherit;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
}
.field input:hover, .field select:hover, .field textarea:hover,
.filter-input:hover, .type-search:hover, .login-form input:hover { border-color: var(--border-strong); }
.field input:focus, .field select:focus, .field textarea:focus,
.filter-input:focus, .type-search:focus, .flt-range input:focus, .login-form input:focus {
  outline: none;
  border-color: var(--primary);
  background: var(--surface);
  box-shadow: 0 0 0 3px var(--primary-ring);
}
.field textarea { min-height: 74px; resize: vertical; line-height: 1.6; }
.field select { cursor: pointer; }

/* 弹窗 */
.modal-mask {
  position: fixed; inset: 0; z-index: var(--z-modal);
  background: rgba(16, 24, 40, .42);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  padding: var(--sp-4);
  animation: fadeIn .18s var(--ease) both;
}
.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  width: 720px; max-width: 100%; max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--shadow-lg);
  padding: var(--sp-6);
  animation: pop .22s var(--ease) both;
}
.modal h3 {
  font-size: 17px; font-weight: 700;
  margin: 0 0 var(--sp-4);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--border);
}
.modal-body { font-size: 14px; }
.modal-actions {
  display: flex; justify-content: flex-end; gap: 10px;
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }

/* Toast */
#toast-root {
  position: fixed; top: 18px; left: 50%; transform: translateX(-50%);
  z-index: var(--z-toast); display: flex; flex-direction: column; gap: 8px; align-items: center;
  pointer-events: none;
}
.toast {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-mute);
  padding: 11px 18px;
  border-radius: var(--radius);
  font-size: 13px; font-weight: 500;
  box-shadow: var(--shadow-lg);
  animation: toastIn .24s var(--ease) both;
}
.toast.ok { border-left-color: var(--primary); }
.toast.ok::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--primary); }
.toast.err { border-left-color: var(--danger); }
.toast.err::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--danger); }
@keyframes toastIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }

/* ---------- 5. 业务组件 ---------- */

/* 登录页 */
.login-wrap {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: var(--sp-5);
  background-image:
    radial-gradient(900px 500px at 20% 0%, var(--bg-veil-1), transparent 60%),
    radial-gradient(800px 480px at 85% 100%, var(--bg-veil-2), transparent 60%);
}
.login-card {
  width: 392px; max-width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  padding: 38px 34px 30px;
  text-align: center;
  animation: pop .32s var(--ease) both;
}
.login-logo { display: flex; justify-content: center; }
.login-logo img { height: 50px; display: inline-block; vertical-align: middle; }
.login-title {
  font-size: 21px; font-weight: 700; line-height: 1.4;
  margin: 16px 0 22px;
  letter-spacing: -.01em;
}
.login-form { text-align: left; }
.login-form label {
  display: block; font-size: 12.5px; font-weight: 500;
  color: var(--text-soft); margin: 14px 0 6px;
}
.login-form input { width: 100%; }
.login-error { color: var(--danger); font-size: 13px; min-height: 18px; margin: 10px 0 0; }
.login-hint {
  margin-top: 24px; padding-top: 18px;
  border-top: 1px dashed var(--border);
  text-align: left;
}
.login-hint-title { font-size: 12px; color: var(--text-mute); margin-bottom: 9px; }

/* 工具栏与筛选下拉 */
.toolbar {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  margin-bottom: var(--sp-4);
  /* 关键：主动建立层叠上下文并置于内容卡片（--z-card）之上。
     .content > * 带 transform 动画，若工具栏未显式定位，其弹层会被后续的表格卡片
     （同为层叠上下文、DOM 顺序在后）盖住；显式定位 + z-index 后，
     四个筛选下拉面板始终渲染在表格上层，且不影响表格自身的展开与横向滚动。 */
  position: relative;
  z-index: var(--z-toolbar);
}
.toolbar .spacer { flex: 1; }
.filter-input { min-width: 200px; }
.toolbar > input.filter-input { width: 260px; min-width: 220px; }

.dropdown { position: relative; display: inline-block; }
.dropdown .type-btn {
  width: 158px; min-width: 158px;
  text-align: left; cursor: pointer; font-family: inherit; font-size: 13px;
  box-sizing: border-box;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dropdown-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: var(--z-panel);
  width: 288px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 10px;
  animation: pop .16s var(--ease) both;
}
.type-search { width: 100%; box-sizing: border-box; font-size: 13px; padding: 8px 11px; margin-bottom: 8px; }
.type-list { max-height: 260px; overflow-y: auto; }
.type-item {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 8px 10px; border-radius: var(--radius-sm);
  font-size: 13px; color: var(--text); cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.type-item:hover { background: var(--surface-2); }
.type-item.active { background: var(--primary-soft); color: var(--primary-dark); font-weight: 600; }
.type-item.disabled { color: var(--text-mute); cursor: default; }
.type-item .type-code {
  font-size: 11px; color: var(--text-soft); font-family: var(--font-mono);
  background: var(--surface-3); border-radius: var(--radius-xs); padding: 1px 7px;
}

.flt-ops { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; padding: 0 2px; }
.link-btn {
  background: none; border: none; color: var(--primary-dark);
  font-size: 12px; font-weight: 500; cursor: pointer; padding: 2px 4px; font-family: inherit;
  transition: color var(--dur) var(--ease);
}
.link-btn:hover { color: var(--primary); text-decoration: underline; }
.flt-cnt { margin-left: auto; font-size: 11px; color: var(--text-mute); }
.flt-item input[type="checkbox"] { accent-color: var(--primary); width: 15px; height: 15px; cursor: pointer; margin: 0; }
.flt-item .flt-left { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.leader-no {
  font-size: 11px; color: var(--text-soft); font-family: var(--font-mono);
  background: var(--surface-3); border-radius: var(--radius-xs); padding: 1px 7px;
}
.flt-range { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-soft); white-space: nowrap; }
.flt-range input { width: 58px; padding: 4px 7px; font-size: 12px; font-family: inherit; }

/* 空状态 / 提示条 */
.empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  text-align: center; color: var(--text-mute);
  padding: 48px 0; font-size: 13px;
}
.empty .ico-lg { color: var(--primary); }
.alert-bar {
  display: flex; align-items: center; gap: 9px;
  background: var(--danger-soft);
  border: 1px solid var(--danger);
  color: var(--danger);
  padding: 11px 14px;
  border-radius: var(--radius);
  font-size: 13px; font-weight: 500;
  margin-bottom: var(--sp-4);
}

/* 键值表 */
.kv { display: grid; grid-template-columns: 130px 1fr; gap: 10px 16px; font-size: 13px; }
.kv dt { color: var(--text-soft); }
.kv dd { margin: 0; color: var(--text); }

/* ---------- 5.1 项目基本信息（四模块卡片版）----------
 * 版式：四个独立圆角卡片（项目概况 / 合同收款 / 责任团队 / 总体情况），等间距堆叠；
 * 每个卡片绿条标题锚点统一，字段名（小号 / 次级灰）在上、取值（大一号 / 主文本色）在下；
 * 关键字段（名称 / 状态 / 合同额 / 已收款合计）加重强调，次要信息（0 值收款 / 未分配审核人）弱化灰显。
 * 色彩：仅取设计令牌（--text / --text-soft / --text-mute / --primary-dark / --danger），与全站语义色保持一致。 */
/* 四模块卡片堆栈：等间距垂直排布，间距统一走 --gap-block */
.info-stack { display: grid; gap: var(--gap-block); }

/* 独立圆角卡片：内边距加大，配合 .card 的 radius-lg 形成清晰边界与呼吸感 */
.info-card { padding: var(--sp-6); }

/* 模块标题：左侧主色渐变竖条做视觉锚点，替代"裸文字标题" */
.info-card-title {
  display: flex; align-items: center; gap: 10px;
  position: relative; padding-left: 12px;
  font-size: 15px; font-weight: 700; letter-spacing: .01em;
  color: var(--text); margin-bottom: var(--sp-5);
}
.info-card-title::before {
  content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 3px; height: 15px; border-radius: var(--radius-pill);
  background: var(--primary-grad);
}

/* 项目概况：左字段栅格 + 右圆圈进度盘，同一行不换行
   字段关系用「命名区域」固定，任何断点下都不变：
     ① 项目地区 恒在 建设单位 正下方；② 约定完成时间 恒在 开始时间 右侧
   复合选择器压过 .info-grid 的 auto-fill 基础值 */
.info-overview { display: flex; align-items: center; gap: var(--sp-6); }
.info-grid.info-grid--overview {
  grid-template-columns: repeat(3, 1fr);
  grid-template-areas:
    "client unit  type"
    "area   start due";
  flex: 1 1 auto; min-width: 0;   /* 允许随容器收窄，数值换行而不撑破卡片 */
}
.ov-client { grid-area: client; }
.ov-unit   { grid-area: unit; }
.ov-type   { grid-area: type; }
.ov-area   { grid-area: area; }
.ov-start  { grid-area: start; }
.ov-due    { grid-area: due; }

/* 合同收款：五列指标带（合同单位已移至项目概况），合同额/已收款合计大号数字强调 */
.money-strip { display: grid; grid-template-columns: 1.2fr 1fr 1fr 1fr 1.2fr; gap: var(--sp-4); align-items: end; }
.money-label { font-size: 12px; line-height: var(--lh-meta); color: var(--text-soft); margin-bottom: var(--sp-2); letter-spacing: .04em; }
.money-value { font-size: 15px; font-weight: 500; line-height: 1.35; color: var(--text); font-variant-numeric: tabular-nums; }
.money-value .unit { font-size: 12px; color: var(--text-mute); font-weight: 400; margin-left: 3px; }
.money-value.big { font-size: 26px; font-weight: 700; letter-spacing: -.01em; }
.money-value.big .unit { font-size: 13px; }
.money-value.sum { color: var(--primary-dark); }
.money-value.zero { color: var(--text-mute); }
.money-cell.hero .money-label { color: var(--primary-dark); font-weight: 600; }

/* 责任团队：五列成员样式（负责人/主持人/一级审核人/二级审核人/承接人），
   头像圈 + 角色 + 姓名；未分配灰显 */
.team { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--sp-5); }
.member { display: flex; align-items: center; gap: var(--sp-3); }
.avatar {
  width: 42px; height: 42px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 600; color: var(--primary-dark);
  background: var(--primary-soft); border: 1px solid var(--primary-ring);
}
.member.is-empty .avatar { background: var(--surface-3); border-color: var(--border); color: var(--text-mute); }
.member-role { font-size: 12px; line-height: var(--lh-meta); color: var(--text-soft); margin-bottom: 2px; }
.member-name { font-size: 15px; font-weight: 500; line-height: var(--lh-title); color: var(--text); }
.member.is-empty .member-name { color: var(--text-mute); font-weight: 400; }

/* 总体情况：勾选图标 + 状态摘要，风险/协调作为子注记沿用 .info-note */
.summary { display: flex; align-items: flex-start; gap: var(--sp-3); }
.summary-ico {
  width: 40px; height: 40px; border-radius: var(--radius); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--primary-soft); border: 1px solid var(--primary-ring);
}
.summary-ico .ico { width: 20px; height: 20px; color: var(--primary-dark); }
.summary-label { font-size: 12px; line-height: var(--lh-meta); color: var(--text-soft); margin-bottom: 4px; letter-spacing: .04em; }
.summary-text { font-size: 15px; font-weight: 600; line-height: var(--lh-base); color: var(--primary-dark); word-break: break-word; }
.summary + .info-note { margin-top: var(--gap-block); }

/* 我的项目三模块卡片：标题右侧计数、空态内边距（复用 .info-card-title 绿条标题） */
.mod-count { margin-left: auto; font-size: 12px; font-weight: 500; color: var(--text-soft); }
.mod-empty { padding: var(--sp-2) 0 var(--sp-3); }

/* 四模块响应式：列数递减、内边距随屏宽收窄，卡片间距/圆角保持一致
   （进度盘随屏宽等比收窄，始终固定在模块最右侧；字段区域关系保持固定） */
@media (max-width: 1120px) {
  /* 三列时单列不足 240px 会让单位名换行、行高参差 → 提前降为两列 */
  .info-overview { --ring-size: 92px; }
  .info-grid.info-grid--overview {
    grid-template-columns: repeat(2, 1fr);
    grid-template-areas:
      "client unit"
      "area   type"
      "start  due";
  }
}
@media (max-width: 900px) {
  .info-overview { --ring-size: 88px; gap: var(--sp-5); }
  .money-strip { grid-template-columns: repeat(3, 1fr); }
  .team { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
  .info-card { padding: var(--sp-5) var(--sp-4); }
  .info-overview { --ring-size: 80px; gap: var(--sp-4); }
  .money-strip { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px) {
  .info-overview { --ring-size: 72px; }
  .info-grid.info-grid--overview {
    grid-template-columns: 1fr;
    grid-template-areas:
      "client"
      "area"
      "unit"
      "type"
      "start"
      "due";
  }
  .team { grid-template-columns: 1fr; }
}

/* 字段栅格 */
.info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(205px, 1fr));
  gap: var(--sp-5) var(--sp-5);
  margin: 0;
}
.info-item { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.info-item dt {
  font-size: 12px; line-height: var(--lh-meta); font-weight: 500;
  color: var(--text-soft); letter-spacing: .04em;
}
.info-item dd {
  margin: 0;
  /* 取值行最小高度 = 最高的取值控件（「状态」徽章 26px），
     使 19 个字段所在行的行高与行距完全一致，不因字段类型（文本/徽章/进度条）出现参差 */
  min-height: 26px;
  display: flex; flex-direction: column; justify-content: center;
  font-size: 14px; line-height: var(--lh-title); font-weight: 500;
  color: var(--text);
  font-variant-numeric: tabular-nums;   /* 金额 / 百分比数字等宽，纵向对齐更整齐 */
  word-break: break-word; overflow-wrap: anywhere;
}
/* 徽章类取值（状态）：按内容宽度收缩，不被 flex 容器拉伸成整行宽 */
.info-item dd > .badge { align-self: flex-start; }

/* 项目名称：宽屏占两列，作为整块信息的主标题，形成第一层级 */
.info-item--wide { grid-column: span 2; }
.info-item--wide dd { font-size: 15px; font-weight: 600; letter-spacing: .005em; }

/* 已收款合计：全表唯一的强调色，收敛视觉焦点 */
.info-item--strong dd { color: var(--primary-dark); font-weight: 600; }

/* 约定完成超期：沿用语义红，但不改变其他字段配色 */
.info-item--overdue dd { color: var(--danger); font-weight: 600; }

/* 整体进度 · 圆圈进度盘：SVG 描边环（12 点起顺时针填充），圆心中置进度数值，置于模块最右侧 */
.ring-block { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: var(--gap-inline); }
.ring { position: relative; width: var(--ring-size); height: var(--ring-size); flex-shrink: 0; }
.ring-svg { display: block; width: 100%; height: 100%; transform: rotate(-90deg); }
.ring-track { fill: none; stroke: var(--surface-3); stroke-width: 9; }
.ring-arc {
  fill: none; stroke: var(--primary); stroke-width: 9; stroke-linecap: round;
  transition: stroke-dashoffset 900ms var(--ease), stroke var(--dur) var(--ease);
}
.ring--over .ring-arc { stroke: var(--danger); }
.ring-center { position: absolute; inset: 0; display: grid; place-items: center; color: var(--text); }
.ring-center b { font-size: 26px; font-weight: 700; line-height: 1; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.ring-pct { font-size: 13px; font-weight: 600; color: var(--text-soft); margin-left: 1px; }
.ring-caption { font-size: 12px; line-height: var(--lh-meta); font-weight: 500; color: var(--text-soft); letter-spacing: .04em; }

/* 长文本区块（总体情况 / 风险问题点 / 需协调事项）：浅底容器 + 左侧语义色内嵌竖条 */
.info-note {
  margin-top: var(--sp-5);
  padding: 13px var(--sp-4) 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: inset 3px 0 0 var(--primary);
}
.info-note + .info-note { margin-top: var(--gap-item); }
.info-note-label { font-size: 12.5px; font-weight: 600; color: var(--text-soft); line-height: var(--lh-meta); margin-bottom: 5px; }
.info-note-text { font-size: 13.5px; line-height: var(--lh-base); color: var(--text); word-break: break-word; }
.info-note--risk { box-shadow: inset 3px 0 0 var(--danger); }
.info-note--coord { box-shadow: inset 3px 0 0 var(--warn); }

/* 时间轴（里程碑）· 行距令牌统一：--gap-block 节点间距 / --gap-row 卡内行距 / --gap-inline 段落行距 */
.timeline { position: relative; padding-left: 4px; }
.tl-item { position: relative; padding: 0 0 var(--gap-block) 30px; border-left: 2px solid var(--border); }
.tl-item:last-child { border-left-color: transparent; padding-bottom: 2px; }
.tl-dot {
  position: absolute; left: -8px; top: 3px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--gray);
  border: 3px solid var(--surface);
  box-shadow: 0 0 0 1px var(--border);
  transition: box-shadow var(--dur) var(--ease);
}
.tl-item.done .tl-dot { background: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.tl-item.overdue .tl-dot { background: var(--danger); box-shadow: 0 0 0 4px var(--danger-soft); }
.tl-item.pending .tl-dot { background: var(--gray); }
.tl-head { display: flex; align-items: center; justify-content: space-between; gap: var(--gap-row); min-height: 22px; }
.tl-name { font-weight: 700; font-size: 14px; line-height: var(--lh-title); }
.tl-badges { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* 元信息行：整体行高 --lh-meta，与节点名间距 --gap-inline */
.tl-date {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 14px;
  margin-top: var(--gap-inline);
  font-size: 12px; line-height: var(--lh-meta); color: var(--text-soft);
}
.tl-date .d-label { color: var(--text-mute); margin-right: 4px; }
.tl-note { margin-top: var(--gap-inline); font-size: 12px; line-height: var(--lh-meta); color: var(--text-soft); }
.tl-log-preview {
  display: flex; align-items: baseline; gap: 6px;
  margin-top: var(--gap-row);
  padding: 8px 12px;
  font-size: 12.5px; line-height: var(--lh-base); color: var(--text-soft);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.tl-log-preview .ico { flex: 0 0 auto; }
.tl-actions { margin-top: var(--gap-row); }
/* 卡片内操作按钮：轻量文字态（悬停浮出浅底），减少重复按钮造成的视觉噪音 */
.tl-actions .btn,
.log-item .log-head .btn {
  background: transparent; border-color: transparent; box-shadow: none;
  padding: 3px 9px; color: var(--text-soft);
}
.tl-actions .btn { color: var(--primary-dark); }
.log-item .log-head .btn:hover { background: var(--surface-3); border-color: transparent; color: var(--text); }
.tl-actions .btn:hover { background: var(--primary-soft); border-color: transparent; color: var(--primary-dark); }

/* 项目详情头 + 页签 */
.proj-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 14px; flex-wrap: wrap; margin-bottom: var(--sp-4);
}
.proj-title { display: flex; align-items: center; gap: 8px; font-size: 18px; font-weight: 800; letter-spacing: -.01em; }
.proj-meta { margin-top: 8px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px; color: var(--text-soft); }
.proj-head-actions { display: flex; gap: 8px; flex-shrink: 0; }

.tabs { display: flex; gap: 4px; margin-bottom: var(--sp-4); border-bottom: 1px solid var(--border); }
.tab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 10px 16px; cursor: pointer; user-select: none;
  font-size: 14px; font-weight: 500; color: var(--text-soft);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), background var(--dur) var(--ease);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.tab:hover { color: var(--text); background: var(--surface-2); }
.tab.active { color: var(--primary-dark); font-weight: 700; border-bottom-color: var(--primary); background: transparent; }

/* ---------- 5.5 项目详情页 · 视觉重排（仅视觉层，不改结构/类名/字段/事件） ----------
 * 目标：① 头部与页签建立"页面级"层次；② 四张卡片内部改为"内嵌信息块 + 分隔线"的分区结构；
 *③ 关键数值（合同额 / 已收款合计 / 进度 / 逾期）成为唯一视觉焦点；
 * ④ 成员、空态、日志预览统一为浅底圆角块，与卡片语言一致；
 * ⑤ 补齐 1280 / 900 / 700 / 520 / 460 五档响应式与长文本溢出处理。
 * 约束：全部取设计令牌（--sp-* / --gap-* / --radius-* / --text-* / --primary-*），不引入裸数值色值。 */

/* ① 详情头部：加主色锚条 + 加大内边距，标题升为页面唯一 H1 级字号；操作区右对齐且不被挤压 */
.proj-head {
  align-items: center;
  gap: var(--sp-5);
  padding: var(--sp-5) var(--sp-6);
  margin-bottom: var(--gap-block);
  position: relative; overflow: hidden;
}
.proj-head::before {                    /* 与 .info-card-title 同一套"绿条锚点"语言 */
  content: ''; position: absolute; left: 0; top: var(--sp-5); bottom: var(--sp-5);
  width: 3px; border-radius: var(--radius-pill); background: var(--primary-grad);
}
.proj-title {
  font-size: 20px; font-weight: 800; line-height: var(--lh-title); letter-spacing: -.01em;
  overflow-wrap: anywhere;                /* 超长项目名换行，不撑破卡片 */
}
.proj-meta { margin-top: var(--gap-row); gap: 6px; }
.proj-meta .tag { margin: 0; }           /* 间距统一交给 .proj-meta 的 gap，避免双重外边距 */
.proj-head-actions { gap: var(--sp-2); align-self: center; margin-left: auto; }

/* 页签 → 分段控件（segmented）：容器承载底色与描边，选中项白底浮起，层级比下划线式更清晰 */
.tabs {
  display: inline-flex; gap: 2px;
  width: fit-content; max-width: 100%;
  padding: 4px; margin-bottom: var(--gap-block);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
}
.tab {
  padding: 8px 16px; margin-bottom: 0;
  border-bottom: none; border-radius: var(--radius-sm);
  font-weight: 600; white-space: nowrap;
}
.tab:hover { background: var(--surface-3); }
.tab.active {
  background: var(--surface); color: var(--primary-dark); font-weight: 700;
  box-shadow: 0 1px 2px rgba(16, 24, 40, .08);
}
[data-theme="dark"] .tab.active { box-shadow: 0 1px 2px rgba(0, 0, 0, .4); }

/* ② 卡片分区边界：标题与内容之间加一条细分隔线，"标题—内容"关系一眼可辨 */
.info-card { padding: var(--sp-6); }
.info-card-title {
  margin-bottom: 0; padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--border);
  font-size: 14.5px; letter-spacing: .02em;
}
.info-card > .info-overview,
.info-card > .money-strip,
.info-card > .team,
.info-card > .summary { margin-top: var(--sp-5); }

/* 项目概况：取值字号微升一档拉开与标签的对比；进度盘描边加粗，视觉分量匹配数字 */
.info-item dd { font-size: 14.5px; }
.ring-track, .ring-arc { stroke-width: 10; }
.ring-caption { margin-top: 2px; }

/* 合同收款：五格改为"内嵌指标块"，hero 块用主色浅底突出，数值不再悬空 */
.money-strip { gap: var(--gap-item); align-items: stretch; }
.money-cell {
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
  overflow-wrap: anywhere;
}
.money-cell.hero { background: var(--primary-soft); border-color: var(--primary-ring); }
.money-value.big { font-size: 24px; line-height: 1.25; }
.money-value.zero { color: var(--text-mute); }

/* 责任团队：成员改为浅底圆角块；未分配用虚线弱化，与在岗成员形成"有空位"的语义对比 */
.team { gap: var(--gap-item); }
.member {
  gap: var(--sp-3); min-width: 0; padding: var(--sp-3);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.member.is-empty { background: transparent; border-style: dashed; }
.member-name { font-size: 14.5px; overflow-wrap: anywhere; }
.avatar { width: 40px; height: 40px; font-size: 15px; }

/* 总体情况：摘要图标与文字加大一号；风险/协调注记加深左色条与行距，长文本不溢出 */
.summary { gap: var(--sp-4); }
.summary-ico { width: 44px; height: 44px; }
.summary-text { font-size: 16px; overflow-wrap: anywhere; }
.info-note { padding: 14px var(--sp-4); box-shadow: inset 4px 0 0 var(--primary); }
.info-note--risk { box-shadow: inset 4px 0 0 var(--danger); }
.info-note--coord { box-shadow: inset 4px 0 0 var(--warn); }
.info-note-text { overflow-wrap: anywhere; }

/* 关键节点时间轴：节点项加大留白与悬停反馈；日志预览块与卡片语言统一 */
.tl-item { padding-bottom: var(--sp-5); }
.tl-item:hover { background: var(--surface-2); border-radius: var(--radius-sm); }
.tl-head { flex-wrap: wrap; }
.tl-name { font-size: 14.5px; overflow-wrap: anywhere; }
.tl-date { gap: 0 var(--sp-4); }
.tl-log-preview {
  padding: 10px var(--sp-3);
  box-shadow: inset 3px 0 0 var(--primary-ring);
  overflow-wrap: anywhere;
}

/* ③ 空态 / 加载态：留白更舒展、弱色不刺眼、虚线圆环提示"这里本该有内容"；
   :has() 不支持时自动退化为原样式；#tab-body 预留最小高度，加载中不塌缩、不跳版 */
.empty { padding: 56px var(--sp-6); font-size: 13.5px; }
.empty:not(:has(.ico))::before {
  content: ''; width: 40px; height: 40px; margin-bottom: var(--sp-2);
  border: 2px dashed var(--border-strong); border-radius: 50%;
}
#tab-body { min-height: 220px; }

/* ④ 响应式：成员 5→3→2→1，指标带 5→3→2→1，页签在窄屏铺满一行 */
@media (max-width: 1280px) {
  .team { grid-template-columns: repeat(3, 1fr); }
  .money-strip { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 900px) {
  .proj-head { padding: var(--sp-4) var(--sp-5); }
  .proj-title { font-size: 18px; }
  .team { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
  .tabs { width: 100%; }
  .tab { flex: 1 1 0; justify-content: center; }
  .proj-head-actions { width: 100%; margin-left: 0; }
  .money-strip { grid-template-columns: repeat(2, 1fr); }
  .tl-head { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 520px) {
  .team { grid-template-columns: 1fr; }
}
@media (max-width: 460px) {
  .money-strip { grid-template-columns: 1fr; }
  .info-card { padding: var(--sp-5) var(--sp-4); }
}

/* 节点工作台分区 · 区块间距 --gap-block，区块标题↔内容 --gap-item */
.ms-section { border-top: 1px solid var(--border); padding: var(--gap-block) 0 0; margin-top: var(--gap-block); }
.ms-section:first-child { border-top: none; margin-top: 0; padding-top: 0; }
.ms-section h4 {
  margin: 0 0 var(--gap-item); font-size: 14px; font-weight: 700; line-height: var(--lh-title);
  display: flex; align-items: center; justify-content: space-between; gap: var(--gap-row);
}
/* 工作过程记录 · 单条记录：条目间距 --gap-item，卡内 --gap-row，正文行高 --lh-base */
.log-item {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--gap-item) 14px;
  margin-bottom: var(--gap-item);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.log-item:hover { border-color: var(--border-strong); }
.log-item .log-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--gap-row);
  font-size: 12px; line-height: var(--lh-meta); color: var(--text-mute);
  padding-bottom: var(--gap-row); margin-bottom: var(--gap-row);
  border-bottom: 1px dashed var(--border);
}
.log-item .log-head > span:first-child { display: inline-flex; align-items: center; gap: 5px; }
/* 内容行：标签定宽左对齐、值自适应，行间 --gap-inline */
.log-item .log-row {
  display: flex; align-items: flex-start; gap: var(--gap-row);
  font-size: 13px; line-height: var(--lh-base);
  margin: 0 0 var(--gap-inline);
}
.log-item .log-row:last-child { margin-bottom: 0; }
.log-item .log-row > b { flex: 0 0 auto; min-width: 4.9em; color: var(--text-soft); font-weight: 600; }
.log-item .log-row > :not(b) { flex: 1 1 auto; min-width: 0; }
/* 状态行：与内容行虚线分隔，值以徽章呈现（层级高于普通文本） */
.log-item .log-status { margin-top: var(--gap-row); padding-top: var(--gap-row); border-top: 1px dashed var(--border); }
.log-item .log-status > b { min-width: 0; }
.log-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 9px; border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 600; line-height: 1.5;
  background: var(--gray-soft); color: var(--text-soft);
}
.log-badge.rs-yes { background: var(--primary-soft); color: var(--primary-dark); }
.log-badge.rs-no { background: var(--danger-soft); color: var(--danger); }

.file-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  margin-bottom: 6px; font-size: 13px;
  background: var(--surface-2);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.file-item:hover { border-color: var(--border-strong); background: var(--surface); }
.file-item .f-name { flex: 1; word-break: break-all; }
.file-item .f-meta { color: var(--text-mute); font-size: 12px; white-space: nowrap; }

.review-item {
  border-left: 3px solid var(--info);
  background: var(--info-soft);
  border-radius: var(--radius-sm);
  padding: 11px 13px; margin-bottom: 8px;
}
.review-item .r-head {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 12px; color: var(--text-soft); margin-bottom: 5px;
}
.review-item .r-content { font-size: 13px; line-height: 1.6; white-space: pre-wrap; }

/* 表单容器：行与行之间的垂直间距统一由 flex gap 控制（--gap-item），
   不再用 .frow 的 margin-bottom——避免末行多出外边距，也保证任意两行间距完全一致 */
.inline-form {
  display: flex; flex-direction: column; gap: var(--gap-item);
  background: var(--surface-2);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  padding: var(--gap-item) 14px; margin-top: var(--gap-item);
}
.inline-form .frow { display: flex; gap: var(--gap-item); flex-wrap: wrap; }
.inline-form .frow > * { flex: 1; min-width: 120px; }
/* 容器为 flex 列，直接子级按钮默认会被拉伸满宽——保持原有的「内容宽度 + 左对齐」 */
.inline-form > .btn { align-self: flex-start; }
/* 工作过程记录 · 存在问题是否解决：「整体放大 15%」（行高 + 控件同步放大，标签字号仍取系统 label 规范 13px） */
.inline-form .log-resolved-row { align-items: center; min-height: var(--row-h-resolved); }
.inline-form .log-resolved-row .frow-label { flex: 0 0 auto; font-size: 13px; color: var(--text-soft); white-space: nowrap; }
.inline-form .log-resolved-row select { flex: 0 0 auto; width: 120px; height: var(--row-h-resolved); padding: 0 8px; }

/* 表单控件（日期框 / 文本域）公共外观：边框、圆角、字号——行高不在此处定义，见下方 --log 专用规则 */
.inline-form input[type="date"],
.inline-form textarea {
  padding: 10px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-size: 14px; font-family: inherit; line-height: 1.5;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
}
/* 仅「工作过程记录」表单（.inline-form--log）：四行统一行高 --field-h（40px）
   —— 单行文本 21px + 内边距 16 + 边框 2 = 39px，40px 内不裁字；行距统一 --gap-item
   作用域限定在 --log，故「审核意见」「节点附件」等其它表单的多行文本域不受影响 */
.inline-form--log input[type="date"],
.inline-form--log textarea {
  height: var(--field-h); min-height: var(--field-h);
  padding: 8px 13px;
}
.inline-form input[type="date"] {
  flex: 1; min-width: 120px;
  font-weight: 600;
  cursor: pointer;
}
.inline-form textarea { resize: vertical; }
.inline-form input[type="date"]:hover,
.inline-form textarea:hover { border-color: var(--border-strong); }
.inline-form input[type="date"]:focus,
.inline-form textarea:focus {
  outline: none;
  border-color: var(--primary);
  background: var(--surface);
  box-shadow: 0 0 0 3px var(--primary-ring);
}
.inline-form input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer; width: 18px; height: 18px; padding: 3px;
  border-radius: 4px; opacity: .8;
}
.inline-form input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; background: var(--primary-soft); }

/* ---------- 6. 工具类 ---------- */
.tag {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--surface-3); color: var(--text-soft);
  padding: 3px 9px; border-radius: var(--radius-xs);
  font-size: 12px; margin: 2px 4px 2px 0;
  vertical-align: middle;
}
.tag .ico { width: 11px; height: 11px; opacity: .8; }

/* 工作过程记录 · 「工作日志 (N)」展开/收起入口 */
.log-toggle-btn {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--surface-3); color: var(--text-soft);
  padding: 3px 10px; border-radius: var(--radius-xs);
  border: 1px solid transparent;
  font-size: 12px; font-weight: 600; margin: 2px 0;
  cursor: pointer; vertical-align: middle;
  transition: background .15s, color .15s;
}
.log-toggle-btn:hover { background: var(--surface-2); color: var(--text); }
.log-toggle-btn.open { background: var(--primary); color: #fff; }
.log-toggle-btn.disabled { cursor: default; opacity: .6; }
.row-actions { display: flex; gap: 6px; }
.overdue-flag { color: var(--danger); font-weight: 700; }

/* 图标统一尺寸 */
.ico { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; flex-shrink: 0; vertical-align: -0.14em; }
.ico svg { width: 100%; height: 100%; }
.ico-xs { width: 12px; height: 12px; }
.ico-lg { width: 18px; height: 18px; }
.ico-warn { color: var(--danger); }
.ico-alert { color: var(--danger); }

/* 危险状态圆点（页签等） */
.dot-danger {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--danger); box-shadow: 0 0 0 3px var(--danger-soft);
}

/* ---------- 7. 响应式 ---------- */
@media (max-width: 1024px) {
  :root { --content-max: 100%; }
}
@media (max-width: 900px) {
  .grid-2 { grid-template-columns: 1fr; }
  .sidebar { display: none; }
  .content { padding: var(--sp-4); }
  .topbar { padding: 0 var(--sp-4); }
}
@media (max-width: 700px) {
  .form-grid { grid-template-columns: 1fr; }
  .kv { grid-template-columns: 110px 1fr; }
  .toolbar > input.filter-input { width: 100%; }
  /* 项目基本信息（四模块版）：小屏收窄字段最小宽度，内边距同步收窄 */
  .info-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: var(--gap-block) var(--sp-3); }
}

/* ---------- 8. 动效降级 ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ===========================================================================
   9. 进度展板（新增视图 · 仅本模块类名，不影响既有样式）
   ---------------------------------------------------------------------------
   版式：顶部概览条（区间 / 项目数 / 记录数 / 节点数）→ 项目卡片列表。
   卡片内：标题行（编号 + 名称 + 状态 + 进度条）→ 元信息行（负责人等，操作按钮右对齐）
        → 节点分组（节点名 + 状态 + 记录数）→ 记录条目（日期 / 进度内容 / 存在问题 / 填报人）。
   全部尺寸与色值走设计令牌；层级靠「卡片 → 节点块 → 记录行」三级底色与左侧色条区分。
   =========================================================================== */

/* —— 筛选栏 —— */
.board-toolbar { flex-wrap: wrap; row-gap: var(--gap-row); }
.board-range { display: inline-flex; align-items: center; gap: var(--gap-row); }
.board-range-label { font-size: 12.5px; color: var(--text-soft); }
.board-range-sep { color: var(--text-mute); font-size: 13px; }
.board-date { min-width: 148px; width: 148px; font-variant-numeric: tabular-nums; }
.board-presets { display: inline-flex; gap: var(--gap-inline); padding: 3px; background: var(--surface-3); border-radius: var(--radius); }
.board-preset {
  border: 0; background: transparent; cursor: pointer;
  font-family: inherit; font-size: 12.5px; line-height: var(--lh-meta);
  color: var(--text-soft); padding: 5px 12px; border-radius: var(--radius-sm);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.board-preset:hover { color: var(--text); }
.board-preset.active {
  background: var(--surface); color: var(--primary-dark); font-weight: 600;
  box-shadow: 0 1px 2px rgba(16, 24, 40, .08);
}
.board-kw { min-width: 240px; flex: 1 1 240px; }

/* —— 顶部概览条 —— */
.board-summary {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--gap-item);
  margin-bottom: var(--gap-block);
}
.board-sum-item {
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  display: flex; flex-direction: column; gap: var(--gap-inline); justify-content: center;
}
.board-sum-label { font-size: 12px; color: var(--text-soft); line-height: var(--lh-meta); }
.board-sum-value {
  font-size: 26px; font-weight: 800; color: var(--text);
  line-height: var(--lh-title); font-variant-numeric: tabular-nums;
  display: flex; align-items: baseline; gap: var(--gap-inline);
}
.board-sum-value.sm { font-size: 14px; font-weight: 600; }
.board-sum-sub { font-size: 12px; font-weight: 500; color: var(--text-mute); }
.board-dup { margin-bottom: var(--gap-block); }
.board-empty-ops { display: flex; gap: var(--gap-row); justify-content: center; margin-top: var(--gap-row); }
.board-empty-ops .board-preset { border: 1px solid var(--border-strong); background: var(--surface); }

/* —— 项目卡片 —— */
.board-card { margin-bottom: var(--gap-block); }
.board-card:last-child { margin-bottom: 0; }
.board-card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--gap-block); flex-wrap: wrap;
}
.board-card-title { display: flex; align-items: baseline; gap: var(--gap-row); min-width: 0; }
.board-code {
  font-size: 12px; color: var(--text-soft); font-variant-numeric: tabular-nums;
  background: var(--surface-3); padding: 2px 8px; border-radius: var(--radius-xs); flex-shrink: 0;
}
.board-name {
  font-size: 15px; font-weight: 700; color: var(--text); line-height: var(--lh-title);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.board-card-tags { display: flex; align-items: center; gap: var(--gap-row); flex-shrink: 0; }
.board-prog { display: inline-flex; align-items: center; gap: var(--gap-row); font-size: 12.5px; color: var(--text-soft); }
.board-prog b { font-variant-numeric: tabular-nums; color: var(--text); }
.board-prog-bar {
  display: inline-block; width: 84px; height: 7px; border-radius: var(--radius-pill);
  background: var(--surface-3); overflow: hidden;
}
.board-prog-bar > i { display: block; height: 100%; border-radius: var(--radius-pill); background: var(--primary-grad); }

/* 元信息行：负责人/主持人/承接人/节点数/记录数/最近更新 + 右对齐操作 */
.board-card-meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--gap-row) var(--sp-4);
  margin-top: var(--gap-row); padding-bottom: var(--gap-row);
  border-bottom: 1px solid var(--border);
  font-size: 12.5px; color: var(--text-soft); line-height: var(--lh-meta);
}
.board-card-meta b { color: var(--text); font-weight: 600; }
.board-last { margin-left: auto; }
.board-open { flex-shrink: 0; }

/* —— 节点分组 —— */
.board-nodes { margin-top: var(--gap-row); display: flex; flex-direction: column; gap: var(--gap-item); }
.board-node {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2); overflow: hidden;
}
.board-node-head {
  display: flex; align-items: center; gap: var(--gap-row); flex-wrap: wrap;
  padding: var(--gap-row) var(--sp-3);
  background: var(--surface-3);
}
.board-node-name {
  display: inline-flex; align-items: center; gap: var(--gap-inline);
  font-size: 13.5px; font-weight: 700; color: var(--text);
}
.board-node-name .ico { color: var(--primary); }
.board-node-meta { margin-left: auto; font-size: 12px; color: var(--text-soft); font-variant-numeric: tabular-nums; }

/* —— 记录条目 —— */
.board-node-logs { display: flex; flex-direction: column; }
.board-log {
  display: grid; grid-template-columns: 92px minmax(0, 1fr) auto;
  gap: var(--gap-row) var(--sp-3);
  align-items: start;
  padding: var(--gap-row) var(--sp-3);
  border-top: 1px solid var(--border);
}
.board-log:first-child { border-top: 0; }
.board-log:hover { background: var(--surface); }
.board-log-date {
  font-size: 12.5px; color: var(--text-soft); font-variant-numeric: tabular-nums;
  line-height: var(--lh-meta); padding-top: 1px;
}
.board-log-body { min-width: 0; display: flex; flex-direction: column; gap: var(--gap-inline); }
.board-log-text { font-size: 13.5px; color: var(--text); line-height: var(--lh-base); overflow-wrap: anywhere; }
.board-log-text.muted { color: var(--text-mute); }
.board-log-line {
  display: flex; align-items: flex-start; gap: var(--gap-inline);
  font-size: 12.5px; line-height: var(--lh-base); overflow-wrap: anywhere;
}
.board-log-line.risk { color: var(--warn); }
.board-log-line.risk .ico { margin-top: 3px; }
.board-log-by {
  font-size: 12px; color: var(--text-mute); line-height: var(--lh-meta);
  white-space: nowrap; padding-top: 1px;
}

/* —— 响应式 —— */
@media (max-width: 1180px) {
  .board-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  .board-toolbar { align-items: stretch; }
  .board-kw { min-width: 0; width: 100%; flex-basis: 100%; }
  .board-card-meta { gap: var(--gap-row) var(--sp-3); }
  .board-last { margin-left: 0; width: 100%; }
  .board-open { width: 100%; }
  .board-log { grid-template-columns: 84px minmax(0, 1fr); }
  .board-log-by { grid-column: 2; }
}
@media (max-width: 560px) {
  .board-summary { grid-template-columns: minmax(0, 1fr); }
  .board-range { width: 100%; }
  .board-date { flex: 1 1 0; min-width: 0; width: auto; }
  .board-presets { width: 100%; }
  .board-preset { flex: 1 1 0; padding: 5px 6px; }
  .board-log { grid-template-columns: minmax(0, 1fr); }
  .board-log-by { grid-column: 1; }
}
