/* =============================================================
   海拆社订单管理系统 · 原型设计语言
   四条定调：高流畅度元素 · 简洁精炼风格 · 流程分界清晰 · 操作直观具体
   ============================================================= */

/* ---------- 1. 设计令牌 ---------- */
:root {
  /* 画布与面 */
  --bg:          #F5F6F8;   /* 极浅蓝白 —— 比纯白暖，久看不刺眼（🔴 随品牌蓝） */
  --surface:     #FFFFFF;
  --surface-2:   #FAFBFC;
  --surface-3:   #F2F4F7;

  /* 线（细到粗，全站只用这四级） */
  --line:        #E7E9ED;
  --line-2:      #D5D9E0;
  --line-3:      #B9BFC9;
  --line-4:      #8A91A0;

  /* 墨（文字四级，够了） */
  --ink:         #14161A;
  --ink-2:       #5B6270;
  --ink-3:       #8A91A0;
  --ink-4:       #B3B9C6;

  /* 品牌（唯一强调色，克制使用）
     🔴 **蓝是品牌色，恒定不变** —— 2026-10-17 曾为「温馨风」整体换墨绿，
        业务方拍板「保持原蓝色不变」后改回：温馨感靠**圆角 · 间距 · 渐变底 ·
        柔和阴影**这些不碰品牌色的手段做，颜色本身是品牌资产，不跟着风格走。 */
  --brand:       #2F5BE8;
  --brand-hi:    #4570F0;
  --brand-lo:    #2550D6;
  --brand-weak:  #EEF2FE;
  --brand-line:  #C6D2FB;

  /* 语义色 */
  --ok:          #0E9A55;
  --ok-weak:     #E7F6EE;
  --ok-line:     #B7E4CB;
  --warn:        #C0730A;
  --warn-weak:   #FDF3E6;
  --warn-line:   #F0D9B4;
  --danger:      #D93A3A;
  --danger-weak: #FDECEC;
  --danger-line: #F5C6C6;

  /* 流程分段专用色 —— 让「分界」有颜色语义 */
  --main:        #2F5BE8;   /* 主链 ①–⑥（🔴 随品牌蓝） */
  --main-weak:   #EEF2FE;
  --bypass:      #8A91A0;   /* 审单旁路（灰 · 不占编号） */
  --complete:    #6D5BE0;   /* 紫 · 通用辅助色（原⑦完备，已随完备期撤销转通用） */
  --complete-w:  #F0EDFC;
  --aftersale:   #0E8F8F;   /* ⑧ 售后 */
  --aftersale-w: #E4F5F5;

  /* 圆角（🔴 整体加大一档 —— 圆角越大越柔和，是「温馨感」最便宜的来源） */
  --r-xs: 6px;
  --r-sm: 9px;
  --r:    12px;
  --r-lg: 16px;
  --r-xl: 22px;

  /* 间距（4 的倍数，只有这七档） */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 24px; --s8: 32px; --s10: 40px;

  /* 动效 —— 高流畅度的全部秘密就在这三条曲线里 */
  --dur-1: 110ms;   /* 微交互：hover / 按下 / 高亮 */
  --dur-2: 200ms;   /* 常规：展开 / 滑入 / 切换 */
  --dur-3: 340ms;   /* 大动：页面 / 面板 / 弹窗 */
  --ease:   cubic-bezier(.2, .8, .2, 1);      /* 标准：快出慢入，不拖泥带水 */
  --spring: cubic-bezier(.34, 1.36, .64, 1);  /* 弹：打勾 / 弹窗 / 徽章 */
  --out:    cubic-bezier(.4, 0, .2, 1);

  /* 影（三级，克制） */
  --sh-1: 0 1px 2px rgba(18, 22, 33, .05);
  --sh-2: 0 4px 14px rgba(18, 22, 33, .07);
  --sh-3: 0 18px 48px rgba(18, 22, 33, .16);
  --sh-brand: 0 4px 14px rgba(47, 91, 232, .22);

  /* 尺寸 */
  --topbar-h: 56px;
  --side-w:   232px;
  --side-w-md: 64px;
}

/* ---------- 2. 基础 ---------- */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
               "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; border: 0; background: none; padding: 0; }
a { color: var(--brand); text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; }

/* 🔴 页面主标题 —— 全站统一节奏：一根品牌色短竖条 + 20px 半粗标题。
   （此前 h2 裸奔：与正文同色同大小附近，页面没有视觉起点，显「死板」。） */
.main h2 {
  font-size: 20px; font-weight: 680; letter-spacing: -.3px; color: var(--ink);
  display: flex; align-items: center; gap: 10px;
  margin: 2px 0 4px;
}
.main h2::before {
  content: ''; width: 4px; height: 19px; border-radius: 3px;
  background: var(--brand); flex: 0 0 auto;
}
/* 🔴 标题本身**不许被副标题挤扁**（2026-10-22 实测）：h2 是 flex 行
   （品牌条 · 返回 · 标题 · 副标题），标题原来是**裸文本节点** —— 它会被当作
   可收缩的 flex 项压到 min-content，390 宽下「订单」变成**竖排两个字**。
   现在标题有自己的 `<span class="h2-t">`，宽度按内容走；副标题放不下时
   （手机上）整段换到第二行，标题永远在第一位。 */
.main h2 .h2-t { flex: 0 0 auto; white-space: nowrap; }
.main h2 .h2-sub {
  font-size: 12.5px; font-weight: 400; color: var(--ink-3); letter-spacing: 0;
  margin-left: 2px; margin-top: 3px;
}
p { margin: 0; }
table { border-collapse: collapse; width: 100%; }

/* 表格行 hover —— 列表页最基本的一口「活气」：鼠标到哪行，哪行亮 */
tbody tr { transition: background var(--dur-1) var(--ease); }
tbody tr:hover { background: var(--surface-2); }

/* 数字一律等宽 —— 金额/面积/时间对齐了才显干净 */
.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

::selection { background: var(--brand-line); }

/* 滚动条：细、无色，不抢戏 */
* { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 8px; border: 2px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--line-3); background-clip: content-box; }
*::-webkit-scrollbar-track { background: transparent; }

:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: var(--r-xs); }

/* ---------- 3. 外壳 ---------- */
.topbar {
  position: fixed; inset: 0 0 auto 0; height: var(--topbar-h);
  display: flex; align-items: center; gap: var(--s4);
  padding: 0 var(--s5);
  background: rgba(255,255,255,.86);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--line);
  z-index: 40;
}
.brand { display: flex; align-items: center; gap: var(--s2); font-weight: 650; letter-spacing: .2px; }
.brand-mark {
  /* 🔴 **图标与名称块 1:1**（2026-10-21 业务方：「把图标加大到1:1」）——
     顶栏名称块实测 32.5px（14.5 与 10.5 两行、行高 1.3），故图标 32。
     顶栏是固定 58px 高，32px 图标撑不破它。
     🔴 不垫底、不描边：图标按原图呈现。 */
  width: 32px; height: 32px; border-radius: 8px;
  display: grid; place-items: center;
  font-size: 13px; font-weight: 700;
  transition: transform var(--dur-2) var(--spring);
}
.brand:hover .brand-mark { transform: rotate(-8deg) scale(1.06); }
/* 🔴 不再有 `margin-left`：那 2px 让副标题比主标题右移，两行左边缘对不齐（2026-10-21） */
.brand-sub { color: var(--ink-3); font-weight: 400; font-size: 12px; }

/* 顶部常显「当前客户 + 角色」〔R-55〕 */
.cust-chip {
  display: flex; align-items: center; gap: var(--s2);
  padding: 5px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface-2); font-size: 12.5px; color: var(--ink-2);
  transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.cust-chip:hover { border-color: var(--line-2); background: var(--surface); }
.cust-chip b { color: var(--ink); font-weight: 600; }
.cust-chip .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--brand); }

.topbar-right { margin-left: auto; display: flex; align-items: center; gap: var(--s2); }

.icon-btn {
  width: 34px; height: 34px; border-radius: var(--r-sm);
  display: grid; place-items: center; color: var(--ink-2); position: relative;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease), transform var(--dur-1) var(--spring);
}
.icon-btn:hover { background: var(--surface-3); color: var(--ink); }
.icon-btn:active { transform: scale(.94); }
.icon-btn .badge-dot {
  position: absolute; top: 5px; right: 5px; min-width: 15px; height: 15px; padding: 0 4px;
  border-radius: 999px; background: var(--danger); color: #fff;
  font-size: 10px; line-height: 15px; text-align: center; font-weight: 600;
  box-shadow: 0 0 0 2px var(--surface);
}

/* 角色切换（原型演示用） */
.role-switch {
  display: flex; align-items: center; gap: var(--s2);
  padding: 4px 6px 4px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); font-size: 12.5px;
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.role-switch:hover { border-color: var(--brand-line); box-shadow: 0 0 0 3px var(--brand-weak); }
.role-switch select {
  border: 0; background: none; font-size: 12.5px; font-weight: 600; color: var(--brand);
  padding-right: 2px; outline: none; cursor: pointer;
}

