/* ============================================================================
   立邦供应商风控系统 · 设计令牌与基础组件
   归属：地基（前端外壳会话）。并行会话请直接复用下面的组件类，
   需要新颜色时在 :root / 两处暗色块里各加一次令牌，不要在组件里写字面色值。

   纪律（改这个文件前必读）：
   1. 全站只用令牌，禁止字面色值（#xxxxxx / rgb(...)）出现在组件规则里。
   2. 任何颜色都不能只定义在媒体查询里 —— 亮色是基准，暗色只做重定义。
   3. 暗色要写两份：@media (prefers-color-scheme: dark) 里的 :root:not([data-theme="light"])
      与手动切换的 :root[data-theme="dark"]，两份令牌必须一致。
   4. 不在 html / body 上写 overflow-x: hidden（会破坏 sticky），用 overflow-x: clip。
   5. 过场一律用 CSS transition，不要用 requestAnimationFrame 驱动。
   ========================================================================= */

/* ── 令牌：亮色（基准，全部颜色都在这里有定义） ───────────────────────── */
:root {
  /* 底色与文字 */
  --ground:       #F5F6F9;
  --card:         #FFFFFF;
  --card-2:       #F8F9FC;   /* 表头 / 次级分区底 */
  --ink:          #1D2434;
  --muted:        #5C6678;
  --faint:        #8B94A8;   /* 更弱一级的说明文字 */

  /* 描边 */
  --line:         #E2E6EE;
  --line-strong:  #C9D0DC;

  /* 主色（靛蓝） */
  --accent:       #33518E;
  --accent-soft:  #E8EDF7;
  --accent-ink:   #2A4478;
  --accent-on:    #FFFFFF;   /* 主色底上的文字 */

  /* 语义色（与主色分开，不当强调色用） */
  --deny:         #8F2B20;   --deny-bg:  #F6E4E1;
  --red:          #A93B2D;   --red-bg:   #FBEAE7;
  --warn:         #7A5410;   --warn-bg:  #F7EDD8;
  --ok:           #23604A;   --ok-bg:    #E4EFEA;

  /* 中性标记（模拟接口、建设中等，绝不用告警色） */
  --chip-bg:      #EEF1F6;
  --chip-ink:     #5C6678;

  /* 遮罩与投影 */
  --overlay:      rgba(29, 36, 52, .48);
  --shadow-sm:    0 1px 2px rgba(29, 36, 52, .06);
  --shadow:       0 2px 10px rgba(29, 36, 52, .09);
  --shadow-lg:    0 12px 40px rgba(29, 36, 52, .20);
  --focus-ring:   0 0 0 3px rgba(51, 81, 142, .28);

  /* 尺寸 */
  --r-sm: 4px;  --r: 6px;  --r-lg: 10px;  --r-pill: 999px;
  --sidebar-w: 216px;
  --header-h: 56px;

  /* 字号（B 端后台：信息密度优先） */
  --fs-xs: 12px; --fs-sm: 13px; --fs: 14px;
  --fs-lg: 16px; --fs-xl: 20px; --fs-2xl: 26px; --fs-3xl: 32px;

  --font: "PingFang SC", "Microsoft YaHei", system-ui, -apple-system, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ── 令牌：暗色（跟随系统） ─────────────────────────────────────────── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground:      #0F1319;
    --card:        #171C25;
    --card-2:      #1D2330;
    --ink:         #E6EAF2;
    --muted:       #96A0B2;
    --faint:       #7A8497;

    --line:        #262D3A;
    --line-strong: #3A4354;

    --accent:      #7FA0DF;
    --accent-soft: #1C2740;
    --accent-ink:  #A9C0EC;
    --accent-on:   #101725;

    --deny:        #F0968A;   --deny-bg: #3A201B;
    --red:         #E2937B;   --red-bg:  #33231C;
    --warn:        #D8B565;   --warn-bg: #2F2712;
    --ok:          #5FBF9A;   --ok-bg:   #143026;

    --chip-bg:     #232A37;
    --chip-ink:    #96A0B2;

    --overlay:     rgba(0, 0, 0, .64);
    --shadow-sm:   0 1px 2px rgba(0, 0, 0, .40);
    --shadow:      0 2px 10px rgba(0, 0, 0, .45);
    --shadow-lg:   0 12px 40px rgba(0, 0, 0, .60);
    --focus-ring:  0 0 0 3px rgba(127, 160, 223, .32);
  }
}

/* ── 令牌：暗色（右上角手动切换，与上面保持一致） ────────────────────── */
:root[data-theme="dark"] {
  --ground:      #0F1319;
  --card:        #171C25;
  --card-2:      #1D2330;
  --ink:         #E6EAF2;
  --muted:       #96A0B2;
  --faint:       #7A8497;

  --line:        #262D3A;
  --line-strong: #3A4354;

  --accent:      #7FA0DF;
  --accent-soft: #1C2740;
  --accent-ink:  #A9C0EC;
  --accent-on:   #101725;

  --deny:        #F0968A;   --deny-bg: #3A201B;
  --red:         #E2937B;   --red-bg:  #33231C;
  --warn:        #D8B565;   --warn-bg: #2F2712;
  --ok:          #5FBF9A;   --ok-bg:   #143026;

  --chip-bg:     #232A37;
  --chip-ink:    #96A0B2;

  --overlay:     rgba(0, 0, 0, .64);
  --shadow-sm:   0 1px 2px rgba(0, 0, 0, .40);
  --shadow:      0 2px 10px rgba(0, 0, 0, .45);
  --shadow-lg:   0 12px 40px rgba(0, 0, 0, .60);
  --focus-ring:  0 0 0 3px rgba(127, 160, 223, .32);
}

/* ── 基础 ──────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  overflow-x: clip;              /* 不用 hidden：会破坏 sticky */
  font-family: var(--font);
  font-size: var(--fs);
  line-height: 1.6;
  color: var(--ink);
  background: var(--ground);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.35; }
p  { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-ink); text-decoration: underline; }

img, svg { max-width: 100%; }

button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--r-sm); }

::selection { background: var(--accent-soft); color: var(--accent-ink); }

/* 数字列：等宽数字，便于纵向比对 */
.num, .tnum, td.num, th.num { font-variant-numeric: tabular-nums; }
.num, td.num, th.num { text-align: right; }
.mono { font-family: var(--mono); font-size: var(--fs-sm); }

