/* ============================================================
   项目管理系统 · 全站样式
   品牌色由 --brand 驱动（登录后按租户配置注入）
   ============================================================ */
:root {
  --brand: #1F4E79;
  --brand-700: color-mix(in srgb, var(--brand) 80%, #000);
  --brand-500: var(--brand);
  --brand-100: color-mix(in srgb, var(--brand) 12%, #fff);
  --brand-050: color-mix(in srgb, var(--brand) 6%, #fff);

  --bg: #f4f6f9;
  --card: #ffffff;
  --line: #e4e9f0;
  --line-soft: #eef2f7;
  --text: #1f2937;
  --muted: #6b7280;
  --muted-2: #9aa4b2;

  --ok: #10b981;
  --warn: #f59e0b;
  --danger: #ef4444;
  --info: #3b82f6;

  --radius: 10px;
  --shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 4px 12px rgba(16, 24, 40, .05);
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Microsoft YaHei", "PingFang SC", "Segoe UI", system-ui, -apple-system, sans-serif;
  font-size: 14px;
  line-height: 1.6;
}
/* 🔴 纵向 flex：让全站页脚（.site-foot）在内容不足一屏时也落在底部。
   内容区自己撑高（.layout / .login-wrap 有 min-height 或 flex:1），页脚不参与拉伸。 */
body { min-height: 100vh; display: flex; flex-direction: column; }
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; }

/* ---------- 顶栏 ---------- */
.topbar {
  height: 58px;
  background: linear-gradient(90deg, var(--brand-700), var(--brand-500));
  color: #fff;
  display: flex; align-items: center;
  padding: 0 20px;
  gap: 16px;
  position: sticky; top: 0; z-index: 30;
  box-shadow: 0 1px 3px rgba(0,0,0,.12);
}
.topbar .brand-box { display: flex; align-items: center; gap: 10px; min-width: 0; }
.topbar .brand-box img { height: 26px; width: auto; display: block; }
.topbar .brand-name { font-size: 15px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar .brand-sub { font-size: 12px; opacity: .8; margin-left: 4px; }
.topbar .spacer { flex: 1; }
.topbar .user-box { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.topbar .user-box .avatar {
  width: 28px; height: 28px; border-radius: 50%;
  background: rgba(255,255,255,.2);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600;
}
.topbar .user-box a { color: #fff; opacity: .85; }
.topbar .user-box a:hover { opacity: 1; }
.topbar .role-tag {
  font-size: 11px; padding: 3px 8px; border-radius: 20px;
  background: rgba(255,255,255,.18); white-space: nowrap;
}

/* ---------- 布局 ---------- */
.layout { display: flex; align-items: flex-start; min-height: calc(100vh - 58px); }
.sidebar {
  width: 208px; flex: 0 0 208px;
  background: var(--card);
  border-right: 1px solid var(--line);
  padding: 12px 8px;
  position: sticky; top: 58px;
  height: calc(100vh - 58px); overflow-y: auto;
}
.sidebar .nav-group { margin-bottom: 14px; }
.sidebar .nav-group-title {
  font-size: 11px; color: var(--muted-2); padding: 4px 12px; letter-spacing: .5px;
}
.sidebar a.nav-item {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 12px; border-radius: 8px;
  color: #384252; font-size: 13.5px;
  margin-bottom: 2px;
}
.sidebar a.nav-item:hover { background: var(--brand-050); text-decoration: none; }
.sidebar a.nav-item.active { background: var(--brand-100); color: var(--brand-700); font-weight: 600; }
.sidebar .nav-item .ico { width: 16px; text-align: center; opacity: .85; }
.sidebar .nav-item .badge {
  margin-left: auto; font-size: 11px; background: var(--danger); color: #fff;
  border-radius: 10px; padding: 0 6px; line-height: 16px;
}

.main { flex: 1; padding: 20px 24px 40px; min-width: 0; }

/* ---------- 页头 ---------- */
/* 🔴 v0.11.2：页头改成「标题行 + 说明行」两级结构（对齐 CRM 管理台）。
   改前 .sub 与 h2 是 flex 同行兄弟 → 长说明从标题右侧一路拖到行尾，
   看上去像"标题后面挂了条尾巴"，全站 26 个页面都是这个毛病。
   现在 .sub 用 order:9 + flex-basis:100% 强行独占第二行，
   标题行只留 标题 / 状态标签 / 右侧操作按钮。 */
.page-head { display: flex; align-items: center; gap: 4px 14px; margin-bottom: 18px; flex-wrap: wrap; }
.page-head h2 { font-size: 19px; }
.page-head .sub {
  order: 9; flex: 1 1 100%; margin-top: 2px;
  color: var(--muted); font-size: 13px; line-height: 1.65;
}
.page-head .sub code { background: var(--line-soft); padding: 1px 5px; border-radius: 4px; font-size: 12px; }
.page-head .spacer { flex: 1; }

/* ---------- 卡片 ---------- */
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  margin-bottom: 18px; overflow: hidden;
}
.card > .card-head {
  padding: 12px 16px; border-bottom: 1px solid var(--line-soft);
  display: flex; align-items: center; gap: 10px;
}
.card > .card-head h3 { font-size: 14.5px; }
.card > .card-head .spacer { flex: 1; }
.card > .card-body { padding: 16px; }
/* 🔴 v0.6.5：无内边距的卡片体要能横向滚动。
   .card 自己是 overflow:hidden（为了圆角裁边），列表页表格一旦比卡片宽，
   右侧的「操作」列就会被**直接裁掉** —— 用户既看不见也滚不到。
   会话新增「项目名称」列后，13 列的表在 1049px 宽的窗口下必然超出，
   所以这里让卡片体成为横向滚动容器。 */
.card > .card-body.p0 { padding: 0; overflow-x: auto; }

/* ---------- 统计卡 ---------- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr)); gap: 14px; margin-bottom: 18px; }
.stat {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px; box-shadow: var(--shadow); position: relative; overflow: hidden;
}
.stat::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--brand);
}
.stat .k { color: var(--muted); font-size: 12.5px; }
.stat .v { font-size: 24px; font-weight: 700; margin-top: 4px; line-height: 1.2; }
.stat .v small { font-size: 13px; font-weight: 500; color: var(--muted-2); margin-left: 3px; }
.stat.warn::after { background: var(--warn); }
.stat.danger::after { background: var(--danger); }
.stat.ok::after { background: var(--ok); }
.stat .foot { font-size: 12px; color: var(--muted-2); margin-top: 4px; }

/* ---------- 表格 ---------- */
table.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
table.tbl th {
  background: var(--brand-050); color: var(--brand-700);
  text-align: left; font-weight: 600; padding: 9px 12px;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
table.tbl td { padding: 9px 12px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
table.tbl tbody tr:hover { background: #fafcff; }
table.tbl tr:last-child td { border-bottom: none; }
table.tbl .num { text-align: right; font-variant-numeric: tabular-nums; }
table.tbl .nowrap { white-space: nowrap; }

/* ---------- 标签 ---------- */
.tag {
  display: inline-block; font-size: 11.5px; padding: 2px 8px; border-radius: 20px;
  background: var(--line-soft); color: #48566b; white-space: nowrap;
}
.tag.ok { background: #e7f7f0; color: #0d7a55; }
.tag.warn { background: #fef4e6; color: #a15c07; }
.tag.danger { background: #fdeceb; color: #b32a25; }
.tag.info { background: #e9f1fd; color: #1d4ed8; }
.tag.gray { background: #f1f3f6; color: #7a8699; }
.tag.brand { background: var(--brand-100); color: var(--brand-700); }

/* ---------- 进度条 ---------- */
.bar { height: 6px; background: var(--line-soft); border-radius: 4px; overflow: hidden; min-width: 60px; }
.bar > i { display: block; height: 100%; background: var(--brand); border-radius: 4px; }
.bar.ok > i { background: var(--ok); }
.bar.warn > i { background: var(--warn); }

/* ---------- 按钮 ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: 8px; border: 1px solid var(--line);
  background: #fff; color: #384252; font-size: 13px; cursor: pointer;
  font-family: inherit;
}
.btn:hover { background: #f7f9fc; text-decoration: none; }
.btn.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn.primary:hover { background: var(--brand-700); }

/* v0.26.0 子页面返回按钮 ----------------------------------------------
   加之前全站的返回写法有 4 种（← 返回列表 / ← 返回项目列表 / ← 项目列表 /
   ← 租户列表），位置也不统一。现在统一走 partials/page-back.ejs，
   样式收敛到这一条规则上。 */
.page-back { flex: 0 0 auto; white-space: nowrap; }

/* ---------- v0.27.0 工作台「最近沟通 / 最近问题」双击进详情 ----------
   悬停给一点点底色 + 指针，让用户**看得出**这行能点。
   🔴 用 cursor:pointer（默认手势）而不是 pointer：
      pointer 会让人以为是可点击的小控件，而这里实际是「双击整行」，
      已经在 title 里写明「双击查看…详情」，悬停也会看到。 */
tr.row-dblclick:hover { background: #F5F8FB; }
tr.row-dblclick:hover td { cursor: default; }
tr.row-dblclick a { cursor: pointer; }

/* ---------- 登录页 ---------- */
.login-wrap {
  /* 原来是 min-height:100vh —— 现在页脚在它下方，若仍占满整屏会把页脚挤出视口。
     改成弹性撑满「剩余高度」：内容不足时渐变区铺满，页脚自然落在底部，不出现滚动条。 */
  flex: 1 0 auto; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--brand-700), var(--brand-500));
  padding: 24px;
}
.login-card {
  width: 100%; max-width: 400px; background: #fff; border-radius: 14px;
  box-shadow: 0 20px 50px rgba(0,0,0,.25); overflow: hidden;
}
.login-card .lc-head { padding: 28px 32px 8px; text-align: center; }
.login-card .lc-head img { height: 38px; margin-bottom: 10px; }
.login-card .lc-head .co { font-size: 17px; font-weight: 700; color: var(--brand-700); }
.login-card .lc-head .sys { font-size: 12.5px; color: var(--muted); margin-top: 4px; }
.login-card form { padding: 18px 32px 12px; }
.login-card .field { margin-bottom: 14px; }
.login-card label { display: block; font-size: 12.5px; color: var(--muted); margin-bottom: 5px; }
.login-card input[type=text], .login-card input[type=password] {
  width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px;
  font-size: 14px; font-family: inherit; outline: none;
}
.login-card input:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-100); }
.login-card .btn.primary { width: 100%; justify-content: center; padding: 11px; font-size: 14.5px; margin-top: 6px; }
.login-card .err {
  background: #fdeceb; color: #b32a25; border-radius: 8px; padding: 9px 12px;
  font-size: 12.5px; margin-bottom: 14px;
}
.login-card .lc-foot {
  padding: 12px 32px 22px; text-align: center; color: var(--muted-2); font-size: 11.5px;
}

/* ---------- 申请结果页（开户申请已提交）：正文容器 ----------
   🔴 v0.11.2：改前这一段正文用的是内联样式，**完全没有左右内边距**，
   于是文字直接顶到卡片边缘（与上方居中的标题、下方居中的页脚对不齐），
   用户原话「界面乱」。现在有 .lc-body 统一内边距，与 .lc-head/.lc-foot 的 32px 对齐。 */
.login-card .lc-body {
  padding: 4px 32px 10px; text-align: left;
  font-size: 14px; line-height: 1.75; color: var(--text);
}
.login-card .lc-body p { margin: 0 0 12px; }
.login-card .lc-body p:last-child { margin-bottom: 0; }
.login-card .lc-body .sd-hint { font-size: 12px; color: var(--muted-2); line-height: 1.7; }
.login-card .lc-body .sd-lead { color: var(--text); }
/* 「接下来会怎样」信息块：蓝色信息框（与 .alert-info 同一套色），
   把原来挤成一大段的流程说明拆成有序步骤 */
.sd-steps {
  margin: 14px 0 12px; padding: 12px 14px; border-radius: 8px;
  background: #eef4fb; border: 1px solid #cfe0f2; color: #22507f;
  font-size: 13px; line-height: 1.8;
}
.sd-steps .sd-steps-h { font-weight: 700; margin-bottom: 5px; color: #1b4372; }
.sd-steps ol { margin: 0; padding-left: 20px; }
.sd-steps li { margin-bottom: 3px; }
.sd-steps li:last-child { margin-bottom: 0; }
.sd-steps b { color: #1b4372; }

/* ---------- 申请试用页：审核时效提示条 ---------- */
.signup-tip {
  margin: 0 32px 14px; padding: 11px 14px; border-radius: 8px;
  background: var(--line-soft); border: 1px solid var(--brand-100);
  color: var(--brand-700); font-size: 12.5px; line-height: 1.75; text-align: left;
}
.signup-tip .st-sub { margin-top: 5px; color: var(--muted); font-size: 12px; }

/* ---------- 登录页：试用申请入口（对应 CRM 登录页的 /signup 入口） ---------- */
.login-card .lc-alt {
  margin: 0 32px; padding: 13px 0 2px; text-align: center;
  border-top: 1px dashed var(--line);
}
.login-card .lc-alt .la-note { font-size: 12.5px; color: var(--muted); margin-right: 5px; }
.login-card .lc-alt .la-go {
  font-size: 13px; font-weight: 600; color: var(--brand-700); text-decoration: none;
  border-bottom: 1px solid var(--brand-100);
}
.login-card .lc-alt .la-go:hover { color: var(--brand); border-bottom-color: var(--brand); }
.login-card .lc-alt .la-sub { margin-top: 5px; font-size: 11.5px; color: var(--muted-2); }

/* ---------- 登录页：演示账号快捷登录（DEMO_LOGIN 开启时出现） ---------- */
.login-stack { display: flex; flex-direction: column; align-items: center; gap: 18px; width: 100%; }
.demo-box {
  width: 100%; max-width: 760px; background: #fff; border-radius: 14px;
  box-shadow: 0 20px 50px rgba(0,0,0,.18); padding: 16px 18px 14px;
}
.demo-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 12px;
}
.demo-head .dh-t { font-size: 13.5px; font-weight: 700; color: var(--brand-700); }
.demo-head .dh-p { font-size: 12px; color: var(--muted); }
.demo-head code, .demo-tip code {
  background: var(--brand-050); border: 1px solid var(--line); border-radius: 5px;
  padding: 1px 6px; font-size: 11.5px; color: var(--brand-700);
  font-family: ui-monospace, Consolas, "Courier New", monospace;
}
.demo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(238px, 100%), 1fr)); gap: 8px; }
.demo-group {
  /* 🔴 min-width:0 不能省：grid item 默认 min-width:auto = min-content，
     而组内 .di-user 是 monospace 且 flex:0 0 auto（不收缩）、.di-tag 是 nowrap，
     窄屏下整组的 min-content 达 358px，会把登录卡撑破（360 视口下溢出 40px）。 */
  min-width: 0;
  border: 1px solid var(--line); border-radius: 10px; padding: 7px 8px 8px;
  background: linear-gradient(180deg, #fff, var(--brand-050));
}
.dg-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.dg-label { font-size: 12.5px; font-weight: 700; color: var(--text); }
.dg-note { font-size: 10.5px; color: var(--muted-2); line-height: 1.4; margin: 1px 0 6px; }
.dg-accounts { display: flex; gap: 6px; }
.demo-item {
  display: flex; align-items: center; gap: 5px; min-width: 0; flex: 1 1 0;
  background: #fff; border: 1px solid var(--line); border-radius: 8px;
  padding: 4px 5px 4px 8px; cursor: pointer; font-family: inherit;
  transition: border-color .12s, background .12s, box-shadow .12s;
}
.demo-item:hover { border-color: var(--brand); background: var(--brand-050); }
.demo-item:focus-visible { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-100); }
.demo-item.on { border-color: var(--brand); background: var(--brand-100); box-shadow: 0 0 0 2px var(--brand-100); }
.di-tag {
  font-size: 10px; padding: 0 5px; border-radius: 20px; line-height: 15px;
  white-space: nowrap; background: #eef2f7; color: var(--muted);
}
.di-tag[data-tag="管理"] { background: #e8eef7; color: #2b4e78; }
.di-tag[data-tag="成控"] { background: #fdf0e3; color: #9a5b0b; }
.di-tag[data-tag="项目"] { background: #e6f4ef; color: #0b6b4f; }
.di-tag[data-tag="设计"] { background: #eeeaf9; color: #5b3fa8; }
.di-tag[data-tag="销售"] { background: #fde9ef; color: #a32550; }
.di-tag[data-tag="平台"] { background: #eaf0f6; color: #40607f; }
.di-user {
  font-size: 11.5px; color: var(--brand-700); flex: 0 0 auto;
  font-family: ui-monospace, Consolas, monospace;
}
.di-name {
  font-size: 10px; color: var(--muted-2); flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.di-go {
  flex: 0 0 auto; border: 1px solid var(--line); background: #fff; color: var(--brand-700);
  font-size: 10px; font-family: inherit; border-radius: 6px; padding: 1px 5px;
  cursor: pointer; white-space: nowrap; opacity: .55; transition: opacity .12s, background .12s;
}
.demo-item:hover .di-go, .demo-item:focus-within .di-go, .demo-item.on .di-go { opacity: 1; }
.di-go:hover { background: var(--brand); border-color: var(--brand); color: #fff; }
.demo-tip {
  margin-top: 11px; font-size: 11px; color: var(--muted-2); line-height: 1.6;
  border-top: 1px dashed var(--line); padding-top: 9px;
}
@media (max-width: 560px) {
  .demo-grid { grid-template-columns: 1fr; }
  .di-go { opacity: 1; }
}

/* ---------- 空状态 ---------- */
.empty { padding: 30px 16px; text-align: center; color: var(--muted-2); font-size: 13px; }

/* ---------- 键值列表 ---------- */
.kv { display: grid; grid-template-columns: 110px 1fr; gap: 8px 14px; font-size: 13px; }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; }

.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
@media (max-width: 1080px) { .two-col { grid-template-columns: 1fr; } }
@media (max-width: 860px) {
  .sidebar { display: none; }
  .main { padding: 14px; }
}

/* ---------- 节点时间线 ---------- */
.node-list { display: flex; flex-direction: column; }
.node-row {
  /* 🔴 v0.6.4 起多了一列「完成人」（用户要求：完成了要看得见是谁完成的）。
     列数从 7 → 8，必须同步改这里 —— grid 少一列会把最后一个子元素挤到下一行。 */
  display: grid; grid-template-columns: 46px 1fr 88px 96px 80px 96px 210px 128px;
  gap: 10px; align-items: center; padding: 9px 16px;
  border-bottom: 1px solid var(--line-soft); font-size: 13px;
}
.node-row:last-child { border-bottom: none; }
.node-row .sq {
  width: 26px; height: 26px; border-radius: 50%; background: var(--line-soft);
  color: #5b6879; display: flex; align-items: center; justify-content: center;
  font-size: 11.5px; font-weight: 600;
}
.node-row.done .sq { background: var(--ok); color: #fff; }
.node-row.doing .sq { background: var(--brand); color: #fff; }
.node-row .nm { font-weight: 500; }
.node-row .ev { color: var(--muted-2); font-size: 12px; }
.nd-act { display: flex; gap: 6px; align-items: center; justify-content: flex-end; }
.nd-legend {
  padding: 9px 16px; border-top: 1px solid var(--line-soft);
  font-size: 11.5px; color: var(--muted-2); line-height: 1.6; background: #fafbfd;
}

/* ---------- 表单 ---------- */
.frow { margin-bottom: 13px; }
.frow > label { display: block; font-size: 12.5px; color: var(--muted); margin-bottom: 5px; }
.frow > label b { color: var(--danger); }
.frow input[type=text], .frow input[type=email], .frow input[type=password],
.frow textarea, .frow select {
  width: 100%; padding: 8px 11px; border: 1px solid var(--line); border-radius: 8px;
  font-size: 13.5px; font-family: inherit; outline: none; background: #fff; color: var(--text);
}
.frow input:focus, .frow textarea:focus, .frow select:focus {
  border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-100);
}
.color-row { display: flex; align-items: center; gap: 10px; }
.color-row input[type=color] {
  width: 48px; height: 34px; padding: 2px; border: 1px solid var(--line);
  border-radius: 8px; background: #fff; cursor: pointer;
}
.hint { font-size: 12px; color: var(--muted-2); }

/* ---------- 提示条 ---------- */
.alert { border-radius: 8px; padding: 10px 14px; font-size: 13px; margin-bottom: 16px; border: 1px solid transparent; }
.alert-ok { background: #e7f7f0; color: #0d7a55; border-color: #bfe9d7; }
.alert-warn { background: #fef4e6; color: #a15c07; border-color: #f7ddb5; }
.alert-error { background: #fdeceb; color: #b32a25; border-color: #f7cbc8; }

/* ---------- Logo 预览 ---------- */
.logo-preview { display: flex; flex-direction: column; gap: 12px; margin-bottom: 16px; }
.lp-box {
  border: 1px solid var(--line); border-radius: 8px; padding: 12px;
  display: flex; flex-direction: column; gap: 8px; align-items: flex-start;
}
.lp-box.light { background: #fff; }
.lp-box.dark { background: #21456b; }
.lp-box .lp-label { font-size: 11.5px; color: var(--muted-2); }
.lp-box.dark .lp-label { color: rgba(255, 255, 255, .65); }
.lp-box img { max-width: 220px; height: auto; }
.lp-none { font-size: 12px; color: var(--muted-2); }
.spec { border-top: 1px dashed var(--line); padding-top: 12px; }
.spec-title { font-size: 12.5px; font-weight: 600; margin-bottom: 6px; }
.spec ul { margin: 0; padding-left: 18px; font-size: 12.5px; color: var(--muted); }
.spec li { margin-bottom: 3px; }
.spec code { background: var(--line-soft); padding: 1px 5px; border-radius: 4px; font-size: 11.5px; }

/* ============================================================
   组织架构
   ============================================================ */
.org-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(430px, 100%), 1fr)); gap: 16px; align-items: start; }
@media (max-width: 1180px) { .org-grid { grid-template-columns: 1fr; } }

.org-unit .card-head h3 { font-size: 15px; }

.org-lead {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 16px; background: var(--brand-050);
  border-bottom: 1px solid var(--line-soft); font-size: 13.5px;
}
.org-lead .lead-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--brand); flex: 0 0 8px;
}
.org-lead .lead-dot.warn { background: var(--warn); }
.org-lead .spacer { flex: 1; }

.org-leaf {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 16px 7px 26px; font-size: 13px;
  border-bottom: 1px solid var(--line-soft);
}
.org-leaf:last-child { border-bottom: none; }
.org-leaf .tree-line { color: var(--muted-2); font-family: monospace; }
.org-leaf .spacer { flex: 1; }
.org-leaf.empty-leaf { color: var(--muted-2); padding-left: 34px; font-size: 12.5px; }

.muted-sm { color: var(--muted-2); font-size: 12px; }
.inline-form { display: inline; margin: 0; }
.btn.tiny { padding: 2px 9px; font-size: 11.5px; border-radius: 6px; }

.unit-tune { border-bottom: 1px solid var(--line-soft); }
.unit-tune > summary {
  cursor: pointer; padding: 7px 16px; font-size: 12.5px; color: var(--muted);
  list-style: none; user-select: none;
}
.unit-tune > summary::-webkit-details-marker { display: none; }
.unit-tune > summary::before { content: "⚙ "; opacity: .7; }
.unit-tune[open] > summary { color: var(--brand-700); background: var(--brand-050); }
.tune-form {
  display: grid; grid-template-columns: repeat(3, 1fr) auto; gap: 10px; align-items: end;
  padding: 12px 16px; background: #fafcff;
}
.tune-form .frow { margin: 0; }
.tune-form .frow label { font-size: 11.5px; }
@media (max-width: 720px) { .tune-form { grid-template-columns: 1fr 1fr; } }

.new-user-form {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr)); gap: 12px 16px; align-items: end;
}
.new-user-form .frow { margin: 0; }
.new-user-form .submit-row { grid-column: 1 / -1; }
.new-user-form label small { font-weight: 400; }

/* 成本与合同 —— 金额列 */
table.tbl td.money, table.tbl th.money { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.rate-good { color: #0d7a55; font-weight: 600; }
.rate-warn { color: #a15c07; font-weight: 600; }
.rate-bad { color: #b32a25; font-weight: 600; }

/* ============================================================
   行动提醒中心（铃铛 / 提醒列表 / 计划任务）—— 浅色主题
   ============================================================ */

/* ---------- 按钮补充档位 ---------- */
.btn.sm { padding: 3px 10px; font-size: 12px; border-radius: 6px; }
.btn.ghost { background: transparent; border-color: var(--line); color: var(--muted); }
.btn.ghost:hover { background: #f7f9fc; color: var(--text); }
.btn.ghost.danger { color: #b32a25; border-color: #f2d3d1; }
.btn.ghost.danger:hover { background: #fdeceb; }

/* ---------- 顶栏铃铛 ---------- */
.topbar .bell { position: relative; }
.topbar .bell > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 10px; border-radius: 8px;
  background: rgba(255,255,255,.14);
  border: 1px solid rgba(255,255,255,.20);
  transition: background .15s;
}
.topbar .bell > summary::-webkit-details-marker { display: none; }
.topbar .bell > summary:hover { background: rgba(255,255,255,.26); }
.topbar .bell .bell-ico { font-size: 14px; line-height: 1; filter: saturate(0) brightness(3); }
.topbar .bell .bell-badge {
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 9px; background: #ff4d4f; color: #fff;
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
}
.topbar .bell .bell-badge.hide { display: none; }

.bell-panel {
  position: absolute; right: 0; top: calc(100% + 10px);
  width: 380px; max-width: 92vw;
  background: var(--card); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 10px 30px rgba(16,24,40,.16);
  overflow: hidden; z-index: 60;
}
.bell-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-bottom: 1px solid var(--line-soft);
  background: #fafcff; font-size: 13px;
}
.bell-head .bell-buckets { margin-left: auto; font-size: 11.5px; color: var(--muted-2); }
.bell-empty { padding: 22px 14px; text-align: center; color: var(--muted-2); font-size: 13px; }
.bell-list { list-style: none; margin: 0; padding: 0; max-height: 384px; overflow-y: auto; }
.bell-list li { border-bottom: 1px solid var(--line-soft); }
.bell-list li:last-child { border-bottom: none; }
.bell-list a { display: flex; gap: 9px; padding: 9px 14px; color: var(--text); }
.bell-list a:hover { background: #f7f9fc; text-decoration: none; }
.bell-list .bl-ico { flex: none; width: 18px; text-align: center; opacity: .7; font-size: 13px; }
.bell-list .bl-main { min-width: 0; flex: 1; }
.bell-list .bl-title {
  display: block; font-size: 12.8px; line-height: 1.45;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bell-list .bl-meta { display: block; font-size: 11.5px; color: var(--muted-2); margin-top: 2px; }
.bell-more { padding: 7px 14px; font-size: 12px; color: var(--muted-2); background: #fafcff; border-top: 1px solid var(--line-soft); }
.bell-foot {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px; border-top: 1px solid var(--line);
  background: #fafcff; font-size: 12.5px;
}
.bell-foot .bell-acked { margin-left: auto; color: var(--muted-2); font-size: 11.5px; }

/* ---------- 侧栏徽章 ---------- */
.sidebar .nav-item .nav-badge {
  margin-left: auto; min-width: 17px; height: 17px; padding: 0 5px;
  border-radius: 9px; background: #ff4d4f; color: #fff;
  font-size: 11px; font-weight: 700; line-height: 17px; text-align: center;
}
.sidebar a.nav-item { display: flex; align-items: center; gap: 8px; }

/* ---------- 紧迫度标记 ---------- */
.u-overdue { color: #b32a25; font-style: normal; font-weight: 600; }
.u-urgent  { color: #a15c07; font-style: normal; font-weight: 600; }
.u-soon    { color: #1d4ed8; font-style: normal; font-weight: 600; }
.u-normal  { color: var(--muted-2); font-style: normal; }

/* ---------- 提醒说明条 ---------- */
.al-note {
  background: #fafcff; border: 1px solid var(--line); border-left: 3px solid var(--brand);
  border-radius: 8px; padding: 9px 14px; margin-bottom: 18px;
  font-size: 12.5px; color: var(--muted); line-height: 1.9;
}
.al-note b { color: var(--text); }

/* ---------- 提醒列表 ---------- */
.alert-list { list-style: none; margin: 0; padding: 0; }
.al-item {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 16px; border-bottom: 1px solid var(--line-soft);
  border-left: 3px solid transparent;
}
.alert-list li:last-child { border-bottom: none; }
.al-item:hover { background: #fafcff; }
.al-item.al-overdue { border-left-color: #ef4444; }
.al-item.al-urgent  { border-left-color: #f59e0b; }
.al-item.al-soon    { border-left-color: #3b82f6; }
.al-item.al-normal  { border-left-color: var(--line); }
.al-item.al-acked   { opacity: .62; border-left-color: var(--line); }

.al-ico { flex: none; width: 22px; text-align: center; font-size: 14px; opacity: .8; padding-top: 2px; }
.al-body { flex: 1; min-width: 0; }
.al-title { font-size: 13.5px; font-weight: 600; line-height: 1.5; }
.al-title em { margin-left: 6px; font-size: 11.5px; }
.al-ovd {
  margin-left: 6px; font-size: 11px; font-weight: 600;
  background: #fdeceb; color: #b32a25; padding: 1px 6px; border-radius: 4px;
}
.al-detail { font-size: 12.5px; color: var(--muted); margin-top: 3px; line-height: 1.6; }
.al-meta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 5px; font-size: 11.5px; color: var(--muted-2); }
.al-meta .al-src { background: #f1f3f6; color: #7a8699; padding: 1px 7px; border-radius: 4px; }
/* 记录编号（2026-10-07）：提醒卡片上直接显示是哪一条，不用点进去才知道。
   用等宽 + 品牌色浅底，与左边 .al-src 的灰调区分开 —— 编号是要被读的信息，不是标签。 */
.al-meta .al-ref { background: #eaf2fd; color: #1a5fb4; padding: 1px 7px; border-radius: 4px;
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11.5px; letter-spacing: .01em; }
.al-act { flex: none; display: flex; align-items: center; gap: 6px; }
.al-act form { margin: 0; }
.al-more { padding: 10px 16px; font-size: 12.5px; background: #fafcff; border-top: 1px solid var(--line-soft); }

/* 提醒标题可点（v0.22.0）：用户反馈「无法点进去、无法跟踪」。
   原来标题是纯文本，只有右边「去处理」能点 —— 但人看到标题会自然去点标题。
   做法：视觉上仍然像标题（继承标题的字号字重，不加按钮底色），
   hover 时才现出链接特征（变主色 + 下划线），
   避免与右侧「去处理」按钮抢视觉焦点、也不让静态页面显得满屏都是链接。 */
.al-title .al-link { color: inherit; text-decoration: none; }
.al-title .al-link:hover { color: var(--brand, #1a5fb4); text-decoration: underline; }
.al-title .al-link:focus-visible { outline: 2px solid var(--brand, #1a5fb4); outline-offset: 2px; border-radius: 2px; }

/* 从提醒跳进计划表格时高亮目标行：浏览器自带 :target 锚点没有视觉反馈，
   十几行表格里定位到了也看不出是哪一行。 */
tr:target > td, tr.al-focus > td { background: #fff8e1; }
tr.al-focus > td:first-child { box-shadow: inset 3px 0 0 #f0a500; }

/* 「关联记录」单元格内的折叠设置块（v0.22.0）
   用原生 <details> 而不是弹窗：这类操作低频、且不该遮挡整页，
   原生控件还自带键盘可达性与展开状态。 */
.inline-set { margin-top: 4px; }
.inline-set > summary { list-style: none; cursor: pointer; display: inline-block; }
.inline-set > summary::-webkit-details-marker { display: none; }
.link-form {
  display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
  margin-top: 6px; padding: 8px; min-width: 260px;
  background: #f6f8fb; border: 1px solid #e3e8ef; border-radius: 6px;
}
.link-form select { max-width: 240px; height: 28px; font-size: 12.5px; }
.link-form .hint { flex: 1 0 100%; font-size: 11.5px; line-height: 1.5; }
.inline-set[open] > summary { color: var(--brand, #1a5fb4); }

/* 紧凑版（工作台卡片） */
.alert-list.compact .al-item { padding: 9px 16px; }
.alert-list.compact .al-detail { display: none; }

/* ---------- 计划任务表单 ---------- */
.new-plan > summary { display: inline-block; margin-bottom: 14px; }
.new-plan[open] > summary { margin-bottom: 16px; }
.plan-form {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
  gap: 12px 16px; align-items: end;
  padding: 16px; background: #fafcff;
  border: 1px solid var(--line); border-radius: 8px;
}
.plan-form .frow { margin: 0; }
.plan-form .frow-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 10px; grid-column: span 2; }
.plan-form .frow-2 label { grid-column: span 1; }
@media (max-width: 720px) { .plan-form .frow-2 { grid-column: 1 / -1; } }

/* ---------- 表格单元格 ---------- */
.cell-strong { font-weight: 600; }
.cell-sub { font-size: 11.5px; color: var(--muted-2); margin-top: 2px; }
.row-muted { opacity: .55; }

/* ---------- 已关闭面板 ---------- */
.acked-card > summary { cursor: pointer; list-style: none; }
.acked-card > summary::-webkit-details-marker { display: none; }
.acked-card > summary::after { content: '展开 ▾'; font-size: 11.5px; color: var(--muted-2); margin-left: 6px; }
.acked-card[open] > summary::after { content: '收起 ▴'; }

/* ============================================================
   v0.4.0 —— 岗位界面差异化 / 录入表单 / 分析页
   ============================================================ */

/* ---------- 录入表单 ---------- */
.frm-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 18px;
}
@media (max-width: 860px) { .frm-grid { grid-template-columns: 1fr; } }

.frm-cell { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.frm-cell.wide { grid-column: 1 / -1; }
.frm-cell > label { font-size: 12.5px; color: var(--muted); font-weight: 600; }
.frm-cell > label b { color: var(--danger); }
.frm-cell input[type="text"], .frm-cell input[type="date"], .frm-cell input[type="number"],
.frm-cell select, .frm-cell textarea {
  width: 100%; box-sizing: border-box; padding: 8px 10px; font-size: 13.5px;
  border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--text);
  font-family: inherit;
}
.frm-cell textarea { resize: vertical; line-height: 1.55; }
.frm-cell input:focus, .frm-cell select:focus, .frm-cell textarea:focus {
  outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px rgba(31, 78, 121, .12);
}
.frm-ro {
  padding: 8px 10px; font-size: 13.5px; border-radius: 8px;
  background: #f4f6f9; border: 1px dashed var(--line); color: var(--muted); min-height: 20px;
}
.frm-hint { font-size: 11.5px; color: var(--muted-2); }
.frm-act { margin-top: 20px; display: flex; gap: 10px; align-items: center; }
.err-list { margin: 8px 0 0 18px; padding: 0; font-size: 13px; }

.danger-card { border-color: #f0c9c9; }
.danger-card .card-head { background: #fdf5f5; }

/* ---------- 侧栏页脚 / 角色标识 ---------- */
.side-foot { margin: 22px 12px 8px; padding-top: 12px; border-top: 1px solid var(--line); }
.side-role { margin-bottom: 6px; }
.side-hint { font-size: 11.5px; color: var(--muted-2); }
.nav-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: #e8833a; margin-left: 6px; vertical-align: middle;
}

/* ---------- 工作台：我的工作 / 快捷录入 ---------- */
.my-card .card-head { background: #f7fafc; }
.quick-bar {
  margin-top: 16px; padding-top: 14px; border-top: 1px dashed var(--line);
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
.quick-label { font-size: 12.5px; color: var(--muted); margin-right: 4px; }

/* ---------- 分析页 ---------- */
.an-tabs { display: flex; gap: 10px; margin-bottom: 16px; flex-wrap: wrap; }
.an-tab {
  padding: 7px 14px; border-radius: 20px; font-size: 13px; text-decoration: none;
  background: var(--card); border: 1px solid var(--line); color: var(--text);
}
.an-tab:hover { border-color: var(--brand); color: var(--brand); }

.an-split { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 18px; margin-top: 20px; }
.an-split2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: 18px; padding: 16px 20px 20px; }
.an-panel {
  border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px; background: #fcfdfe;
}
.an-panel h4 { margin: 0 0 10px; font-size: 13.5px; color: var(--text); }
.an-note { margin: 0; padding-left: 18px; font-size: 12.5px; color: var(--muted); line-height: 1.75; }
.an-note b { color: var(--text); }
.an-next {
  margin-top: 18px; padding: 12px 16px; border-radius: 10px;
  background: #f4f8fc; border: 1px solid #d6e4f0; font-size: 13.5px;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.pj-head { margin-bottom: 16px; }
.pj-head > div:first-child { font-size: 15px; margin-bottom: 4px; }

/* 堆叠条形（占比可视化） */
.stack { display: flex; flex-direction: column; gap: 9px; }
.stack-row { display: grid; grid-template-columns: 76px 1fr 44px; gap: 10px; align-items: center; }
.stack-l { font-size: 12px; }
.stack-bar { height: 12px; background: #eef1f5; border-radius: 6px; overflow: hidden; }
.stack-bar > i { display: block; height: 100%; border-radius: 6px; background: var(--brand); }
.stack-bar > i.ok { background: #2f9e6e; }
.stack-bar > i.info { background: #3b82c4; }
.stack-bar > i.gray { background: #b9c2cc; }
.stack-bar > i.danger { background: #d9534f; }
.stack-bar > i.brand { background: var(--brand); }
.stack-v { font-size: 12.5px; text-align: right; color: var(--text); font-weight: 600; }

/* 表格：紧凑 / 行状态 */
.tbl.mini { font-size: 12.5px; }
.tbl.mini td, .tbl.mini th { padding: 6px 8px; }
.row-me { background: #f2f8ff; }
.row-danger { background: #fdf6f6; }
.row-total { font-weight: 700; background: #f7f9fb; }

/* stat 别名：分析页用 .n / .l */
.stat .n { font-size: 24px; font-weight: 700; margin-top: 4px; line-height: 1.2; }
.stat .n small { font-size: 13px; font-weight: 500; color: var(--muted-2); margin-left: 3px; }
.stat .l { font-size: 12.5px; color: var(--muted); }

/* ---------- v0.5.0：节点 15 节点重排 + 行级确认 ---------- */
.alert-info { background: #eef4fb; color: #22507f; border-color: #cfe0f2; }
/* 🔴 v0.11.2：页面内的「口径说明 / 规则说明」统一用信息框呈现（原来是卡片里挂一段小字，
   与别处的信息框两种长相）。列表用 ul 而不是手写「·」，缩进与行距才齐。 */
.alert > ul { margin: 6px 0 0; padding-left: 20px; }
.alert > ul > li { margin-bottom: 2px; }
.alert code { background: rgba(255, 255, 255, .7); padding: 1px 5px; border-radius: 4px; font-size: 12px; }
.btn.xs { padding: 2px 9px; font-size: 11.5px; border-radius: 6px; }
.btn.xs.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn.xs.primary:hover { background: var(--brand-700); }
.node-row .lk { font-size: 10px; color: var(--muted-2); background: #f0f2f5; border-radius: 4px; padding: 0 5px; margin-left: 5px; font-weight: 400; }

/* 多选字段（协作角色） */
.frm-multi { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 4px 0; }
.frm-multi .chk { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--text); cursor: pointer; }
.frm-multi .chk input { margin: 0; }

/* 项目背景信息块 + 列表副注 */
.bg-note { margin-top: 12px; border-top: 1px dashed var(--line); padding-top: 10px; }
.bg-note .bg-t { font-size: 12.5px; font-weight: 600; color: var(--muted); margin-bottom: 4px; }
.bg-note .bg-c { font-size: 13px; line-height: 1.7; color: var(--text); }
.sub-note { font-size: 11.5px; color: var(--muted-2); margin-top: 2px; }

/* ---------- v0.6.0：节点台账「一项目一行 + 双击展开」 ---------- */
.nd-grouped { table-layout: auto; }
.nd-grouped tbody.nd-grp { border-bottom: 1px solid var(--line); }
.nd-grouped tbody.nd-grp:last-child { border-bottom: none; }
.nd-sum { cursor: pointer; }
.nd-sum:hover { background: var(--brand-050); }
.nd-grouped tbody.open > .nd-sum { background: var(--brand-050); }
.nd-sum .caret {
  display: inline-block; width: 14px; color: var(--brand); font-size: 11px;
  transition: transform .15s ease;
  user-select: none; cursor: pointer;
}
.nd-grouped tbody.open .nd-sum .caret { transform: rotate(90deg); }
.nd-detail > td { padding: 0 !important; background: #fbfcfe; border-top: 1px dashed var(--line); }
.nd-wrap { padding: 12px 14px 14px; }
.nd-wrap-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px; }
.nd-wrap-head .hint { font-size: 11.5px; color: var(--muted-2); }
.nd-sub.tbl { font-size: 12.5px; box-shadow: none; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.nd-sub.tbl th { background: #f4f7fb; }
.nd-sub tr.nd-cur > td { background: #eef4fb; }
.who-none { color: var(--muted-2); font-size: 12px; }
.assign-inline { display: flex; align-items: center; gap: 5px; margin: 0; min-width: 0; }
.assign-inline select {
  padding: 3px 6px; font-size: 12px; border: 1px solid var(--line); border-radius: 6px;
  background: #fff; color: var(--text); font-family: inherit;
  flex: 1 1 auto; min-width: 0; max-width: 168px;
}
.assign-inline button { flex: 0 0 auto; }
.assign-inline select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand-100); }

/* ---------- v0.6.0：项目编号规则（企业与品牌页）---------- */
.no-preview {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  background: var(--brand-050); border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 14px;
}
.no-demo {
  font-family: Consolas, "Courier New", monospace; font-size: 21px; font-weight: 700;
  letter-spacing: .5px; color: var(--brand-700);
}
.no-demo2 {
  font-family: Consolas, "Courier New", monospace; font-size: 14px; color: var(--muted);
}
.no-list { display: flex; flex-wrap: wrap; gap: 6px; }
.no-list .tag { font-family: Consolas, "Courier New", monospace; }

/* ---------- v0.6.1：项目列表「当前节点」列（阶段名称 + 进度副注） ----------
   原先该列只渲染 `6/15 (40%)` 这种「编号式」数字，看不出项目卡在哪个阶段。
   现在主行是**阶段名称**，进度降为副注；名称过长时在列内换行（不截断、不溢出）。 */
.cur-td { max-width: 172px; }
.cur-nd { line-height: 1.4; }
.cur-nd .nd-code {
  display: inline-block; min-width: 19px; margin-right: 3px;
  color: var(--muted-2); font-size: 11.5px; font-variant-numeric: tabular-nums;
}
.cur-nd a { text-decoration: none; }
.cur-nd a:hover { text-decoration: underline; }
.cur-td .sub-note { white-space: nowrap; }

/* ---------- v0.6.2：统计卡片可点击（工作台 → 列表页下钻） ----------
   原先工作台的 9 张统计卡片是纯展示，看到「我的逾期节点 1 个」也只能自己再去列表里翻。
   现在卡片本体是 <a>，hover 时边框变品牌色并微微上浮，右下角出现 → 表示可点。
   ⚠️ .stat 原为 div 样式，改成 <a> 后必须补 display/color/text-decoration，
      否则会变成一行内联文字（浏览器默认 <a> 是 inline，且带下划线）。 */
a.stat { display: block; color: inherit; text-decoration: none; }
a.stat:hover { text-decoration: none; }
a.stat.clickable { transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease; }
a.stat.clickable:hover {
  border-color: var(--brand);
  box-shadow: 0 4px 14px rgba(15, 40, 80, .12);
  transform: translateY(-1px);
}
a.stat.clickable:hover .k { color: var(--brand); }
a.stat:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
a.stat .foot .go {
  display: inline-block; margin-left: 6px; color: var(--brand);
  opacity: .35; transition: opacity .15s ease, transform .15s ease;
}
a.stat.clickable:hover .foot .go { opacity: 1; transform: translateX(2px); }

/* ---------- v0.6.2：列表页「快速筛选」条 ----------
   从卡片点进来后，用户要能立刻看出：当前按什么条件看 / 还能切到哪几种 / 怎么清掉。
   没有这条，点进去看到一张列表会不知道「这是筛过的还是全量」。 */
.filter-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 0 0 14px; padding: 10px 14px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); font-size: 12.5px;
}
.filter-bar .fb-label { color: var(--muted); }
.filter-bar .fb-chip {
  display: inline-block; padding: 4px 11px; border-radius: 999px;
  border: 1px solid var(--line); background: #fff; color: var(--text);
  text-decoration: none; white-space: nowrap;
}
.filter-bar .fb-chip:hover { border-color: var(--brand); color: var(--brand); text-decoration: none; }
.filter-bar .fb-chip.active { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }
.filter-bar .fb-cur { color: var(--muted); margin-left: auto; }
.filter-bar .fb-cur b { color: var(--text); }
.filter-bar .fb-clear { color: var(--danger); white-space: nowrap; }

/* ---------- v0.6.3：「我的」口径说明（可见范围） ----------
   背景（2026-10-04 用户拍板）：销售=所属工作皆可见；后续岗位=所属项目相关皆可见。
   落实为按**项目**横向展开，不是「只看我登记的」。

   于是页面上出现两套「我的」：
     · 节点两张卡（我的逾期节点 / 我的节点完成）→ 岗位责任 ∪ 划拨到我
     · 问题两张卡（我的未闭合问题 / 我可见项目）→ 我可见范围（我所属项目）
   都叫「我的」但口径不同，是最容易误读的地方 —— 所以卡区 hint、卡片 title、
   筛选条下方各写明一次。文案唯一实现在 lib/scope.js 的 scopeNote()，别在页面里手写。 */
.my-card > .card-head { flex-wrap: wrap; }
.my-card > .card-head .hint { text-align: right; line-height: 1.5; white-space: normal; }
.fb-scope { margin: -8px 0 14px; }

/* ============================================================
   v0.6.4 通用记录详情页 + 证据上传 + 竣工资料按阶段成册
   ------------------------------------------------------------
   本轮解决三件「点不进去 / 传不上去 / 找不到」的事：
     ① 列表里的业务编号与名称 → 通用只读详情页（原先根本没有查看页）
     ② 每条记录详情页都有**证据上传入口**（所有模块同一套面板）
     ③ 竣工资料按阶段（节点）成卷，应有文件 vs 实有文件对照
   新增类：.dt-* 详情页 / .att-* 证据面板 / .ds-* 竣工册
   ============================================================ */

/* ---------- 通用小工具 ---------- */
.mono { font-family: ui-monospace, Consolas, "Courier New", monospace; font-size: 11.5px; letter-spacing: .2px; }
.muted { color: var(--muted-2); }
a.cell-link { color: var(--brand); font-weight: 600; }
a.cell-link:hover { text-decoration: underline; }

/* ---------- 列表：可点单元格 ---------- */
td > a.cell-link + .sub-note { margin-top: 2px; }

/* ---------- 详情页 ---------- */
.dt-no {
  display: inline-block; padding: 1px 9px; margin-right: 8px;
  border: 1px solid var(--brand); border-radius: 999px;
  background: var(--brand-050); color: var(--brand);
  font-size: 13px; font-weight: 700; letter-spacing: .3px;
  font-family: ui-monospace, Consolas, monospace;
}
.dt-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px; margin: 0; padding: 0;
  background: var(--line-soft); border: 1px solid var(--line-soft); border-radius: 8px;
  overflow: hidden;
}
.dt-cell { background: var(--card); padding: 10px 14px; min-width: 0; }
.dt-cell.wide { grid-column: 1 / -1; }
.dt-cell dt {
  margin: 0 0 3px; color: var(--muted); font-size: 12px; font-weight: 600;
}
.dt-cell dd { margin: 0; font-size: 13.5px; word-break: break-word; }
.dt-area { white-space: pre-wrap; }
.dt-hint { margin-top: 4px; color: var(--muted-2); font-size: 11.5px; line-height: 1.5; }
.dt-meta {
  margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line);
  display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 12px; color: var(--muted);
}
.dt-meta-item b { color: var(--text); font-weight: 600; }
.dt-legend {
  margin: 14px 0 0; padding: 10px 14px;
  background: var(--brand-050); border: 1px dashed var(--brand-100);
  border-radius: var(--radius); color: var(--muted); font-size: 12.5px; line-height: 1.7;
}

/* ---------- 证据 / 附件面板（所有模块共用同一套） ---------- */
.att-wrap { border: 0; }
.att-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.att-head h3 { margin: 0; font-size: 15px; }
.att-form {
  margin: 0 0 14px; padding: 14px;
  background: var(--brand-050); border: 1px solid var(--brand-100); border-radius: var(--radius);
}
.att-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.att-cell { min-width: 0; }
.att-cell.wide { grid-column: 1 / -1; }
.att-cell label { display: block; margin-bottom: 4px; color: var(--muted); font-size: 12px; font-weight: 600; }
.att-cell label .hint { font-weight: 400; }
.att-cell input[type=text], .att-cell select { width: 100%; }
.att-cell input[type=file] {
  width: 100%; padding: 8px; background: #fff;
  border: 1px dashed var(--brand-100); border-radius: 8px; font-size: 12.5px;
}
.att-act { display: flex; align-items: center; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.att-empty {
  padding: 18px 16px; text-align: center; color: var(--muted);
  background: var(--line-soft); border-radius: var(--radius); font-size: 13px;
}
.att-empty .hint { margin-top: 6px; }
.att-tbl td { vertical-align: top; }
.att-noent { color: var(--muted-2); }
.att-legend {
  margin-top: 10px; color: var(--muted-2); font-size: 11.5px; line-height: 1.7;
}
.att-legend code {
  background: var(--line-soft); padding: 0 4px; border-radius: 3px;
  font-family: ui-monospace, Consolas, monospace; font-size: 11px;
}
.att-mini .att-head h3 { font-size: 13.5px; }
/* v0.9.0 版本链：历史版灰显（但必须看得见 —— 不是删除） */
.att-hist td { background: color-mix(in srgb, var(--muted) 4%, #fff); color: var(--muted); }
.att-hist .att-noent { color: var(--muted); }
.att-sup {
  display: inline-block; margin-left: 4px; padding: 0 5px; border-radius: 3px;
  background: color-mix(in srgb, var(--muted) 14%, #fff); color: var(--muted);
  font-size: 11px; border: 1px solid var(--line);
}

/* ---------- 竣工资料（按阶段成册） ---------- */
.ds-head {
  display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
  padding: 16px 18px; margin-bottom: 14px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.ds-head h2 { margin: 0 0 4px; font-size: 19px; }
.ds-head .sub { color: var(--muted); font-size: 12.5px; }
.ds-preview {
  padding: 3px 12px; border-radius: 999px; font-size: 12px; font-weight: 600;
  background: color-mix(in srgb, var(--warn) 14%, #fff); color: #92400e;
  border: 1px solid color-mix(in srgb, var(--warn) 40%, #fff);
}
.ds-summary {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
  gap: 10px; margin-bottom: 16px;
}
.ds-sum-item {
  padding: 10px 14px; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.ds-sum-item .k { color: var(--muted); font-size: 12px; }
.ds-sum-item .v { font-size: 20px; font-weight: 700; }
.ds-sum-item .v small { font-size: 13px; font-weight: 400; color: var(--muted); }
.ds-sum-item.bad .v { color: var(--danger); }
.ds-sum-item.good .v { color: var(--ok); }

.ds-vol {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); margin-bottom: 12px; overflow: hidden;
}
.ds-vol-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 11px 16px; background: var(--line-soft); border-bottom: 1px solid var(--line);
}
.ds-vol-head .no {
  display: inline-block; min-width: 30px; text-align: center;
  padding: 1px 8px; border-radius: 6px; background: var(--brand); color: #fff;
  font-size: 13px; font-weight: 700; font-family: ui-monospace, Consolas, monospace;
}
.ds-vol-head .nm { font-size: 15px; font-weight: 600; }
.ds-vol-head .spacer { flex: 1 1 auto; }
.ds-vol-body { padding: 12px 16px 14px; }
.ds-meta {
  display: flex; flex-wrap: wrap; gap: 4px 18px;
  margin: 0 0 12px; padding-bottom: 10px; border-bottom: 1px dashed var(--line);
  font-size: 12px; color: var(--muted);
}
.ds-meta b { color: var(--text); font-weight: 600; }
.ds-sec { margin: 0 0 10px; }
.ds-sec > .t {
  font-size: 12px; font-weight: 700; color: var(--muted); margin-bottom: 6px;
}
.ds-need {
  padding: 9px 12px; border-radius: 8px; font-size: 12.5px; line-height: 1.7;
  background: color-mix(in srgb, var(--info) 7%, #fff);
  border: 1px solid color-mix(in srgb, var(--info) 22%, #fff);
}
.ds-missing {
  margin-top: 8px; padding: 9px 12px; border-radius: 8px; font-size: 12.5px; font-weight: 600;
  background: color-mix(in srgb, var(--danger) 8%, #fff);
  border: 1px solid color-mix(in srgb, var(--danger) 30%, #fff);
  color: #991b1b;
}
.ds-ok-line {
  margin-top: 8px; padding: 8px 12px; border-radius: 8px; font-size: 12.5px;
  background: color-mix(in srgb, var(--ok) 8%, #fff);
  border: 1px solid color-mix(in srgb, var(--ok) 28%, #fff);
  color: #065f46; font-weight: 600;
}
.ds-empty { color: var(--muted-2); font-size: 12.5px; padding: 6px 0; }
.ds-tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.ds-tbl th, .ds-tbl td { padding: 6px 8px; border-bottom: 1px solid var(--line-soft); text-align: left; }
.ds-tbl th { color: var(--muted); font-weight: 600; background: transparent; }
.ds-tbl td.num { text-align: right; font-family: ui-monospace, Consolas, monospace; }
.ds-vol.unfinished { border-left: 3px solid var(--line); }
.ds-vol.unfinished .ds-vol-head .no { background: var(--muted-2); }
.ds-legend {
  margin-top: 16px; padding: 12px 16px; font-size: 12px; line-height: 1.8;
  background: var(--brand-050); border: 1px dashed var(--brand-100); border-radius: var(--radius);
  color: var(--muted);
}
.ds-sign {
  margin-top: 22px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;
  font-size: 12.5px; color: var(--muted);
}
.ds-sign .line { margin-top: 34px; border-top: 1px solid var(--line); padding-top: 4px; }

/* ---------- 文件版本链（v0.9.0）---------- */
.vn-box { border-bottom: 1px solid var(--line-soft); background: var(--brand-050); }
.vn-summary {
  cursor: pointer; padding: 9px 12px; font-size: 13px; font-weight: 600; color: var(--brand);
  list-style: none;
}
.vn-summary::-webkit-details-marker { display: none; }
.vn-summary:before { content: '▸ '; }
.vn-box[open] .vn-summary:before { content: '▾ '; }
.vn-form { padding: 4px 12px 12px; }
.vn-grid { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.vn-cell { display: flex; flex-direction: column; gap: 4px; }
.vn-cell.wide { flex: 1 1 320px; }
.vn-cell label { font-size: 12.5px; font-weight: 600; }
.vn-note { margin-top: 8px; font-size: 12.5px; color: var(--muted); }
.vn-cur { background: var(--brand-050); }
.vn-old td { color: var(--muted); }

/* ---------- 竣工文件整理（v0.9.0）---------- */
/* 归档进度条（项目一览页） */
.dz-bar {
  display: inline-block; width: 76px; height: 6px; border-radius: 3px;
  background: var(--line); vertical-align: middle; overflow: hidden;
}
.dz-bar i { display: block; height: 100%; background: var(--ok); }
.dz-bar-n { font-size: 12px; color: var(--muted); margin-left: 6px; }

/* 一卷 */
.dz-vol { margin-bottom: 14px; }
.dz-vol-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 9px 12px; background: var(--brand-050);
  border-bottom: 1px solid var(--line);
  border-radius: var(--radius) var(--radius) 0 0;
}
.dz-vol-head .no {
  display: inline-block; min-width: 28px; text-align: center;
  background: var(--brand); color: #fff; border-radius: 4px;
  font-weight: 700; font-size: 12px; padding: 2px 6px;
}
.dz-vol-head .nm { font-weight: 700; }
.dz-spacer { flex: 1 1 auto; }
.dz-cnt { font-size: 12.5px; color: var(--muted); }
.dz-cnt.good { color: var(--ok); font-weight: 700; }
.dz-cnt.bad { color: var(--danger); font-weight: 700; }

.dz-vol.dz-missing { border: 1px solid color-mix(in srgb, var(--danger) 35%, var(--line)); }
.dz-vol.dz-missing .dz-vol-head { background: color-mix(in srgb, var(--danger) 8%, #fff); }

.dz-need {
  padding: 8px 12px; font-size: 12.5px;
  background: var(--card); border-bottom: 1px solid var(--line-soft);
}
.dz-meta { color: var(--muted); margin-left: 10px; }
.dz-empty { padding: 18px 12px; color: var(--muted); font-size: 13px; text-align: center; }

/* 件 / 版本行 */
.dz-tbl td { vertical-align: middle; }
.dz-item.dz-hist { background: color-mix(in srgb, var(--muted) 4%, #fff); }
.dz-item.dz-hist td { color: var(--muted); }
.dz-no { border-right: 1px solid var(--line-soft); }
.dz-item-no {
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 12px; font-weight: 700; color: var(--brand);
}

/* 底部保存条 */
.dz-actions {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; margin-top: 6px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.dz-actions-info { flex: 1; font-size: 12.5px; color: var(--muted); }

/* ---------- 打印（竣工资料 / 详情页另存 PDF） ---------- */
@media print {
  .sidebar, .topbar, .page-head .btn, .btn, .att-form, .filter-bar,
  .att-toggle, .ds-no-print, button, .sidebar-toggle { display: none !important; }
  /* 竣工整理页的勾选框与底部保存条不进打印件 */
  .dz-actions, .dz-tbl thead th:nth-child(2), .dz-tbl tbody td:nth-child(2) { display: none !important; }
  html, body { background: #fff !important; font-size: 12px; }
  .layout { display: block !important; }
  .main { padding: 0 !important; margin: 0 !important; }
  .card, .ds-vol, .ds-head, .ds-sum-item {
    box-shadow: none !important; break-inside: avoid; page-break-inside: avoid;
  }
  .ds-vol { border: 1px solid #999 !important; }
  .ds-vol-head { background: #f2f2f2 !important; }
  a { color: #000 !important; text-decoration: none !important; }
  .ds-vol { page-break-after: auto; }
  @page { margin: 14mm 12mm; }
}

/* ============================================================
   v0.10.0 · 租户管理 + 租户内团队管理
   ============================================================ */

/* ---------- 登录页：企业级闸门提示 ----------
   与「账号或密码错误」在视觉上明确区分：这是「你没错，是这家企业进不来」，
   免得用户以为密码记错了，然后一直重试、一直找管理员重置密码。 */
.login-blocked {
  display: flex; gap: 10px; align-items: flex-start;
  margin: 0 0 14px; padding: 11px 13px;
  background: #fef2f2; border: 1px solid #fecaca; border-left: 4px solid var(--danger);
  border-radius: 8px; font-size: 12.5px; line-height: 1.7; color: #991b1b;
  text-align: left;
}
.login-blocked .lb-ico {
  flex: none; width: 18px; height: 18px; margin-top: 1px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--danger); color: #fff; border-radius: 50%;
  font-size: 12px; font-weight: 700;
}
.login-blocked .lb-txt b { display: block; margin-bottom: 2px; font-size: 13px; }

/* ---------- 全站告警条（宽限期 / 即将到期） ---------- */
.gate-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 20px; font-size: 12.5px; line-height: 1.6;
  background: #fffbeb; color: #92400e; border-bottom: 1px solid #fde68a;
}
.gate-bar.danger { background: #fef2f2; color: #991b1b; border-bottom-color: #fecaca; }
.gate-bar .gb-tag {
  flex: none; padding: 1px 7px; border-radius: 999px;
  background: var(--warn); color: #fff; font-size: 11.5px; font-weight: 600;
}
.gate-bar.danger .gb-tag { background: var(--danger); }
.gate-bar .gb-sp { flex: 1; }

/* ---------- 排障模式红条（平台管理员进入某租户时） ---------- */
.imp-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 20px; font-size: 12.5px; line-height: 1.6;
  background: #7f1d1d; color: #fff;
}
.imp-bar .ib-tag {
  flex: none; padding: 1px 8px; border-radius: 999px;
  background: #fff; color: #7f1d1d; font-size: 11.5px; font-weight: 700;
}
.imp-bar .ib-sp { flex: 1; }
.imp-bar form { margin: 0; }
.imp-bar button {
  background: rgba(255, 255, 255, .16); color: #fff;
  border: 1px solid rgba(255, 255, 255, .5); border-radius: 6px;
  padding: 3px 10px; font-size: 12px; cursor: pointer; font-family: inherit;
}
.imp-bar button:hover { background: rgba(255, 255, 255, .28); }

/* ---------- 组织架构：成员行 + 「管理」折叠面板 ---------- */
/* 行内要能塞下「管理」面板，故允许换行；面板展开时独占整行（flex-basis:100%）。 */
.org-leaf { flex-wrap: wrap; }
.org-leaf.is-lead { background: #fbfdff; }
.org-leaf .leaf-name { font-weight: 600; }

.row-edit > summary { list-style: none; cursor: pointer; user-select: none; }
.row-edit > summary::-webkit-details-marker { display: none; }
.row-edit[open] { flex-basis: 100%; }
.row-edit-panel {
  margin: 8px 0 4px; padding: 12px 14px;
  background: #fafcff; border: 1px solid var(--line-soft);
  border-left: 3px solid var(--brand); border-radius: 8px;
}
.re-form { margin: 0; }
.re-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); gap: 10px 14px; }
.re-grid label { display: flex; flex-direction: column; gap: 3px; font-size: 11.5px; color: var(--muted); }
.re-grid input, .re-grid select { font-size: 12.5px; }
.re-actions { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.re-side {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line-soft);
}
.re-inline { display: flex; gap: 6px; margin: 0; align-items: center; }
.re-inline input { font-size: 12.5px; }
.re-sub { font-size: 12px; font-weight: 600; margin-bottom: 6px; color: var(--muted); }
.re-members { margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--line-soft); }

/* 团队成员勾选器：成员多时内部滚动，不把卡片撑成一条长龙 */
.mem-picker {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(155px, 100%), 1fr));
  gap: 4px 12px; max-height: 210px; overflow-y: auto;
  padding: 8px 10px; background: #fff;
  border: 1px solid var(--line-soft); border-radius: 8px;
}
.mem-item { display: flex; align-items: center; gap: 5px; font-size: 12.5px; }
.mem-item input { margin: 0; }

.btn.danger { background: #fdeceb; border-color: #f7cbc8; color: #b32a25; }
.btn.danger:hover { background: #fbdad7; }

/* ---------- 编制与席位总览表 ---------- */
.cap-bar {
  height: 6px; border-radius: 999px; background: var(--line-soft);
  overflow: hidden; margin-bottom: 5px; min-width: 90px;
}
.cap-bar i { display: block; height: 100%; background: var(--brand); }
tr.cap-total td { background: #f7f9fc; }

/* ---------- 团队字典 ---------- */
.team-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: 14px; }
.team-card { border: 1px solid var(--line-soft); border-radius: 10px; padding: 12px 14px; background: #fff; }
.team-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.team-head .spacer { flex: 1; }
.team-code {
  font-family: monospace; font-size: 11.5px; padding: 1px 6px;
  border-radius: 5px; background: var(--brand-050); color: var(--brand-700);
}
.team-meta { margin: 6px 0 8px; }
.team-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip { font-size: 11.5px; padding: 1px 8px; border-radius: 999px; background: #f1f3f6; color: #5b6675; }
.chip.chip-lead { background: var(--brand-100); color: var(--brand-700); font-weight: 600; }

/* ============================================================
   平台侧（跨租户后台）· v0.12.0 顶部横向导航
   —— 对齐菁筑CRM 一级管理员界面（用户 2026-10-05 拍板）

   🔴 为什么平台侧用**白底横排顶栏**，而企业侧是「深蓝顶栏 + 左侧边栏」：
      · 企业侧那个深蓝顶栏上写的是**这家企业的名字与 logo**（品牌注入），
        平台账号不归属任何企业，套上去等于给自己贴了别人家的牌子。
      · 平台侧只有 8 个运维模块，横排一行放得下；企业侧 19 个业务模块
        才需要侧边栏分组。
      · CRM 一级管理员就是白底横排 —— 用户明确要求对齐。
   ============================================================ */
.plat-bar {
  background: #fff;
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(16, 24, 40, .04);
  position: sticky; top: 0; z-index: 30;
}
.plat-inner {
  max-width: 1440px; margin: 0 auto;
  display: flex; align-items: center; gap: 2px 16px;
  padding: 0 22px; min-height: 56px; flex-wrap: wrap;
}
.plat-brand { font-size: 16px; font-weight: 700; color: var(--brand); white-space: nowrap; }
.plat-brand:hover { text-decoration: none; }
.plat-brand .pb-sub { font-size: 11.5px; font-weight: 500; color: var(--muted-2); margin-left: 7px; letter-spacing: .3px; }
.plat-nav { display: flex; align-items: center; gap: 2px 4px; flex: 1 1 auto; flex-wrap: wrap; }
.plat-nav a {
  position: relative; padding: 6px 11px; border-radius: 7px;
  font-size: 13.5px; color: #48546a; white-space: nowrap;
}
.plat-nav a:hover { background: var(--brand-050); color: var(--brand-700); text-decoration: none; }
.plat-nav a.active { color: var(--brand-700); font-weight: 600; background: var(--brand-100); }
.plat-nav a .pn-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 17px; height: 17px; padding: 0 5px; margin-left: 5px;
  border-radius: 9px; background: #ff4d4f; color: #fff;
  font-size: 11px; font-weight: 700; line-height: 17px; vertical-align: middle;
}
.plat-right { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--muted); }
.plat-right .avatar {
  width: 27px; height: 27px; border-radius: 50%;
  background: var(--brand-100); color: var(--brand-700);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
}
.plat-right .role-tag {
  font-size: 11px; padding: 3px 9px; border-radius: 999px;
  background: var(--brand-050); color: var(--brand-700);
  border: 1px solid var(--brand-100); white-space: nowrap;
}
.plat-right a { color: var(--muted); }
.plat-right a:hover { color: var(--brand-700); }

.plat-crumb {
  max-width: 1440px; margin: 0 auto; padding: 12px 22px 0;
  font-size: 12.5px; color: var(--muted-2);
}
.plat-crumb b { color: var(--muted); font-weight: 600; }
.plat-crumb .sep { margin: 0 7px; opacity: .45; }

/* flex:1 0 auto —— 内容不足一屏时由它吃掉剩余高度，把页脚顶到底部；
   否则 body 的剩余空间会落在页脚**之后**，页脚就浮在页面中间（实测扩容申请页空 93px）。

   🔴 width:100% 不能省（360px 横向溢出的真正根因，2026-10-11 实测）：
     body 是 flex column → 宽度走**交叉轴**，子项默认靠 align-items:stretch 拉伸。
     但规则里同时有 `margin: 0 auto`（为了宽屏居中）—— **交叉轴上的 auto margin 会让
     stretch 失效**，子项宽度退化成 fit-content；平台首页欢迎语一行宽 374px > 360px，
     于是 main 被撑到 374、横向溢出 14px。
     `flex-shrink` 管的是**主轴（高度）**，`min-width` 管的是下限 —— 两者都不是本案病根，
     只加 `min-width:0` 实测无效（已证伪）。显式给 `width:100%` 才能让它在窄屏收缩到容器宽。
     宽屏不受影响：width:100% 被 max-width:1440px 截断，margin:auto 照常居中。 */
.plat-main {
  flex: 1 0 auto; width: 100%; max-width: 1440px; margin: 0 auto;
  padding: 14px 22px 40px;
}

/* ---------- 全站页脚：版权 + ICP 备案号 ----------
   唯一来源 = partials/site-foot.ejs（所有页面经 partials/foot.ejs 引入）。
   原 .plat-foot 已随「平台侧独立页脚」一并撤销，样式收敛到这里。 */
.site-foot {
  flex: 0 0 auto;
  max-width: 1440px; margin: 28px auto 0; padding: 18px 22px 28px;
  border-top: 1px solid var(--line-soft);
  text-align: center; color: var(--muted-2); font-size: 12px; line-height: 1.9;
}
.site-foot a { color: var(--muted-2); }
.site-foot a:hover { color: var(--muted); text-decoration: none; }
.site-foot .sf-ver { opacity: .8; font-size: 11.5px; }

/* 平台侧窄屏：横排菜单换行后仍可点，不出现横向溢出 */
@media (max-width: 720px) {
  .plat-inner { padding: 8px 14px; gap: 4px 10px; }
  .plat-nav { width: 100%; }
  .plat-main, .plat-crumb, .site-foot { padding-left: 14px; padding-right: 14px; }
}

/* ---------- 平台首页（对齐 CRM 一级管理员首页） ---------- */
.hero {
  border-radius: 14px; padding: 30px 32px;
  background: linear-gradient(135deg, #2f6fd0 0%, #1f4e79 55%, #16395a 100%);
  color: #fff; display: flex; align-items: center; gap: 28px;
  box-shadow: 0 6px 22px rgba(31, 78, 121, .18);
}
.hero .h-main { flex: 1 1 auto; min-width: 0; }
.hero .h-hi { font-size: 13.5px; color: rgba(255, 255, 255, .84); }
.hero .h-title { margin: 9px 0 0; font-size: 26px; font-weight: 700; letter-spacing: .5px; }
.hero .h-desc { margin: 12px 0 0; font-size: 14px; line-height: 1.85; color: rgba(255, 255, 255, .9); max-width: 740px; }
.hero .h-slogan { margin: 17px 0 0; font-size: 18.5px; font-weight: 600; letter-spacing: .12em; }
.hero .h-meta { margin-top: 19px; font-size: 11.5px; color: rgba(255, 255, 255, .72); }
.hero .h-badge { flex: 0 0 auto; align-self: center; }
.hero .h-badge img { width: 148px; height: auto; display: block; opacity: .95; }
@media (max-width: 760px) { .hero { flex-direction: column; align-items: flex-start; } .hero .h-badge img { width: 110px; } }

.sec-title { font-size: 16.5px; font-weight: 700; margin: 26px 0 12px; }
.start-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(262px, 100%), 1fr)); gap: 12px; }
a.start-card {
  position: relative; display: block;
  background: var(--card); border: 1px solid var(--line); border-radius: 11px;
  padding: 15px 17px; box-shadow: var(--shadow);
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
a.start-card:hover {
  text-decoration: none; border-color: var(--brand);
  box-shadow: 0 4px 16px rgba(31, 78, 121, .13); transform: translateY(-1px);
}
.start-card .sc-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.start-card .sc-title { font-size: 14.5px; font-weight: 600; color: var(--text); }
.start-card .sc-arrow { color: var(--muted-2); }
.start-card:hover .sc-title { color: var(--brand-700); }
.start-card .sc-desc { margin-top: 5px; font-size: 12.5px; color: var(--muted); line-height: 1.7; }
.start-card.hot .sc-title, .start-card.hot .sc-desc { color: #c0392b; }
.start-card.hot .sc-desc { font-weight: 500; }
.start-card .sc-badge {
  position: absolute; top: -8px; right: -8px;
  min-width: 22px; height: 22px; padding: 0 6px;
  border-radius: 11px; background: #ff4d4f; color: #fff;
  font-size: 12px; font-weight: 700; line-height: 22px; text-align: center;
  box-shadow: 0 2px 6px rgba(255, 77, 79, .4);
}

.tips-box { background: var(--card); border: 1px solid var(--line); border-radius: 11px; padding: 19px 22px; box-shadow: var(--shadow); }
.tips-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 14px; }
.tip-item { border-left: 4px solid var(--brand-100); padding: 3px 0 3px 14px; }
.tip-item .t-name { font-size: 13.5px; font-weight: 600; color: #46536a; }
.tip-item .t-text { margin-top: 4px; font-size: 12.5px; color: var(--muted); line-height: 1.75; }

/* ============================================================
   样板文件库（v0.13.0）
   12 份节点工作空白表格的卡片网格。

   🔴 为什么不复用 .start-grid / .start-card：
      那是「点一下跳转」的导航卡（整卡是一个 <a>），这是「带下载按钮」的资料卡，
      卡内还有「对应节点 / 责任岗位 / 关键栏位」三类信息。
      硬套会出现「整卡看着可点、点下去其实是下载」的语义错位。
      网格参数保持一致（300px 起）以便两处观感统一。
   ============================================================ */
.tpl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: 12px; }
.tpl-card {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--card); border: 1px solid var(--line); border-radius: 11px;
  padding: 14px 16px; box-shadow: var(--shadow);
  transition: border-color .15s, box-shadow .15s;
}
.tpl-card:hover { border-color: var(--brand); box-shadow: 0 4px 16px rgba(31, 78, 121, .13); }
/* 文件没生成出来的那份：虚线框 + 降透明度，一眼能从一片卡里挑出来 */
.tpl-card.tpl-miss { opacity: .72; border-style: dashed; }

.tpl-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tpl-code {
  display: inline-block; padding: 1px 8px; border-radius: 5px;
  background: var(--brand); color: #fff;
  font-size: 12px; font-weight: 700; letter-spacing: .5px;
}
.tpl-node { font-size: 12px; color: var(--muted-2); }
.tpl-name { font-size: 14.5px; font-weight: 600; color: var(--text); line-height: 1.45; }
.tpl-brief { font-size: 12.5px; color: var(--muted); line-height: 1.75; }

.tpl-fields { display: flex; flex-wrap: wrap; gap: 5px; }
.tpl-tag {
  font-size: 11.5px; padding: 1px 7px; border-radius: 4px;
  background: #eef4fb; color: #22507f; border: 1px solid #cfe0f2;
}

.tpl-foot {
  display: flex; align-items: center; gap: 10px;
  margin-top: auto; padding-top: 8px;
  border-top: 1px dashed var(--line-soft);
}
.tpl-owner { flex: 1; font-size: 12px; color: var(--muted-2); }

@media (max-width: 720px) {
  .tpl-grid { grid-template-columns: 1fr; }
}

/* ---------- v0.14.0：项目管理「八域矩阵」 ---------- */
/* 行 = 项目；列 = 合同管理 / 设计管理 / 施工管理 / 文件管理 / 安全管理 / 进度控制 / 质量控制 / 造价控制
   每格 = 状态点 + 主值 + 副注，两行合一：比"一列一个裸数字"可读，也把八个域压进一屏。
   🔴 table-layout:fixed + 固定列宽 —— 用 auto 布局时 td 的宽度只是"建议值"，
      长节点名会把整列撑开、把矩阵挤爆（试过，第 2 列一长整张表就横向溢出）。
      固定布局下超长文本走 ellipsis，鼠标悬停看 title 里的完整内容。
   🔴 窄屏不重排、改为横向滚动（.card > .card-body.p0 自带 overflow-x:auto）。
      八列一列都不能少，折行会读不出"横向对比"的意思。 */
/* 🔴 列宽是量出来的，不是估的：`.dm-main` 的可用宽度 = 列宽 − td 内边距 − 链接内边距。
      实测 104px 列 + 6px/6px 内边距时只剩 80px，
      「毛利 21.7%」(含状态点 82px) 与「03 技术要求确认」(86px) 两处会被 ellipsis 吃掉 →
      列宽提到 108px、内边距收到 4px/5px，可用宽度 90px，两处都有余量。
      用工具脚本 _probe_trunc.js 量过：主值截断 0 格、副注截断 0 格。 */
.dom-matrix { table-layout: fixed; min-width: 1140px; }
.dom-matrix th:nth-child(1) { width: 78px; }
.dom-matrix th:nth-child(2) { width: auto; }        /* 项目名称吃掉剩余宽度（1440 下实测 196px） */
.dom-matrix th.dm-th { width: 106px; text-align: center; font-size: 12.5px; white-space: nowrap; }
.dom-matrix th.dm-op { width: 60px; }
.dom-matrix td.dm-cell { padding: 6px 4px; vertical-align: middle; }
.dom-matrix td.dm-op { text-align: center; }
/* 项目名是最长的一串（「都江堰某食品厂厂房改造工程」13 字），13px 在 172px 里会折成
   「…改造工 / 程」—— 第二行只剩一个孤字。降到 12.5px 让 13 字的项目一行放下；
   再长的（如 14 字的「成都某科技公司办公楼装修工程」）用 text-wrap:balance
   折成两行等长，而不是「…装修工 / 程」这种孤字尾行。 */
.dm-proj a.cell-link { display: block; font-size: 12.5px; text-wrap: balance; }
.dm-meta {
  display: flex; align-items: center; gap: 6px; margin-top: 3px;
  font-size: 11px; color: var(--muted-2); white-space: nowrap;
}

.dm-link {
  display: block; padding: 5px 5px; border-radius: 7px;
  overflow: hidden; text-decoration: none; line-height: 1.35;
}
.dm-link:hover { background: var(--brand-050); text-decoration: none; }
.dm-main {
  display: block; font-size: 13px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dm-link i {
  display: block; font-style: normal; font-size: 11.5px; color: var(--muted); margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dm-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-right: 5px; vertical-align: 1px;
}

.dm-ok     .dm-dot { background: #2f9e6e; } .dm-ok     .dm-main { color: #1f7a53; }
.dm-info   .dm-dot { background: #3b82c4; } .dm-info   .dm-main { color: #22507f; }
.dm-warn   .dm-dot { background: #d9930a; } .dm-warn   .dm-main { color: #91590a; }
.dm-danger .dm-dot { background: #d9534f; } .dm-danger .dm-main { color: #b03b37; }
.dm-gray   .dm-dot { background: #c3cad3; } .dm-gray   .dm-main { color: #8a93a0; font-weight: 500; }

.dom-legend {
  margin-top: 14px; padding: 12px 16px;
  border: 1px solid #d6e4f0; border-radius: 10px; background: #f4f8fc;
  font-size: 12.5px; line-height: 1.8; color: #38485a;
}
.dom-legend b { color: var(--text); }
.dom-legend b.dl-warn { color: #91590a; }

/* ================= 说明区「一行一条」通用版式（v0.18.0）=================
   全站说明区共用**一套**结构，不在各页、各类名里重复实现
   （重复实现必然漂移 —— 与技能里「同一件事两套 SQL ⇒ 一个对了另一个静默退化」同族）。

   用法（任何说明容器，class 名随意）：
     <div class="xx-legend">
       <div class="lg-head">一句话标题</div>
       <ul class="lg-rows">
         <li>条目一</li>
         <li class="lg-warn">要警示的条目
           <div class="lg-sub">从属说明（缩进挂在**所属那一条内部**，别飘到段尾）</div>
         </li>
       </ul>
       <div class="lg-foot">结尾说明（自动虚线分隔）</div>
     </div>

   🔴 圆点用 `currentColor` + 半透明 → **自动跟随容器文字色**，
      于是一套样式能适配灰底 / 白底 / 橙底 / 深底等各种说明容器，无需逐个重写。
   `.dl-*` 是 v0.17.1 项目页先用上的旧名，与 `.lg-*` **共用同一组选择器**
   （一套实现、两个名字；上轮验证脚本按 `.dl-rows > li` 取元素仍可选中）。
   ====================================================================== */
.lg-head, .dl-head { line-height: 1.8; }
.lg-grp, .dl-grp {
  margin-top: 11px; padding-top: 9px;
  border-top: 1px dashed rgba(0, 0, 0, .10);
  font-weight: 600; line-height: 1.8;
}
.lg-rows, .dl-rows { margin: 8px 0 0; padding: 0; list-style: none; }
.lg-rows > li, .dl-rows > li { position: relative; padding: 3px 0 3px 15px; line-height: 1.75; }
.lg-rows > li::before, .dl-rows > li::before {
  content: ''; position: absolute; left: 3px; top: 10px;
  width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; opacity: .45;
}
.lg-rows > li.lg-warn, .dl-rows > li.dl-warn { color: #91590a; }
.lg-rows > li.lg-warn::before, .dl-rows > li.dl-warn::before { background: #d9930a; opacity: 1; }
.lg-rows > li.lg-warn > b, .dl-rows > li.dl-warn > b { color: #91590a; }
.lg-sub, .dl-sub {
  margin-top: 5px; padding: 6px 10px;
  border-left: 3px solid #e0a83a; border-radius: 0 6px 6px 0;
  background: #fdf6e6; color: #91590a; line-height: 1.7;
}
.lg-sub b, .dl-sub b { color: #8a5308; }
/* 步骤型说明（①②③④ 本来就该有序号）—— 用 ol，别再手打圈码 + <br> */
.lg-steps, .dl-steps { margin: 8px 0 0; padding-left: 26px; line-height: 1.75; }
.lg-steps > li, .dl-steps > li { padding: 3px 0; }
.lg-steps > li::marker, .dl-steps > li::marker { font-weight: 600; opacity: .7; }
.lg-foot, .dl-foot {
  margin-top: 9px; padding-top: 9px;
  border-top: 1px dashed rgba(0, 0, 0, .12); line-height: 1.8;
}


/* ================= 协作单位会签（v0.16.0）=================
   用户 2026-10-05：「节点 1~13，都应该有协作单位的意见，全部协作单位都需要
   确认闭环才能进入下一节点。」本节样式服务两处：
     · 台账 / 详情页的「还不能确认完成」提示（.nd-blocked）
     · 节点详情页的会签面板（.so-*） */

/* <a class="tag"> 默认会带下划线 —— 会签进度 tag 是可点入口，去掉它更像标签 */
a.tag { text-decoration: none; }
a.tag:hover { text-decoration: none; filter: brightness(.96); }

.nd-blocked {
  display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 11.5px;
  color: #91590a; background: #fef4e6; border: 1px dashed #f0cf9a;
  text-decoration: none; white-space: nowrap; cursor: help;
}
.nd-blocked:hover { background: #fdecd3; text-decoration: none; }
.nd-legend-hit { color: var(--brand); }

.so-list { display: grid; gap: 10px; }
.so-item {
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 13px;
  background: var(--card);
}
.so-item.so-todo { border-left: 3px solid var(--warn); }
.so-item.so-done { border-left: 3px solid var(--ok); }
.so-item.so-mine { background: #f7fbff; box-shadow: inset 0 0 0 1px #cfe4ff; }

.so-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.so-role { font-weight: 600; font-size: 13.5px; }

.so-note {
  margin-top: 7px; padding: 7px 10px; border-radius: 7px; background: #f6f8fa;
  font-size: 12.5px; line-height: 1.65; white-space: pre-wrap;
  word-break: break-word; color: var(--text);
}
.so-files { margin-top: 7px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.so-form { margin-top: 9px; }
.so-form textarea {
  width: 100%; display: block; border: 1px solid var(--line); border-radius: 7px;
  padding: 7px 10px; font: inherit; font-size: 12.5px; resize: vertical;
  color: var(--text); background: #fff;
}
.so-form textarea:focus { outline: none; border-color: var(--brand); }
.so-row { display: flex; align-items: center; gap: 10px; margin-top: 7px; flex-wrap: wrap; }
.so-file { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); }
.so-file input[type=file] { font-size: 11.5px; }
.so-mini { margin-top: 6px; }

.so-legend {
  margin-top: 12px; padding: 10px 13px; border-radius: 8px; background: #f6f8fa;
  font-size: 11.5px; line-height: 1.8; color: #57606a;
}
.so-legend b { color: var(--text); }

/* ==========================================================================
   v0.17.0 进度基线（baseline）· 偏差（deviation）· 时间轴（甘特）
   --------------------------------------------------------------------------
   全部纯 HTML/CSS，不引第三方图表库 —— 离线包不变大、打印友好。
   🔴 偏差的"值"由 lib/plan.js 算好，这里只负责"长什么样"。
   ========================================================================== */

/* ---- 偏差徽标 ---- */
.dev {
  display: inline-block; font-size: 11.5px; line-height: 1.7; padding: 1px 8px;
  border-radius: 999px; border: 1px solid; font-weight: 600; white-space: nowrap;
}
.dev-late   { color: #b42318; background: #fef3f2; border-color: #fbd3cf; }
.dev-early  { color: #0f6b3f; background: #eefaf3; border-color: #c3e8d3; }
.dev-ontime { color: #0f6b3f; background: #eefaf3; border-color: #c3e8d3; }
.dev-pending{ color: #1f4e79; background: #eef4fa; border-color: #cfe0ef; }
.dev-none   { color: #6b7280; background: #f4f6f8; border-color: var(--line); }

/* ---- 基线控件（共享 partial _baseline-ctl.ejs）---- */
.base-ctl { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; width: 100%; }
.base-state { font-size: 11.5px; font-weight: 700; padding: 2px 10px; border-radius: 999px; border: 1px solid; }
.base-state.on  { color: #0f6b3f; background: #eefaf3; border-color: #c3e8d3; }
.base-state.off { color: #8a5a00; background: #fff8e6; border-color: #f3e0b0; }
.base-form { display: inline-flex; align-items: center; gap: 6px; }
.base-change { display: inline-block; }
.base-change > summary { cursor: pointer; list-style: none; }
.base-change > summary::-webkit-details-marker { display: none; }
.base-change > form {
  position: absolute; right: 18px; z-index: 6; margin-top: 6px; min-width: 320px;
  background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 11px 12px;
  box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 7px;
}
.base-change > form input[type=text] { width: 100%; }
.base-note { font-size: 11px; color: var(--muted-2); }
.base-moved { color: #8a5a00; }

/* 基准留痕（节点详情页） */
.base-note-block { margin-top: 12px; border-top: 1px dashed var(--line); padding-top: 9px; }
.base-note-head { font-size: 11.5px; color: var(--muted); margin-bottom: 5px; }
.base-note-pre {
  margin: 0; white-space: pre-wrap; font-family: inherit; font-size: 12px; line-height: 1.75;
  color: #3d4450; background: #f8fafc; border: 1px solid var(--line-soft);
  border-radius: 7px; padding: 9px 11px;
}

/* 折叠视图的项目头允许基线控件换行占满一行 */
.nd-wrap-head { flex-wrap: wrap; }

/* ---- 时间轴 ---- */
.gt-pick { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13.5px; }
.gt-pick select { min-width: 300px; }
.gt-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.gt-range { font-size: 12px; color: var(--muted); margin-top: 4px; }

.gt-wrap { min-width: 660px; }

.gt-axis, .gt-row {
  display: grid; grid-template-columns: 236px minmax(380px, 1fr);
  gap: 12px; align-items: center; padding: 6px 14px;
}
.gt-axis {
  position: sticky; top: 0; z-index: 3; background: #f8fafc;
  border-bottom: 1px solid var(--line);
}
.gt-axis-label { font-size: 11.5px; color: var(--muted); font-weight: 600; }
.gt-axis-track { position: relative; height: 18px; }
.gt-tick { position: absolute; top: 0; height: 18px; }
.gt-tick i { display: block; width: 1px; height: 18px; background: var(--line); }
.gt-tick em {
  position: absolute; left: 4px; top: 1px; font-style: normal;
  font-size: 11px; color: var(--muted-2); white-space: nowrap;
}

.gt-row { border-bottom: 1px solid var(--line-soft); }
.gt-row:hover { background: #fbfcfe; }
.gt-label { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 13px; }
.gt-code { font-weight: 600; }
.gt-name { color: var(--text); }
.gt-meta { font-size: 11.5px; color: var(--muted-2); }

.gt-track {
  position: relative; height: 26px; border-radius: 5px;
  background: linear-gradient(#fbfcfe, #f5f8fb); border: 1px solid var(--line-soft);
}
.gt-gl { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line-soft); }
.gt-today {
  position: absolute; top: -1px; bottom: -1px; width: 2px; background: #e8a33d;
  box-shadow: 0 0 0 1px rgba(232, 163, 61, .22); z-index: 1;
}
.gt-slip { position: absolute; top: 10px; height: 5px; background: #cfe0ef; border-radius: 3px; }

.gt-dot {
  position: absolute; top: 50%; transform: translate(-50%, -50%);
  width: 12px; height: 12px; border-radius: 50%; z-index: 2;
}
.gt-dot-base { background: #fff; border: 2px solid var(--brand); }
.gt-dot-plan { background: var(--brand); border: 2px solid #fff; box-shadow: 0 0 0 1px var(--brand); }
.gt-dot-act  { background: var(--ok);     border: 2px solid #fff; box-shadow: 0 0 0 1px var(--ok); }
.gt-dot-act.late { background: var(--danger); box-shadow: 0 0 0 1px var(--danger); }
.gt-dot-now  { background: #fff; border: 2px dashed var(--warn); }
.gt-dot-now.late { border-color: var(--danger); }

.gt-legend {
  margin-top: 14px; padding: 11px 14px; border-radius: 8px; background: #f6f8fa;
  font-size: 11.5px; line-height: 1.95; color: #57606a;
}
.gt-legend b { color: var(--text); }
/* 🔴 这两个是**色块示意**，宽度就是色块本身 —— 文字必须放在块**外面**。
   原先把文字塞进 span 里，被 15px / 2px 的固定宽度压成竖排（挤在一段里时不显眼，改成一行一条后才暴露）。 */
/* 🔴 v0.23.1 修正：这两个类原本**只定义色块尺寸**（width 15px / 3px），
   却被用来包文字（"浅蓝区间"/"橙色竖线"）—— 文字被塞进 15px 宽的盒子，
   只能逐字换行，页面上就出现「竖排的字」。截图证据：图例区两列竖字。
   改法：拆成 .gt-key（行内容器，正常排版） + .gt-key-slip/.gt-key-today（纯色块，空元素）。
   容器不能设固定宽度，否则同样的错会再来一次。 */
.gt-key { display: inline-flex; align-items: center; white-space: nowrap; vertical-align: middle; }
.gt-key-slip  { display: inline-block; flex: 0 0 15px; width: 15px; height: 5px; background: #cfe0ef; border-radius: 3px; margin-right: 5px; }
.gt-key-today { display: inline-block; flex: 0 0 3px;  width: 3px;  height: 13px; background: #e8a33d; vertical-align: middle; margin-right: 5px; }

/* ============================================================================
   项目节点计划时间线（节点 09 详情页，v0.19.0）
   —— 一张可增删改的节点清单：改内容 / 末尾空行新增 / 行尾按钮取消。
   零 JS：整表一个原生 form；「取消」用 <button form="..."> 关联表外小表单，
   因为 HTML 不允许 <form> 嵌套，这是在「不写脚本」前提下唯一正规的做法。
   ========================================================================== */
.np-form { margin: 0; }
.np-tbl { width: 100%; }
.np-tbl th { white-space: nowrap; }
.np-tbl td { vertical-align: middle; padding-top: 6px; padding-bottom: 6px; }

/* 行内输入控件：撑满单元格又不过分高 */
.np-in {
  width: 100%; min-width: 58px; box-sizing: border-box;
  padding: 4px 6px; font-size: 12.5px; color: var(--text);
  border: 1px solid var(--line); border-radius: 5px; background: #fff;
}
.np-in:focus { outline: 2px solid var(--brand-100); border-color: var(--brand); }
input[type=date].np-in, select.np-in { padding: 3px 4px; }

/* 只读态（无编辑权限的岗位）：排布与可编辑态一致，避免行高跳动 */
.np-ro { font-size: 12.5px; color: var(--text); }
.np-sub { font-size: 10.5px; color: var(--muted-2); margin-top: 2px; }
.np-base { font-size: 12px; color: #8a5a00; }

/* 行状态：当前节点高亮 / 已取消灰显 / 待填空白行虚线 */
.np-tbl tr.np-cur > td { background: var(--brand-050); }
.np-tbl tr.np-off > td { background: #fafafa; color: var(--muted-2); }
.np-tbl tr.np-off .np-in { background: #f6f6f6; }
.np-tbl tr.np-blank > td { background: #fcfdff; }
.np-tbl tr.np-blank .np-in { border-style: dashed; }

.np-actions {
  display: flex; align-items: center; gap: 12px;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-soft);
}
.np-actions .hint { font-size: 11.5px; line-height: 1.7; }

/* 表外小表单：只用于给按钮提供 form 归属，不占版面 */
.np-mini { display: none; }

.np-legend {
  margin-top: 12px; padding: 11px 14px; border-radius: 8px; background: #f6f8fa;
  font-size: 11.5px; line-height: 1.95; color: #57606a;
}
.np-legend b { color: var(--text); }

/* ===== 新增行的可发现性（v0.19.0 补丁）=====
   起因：用户反馈「增加不了」—— 其实新增成功了，但新行出现在表格**中段**
   （15 个标准节点之后），而用户填的空行在**底部**、底部又永远保留 3 个空行，
   保存后视线没跟上，看着像没生效。
   两道保险都是零 JS：
     ① <tr id="np-36"> + 浏览器原生锚点滚动（URL 带 #np-36）；
     ② np-new 绿框高亮 + 「刚新增」标签。 */

/* 锚点滚动时给 sticky 顶栏留出空间，否则新行会被顶栏盖住 */
tr[id^="np-"] { scroll-margin-top: 92px; }

tr.np-new > td {
  background: #eaf7ee !important;
  box-shadow: inset 0 0 0 1px #b7e0c4;
}
tr.np-new > td:first-child { border-left: 3px solid #2da44e; }

.np-newtag {
  display: inline-block; margin-left: 4px; padding: 0 4px; border-radius: 4px;
  background: #2da44e; color: #fff; font-size: 9.5px; font-weight: 600;
  vertical-align: 1px; white-space: nowrap;
}

/* 「第二步：确认为比较基准」区块 —— 与保存按钮同卡片，保存完紧接着就能锁定。
   🔴 类名用 np-basectl，**不能**用 np-base —— 那个已被「基准计划」单元格
      （第 1763 行 .np-base，棕色小字）占用。首版撞名导致 margin/padding/border
      被追加到每一格基准日期上（首跑截图断言就因此报出 16 个匹配元素）。 */
.np-basectl {
  margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line, #d8dee4);
}
.np-basectl-head {
  margin-bottom: 8px; font-size: 12px; color: #57606a; line-height: 1.8;
}
.np-basectl-head b { color: var(--text); }