/* 侧栏 */
.sidebar {
  position: fixed; top: var(--topbar-h); bottom: 0; left: 0; width: var(--side-w);
  background: var(--surface); border-right: 1px solid var(--line);
  padding: var(--s4) var(--s3); overflow-y: auto; z-index: 30;
  transition: width var(--dur-3) var(--ease);
}
.nav-group { margin-bottom: var(--s5); }
.nav-group-t {
  font-size: 11px; font-weight: 600; color: var(--ink-4); letter-spacing: .8px;
  padding: 0 var(--s3); margin-bottom: var(--s2); text-transform: uppercase;
}
.nav-item {
  display: flex; align-items: center; gap: var(--s3);
  width: 100%; padding: 8px var(--s3); border-radius: var(--r-sm);
  color: var(--ink-2); font-size: 13.5px; text-align: left; position: relative;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.nav-item .ic { width: 18px; text-align: center; font-size: 14px; opacity: .85; }
.nav-item:hover { background: var(--surface-3); color: var(--ink); }
.nav-item.on { background: var(--brand-weak); color: var(--brand); font-weight: 600; }
.nav-item .pid { font: 600 10px/1 var(--mono); opacity: .5; margin-right: 6px; letter-spacing: .3px; }
.nav-item .ro {
  margin-left: auto; font-size: 10px; font-weight: 600; color: var(--ink-3);
  background: var(--surface-3); border: 1px solid var(--line); border-radius: var(--r-xs);
  padding: 1px 5px; flex: 0 0 auto;
}
.nav-item.on .ro { color: var(--brand); background: #fff; border-color: var(--brand-line); }
.nav-item.on .pid { opacity: .85; }
.nav-item.on::before {
  content: ''; position: absolute; left: 0; top: 50%; width: 3px; height: 18px;
  border-radius: 0 3px 3px 0; background: var(--brand);
  transform: translateY(-50%);
  animation: navIn var(--dur-2) var(--spring);
}
@keyframes navIn { from { height: 0; opacity: 0; } to { height: 18px; opacity: 1; } }
.nav-item.locked { color: var(--ink-4); cursor: not-allowed; }
.nav-item.locked:hover { background: transparent; }
.nav-item .lock { margin-left: auto; font-size: 11px; opacity: .7; }
.nav-item .cnt {
  margin-left: auto; font-size: 11px; font-weight: 600;
  background: var(--surface-3); color: var(--ink-3);
  padding: 1px 6px; border-radius: 999px;
}
.nav-item.on .cnt { background: #fff; color: var(--brand); }

/* 主区 */
.main {
  margin-left: var(--side-w); padding-top: var(--topbar-h);
  min-height: 100vh;
  transition: margin-left var(--dur-3) var(--ease);
}
.wrap { max-width: 1180px; padding: var(--s6) var(--s6) var(--s10); margin: 0 auto; }

/* ---------- 4. 页头 ---------- */
.crumb { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-3); }
.crumb span.sep { opacity: .5; }
.crumb b { color: var(--ink-2); font-weight: 500; }

.page-head {
  display: flex; align-items: flex-start; gap: var(--s4);
  margin: var(--s3) 0 var(--s5); flex-wrap: wrap;
}
.page-head .t { font-size: 21px; font-weight: 650; letter-spacing: -.2px; line-height: 1.3; }
.page-head .sub { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
.page-head .acts { margin-left: auto; display: flex; gap: var(--s2); flex-wrap: wrap; }
.page-tag {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11.5px; color: var(--ink-3); background: var(--surface-3);
  padding: 2px 8px; border-radius: var(--r-xs); margin-left: var(--s2);
  vertical-align: 3px; font-weight: 500;
}

/* ---------- 5. 卡片 / 分区 ---------- */
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--sh-1);
}
.card-pad { padding: var(--s5); }
.card-head {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s4) var(--s5); border-bottom: 1px solid var(--line);
}
.card-head .t { font-size: 14.5px; font-weight: 620; }
.card-head .hint { font-size: 12px; color: var(--ink-3); font-weight: 400; }
.card-head .r { margin-left: auto; display: flex; gap: var(--s2); align-items: center; }
.card-foot { padding: var(--s3) var(--s5); border-top: 1px solid var(--line); background: var(--surface-2); border-radius: 0 0 var(--r) var(--r); }

/* 内嵌【更新下单】面板 —— 属于本单流程范围，视觉上收在核心区内（不占独立页面） */
.upd-panel {
  margin-top: var(--s4); border: 1px solid var(--brand-line); border-radius: var(--r);
  background: var(--surface-2); overflow: hidden; box-shadow: var(--sh-1);
}
.upd-panel > .card-head { background: var(--brand-weak); border-bottom-color: var(--brand-line); }
.upd-panel > .card-head .t { font-size: 13.5px; }
.upd-panel > .card-pad { padding: var(--s4) var(--s5) var(--s5); }
@media (max-width: 900px) {
  .upd-panel > .card-pad { padding: var(--s4); }
}

.grid { display: grid; gap: var(--s4); }
.split { display: grid; gap: var(--s4); align-items: start; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
.split-form { display: grid; gap: var(--s4); align-items: start; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); }
.g2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
.row { display: flex; gap: var(--s4); align-items: center; }
.row-wrap { flex-wrap: wrap; }
.push { margin-left: auto; }
.stack { display: flex; flex-direction: column; gap: var(--s3); }
.muted { color: var(--ink-3); }
.tiny { font-size: 12px; }
.small { font-size: 12.5px; }

/* 分区带 —— 「流程分界清晰」的第二件武器：一条细线 + 一个小标签 */
.divider {
  display: flex; align-items: center; gap: var(--s3);
  margin: var(--s6) 0 var(--s4);
}
.divider::after { content: ''; flex: 1; height: 1px; background: var(--line); }
.divider .lbl {
  font-size: 11.5px; font-weight: 650; color: var(--ink-3);
  letter-spacing: .6px; white-space: nowrap;
}
.divider .lbl::before {
  content: ''; display: inline-block; width: 3px; height: 11px; border-radius: 2px;
  background: var(--line-3); margin-right: 6px; vertical-align: -1px;
}
.divider.is-main .lbl::before { background: var(--main); }
.divider.is-complete .lbl::before { background: var(--complete); }
.divider.is-after .lbl::before { background: var(--aftersale); }

/* ---------- 6. 按钮 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 34px; padding: 0 14px; border-radius: var(--r-sm);
  font-size: 13.5px; font-weight: 550; white-space: nowrap;
  border: 1px solid transparent; position: relative; overflow: hidden;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease), transform var(--dur-1) var(--spring),
              box-shadow var(--dur-1) var(--ease), opacity var(--dur-1) var(--ease);
}
.btn:active { transform: scale(.975); }
.btn[disabled] { opacity: .45; pointer-events: none; }

/* 🔴 与 `index.html` 内联段的分工一致：主色=蓝，**按钮=语义色**
   （推进=绿 `--ok` / 危险=红 `--danger` / 次要=灰描边） */