/* ── 工具类 ────────────────────────────────────────────────────────── */
.muted   { color: var(--muted); }
.faint   { color: var(--faint); }
.small   { font-size: var(--fs-sm); }
.xsmall  { font-size: var(--fs-xs); }
.strong  { font-weight: 600; }
.nowrap  { white-space: nowrap; }
.row     { display: flex; align-items: center; gap: 8px; }
.row-wrap{ display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.spread  { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.stack   { display: flex; flex-direction: column; gap: 4px; }
.grow    { flex: 1 1 auto; min-width: 0; }
.hide    { display: none !important; }
.truncate{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ══════════════════════════════════════════════════════════════════════
   登录页
   ═══════════════════════════════════════════════════════════════════ */
.login-wrap {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px 16px;
  background: var(--ground);
}
.login-card {
  width: 100%; max-width: 380px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  padding: 32px 28px 26px;
}
.login-mark {
  width: 38px; height: 38px; border-radius: var(--r);
  background: var(--accent); color: var(--accent-on);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-lg); font-weight: 600; letter-spacing: .5px;
  margin-bottom: 16px;
}
.login-card h1 { font-size: var(--fs-xl); letter-spacing: .5px; }
.login-card .sub { color: var(--muted); font-size: var(--fs-sm); margin-top: 4px; }
.login-form { margin-top: 24px; display: flex; flex-direction: column; gap: 14px; }
.login-hint {
  margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line);
  color: var(--faint); font-size: var(--fs-xs); line-height: 1.7;
}

/* ── 表单 ─────────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label { font-size: var(--fs-sm); color: var(--muted); }

.input, .select {
  width: 100%;
  padding: 8px 10px;
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.input::placeholder { color: var(--faint); }
.input:hover, .select:hover { border-color: var(--accent); }
.input:focus, .select:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }

.select {
  appearance: none;
  padding-right: 28px;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 15px) 52%, calc(100% - 10px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.btn:hover { border-color: var(--accent); color: var(--accent-ink); }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-primary {
  background: var(--accent); border-color: var(--accent); color: var(--accent-on);
}
.btn-primary:hover { background: var(--accent-ink); border-color: var(--accent-ink); color: var(--accent-on); }
.btn-block { width: 100%; padding: 10px 14px; }
.btn-sm { padding: 4px 10px; font-size: var(--fs-sm); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn-ghost:hover { background: var(--chip-bg); color: var(--ink); border-color: transparent; }
.btn-icon { padding: 6px 8px; }

/* 提示条 */
.alert {
  padding: 8px 12px; border-radius: var(--r);
  font-size: var(--fs-sm); line-height: 1.6;
  border: 1px solid var(--line);
  background: var(--card-2); color: var(--muted);
}
.alert-error  { background: var(--red-bg);  color: var(--red);  border-color: var(--red-bg); }
.alert-ok     { background: var(--ok-bg);   color: var(--ok);   border-color: var(--ok-bg); }
.alert-info   { background: var(--accent-soft); color: var(--accent-ink); border-color: var(--accent-soft); }

/* ══════════════════════════════════════════════════════════════════════
   外壳：侧边导航 + 顶栏 + 内容区
   ═══════════════════════════════════════════════════════════════════ */
.shell { display: flex; min-height: 100vh; }

.sidebar {
  flex: 0 0 var(--sidebar-w);
  width: var(--sidebar-w);
  background: var(--card);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
.brand {
  height: var(--header-h);
  display: flex; align-items: center; gap: 10px;
  padding: 0 16px;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}
.brand-mark {
  width: 26px; height: 26px; flex: 0 0 26px; border-radius: var(--r-sm);
  background: var(--accent); color: var(--accent-on);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .5px;
}
.brand-text { font-size: var(--fs-sm); font-weight: 600; letter-spacing: .3px; }

.nav { padding: 12px 10px; display: flex; flex-direction: column; gap: 2px; overflow-y: auto; }
.nav-group-label {
  font-size: var(--fs-xs); color: var(--faint);
  padding: 12px 8px 4px; letter-spacing: .5px;
}
.nav-item {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px;
  border-radius: var(--r);
  color: var(--muted);
  font-size: var(--fs);
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.nav-item:hover { background: var(--chip-bg); color: var(--ink); text-decoration: none; }
.nav-item.active { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; }
.nav-item .nav-ico { flex: 0 0 16px; width: 16px; height: 16px; opacity: .85; }
.nav-item.active .nav-ico { opacity: 1; }
.nav-item .grow { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  height: var(--header-h);
  flex: 0 0 auto;
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 12px;
  padding: 0 20px;
  background: var(--card);
  border-bottom: 1px solid var(--line);
}
.topbar-title { font-size: var(--fs-lg); font-weight: 600; }

.who { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.3; }
.who-name { font-size: var(--fs-sm); font-weight: 600; }
.who-role { font-size: var(--fs-xs); color: var(--muted); }

.view { flex: 1 1 auto; padding: 20px; min-width: 0; }

/* 窄屏：侧栏变顶部横向导航条，主体永不横向滚动 */
@media (max-width: 880px) {
  .shell { flex-direction: column; }
  .sidebar {
    flex: 0 0 auto; width: 100%; height: auto; position: static;
    border-right: none; border-bottom: 1px solid var(--line);
  }
  .nav {
    flex-direction: row; gap: 4px;
    overflow-x: auto; overflow-y: hidden;
    padding: 8px 10px;
    scrollbar-width: thin;
  }
  .nav-item { white-space: nowrap; padding: 6px 12px; }
  .nav-group-label { display: none; }
  .nav-item .nav-ico { display: none; }
  .topbar { padding: 0 14px; gap: 8px; }
  .topbar-title { font-size: var(--fs); }
  .view { padding: 14px; }
  .who { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════
   通用容器
   ═══════════════════════════════════════════════════════════════════ */
.page-head { margin-bottom: 16px; }
.page-head h2 { font-size: var(--fs-xl); }
.page-head .desc { color: var(--muted); font-size: var(--fs-sm); margin-top: 4px; }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.card + .card { margin-top: 16px; }
.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.card-head h3 { font-size: var(--fs); }
.card-head .sub { color: var(--muted); font-size: var(--fs-xs); }
.card-body { padding: 16px; }
.card-body.tight { padding: 0; }

.sec { margin-bottom: 16px; }

.grid { display: grid; gap: 12px; }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1080px) { .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 880px)  { .grid-3, .grid-2 { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 560px)  { .grid-4 { grid-template-columns: minmax(0, 1fr); } }

/* ── 统计卡 ───────────────────────────────────────────────────────── */
.stat {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 14px 16px;
  box-shadow: var(--shadow-sm);
}
.stat-label { font-size: var(--fs-sm); color: var(--muted); }
.stat-value {
  font-size: var(--fs-3xl); font-weight: 600; line-height: 1.2;
  font-variant-numeric: tabular-nums;
  margin-top: 6px;
}
.stat-unit { font-size: var(--fs-sm); font-weight: 400; color: var(--muted); margin-left: 4px; }
.stat-foot { font-size: var(--fs-xs); color: var(--faint); margin-top: 6px; }
.stat-value.tone-deny { color: var(--deny); }
.stat-value.tone-red  { color: var(--red); }
.stat-value.tone-warn { color: var(--warn); }
.stat-value.tone-ok   { color: var(--ok); }

/* ── chip / 标记 ─────────────────────────────────────────────────── */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 1px 8px;
  border-radius: var(--r-pill);
  font-size: var(--fs-xs); line-height: 1.7;
  white-space: nowrap;
  background: var(--chip-bg); color: var(--chip-ink);
}
.chip-deny { background: var(--deny-bg); color: var(--deny); }
.chip-red  { background: var(--red-bg);  color: var(--red); }
.chip-warn { background: var(--warn-bg); color: var(--warn); }
.chip-ok   { background: var(--ok-bg);   color: var(--ok); }
.chip-accent { background: var(--accent-soft); color: var(--accent-ink); }
/* 未运算：中性灰，与「无预警」的绿色区分开 */
.chip-muted { background: var(--line); color: var(--muted); }
/* 待人工判定：算过了但数据不全判不了。用主色而非语义色——它不是一档风险，
   而是「系统拒绝下结论」，要显眼到有人去处理，但不能读成红色预警。 */
.chip-manual { background: var(--accent-soft); color: var(--accent-ink); }
/* 资料弹层里的 PDF 内嵌预览 */
.viewer-pdf { width: 100%; height: 60vh; min-height: 320px; border: none;
  background: var(--card); border-radius: 6px; }

/* ══ 登录页的演示账号一点即登 ══
   由服务端 demo_login_hint 开关控制，关掉后这一块不渲染。
   用主色浅底而不是语义色：它不是一档风险状态，是个便捷入口。 */
.demo-accts { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 14px; }
.demo-accts-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px; flex-wrap: wrap; margin-bottom: 8px;
}
.demo-accts-title { font-size: var(--fs-sm); font-weight: 600; color: var(--ink); }
.demo-accts-pwd {
  font-size: var(--fs-xs); color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.demo-acct {
  display: grid; grid-template-columns: auto auto 1fr; align-items: baseline;
  gap: 4px 10px; width: 100%; text-align: left;
  padding: 8px 10px; margin-bottom: 6px;
  background: var(--accent-soft); color: var(--accent-ink);
  border: 1px solid transparent; border-radius: 6px;
  font: inherit; font-size: var(--fs-sm); cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.demo-acct:last-child { margin-bottom: 0; }
.demo-acct:hover { border-color: var(--accent); }
.demo-acct:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.demo-acct-name { font-weight: 600; }
.demo-acct-role { font-size: var(--fs-xs); opacity: .85; }
.demo-acct-note {
  font-size: var(--fs-xs); color: var(--muted);
  text-align: right; min-width: 0; overflow-wrap: anywhere;
}
@media (max-width: 420px) {
  .demo-acct { grid-template-columns: auto 1fr; }
  .demo-acct-note { grid-column: 1 / -1; text-align: left; }
}
.chip-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 6px; }

/* 中性小标记：模拟接口 / 建设中，绝不用告警色 */
.tag-neutral {
  display: inline-flex; align-items: center;
  padding: 0 6px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  font-size: var(--fs-xs); line-height: 1.6;
  color: var(--muted); background: transparent;
}

/* ── 表格 ─────────────────────────────────────────────────────────── */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
}
.tbl.wide { min-width: 900px; }
.tbl.mid  { min-width: 640px; }
.tbl th {
  text-align: left; font-weight: 600; color: var(--muted);
  background: var(--card-2);
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.tbl td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
.tbl tbody tr:last-child td { border-bottom: none; }
.tbl tbody tr.clickable { cursor: pointer; transition: background-color .12s ease; }
.tbl tbody tr.clickable:hover { background: var(--card-2); }
.tbl .cell-id { font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); }

/* ── 描述列表（基本信息） ─────────────────────────────────────────── */
.dl { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px 24px; }
@media (max-width: 880px) { .dl { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px) { .dl { grid-template-columns: minmax(0, 1fr); } }
.dl-item { min-width: 0; }
.dl-key { font-size: var(--fs-xs); color: var(--muted); }
.dl-val { font-size: var(--fs); margin-top: 2px; word-break: break-word; }

/* ── 分布条（手写，无第三方图表库） ─────────────────────────────────── */
.dist { display: flex; height: 14px; border-radius: var(--r-pill); overflow: hidden; background: var(--chip-bg); }
.dist-seg { height: 100%; transition: width .3s ease; }
.dist-seg.seg-deny { background: var(--deny); }
.dist-seg.seg-red  { background: var(--red); }
.dist-seg.seg-warn { background: var(--warn); }
.dist-seg.seg-ok   { background: var(--ok); }
.dist-legend { display: flex; flex-wrap: wrap; gap: 8px 20px; margin-top: 12px; }
.dist-legend-item { display: flex; align-items: baseline; gap: 6px; font-size: var(--fs-sm); }
.dist-key { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); }
.dist-swatch { width: 8px; height: 8px; border-radius: 2px; flex: 0 0 8px; }
.dist-swatch.seg-deny { background: var(--deny); }
.dist-swatch.seg-red  { background: var(--red); }
.dist-swatch.seg-warn { background: var(--warn); }
.dist-swatch.seg-ok   { background: var(--ok); }
.dist-seg.seg-muted, .dist-swatch.seg-muted { background: var(--line-strong); }
.dist-n { font-weight: 600; font-variant-numeric: tabular-nums; }

/* 阶段条（横向，逐行） */
.bars { display: flex; flex-direction: column; gap: 10px; }
.bar-row { display: grid; grid-template-columns: 88px 1fr 44px; align-items: center; gap: 10px; }
.bar-name { font-size: var(--fs-sm); color: var(--muted); }
.bar-track { height: 10px; background: var(--chip-bg); border-radius: var(--r-pill); overflow: hidden; }
.bar-fill { height: 100%; background: var(--accent); border-radius: var(--r-pill); transition: width .3s ease; }
.bar-n { font-size: var(--fs-sm); font-variant-numeric: tabular-nums; text-align: right; }

/* 回款比例微条 */
.minibar { display: inline-flex; align-items: center; gap: 6px; }
.minibar-track { width: 52px; height: 5px; border-radius: var(--r-pill); background: var(--chip-bg); overflow: hidden; }
.minibar-fill { height: 100%; background: var(--accent); }
.minibar-fill.low { background: var(--warn); }

/* ── 工具栏 / 筛选 ─────────────────────────────────────────────────── */
.toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.toolbar .select { width: auto; min-width: 120px; }
.toolbar .input { width: auto; min-width: 200px; flex: 1 1 200px; max-width: 320px; }

/* ── 空态 / 载入 ──────────────────────────────────────────────────── */
.empty { padding: 44px 20px; text-align: center; color: var(--muted); font-size: var(--fs-sm); }
.empty-title { font-size: var(--fs); color: var(--ink); margin-bottom: 4px; }

.skeleton { padding: 40px 20px; text-align: center; color: var(--faint); font-size: var(--fs-sm); }
.spinner {
  display: inline-block; width: 15px; height: 15px; vertical-align: -2px; margin-right: 8px;
  border: 2px solid var(--line-strong); border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ── 详情页专用 ───────────────────────────────────────────────────── */
.detail-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 16px;
}
.detail-title { font-size: var(--fs-xl); }
.detail-meta { color: var(--muted); font-size: var(--fs-sm); margin-top: 4px; }
.back-link { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-sm); color: var(--muted); }
.back-link:hover { color: var(--accent); text-decoration: none; }

/* 资料清单 */
.doc-group + .doc-group { margin-top: 18px; }
.doc-group-title {
  font-size: var(--fs-sm); color: var(--muted); margin-bottom: 8px;
  padding-bottom: 6px; border-bottom: 1px solid var(--line);
}
.doc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 12px; }
.doc-tile {
  border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden; background: var(--card-2);
  cursor: pointer; text-align: left; padding: 0; width: 100%;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.doc-tile:hover { border-color: var(--accent); box-shadow: var(--shadow-sm); }
.doc-thumb {
  height: 96px; display: flex; align-items: center; justify-content: center;
  background: var(--card); border-bottom: 1px solid var(--line); overflow: hidden;
}
.doc-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 6px; }
.doc-info { padding: 8px 10px; }
.doc-name { font-size: var(--fs-sm); font-weight: 600; }
.doc-sub { font-size: var(--fs-xs); color: var(--muted); margin-top: 2px; }

/* 图片查看弹层 */
.modal {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: var(--overlay);
  opacity: 0; visibility: hidden;
  transition: opacity .18s ease, visibility .18s ease;
}
.modal.open { opacity: 1; visibility: visible; }
.modal-box {
  width: 100%; max-width: 720px; max-height: 90vh;
  display: flex; flex-direction: column;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.modal-body { padding: 16px; overflow: auto; background: var(--card-2); text-align: center; }
.modal-body img { max-height: 62vh; }
.modal-foot { padding: 10px 16px; border-top: 1px solid var(--line); display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

/* 核验结果 */
.verify-list { display: flex; flex-direction: column; }
.verify-row {
  display: grid; grid-template-columns: 1fr auto; gap: 8px 16px;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.verify-row:last-child { border-bottom: none; }
.verify-name { font-size: var(--fs); }
.verify-code { font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); margin-right: 8px; }
.verify-cmp { font-size: var(--fs-sm); color: var(--muted); margin-top: 4px; }
.verify-side { display: flex; align-items: center; gap: 6px; }

/* 预警命中 */
.hit-level-block + .hit-level-block { margin-top: 6px; }
.hit-level-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 16px;
  background: var(--card-2);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-sm); font-weight: 600;
}
.hit-row {
  display: grid; grid-template-columns: 1fr auto;
  gap: 4px 16px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--line);
}
.hit-main { min-width: 0; }
.hit-code { font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); margin-right: 8px; }
.hit-name { font-weight: 600; font-size: var(--fs-sm); }
.hit-sub { font-size: var(--fs-xs); color: var(--muted); margin-top: 3px; line-height: 1.7; }
.hit-actual { color: var(--ink); }

/* 聚合命中：一条规则 × N 个对象，折叠成一行，用 details 展开（零 JS） */
details.hit-agg { border-bottom: 1px solid var(--line); }
details.hit-agg > summary {
  display: grid; grid-template-columns: 1fr auto;
  gap: 4px 16px;
  padding: 11px 16px;
  cursor: pointer;
  list-style: none;
  transition: background-color .12s ease;
}
details.hit-agg > summary::-webkit-details-marker { display: none; }
details.hit-agg > summary:hover { background: var(--card-2); }
details.hit-agg[open] > summary { background: var(--card-2); }
.agg-caret { display: inline-block; color: var(--muted); font-size: var(--fs-xs); transition: transform .18s ease; }
details.hit-agg[open] .agg-caret { transform: rotate(90deg); }
.agg-list { padding: 4px 16px 12px 16px; background: var(--card-2); }
.agg-item {
  display: grid; grid-template-columns: 1fr auto; gap: 8px 16px;
  padding: 7px 0 7px 14px;
  border-left: 2px solid var(--line-strong);
  margin-left: 4px;
  font-size: var(--fs-sm);
}
.agg-item + .agg-item { border-top: 1px solid var(--line); }
.agg-ctx { color: var(--ink); min-width: 0; overflow-wrap: anywhere; }
.agg-val { color: var(--muted); font-size: var(--fs-xs); white-space: nowrap; }