.btn-primary { background: var(--ok); color: #fff; box-shadow: 0 4px 14px rgba(14,154,85,.22); }
.btn-primary:hover { background: #0B7F45; box-shadow: 0 6px 18px rgba(14,154,85,.28); }
.btn-default { background: var(--surface); color: var(--ink); border-color: var(--line-2); }
.btn-default:hover { border-color: var(--line-3); background: var(--surface-2); }
.btn-ghost { background: transparent; color: var(--ink-2); }
.btn-ghost:hover { background: var(--surface-3); color: var(--ink); }
.btn-soft { background: var(--brand-weak); color: var(--brand); }
.btn-soft:hover { background: #E4EAFD; }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { background: #C93; background: #C93030; }
.btn-ok { background: var(--ok); color: #fff; }
.btn-lg { height: 40px; padding: 0 20px; font-size: 14.5px; border-radius: var(--r); }
.btn-sm { height: 28px; padding: 0 10px; font-size: 12.5px; }
.btn-block { width: 100%; }

/* 主操作自带「后果预告」—— 操作直观具体的核心手法 */
.act { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.act .conseq {
  font-size: 11.5px; color: var(--ink-3); font-weight: 400; line-height: 1.45;
  max-width: 260px; white-space: normal; text-align: left;
}
.act-row { display: flex; gap: var(--s2); align-items: flex-start; flex-wrap: wrap; }

/* 按钮 loading（防重复提交） */
.btn.loading { pointer-events: none; color: transparent !important; }
.btn.loading::after {
  content: ''; position: absolute; inset: 0; margin: auto;
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid currentColor; border-color: rgba(255,255,255,.35);
  border-top-color: #fff;
  animation: spin .6s linear infinite;
}
.btn-default.loading::after, .btn-ghost.loading::after, .btn-soft.loading::after {
  border-color: var(--line-2); border-top-color: var(--brand);
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- 7. 徽章 / 状态 ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: var(--r-xs);
  font-size: 12px; font-weight: 550; line-height: 18px; white-space: nowrap;
  border: 1px solid transparent;
}
.badge::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.badge.b-neutral { background: var(--surface-3); color: var(--ink-2); border-color: var(--line); }
.badge.b-brand   { background: var(--brand-weak); color: var(--brand); border-color: var(--brand-line); }
.badge.b-ok      { background: var(--ok-weak); color: var(--ok); border-color: var(--ok-line); }
.badge.b-warn    { background: var(--warn-weak); color: var(--warn); border-color: var(--warn-line); }
.badge.b-danger  { background: var(--danger-weak); color: var(--danger); border-color: var(--danger-line); }
.badge.b-complete{ background: var(--complete-w); color: var(--complete); border-color: #DAD2F7; }
.badge.b-after   { background: var(--aftersale-w); color: var(--aftersale); border-color: #BEE4E4; }
.badge.b-plain   { background: transparent; color: var(--ink-3); border-color: var(--line); }
.badge.b-plain::before { display: none; }
.badge-pop { animation: badgePop var(--dur-3) var(--spring); }
@keyframes badgePop { 0% { transform: scale(.7); opacity: 0; } 60% { transform: scale(1.08); } 100% { transform: scale(1); opacity: 1; } }

.tag { font-size: 11.5px; color: var(--ink-3); background: var(--surface-3); padding: 1px 7px; border-radius: var(--r-xs); }
.tag-o { background: transparent; border: 1px solid var(--line); }

/* ---------- 8. 七步条（本原型的门面） ---------- */
.stepbar-wrap {
  padding: var(--s5) var(--s5) var(--s4);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--sh-1); position: relative; overflow: hidden;
}
.stepbar-top { display: flex; align-items: center; gap: var(--s3); margin-bottom: var(--s5); flex-wrap: wrap; }
.stepbar-top .no { font-size: 15px; font-weight: 650; letter-spacing: -.2px; }
.stepbar-top .no .num { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: 13px; color: var(--ink-3); font-weight: 500; margin-left: 6px; }

.stepbar { display: flex; align-items: flex-start; position: relative; }
.step-group { display: flex; align-items: flex-start; position: relative; }
/* 组间分隔：一条竖细线 + 组名，把 ①–⑥ / ⑦ / ⑧ 切开 */
.step-gate {
  display: flex; flex-direction: column; align-items: center;
  padding: 0 var(--s3); margin-top: -2px; position: relative; flex: 0 0 auto;
}
.step-gate .vl { width: 1px; height: 34px; background: var(--line-2); }
.step-gate .gl {
  font-size: 10.5px; font-weight: 650; letter-spacing: .4px; white-space: nowrap;
  margin-top: 3px; color: var(--ink-4);
}
.step-gate.g-complete .gl { color: var(--complete); }
.step-gate.g-after .gl { color: var(--aftersale); }

.step { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; position: relative; cursor: default; }
.step .rail { position: absolute; top: 13px; left: 50%; width: 100%; height: 2px; background: var(--line); z-index: 0; }
.step:first-child .rail { left: 50%; width: 50%; }
.step-group > .step:last-child .rail { display: none; }
.step .rail .fill { display: block; height: 100%; width: 0; background: var(--main); transition: width var(--dur-3) var(--ease); }
.step.done .rail .fill { width: 100%; }
.step.is-current .rail .fill { width: 100%; }

.step .dot {
  position: relative; z-index: 1;
  width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface); border: 2px solid var(--line-2);
  color: var(--ink-4); font-size: 12px; font-weight: 650;
  transition: background var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease),
              color var(--dur-2) var(--ease), transform var(--dur-2) var(--spring),
              box-shadow var(--dur-2) var(--ease);
}
.step.done .dot { background: var(--main); border-color: var(--main); color: #fff; }
.step.is-current .dot {
  background: var(--main); border-color: var(--main); color: #fff;
  transform: scale(1.14);
  box-shadow: 0 0 0 5px var(--main-weak);
  animation: pulse 2.4s var(--ease) infinite;
}
.step.g7.done .dot, .step.g7.is-current .dot { background: var(--complete); border-color: var(--complete); }
.step.g7.is-current .dot { box-shadow: 0 0 0 5px var(--complete-w); }
.step.g8.done .dot, .step.g8.is-current .dot { background: var(--aftersale); border-color: var(--aftersale); }
.step.g8.is-current .dot { box-shadow: 0 0 0 5px var(--aftersale-w); }
@keyframes pulse {
  0%,100% { box-shadow: 0 0 0 5px var(--main-weak); }
  50%     { box-shadow: 0 0 0 9px rgba(47,91,232,.06); }
}
.step.g7.is-current .dot { animation: pulseC 2.4s var(--ease) infinite; }
@keyframes pulseC { 0%,100% { box-shadow: 0 0 0 5px var(--complete-w); } 50% { box-shadow: 0 0 0 9px rgba(109,91,224,.07); } }
.step .lbl { margin-top: 7px; font-size: 12px; color: var(--ink-3); white-space: nowrap; transition: color var(--dur-2) var(--ease), font-weight var(--dur-2) var(--ease); }
.step.done .lbl { color: var(--ink-2); }
.step.is-current .lbl { color: var(--ink); font-weight: 650; }
.step .who { margin-top: 1px; font-size: 10.5px; color: var(--ink-4); white-space: nowrap; }
.step.clickable { cursor: pointer; }
.step.clickable:hover .dot { transform: scale(1.08); border-color: var(--line-3); }
.step.clickable:hover .lbl { color: var(--ink); }

/* 审单旁路：虚线挂在第④步下方，明确「不占编号」 */
.bypass {
  position: absolute; left: 0; right: 0; top: 46px; height: 36px;
  pointer-events: none;
}
.bypass-branch {
  position: absolute; top: 0; display: flex; flex-direction: column; align-items: center;
  transform: translateX(-50%); pointer-events: auto;
}
.bypass-branch .stem {
  width: 0; height: 12px; border-left: 1.5px dashed var(--bypass);
}
.bypass-branch .node {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 999px;
  border: 1.5px dashed var(--bypass); background: var(--surface);
  font-size: 11px; color: var(--ink-3); white-space: nowrap;
  transition: all var(--dur-2) var(--ease);
}
.bypass-branch.on .node { border-style: solid; border-color: var(--main); color: var(--brand); background: var(--brand-weak); font-weight: 600; }
.bypass-branch:hover .node { border-color: var(--line-3); color: var(--ink-2); }
.stepbar.has-bypass { margin-bottom: 34px; }

/* ---------- 9. 倒计时 ---------- */
.countdown {
  display: inline-flex; align-items: baseline; gap: 3px;
  font-variant-numeric: tabular-nums;
}
.countdown .v { font-size: 20px; font-weight: 650; letter-spacing: -.5px; }
.countdown .u { font-size: 11.5px; color: var(--ink-3); }
.countdown.urgent .v { color: var(--danger); animation: tick 1s steps(1) infinite; }
@keyframes tick { 0%,60% { opacity: 1; } 61%,100% { opacity: .55; } }
.countdown.paused .v { color: var(--ink-3); }

/* ---------- 10. 表格 ---------- */
.tbl { font-size: 13.5px; width: 100%; background: var(--surface);
      /* 🔴 `separate` 而不是 `collapse`（2026-10-22）：**粘性单元格在 collapsed
         边框的表里不生效**（Chrome 的老行为）。行间只有 `border-bottom`、间距设 0，
         外观不变。 */
      border-collapse: separate; border-spacing: 0;
      /* 🔴 **`overflow` 必须留在 `visible`**：写 `hidden` 会把表格自己变成
         **最近的滚动容器** —— 于是 `position:sticky; right:0` 的操作列以表格
         （778px 宽、不滚动）为参照，永远钉不住（实测：scrollLeft=0 时右边界仍是 799）。
         圆角改由外层 `.tbl-scroll` 裁（它本来就是横滚容器）。 */
      border: 1px solid var(--line); border-radius: 8px; }
/* 🔴 圆角与裁切从 `.tbl` 挪到**外层滚动容器**（2026-10-22）：
   表格自己 `overflow:hidden` 会变成最近的滚动容器、把粘性列钉死在表格里。
   🔴 横滚**全宽度都开着**（原来只在 767 以下开）：768~900 这一段表格照样放不下，
   而 `overflow:hidden` 会把右边直接**裁掉且滑不动**（实测 768 宽下退储值复核页
   的操作列被裁、按钮点不到）。只在溢出时才出滚动条，桌面不受影响。 */
.tbl-scroll { border-radius: 8px; overflow-x: auto; overflow-y: hidden;
              -webkit-overflow-scrolling: touch; }
.tbl th {
  text-align: left; font-weight: 550; color: var(--ink-3); font-size: 12px;
  padding: 10px var(--s4); border-bottom: 1px solid var(--line);
  /* 🔴 **表头底色要比「页面底」和「卡片底」都深**（2026-10-21）——
     原来用 `--surface-2`(#FAFBFC)，比页面底色 `--bg`(#F6F7F9) 还浅：
     表格直接放在页面里时，表头等于**消失**（订单列表就是这样，看着没有一个"表头区"）。 */
  background: #EFF2F7; white-space: nowrap;
}
.tbl td { padding: 12px var(--s4); border-bottom: 1px solid var(--line); vertical-align: middle; }
/* 🔴 **表单表格**（行里是输入框，不是数据）—— 2026-10-22 修的手机端填不进去的问题：
   ① `table-layout: auto` 会按**内容**分配列宽，说明列（长句）抢走 234px，
      「姓名 / 手机号 / 密码」三列只剩 44/57/169 → 输入框 32px，手机上根本没法填；
      改成 `fixed`，`<th>` 上声明的宽度才生效。
   ② 说明列在手机上收起（它是一句话解释，不是这一行要填的东西）——
      收起后表格 522 宽，由外层 `.tbl-scroll` 横滚，三列输入框各 98~138px。 */
.tbl-form { table-layout: fixed; }
/* 四列宽度写成 class（不写 inline style）—— 手机上要整体换一套宽度，
   inline 优先级高、改不动（2026-10-22）。桌面按内容的舒适宽度，手机按 346 的预算重排。 */
.tbl-form .c-role  { width: 88px; }
.tbl-form .c-name  { width: 130px; }
.tbl-form .c-phone { width: 150px; }
.tbl-form .c-pwd   { width: 170px; }
/* 角色名是 2~3 个字（老板 / 财务员），列一窄就折成「财务 / 员」—— 单行钉死 */
.tbl-form td:first-child, .tbl-form th:first-child { white-space: nowrap; }
@media (max-width: 767px) {
  .tbl-form th:last-child, .tbl-form td:last-child { display: none; }
  /* 346 - 56 - 88 - 100 - 78 = 24 余量（`width:100%` 会均摊掉）——
     四列刚好一屏放下，不用横滑就能把三行填完。 */
  .tbl-form .c-role  { width: 62px; }
  .tbl-form .c-name  { width: 76px; }
  .tbl-form .c-phone { width: 96px; }
  .tbl-form .c-pwd   { width: 88px; }
  /* 收内边距：每列省 16px，输入框才留得下 70px 以上 */
  .tbl-form th, .tbl-form td { padding-left: 8px; padding-right: 8px; }
}
.tbl tbody tr { transition: background var(--dur-1) var(--ease); position: relative; cursor: pointer; }
.tbl tbody tr:hover { background: var(--surface-2); }
.tbl tbody tr:hover td:first-child { box-shadow: inset 3px 0 0 var(--brand); }
/* 🔴 **表体空态**（2026-10-21）：表头照画、表体留一行占位 ——
   空白期也要看得见「这里该有什么、下一步点哪」，而不是一片什么都没有的页面。 */
.tbl tbody .empty-row td {
  padding: 22px 10px; text-align: center; color: var(--ink-3); font-size: 12.5px;
}
.tbl tbody .empty-row b { color: var(--ink-2); font-weight: 600; }

/* 🔴 **小笔记本（1024~1199）表格收紧一档**（2026-10-21）——
   实测 1024 宽下订单列表会出现「海-261020-/021」「CAD全拆/单」「未分/类」这种**单元格内折行**：
   表格没溢出（740 < 784），但列被挤出折行，比溢出更难看。收 padding + 字号即可装回去。 */
@media (max-width: 1199px) {
  .tbl { font-size: 12.5px; }
  .tbl th, .tbl td { padding-left: 9px; padding-right: 9px; }
}

/* 🔴 **手机端侧栏**（2026-10-21）：真实容器是 `.side`，而上面 767 断点里写的是 `.sidebar`
   —— 那个类名在本项目根本不存在，所以「侧栏滑出 + 汉堡按钮」那几条规则**从来没生效过**。
   这里按真实选择器补一份（老的 `.sidebar` 规则保留，不影响）。 */
.nav-toggle {
  display: none; flex: none; width: 34px; height: 34px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-2);
  align-items: center; justify-content: center; cursor: pointer;
}
@media (max-width: 767px) {
  /* 标题与副标题排不下时**整段换行**，不要压标题 */
  .main h2 { flex-wrap: wrap; row-gap: 2px; }
  .nav-toggle { display: inline-flex; }
  .side {
    position: fixed; top: 58px; bottom: 0; left: 0; z-index: 45;
    width: 232px; overflow-y: auto; box-shadow: var(--sh-3);
    transform: translateX(-100%); transition: transform var(--dur-3) var(--ease);
  }
  .side.open { transform: none; }
  /* 🔴 手机端**别藏表头**：藏了之后每行只剩数值，看不出哪列是什么（没有 data-label 兜底）
     ⚠️ 2026-10-22 复查：下方**第二个** 767 块里还留着一条 `.tbl thead { display: none }`，
     把这条覆盖掉了 —— 也就是说「保留表头」这条决定**生效过又丢了**（实测手机上表头仍是空的）。
     那条已删。🔴 别再开第三个断点块写第二份规则：后写的赢，改的人看不见。 */
  .tbl thead { display: table-header-group; }
  /* 🔴 表格**横滚而不是压缩**：不写 nowrap 的话，列会被压到极限 ——
     「等你：收单」逐字竖排、「CAD全拆单」拆成两行，比横滚难看得多。 */
  .tbl th, .tbl td { white-space: nowrap; }
  /* 🔴 **flex 子项的经典坑**：`.shell` 是 flex，`.main` 默认 `min-width: auto`
     —— 内容（宽表格）会把 `.main` 撑开、进而撑破整个页面（实测文档横向溢出 86px，
     横滚容器形同虚设）。必须显式 `min-width: 0` 才允许它收缩。 */
  .main { min-width: 0; }
  /* 🔴 用 **`clip` 而不是 `hidden`**（2026-10-21）：`hidden` 会建立滚动上下文，
     让表格里的 `position: sticky` 首列**当场失效**（实测首列跟着滚到 -222）。
     `clip` 只裁剪、不建滚动容器，既挡住整页横移，又保住 sticky。 */
  html, body { overflow-x: clip; }

  /* 🔴 顶栏在 390 宽放不下「客户名 + 人名 + 改密码 + 退出」——
     不处理的话客户名会被挤成**竖排单字**（实测截图）。手机端只留：菜单 · 品牌 · 改密码 · 退出。 */
  .top { gap: 6px; padding: 0 10px; }
  #top-co, #top-solo, #top-who { display: none; }
  /* 顶栏 390 宽的预算：菜单 34 + 图标 38 + 标题 ≈130 + 改密码 58 + 退出 50 + 间距 24 ≈ 334 */
  .brand-main { font-size: 14.5px; letter-spacing: 0; }
  .brand-main .dot { margin: 0 1px; }
  .top .btn, .top button { padding: 6px 10px; font-size: 12px; }
  /* 🔴 「改密码」在手机上低频，先让位 —— 不然「退出」被挤出屏幕（`overflow-x:hidden` 之后直接看不见）。 */
  #top-pwd { display: none; }
  /* 🔴 「返回」在 390 宽会被挤成**竖排两字**（「返」/「回」）——
     它是单行短语，必须 inline-block + nowrap 才不会被拆。 */
  .pg-back { display: inline-block; white-space: nowrap; }

  /* 🔴 **手机端订单列表少显示四列**（2026-10-21）——
     先试过「首列 sticky」，但 `html/body` 的 `overflow-x` 一旦不是 `visible`
     （`hidden` 与 `clip` 都一样），sticky 就失去参照：实测首列跟着滚到 -222，钉不住。
     与其为了 sticky 放弃整页防溢出，不如**把次要列收起来**：
     类型 / 交付期 / 面积 / 分类 手机上看不出决策价值，留着反而逼人横滑。 */
  /* 收完四列还差 15px（实测 361 vs 346），把单元格留白再收一档，一屏放下不横滑 */
  .tbl th, .tbl td { padding-left: 6px; padding-right: 6px; }
  .tbl td.c-type, .tbl th.c-type,
  .tbl td.c-delivery, .tbl th.c-delivery,
  .tbl td.c-area, .tbl th.c-area,
  .tbl td.c-cat, .tbl th.c-cat { display: none; }
}

/* 🔴 **带按钮的那一列钉在右边**（2026-10-22 · ≤900 而不是 ≤767）：
   宽表格在窄屏要横滑，而「复核 / 明细 / 通过 / 驳回」这一列是**这一页唯一能干的事** ——
   滑到最右边才找得到，等于把主操作藏起来（实测退储值复核页 778 宽：390 与 768 下
   整列都在视口外）。钉住之后滑动看图，按钮一直在右手边。
   · 只认「最后一格里有按钮」的表（`:has`），数据表的末列（金额 / 说明）不动
   · 不支持 `:has` 的老浏览器 = 这条不生效，退化成今天的样子，不会更坏
   · 🔴 能钉住的前提是 `.tbl` 自己不许 `overflow:hidden`（否则表格成了最近的滚动容器）*/
@media (max-width: 900px) {
  .tbl:has(tbody td:last-child .btn) thead th:last-child,
  .tbl:has(tbody td:last-child .btn) tbody td:last-child {
    position: sticky; right: 0; z-index: 2;
    background: var(--surface);
    box-shadow: -7px 0 8px -7px rgba(16,24,40,.18);
  }
  .tbl:has(tbody td:last-child .btn) thead th:last-child { background: #EFF2F7; }
}

/* 🔴 **工具条 `.bar`**（2026-10-21）：全站多个页面在用（announce / audit / capcfg / invoice …），
   但设计表里一直没有它的样式 —— 于是「统计 + 按钮」是**竖着堆**的，页面看着又散又空。
   统一成：一行、统计在左、操作在右（`<span class="spacer">` 撑开）。 */
.bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.bar .spacer { margin-left: auto; }
.tbl tbody tr:last-child td { border-bottom: 0; }
.tbl .ta-r { text-align: right; }
.tbl .ta-c { text-align: center; }
.tbl .strong { font-weight: 600; }

/* ---------- 11. 表单 ---------- */
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label { font-size: 12.5px; font-weight: 550; color: var(--ink-2); display: flex; align-items: center; gap: 4px; }
.field > label .req { color: var(--danger); }
.field .hint { font-size: 11.5px; color: var(--ink-3); }
.field .err { font-size: 11.5px; color: var(--danger); display: none; }
.field.invalid .err { display: block; animation: shakeIn var(--dur-2) var(--ease); }
.field.invalid .ipt, .field.invalid .sel { border-color: var(--danger); }
@keyframes shakeIn { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }

.ipt, .sel, .ta {
  height: 34px; padding: 0 10px; border: 1px solid var(--line-2); border-radius: var(--r-sm);
  background: var(--surface); font-size: 13.5px; width: 100%;
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.ta { height: auto; padding: 8px 10px; resize: vertical; min-height: 72px; line-height: 1.6; }
.ipt:hover, .sel:hover, .ta:hover { border-color: var(--line-3); }
.ipt:focus, .sel:focus, .ta:focus {
  outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-weak);
}
.ipt::placeholder, .ta::placeholder { color: var(--ink-4); }
.sel { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5L6 8l3-3.5' fill='none' stroke='%238A91A0' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; padding-right: 28px; }
.input-money { position: relative; }
.input-money .ipt { padding-left: 26px; font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums; }
.input-money .cur { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--ink-3); font-size: 13px; pointer-events: none; }
.input-money .sfx { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); color: var(--ink-4); font-size: 12px; pointer-events: none; }

/* 三态分段（继承 / 开 / 关） */
.seg3 { display: inline-flex; background: var(--surface-3); border-radius: var(--r-sm); padding: 2px; gap: 2px; }
.seg3 button {
  padding: 4px 10px; border-radius: 5px; font-size: 12px; color: var(--ink-2); font-weight: 500;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.seg3 button:hover { color: var(--ink); }
.seg3 button.on { background: var(--surface); color: var(--ink); font-weight: 600; box-shadow: var(--sh-1); }
.seg3 button.on[data-v="1"] { color: var(--ok); }
.seg3 button.on[data-v="0"] { color: var(--danger); }
.seg3 button.on[data-v="inherit"] { color: var(--brand); }

/* 开关 */
.sw {
  width: 38px; height: 22px; border-radius: 999px; background: var(--line-2);
  position: relative; transition: background var(--dur-2) var(--ease); flex: 0 0 auto;
}
.sw::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
  border-radius: 50%; background: #fff; box-shadow: var(--sh-1);
  transition: transform var(--dur-2) var(--spring);
}
.sw.on { background: var(--brand); }
.sw.on::after { transform: translateX(16px); }

/* ---------- 12. 金额卡 / 构成条 ---------- */
.amt {
  font-size: 26px; font-weight: 650; letter-spacing: -.6px;
  font-variant-numeric: tabular-nums; line-height: 1.2;
}
.amt .cur { font-size: 15px; font-weight: 500; color: var(--ink-3); margin-right: 2px; }
.amt-sm { font-size: 18px; font-weight: 650; letter-spacing: -.3px; font-variant-numeric: tabular-nums; }
.amt-lg { font-size: 34px; font-weight: 680; letter-spacing: -1px; }

/* ---------- 首页「待办网格」—— 内容区版式的重心 ----------
   🔴 病根（用户 2026-10-17）：flex + hug 宽度 → 卡片又窄又小、右半屏全空；
      数字没有视觉重心；「消息提醒」独占一大行。
   改法：三块（待办 · 金额 · 提醒）**合并成一张网格**，auto-fill 等宽铺满；
      数字放大成视觉主角；hover 抬升 + 箭头位移给「可点」的暗示。 */
.todo-grid {
  display: grid; gap: var(--s4); margin-bottom: var(--s5);
  grid-template-columns: repeat(auto-fill, minmax(236px, 1fr));
}
.todo-grid .stat {
  padding: var(--s5); border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface); box-shadow: var(--sh-1);
  position: relative; overflow: hidden;
  transition: transform var(--dur-2) var(--spring),
              box-shadow var(--dur-2) var(--ease),
              border-color var(--dur-2) var(--ease);
}
.todo-grid .stat::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--line-3); transition: background var(--dur-2) var(--ease);
}
.todo-grid .stat.hl { border-color: var(--line); }
.todo-grid .stat.hl::before { background: var(--brand); }
.todo-grid .stat.money { background: linear-gradient(180deg, var(--brand-weak), var(--surface) 78%); }
.todo-grid .stat.money::before { background: var(--brand); opacity: .55; }
.todo-grid .stat[data-go] { cursor: pointer; }
.todo-grid .stat[data-go]:hover {
  transform: translateY(-3px);
  box-shadow: var(--sh-2);
  border-color: var(--brand-line);
}
.todo-grid .stat[data-go]:hover .go { transform: translateX(3px); }
.todo-grid .stat .k {
  font-size: 12.5px; color: var(--ink-3); font-weight: 550;
  display: flex; align-items: center; gap: 5px;
}
.todo-grid .stat .go {
  margin-left: auto; color: var(--brand); font-weight: 600;
  transition: transform var(--dur-2) var(--spring);
}
.todo-grid .stat .v {
  margin-top: 12px;
  font-size: 27px; font-weight: 700; letter-spacing: -.6px; line-height: 1.1;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.todo-grid .stat .v .u {
  font-style: normal; font-size: 13px; font-weight: 500;
  color: var(--ink-3); letter-spacing: 0; margin-left: 3px;
}
.todo-grid .stat .n { font-size: 12px; color: var(--ink-3); margin-top: 7px; line-height: 1.5; }
.todo-grid .stat .refs {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 11px; color: var(--ink-4);
  margin-top: 5px; letter-spacing: .2px;
}

/* 首页空态 —— 「今天没活了」也要有呼吸感，不挤成一灰行 */
.empty-hero {
  border: 1px dashed var(--line-2); border-radius: var(--r-lg);
  background: var(--surface); text-align: center;
  padding: 52px 24px 56px; margin-bottom: var(--s5);
}
.empty-hero .ic {
  width: 52px; height: 52px; margin: 0 auto var(--s4);
  border-radius: 50%; display: grid; place-items: center;
  background: var(--ok-weak); color: var(--ok); font-size: 22px;
}
.empty-hero .t { font-size: 15.5px; font-weight: 620; color: var(--ink); }
.empty-hero .s { font-size: 12.5px; color: var(--ink-3); margin-top: 6px; }

/* 余额构成条 —— 一段一分界，看得见「哪部分不能动」 */
.compose { display: flex; height: 34px; border-radius: var(--r-sm); overflow: hidden; border: 1px solid var(--line); }
.compose .seg {
  display: grid; place-items: center; font-size: 11.5px; font-weight: 600; color: #fff;
  white-space: nowrap; overflow: hidden; position: relative;
  transition: flex-grow var(--dur-3) var(--ease), filter var(--dur-1) var(--ease);
  min-width: 0;
}
.compose .seg:hover { filter: brightness(1.06); }
.compose .seg.s-recharge { background: #6E86C9; }
.compose .seg.s-floor    { background: #2A3348; }
.compose .seg.s-pending  { background: var(--warn); }
.compose-legend { display: flex; gap: var(--s4); flex-wrap: wrap; margin-top: var(--s3); }
.compose-legend .li { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-2); }
.compose-legend .sw2 { width: 10px; height: 10px; border-radius: 3px; }
.compose-legend .li .v { font-weight: 650; color: var(--ink); font-variant-numeric: tabular-nums; }

/* ---------- 13. 时间线 ---------- */
.tl { position: relative; padding-left: 20px; }
.tl::before { content: ''; position: absolute; left: 5px; top: 6px; bottom: 6px; width: 1px; background: var(--line); }
.tl .it { position: relative; padding: 0 0 var(--s4); }
.tl .it:last-child { padding-bottom: 0; }
.tl .it::before {
  content: ''; position: absolute; left: -20px; top: 5px; width: 11px; height: 11px;
  border-radius: 50%; background: var(--surface); border: 2px solid var(--line-2);
}
.tl .it.done::before { background: var(--main); border-color: var(--main); }
.tl .it.now::before { background: var(--main); border-color: var(--main); box-shadow: 0 0 0 4px var(--main-weak); }
.tl .it.bypass::before { background: var(--surface); border-color: var(--bypass); border-style: dashed; }
.tl .it .h { display: flex; align-items: center; gap: var(--s2); font-size: 13px; }
.tl .it .h b { font-weight: 600; }
.tl .it .h .tm { margin-left: auto; font-size: 11.5px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.tl .it .d { font-size: 12px; color: var(--ink-3); margin-top: 2px; }

/* ---------- 14. 弹窗 / 抽屉 / Toast ---------- */
.mask {
  position: fixed; inset: 0; background: rgba(16,20,30,.42);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  z-index: 60; display: grid; place-items: center; padding: var(--s5);
  animation: fadeIn var(--dur-2) var(--ease);
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.dlg {
  width: 100%; max-width: 520px; background: var(--surface); border-radius: var(--r-lg);
  box-shadow: var(--sh-3); overflow: hidden; max-height: 88vh; display: flex; flex-direction: column;
  animation: dlgIn var(--dur-3) var(--spring);
}
@keyframes dlgIn { from { opacity: 0; transform: translateY(14px) scale(.97); } to { opacity: 1; transform: none; } }
.dlg.warn { border-top: 3px solid var(--warn); }
.dlg.danger { border-top: 3px solid var(--danger); }
.dlg .hd { padding: var(--s5) var(--s5) var(--s3); display: flex; gap: var(--s3); align-items: flex-start; }
.dlg .hd .ic {
  width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center;
  font-size: 17px; flex: 0 0 auto;
}
.dlg.warn .hd .ic { background: var(--warn-weak); color: var(--warn); }
.dlg.danger .hd .ic { background: var(--danger-weak); color: var(--danger); }
.dlg .hd .t { font-size: 16px; font-weight: 650; line-height: 1.4; }
.dlg .hd .s { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
.dlg .bd { padding: 0 var(--s5) var(--s4); overflow-y: auto; }
.dlg .ft { padding: var(--s4) var(--s5); border-top: 1px solid var(--line); background: var(--surface-2); display: flex; gap: var(--s2); justify-content: flex-end; }

/* 阻断弹窗里「会发生 / 不会发生」两栏 —— 操作直观具体 */
.effects { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }
.effects .box { border: 1px solid var(--line); border-radius: var(--r-sm); padding: var(--s3) var(--s4); background: var(--surface-2); }
.effects .box .h { font-size: 11.5px; font-weight: 650; letter-spacing: .4px; margin-bottom: var(--s2); display: flex; align-items: center; gap: 5px; }
.effects .box.will .h { color: var(--ok); }
.effects .box.wont .h { color: var(--ink-3); }
.effects .box ul { display: flex; flex-direction: column; gap: 5px; }
.effects .box li { font-size: 12.5px; color: var(--ink-2); display: flex; gap: 6px; line-height: 1.5; }
.effects .box li .m { color: var(--ink-4); flex: 0 0 auto; }

.quote {
  border-left: 3px solid var(--warn); background: var(--warn-weak);
  padding: var(--s3) var(--s4); border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: 13.5px; font-weight: 600; color: #7A4A05; line-height: 1.6;
}

.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: 480px; max-width: 92vw;
  background: var(--surface); box-shadow: var(--sh-3); z-index: 61;
  display: flex; flex-direction: column;
  animation: drawerIn var(--dur-3) var(--ease);
}
@keyframes drawerIn { from { transform: translateX(100%); } to { transform: none; } }
.drawer .hd { padding: var(--s5); border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: var(--s3); }
.drawer .hd .t { font-size: 15.5px; font-weight: 650; }
.drawer .bd { padding: var(--s5); overflow-y: auto; flex: 1; }
.drawer .ft { padding: var(--s4) var(--s5); border-top: 1px solid var(--line); background: var(--surface-2); display: flex; gap: var(--s2); justify-content: flex-end; }

.toasts { position: fixed; top: calc(var(--topbar-h) + 12px); right: 20px; z-index: 80; display: flex; flex-direction: column; gap: var(--s2); }
.toast {
  display: flex; align-items: flex-start; gap: var(--s2);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-sm);
  box-shadow: var(--sh-2); padding: 10px 14px; font-size: 13px; min-width: 240px; max-width: 380px;
  animation: toastIn var(--dur-3) var(--spring);
}
.toast.out { animation: toastOut var(--dur-2) var(--ease) forwards; }
@keyframes toastIn { from { opacity: 0; transform: translateX(24px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateX(24px) scale(.96); } }
.toast .ic { font-size: 14px; line-height: 1.5; }
.toast.ok .ic { color: var(--ok); }
.toast.warn .ic { color: var(--warn); }
.toast.err .ic { color: var(--danger); }

/* ---------- 15. 骨架 / 入场 ---------- */
.sk { background: var(--surface-3); border-radius: var(--r-xs); position: relative; overflow: hidden; }
.sk::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.75), transparent);
  transform: translateX(-100%); animation: shimmer 1.25s infinite;
}
@keyframes shimmer { 100% { transform: translateX(100%); } }
.sk-line { height: 12px; }
.sk-row { display: flex; gap: var(--s4); padding: 14px var(--s4); border-bottom: 1px solid var(--line); }

/* 列表错峰入场 —— 高流畅度最直观的一处 */
.stagger > * { animation: rise var(--dur-3) var(--ease) backwards; animation-delay: calc(var(--i, 0) * 38ms); }
@keyframes rise { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }

/* 页面切换 */
.page { display: none; }
.page.on { display: block; animation: pageIn var(--dur-3) var(--ease); }
@keyframes pageIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* 面板切换（核心区不跳页） */
.panel-swap { animation: swap var(--dur-3) var(--ease); }
@keyframes swap { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------- 16. 其他小件 ---------- */
.kv { display: grid; grid-template-columns: 96px 1fr; gap: 8px var(--s4); font-size: 13px; }
.kv dt { color: var(--ink-3); }
.kv dd { margin: 0; color: var(--ink); }

.file-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface-2); font-size: 12.5px;
  transition: border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--spring);
}
.file-chip:hover { border-color: var(--brand-line); transform: translateY(-1px); }
.file-chip .ext { font-size: 10px; font-weight: 700; color: var(--brand); background: var(--brand-weak); padding: 1px 5px; border-radius: 4px; }
.file-chip .sz { color: var(--ink-4); font-size: 11px; font-variant-numeric: tabular-nums; }
.file-chip .del {
  border: 0; background: transparent; cursor: pointer; color: var(--ink-4);
  font-size: 14px; line-height: 1; padding: 0 2px; border-radius: 4px;
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.file-chip .del:hover { color: var(--danger); background: var(--danger-weak); }
.file-chip.new { animation: chipIn var(--dur-2) var(--spring) both; }
@keyframes chipIn { from { opacity: 0; transform: translateY(-4px) scale(.96); } to { opacity: 1; transform: none; } }

/* 上传区：点击 / 拖拽两种入口，拖入时整块高亮（A2 直观具体） */
.drop {
  border: 1.5px dashed var(--line-2); border-radius: var(--r-md); background: var(--surface-2);
  cursor: pointer; transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.drop:hover { border-color: var(--brand-line); background: var(--brand-weak); }
.drop.over { border-color: var(--brand); background: var(--brand-weak); }
.drop .dz { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 18px 12px; text-align: center; }
.drop .dz .ic { font-size: 18px; color: var(--brand); }
.drop .dz .tx { font-size: 13px; font-weight: 550; color: var(--ink-2); }
.drop .dz .tiny { color: var(--ink-4); }

/* 卡片式单选：用于「确单不通过」选两态 —— 点哪张选哪张，不用小圆点（A2） */
.pick {
  display: flex; gap: 10px; align-items: flex-start; padding: 12px;
  border: 1.5px solid var(--line-2); border-radius: var(--r-md); background: var(--surface);
  cursor: pointer; transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease), transform var(--dur-1) var(--spring);
}
.pick:hover { border-color: var(--line-3); transform: translateY(-1px); }
.pick.on { border-color: var(--brand); background: var(--brand-weak); }
.pick .box {
  flex: 0 0 auto; width: 16px; height: 16px; margin-top: 2px; border-radius: 50%;
  border: 1.5px solid var(--line-3); transition: all var(--dur-1) var(--ease);
}
.pick.on .box { border-color: var(--brand); border-width: 5px; }
.pick .tx { font-size: 13px; font-weight: 600; color: var(--ink); }
.pick .ds { font-size: 11.5px; color: var(--ink-3); line-height: 1.55; margin-top: 3px; }
.pick .st { font: 600 10.5px/1 var(--mono); color: var(--ink-4); margin-top: 5px; }

.note {
  display: flex; gap: var(--s2); padding: 10px 12px; border-radius: var(--r-sm);
  background: var(--surface-2); border: 1px solid var(--line);
  font-size: 12.5px; color: var(--ink-2); line-height: 1.6;
}
.note.warn { background: var(--warn-weak); border-color: var(--warn-line); color: #7A4A05; }
.note.rule { background: var(--brand-weak); border-color: var(--brand-line); color: #1D3FA8; }
.note.bad  { background: var(--danger-weak); border-color: var(--danger-line); color: #9E1F1F; }
.note .m { flex: 0 0 auto; opacity: .8; }

/* ===== 金额 / 凭证：可点反查 ===== */
.lnk { color: var(--brand); text-decoration: none; border-bottom: 1px dashed var(--brand-line); cursor: pointer; }
.lnk:hover { border-bottom-style: solid; }
.bad, .num.bad { color: var(--danger); }
.tbl tr.row-bad { background: var(--danger-weak); }
.tbl tr.row-bad:hover { background: var(--danger-weak); }
/* 🔴 「现在等你动手」的行（2026-10-20）—— 列表分段之后，段内仍有先后：
   左侧一条品牌色，扫一眼就能定位自己那几单；不用加背景色（会跟 row-bad 打架） */
.tbl tr.row-me td:first-child { box-shadow: inset 3px 0 0 var(--brand); }
.tbl tr.row-me:hover td:first-child { box-shadow: inset 3px 0 0 var(--brand); }
/* 折叠区里的小节标题（订单详情「售后与评价」把三块并进一折） */
.fold-bd .sub-hd { margin: 14px 0 6px; font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.fold-bd .sub-hd:first-child { margin-top: 0; }

/* ===== P01 登录页 ===== */
/* 🔴 登录页铺满视口 + **渐变底** —— 与参考站统一：
   白底冷、像后台工具；渐变有氛围、像「给人用的产品」。
   ⚠️ 渐变色**取自品牌蓝**（--brand-lo → --brand → --brand-hi 的等效值）——
      温馨感来自渐变这件事本身，不必改成绿色，品牌色不动。
   ⚠️ `min-height:100vh` 必须配 `padding`，窄屏卡片才不会贴边。 */
.login-wrap {
  display: grid; place-items: center; min-height: 100vh;
  padding: 40px 16px 64px;
  background: linear-gradient(135deg, #2550D6 0%, #2F5BE8 55%, #4570F0 100%);
}
.login-card {
  width: 100%; max-width: 392px; background: var(--surface);
  border: 1px solid rgba(255, 255, 255, .6); border-radius: 20px;
  padding: 38px 30px 28px; text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .25);
  animation: rise 420ms var(--spring) both;
}
/* 🔴 **`margin: 0 auto` 是「脱节」的真凶**（2026-10-21）：`.cardhead` 是 flex row，
   子项上的 auto 左右边距会吃掉**整行剩余空间** —— 图标被推到中间、文字被甩到右边，
   量出来是 37px 的空当（顶栏只有 6px）。现在靠 `justify-content` 让整组居中。 */
/* 🔴 **图标要与名称块等高**（2026-10-21）：登录卡这里原来是 52px 见方，
   配上 17px 标题 + 11px 副标题（两行合计约 40px）就是**头重脚轻** ——
   图标比整块文字还高，看着像「徽章 + 一段说明」，不像一个品牌锁版。
   实测文字块高 46px，图标取 **44px**（比例 0.96）：几乎等高，但图标**不压**文字 ——
   反过来（图标高过文字块）就又回到头重脚轻。
   圆角 11px（约 4:1）—— 比等比缩放的 13px 再方一点：
   「官方稳重」的观感靠**小圆角 + 齐边**，圆角一大就往活泼/玩具那边走。 */
.login-card .brand-mark {
  /* 🔴 业务方已确认「比例完美定版」：名称块 47px，图标 47×47（1:1），不垫底、不描边。 */
  width: 47px; height: 47px; margin: 0; border-radius: 12px;
  display: grid; place-items: center;
  font-size: 24px; font-weight: 700; letter-spacing: 0;
}
.login-card .field { text-align: left; }
.login-card .field label { display: block; margin-bottom: 5px; }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); }
.tabs button {
  padding: 8px 14px; font-size: 13.5px; color: var(--ink-2); position: relative;
  transition: color var(--dur-1) var(--ease);
}
.tabs button:hover { color: var(--ink); }
.tabs button.on { color: var(--brand); font-weight: 600; }
.tabs button.on::after {
  content: ''; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px;
  background: var(--brand); border-radius: 2px;
  animation: tabIn var(--dur-2) var(--spring);
}
@keyframes tabIn { from { transform: scaleX(.3); opacity: 0; } to { transform: none; opacity: 1; } }

.chips { display: flex; gap: var(--s2); flex-wrap: wrap; }
.chip {
  padding: 5px 12px; border-radius: 999px; border: 1px solid var(--line-2);
  background: var(--surface); font-size: 12.5px; color: var(--ink-2);
  transition: all var(--dur-1) var(--ease);
}
.chip:hover { border-color: var(--line-3); color: var(--ink); }
.chip.on { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 550; }

.pager { display: flex; align-items: center; gap: var(--s2); font-size: 12.5px; color: var(--ink-3); }
.pager .pg {
  min-width: 28px; height: 28px; padding: 0 6px; border-radius: var(--r-xs);
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-2);
  transition: all var(--dur-1) var(--ease);
}
.pager .pg:hover { border-color: var(--line-3); }
.pager .pg.on { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }

.empty { padding: var(--s10) var(--s5); text-align: center; color: var(--ink-3); }
.empty .ic { font-size: 34px; opacity: .35; margin-bottom: var(--s3); }

/* 二维码占位 */
.qr {
  width: 208px; height: 208px; border-radius: var(--r); background: var(--surface);
  border: 1px solid var(--line); display: grid; place-items: center; position: relative;
  box-shadow: var(--sh-1);
}
.qr .grid {
  width: 176px; height: 176px;
  background-image:
    linear-gradient(45deg, var(--ink) 25%, transparent 25%, transparent 75%, var(--ink) 75%),
    linear-gradient(45deg, var(--ink) 25%, transparent 25%, transparent 75%, var(--ink) 75%);
  background-size: 16px 16px; background-position: 0 0, 8px 8px; opacity: .9;
}
.qr .corner { position: absolute; width: 22px; height: 22px; border: 3px solid var(--ink); }
.qr .c1 { top: 12px; left: 12px; border-right: 0; border-bottom: 0; border-radius: 4px 0 0 0; }
.qr .c2 { top: 12px; right: 12px; border-left: 0; border-bottom: 0; border-radius: 0 4px 0 0; }
.qr .c3 { bottom: 12px; left: 12px; border-right: 0; border-top: 0; border-radius: 0 0 0 4px; }
.qr .logo {
  position: absolute; width: 42px; height: 42px; border-radius: 10px; background: #fff;
  display: grid; place-items: center; font-size: 18px; box-shadow: 0 0 0 3px #fff;
}
.qr .scanline {
  position: absolute; left: 14px; right: 14px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--brand), transparent);
  animation: scan 2.4s var(--ease) infinite; opacity: .8;
}
@keyframes scan { 0% { top: 16px; opacity: 0; } 12% { opacity: .9; } 88% { opacity: .9; } 100% { top: 186px; opacity: 0; } }