/* 窄屏：这几处「左内容 + 右徽标」的两列栅格要拆成单列。
   页面主体是 overflow-x: clip，右列一旦被挤出视口就是静默裁切 ——
   看不到滚动条，值直接消失，比横向滚动更坑。 */
@media (max-width: 620px) {
  .verify-row,
  .hit-row,
  details.hit-agg > summary,
  .agg-item { grid-template-columns: minmax(0, 1fr); }
  .verify-row .verify-side,
  .hit-row .verify-side,
  details.hit-agg > summary .verify-side { justify-content: flex-start; }
  .agg-val { white-space: normal; }
}

/* 待办 */
.task-row { padding: 12px 16px; border-bottom: 1px solid var(--line); }
.task-row:last-child { border-bottom: none; }
.task-title { font-size: var(--fs-sm); font-weight: 600; }
.task-detail { font-size: var(--fs-xs); color: var(--muted); margin-top: 3px; line-height: 1.7; }

/* ── 接口状态页 ───────────────────────────────────────────────────── */
.intg-row { padding: 14px 16px; border-bottom: 1px solid var(--line); }
.intg-row:last-child { border-bottom: none; }
.intg-name { font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); }
.intg-label { font-size: var(--fs); font-weight: 600; }
.intg-note { font-size: var(--fs-sm); color: var(--muted); margin-top: 6px; line-height: 1.7; }
.intg-fields { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 8px; font-size: var(--fs-xs); color: var(--faint); }
.intg-fields code { font-family: var(--mono); color: var(--muted); }

/* ── 建设中占位页 ─────────────────────────────────────────────────── */
.wip { padding: 56px 24px; text-align: center; }
.wip h3 { font-size: var(--fs-lg); }
.wip p { color: var(--muted); font-size: var(--fs-sm); margin-top: 8px; max-width: 460px; margin-left: auto; margin-right: auto; line-height: 1.8; }

/* ── 轻提示 ───────────────────────────────────────────────────────── */
.toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%) translateY(8px);
  z-index: 200;
  padding: 9px 16px;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--r);
  box-shadow: var(--shadow-lg);
  font-size: var(--fs-sm);
  opacity: 0; visibility: hidden;
  transition: opacity .18s ease, transform .18s ease, visibility .18s ease;
}
.toast.open { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }

/* ── 分页 ─────────────────────────────────────────────────────────── */
.pager {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap;
  padding: 10px 16px; border-top: 1px solid var(--line);
  font-size: var(--fs-sm); color: var(--muted);
}

/* ══════════════════════════════════════════════════════════════
   以下为各并行会话的样式追加区。

   纪律：只在文件末尾追加自己的整块，块内自成体系；
        不要改上面的令牌区和公共组件区，不要动别人的块。
        合并后必须验花括号平衡：
        python3 -c "s=open('web/assets/app.css').read();print(s.count('{')==s.count('}'))"
   详见 docs/06-设计令牌与前端纪律.md
   ══════════════════════════════════════════════════════════════ */

/* >>> BLOCK:S1-collect */
/* ══════════════════════════════════════════════════════════════════════
   S1 客户端采集 —— 移动端优先（先按 375px 设计），复用上面的设计令牌。
   只用令牌，不写字面色值；过场只用 CSS，不用 requestAnimationFrame。
   ═══════════════════════════════════════════════════════════════════ */

/* 客户端 / 销售端两个独立页面的 body（工作台页面不带这个类，互不影响） */
.cl-body-root { background: var(--ground); }

.cl-page {
  display: flex; flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

.cl-body {
  flex: 1 1 auto;
  width: 100%; max-width: 560px;
  margin: 0 auto;
  padding: 16px 16px 24px;
}

.cl-center {
  flex: 1 1 auto;
  display: flex; align-items: center; justify-content: center;
  min-height: 60vh; padding: 24px 16px;
}
.cl-loading { color: var(--muted); font-size: var(--fs-sm); }

/* 内容切换的过场：CSS 动画，后台标签页回来也不会卡死 */
.cl-fade { animation: cl-in .18s ease both; }
@keyframes cl-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ── 顶部：细进度指示 ─────────────────────────────────────────────── */
.cl-top {
  position: sticky; top: 0; z-index: 10;
  background: var(--card);
  border-bottom: 1px solid var(--line);
}
.cl-top-row {
  display: flex; align-items: center; gap: 10px;
  width: 100%; max-width: 560px; margin: 0 auto;
  padding: 10px 16px;
}
.cl-top-label { font-size: var(--fs-sm); font-weight: 600; }
.cl-top-sub { font-size: var(--fs-xs); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cl-step-n { font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

.cl-back {
  flex: 0 0 32px; width: 32px; height: 32px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: none; border-radius: var(--r);
  color: var(--muted); cursor: pointer;
}
.cl-back:hover { background: var(--chip-bg); color: var(--ink); }
.cl-back svg { width: 20px; height: 20px; }

.cl-brand-mark {
  flex: 0 0 30px; width: 30px; height: 30px; border-radius: var(--r-sm);
  background: var(--accent); color: var(--accent-on);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .5px;
}

.cl-bar { height: 3px; background: var(--chip-bg); overflow: hidden; }
.cl-bar-fill { display: block; height: 100%; background: var(--accent); transition: width .25s ease; }
.cl-bar-lg { height: 6px; border-radius: var(--r-pill); }

/* ── 首屏 ─────────────────────────────────────────────────────────── */
.cl-hero {
  padding: 28px 16px 20px;
  text-align: center;
  background: var(--card);
  border-bottom: 1px solid var(--line);
}
.cl-hero .cl-brand-mark { margin: 0 auto 12px; }
.cl-hero-title { font-size: var(--fs-xl); font-weight: 600; }
.cl-hero-sub { font-size: var(--fs-sm); color: var(--muted); margin-top: 4px; }

.cl-facts {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 4px 14px; box-shadow: var(--shadow-sm);
}
.cl-fact {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--line);
}
.cl-fact:last-child { border-bottom: none; }
.cl-fact-k { font-size: var(--fs-sm); color: var(--muted); flex: 0 0 auto; }
.cl-fact-v { font-size: var(--fs-sm); text-align: right; word-break: break-all; }

.cl-steps-brief {
  margin-top: 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm); overflow: hidden;
}
.cl-brief-head {
  padding: 11px 14px; font-size: var(--fs-sm); font-weight: 600;
  background: var(--card-2); border-bottom: 1px solid var(--line);
}
.cl-brief-list { padding: 4px 0; }
.cl-brief-item, .cl-check-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px;
  font-size: var(--fs-sm);
}
.cl-brief-dot {
  flex: 0 0 7px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--line-strong);
}
.cl-brief-item.is-done .cl-brief-dot,
.cl-check-item.is-done .cl-brief-dot { background: var(--ok); }
.cl-check-item.is-missing .cl-brief-dot { background: var(--accent); }
.cl-brief-tag { font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }
.cl-brief-item .grow, .cl-check-item .grow { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cl-tip {
  margin-top: 14px; font-size: var(--fs-sm); color: var(--muted); line-height: 1.8;
}

/* ── 单步内容 ─────────────────────────────────────────────────────── */
.cl-title {
  font-size: var(--fs-lg); font-weight: 600; line-height: 1.4;
  margin: 4px 0 12px;
}
.cl-optional {
  display: inline-block; margin-left: 8px; vertical-align: 2px;
  padding: 0 6px;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  font-size: var(--fs-xs); font-weight: 400; color: var(--muted);
}

.cl-guide-img {
  background: var(--card-2);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  overflow: hidden;
  margin-bottom: 12px;
}
.cl-guide-img img {
  display: block; width: 100%; aspect-ratio: 8 / 5; object-fit: contain;
}
.cl-guide-text { font-size: var(--fs-sm); color: var(--muted); line-height: 1.8; }

.cl-pickers { display: flex; flex-direction: column; gap: 10px; margin: 16px 0 4px; }

.cl-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%;
  padding: 12px 16px;
  border: 1px solid var(--line-strong); border-radius: var(--r);
  background: var(--card); color: var(--ink);
  font-size: var(--fs); font-weight: 600;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease, opacity .15s ease;
}
.cl-btn:hover { border-color: var(--accent); color: var(--accent-ink); }
.cl-btn:disabled, .cl-btn[disabled] { opacity: .5; cursor: not-allowed; }
.cl-btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-on); }
.cl-btn-primary:hover { background: var(--accent-ink); border-color: var(--accent-ink); color: var(--accent-on); }
.cl-btn-outline { background: var(--card); border-color: var(--line-strong); color: var(--muted); }
.cl-btn-wide { margin-top: 6px; }

.cl-link {
  display: inline-block; width: auto;
  padding: 8px 0; margin: 0 auto;
  background: none; border: none;
  color: var(--accent); font-size: var(--fs-sm);
  cursor: pointer;
}
.cl-link:hover { color: var(--accent-ink); text-decoration: underline; }

.cl-err {
  margin-top: 14px; padding: 10px 12px;
  background: var(--red-bg); color: var(--red);
  border: 1px solid var(--red-bg); border-radius: var(--r);
  font-size: var(--fs-sm); line-height: 1.8;
}
.cl-limit { margin-top: 12px; font-size: var(--fs-xs); color: var(--faint); line-height: 1.8; }

.cl-uploading { margin: 20px 0 8px; }
.cl-uploading-text { margin-top: 8px; font-size: var(--fs-sm); color: var(--muted); text-align: center; }

/* ── 已上传卡片与预览 ─────────────────────────────────────────────── */
.cl-done-card {
  margin-top: 16px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  overflow: hidden; box-shadow: var(--shadow-sm);
}
.cl-done-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; }
.cl-check {
  flex: 0 0 22px; width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--ok-bg); color: var(--ok);
}
.cl-check svg { width: 14px; height: 14px; }
.cl-check-lg { width: 44px; height: 44px; margin: 0 auto 14px; }
.cl-check-lg svg { width: 26px; height: 26px; }
.cl-done-name { font-size: var(--fs-sm); font-weight: 600; }
.cl-done-sub { font-size: var(--fs-xs); color: var(--muted); margin-top: 2px; word-break: break-all; }
.cl-done-foot {
  padding: 9px 14px; border-top: 1px solid var(--line);
  background: var(--card-2);
  font-size: var(--fs-xs); color: var(--muted); line-height: 1.7;
}

.cl-preview {
  border-top: 1px solid var(--line);
  background: var(--card-2);
  display: flex; align-items: center; justify-content: center;
  min-height: 120px;
}
.cl-preview-img { display: block; max-width: 100%; max-height: 240px; }
/* 遗留 #6：PDF 也要能内嵌看，不只是「在新标签打开」 */
.cl-pdf { width: 100%; }
.cl-preview-pdf { display: block; width: 100%; height: 220px; border: none; background: var(--card-2); }
.cl-pdf-foot {
  padding: 8px 14px; border-top: 1px solid var(--line);
  font-size: var(--fs-xs); color: var(--muted); text-align: center;
}
.cl-preview-fallback { padding: 24px 16px; font-size: var(--fs-sm); color: var(--muted); text-align: center; }