/* 原型说明条 */
.protobar {
  display: flex; align-items: center; gap: var(--s3);
  padding: 9px var(--s5); font-size: 12.5px;
  background: linear-gradient(90deg, #EEF2FE, #F7F9FF);
  border: 1px solid var(--brand-line); border-radius: var(--r-sm); color: #1D3FA8;
  margin-bottom: var(--s5);
}
.protobar .x { margin-left: auto; color: var(--brand); font-size: 15px; line-height: 1; opacity: .7; }
.protobar .x:hover { opacity: 1; }

/* ---------- 17. 响应式（不拆文件，只切样式） ---------- */
@media (max-width: 1199px) {
  .sidebar { width: var(--side-w-md); padding: var(--s4) var(--s2); }
  .sidebar .nav-group-t, .sidebar .nav-item span.tx, .sidebar .nav-item .cnt, .sidebar .nav-item .lock { display: none; }
  .sidebar .nav-item { justify-content: center; padding: 10px 0; }
  .main { margin-left: var(--side-w-md); }
  .wrap { padding: var(--s5) var(--s5) var(--s10); }
  .g4 { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .effects { grid-template-columns: 1fr; }
}
@media (max-width: 767px) {
  .sidebar { transform: translateX(-100%); width: 232px; box-shadow: var(--sh-3); transition: transform var(--dur-3) var(--ease); }
  .sidebar .nav-group-t, .sidebar .nav-item span.tx, .sidebar .nav-item .cnt { display: block; }
  .sidebar .nav-item { justify-content: flex-start; padding: 8px var(--s3); }
  .sidebar.open { transform: none; }
  /* 汉堡按钮在 HTML 里内联了 display:none，这里必须 !important 才能放开 —— 否则手机端打不开导航 */
  #navToggle { display: inline-flex !important; }
  .main { margin-left: 0; }
  .wrap { padding: var(--s4) var(--s4) 96px; }
  .g2, .g3, .g4, .split, .split-form { grid-template-columns: 1fr; }
  .topbar { padding: 0 var(--s3); gap: var(--s2); }
  .brand-sub, .cust-chip span.tx { display: none; }
  .brand, .role-switch, .topbar .icon-btn { flex: 0 0 auto; white-space: nowrap; }
  .page-head .acts { width: 100%; }
  /* 主操作移到底部固定条 */
  .actbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
    background: rgba(255,255,255,.94); backdrop-filter: blur(12px);
    border-top: 1px solid var(--line); padding: var(--s3) var(--s4) calc(var(--s3) + env(safe-area-inset-bottom));
    display: flex; gap: var(--s2);
  }
  .actbar .btn { flex: 1; }
  /* 🔴 下面五条属于**已废弃的 `.stepbar` 组件**（现在只有 `UI.steps` 的 `.steps` 在用）。
     原来 `.step` 没限定父级 —— 7 条 `min-width:62px` 把**七步进度条**也钉成 434px 宽，
     而容器只有 346px：手机上第 6/7 格「收单 · 售后」被裁在视口外（实测 5/7 可见，
     每一张订单详情都中）。给自己人留后路 = 限定到 `.stepbar` 之内。 */
  .stepbar { overflow-x: auto; padding-bottom: var(--s2); }
  .stepbar .step { min-width: 62px; }
  .stepbar .bypass { top: 42px; }
  .stepbar .bypass-branch .stem { height: 7px; }
  .stepbar .bypass-branch .node { font-size: 10px; padding: 1px 6px; }
}

/* 统计卡数值的单位后缀 */
.v .u { margin-left: 6px; font-size: 13px; font-weight: 400; color: var(--ink-3); }

/* ===== 流程链：表达「旁路 / 分支」，灰色虚线 = 不占主链编号〔R-10〕 ===== */
.chain { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.chain .node {
  padding: 5px 12px; border-radius: 999px; font-size: 13px;
  background: var(--surface-3); border: 1px solid var(--line-2); color: var(--ink-3);
  transition: all var(--dur-1) var(--ease);
}
.chain .node.on {
  background: var(--main-weak); border-color: var(--brand-line);
  color: var(--brand); font-weight: 600;
}
.chain .node.dim { border-style: dashed; }
.chain .arw {
  font-size: 11px; color: var(--ink-4); padding: 0 2px;
  border-bottom: 1px dashed var(--line-3); line-height: 1.4;
}

/* 待办卡左侧的序号圆标（P01） */
.todo-ic {
  width: 30px; height: 30px; flex: none; border-radius: 999px;
  display: grid; place-items: center; font-size: 13px; font-weight: 600;
  background: var(--main-weak); color: var(--brand); border: 1px solid var(--brand-line);
}

/* ---------- 趋势柱状图（P25 统计盈亏） ---------- */
.bars { display: flex; align-items: flex-end; gap: 10px; height: 196px; }
.bars .bar { flex: 1; height: 100%; display: flex; flex-direction: column;
  justify-content: flex-end; align-items: center; gap: 6px; }
.bars .bar .pair { flex: 1; display: flex; align-items: flex-end; justify-content: center; gap: 4px; width: 100%; }
.bars .bar .col { width: 15px; border-radius: 4px 4px 0 0; background: var(--main);
  min-height: 3px; transition: height .35s ease; }
.bars .bar .col.g { background: var(--complete); }
.bars .bar .lb { font-size: 11px; color: var(--ink-3); white-space: nowrap; }
.bars .bar .vv { font-size: 11px; font-weight: 600; color: var(--ink-2); white-space: nowrap; }
@media (max-width: 640px) {
  .bars { height: 160px; gap: 6px; }
  .bars .bar .col { width: 9px; }
  .bars .bar .lb, .bars .bar .vv { font-size: 10px; }
}

/* ---------- 指派关系（客户组 / 审单组） ----------
   🔴 用户 2026-10-20：「客户组和审单组怎么操作的，没看有操作界面」——
      原来这一页只有裸元素：左边一排链接、右边一个复选框，看着像草稿不像操作台。
      这里补成「左人名 · 右勾选」的两栏，勾选做成网格卡片，底部一条变更摘要。 */
.asg2 { display: grid; grid-template-columns: 246px 1fr; gap: var(--s4); align-items: start; }
@media (max-width: 820px) { .asg2 { grid-template-columns: 1fr; } }

/* 左：人员列表 */
.asg2-people { display: flex; flex-direction: column; gap: 6px; }
.asg2-p {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 9px 11px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); transition: border-color .16s, background .16s;
}
.asg2-p:hover { border-color: var(--brand-line); background: var(--surface-2); }
.asg2-p.on { border-color: var(--brand); background: var(--brand-weak); }
.asg2-p .av {
  width: 28px; height: 28px; flex: none; border-radius: 999px; display: grid;
  place-items: center; font-size: 12px; font-weight: 600;
  background: var(--surface-3); color: var(--ink-2);
}
.asg2-p.on .av { background: var(--brand); color: #fff; }
.asg2-p > span:not(.av):not(.n) { display: flex; flex-direction: column; min-width: 0; }
.asg2-p .nm { font-size: 13px; font-weight: 550; color: var(--ink); line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.asg2-p .ph { font-size: 11px; color: var(--ink-3); line-height: 1.3; }
.asg2-p .n {
  margin-left: auto; flex: none; white-space: nowrap;
  font-size: 11px; font-weight: 600; color: var(--brand);
  background: var(--surface); border: 1px solid var(--brand-line);
  border-radius: 999px; padding: 2px 8px;
}
.asg2-p.on .n { background: #fff; }

/* 右：勾选面板 */
.asg2-panel { border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); overflow: hidden; }
.asg2-hd {
  display: flex; align-items: center; gap: var(--s2); padding: 10px var(--s3);
  border-bottom: 1px solid var(--line); background: var(--surface-2);
}
.asg2-hd .t { font-size: 13px; font-weight: 600; }
.asg2-hd .s { font-size: 11.5px; color: var(--ink-3); }
.asg2-srch {
  margin-left: auto; width: 168px; padding: 5px 10px; font-size: 12px;
  border: 1px solid var(--line-2); border-radius: 999px; outline: none; background: #fff;
}
.asg2-srch:focus { border-color: var(--brand); }
.asg2-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
  gap: 2px 10px; padding: var(--s3); max-height: 320px; overflow: auto;
}
.asg2-c {
  display: flex; align-items: center; gap: 8px; padding: 7px 8px;
  border-radius: var(--r-xs); cursor: pointer; font-size: 13px; color: var(--ink);
  line-height: 1.3;
}
.asg2-c:hover { background: var(--surface-3); }
.asg2-c input { width: 15px; height: 15px; accent-color: var(--brand); cursor: pointer; flex: none; }
.asg2-c .else { font-size: 11px; color: var(--warn); background: var(--warn-weak);
  border-radius: 999px; padding: 0 6px; margin-left: 2px; }
.asg2-c.hid { display: none; }
.asg2-ft {
  display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
  padding: 10px var(--s3); border-top: 1px solid var(--line); background: var(--surface-2);
}
.asg2-ft .chg { font-size: 12px; color: var(--ink-3); }
.asg2-ft .chg b { color: var(--brand); font-weight: 600; }
.asg2-ft .chg i { color: var(--danger); font-style: normal; font-weight: 600; }
.asg2-empty { padding: var(--s5); text-align: center; font-size: 13px; color: var(--ink-3); }
/* 未归属警示条 */
.asg2-warn {
  display: flex; align-items: center; gap: 8px; padding: 9px var(--s3);
  border: 1px solid var(--warn-line); background: var(--warn-weak);
  border-radius: var(--r-sm); font-size: 12.5px; color: var(--warn); margin-bottom: var(--s3);
}

/* 尊重系统「减少动效」 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- 版本哨兵条（`app.js` 的 watchBuild） ----------
   只在「服务器已是新版、页面还是旧版」时出现 —— 让界面自己说出
   「你看到的是旧页面」，而不是要求用户记住 Ctrl+F5（2026-10-20）。 */
.ver-bar {
  position: fixed; inset: 0 0 auto 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  padding: 8px 16px; font-size: 13px; line-height: 1.4;
  background: var(--warn-weak); color: var(--warn);
  border-bottom: 1px solid var(--warn-line);
}
.ver-bar .btn { padding: 3px 10px; font-size: 12px; }