.cl-done-hero { text-align: center; max-width: 380px; }
.cl-done-hero .cl-title { margin-bottom: 8px; }
.cl-done-hero .cl-guide-text + .cl-guide-text { margin-top: 10px; }

/* ── 底部固定动作条 ───────────────────────────────────────────────── */
.cl-foot {
  position: sticky; bottom: 0; z-index: 10;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--card);
  border-top: 1px solid var(--line);
}
.cl-foot > .cl-btn { max-width: 528px; }

/* ── 核对清单 ─────────────────────────────────────────────────────── */
.cl-check-list {
  margin-top: 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  overflow: hidden; box-shadow: var(--shadow-sm);
}
.cl-check-item { border-bottom: 1px solid var(--line); }
.cl-check-item:last-child { border-bottom: none; }
.cl-check-item[data-act] { cursor: pointer; transition: background-color .12s ease; }
.cl-check-item[data-act]:hover { background: var(--card-2); }
.cl-chev { color: var(--faint); font-size: var(--fs-lg); line-height: 1; }

/* ── 项目台账在线填列 ─────────────────────────────────────────────── */
.cl-tabs {
  display: flex; gap: 4px; padding: 3px;
  background: var(--chip-bg); border-radius: var(--r);
  margin-bottom: 14px;
}
.cl-tab {
  flex: 1 1 0; padding: 7px 10px;
  background: transparent; border: none; border-radius: var(--r-sm);
  color: var(--muted); font-size: var(--fs-sm); cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.cl-tab.active { background: var(--card); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-sm); }

.cl-lg { margin-top: 14px; }
.cl-lg-year + .cl-lg-year { margin-top: 18px; }
.cl-lg-year-head {
  display: flex; align-items: baseline; justify-content: space-between;
  font-size: var(--fs-sm); font-weight: 600;
  padding-bottom: 6px; border-bottom: 1px solid var(--line);
}
.cl-lg-count { font-size: var(--fs-xs); color: var(--faint); font-variant-numeric: tabular-nums; }
.cl-lg-row {
  margin-top: 10px; padding: 12px 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.cl-lg-row-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px;
}
.cl-lg-idx { font-size: var(--fs-xs); color: var(--muted); }
.cl-lg-del { padding: 0; font-size: var(--fs-xs); color: var(--muted); }
.cl-lg-del:hover { color: var(--red); text-decoration: none; }
.cl-lg-add { display: block; width: 100%; margin-top: 10px; text-align: center; }

.cl-f { display: block; margin-top: 10px; }
.cl-f > span { display: block; font-size: var(--fs-xs); color: var(--muted); margin-bottom: 4px; }
.cl-f-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.cl-input {
  width: 100%; padding: 10px 12px;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--r);
  font-size: var(--fs);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.cl-input::placeholder { color: var(--faint); }
.cl-input:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }

/* ── 提示卡 ───────────────────────────────────────────────────────── */
.cl-note-card {
  max-width: 380px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 24px 20px; box-shadow: var(--shadow-sm); text-align: center;
}
.cl-note-inline {
  margin-top: 14px; padding: 14px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-lg);
}
.cl-note-title { font-size: var(--fs); font-weight: 600; margin-bottom: 6px; }
.cl-note-text { font-size: var(--fs-sm); color: var(--muted); line-height: 1.8; }
.cl-note-card .cl-btn { margin-top: 16px; }

/* ── 销售端现场合影 ───────────────────────────────────────────────── */
.cl-card {
  margin-top: 16px; padding: 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.cl-card .cl-title { margin-top: 0; }

.cl-geo {
  padding: 12px 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.cl-geo-head { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sm); font-weight: 600; }
.cl-geo-dot {
  flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--line-strong);
}
.cl-geo.is-ok .cl-geo-dot { background: var(--ok); }
.cl-geo.is-warn .cl-geo-dot { background: var(--warn); }
.cl-geo-text { margin-top: 6px; font-size: var(--fs-sm); color: var(--muted); line-height: 1.8; }
.cl-geo.is-warn .cl-geo-text { color: var(--warn); }
.cl-geo .cl-link { margin: 0; padding: 0; }

/* ── 工作台侧「采集链接」页 ───────────────────────────────────────── */
.cl-link-row { padding: 14px 16px; border-bottom: 1px solid var(--line); }
.cl-link-row:last-child { border-bottom: none; }
.cl-link-box {
  margin-top: 10px; padding: 12px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r);
}
.cl-link-box .input { min-width: 0; }
/* <<< BLOCK:S1-collect */

/* >>> BLOCK:S3-rules */
/* 规则管理与 A/B 试算。只用令牌，不写字面色值；
   宽内容自带 overflow-x，页面主体不横向滚动。 */

.rule-cat {
  display: flex; align-items: baseline; gap: 8px;
  padding: 10px 16px;
  background: var(--card-2);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-sm); font-weight: 600;
}

.rule-row {
  display: grid; grid-template-columns: 1fr auto;
  gap: 6px 16px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.rule-row.off { background: var(--card-2); }
.rule-row.off .rule-name, .rule-row.off .rule-cond { color: var(--muted); }
.rule-row.editing { background: var(--accent-soft); }

.rule-main { min-width: 0; }
.rule-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rule-code {
  font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted);
}
.rule-name { font-weight: 600; font-size: var(--fs-sm); }
.rule-def { margin-top: 3px; line-height: 1.7; }
.rule-cond {
  margin-top: 5px; font-size: var(--fs-sm); color: var(--ink);
  overflow-wrap: anywhere;
}
.rule-orig { margin-top: 3px; line-height: 1.7; }
.rule-prob { margin-top: 5px; color: var(--warn); }

.rule-side {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  align-self: flex-start;
}
.rule-acts { display: flex; gap: 6px; }

.rule-check { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }

/* ── 编辑区 ───────────────────────────────────────────────────────── */
.rule-editor {
  padding: 14px 16px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--card-2);
}
.rule-editor .field > span,
.ver-form .field > span { font-size: var(--fs-xs); color: var(--muted); }

.ed-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px; margin-bottom: 12px;
}
.ed-body { display: flex; flex-direction: column; gap: 10px; }
.ed-text { margin-top: 12px; }
.ed-foot {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line);
}

.cond-list { display: flex; flex-direction: column; gap: 10px; }
.cond-item {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
}
/* 字段名可以很长（「近3月硬查询次数（贷款/信用卡审批、担保资格审查）」），
   给下拉封顶，免得把阈值输入框挤到下一行 */
.cond-item .select { width: auto; min-width: 150px; max-width: 300px; flex: 0 1 auto; }
.cond-no { flex: 0 0 auto; }
.cond-val { flex: 1 1 200px; min-width: 160px; }
.rule-oneval { max-width: 200px; }
.rule-range { display: flex; align-items: center; gap: 8px; }
.rule-range .input { max-width: 120px; }
.rule-noval { padding: 6px 0; }

.rule-vals { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.val-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 4px 1px 8px;
  border-radius: var(--r-pill);
  background: var(--chip-bg); color: var(--chip-ink);
  font-size: var(--fs-xs);
}
.val-x {
  border: none; background: transparent; color: var(--muted);
  cursor: pointer; padding: 0 4px; line-height: 1; font-size: var(--fs);
}
.val-x:hover { color: var(--ink); }
.val-new { flex: 1 1 150px; min-width: 130px; }
.rule-pool { margin-top: 6px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.val-add {
  border: 1px dashed var(--line-strong); background: transparent; color: var(--muted);
  border-radius: var(--r-pill); padding: 0 8px; font-size: var(--fs-xs); cursor: pointer;
}
.val-add:hover { border-color: var(--accent); color: var(--accent-ink); border-style: solid; }

.ver-form { display: flex; flex-direction: column; gap: 12px; text-align: left; }

/* ── A / B 试算 ───────────────────────────────────────────────────── */
.trial-card .card-body { padding: 12px 16px; }
.trial-nums { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.trial-num .stat-value { font-size: var(--fs-2xl); margin-top: 2px; }

/* 试算工具栏：三个下拉不许把按钮挤到第二行 */
#t-app { flex: 1 1 260px; min-width: 200px; max-width: 340px; }
#t-a, #t-b { flex: 0 1 200px; min-width: 150px; }

.diff-col .card-head h3 { font-size: var(--fs-sm); }
.diff-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px; border-bottom: 1px solid var(--line);
}
.diff-row:last-child { border-bottom: none; }
.diff-row .rule-name { margin-left: 6px; }

@media (max-width: 620px) {
  .rule-row { grid-template-columns: minmax(0, 1fr); }
  .ed-grid { grid-template-columns: minmax(0, 1fr); }
  .trial-nums { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cond-item .select { width: 100%; }
  .rule-oneval { max-width: none; }
}
/* <<< BLOCK:S3-rules */

/* >>> BLOCK:S4-review */
/* 审核工作台 / 单进件审核视图 / 预警看板。归属 S4。
   只用令牌，不写字面色值；语义色只表达风险等级，不当强调色用。 */

/* ── 队列：命中计数徽标 ── */
.cnt-row { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.cnt {
  display: inline-flex; align-items: center;
  padding: 0 6px; border-radius: var(--r-sm);
  font-size: var(--fs-xs); line-height: 1.6;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.cnt-deny { background: var(--deny-bg); color: var(--deny); }
.cnt-red  { background: var(--red-bg);  color: var(--red); }
.cnt-warn { background: var(--warn-bg); color: var(--warn); }

/* ── 审核视图：吸顶决策条 ──
   顶栏高 var(--header-h)，这里贴在它下面。父链上没有 overflow-x:hidden，
   sticky 才立得住（app.css 头部第 4 条纪律）。 */
.rv-bar {
  position: sticky; top: var(--header-h); z-index: 15;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-areas: "main side acts" "foot foot foot";
  gap: 6px 14px;
  align-items: center;
  margin: 10px 0 16px;
  padding: 12px 16px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
}
.rv-bar-main { grid-area: main; min-width: 0; }
.rv-bar-side { grid-area: side; display: flex; align-items: center; gap: 6px; }
.rv-bar-acts { grid-area: acts; display: flex; align-items: center; gap: 6px; }
.rv-bar-foot { grid-area: foot; padding-top: 6px; border-top: 1px solid var(--line); }
.rv-bar-title { font-size: var(--fs-lg); font-weight: 600; }
.rv-bar-meta { font-size: var(--fs-xs); color: var(--muted); margin-top: 2px; }
.rv-veto { font-size: var(--fs-xs); color: var(--deny); }

/* ── 资料齐备度 ── */
.rv-progress { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.rv-progress-track {
  flex: 1 1 auto; height: 8px; border-radius: var(--r-pill);
  background: var(--chip-bg); overflow: hidden;
}
.rv-progress-fill { height: 100%; background: var(--accent); transition: width .3s ease; }
.rv-doc-row { display: flex; flex-wrap: wrap; gap: 8px; }
.rv-doc {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  background: var(--card-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r);
  font-size: var(--fs-sm); cursor: pointer;
  max-width: 100%;
  transition: border-color .15s ease;
}
.rv-doc:hover:not(:disabled) { border-color: var(--accent); }
.rv-doc:disabled { opacity: .55; cursor: not-allowed; }
.rv-doc-name { max-width: 210px; }

/* ── 待人工判定：中性提醒，不做红色轰炸 ── */
.rv-manual { border-color: var(--line-strong); }
.rv-manual .card-head { background: var(--card-2); border-radius: var(--r-lg) var(--r-lg) 0 0; }

/* ── 命中：等级块下再分一层分类 ── */
.hit-cat + .hit-cat { border-top: 1px solid var(--line); }
.hit-cat-head {
  display: flex; align-items: baseline; gap: 8px;
  padding: 8px 16px 6px;
  font-size: var(--fs-xs); color: var(--muted); letter-spacing: .3px;
}
.hit-row.clickable { cursor: pointer; transition: background-color .12s ease; }
.hit-row.clickable:hover { background: var(--card-2); }
.agg-item.clickable { cursor: pointer; border-radius: var(--r-sm); }
.agg-item.clickable:hover { background: var(--chip-bg); }
.agg-item .hit-sub { margin-top: 2px; }

/* ── 下钻弹层 ── */
.rv-modal { max-width: 880px; }
.rv-modal-body { text-align: left; }
.rv-block + .rv-block { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
.rv-block-head {
  font-size: var(--fs-xs); color: var(--muted);
  margin-bottom: 8px; letter-spacing: .3px;
}
.rv-modal .dl { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 20px; }
.rv-note { min-height: 96px; resize: vertical; font-family: var(--font); line-height: 1.7; }

/* 来源资料缩略 */
.rv-src { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.rv-src-item {
  display: flex; gap: 10px; align-items: center;
  padding: 8px; min-width: 0;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
}
.rv-src-thumb {
  flex: 0 0 56px; width: 56px; height: 56px;
  display: flex; align-items: center; justify-content: center;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-sm);
  overflow: hidden;
}
.rv-src-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 3px; }

/* ── 看板：逐行堆叠条 ── */
.mbars { display: flex; flex-direction: column; gap: 10px; }
.mbar-row {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) 40px 84px;
  align-items: center; gap: 10px;
}
.mbar-name { font-size: var(--fs-sm); color: var(--muted); }
.mbar-track {
  display: flex; height: 12px; min-width: 4px;
  border-radius: var(--r-pill); overflow: hidden; background: var(--chip-bg);
}
.mbar-n { font-size: var(--fs-sm); font-variant-numeric: tabular-nums; text-align: right; }
.mbar-risk { text-align: right; }

/* ── 窄屏 ──
   决策条的三列在窄屏必须拆开：主体是 overflow-x: clip，
   右列一旦被挤出视口就是静默裁切，按钮会直接消失。 */
@media (max-width: 880px) {
  .rv-bar {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "main" "side" "acts" "foot";
    position: static;
  }
  .rv-bar-acts { flex-wrap: wrap; }
  .rv-bar-acts .btn { flex: 1 1 auto; }
  .rv-modal .dl { grid-template-columns: minmax(0, 1fr); }
  .mbar-row { grid-template-columns: 56px minmax(0, 1fr) 34px; }
  .mbar-risk { grid-column: 1 / -1; text-align: left; padding-left: 66px; }
}
@media (max-width: 620px) {
  .hit-row.clickable, .agg-item.clickable { grid-template-columns: minmax(0, 1fr); }
  .rv-doc-name { max-width: 100%; }
  .rv-src { grid-template-columns: minmax(0, 1fr); }
}
/* <<< BLOCK:S4-review */

/* >>> BLOCK:S5-project */
/* ── 项目台账（S5） ────────────────────────────────────────────────────
   只用 app.css 头部的设计令牌，不写字面色值。
   核验结果三态用「相符 / 不相符 / 无法判定」三种中性程度的色，
   不相符用 warn 而不是 red —— J-01~J-07 出厂都是 warn 级，不做红色轰炸。 */

/* 详情页右上角的按钮组 */
.toolbar-inline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* 文件选择框本身不露脸，点的是它前面那个 <label class="btn"> */
.hidden-file {
  position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip-path: inset(50%); border: 0;
}

/* 年度分组：三年 15 行不平铺，一年一块，往年默认折起（地基遗留清单第 4 条） */
.year-block {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm); overflow: hidden;
}
.year-block + .year-block { margin-top: 12px; }
.year-head {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px; cursor: pointer; list-style: none;
  border-bottom: 1px solid transparent; transition: background-color .12s ease;
}
.year-head::-webkit-details-marker { display: none; }
.year-head:hover { background: var(--card-2); }
.year-block[open] .year-head { border-bottom-color: var(--line); }
.year-head::before {
  content: "▸"; color: var(--muted); font-size: var(--fs-xs);
  transition: transform .18s ease; display: inline-block;
}
.year-block[open] .year-head::before { transform: rotate(90deg); }
.year-name { font-weight: 600; font-size: var(--fs); }
.year-meta { color: var(--muted); font-size: var(--fs-sm); }
.year-body { padding: 0 0 4px; }

/* 六项自动核验的结果格 */
.chk-grid { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-width: 220px; }
.chk {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 6px; border-radius: var(--r-pill);
  font-size: var(--fs-xs); line-height: 1.7; white-space: nowrap;
  background: var(--chip-bg); color: var(--chip-ink);
}
.chk i { font-style: normal; font-weight: 700; }
.chk b { font-weight: 500; }
.chk-yes { background: var(--ok-bg);   color: var(--ok); }
.chk-no  { background: var(--warn-bg); color: var(--warn); }
.chk-unk { background: var(--chip-bg); color: var(--faint); }

.chk-legend {
  display: flex; flex-wrap: wrap; gap: 6px 16px;
  padding: 10px 16px 14px; font-size: var(--fs-xs); color: var(--muted);
}
.chk-legend > span { display: inline-flex; align-items: center; gap: 4px; }
.chk-legend .chk { padding: 0 4px; }

/* 在线填列：表格里的紧凑输入框 */
.input-sm { padding: 4px 8px; font-size: var(--fs-sm); min-width: 96px; }
.ledger-edit td { padding: 6px 8px; vertical-align: middle; }
.ledger-edit .input-sm.num { text-align: right; min-width: 84px; }
.ledger-edit td:nth-child(2) .input-sm,
.ledger-edit td:nth-child(3) .input-sm { min-width: 168px; }

/* Excel 导入预览：需人工确认的行给一条左侧标记，不整行涂色 */
.tbl tbody tr.row-manual td:first-child { box-shadow: inset 2px 0 0 var(--warn); }
.tbl tbody tr.row-manual { background: var(--card-2); }

/* 列表里"点进去看"的提示 */
.link-cue { color: var(--accent); font-size: var(--fs-sm); white-space: nowrap; }

@media (max-width: 720px) {
  .chk-grid { min-width: 0; }
  .toolbar-inline { width: 100%; }
}
/* <<< BLOCK:S5-project */

/* >>> BLOCK:S6-tasks */
/* 待办闭环 / 通知记录 / 审计日志。只用上面的令牌，不写字面色值。 */

/* 复选框标签：与 toolbar 里的 select / input 对齐 */
.check {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--fs-sm); color: var(--muted); white-space: nowrap;
  cursor: pointer;
}
.check input { margin: 0; accent-color: var(--accent); }
.toolbar.tight-toolbar { border-top: 1px solid var(--line); border-bottom: none; }

/* 列表里的说明文字截两行，避免长文案把行撑高 */
.truncate-2 {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; line-height: 1.6;
}

/* 催办四档阶梯：0 未催 → 1 催办 → 2 警告 → 3 触发下架 */
.escalate-ladder {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 12px 14px; background: var(--card-2);
  border: 1px solid var(--line); border-radius: var(--r);
}
.ladder-step {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--fs-sm); color: var(--ink);
}
.ladder-n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--chip-bg); color: var(--chip-ink);
  font-size: var(--fs-xs); font-variant-numeric: tabular-nums;
}
.ladder-step:last-child .ladder-n { background: var(--deny-bg); color: var(--deny); }
.ladder-arrow { color: var(--faint); font-size: var(--fs-sm); }

/* 扫描结果里的清单 */
.plain-list { margin: 6px 0 0; padding: 0; list-style: none; }
.plain-list li { line-height: 1.9; }

/* 流转日志时间线。纯 CSS，无动画帧。 */
.timeline { margin: 0; padding: 0; list-style: none; }
.tl-item { position: relative; padding: 0 0 16px 20px; }
.tl-item::before {
  content: ""; position: absolute; left: 4px; top: 14px; bottom: 0;
  width: 1px; background: var(--line);
}
.tl-item:last-child { padding-bottom: 0; }
.tl-item:last-child::before { display: none; }
.tl-dot {
  position: absolute; left: 0; top: 5px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--card); border: 2px solid var(--accent);
}
.tl-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.tl-meta { font-size: var(--fs-xs); color: var(--muted); margin-top: 2px; }
.tl-note {
  font-size: var(--fs-sm); color: var(--ink); margin-top: 6px;
  padding: 8px 10px; background: var(--card-2);
  border-radius: var(--r-sm); line-height: 1.75;
  white-space: pre-wrap; overflow-wrap: anywhere;
}

/* 解决方案与审批区 */
.solution-box {
  padding: 10px 12px; background: var(--card-2);
  border: 1px solid var(--line); border-radius: var(--r);
  font-size: var(--fs-sm); line-height: 1.8;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.approve-box {
  padding: 14px; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--card-2);
}
textarea.input { resize: vertical; min-height: 84px; line-height: 1.7; }

/* 通知记录 */
.notif-content {
  font-size: var(--fs-sm); color: var(--muted); margin: 4px 0 4px;
  line-height: 1.75; white-space: pre-wrap; overflow-wrap: anywhere;
}
.chan-state { margin-top: 8px; }

/* 催办面板里的次级扫描入口 */
.other-scans { padding-top: 12px; border-top: 1px solid var(--line); }

/* 审计日志：明细键值对 + 不可逆操作行的左侧标记 */
.audit-detail { display: flex; flex-wrap: wrap; gap: 4px 10px; max-width: 420px; }
.kv { font-size: var(--fs-xs); color: var(--muted); overflow-wrap: anywhere; }
.kv-k { color: var(--faint); margin-right: 4px; font-family: var(--mono); }
.tbl tbody tr.row-flag td:first-child { box-shadow: inset 2px 0 0 var(--deny); }

/* 窄屏：统计卡与通道卡降到两列，与地基的栅格规则保持一致 */
@media (max-width: 900px) {
  .audit-detail { max-width: 260px; }
}
/* <<< BLOCK:S6-tasks */
