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

   视觉语言：飞书（Feishu / Arco）。主张是「克制的工具台 + 一处会说话的地方」——
   层级靠留白、字重、细线分，不靠色块喊；全页只留一处可以重、可以有色（概览页
   顶部的结论条），其余一律退到中性色。不做玻璃拟态 / 渐变底 / 氛围层：半透顶栏
   会让滚过去的表格行透上来，把上面两条全糊掉。

   纪律（改这个文件前必读，另见 docs/06-设计令牌与前端纪律.md）：
   1. 全站只用令牌，禁止字面色值（#xxxxxx / rgb(...)）出现在组件规则里。
   2. 任何颜色都不能只定义在媒体查询里 —— 亮色是基准，暗色只做重定义。
   3. 暗色要写两份：@media (prefers-color-scheme: dark) 里的 :root:not([data-theme="light"])
      与手动切换的 :root[data-theme="dark"]，两份令牌必须一致。
   4. 语义色有深浅两套，别混用：--deny / --red / --warn / --ok 是**深色版**，
      给要读的字（表格数值、pill 文字）；--*-solid 是**亮色版**，只用来填色块和
      画条形。飞书官方那组绿橙红在白底上只有 2.2:1 ~ 3.6:1，14px 的字放上去读不清。
      判断方法：这个颜色是「用来读的」还是「用来看的」，读就用深色版。
   5. 不在 html / body 上写 overflow-x: hidden（会破坏 sticky），用 overflow-x: clip。
   6. 过场一律用 CSS transition，不要用 requestAnimationFrame 驱动。

   改完跑 python3 -m unittest tests.test_design_tokens —— 幽灵令牌、亮暗令牌不对等、
   花括号不平衡、组件区字面色值，这四类错都不报异常，只能靠守卫拦。
   ========================================================================= */

/* ── 令牌：亮色（基准，全部颜色都在这里有定义） ───────────────────────── */
:root {
  color-scheme: light;

  /* 底色与文字（纯灰，不带色偏：带青绿或蓝紫味的中性色会让整页脏一档） */
  --ground:       #F5F6F7;
  --card:         #FFFFFF;
  --card-2:       #F7F8FA;   /* 表头 / 次级分区底 / 悬浮行 */
  --ink:          #1F2329;
  --muted:        #646A73;
  --faint:        #8F959E;   /* 更弱一级的说明文字 */

  /* 描边。--line-soft 给表格行分隔与卡片外框：飞书的表无竖线，
     横线也要比容器边框更淡，否则一屏几十行会织成一张网。 */
  --line:         #DEE0E3;
  --line-soft:    #EFF0F1;
  --line-strong:  #C9CDD4;

  /* 主色（飞书蓝） */
  --accent:       #3370FF;
  --accent-soft:  #F0F4FF;   /* 选中行 / 选中导航项的底 */
  --accent-ink:   #245BDB;   /* 悬停与浅底上的主色文字 */
  --accent-bar:   #C2D5FF;   /* 量级条填充：条长表达量级，颜色不必再喊一遍 */
  --accent-line:  #C2D5FF;   /* 主色描边：只给结论条这一处「重」的用 */
  --accent-on:    #FFFFFF;   /* 主色底上的文字 */

  /* 语义色（与主色分开，不当强调色用）。每档两个值，用途见上面纪律第 4 条。 */
  --deny:  #9A211C;   --deny-bg:  #FBE4E2;   --deny-solid:  #B32B25;
  --red:   #C4342F;   --red-bg:   #FDEDEC;   --red-solid:   #F54A45;
  --warn:  #A85B00;   --warn-bg:  #FFF3E0;   --warn-solid:  #FF8800;
  --ok:    #1F7A16;   --ok-bg:    #E8F7E4;   --ok-solid:    #34C724;

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

  /* 遮罩与投影 */
  --overlay:      rgba(31, 35, 41, .42);
  --shadow-sm:    0 1px 3px rgba(31, 35, 41, .05), 0 4px 12px rgba(31, 35, 41, .04);
  --shadow:       0 4px 12px rgba(31, 35, 41, .07), 0 16px 40px rgba(31, 35, 41, .08);
  --shadow-lg:    0 12px 32px rgba(31, 35, 41, .12), 0 32px 64px rgba(31, 35, 41, .10);
  --focus-ring:   0 0 0 3px rgba(51, 112, 255, .22);

  /* 尺寸。这套语言的「软」有一半来自圆角这一档，再大就变成消费级应用了，
     表格单元格会显得松垮。 */
  --r-sm: 4px;  --r: 7px;  --r-lg: 10px;  --r-xl: 14px;  --r-pill: 999px;
  --sidebar-w: 216px;
  --header-h: 56px;

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

  /* 拉丁字母与数字走 SF / Segoe，汉字回落 PingFang —— 系统字体栈，不引在线字体 */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Microsoft YaHei", system-ui, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ── 令牌：暗色（跟随系统） ─────────────────────────────────────────── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --ground:      #17171A;
    --card:        #232324;
    --card-2:      #2A2A2B;
    --ink:         #F7F8FA;
    --muted:       #C9CDD4;
    --faint:       #929AA5;

    --line:        #333335;
    --line-soft:   #2A2A2B;
    --line-strong: #48484A;

    --accent:      #4E83FD;
    --accent-soft: #182444;
    --accent-ink:  #94B4FF;
    --accent-bar:  #2A4A94;
    --accent-line: #2A4A94;
    --accent-on:   #0B1220;

    /* 暗底上深色文字读不出来，所以语义色整体提亮：这里深浅版的关系是反的，
       --ok 比 --ok-solid 更亮。色块用的 -solid 保持不变，那是给面积用的。 */
    --deny:  #FF9A93;   --deny-bg:  #451916;   --deny-solid:  #C2352F;
    --red:   #FF7D75;   --red-bg:   #351A19;   --red-solid:   #F54A45;
    --warn:  #FFB545;   --warn-bg:  #33240C;   --warn-solid:  #FF8800;
    --ok:    #5ED94A;   --ok-bg:    #17301A;   --ok-solid:    #34C724;

    --chip-bg:     #2A2A2B;
    --chip-ink:    #C9CDD4;

    --overlay:     rgba(0, 0, 0, .55);
    --shadow-sm:   0 1px 2px rgba(0, 0, 0, .40);
    --shadow:      0 6px 18px rgba(0, 0, 0, .50), 0 2px 5px rgba(0, 0, 0, .35);
    --shadow-lg:   0 18px 44px rgba(0, 0, 0, .60), 0 4px 12px rgba(0, 0, 0, .40);
    --focus-ring:  0 0 0 3px rgba(78, 131, 253, .34);
  }
}

/* ── 令牌：暗色（右上角手动切换，与上面保持一致） ────────────────────── */
:root[data-theme="dark"] {
  color-scheme: dark;

  --ground:      #17171A;
  --card:        #232324;
  --card-2:      #2A2A2B;
  --ink:         #F7F8FA;
  --muted:       #C9CDD4;
  --faint:       #929AA5;

  --line:        #333335;
  --line-soft:   #2A2A2B;
  --line-strong: #48484A;

  --accent:      #4E83FD;
  --accent-soft: #182444;
  --accent-ink:  #94B4FF;
  --accent-bar:  #2A4A94;
  --accent-line: #2A4A94;
  --accent-on:   #0B1220;

  --deny:  #FF9A93;   --deny-bg:  #451916;   --deny-solid:  #C2352F;
  --red:   #FF7D75;   --red-bg:   #351A19;   --red-solid:   #F54A45;
  --warn:  #FFB545;   --warn-bg:  #33240C;   --warn-solid:  #FF8800;
  --ok:    #5ED94A;   --ok-bg:    #17301A;   --ok-solid:    #34C724;

  --chip-bg:     #2A2A2B;
  --chip-ink:    #C9CDD4;

  --overlay:     rgba(0, 0, 0, .55);
  --shadow-sm:   0 1px 2px rgba(0, 0, 0, .40);
  --shadow:      0 6px 18px rgba(0, 0, 0, .50), 0 2px 5px rgba(0, 0, 0, .35);
  --shadow-lg:   0 18px 44px rgba(0, 0, 0, .60), 0 4px 12px rgba(0, 0, 0, .40);
  --focus-ring:  0 0 0 3px rgba(78, 131, 253, .34);
}

/* ── 基础 ──────────────────────────────────────────────────────────── */
*, *::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-soft);
  border-radius: var(--r-xl);
  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;
}

/* ── 合作伙伴门户入口 ───────────────────────────────────────────────────
   两处入口，都只是一个链接，不碰任何登录逻辑：门户是外部账号体系
   （手机号 + 自己设的口令），走它自己的登录页。
     · 内部登录页右侧的分栏 —— 给误入内部登录页的外部用户指路；
     · 工作台顶栏的那颗按钮 —— 内部人切到合作伙伴视角看一眼。 */
.login-split {
  /* flex-start 而不是 stretch：左卡片的高度随演示账号条数变，
     右栏被拉平会中间一大片空。 */
  display: flex; align-items: flex-start; gap: 20px;
  width: 100%; max-width: 720px;
}
.login-split > .login-card { flex: 1 1 380px; max-width: 380px; }
.login-aside {
  flex: 0 1 300px;
  display: flex; flex-direction: column; gap: 10px;
  padding: 28px 26px;
  background: var(--card);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-sm);
}
.login-aside h2 { font-size: var(--fs-lg); font-weight: 600; }
.login-aside p { color: var(--muted); font-size: var(--fs-sm); line-height: 1.7; }
.login-aside .btn { margin-top: 4px; }
.login-aside-note {
  margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--line);
  color: var(--faint); font-size: var(--fs-xs); line-height: 1.7;
}

/* .btn 用在 <a> 上时，全局的 a:hover 会给它加一条下划线 */
a.btn, a.btn:hover { text-decoration: none; }

/* 窄屏：右栏落到卡片下方，不做两列挤压 */
@media (max-width: 760px) {
  .login-split { flex-direction: column; max-width: 380px; }
  .login-split > .login-card { max-width: none; }
  .login-aside { padding: 20px 22px; }
}

/* ── 表单 ─────────────────────────────────────────────────────────── */
.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 自己的 12px 内边距，再叠一次会顶出一块空白 */
.nav-group-label:first-child { padding-top: 2px; }
.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); font-weight: 600; }
/* 尺寸给所有 .nav-ico：顶栏的主题切换按钮也用这个类，之前尺寸只写在
   .nav-item 后代选择器里，那颗按钮的图标就一直是 0×0（看不见但点得到）。 */
.nav-ico { flex: 0 0 16px; width: 16px; height: 16px; }
.nav-item .nav-ico { 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-soft);
  border-radius: var(--r-xl);
  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-soft);
  border-radius: var(--r-xl);
  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-sm);
  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-solid); color: var(--accent-on); }
.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: 10px 12px;
  border-bottom: 1px solid var(--line-soft);
  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-sm); overflow: hidden; background: var(--chip-bg); }
.dist-seg { height: 100%; transition: width .3s ease; }
.dist-seg.seg-deny { background: var(--deny-solid); }
.dist-seg.seg-red  { background: var(--red-solid); }
.dist-seg.seg-warn { background: var(--warn-solid); }
.dist-seg.seg-ok   { background: var(--ok-solid); }
.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-solid); }
.dist-swatch.seg-red  { background: var(--red-solid); }
.dist-swatch.seg-warn { background: var(--warn-solid); }
.dist-swatch.seg-ok   { background: var(--ok-solid); }
.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(--accent-soft); border-radius: var(--r-sm); overflow: hidden; }
.bar-fill { height: 100%; background: var(--accent-bar); border-radius: var(--r-sm); 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-sm); background: var(--accent-soft); overflow: hidden; }
.minibar-fill { height: 100%; background: var(--accent-bar); }
.minibar-fill.low { background: var(--warn-solid); }

/* ── 工具栏 / 筛选 ─────────────────────────────────────────────────── */
.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-xl); 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-soft);
}
.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-soft);
}
.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-soft); }
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-soft); }
.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-soft); }
.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); }

/* >>> BLOCK:S0-channels  降级链逐条明细。窄屏下标签留在第一行、说明整段换行，
   不用 grid 硬分列——说明文字长短差很多，硬分列会把短的那几行拉出大片空白。 */
.intg-chans { margin-top: 10px; padding-left: 10px; border-left: 2px solid var(--line); }
.intg-chan { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
             padding: 4px 0; font-size: var(--fs-xs); }
.intg-chan-k { font-weight: 600; color: var(--ink); }
.intg-chan-v { color: var(--faint); line-height: 1.7; flex: 1 1 220px; min-width: 0; }
/* <<< BLOCK:S0-channels */

/* ── 建设中占位页 ─────────────────────────────────────────────────── */
.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-sm); }

/* ── 首屏 ─────────────────────────────────────────────────────────── */
.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-xl);
  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-xl);
  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-solid); }
.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-xl);
  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-xl);
  overflow: hidden; box-shadow: var(--shadow-sm);
}
.cl-check-item { border-bottom: 1px solid var(--line-soft); }
.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-xl);
  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; }
/* 卡片整体居中对齐，但徽标是块级定宽元素，text-align 管不到它 */
.cl-note-card .cl-brand-mark { margin: 0 auto 12px; }

/* ── 销售端现场合影 ───────────────────────────────────────────────── */
.cl-card {
  margin-top: 16px; padding: 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-xl);
  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-solid); }
.cl-geo.is-warn .cl-geo-dot { background: var(--warn-solid); }
.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-soft); }
.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-soft);
}
.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-sm);
  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-sm); 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-soft);
}
.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-xl);
  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-sm);
  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-xl) var(--r-xl) 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-sm); 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-xl); 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-sm);
  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-solid); }
.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-solid); }

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

/* >>> BLOCK:S0-intake */
/* 建档弹层（新建合作伙伴 / 新建进件）。只写排版，颜色一律取头部令牌。 */
.intake-body { text-align: left; }        /* .modal-body 默认居中，那是给图片预览用的 */
.intake-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.intake-grid .span-2 { grid-column: 1 / -1; }
.intake-grid .field > span { font-size: var(--fs-sm); color: var(--muted); }
.intake-grid .req::after { content: ' *'; color: var(--deny); }
.intake-sep {
  margin: 16px 0 10px; padding-top: 14px; border-top: 1px solid var(--line);
  font-size: var(--fs-sm); color: var(--muted);
}
.intake-sep.first { margin-top: 0; padding-top: 0; border-top: none; }
.intake-pick { display: flex; flex-direction: column; gap: 6px; max-height: 46vh; overflow: auto; }
.intake-pick-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 10px 12px; text-align: left;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  cursor: pointer; font: inherit; color: inherit;
}
.intake-pick-row:hover { border-color: var(--accent); }
.intake-pick-row[disabled] { cursor: not-allowed; opacity: .72; }
.intake-pick-row[disabled]:hover { border-color: var(--line); }
.intake-done { display: flex; flex-direction: column; gap: 10px; }
@media (max-width: 640px) { .intake-grid { grid-template-columns: 1fr; } }
/* <<< BLOCK:S0-intake */

/* >>> BLOCK:T3-boundary  客户端销售侧采集项的中性状态徽标 —— 替代原来的缩略图卡片。
   销售现场取证的照片是内部核验证据（含 GPS、拍摄人、实控人肖像），客户端只出三态。
   颜色克制：这是给客户看的进度，不是预警，别用告警红。 */
.cl-state {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 10px; padding: 5px 10px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--muted);
  font-size: var(--fs-sm); line-height: 1.4;
}
.cl-state-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex: none;
}
.cl-state-verified { background: var(--ok-bg); border-color: transparent; color: var(--ok); }
.cl-state-redo { background: var(--warn-bg); border-color: transparent; color: var(--warn); }
/* <<< BLOCK:T3-boundary */

/* >>> BLOCK:T1-portal-login  合作伙伴门户登录 / 首登改密 / 开户激活
   归属：T1 ✎。只用头部令牌，不写字面色值；过场只用 transition。
   PC 优先：左侧说明栏 + 右侧表单卡，窄屏收成单列（说明栏收起，卡片撑满）。
   —— 本轮重构的起因之一就是「纯为手机端开发」，登录页不做手机柱子。 */
.pl-page {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  background: var(--ground);
}
.pl-aside {
  /* 深一档的主色而不是 --accent 本体：换飞书蓝之后主色亮了很多，
     铺满半屏会压过右侧表单，而这一屏真正要人做的事在右边。 */
  background: var(--accent-ink);
  color: var(--accent-on);
  padding: 56px 56px 40px;
  display: flex; flex-direction: column; gap: 28px;
}
.pl-aside-brand { display: flex; align-items: center; gap: 12px; }
.pl-aside-mark {
  width: 36px; height: 36px; border-radius: var(--r);
  background: var(--accent-on); color: var(--accent-ink);
  display: flex; align-items: center; justify-content: center;
  font-weight: 600; letter-spacing: .5px;
}
.pl-aside-brand-text { font-size: var(--fs); letter-spacing: .5px; }
.pl-aside h1 { font-size: var(--fs-2xl); line-height: 1.45; font-weight: 600; }
.pl-aside-sub { font-size: var(--fs-sm); line-height: 1.9; opacity: .84; max-width: 30em; }
.pl-aside-list { display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.pl-aside-item { display: flex; gap: 10px; font-size: var(--fs-sm); line-height: 1.7; opacity: .92; }
.pl-aside-idx {
  flex: 0 0 20px; height: 20px; border-radius: var(--r-pill);
  border: 1px solid currentColor; opacity: .7;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-xs);
}
.pl-aside-foot { margin-top: auto; font-size: var(--fs-xs); opacity: .7; line-height: 1.8; }

.pl-main {
  display: flex; align-items: center; justify-content: center;
  padding: 40px 24px;
}
.pl-card { width: 100%; max-width: 400px; }
.pl-card-brand { display: none; align-items: center; gap: 10px; margin-bottom: 24px; }
.pl-card-mark {
  width: 32px; height: 32px; border-radius: var(--r);
  background: var(--accent); color: var(--accent-on);
  display: flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: var(--fs-sm);
}
.pl-title { font-size: var(--fs-xl); }
.pl-sub { color: var(--muted); font-size: var(--fs-sm); margin-top: 6px; line-height: 1.7; }
.pl-form { margin-top: 24px; display: flex; flex-direction: column; gap: 14px; }

.pl-tabs { display: flex; gap: 4px; padding: 3px; background: var(--chip-bg); border-radius: var(--r); }
.pl-tab {
  flex: 1 1 0; padding: 6px 10px; border: none; border-radius: var(--r-sm);
  background: transparent; color: var(--muted); font-size: var(--fs-sm);
  cursor: pointer; transition: background-color .15s ease, color .15s ease;
}
.pl-tab.on { background: var(--card); color: var(--ink); box-shadow: var(--shadow-sm); }

.pl-pwd { position: relative; }
.pl-pwd .input { padding-right: 56px; }
.pl-pwd-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  border: none; background: transparent; color: var(--muted);
  font-size: var(--fs-xs); padding: 4px 6px; cursor: pointer;
}
.pl-pwd-toggle:hover { color: var(--accent-ink); }

.pl-rule { font-size: var(--fs-xs); color: var(--faint); line-height: 1.7; }
.pl-note {
  font-size: var(--fs-xs); color: var(--muted); line-height: 1.8;
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: var(--r); padding: 10px 12px;
}
.pl-greet {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--card-2); padding: 12px 14px;
  display: flex; flex-direction: column; gap: 4px;
}
.pl-greet-name { font-size: var(--fs-lg); }
.pl-greet-meta { font-size: var(--fs-xs); color: var(--muted); }
.pl-foot {
  margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line);
  color: var(--faint); font-size: var(--fs-xs); line-height: 1.9;
}
.pl-foot a, .pl-link {
  color: var(--accent-ink); background: none; border: none; padding: 0;
  font-size: inherit; cursor: pointer;
}
.pl-link:hover { text-decoration: underline; }

@media (max-width: 960px) {
  .pl-page { grid-template-columns: minmax(0, 1fr); }
  .pl-aside { display: none; }
  .pl-card-brand { display: flex; }
  .pl-main { align-items: flex-start; padding: 32px 20px 48px; }
}
/* <<< BLOCK:T1-portal-login */

/* >>> BLOCK:T1-portal-accounts  内部工作台「合作伙伴账号」页
   归属：T1 ✎。.modal-body 默认居中（图片预览用），这里的表单要左对齐。 */
.pa-note {
  font-size: var(--fs-sm); line-height: 1.8;
  background: var(--accent-soft); color: var(--accent-ink);
  border-radius: var(--r); padding: 10px 14px; margin-bottom: 16px;
}
.pa-form { text-align: left; display: flex; flex-direction: column; gap: 14px; }
.pa-form .pa-note { margin-bottom: 0; }
.pa-pwd-label { font-size: var(--fs-sm); color: var(--muted); }
.pa-copy {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  border: 1px solid var(--line-strong); border-radius: var(--r);
  background: var(--card-2); padding: 10px 12px;
}
.pa-copy-text { flex: 1 1 220px; min-width: 0; word-break: break-all; line-height: 1.7; }
.pa-pwd { font-family: var(--mono); font-size: var(--fs-2xl); letter-spacing: 3px; }
/* 发送方式勾选：整行可点，勾选框和文字之间不留可点空隙 */
.pa-check {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: var(--fs-sm); line-height: 2.2; cursor: pointer;
}
.pa-check input[disabled] { cursor: not-allowed; }
.pa-check.muted { cursor: not-allowed; color: var(--muted); }
/* 邮件正文要保留换行 —— 销售复制过去的应该是排好的信，不是一整坨 */
.pa-pre {
  white-space: pre-wrap; word-break: break-word;
  font-size: var(--fs-sm); max-height: 240px; overflow-y: auto;
}
/* <<< BLOCK:T1-portal-accounts */

/* >>> BLOCK:T5-workbench  资料来源与证据力 / 补件单 / 访问审计。归属 T5。
   证据力不是风险等级：高证据力用主色，低的用中性灰，**不借用告警色**，
   否则「客户自传」会被读成「有问题」。 */

/* ── 证据力徽标 ── */
.ev {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 1px 8px 1px 5px; border-radius: var(--r-sm);
  font-size: var(--fs-xs); line-height: 1.7; white-space: nowrap;
  background: var(--chip-bg); color: var(--chip-ink);
}
.ev b { font-weight: 600; font-family: var(--mono); font-size: var(--fs-xs); }
.ev-hi  { background: var(--accent-soft); color: var(--accent-ink); }
.ev-mid { background: var(--ok-bg); color: var(--ok); }
.ev-lo  { background: var(--chip-bg); color: var(--chip-ink); }
.ev-n {
  padding-left: 5px; margin-left: 1px;
  border-left: 1px solid currentColor;
  font-variant-numeric: tabular-nums; opacity: .85;
}
.ev-strip { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }

/* 行内说明：采信的不是最后一版 / 已挂补件 / 销售现场取证 */
.ev-note {
  margin-top: 4px; font-size: var(--fs-xs); line-height: 1.6;
  color: var(--muted);
  padding-left: 8px; border-left: 2px solid var(--line-strong);
}

/* ── 历史版本 ── */
.ev-ver-row > td { padding-top: 0; padding-bottom: 0; background: var(--card-2); }
.ev-versions { padding: 4px 0 10px; }
.ev-versions > summary {
  cursor: pointer; font-size: var(--fs-xs); color: var(--muted);
  padding: 6px 0; list-style: none;
}
.ev-versions > summary::-webkit-details-marker { display: none; }
.ev-versions > summary::before { content: "▸ "; }
.ev-versions[open] > summary::before { content: "▾ "; }
.ev-ver {
  display: grid; align-items: center; gap: 8px;
  grid-template-columns: 72px auto minmax(0, 1fr) auto auto auto;
  padding: 6px 0; border-top: 1px solid var(--line);
}
.ev-ver-no { font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.ev-ver-used { background: var(--accent-soft); border-radius: var(--r-sm); padding-inline: 8px; }

/* ── 补件单 ── */
.sup-current {
  padding: 12px; margin-top: 4px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r);
}
.sup-item {
  margin-top: 10px; padding: 10px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
}
.sup-item-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sup-line {
  display: flex; gap: 8px; align-items: baseline;
  margin-top: 6px; font-size: var(--fs-sm); line-height: 1.6;
}
/* 内部备注与客户话术并排，两个标签必须一眼分得开 ——
   分不开的那天，就会有人把内部结论写进「客户看到」那一栏。 */
.sup-tag {
  flex: none; padding: 0 6px; border-radius: var(--r-sm);
  font-size: var(--fs-xs); line-height: 1.8;
  background: var(--chip-bg); color: var(--chip-ink);
}
.sup-tag-cust { background: var(--accent-soft); color: var(--accent-ink); }

.sup-history { margin-top: 12px; }
.sup-history > summary {
  cursor: pointer; font-size: var(--fs-sm); color: var(--muted); padding: 6px 0;
}
.sup-hist {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 0; border-top: 1px solid var(--line); min-width: 0;
}

/* ── 发起补件弹层 ── */
.sup-modal { max-width: 760px; }
.sup-modal-body { text-align: left; }
.sup-picks { display: flex; flex-direction: column; gap: 8px; }
.sup-pick {
  padding: 10px; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--card); transition: border-color .15s ease, background-color .15s ease;
}
.sup-pick-on { border-color: var(--accent); background: var(--card-2); }
.sup-pick-head { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.sup-pick-body {
  display: none; gap: 8px; flex-wrap: wrap;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line);
}
.sup-pick-on .sup-pick-body { display: flex; }
.sup-pick-body .select { flex: 0 0 auto; min-width: 190px; }
.sup-pick-body .sup-note { flex: 1 1 240px; min-width: 0; }
.sup-preview { flex: 1 1 100%; display: flex; gap: 8px; align-items: baseline; color: var(--muted); }
.sup-preview:empty { display: none; }
.sup-notify {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: 14px; font-size: var(--fs-sm); color: var(--muted); line-height: 1.6;
}

/* ── 访问审计 ── */
.visit-sum {
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  font-size: var(--fs-sm); color: var(--muted);
}
.visit-sum b { color: var(--ink); }
.visit-detail > summary {
  cursor: pointer; font-size: var(--fs-sm); color: var(--accent-ink);
  margin-top: 10px; padding: 6px 0;
}
.visit-write > td { background: var(--card-2); }

/* 队列顶上的「另有 N 件在补件中」 */
.sec-hint { display: flex; align-items: center; gap: 10px; margin: 12px 16px; }

@media (max-width: 880px) {
  .ev-ver { grid-template-columns: 72px auto minmax(0, 1fr); }
  .sup-pick-body .select, .sup-pick-body .sup-note { flex: 1 1 100%; min-width: 0; }
  .sec-hint { flex-wrap: wrap; }
}
/* <<< BLOCK:T5-workbench */

/* >>> BLOCK:T2-portal */
/* ══════════════════════════════════════════════════════════════════════
   T2 合作伙伴门户（/portal）—— **PC 优先**，与 S1 的移动采集页是两套信息组织。
   评审原话：「整体电脑端体验一般，感觉纯为手机端开发的，但很多东西是需要
   合作伙伴在 pc 端操作的。」所以这一块先按 1440px 设计，再往下收：

     >=1024  左侧清单导航（sticky）+ 右侧详情工作区
     768~1023 单列清单 + 展开式详情
     <768    分步向导，一屏一件事

   只用令牌，不写字面色值（唯一的例外在 .pt-qr-tile，理由写在那里）；
   过场只用 CSS transition；不在 html/body 写 overflow-x:hidden（sticky 会坏）。
   ═══════════════════════════════════════════════════════════════════ */

.pt-body { background: var(--ground); overflow-x: clip; }

.pt-shell { display: flex; flex-direction: column; min-height: 100vh; }
.pt-center {
  min-height: 70vh; padding: 24px 16px;
  display: flex; align-items: center; justify-content: center;
}
.pt-fade { animation: pt-in .18s ease both; }
@keyframes pt-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.pt-ico { width: 16px; height: 16px; flex: none; }
.pt-sep { display: inline-block; width: 1px; height: 10px; margin: 0 8px;
          background: var(--line-strong); vertical-align: -1px; }
.pt-opt {
  display: inline-block; margin-left: 8px; 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);
}
.pt-count { font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.pt-chev { color: var(--faint); }

/* ── 顶栏 ─────────────────────────────────────────────────────────── */
.pt-head {
  position: sticky; top: 0; z-index: 20;
  background: var(--card); border-bottom: 1px solid var(--line);
}
.pt-head-in {
  display: flex; align-items: center; gap: 20px;
  max-width: 1440px; margin: 0 auto; padding: 0 24px; height: 56px;
}
.pt-brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: inherit; }
.pt-brand-mark {
  flex: none; 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;
}
.pt-brand-text { font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; }

.pt-nav { display: flex; align-items: center; gap: 2px; flex: 1 1 auto; }
.pt-nav-item {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: var(--r);
  color: var(--muted); font-size: var(--fs-sm); text-decoration: none;
  transition: background-color .15s ease, color .15s ease;
}
.pt-nav-item:hover { background: var(--chip-bg); color: var(--ink); text-decoration: none; }
.pt-nav-item.active { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; }

.pt-who { text-align: right; line-height: 1.3; min-width: 0; }
.pt-who-org { font-size: var(--fs-sm); font-weight: 600; }
.pt-who-name { font-size: var(--fs-xs); color: var(--muted); }

/* ── 页面骨架 ─────────────────────────────────────────────────────── */
.pt-main { flex: 1 1 auto; }
.pt-page { max-width: 1120px; margin: 0 auto; padding: 24px; }
.pt-page-wide { max-width: 1440px; }
.pt-page-head { margin-bottom: 18px; }
.pt-page-head h1 { font-size: var(--fs-2xl); font-weight: 600; }
.pt-page-desc { margin-top: 6px; color: var(--muted); font-size: var(--fs-sm); }

.pt-cols { display: grid; grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); gap: 20px; }
.pt-col-main, .pt-col-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

.pt-card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-xl); box-shadow: var(--shadow-sm); overflow: hidden;
}
.pt-card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 16px; border-bottom: 1px solid var(--line); background: var(--card-2);
}
.pt-card-head h3 { font-size: var(--fs); font-weight: 600; }
.pt-card-body { padding: 16px; }
.pt-card-body.tight { padding: 0; }
.pt-card-foot { padding: 11px 16px; border-top: 1px solid var(--line); line-height: 1.7; }

.pt-empty { padding: 22px 16px; text-align: center; color: var(--muted); font-size: var(--fs-sm); }
.pt-err {
  margin: 12px 0; 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;
}
.pt-note-card {
  max-width: 420px; padding: 26px 22px; text-align: center;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-xl);
  box-shadow: var(--shadow-sm);
}
.pt-note-title { font-size: var(--fs-lg); font-weight: 600; margin-bottom: 8px; }
.pt-note-text { font-size: var(--fs-sm); color: var(--muted); line-height: 1.8; }
.pt-note-card .btn { margin-top: 16px; }

/* ── 状态徽标：这是进度，不是预警，颜色克制 ──────────────────────── */
.pt-state {
  display: inline-flex; align-items: center; padding: 3px 10px;
  border-radius: var(--r-sm); background: var(--chip-bg); color: var(--chip-ink);
  font-size: var(--fs-xs); white-space: nowrap;
}
.pt-state.is-open { background: var(--accent-soft); color: var(--accent-ink); }
.pt-state.is-working { background: var(--card-2); color: var(--muted); }
.pt-state.is-closed { background: var(--chip-bg); color: var(--chip-ink); }

.pt-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: var(--r-sm);
  background: var(--chip-bg); color: var(--chip-ink);
  font-size: var(--fs-xs); white-space: nowrap; flex: none;
}
.pt-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.pt-badge.is-done,
.pt-badge.is-verified,
.pt-badge.is-valid { background: var(--ok-bg); color: var(--ok); }
.pt-badge.is-wait,
.pt-badge.is-pending { background: var(--chip-bg); color: var(--chip-ink); }
.pt-badge.is-todo,
.pt-badge.is-redo,
.pt-badge.is-soon { background: var(--accent-soft); color: var(--accent-ink); }
.pt-badge.is-expired { background: var(--warn-bg); color: var(--warn); }
.pt-badge.is-opt,
.pt-badge.is-missing { background: transparent; color: var(--faint);
                        box-shadow: inset 0 0 0 1px var(--line); }

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

/* ── 首页 ─────────────────────────────────────────────────────────── */
.pt-hero { padding: 20px; }
.pt-hero-top { display: flex; align-items: flex-start; gap: 16px; }
.pt-hero-label { font-size: var(--fs-xs); color: var(--muted); }
.pt-hero-title { font-size: var(--fs-xl); font-weight: 600; margin-top: 2px; }
.pt-hero-sub { margin-top: 6px; font-size: var(--fs-sm); color: var(--muted); }
.pt-hero-prog { margin-top: 18px; display: flex; flex-direction: column; gap: 8px; }
.pt-hero-foot {
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}

.pt-todo-list { display: flex; flex-direction: column; }
.pt-todo-row {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 11px 16px; text-align: left;
  background: transparent; border: none; border-bottom: 1px solid var(--line-soft);
  color: inherit; font: inherit; cursor: pointer;
  transition: background-color .12s ease;
}
.pt-todo-row:last-child { border-bottom: none; }
.pt-todo-row:hover { background: var(--card-2); }
.pt-todo-row .pt-dot { background: var(--accent); }
.pt-todo.is-expiring .pt-todo-row .pt-dot { background: var(--warn-solid); }
.pt-todo-why { font-size: var(--fs-xs); color: var(--muted); max-width: 40%;
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pt-arch-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; border-bottom: 1px solid var(--line-soft); font-size: var(--fs-sm);
}
.pt-arch-row:last-child { border-bottom: none; }

/* ── 资料清单：PC 双栏 ───────────────────────────────────────────── */
/* 侧栏 sticky 的正确姿势：网格项被拉伸到整行高（默认 stretch，别写 align-items:start，
   写了包含块就等于元素本身高度，sticky 没有可移动的余地），sticky 挂在内层。 */
.pt-two { display: grid; grid-template-columns: 340px minmax(0, 1fr); gap: 20px; }
.pt-side { min-width: 0; }
.pt-side-in {
  position: sticky; top: 76px;
  display: flex; flex-direction: column; gap: 12px;
  /* 侧栏本身必须比视口矮，否则 top-sticky 永远不会生效（浏览器规范如此）。
     所以整根侧栏封顶到视口高度，清单在内部滚。 */
  max-height: calc(100vh - 96px);
}

.pt-sum {
  padding: 14px 16px; display: flex; flex-direction: column; gap: 10px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-xl); box-shadow: var(--shadow-sm);
}
.pt-sum-miss { display: flex; flex-wrap: wrap; gap: 6px; }
.pt-miss {
  padding: 3px 9px; border-radius: var(--r-sm);
  background: var(--accent-soft); color: var(--accent-ink);
  border: none; font: inherit; font-size: var(--fs-xs); cursor: pointer;
}
.pt-miss:hover { background: var(--accent); color: var(--accent-on); }

.pt-items {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-xl); box-shadow: var(--shadow-sm);
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
}
.pt-item-grp-head {
  padding: 9px 14px; background: var(--card-2);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-xs); color: var(--muted); letter-spacing: .3px;
}
.pt-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 11px 14px; text-align: left;
  background: transparent; border: none; border-bottom: 1px solid var(--line-soft);
  border-left: 2px solid transparent;
  color: inherit; font: inherit; cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}
.pt-item:hover { background: var(--card-2); }
.pt-item.active { background: var(--accent-soft); border-left-color: var(--accent); }
.pt-item.is-flag .pt-item-name { font-weight: 600; }
.pt-item-seq {
  flex: none; width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--chip-bg); color: var(--muted);
  font-size: var(--fs-xs); font-variant-numeric: tabular-nums;
}
.pt-item.active .pt-item-seq { background: var(--accent); color: var(--accent-on); }
.pt-item-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pt-item-name { font-size: var(--fs-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pt-item-grp { font-size: var(--fs-xs); color: var(--faint); }

.pt-submit { display: flex; flex-direction: column; gap: 8px; }
.pt-submit-note { line-height: 1.7; }

/* ── 资料清单：右侧工作区 ────────────────────────────────────────── */
.pt-work {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-xl); box-shadow: var(--shadow-sm); padding: 22px 24px;
  min-height: 420px;
}
.pt-work-head {
  display: flex; align-items: flex-start; gap: 14px;
  padding-bottom: 16px; border-bottom: 1px solid var(--line); margin-bottom: 18px;
}
.pt-work-title { font-size: var(--fs-lg); font-weight: 600; line-height: 1.4; }
.pt-work-sub { margin-top: 4px; font-size: var(--fs-xs); color: var(--muted); }
.pt-work-tools { margin-top: 14px; display: flex; gap: 10px; flex-wrap: wrap; }
.pt-handoff-btn { display: inline-flex; align-items: center; gap: 6px; }

.pt-notice {
  margin-bottom: 14px; padding: 12px 14px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r);
}
.pt-notice.is-todo { background: var(--accent-soft); border-color: transparent; }
.pt-notice-title { font-size: var(--fs-sm); font-weight: 600; }
.pt-notice-text { margin-top: 4px; font-size: var(--fs-sm); color: var(--muted); line-height: 1.8; }
.pt-notice.is-todo .pt-notice-title { color: var(--accent-ink); }

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

/* ── 拖拽上传 ─────────────────────────────────────────────────────── */
.pt-drop {
  display: flex; align-items: center; gap: 14px;
  padding: 20px; cursor: pointer;
  background: var(--card-2);
  border: 1px dashed var(--line-strong); border-radius: var(--r-lg);
  transition: border-color .15s ease, background-color .15s ease;
}
.pt-drop:hover, .pt-drop.is-over { border-color: var(--accent); background: var(--accent-soft); }
.pt-drop-ico {
  flex: none; width: 38px; height: 38px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--card); color: var(--accent); border: 1px solid var(--line);
}
.pt-drop-main { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pt-drop-title { font-size: var(--fs); font-weight: 600; }
.pt-drop-sub { font-size: var(--fs-xs); color: var(--muted); line-height: 1.7; }

.pt-queue { margin-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.pt-q {
  padding: 10px 12px; display: flex; flex-direction: column; gap: 7px;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r);
}
.pt-q.is-ok .pt-bar-fill { background: var(--ok-solid); }
.pt-q.is-err { border-color: var(--red-bg); }
.pt-q.is-err .pt-bar-fill { background: var(--red-solid); }
.pt-q .pt-err { margin: 0; }

/* ── 已提交的文件与预览 ──────────────────────────────────────────── */
.pt-done {
  margin-top: 16px; border: 1px solid var(--line); border-radius: var(--r-lg);
  overflow: hidden; background: var(--card);
}
.pt-done-head { display: flex; align-items: center; gap: 12px; padding: 13px 14px; }
.pt-check {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--ok-bg); color: var(--ok);
}
.pt-check-lg { width: 44px; height: 44px; margin: 0 auto 12px; }
.pt-file { flex: 1 1 auto; min-width: 0; }
.pt-file-name { font-size: var(--fs-sm); font-weight: 600; word-break: break-all; }
.pt-file-sub { margin-top: 2px; font-size: var(--fs-xs); color: var(--muted); }
.pt-done-foot { padding: 9px 14px; border-top: 1px solid var(--line);
                background: var(--card-2); line-height: 1.7; }

.pt-view { border-top: 1px solid var(--line); background: var(--card-2); }
.pt-view-img { display: block; max-width: 100%; max-height: 420px; margin: 0 auto; }
.pt-view-frame { display: block; width: 100%; height: 520px; border: none; background: var(--card-2); }
.pt-view-foot { padding: 9px 14px; border-top: 1px solid var(--line);
                font-size: var(--fs-xs); color: var(--muted); text-align: center; }
.pt-view-fallback { padding: 26px 16px; font-size: var(--fs-sm); color: var(--muted); text-align: center; }

.pt-sales { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }

/* ── 平板：单列 + 展开式详情 ─────────────────────────────────────── */
.pt-acc {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-xl); box-shadow: var(--shadow-sm); overflow: hidden;
  margin-top: 16px;
}
.pt-acc-item { border-bottom: 1px solid var(--line-soft); }
.pt-acc-item:last-child { border-bottom: none; }
.pt-acc-head {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 13px 16px; text-align: left;
  background: transparent; border: none; color: inherit; font: inherit; cursor: pointer;
}
.pt-acc-head:hover { background: var(--card-2); }
.pt-acc-head .grow { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pt-acc-body { padding: 4px 16px 20px; border-top: 1px solid var(--line); }
.pt-acc-body .pt-work-head { border-bottom: none; padding-bottom: 8px; margin-bottom: 10px; }

/* ── 手机：分步向导 ──────────────────────────────────────────────── */
.pt-wiz { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh;
          background: var(--ground); }
.pt-wiz-top {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  background: var(--card); border-bottom: 1px solid var(--line);
}
.pt-wiz-back {
  flex: none; 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;
}
.pt-wiz-back:hover { background: var(--chip-bg); color: var(--ink); }
.pt-wiz-label { font-size: var(--fs-sm); font-weight: 600; }
.pt-wiz-sub { font-size: var(--fs-xs); color: var(--muted); }
.pt-wiz-n { font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.pt-wiz-body { flex: 1 1 auto; padding: 16px 16px 24px; }
.pt-wiz-body .pt-work-title { margin-bottom: 12px; }
.pt-wiz-foot {
  position: sticky; bottom: 0; z-index: 10;
  display: flex; flex-direction: column; gap: 4px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--card); border-top: 1px solid var(--line);
}

/* ── 扫码转手机 ──────────────────────────────────────────────────── */
.pt-modal {
  position: fixed; inset: 0; z-index: 40;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: var(--overlay);
  animation: pt-in .15s ease both;
}
.pt-modal-card {
  width: 100%; max-width: 380px;
  background: var(--card); border-radius: var(--r-xl); box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.pt-modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 16px; border-bottom: 1px solid var(--line);
}
.pt-modal-head h3 { font-size: var(--fs); font-weight: 600; }
.pt-modal-body { padding: 18px 16px 20px; display: flex; flex-direction: column;
                 gap: 10px; align-items: center; text-align: center; }
.pt-modal-body .input { width: 100%; }

/* 二维码是给摄像头读的，不是 UI 元素：跟着主题反色会让一部分扫码器读不出来，
   所以这两个色值必须钉死黑白，不跟令牌走。全站唯一允许的字面色值，理由在此。 */
.pt-qr-tile {
  --qr-paper: #FFFFFF;
  --qr-ink:   #101010;
  padding: 10px; border-radius: var(--r);
  background: var(--qr-paper); color: var(--qr-ink);
}
.pt-qr-svg { display: block; width: 200px; height: 200px; }

/* ── 项目台账：PC 上是真表格 ─────────────────────────────────────── */
.pt-lg { display: flex; flex-direction: column; gap: 12px; }
.pt-lg-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.pt-lg-wrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--line); border-radius: var(--r);
}
.pt-lg-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.pt-lg-table th {
  padding: 9px 8px; text-align: left; white-space: nowrap;
  background: var(--card-2); border-bottom: 1px solid var(--line);
  font-size: var(--fs-xs); font-weight: 600; color: var(--muted);
}
.pt-lg-table td { padding: 4px 6px; border-bottom: 1px solid var(--line-soft); }
.pt-lg-table tbody tr:last-child td { border-bottom: none; }
/* 竖向格线由单元格给，输入框本身保持无框 —— 空表格也一眼看得出「这是一张表」，
   而不是一片什么都没有的白。 */
.pt-lg-table th, .pt-lg-table td { border-right: 1px solid var(--line); }
.pt-lg-table th:last-child, .pt-lg-table td:last-child { border-right: none; }
.pt-lg-ops { width: 62px; text-align: right; }
.pt-lg-in {
  width: 100%; padding: 7px 8px;
  background: var(--card); color: var(--ink);
  border: 1px solid transparent; border-radius: var(--r-sm);
  font: inherit; font-size: var(--fs-sm);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.pt-lg-in:hover { border-color: var(--line); }
.pt-lg-in:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.pt-lg-in.num { text-align: right; font-variant-numeric: tabular-nums; }
.pt-lg-foot { display: flex; gap: 10px; }
.pt-lg-tip { line-height: 1.7; }

.pt-lg-cards { display: flex; flex-direction: column; gap: 12px; }
.pt-lg-card {
  padding: 12px 14px; background: var(--card-2);
  border: 1px solid var(--line); border-radius: var(--r-lg);
}
.pt-lg-f { display: block; margin-top: 10px; }
.pt-lg-f > span { display: block; font-size: var(--fs-xs); color: var(--muted); margin-bottom: 4px; }
.pt-lg-card .pt-lg-in { border-color: var(--line-strong); }

/* ── 企业档案 ─────────────────────────────────────────────────────── */
.pt-arch-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
.pt-arch-card {
  padding: 16px; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r-xl); box-shadow: var(--shadow-sm);
}
.pt-arch-top { display: flex; align-items: flex-start; gap: 12px; }
.pt-arch-name { font-size: var(--fs); font-weight: 600; }
.pt-arch-sub { margin-top: 3px; font-size: var(--fs-xs); color: var(--muted); }
.pt-arch-meta { margin-top: 12px; font-size: var(--fs-xs); color: var(--muted); line-height: 1.8; }
.pt-arch-foot { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }

/* ── 断点：平板 ───────────────────────────────────────────────────── */
@media (max-width: 1023px) {
  .pt-head-in { padding: 0 16px; gap: 12px; }
  .pt-brand-text { display: none; }
  .pt-page, .pt-page-wide { padding: 18px 16px; }
  .pt-cols { grid-template-columns: minmax(0, 1fr); }
  .pt-two { grid-template-columns: minmax(0, 1fr); }
  .pt-side-in { position: static; max-height: none; }
  .pt-items { flex: none; overflow: visible; }
  .pt-work { padding: 18px 16px; }
  .pt-arch-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ── 断点：手机 ───────────────────────────────────────────────────── */
@media (max-width: 767px) {
  .pt-head-in { height: 52px; }
  .pt-nav { overflow-x: auto; }
  .pt-nav-item span { display: none; }
  .pt-nav-item { padding: 8px 10px; }
  .pt-who { display: none; }
  .pt-page, .pt-page-wide { padding: 14px 14px 24px; }
  .pt-page-head h1 { font-size: var(--fs-xl); }
  .pt-hero-top { flex-direction: column; gap: 10px; }
  .pt-drop { padding: 16px; }
  .pt-view-frame { height: 300px; }
  .pt-todo-why { display: none; }
  .pt-guide-img { max-width: 100%; }
  .pt-qr-svg { width: 168px; height: 168px; }
}
/* <<< BLOCK:T2-portal */

/* >>> BLOCK:S0-portal-demo  门户登录页的演示账号，一点即填。
   由 config/app.json 的 demo_login_hint 控制，交付生产前关掉，这一块整个不渲染。 */
.pl-demo {
  margin-top: 16px; padding-top: 14px;
  border-top: 1px dashed var(--line);
}
.pl-demo-head { font-size: var(--fs-sm); color: var(--muted); margin-bottom: 8px; }
.pl-demo-list { display: grid; gap: 6px; }
.pl-demo-item {
  display: flex; align-items: baseline; gap: 10px;
  width: 100%; padding: 7px 10px; text-align: left;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--card); color: var(--ink);
  font: inherit; cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.pl-demo-item:hover { border-color: var(--accent); background: var(--accent-soft); }
.pl-demo-phone { font-variant-numeric: tabular-nums; font-size: var(--fs-sm); }
.pl-demo-sup { color: var(--muted); font-size: var(--fs-xs); flex: 1; text-align: right; }
/* <<< BLOCK:S0-portal-demo */

/* >>> BLOCK:S0-verdict  概览页结论条。归属：地基。
   全页唯一允许「重」和「有色」的地方。理由：如果卡片、图表、表格都在争夺注意力，
   那「重」就失效了，页面回到没有落点的状态——所以这一块可以大字号、可以上语义色，
   其余部分一律退到中性色。句子里的高亮走深色版语义色，亮色版在 14px 上读不出来。 */
.verdict {
  display: grid; grid-template-columns: 196px minmax(0, 1fr);
  gap: 24px; padding: 20px 24px; margin-bottom: 16px;
  background: linear-gradient(120deg, var(--accent-soft) 0%, var(--card) 62%);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-sm);
}
.verdict-lead { border-right: 1px solid var(--accent-line); padding-right: 24px; }
.verdict-k { font-size: var(--fs-sm); color: var(--faint); }
.verdict-v {
  font-variant-numeric: tabular-nums;
  font-size: 34px; font-weight: 600; line-height: 1.05;
  letter-spacing: -.02em; margin-top: 4px; color: var(--ink);
}
.verdict-v.tone-deny { color: var(--deny); }
.verdict-v.tone-red  { color: var(--red); }
.verdict-v.tone-ok   { color: var(--ok); }
.verdict-v span { font-size: var(--fs-lg); font-weight: 500; color: var(--faint); margin-left: 4px; }
.verdict-sub { margin-top: 8px; font-size: var(--fs-sm); color: var(--faint); }
.verdict-body h3 { font-size: var(--fs-lg); }
.verdict-body p { margin-top: 8px; font-size: var(--fs); line-height: 1.85; color: var(--muted);
                  max-width: 52em; }
.verdict-body p b { color: var(--ink); font-weight: 600; }
.verdict-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 14px; }

/* 句子里的高亮：数字等宽，颜色一律深色版 */
.hl { font-variant-numeric: tabular-nums; font-weight: 600; }
.hl-deny { color: var(--deny); }
.hl-red  { color: var(--red); }
.hl-warn { color: var(--warn); }
.hl-ok   { color: var(--ok); }
.hl-accent { color: var(--accent-ink); }

/* 缺口占位：算不出来的时候出原因，不出数字。
   「未运算 2 件」和「无预警 2 件」是两件完全不同的事，画成同一个数就等于说了谎。
   所以它要看得出是缺口，不能长得像正常内容。 */
.gap-note {
  display: block; margin-top: 12px; padding: 8px 12px;
  border-left: 2px solid var(--line-strong);
  background: var(--card-2);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: var(--fs-sm); line-height: 1.7; color: var(--faint);
  max-width: 52em;
}

/* 窄屏堆叠。这条必须写在 .verdict-lead 之后——同特异性下靠源序取胜。 */
@media (max-width: 900px) {
  .verdict { grid-template-columns: minmax(0, 1fr); gap: 16px; padding: 16px; }
  .verdict-lead { border-right: 0; border-bottom: 1px solid var(--line-soft); padding: 0 0 16px; }
}
/* <<< BLOCK:S0-verdict */

/* >>> BLOCK:G1-tour  系统演示：暗层挖洞 + 讲解卡 + 场景选择器。归属 G1。

   两条硬约束：
   1. 整层 pointer-events:none，只有讲解卡与场景选择器收点击 —— 演示时讲的人
      要能边讲边操作页面，挡住反而碍事。
   2. 打光用 SVG 遮罩挖洞，不用 box-shadow 撑大圈：同屏多锚点是主力形态，
      N 层 box-shadow 会把画面叠成一片死黑。
   层级：低于图片弹层（.modal z=100），高于轻提示（.toast z=200）的只有讲解卡，
   这样下钻弹层打开时它压在暗层之上，讲解卡仍然读得到。 */

.tour-layer { position: fixed; inset: 0; z-index: 90; pointer-events: none;
              opacity: 0; visibility: hidden; transition: opacity .18s ease, visibility .18s ease; }
.tour-layer.open { opacity: 1; visibility: visible; }

.tour-mask { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.tour-dim { fill: var(--overlay); }

.tour-ring { position: fixed; border: 2px solid var(--accent); border-radius: var(--r-xl);
             box-shadow: var(--focus-ring); pointer-events: none;
             transition: top .18s ease, left .18s ease, width .18s ease, height .18s ease; }
.tour-ring-n { position: absolute; top: -11px; left: -11px;
               width: 22px; height: 22px; border-radius: var(--r-pill);
               background: var(--accent); color: var(--accent-on);
               font-size: var(--fs-xs); font-weight: 700; line-height: 22px; text-align: center;
               box-shadow: var(--shadow-sm); }

/* 讲解卡：右下角钉住；锚点压在它底下时翻到左边（.flip 由 JS 加） */
.tour-card { position: fixed; right: 20px; bottom: 20px; left: auto; width: 372px;
             z-index: 210; pointer-events: auto;
             background: var(--card); border: 1px solid var(--line);
             border-radius: var(--r-xl); box-shadow: var(--shadow-lg); padding: 16px; }
.tour-card.flip { left: 20px; right: auto; }
.tour-card-head { display: flex; align-items: center; gap: 8px; }
.tour-card-tag { flex: 1; min-width: 0; font-size: var(--fs-xs); font-weight: 600;
                 letter-spacing: .04em; color: var(--accent-ink); }
.tour-card-no { font-size: var(--fs-xs); color: var(--faint);
                font-variant-numeric: tabular-nums; }
.tour-x { width: 24px; height: 24px; border: 0; border-radius: var(--r-pill);
          background: var(--chip-bg); color: var(--muted); cursor: pointer;
          font-size: var(--fs-xs); line-height: 1; transition: background .15s ease, color .15s ease; }
.tour-x:hover { background: var(--line); color: var(--ink); }

.tour-prog { height: 3px; margin-top: 10px; border-radius: var(--r-pill);
             background: var(--line-soft); overflow: hidden; }
.tour-prog i { display: block; height: 100%; background: var(--accent);
               border-radius: var(--r-pill); transition: width .4s ease; }

.tour-card-title { font-size: var(--fs); font-weight: 600; color: var(--ink); margin-top: 12px; }
.tour-card-desc { font-size: var(--fs-sm); line-height: 1.85; color: var(--muted); margin-top: 8px;
                  max-height: 38vh; overflow-y: auto; }

.tour-rows { margin-top: 10px; max-height: 42vh; overflow-y: auto; }
.tour-row { display: flex; gap: 8px; width: 100%; text-align: left;
            border: 0; background: none; cursor: pointer; padding: 6px; margin-left: -6px;
            border-radius: var(--r); transition: background .15s ease; }
.tour-row:hover { background: var(--card-2); }
.tour-row + .tour-row { margin-top: 2px; }
.tour-row-n { flex: none; width: 17px; height: 17px; margin-top: 3px;
              border-radius: var(--r-pill); background: var(--accent); color: var(--accent-on);
              font-size: 10px; font-weight: 700; line-height: 17px; text-align: center; }
.tour-row-body { min-width: 0; }
.tour-row-title { display: block; font-size: var(--fs-sm); font-weight: 600; color: var(--ink);
                  line-height: 1.5; }
.tour-row-off { color: var(--accent-ink); font-weight: 500; font-size: var(--fs-xs); }
.tour-row-text { display: block; font-size: var(--fs-xs); line-height: 1.75; color: var(--muted);
                 margin-top: 2px; }

.tour-acts { display: flex; align-items: center; gap: 8px; margin-top: 14px; }
.tour-hint { font-size: var(--fs-xs); color: var(--faint); text-align: center; margin-top: 8px; }

/* 顶栏按钮 */
.tour-btn { display: inline-flex; align-items: center; gap: 6px; }
.tour-btn .nav-ico { width: 15px; height: 15px; }

/* ── 场景选择器 ─────────────────────────────────────────────────── */
.tour-picker { position: fixed; inset: 0; z-index: 220; overflow-y: auto;
               display: flex; align-items: flex-start; justify-content: center;
               padding: 24px 16px; background: var(--overlay);
               opacity: 0; visibility: hidden; transition: opacity .18s ease, visibility .18s ease; }
.tour-picker.open { opacity: 1; visibility: visible; }
.tour-picker-box { width: 100%; max-width: 900px; margin: auto;
                   background: var(--ground); border: 1px solid var(--line);
                   border-radius: var(--r-xl); box-shadow: var(--shadow-lg); padding: 22px; }
.tour-picker-head { display: flex; align-items: flex-start; gap: 16px; }
.tour-picker-head h2 { font-size: var(--fs-2xl); font-weight: 600; letter-spacing: -.01em; }
.tour-picker-head p { font-size: var(--fs-sm); line-height: 1.85; color: var(--muted);
                      margin-top: 6px; max-width: 62em; }
.tour-picker-head .tour-x { flex: none; }
.tour-picker-foot { font-size: var(--fs-xs); line-height: 1.9; color: var(--faint); margin-top: 18px; }

.tour-sec { margin-top: 18px; }
.tour-sec-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px; }
.tour-sec-title { font-size: var(--fs-xs); font-weight: 600; letter-spacing: .06em; color: var(--muted); }
.tour-sec-note { font-size: var(--fs-xs); color: var(--faint); }
.tour-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; align-items: start; }

/* 一条龙：整个选择器里唯一一处带色的块 */
.tour-lead { display: flex; align-items: center; gap: 16px; width: 100%; text-align: left;
             padding: 18px; border: 1px solid var(--accent-line); border-radius: var(--r-lg);
             background: var(--accent-soft); cursor: pointer;
             transition: border-color .15s ease; }
.tour-lead:hover { border-color: var(--accent); }
.tour-lead-body { min-width: 0; }
.tour-lead-tag { display: block; font-size: var(--fs-xs); font-weight: 600; letter-spacing: .06em;
                 color: var(--accent-ink); }
.tour-lead-title { display: block; font-size: var(--fs-lg); font-weight: 600; color: var(--ink);
                   margin-top: 5px; }
.tour-lead-sub { display: block; font-size: var(--fs-sm); line-height: 1.8; color: var(--muted);
                 margin-top: 5px; }
.tour-lead-side { flex: none; margin-left: auto; text-align: right; }
.tour-lead-min { display: block; font-size: var(--fs-xs); color: var(--faint);
                 font-variant-numeric: tabular-nums; }
.tour-lead-go { display: inline-block; margin-top: 8px; padding: 6px 14px;
                border-radius: var(--r-pill); background: var(--accent); color: var(--accent-on);
                font-size: var(--fs-sm); font-weight: 500; }

/* 场景卡 */
.tour-item { display: block; width: 100%; text-align: left; cursor: pointer;
             padding: 13px 14px; background: var(--card);
             border: 1px solid var(--line-soft); border-radius: var(--r-lg);
             transition: border-color .15s ease, background .15s ease; }
.tour-item:hover { border-color: var(--line-strong); background: var(--card-2); }
.tour-item-head { display: flex; align-items: center; gap: 8px; }
.tour-item-n { font-size: var(--fs-sm); font-weight: 600; color: var(--faint);
               font-variant-numeric: tabular-nums; }
.tour-item-title { flex: 1; min-width: 0; font-size: var(--fs-sm); font-weight: 600; color: var(--ink); }
.tour-item-min { flex: none; font-size: var(--fs-xs); color: var(--faint);
                 font-variant-numeric: tabular-nums; }
.tour-item-sub { display: block; font-size: var(--fs-xs); line-height: 1.8; color: var(--muted);
                 margin-top: 5px; }
/* 讲过：演示常被打断好几次，用来记住讲到哪了。中性色，不是状态色。 */
.tour-seen { flex: none; display: inline-flex; align-items: center; padding: 1px 7px;
             border-radius: var(--r-pill); background: var(--chip-bg); color: var(--chip-ink);
             font-size: var(--fs-xs); }

.tour-branch-toggle { display: block; margin: 4px 0 0 6px; border: 0; background: none;
                      cursor: pointer; font-size: var(--fs-xs); color: var(--faint);
                      transition: color .15s ease; }
.tour-branch-toggle:hover { color: var(--accent-ink); }
.tour-branch { margin: 6px 0 0 10px; padding-left: 10px; border-left: 2px solid var(--accent-line); }
.tour-branch .tour-item + .tour-item { margin-top: 6px; }

@media (max-width: 900px) {
  .tour-card { left: 12px; right: 12px; bottom: 12px; width: auto; }
  .tour-card.flip { left: 12px; right: 12px; }
  .tour-grid { grid-template-columns: minmax(0, 1fr); }
  .tour-lead { flex-wrap: wrap; }
  .tour-lead-side { margin-left: 0; text-align: left; }
  .tour-btn span { display: none; }
}
/* <<< BLOCK:G1-tour */

/* >>> BLOCK:G3-qc  材料质检（内部工作台口径） */
.qc-issues { display: flex; flex-direction: column; gap: 4px; }
.qc-issue { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.qc-issue-label { font-size: var(--fs-sm); color: var(--ink); }
.qc-issue-note { font-size: var(--fs-xs); color: var(--muted); }
/* <<< BLOCK:G3-qc */

/* >>> BLOCK:G2-extract
   自动识别：行内入口 + 展开的识别结果面板（web/assets/pages/materials.js）。
   面板是给内部信用审核看的，密度优先：一行一个字段，需人工的那条靠左侧一道
   警示色边挑出来，其余一律退到中性色 —— 一屏十几条都染色等于没染。
   过场只用 transition，spinner 复用公共的 .spinner。 */

.g2-ext-actions {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 10px; flex-wrap: wrap; max-width: 620px;
}

.g2-ext-cell { display: flex; align-items: center; gap: 4px; }
.g2-ext-btn .spinner { width: 11px; height: 11px; margin-right: 5px; vertical-align: -1px; }

/* 状态计数条。卡片是 tight（padding: 0），这一条自己带内边距。 */
.g2-ext-sum {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 18px;
  padding: 10px 16px; border-bottom: 1px solid var(--line-soft);
  font-size: var(--fs-sm); color: var(--muted);
}
.g2-ext-sum b { color: var(--ink); font-weight: 600; }
/* 待人工复核 / 识别失败：数字本身要读，用深色版语义色 */
.g2-ext-alarm, .g2-ext-alarm b { color: var(--warn); }
.g2-ext-busy-note { margin: 12px 16px 0; }

/* 展开的结果面板 */
.g2-ext-row > td { padding: 0; background: var(--card-2); }
.g2-ext-panel {
  padding: 12px 16px;
  border-left: 2px solid var(--accent-line);
  animation: g2-ext-in .18s ease;
}
@keyframes g2-ext-in { from { opacity: 0; } to { opacity: 1; } }

.g2-ext-item {
  padding: 10px 12px; background: var(--card);
  border: 1px solid var(--line-soft); border-radius: var(--r);
}
.g2-ext-item + .g2-ext-item { margin-top: 8px; }
/* 需人工的那条才有色边。给每条都加边等于一条都没挑出来。 */
.g2-ext-manual { border-left: 3px solid var(--warn-solid); }

.g2-ext-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.g2-ext-note {
  margin-top: 6px; padding-left: 8px;
  border-left: 2px solid var(--line-strong);
  font-size: var(--fs-sm); line-height: 1.7; color: var(--muted);
}
.g2-ext-manual .g2-ext-note { border-left-color: var(--warn-solid); color: var(--warn); }
/* 多条理由一条一行。不用项目符号：左边已经有一条竖线了，再加圆点是第二层装饰。 */
.g2-ext-notes { margin: 6px 0 0; padding: 0 0 0 10px; list-style: none; }
.g2-ext-notes > li + li { margin-top: 3px; }

.g2-ext-sub {
  margin: 10px 0 2px; padding-top: 8px; border-top: 1px solid var(--line-soft);
  font-size: var(--fs-xs); color: var(--faint);
}
/* 字段区最多四列：auto-fill 在 1900px 的屏上会排到八列，
   104px 的名字列里「近1年查询明细中高息机构占比」要折成四行，
   同一行其余七格全被这四行拉高 —— 密度没换来，只换来一屏空白。
   calc(25% - 12px) 抵掉三个列间距，是「不超过四列」的写法。 */
.g2-ext-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(max(200px, calc(25% - 12px)), 1fr));
  gap: 10px 16px; margin-top: 8px; align-items: start;
}
/* 名字在上、值在下。这里的字段名动辄十几个字（「近3年最差五级分类」
   「除信用卡外未结清贷款机构总数」），左右式要给名字留一列固定宽度，
   宽了挤值、窄了折行，两头都不讨好；竖排下每格稳定两三行，行与行才对得齐。 */
.g2-ext-f {
  display: flex; flex-direction: column; min-width: 0;
  font-size: var(--fs-sm); line-height: 1.6;
}
/* 整段文本（页面文字、经营范围、未取到的字段清单）占满一行 */
.g2-ext-f-wide { grid-column: 1 / -1; }
.g2-ext-k {
  font-size: var(--fs-xs); color: var(--faint);
  /* 没翻译的英文键名（subject_name_match）过去会溢出去盖住右边的值 */
  overflow-wrap: anywhere;
}
.g2-ext-v { min-width: 0; color: var(--ink); overflow-wrap: anywhere; }
/* 候选值是「读出来了但没敢采信」，不是结论。标出来，别让人当成已采信的字段。 */
.g2-ext-cand { color: var(--warn); }

.g2-ext-more { margin-top: 8px; }
.g2-ext-more > summary {
  cursor: pointer; font-size: var(--fs-sm); color: var(--muted);
  transition: color .15s ease;
}
.g2-ext-more > summary:hover { color: var(--accent-ink); }
/* 宽表自己滚，页面主体永不横向滚动 */
.g2-ext-tbl { overflow-x: auto; margin-top: 6px; }
.g2-ext-tbl .tbl { min-width: 520px; }
.g2-ext-tbl .tbl th, .g2-ext-tbl .tbl td { padding: 6px 10px; font-size: var(--fs-xs); }

@media (max-width: 900px) {
  .g2-ext-actions { justify-content: flex-start; }
  .g2-ext-grid { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }
}
/* <<< BLOCK:G2-extract */

/* >>> BLOCK:V3-manual
   人工复核工作台。归属：V3。

   排版意图：**左边原件、右边依据与结论，一屏之内判得完。**
   复核这件事的成本几乎全在「翻来翻去对照」上 —— 把原件和分数分到两页，
   人就会跳过原件直接按按钮，那队列就白建了。
   全篇只用中性色与语义色的既有令牌，不新增颜色。 */

/* 两栏：左原件右结论。窄屏落成上下两块，原件在上（先看东西再下结论）。 */
.mq-split {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 12px; align-items: start;
}
.mq-pane { min-width: 0; }

.mq-foot { margin-top: 10px; line-height: 1.7; }
.mq-stuck { font-size: var(--fs-sm); color: var(--ink); }
/* 「已有人工记录仍判不了」是给排队的人看的信号，不是告警，用中性偏暖的那一档 */
.mq-blocked { color: var(--warn); margin-top: 2px; }

/* ── 原件 ── */
.mq-file {
  border: 1px solid var(--line-soft); border-radius: var(--r);
  overflow: hidden; background: var(--card-2);
}
.mq-file-img { display: block; width: 100%; height: auto; background: var(--card); }
.mq-file-pdf { display: block; width: 100%; height: 420px; border: 0; background: var(--card); }
.mq-file-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 6px 10px; border-top: 1px solid var(--line-soft);
}
.mq-companion { margin-top: 12px; }
.mq-companion > .xsmall { margin-bottom: 4px; }

/* ── 分块 ── */
.mq-block { padding-top: 12px; }
.mq-block + .mq-block { margin-top: 4px; border-top: 1px solid var(--line-soft); }
.mq-block-head {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  font-size: var(--fs-xs); color: var(--faint); margin-bottom: 8px;
}
.mq-note {
  margin-top: 8px; padding-left: 8px;
  border-left: 2px solid var(--line-strong);
  font-size: var(--fs-sm); line-height: 1.7; color: var(--muted);
}

/* ── 机器给的依据 ── */
.mq-basis-row {
  display: grid; grid-template-columns: 116px 84px minmax(0, 1fr);
  gap: 10px; align-items: baseline;
  font-size: var(--fs-sm); line-height: 1.9;
}
.mq-basis-k { color: var(--muted); }
.mq-basis-v { color: var(--ink); font-variant-numeric: tabular-nums; }
.mq-basis-hint { color: var(--faint); font-size: var(--fs-xs); min-width: 0; }
/* 整段文字横跨数值列与备注列：挤在一个数那么宽的列里会一个字一行 */
.mq-basis-wide { grid-column: 2 / -1; overflow-wrap: anywhere; }

/* ── 灰区刻度条：分数落在两条阈值之间，一眼看得出为什么轮到人判 ──
   条形是「用来看的」，所以用 -solid 那组；不用告警色，灰区本身不是坏事。 */
.mq-gauge-track {
  margin-top: 4px;
  position: relative; height: 10px; border-radius: var(--r-sm);
  background: var(--card-2); border: 1px solid var(--line-soft);
}
.mq-gauge-zone {
  position: absolute; top: 0; bottom: 0;
  background: var(--warn-bg); border-left: 1px solid var(--warn-solid);
  border-right: 1px solid var(--warn-solid);
}
.mq-gauge-mark {
  position: absolute; top: -3px; bottom: -3px; width: 2px;
  background: var(--accent); border-radius: var(--r-sm);
}
.mq-gauge-legend {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  margin-top: 6px; font-size: var(--fs-xs); color: var(--faint);
  font-variant-numeric: tabular-nums;
}
.mq-gauge-note { flex: 1 1 auto; text-align: center; min-width: 0; }

/* ── 报告片段出处 ── */
.mq-prov-row {
  display: grid; grid-template-columns: minmax(0, 150px) 68px minmax(0, 1fr);
  gap: 10px; align-items: baseline;
  font-size: var(--fs-sm); line-height: 1.9;
  border-bottom: 1px solid var(--line-soft); padding: 2px 0;
}
.mq-prov-row:last-of-type { border-bottom: none; }
.mq-prov-k { color: var(--muted); overflow-wrap: anywhere; }
.mq-prov-page { color: var(--accent-ink); white-space: nowrap; }
.mq-prov-s { color: var(--ink); overflow-wrap: anywhere; }
.mq-prov-foot { margin-top: 8px; line-height: 1.7; }

/* ── 人工处理记录 ── */
.mq-hist-row {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px;
  padding: 4px 0; border-bottom: 1px solid var(--line-soft);
}
.mq-hist-row:last-child { border-bottom: none; }

/* ── 结论 ── */
.mq-decide { padding-top: 14px; }
.mq-opts { display: grid; gap: 8px; margin-bottom: 12px; }
.mq-opt {
  display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 4px 10px;
  align-items: baseline; padding: 8px 10px; cursor: pointer;
  border: 1px solid var(--line-soft); border-radius: var(--r);
  transition: border-color .15s ease, background-color .15s ease;
}
.mq-opt:hover { border-color: var(--accent); background: var(--accent-soft); }
.mq-opt input { grid-row: span 2; }
.mq-opt-t { font-size: var(--fs); color: var(--ink); font-weight: 600; }
.mq-opt-d { grid-column: 2; font-size: var(--fs-xs); color: var(--muted); line-height: 1.7; }

.mq-fix-desc { line-height: 1.7; margin-bottom: 6px; }
.mq-fix-row {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px;
  padding: 4px 0; cursor: pointer; font-size: var(--fs-sm);
}
.mq-fix-k { color: var(--muted); }
/* 候选值是「读出来了但没敢采信」，与识别面板保持同一个说法 */
.mq-fix-v { color: var(--warn); overflow-wrap: anywhere; }

.mq-note-hint { margin-top: 2px; line-height: 1.7; }
.mq-err { margin: 10px 0 0; }
.mq-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 14px; }

@media (max-width: 1080px) {
  .mq-split { grid-template-columns: minmax(0, 1fr); }
  .mq-file-pdf { height: 320px; }
  .mq-basis-row { grid-template-columns: 104px 76px minmax(0, 1fr); }
  .mq-prov-row { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}
/* 识别面板里的「去人工复核」入口：与面板同宽、左对齐，
   与右对齐的整件识别按钮区区分开 —— 那是操作，这是去处。 */
.g2-ext-manual-link {
  justify-content: flex-start; max-width: none;
  margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line-soft);
}
/* <<< BLOCK:V3-manual */
/* >>> BLOCK:V4-collect
   台账 Excel 模板 / 导入条 + 采集授权确认。归属：V4。
   只用文件头的令牌，不写字面色值；过场一律 CSS transition。 */

/* 台账页顶部的两个 Excel 入口。它是「另一条路」，不是主操作，
   所以用次级按钮 + 一条淡底，别和「保存台账」抢。 */
.pt-lg-xls {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  padding: 10px 12px; border-radius: var(--r);
  background: var(--card-2); border: 1px solid var(--line-soft);
}
.pt-lg-pick { cursor: pointer; }
/* 导入失败时逐行列出「第几行、哪里不对」。系统不替客户猜值，
   所以这份清单就是他要改的全部内容。 */
.pt-lg-errs { margin: 6px 0 0; padding-left: 18px; line-height: 1.9; color: var(--muted); }

/* 采集授权确认：整块是一屏里唯一的事，所以给足留白，不做成小字提示。 */
.pt-auth {
  padding: 16px 18px; border-radius: var(--r-lg);
  background: var(--card-2); border: 1px solid var(--line);
}
.pt-auth-head { font-size: var(--fs); font-weight: 600; color: var(--ink); }
.pt-auth-text { margin-top: 10px; font-size: var(--fs-sm); color: var(--muted); }
.pt-auth-text p { margin: 0 0 8px; line-height: 1.9; }
.pt-auth-text p:last-child { margin-bottom: 0; }

.pt-auth-check {
  display: flex; align-items: center; gap: 10px;
  margin-top: 14px; padding: 10px 12px; width: 100%;
  text-align: left; cursor: pointer;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r);
  font: inherit; font-size: var(--fs-sm);
  transition: border-color .15s ease, background-color .15s ease;
}
.pt-auth-check:hover { border-color: var(--line-strong); }
.pt-auth-check.is-on { border-color: var(--accent); background: var(--accent-soft); }
.pt-auth-check:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.pt-auth-box {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: var(--r-sm);
  border: 1px solid var(--line-strong); background: var(--card);
  transition: border-color .15s ease, background-color .15s ease;
}
.pt-auth-check.is-on .pt-auth-box {
  border-color: var(--accent); background: var(--accent); color: var(--accent-on);
}
.pt-auth-box svg { width: 12px; height: 12px; }
.pt-auth-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin-top: 14px; }

@media (max-width: 767px) {
  .pt-lg-xls { flex-direction: column; align-items: stretch; }
  /* 「已保存 N 个项目」在窄屏会被挤成一列竖排，让它整个换行 */
  .pt-lg-head { flex-wrap: wrap; }
}
/* <<< BLOCK:V4-collect */

/* >>> BLOCK:S0-pipeline  流水线提示条：跑着 / 上一轮失败。用语义色的浅底深字，不刷整块亮色 */
.alert-warn   { background: var(--warn-bg); color: var(--warn); border-color: var(--warn-bg); }
.rv-pipe      { margin: 10px 0 0; }
.rv-pipe .spinner { width: 12px; height: 12px; margin-right: 8px; vertical-align: -2px; }
/* <<< BLOCK:S0-pipeline */

/* >>> BLOCK:S0-guard */
/* 核验格的第四态「未接入」：非演示进件上外部接口还是 mock，本项压根没核验。
   与「无法判定」（chk-unk，要人去查）分开画：虚线感的描边、更弱的字色，中性不告警。
   用 inset 阴影而不是 border，格子尺寸与同排的其它三态保持一致。 */
.chk-off {
  background: transparent; color: var(--faint);
  box-shadow: inset 0 0 0 1px var(--line-strong);
}
.chk-off i { font-weight: 500; }
/* <<< BLOCK:S0-guard */

/* >>> BLOCK:S0-manual */
/* 人工复核 · 征信字段人工录入 / 报告要素采信（S0-manual）。
   只用上面的令牌，不新增颜色。录入表单是「照着原件抄」，不是「猜」：
   留空一律按无法判定处理，页面顶上那行提示用主色底，不用告警色。 */
.mq-entry-lead {
  margin-bottom: 10px; padding: 8px 10px;
  border-left: 2px solid var(--accent); background: var(--accent-soft);
  color: var(--accent-ink); font-size: var(--fs-sm); line-height: 1.7;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}
.mq-entry-group { margin-top: 10px; }
.mq-entry-group-t { font-size: var(--fs-xs); color: var(--muted); margin-bottom: 6px; }
.mq-entry-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px;
}
.mq-entry-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mq-entry-field > label { font-size: var(--fs-xs); color: var(--muted); line-height: 1.5; }
.mq-entry-field .input, .mq-entry-field .select { width: 100%; box-sizing: border-box; }
.mq-entry-wide { grid-column: 1 / -1; }
/* 机器预填的值：中性提示，不是结论 */
.mq-entry-machine { color: var(--faint); font-size: var(--fs-xs); }
.mq-check-list { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 4px 0; }
.mq-check-list .check { white-space: normal; color: var(--ink); }
.mq-check-none { color: var(--muted); }

/* 四项核对现状：状态字用深色版语义色（要读的字），不用亮色版 */
.mq-checks-row {
  display: grid; grid-template-columns: 116px 64px minmax(0, 1fr); gap: 10px;
  align-items: baseline; font-size: var(--fs-sm); line-height: 1.9;
}
.mq-checks-k { color: var(--muted); }
.mq-checks-s { font-weight: 600; }
.mq-checks-s.is-pass { color: var(--ok); }
.mq-checks-s.is-fail { color: var(--red); }
.mq-checks-s.is-unknown { color: var(--warn); }
.mq-checks-r { color: var(--faint); font-size: var(--fs-xs); overflow-wrap: anywhere; }

/* 采信候选值：候选只来自解析结果，行里没有输入框 */
.mq-cand-row {
  display: grid; grid-template-columns: 18px 104px minmax(0, 1fr); gap: 2px 10px;
  align-items: baseline; padding: 6px 0; cursor: pointer;
  border-bottom: 1px solid var(--line-soft); font-size: var(--fs-sm);
}
.mq-cand-row:last-of-type { border-bottom: none; }
.mq-cand-row input { margin: 0; accent-color: var(--accent); }
.mq-cand-k { color: var(--muted); }
.mq-cand-v { color: var(--ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.mq-cand-cur { grid-column: 3; color: var(--faint); font-size: var(--fs-xs); }
.mq-entry-link { margin-top: 8px; line-height: 1.7; }

@media (max-width: 1080px) {
  .mq-entry-grid { grid-template-columns: minmax(0, 1fr); }
  .mq-checks-row { grid-template-columns: 104px 56px minmax(0, 1fr); }
}
/* <<< BLOCK:S0-manual */

/* >>> BLOCK:S0-portal
   门户首页状态说明 / 清单只读提示 / 内部「用这个对接人开户」横幅。归属：S0-portal。
   只用文件头的令牌，不写字面色值。 */
.pt-hero-note { margin-top: 8px; line-height: 1.7; }
.pt-readonly { margin-bottom: 14px; }
.pa-suggest {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px;
  padding: 10px 14px; margin-bottom: 12px; border-radius: var(--r);
  background: var(--accent-soft); border: 1px solid var(--line);
}
.pa-suggest .grow { min-width: 0; line-height: 1.7; }
/* <<< BLOCK:S0-portal */

/* >>> BLOCK:W1-audit  审计链页（内部）。归属 W1。
   只有四个类：自检条的两栏排布、链内序号的等宽、断口行的底色、明细的折行。
   结论色一律走 .alert 的现成三档（ok / error / info），不另起一套语义色。 */
.chain-bar { display: flex; align-items: flex-start; gap: 12px; }
.chain-bar-main { flex: 1 1 auto; min-width: 0; }
.chain-bar-title { font-weight: 600; }
/* 说明文字用 currentColor 淡一档，而不是切到 --muted：
   放在 .alert-error 的浅红底上，中性灰会显得脏。 */
.chain-bar-note { font-size: var(--fs-sm); margin-top: 3px; opacity: .85; }
.chain-seq { font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }
.chain-row-broken td { background: var(--red-bg); }
.chain-detail { font-size: var(--fs-xs); color: var(--muted); overflow-wrap: anywhere; }
/* <<< BLOCK:W1-audit */
/* >>> BLOCK:W2-formula
   规则命中的算式化证据（下钻弹层里的一行算式）。归属 W2。
   只用文件头的令牌，不写字面色值。算式是给立邦内部看的，客户端一个字都没有。
   底色用 --card-2 而不是语义色：它是「怎么算的」，不是又一条预警。 */
.rv-formula {
  margin-bottom: 10px; padding: 10px 12px;
  border-radius: var(--r-sm); border-left: 2px solid var(--line-strong);
  background: var(--card-2); color: var(--ink);
  font-size: var(--fs-sm); line-height: 1.8;
  overflow-wrap: anywhere;
}
.rv-formula-none { color: var(--faint); border-left-color: var(--line); }
/* <<< BLOCK:W2-formula */

/* >>> BLOCK:W3-radar  存续期变更雷达（内部页）。归属 W3。
   颜色一律用头部令牌，不写字面色值。语义色只用来表达影响档（实质 / 关注），
   主色留给「已接入」这类中性状态，两套不互相借用（docs/06）。 */
.radar-bar { display: flex; align-items: flex-start; gap: 16px; }
.radar-bar-main { flex: 1 1 auto; min-width: 0; }
.radar-bar-title { font-size: var(--fs-lg); font-weight: 600; }
.radar-bar-note { margin-top: 4px; font-size: var(--fs-sm); color: var(--muted); }

/* 数据源逐条列出。一条链被压成一个 live/mock 二值，说出来的话必然是错的 ——
   本地字段一直可比，外部现状可能压根没接入，两者必须分开显示。 */
.radar-srcs { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.radar-src { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
             font-size: var(--fs-sm); }
.radar-src-name { font-weight: 600; color: var(--ink); }
.radar-src-note { color: var(--muted); flex: 1 1 240px; min-width: 0; }

.radar-sum { display: flex; flex-wrap: wrap; gap: 8px 20px; }
.radar-sum-i { font-size: var(--fs-sm); color: var(--ink); }

/* 「未参与比对」区：故意不做成折叠。藏起来页面就会让人以为所有字段都核对过了。 */
.radar-skip { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.radar-skip-title { font-size: var(--fs-sm); font-weight: 600; margin-bottom: 6px; }
.radar-skip-row { display: flex; align-items: baseline; gap: 10px;
                  font-size: var(--fs-sm); padding: 3px 0; }
.radar-skip-f { min-width: 8em; color: var(--ink); }
.radar-skip-n { margin-left: auto; color: var(--faint); font-variant-numeric: tabular-nums; }

/* 旧值 → 新值。用字重与颜色分主次，不画箭头图形：
   「变为」两个字比一个箭头更经得起窄屏与复制粘贴。 */
.radar-old { color: var(--muted); text-decoration: line-through;
             text-decoration-color: var(--line-strong); }
.radar-arrow { margin: 0 8px; font-size: var(--fs-xs); color: var(--faint); }
.radar-new { color: var(--ink); font-weight: 600; }
.radar-task { font-family: var(--mono); font-size: var(--fs-sm); }

.modal-wide { max-width: 880px; width: min(92vw, 880px); }

.radar-snaps { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.radar-snap { border: 1px solid var(--line-soft); border-radius: var(--r);
              padding: 10px 12px; background: var(--card-2); }
.radar-snap-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; }
.radar-snap-grid { display: grid; grid-template-columns: max-content 1fr;
                   gap: 4px 16px; font-size: var(--fs-sm); }
.radar-snap-k { color: var(--muted); }
.radar-snap-v { color: var(--ink); word-break: break-all; }

@media (max-width: 720px) {
  .radar-bar { flex-direction: column; }
  .radar-skip-row { flex-wrap: wrap; }
  .radar-skip-n { margin-left: 0; }
}
/* <<< BLOCK:W3-radar */
/* >>> BLOCK:W5-relations  关联方图谱（内部页）。归属：W5。
   三档必须视觉可分，而且**不能只靠颜色**：这一页会被打印出来带进授信会，
   一张全是同色实线的图在黑白打印件上就没有档位了。所以三档同时在
   「粗细 / 色深 / 实虚」三个维度上分开 —— 少了颜色照样读得出来。

   档位不是风险等级，所以这里不用语义色（docs/06：语义色只表达风险等级）。
   唯一用到 --warn 的地方是「这个合计里含弱信号」那条提示 —— 那确实是风险提示：
   拿含弱信号的敞口去做授信决定，会误伤真实的同名企业。 */
.rel-svg-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.rel-svg { display: block; min-width: 640px; }
/* 标签要压在连线上方读得出来：给字描一圈与卡片同色的边当光晕。
   paint-order: stroke 让描边先画、字后画，字形本身不会被这圈边吃掉。 */
.rel-svg text { font-family: var(--font); paint-order: stroke;
                stroke: var(--card); stroke-width: 3px; stroke-linejoin: round; }

.rel-edge { fill: none; stroke-linecap: round; transition: stroke-width .15s ease; }
.rel-edge-confirmed { stroke: var(--ink);         stroke-width: 2.5; }
.rel-edge-probable  { stroke: var(--accent);      stroke-width: 1.6; }
.rel-edge-weak      { stroke: var(--line-strong); stroke-width: 1;
                      stroke-dasharray: 4 4; }
.rel-edge-dim { opacity: .18; }

.rel-node-hit { cursor: pointer; }
.rel-node { fill: var(--card); stroke: var(--line-strong); stroke-width: 1.4; }
.rel-node-hit:hover .rel-node { stroke: var(--accent); }
.rel-node-on .rel-node { stroke: var(--accent); stroke-width: 2.4; fill: var(--accent-soft); }
.rel-node-dim { opacity: .3; }
.rel-node-id { fill: var(--muted); font-size: 11px; text-anchor: middle;
               font-family: var(--mono); }
.rel-node-name { fill: var(--ink); font-size: 12px; text-anchor: middle; }
.rel-node-amt { fill: var(--faint); font-size: 11px; text-anchor: middle;
                font-variant-numeric: tabular-nums; }

.rel-legend { display: flex; flex-wrap: wrap; gap: 18px; align-items: center;
              padding: 10px 2px 2px; font-size: var(--fs-xs); color: var(--muted); }
.rel-legend-item { display: flex; align-items: center; gap: 7px; }
.rel-legend-line { width: 26px; height: 0; border-top-style: solid; flex: 0 0 26px; }
.rel-legend-confirmed { border-top: 2.5px solid var(--ink); }
.rel-legend-probable  { border-top: 1.6px solid var(--accent); }
.rel-legend-weak      { border-top: 1px dashed var(--line-strong); }

/* 依据行。每条边都要能说清「凭什么连」，所以这块是密排的小字而不是折叠面板：
   折起来的依据等于没有依据。 */
.rel-why { margin: 0; padding: 0; list-style: none; }
.rel-why li { padding: 3px 0; font-size: var(--fs-sm); color: var(--ink); }
.rel-why-caveat { display: block; font-size: var(--fs-xs); color: var(--faint);
                  margin-top: 1px; }
.rel-mask { font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); }

.rel-exposure { border: 1px solid var(--line-soft); border-radius: var(--r);
                padding: 12px 14px; background: var(--card); }
.rel-exposure + .rel-exposure { margin-top: 10px; }
.rel-exposure-top { display: flex; flex-wrap: wrap; gap: 10px;
                    align-items: baseline; justify-content: space-between; }
.rel-exposure-sum { font-size: var(--fs-xl); font-weight: 600; color: var(--ink);
                    font-variant-numeric: tabular-nums; }
.rel-exposure-note { font-size: var(--fs-xs); color: var(--muted); margin-top: 6px; }
.rel-exposure-members { font-size: var(--fs-sm); color: var(--muted); margin-top: 6px; }
/* 含弱信号时的显著标注。左边框而不是整块底色：整块底色会把它读成一条告警，
   它不是告警，是「这个数字不能当结论用」。 */
.rel-exposure-weak { border-left: 3px solid var(--warn); }
.rel-exposure-weak .rel-exposure-note { color: var(--warn); }
/* <<< BLOCK:W5-relations */

/* >>> BLOCK:X1-interview
   面签留痕画面墙。两处共用：内部端的面签复核页（assets/pages/interview.js）
   与面签页自己的报告段（web/interview/）。放这里而不是各写一份，
   是因为两边显示的是同一批图，尺寸一旦不一致，复核时对不上「同一张图」。 */
.iv-frames {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px;
}
.iv-frame {
  border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden; background: var(--card-2);
}
.iv-frame img { display: block; width: 100%; height: auto; }
.iv-frame-cap { font-size: var(--fs-xs); color: var(--muted); padding: 6px 8px; }
/* <<< BLOCK:X1-interview */

/* >>> BLOCK:T1-partial-read
   识别面板里的「送检范围」说明（assets/pages/materials.js）。归属：T1。
   刻意不给左边框、不上语义色 —— 它说的是「这几页机器没看过」，
   跟同一屏里的红色预警不是一类事，长成告警会把真的告警拉平。 */
.g2-ext-scope {
  margin-top: 6px;
  font-size: var(--fs-xs); line-height: 1.7; color: var(--muted);
}
/* <<< BLOCK:T1-partial-read */

/* >>> BLOCK:X3-satellite
   卫星图现场查看弹层（assets/geo.js）与台账里那枚现场判定小标记
   （assets/pages/projects.js）。归属：X3。

   两个刻意的克制：
   1. 判定选项不上语义色。「空地」不是红灯、「已建成」也不是绿灯 —— 卫星影像是
      历史影像，五个选项谁都不能单独下结论，染成红绿就是在替看图的人下判断。
      选中态只用主色描边，与全站「选中行」一致。
   2. 免责声明用中性底而不是 warn 底。它是一句一直成立的口径说明，不是告警；
      每开一次弹层就闪一条橙色，真的告警会被拉平。 */
.sv-body { text-align: left; }        /* .modal-body 默认居中，那是给图片预览用的 */

.sv-disclaimer {
  font-size: var(--fs-xs); line-height: 1.7;
  color: var(--muted); background: var(--chip-bg);
  border-radius: var(--r); padding: 8px 12px; margin-bottom: 12px;
}

.sv-stage { margin-bottom: 8px; }
.sv-map {
  width: 100%; height: 46vh; min-height: 300px;
  border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
  background: var(--card-2);
}

.sv-locate { font-size: var(--fs-xs); line-height: 1.7; margin-bottom: 14px; }
.sv-locate-warn { color: var(--warn); }

.sv-fallback {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--card-2); padding: 16px;
}
.sv-fallback-guide {
  font-size: var(--fs-xs); line-height: 1.8; color: var(--muted); margin-top: 6px;
}
.sv-fallback-acts { margin-top: 12px; }

.sv-judge {
  border: 1px solid var(--line-soft); border-radius: var(--r);
  background: var(--card-2); padding: 14px; margin-bottom: 16px;
}
.sv-judge-head {
  font-size: var(--fs-sm); font-weight: 500; margin-bottom: 10px;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline;
}
.sv-judge-head .muted { font-weight: 400; font-size: var(--fs-xs); }

.sv-opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 8px; }
.sv-opt {
  text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--card); padding: 9px 11px;
  transition: border-color .15s ease, background .15s ease;
}
.sv-opt:hover { border-color: var(--line-strong); }
.sv-opt.on { border-color: var(--accent); background: var(--accent-soft); }
.sv-opt-main { display: block; font-size: var(--fs-sm); font-weight: 500; color: var(--ink); }
.sv-opt.on .sv-opt-main { color: var(--accent-ink); }
.sv-opt-sub {
  display: block; font-size: var(--fs-xs); line-height: 1.6; color: var(--muted); margin-top: 2px;
}

/* 选中项的「这一条说明不了什么」。左边框而不是整块底色：它是限定语，不是告警。 */
.sv-limit {
  margin-top: 10px; padding: 8px 12px;
  border-left: 3px solid var(--line-strong); background: var(--card);
  font-size: var(--fs-xs); line-height: 1.7; color: var(--muted);
}
.sv-limit-k { color: var(--ink); font-weight: 500; }

textarea.sv-note { width: 100%; margin-top: 10px; resize: vertical; }
.sv-judge-acts { margin-top: 10px; align-items: center; }

.sv-history-head {
  font-size: var(--fs-sm); font-weight: 500; margin-bottom: 8px;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline;
}
.sv-history-head .muted { font-weight: 400; font-size: var(--fs-xs); }
.sv-hist-row { padding: 8px 0; border-top: 1px solid var(--line-soft); }
.sv-hist-main { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.sv-hist-note { font-size: var(--fs-sm); color: var(--ink); }

/* 台账行里的现场判定标记。中性 chip + 一枚地球小点，不抢自动核验那一格的注意力。 */
.sv-mark { display: inline-flex; align-items: center; gap: 4px; }
/* <<< BLOCK:X3-satellite */

/* >>> BLOCK:Y0-credit-shell
   v6 页签壳（assets/tabs.js）与客户档案页头。页签条样式全站共用：各模块的页签内容
   自己起前缀写样式，不要改这里。 */
.xt-bar {
  display: flex; flex-wrap: wrap; gap: 2px;
  border-bottom: 1px solid var(--line); margin-bottom: 16px;
}
.xt-tab {
  padding: 9px 14px; border: none; background: transparent; cursor: pointer;
  color: var(--muted); font-size: var(--fs-sm);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color .15s ease, border-color .15s ease;
}
.xt-tab:hover { color: var(--ink); }
.xt-tab.active { color: var(--accent-ink); border-bottom-color: var(--accent); font-weight: 600; }
.xt-body { min-height: 120px; }

.cu-head h2 { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.cu-back { font-size: var(--fs-sm); margin-bottom: 6px; }
.cu-back a { color: var(--muted); text-decoration: none; }
.cu-back a:hover { color: var(--accent-ink); }
.cu-metas { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.cu-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px; margin-top: 14px;
}
/* <<< BLOCK:Y0-credit-shell */

/* >>> BLOCK:Y8-bizdata
   经营数据：客户档案的商机 / 应收页签（assets/pages/cust_biz.js）与「经营数据」页（datasets.js）。
   类名一律 y8- 前缀；颜色只用令牌。图表是手写 SVG，线、柱、点的颜色都在这里定。 */
.y8-note { margin: 0 0 12px; }
.y8-stats { margin-bottom: 16px; }
.y8-toolbar { border-bottom: 1px solid var(--line-soft); }
.y8-pager { padding: 10px 16px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.y8-dim td { color: var(--faint); }
.y8-nw { white-space: nowrap; }
.y8-red { color: var(--red); }
.y8-ok { color: var(--ok); padding: 6px 0; }
.y8-alert { margin-bottom: 12px; }
.y8-two { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 16px; align-items: start; }
@media (max-width: 1080px) { .y8-two { grid-template-columns: minmax(0, 1fr); gap: 0; } }

.y8-chart { width: 100%; height: auto; display: block; }
.y8-grid { stroke: var(--line-soft); stroke-width: 1; }
.y8-axis { fill: var(--faint); font-size: 11px; font-variant-numeric: tabular-nums; }
.y8-bar { fill: var(--accent-bar); }
.y8-line-bal { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.y8-line-ov { fill: none; stroke: var(--red-solid); stroke-width: 1.8; stroke-dasharray: 5 4; stroke-linejoin: round; }
.y8-dot-bal { fill: var(--card); stroke: var(--accent); stroke-width: 1.6; }
.y8-dot-ov { fill: var(--card); stroke: var(--red-solid); stroke-width: 1.6; }
.y8-hit { fill: transparent; }
.y8-hit:hover { fill: var(--accent-soft); fill-opacity: .45; }
.y8-legend { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 8px; }
.y8-legend span { display: inline-flex; align-items: center; gap: 6px; }
.y8-lg { display: inline-block; width: 18px; height: 0; border-top: 2px solid var(--accent); }
.y8-lg-ov { border-top: 2px dashed var(--red-solid); }
.y8-lg-bar { width: 10px; height: 10px; border-top: none; background: var(--accent-bar); border-radius: 2px; }

.y8-aging { display: flex; flex-direction: column; gap: 12px; }
.y8-aging-row { display: grid; grid-template-columns: 84px 1fr 92px 52px; align-items: center; gap: 10px; }
.y8-aging-name { font-size: var(--fs-sm); color: var(--muted); }
.y8-aging-track { height: 12px; background: var(--card-2); border-radius: var(--r-sm); overflow: hidden; }
.y8-aging-fill { height: 100%; border-radius: var(--r-sm); transition: width .3s ease; }
.y8-aging-1 { background: var(--accent-bar); }
.y8-aging-2 { background: var(--warn-solid); opacity: .55; }
.y8-aging-3 { background: var(--warn-solid); }
.y8-aging-4 { background: var(--red-solid); }
.y8-aging-5 { background: var(--deny-solid); }
.y8-aging-n { font-size: var(--fs-sm); font-variant-numeric: tabular-nums; text-align: right; }
.y8-aging-p { text-align: right; font-variant-numeric: tabular-nums; }

.y8-ops { white-space: nowrap; text-align: right; }
.y8-pills { display: flex; flex-wrap: wrap; gap: 6px; padding: 12px 16px; border-bottom: 1px solid var(--line-soft); }
.y8-pill {
  padding: 4px 12px; border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--card);
  color: var(--muted); font-size: var(--fs-sm); cursor: pointer; transition: color .15s ease, border-color .15s ease;
}
.y8-pill:hover { color: var(--ink); }
.y8-pill.active { color: var(--accent-ink); border-color: var(--accent-line); background: var(--accent-soft); }
.y8-conds { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 12px 16px; border-bottom: 1px solid var(--line-soft); }
.y8-reason { max-width: 420px; }
.y8-fold { border-bottom: 1px solid var(--line-soft); }
.y8-fold:last-child { border-bottom: none; }
.y8-fold-head {
  width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 11px 16px; border: none; background: transparent; color: var(--ink); font-size: var(--fs); cursor: pointer; text-align: left;
}
.y8-fold-head:hover { background: var(--card-2); }
.y8-fold .input.y8-alias { width: 100%; max-width: none; }
.input.y8-short { width: 96px; min-width: 0; flex: 0 0 auto; }
.y8-modal { max-width: 820px; }
.modal-body.y8-modal-body { text-align: left; background: var(--card); }
.y8-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 14px; }
@media (max-width: 640px) { .y8-form { grid-template-columns: minmax(0, 1fr); } }
.y8-issues { max-height: 180px; overflow: auto; margin-top: 10px; padding: 8px 10px; border: 1px solid var(--line-soft); border-radius: var(--r); display: flex; flex-direction: column; gap: 4px; }
.y8-condlist { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.y8-cond { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: var(--fs); }
/* <<< BLOCK:Y8-bizdata */
/* >>> BLOCK:Y1-extdata
   风险预查询（pq-）与客户档案的工商司法 / 建筑资质与业绩页签（xd-）。归属：Y1。 */
.pq-form { display: flex; gap: 8px; align-items: center; }
.pq-form .input { flex: 1 1 auto; min-width: 0; }
.pq-gap { margin-top: 10px; }
.pq-modal-body { text-align: left; }
.pq-modal-body .card { margin-top: 12px; }
.pq-result { margin-top: 16px; }
.pq-result:empty { margin-top: 0; }
.pq-history { margin-top: 16px; }
.pq-source {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
  margin: 12px 0; font-size: var(--fs-sm); color: var(--muted);
}
.pq-sep { width: 1px; height: 12px; background: var(--line-strong); display: inline-block; }
.pq-co-name { font-size: var(--fs-lg); font-weight: 600; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pq-scope { margin-top: 14px; }
.pq-scope .small { margin-top: 2px; color: var(--ink); line-height: 1.7; }
.pq-verdict { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pq-verdict-text { font-size: var(--fs); }
.pq-hits { margin-top: 12px; }
.pq-hit { padding: 10px 0; border-top: 1px solid var(--line-soft); }
.pq-hit-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pq-ev { margin: 6px 0 0 18px; padding: 0; font-size: var(--fs-sm); color: var(--muted); line-height: 1.7; }
.pq-sub { margin-top: 16px; font-size: var(--fs-sm); font-weight: 600; }
.pq-miss { padding: 8px 0; }
.pq-foot { margin-top: 12px; }
.pq-examples { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.pq-pager { padding: 10px 16px; border-top: 1px solid var(--line-soft); }

.xd-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px;
  margin-bottom: 12px;
}
.xd-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; font-size: var(--fs-sm); color: var(--muted); }
.xd-meta strong { color: var(--ink); font-weight: 600; }
.xd-stale { color: var(--warn); }
.xd-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.xd-history { width: auto; min-width: 220px; padding-top: 4px; padding-bottom: 4px; font-size: var(--fs-sm); }
.xd-progress { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-sm); color: var(--accent-ink); }
.xd-note { margin-bottom: 12px; }
.xd-filter { width: 220px; max-width: 46vw; }
.xd-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.xd-tab {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--card); color: var(--muted); font-size: var(--fs-sm); cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.xd-tab:hover { color: var(--ink); border-color: var(--line-strong); }
.xd-tab.active { color: var(--accent-ink); border-color: var(--accent-line); background: var(--accent-soft); font-weight: 600; }
.xd-tab-n { font-size: var(--fs-xs); font-weight: 400; color: var(--faint); }
.xd-group-label { margin: 14px 0 6px; font-size: var(--fs-xs); color: var(--faint); }
.xd-sec { border: 1px solid var(--line-soft); border-radius: var(--r); background: var(--card); }
.xd-sec + .xd-sec { margin-top: 6px; }
.xd-sec-head {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 9px 12px; border: none; background: transparent; cursor: pointer;
  font-size: var(--fs); color: var(--ink); text-align: left;
}
.xd-sec-head:hover { background: var(--card-2); }
.xd-caret {
  width: 6px; height: 6px; flex: 0 0 6px;
  border-right: 1.5px solid var(--faint); border-bottom: 1.5px solid var(--faint);
  transform: rotate(-45deg); transition: transform .15s ease;
}
.xd-sec.open .xd-caret { transform: rotate(45deg); }
.xd-sec-title { font-weight: 600; }
.xd-sec-off .xd-sec-title { font-weight: 400; color: var(--muted); }
.xd-sec-count { font-size: var(--fs-sm); color: var(--faint); }
.xd-sec-count.has { color: var(--accent-ink); }
.xd-sec-body { display: none; padding: 4px 12px 12px; border-top: 1px solid var(--line-soft); }
.xd-sec.open .xd-sec-body { display: block; }
.xd-sec-body .dl { margin-top: 10px; }
.xd-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0; }
.xd-tools .input { width: 220px; max-width: 60vw; }
.xd-tbl td { vertical-align: top; }
.xd-cell { max-width: 280px; max-height: 4.8em; overflow: hidden; line-height: 1.6; word-break: break-word; }
.xd-none { margin-top: 8px; }
.xd-src { margin-top: 10px; }
.xd-kv-title { margin-top: 14px; font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.xd-modal-body { text-align: left; }
.xd-modal-body .dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 720px) {
  .pq-form { flex-wrap: wrap; }
  .xd-modal-body .dl { grid-template-columns: minmax(0, 1fr); }
}
/* <<< BLOCK:Y1-extdata */

/* >>> BLOCK:Y3-credit
   征信评级：客户档案「征信与保证人」页签（y3-）与规则库「征信规则」页签（y3r-）。
   颜色只用头部的设计令牌。 */
.y3-top { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 10px; }
.y3-meta { margin-bottom: 8px; }
.y3-list { margin: 6px 0 0; padding-left: 18px; }
.y3-list li { margin: 2px 0; }
.y3-pad { padding: 10px 2px; }
.y3-left { text-align: left; }
.y3-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.y3-ops { white-space: nowrap; text-align: right; }
.y3-off td { color: var(--faint); }
.y3-disp {
  margin: 10px 0 12px; padding: 10px 12px; border: 1px solid var(--line-soft);
  border-radius: var(--r); background: var(--card-2, var(--ground));
}
.y3-fold { margin-top: 12px; border-top: 1px solid var(--line-soft); padding-top: 10px; }
.y3-fold > summary { cursor: pointer; color: var(--muted); font-size: var(--fs-sm); margin-bottom: 8px; }
.y3-fold > summary:hover { color: var(--accent-ink); }
.y3-modal { max-width: 860px; }
.y3-modal-body { text-align: left; }
.y3-sec { margin: 14px 0 8px; font-size: var(--fs-sm); color: var(--muted); font-weight: 600; }
.y3-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px 14px; }
.y3-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.y3-f > span { font-size: var(--fs-xs); color: var(--muted); }
.y3-f > i { font-style: normal; font-size: var(--fs-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.y3-f .input, .y3-f .select { width: 100%; box-sizing: border-box; }
.y3-wide { grid-column: 1 / -1; margin-top: 10px; }

.y3r-kinds { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 16px 4px; }
.y3r-dim { padding: 14px 16px 6px; font-weight: 600; }
.y3r-cond { margin-top: 4px; color: var(--muted); line-height: 2; }
.y3r-num { width: 76px; min-width: 0; text-align: right; display: inline-block; }
.y3r-bad { border-color: var(--red-solid); }
.y3r-c { text-align: center; }
.y3r-inline { display: flex; align-items: center; gap: 6px; }
.y3r-inline .y3r-num { width: 96px; }
.y3r-disp { display: grid; gap: 10px; }
.y3r-disp .y3-wide { margin-top: 0; }
.y3r-fix { display: flex; gap: 10px; align-items: flex-start; margin-top: 14px; cursor: pointer; }
.y3r-fix > span { display: flex; flex-direction: column; gap: 2px; }
.y3r-save { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.y3r-save .input { flex: 1 1 280px; }
/* <<< BLOCK:Y3-credit */

/* >>> BLOCK:Y5-approval
   授信工作台（wb-）、审批权限表页签（doa-）、客户档案审批记录（ca-）、审核页 v6 块（rv-y5-）。
   审批链与审批流转的样式三处共用（NPR.approvalUI）。颜色只用令牌。 */
.wb-modal-body { text-align: left; background: var(--card); }
.wb-gap { margin-top: 12px; }
.wb-gap-b { margin-bottom: 12px; }
.wb-note { margin-top: 6px; }
.wb-note-input { min-height: 72px; resize: vertical; font-family: var(--font); line-height: 1.7; }
.wb-grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; }
.wb-block { margin-top: 16px; }
.wb-block-title { font-size: var(--fs-xs); color: var(--muted); margin-bottom: 8px; }
.wb-modal-body .field + .field, .wb-modal-body .field + .doa-checks,
.wb-modal-body .wb-grid-2 + .field, .wb-modal-body .field + .wb-grid-2 { margin-top: 12px; }
.wb-modal-body .wb-grid-2 > .field { margin-top: 0; }
.wb-reason { white-space: pre-wrap; line-height: 1.7; }
.wb-foot-btns { display: inline-flex; gap: 8px; flex-wrap: wrap; }
.wb-foot-note { margin-top: 10px; }
.wb-acts { text-align: right; white-space: nowrap; }
.wb-miss { color: var(--warn); }

/* 工作台页头与分区页签 */
.wb-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.wb-tabs .xt-tab { display: inline-flex; align-items: center; gap: 6px; }
.wb-count {
  min-width: 20px; padding: 0 6px; border-radius: var(--r-pill);
  background: var(--chip-bg); color: var(--chip-ink);
  font-size: var(--fs-xs); line-height: 18px; text-align: center; font-variant-numeric: tabular-nums;
}
.xt-tab.active .wb-count { background: var(--accent-soft); color: var(--accent-ink); }
.wb-mine { font-size: var(--fs-xs); color: var(--accent-ink); font-weight: 600; }
.wb-mine-row { font-size: var(--fs-xs); color: var(--accent-ink); font-weight: 600; margin-top: 2px; }
.tbl tbody tr.wb-row-mine td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.wb-block-tag { font-size: var(--fs-xs); color: var(--deny); font-weight: 600; }

/* 审批链：岗位（人）一级一级排开 */
.wb-chain { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.wb-chain-item {
  display: inline-flex; align-items: center; gap: 8px; padding: 6px 10px;
  border: 1px solid var(--line-soft); border-radius: var(--r); background: var(--card-2);
  font-size: var(--fs-sm);
}
.wb-chain-item.is-miss { border-color: var(--warn-solid); background: var(--warn-bg); }
.wb-chain-no {
  width: 18px; height: 18px; flex: none; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-ink);
  font-size: var(--fs-xs); line-height: 18px; text-align: center; font-variant-numeric: tabular-nums;
}
.wb-chain-pos { font-weight: 600; }
.wb-chain-who { color: var(--muted); }
.wb-plan-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }

/* 审批流转时间线 */
.wb-steps { list-style: none; margin: 0; padding: 0; }
.wb-step { display: flex; gap: 12px; padding: 0 0 14px; position: relative; }
.wb-step:last-child { padding-bottom: 0; }
.wb-step::before {
  content: ""; position: absolute; left: 10px; top: 22px; bottom: 0; width: 1px; background: var(--line);
}
.wb-step:last-child::before { display: none; }
.wb-step-no {
  width: 21px; height: 21px; flex: none; border-radius: 50%; z-index: 1;
  background: var(--chip-bg); color: var(--chip-ink);
  font-size: var(--fs-xs); line-height: 21px; text-align: center; font-variant-numeric: tabular-nums;
}
.wb-step.st-approved .wb-step-no { background: var(--ok-bg); color: var(--ok); }
.wb-step.st-rejected .wb-step-no { background: var(--red-bg); color: var(--red); }
.wb-step.st-returned .wb-step-no { background: var(--warn-bg); color: var(--warn); }
.wb-step.is-current .wb-step-no { background: var(--accent); color: var(--accent-on); }
.wb-step-main { min-width: 0; flex: 1 1 auto; }
.wb-step-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: var(--fs-sm); }
.wb-step-note {
  margin-top: 6px; padding: 8px 10px; border-radius: var(--r);
  background: var(--card-2); font-size: var(--fs-sm); line-height: 1.7; white-space: pre-wrap;
}
.wb-ap-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.wb-risk { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-sm); }

/* 新建客户向导 */
.wb-wiz-steps { list-style: none; margin: 0 0 16px; padding: 0; display: flex; gap: 6px; flex-wrap: wrap; }
.wb-wiz-steps li {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px 4px 4px;
  border-radius: var(--r-pill); background: var(--chip-bg); color: var(--chip-ink); font-size: var(--fs-sm);
}
.wb-wiz-steps li i {
  width: 20px; height: 20px; border-radius: 50%; font-style: normal;
  background: var(--card); color: var(--muted); font-size: var(--fs-xs); line-height: 20px; text-align: center;
}
.wb-wiz-steps li.is-current { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; }
.wb-wiz-steps li.is-current i { background: var(--accent); color: var(--accent-on); }
.wb-wiz-steps li.is-done i { background: var(--ok-bg); color: var(--ok); }
.wb-wiz-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.wb-wiz-who { margin-bottom: 12px; }
.wb-found { margin-top: 12px; border: 1px solid var(--line-soft); border-radius: var(--r); }
.wb-found-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 12px; border-bottom: 1px solid var(--line-soft);
}
.wb-found-row:last-child { border-bottom: none; }
.wb-pwd { margin-top: 10px; padding: 8px 10px; border-radius: var(--r); background: var(--card-2); }
.wb-url { word-break: break-all; }

/* 审批权限表页签 */
.doa-pad { padding: 10px 16px; }
.doa-note { padding-top: 0; }
.doa-segs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.doa-seg {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--card); color: var(--muted);
  font-size: var(--fs-sm); transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.doa-seg:hover { color: var(--ink); border-color: var(--line-strong); }
.doa-seg.active { color: var(--accent-ink); border-color: var(--accent); background: var(--accent-soft); font-weight: 600; }
.doa-live { font-size: var(--fs-xs); font-weight: 400; padding: 0 6px; border-radius: var(--r-pill); background: var(--ok-bg); color: var(--ok); }
.doa-chain { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px; font-size: var(--fs-sm); }
.doa-pos { padding: 2px 8px; border-radius: var(--r-sm); background: var(--chip-bg); color: var(--ink); white-space: nowrap; }
.doa-arrow { font-style: normal; color: var(--faint); }
.doa-ex { border-top: 1px solid var(--line-soft); }
.doa-ex:first-child { border-top: none; }
.doa-ex-head { padding: 12px 16px 4px; }
.doa-pos-note { max-width: 360px; line-height: 1.6; }
.doa-reg {
  display: inline-flex; align-items: center; gap: 4px; margin: 0 6px 4px 0; padding: 2px 8px;
  border-radius: var(--r-sm); background: var(--chip-bg); font-size: var(--fs-sm); white-space: nowrap;
}
.doa-x { border: none; background: transparent; color: var(--faint); cursor: pointer; padding: 0 2px; font-size: var(--fs); line-height: 1; }
.doa-x:hover { color: var(--red); }
.doa-preview .select, .doa-preview .input { width: auto; }
.doa-checks { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: var(--fs-sm); }
.doa-checks label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.doa-chain-edit { list-style: none; margin: 0 0 10px; padding: 0; border: 1px solid var(--line-soft); border-radius: var(--r); }
.doa-chain-edit li {
  display: flex; align-items: center; gap: 8px; padding: 6px 10px;
  border-bottom: 1px solid var(--line-soft); font-size: var(--fs-sm);
}
.doa-chain-edit li:last-child { border-bottom: none; }

/* 客户档案审批记录 / 审核页 v6 块 */
.ca-stats { margin: 0 0 16px; }
.ca-head-right { display: inline-flex; align-items: center; gap: 8px; }
.rv-y5-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.rv-y5-ap { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 6px 0; font-size: var(--fs-sm); }

@media (max-width: 720px) {
  .wb-grid-2 { grid-template-columns: minmax(0, 1fr); }
  .wb-acts { text-align: left; white-space: normal; }
}
/* <<< BLOCK:Y5-approval */

/* >>> BLOCK:Y7-feishu  登录页的飞书登录入口 + 「飞书接入」页。归属 Y7，类名前缀 fs-。
   卡片预览是把发给飞书的那张卡片照样画一遍：标题色条只表达卡片类型，
   用的是语义色的浅底 + 深字那一套（纪律第 4 条），不另起颜色。 */

/* ── 登录页：飞书登录 ── */
.fs-login { margin-top: 16px; display: flex; flex-direction: column; gap: 10px; }
.fs-login-or {
  display: flex; align-items: center; gap: 10px;
  color: var(--faint); font-size: var(--fs-xs);
}
.fs-login-or::before, .fs-login-or::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--line);
}
.fs-login-note { font-size: var(--fs-xs); color: var(--muted); line-height: 1.7; text-align: center; }
.fs-login-wait { margin-top: 16px; }
.fs-login .btn { text-align: center; text-decoration: none; }

/* ── 飞书接入页 ── */
.fs-stack { display: flex; flex-direction: column; gap: 16px; }
.fs-stack > .card { margin: 0; }
.fs-mono { font-family: var(--mono); font-size: var(--fs-sm); word-break: break-all; }
.fs-gap { margin-top: 12px; }
.fs-pad { padding: 10px 16px; }
.fs-sub {
  margin: 18px 0 8px; font-size: var(--fs-sm); font-weight: 600; color: var(--ink);
}

/* ── 卡片预览弹层 ── */
.fs-modal { max-width: 640px; }
.fs-preview { text-align: left; }
.fs-preview .dl, .fs-dl2 .dl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.fs-card {
  max-width: 420px; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm); overflow: hidden;
}
.fs-card-head { padding: 10px 14px; font-weight: 600; font-size: var(--fs); line-height: 1.5; }
.fs-t-blue   { background: var(--accent-soft); color: var(--accent-ink); }
.fs-t-orange { background: var(--warn-bg); color: var(--warn); }
.fs-t-red    { background: var(--red-bg); color: var(--red); }
.fs-t-green  { background: var(--ok-bg); color: var(--ok); }
.fs-t-grey   { background: var(--chip-bg); color: var(--chip-ink); }
.fs-card-body { padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.fs-card-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 16px; }
.fs-card-field, .fs-card-text { font-size: var(--fs-sm); line-height: 1.7; word-break: break-word; }
.fs-card-field strong { display: inline-block; font-weight: 400; color: var(--muted); font-size: var(--fs-xs); }
.fs-card-hr { height: 1px; background: var(--line-soft); }
.fs-card-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.fs-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 12px; border-radius: var(--r); font-size: var(--fs-sm);
  border: 1px solid var(--line-strong); background: var(--card); color: var(--ink);
}
.fs-btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-on); }
.fs-btn-danger { border-color: var(--red); color: var(--red); }
.fs-btn-link { font-style: normal; font-size: var(--fs-xs); opacity: .75; }
.fs-card-note { font-size: var(--fs-xs); color: var(--faint); }
.fs-raw { margin-top: 16px; font-size: var(--fs-sm); color: var(--muted); }
.fs-raw summary { cursor: pointer; }
.fs-raw pre {
  margin-top: 8px; padding: 10px 12px; max-height: 260px; overflow: auto;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  font-family: var(--mono); font-size: var(--fs-xs); line-height: 1.6;
  white-space: pre-wrap; word-break: break-all; color: var(--ink);
}
@media (max-width: 640px) {
  .fs-preview .dl, .fs-dl2 .dl, .fs-card-fields { grid-template-columns: 1fr; }
}
/* <<< BLOCK:Y7-feishu */

/* >>> BLOCK:Y6-monitor
   风险监控页（mo-）、客户档案「预警与复评」页签（cm-）、批量任务页（bt-）。
   图表是手写 SVG：颜色一律走这里的类（令牌），脚本里不写色值。
   等级配色与全站一致：极高 / 高 / 中 用语义色的亮色版（它们是色块，不是要读的字），
   低用主色的浅一档，未见风险用绿，判不了与未评估退到中性灰。 */
.mo-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px; margin-bottom: 12px;
}
.mo-stats .stat-value { font-size: var(--fs-2xl); }
.mo-notice { margin-bottom: 12px; }
.mo-charts {
  display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  gap: 12px; margin-bottom: 12px;
}
.mo-charts > .card { margin: 0; }
.mo-dist { display: block; width: 100%; height: 26px; }
.mo-seg-critical { fill: var(--deny-solid); background: var(--deny-solid); }
.mo-seg-high     { fill: var(--red-solid);  background: var(--red-solid); }
.mo-seg-medium   { fill: var(--warn-solid); background: var(--warn-solid); }
.mo-seg-low      { fill: var(--accent-bar); background: var(--accent-bar); }
.mo-seg-clear    { fill: var(--ok-solid);   background: var(--ok-solid); }
.mo-seg-unknown  { fill: var(--line-strong); background: var(--line-strong); }
.mo-seg-none     { fill: var(--line); background: var(--line); }
.mo-legend { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 12px; font-size: var(--fs-sm); color: var(--muted); }
.mo-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.mo-legend-item b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.mo-legend-item.is-zero { color: var(--faint); }
.mo-legend-item.is-zero b { color: var(--faint); font-weight: 400; }
.mo-dot { width: 10px; height: 10px; border-radius: 2px; flex: 0 0 10px; }
.mo-delta { display: block; width: 100%; max-width: 420px; height: auto; }
.mo-axis { fill: var(--muted); font-size: 12px; }
.mo-num { fill: var(--ink); font-size: 12px; font-variant-numeric: tabular-nums; }
.mo-track { fill: var(--card-2); }
.mo-bar-up   { fill: var(--red-solid); }
.mo-bar-down { fill: var(--ok-solid); }
.mo-bar-gap  { fill: var(--accent-bar); }
.mo-bar-none { fill: var(--line-strong); }
.mo-up   { color: var(--red); }
.mo-down { color: var(--ok); }
.mo-pager { padding: 10px 16px; }
.mo-ops { white-space: nowrap; }
.mo-foot { margin: 12px 2px 0; }
.mo-form { text-align: left; background: var(--card); display: flex; flex-direction: column; gap: 12px; }
.mo-form textarea.input { width: 100%; resize: vertical; font: inherit; }

.cm-ops { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.cm-note { margin-top: 12px; }
.cm-warn { color: var(--red); }
.cm-good { color: var(--ok); }
.cm-trend { display: block; width: 100%; max-width: 760px; height: auto; margin-bottom: 4px; }
.cm-grid { stroke: var(--line-soft); stroke-width: 1; }
.cm-axis { fill: var(--muted); font-size: 11px; }
.cm-line { fill: none; stroke: var(--line-strong); stroke-width: 1.5; }
.cm-score { fill: none; stroke: var(--accent); stroke-width: 1.2; stroke-dasharray: 3 3; }
.cm-sdot { fill: var(--accent); }
.cm-dot { stroke: var(--card); stroke-width: 1.5; }
.cm-dot-critical { fill: var(--deny-solid); }
.cm-dot-high     { fill: var(--red-solid); }
.cm-dot-medium   { fill: var(--warn-solid); }
.cm-dot-low      { fill: var(--accent-bar); }
.cm-dot-clear    { fill: var(--ok-solid); }
.cm-dot-gap      { fill: var(--line-strong); }
.cm-legend { display: flex; gap: 18px; margin-bottom: 14px; }
.cm-legend span { display: inline-flex; align-items: center; gap: 6px; }
.cm-key { display: inline-block; width: 18px; height: 0; border-top: 2px solid var(--line-strong); }
.cm-key-score { border-top: 2px dashed var(--accent); }
.cm-timeline { margin-top: 6px; }
.cm-entry-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.cm-time { font-variant-numeric: tabular-nums; font-weight: 600; }
.cm-changes { margin: 6px 0 0; padding-left: 18px; font-size: var(--fs-sm); }
.cm-changes li { margin: 2px 0; }

.bt-new { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 12px; margin-bottom: 12px; }
.bt-new > .card { margin: 0; }
.bt-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; }
.bt-form .select, .bt-form .input { width: 100%; }
.bt-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 12px; }
.bt-prog { height: 8px; background: var(--card-2); border: 1px solid var(--line-soft); border-radius: var(--r-pill); overflow: hidden; }
.bt-prog-fill { height: 100%; background: var(--accent-bar); border-radius: var(--r-pill); transition: width .4s ease; }
.bt-prog-fill.is-live { background: var(--accent); }
.bt-prog-cell { min-width: 150px; }
.bt-prog-wide { flex: 1 1 260px; max-width: 420px; }
.bt-headline { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; }
.bt-headline .bt-actions { margin-top: 0; }
.bt-sum { margin-top: 12px; font-size: var(--fs); }
.bt-note { margin-top: 12px; }
.bt-children { margin-top: 10px; }
.bt-invite { padding: 12px 16px; border-bottom: 1px solid var(--line-soft); }
.bt-invite .bt-note { margin: 0 0 4px; }
.bt-bad  { color: var(--red); }
.bt-good { color: var(--ok); }

@media (max-width: 900px) {
  .mo-charts, .bt-new { grid-template-columns: minmax(0, 1fr); }
}
/* <<< BLOCK:Y6-monitor */

/* >>> BLOCK:Y4-conclusion
   统一结论整屏（assets/conclusion_view.js）、客户档案「评估结论」页签、规则库「评分卡与额度」页签。
   全页只有顶上的结论条是「重」的，其余退到中性色。类名一律 y4- 前缀。 */
.y4-conclusion { display: flex; flex-direction: column; gap: 12px; }
.y4-conclusion > .card { margin: 0; }
.y4-row { margin-top: 10px; }
.y4-row:first-child { margin-top: 0; }

/* 结论条：全页唯一有色的地方。左边一道语义色，底是对应的浅底 */
.y4-verdict {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 10px 24px;
  padding: 16px 18px; border-radius: var(--r-lg);
  border: 1px solid var(--line-soft); border-left: 4px solid var(--line-strong);
  background: var(--card);
}
.y4-verdict-main { min-width: 0; flex: 1 1 420px; }
.y4-verdict-big { font-size: var(--fs-2xl); font-weight: 600; line-height: 1.3; }
.y4-verdict-line { margin-top: 4px; font-size: var(--fs); color: var(--ink); overflow-wrap: anywhere; }
.y4-verdict-meta { font-size: var(--fs-xs); color: var(--muted); display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.y4-tone-deny { border-left-color: var(--deny-solid); background: var(--deny-bg); }
.y4-tone-deny .y4-verdict-big { color: var(--deny); }
.y4-tone-red { border-left-color: var(--red-solid); background: var(--red-bg); }
.y4-tone-red .y4-verdict-big { color: var(--red); }
.y4-tone-warn { border-left-color: var(--warn-solid); background: var(--warn-bg); }
.y4-tone-warn .y4-verdict-big { color: var(--warn); }
.y4-tone-ok { border-left-color: var(--ok-solid); background: var(--ok-bg); }
.y4-tone-ok .y4-verdict-big { color: var(--ok); }
.y4-tone-muted .y4-verdict-big { color: var(--muted); }

/* 合成顺序：七步一排，窄屏自动折行 */
.y4-steps {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px;
}
.y4-step {
  padding: 10px 12px; border: 1px solid var(--line-soft); border-radius: var(--r);
  background: var(--card); min-width: 0;
}
.y4-step-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.y4-step-no {
  width: 18px; height: 18px; flex: 0 0 18px; border-radius: 50%;
  background: var(--chip-bg); color: var(--chip-ink);
  font-size: var(--fs-xs); display: inline-flex; align-items: center; justify-content: center;
  font-variant-numeric: tabular-nums;
}
.y4-step-name { font-size: var(--fs-sm); font-weight: 600; }
.y4-step-text { margin-top: 6px; font-size: var(--fs-xs); color: var(--muted); overflow-wrap: anywhere; }

.y4-gaps {
  padding: 10px 14px; border: 1px dashed var(--line-strong); border-radius: var(--r);
  background: var(--card-2); font-size: var(--fs-sm); color: var(--muted);
}
.y4-gaps-title { color: var(--ink); font-weight: 600; margin-bottom: 4px; }
.y4-gaps ul { margin: 0; padding-left: 18px; }
.y4-na { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sm); color: var(--muted); }

/* 可展开的一行：准入核查项、规则命中、征信主体、评分指标都用它 */
details.y4-fold > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 9px 16px; transition: background-color .12s ease;
}
details.y4-fold > summary::-webkit-details-marker { display: none; }
details.y4-fold > summary::before {
  content: ""; width: 6px; height: 6px; flex: 0 0 6px; margin-right: 2px;
  border-right: 1.5px solid var(--faint); border-bottom: 1.5px solid var(--faint);
  transform: rotate(-45deg); transition: transform .15s ease;
}
details.y4-fold[open] > summary::before { transform: rotate(45deg); }
details.y4-fold > summary:hover, details.y4-fold[open] > summary { background: var(--card-2); }
.y4-fold-body { padding: 8px 16px 12px 32px; display: flex; flex-direction: column; gap: 4px; }
.y4-check, .y4-dim { border-bottom: 1px solid var(--line-soft); }
.y4-check:last-child, .y4-dim:last-child { border-bottom: none; }
.y4-check-name { font-size: var(--fs-sm); font-weight: 600; min-width: 96px; }
.y4-check-ev { font-size: var(--fs-sm); color: var(--muted); flex: 1 1 240px; min-width: 0; overflow-wrap: anywhere; }
.card-body:not(.tight) > details.y4-fold > summary { padding-left: 0; padding-right: 0; }
.card-body:not(.tight) > details.y4-fold > .y4-fold-body { padding-left: 16px; padding-right: 0; }

/* 评分：左雷达右六项 */
.y4-score { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 8px 20px; align-items: start; }
.y4-score-side { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; }
.y4-radar { width: 300px; max-width: 100%; height: auto; }
.y4-radar-grid { fill: none; stroke: var(--line); stroke-width: 1; }
.y4-radar-axis { stroke: var(--line); stroke-width: 1; }
.y4-radar-shape { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; }
.y4-radar-dot { fill: var(--accent); stroke: var(--card); stroke-width: 2; }
.y4-radar-label { fill: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.y4-score-total { font-size: var(--fs-3xl); font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1.1; }
.y4-score-total span { font-size: var(--fs-sm); font-weight: 400; color: var(--muted); margin-left: 2px; }
.y4-dims { border: 1px solid var(--line-soft); border-radius: var(--r); overflow: hidden; }
.y4-dims details.y4-fold > summary { padding: 9px 12px; }
.y4-dim-name { font-size: var(--fs-sm); font-weight: 600; flex: 0 0 168px; }
.y4-dim-bar { flex: 1 1 120px; min-width: 80px; }
.y4-dim-bar .bar-track { display: block; }
.y4-dim-bar .bar-fill { display: block; }
.y4-dim-score { flex: 0 0 56px; text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }
.y4-dim-score i { font-style: normal; font-weight: 400; color: var(--faint); font-size: var(--fs-xs); }
.y4-dim-val { flex: 1 1 200px; min-width: 0; font-size: var(--fs-sm); color: var(--muted); }

.y4-score-grade { margin-top: 2px; }
.y4-checks { display: block; }
.y4-ext-slot { min-height: 24px; }      /* Y2 的 NPR.extResult 往这里画 */

/* 额度与账期 */
.y4-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 240px)); gap: 12px; }
.y4-calc-title { margin-top: 14px; font-size: var(--fs-sm); font-weight: 600; }
.y4-calc { margin: 6px 0 0; padding-left: 20px; font-size: var(--fs-sm); line-height: 1.8; }
.y4-notes { margin: 8px 0 0; padding-left: 18px; font-size: var(--fs-sm); line-height: 1.8; color: var(--muted); }

/* 审批路径 */
.y4-chain { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.y4-chain-node {
  display: inline-flex; flex-direction: column; gap: 2px; padding: 6px 12px;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--card-2);
}
.y4-chain-node b { font-size: var(--fs-sm); font-weight: 600; }
.y4-chain-node i { font-style: normal; font-size: var(--fs-xs); color: var(--muted); }
.y4-chain-arrow { color: var(--faint); }

/* 客户档案页签的工具条 */
.y4-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 12px; margin-bottom: 12px; }
.y4-inline { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); color: var(--muted); cursor: pointer; }

/* 规则库 · 评分卡与额度 */
.y4-seg { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 3px; border-radius: var(--r); background: var(--chip-bg); }
.y4-seg-btn {
  padding: 5px 12px; border: none; border-radius: var(--r-sm); background: transparent; cursor: pointer;
  color: var(--muted); font-size: var(--fs-sm); display: inline-flex; align-items: center; gap: 6px;
  transition: background-color .15s ease, color .15s ease;
}
.y4-seg-btn:hover { color: var(--ink); }
.y4-seg-btn.active { background: var(--card); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-sm); }
.y4-dirty { width: 6px; height: 6px; border-radius: 50%; background: var(--warn-solid); }
.y4-savebar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 12px 0; min-height: 30px; }
.y4-savebar .y4-note { flex: 1 1 260px; max-width: 460px; }
.y4-block { padding: 12px 0; border-bottom: 1px solid var(--line-soft); }
.y4-block:first-child { padding-top: 0; }
.y4-block:last-child { border-bottom: none; padding-bottom: 0; }
.y4-block-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px; }
.y4-num { width: 84px; min-width: 0; text-align: right; font-variant-numeric: tabular-nums; }
.y4-bins th, .y4-bins td { padding: 5px 6px; }
.y4-bins tbody th { text-align: left; font-weight: 400; color: var(--muted); font-size: var(--fs-sm); white-space: nowrap; }
.tbl.y4-narrow { max-width: 520px; }
.y4-form-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.y4-form-row:first-child { margin-top: 0; }
.y4-calc-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }

@media (max-width: 760px) {
  .y4-score { grid-template-columns: minmax(0, 1fr); }
  .y4-dim-name { flex-basis: 100%; }
}
/* <<< BLOCK:Y4-conclusion */

/* >>> BLOCK:Y2-ext-rules
   外部数据规则。两组类：
     xres-  判定结果展示组件（assets/ext_result.js），预查询 / 统一结论页 / 监控页共用；
     xr-    规则库「外部数据规则」页签（assets/pages/rulebook_ext.js）。
   只用头部令牌，不写字面色值。全页只有结果组件的结论条（.xres-verdict）可以有色，
   其余一律中性：层级靠留白、字重、细线。规则表是拿来扫的，行高压紧，不画大卡片。 */

/* ── 结果组件 ─────────────────────────────────────────────────────── */
.xres { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.xres-card {
  padding: 16px; background: var(--card);
  border: 1px solid var(--line-soft); border-radius: var(--r-xl); box-shadow: var(--shadow-sm);
}
.xres-title { font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }

/* 结论条：左边一句结论，右边说明、分布、口径 */
.xres-verdict {
  display: grid; grid-template-columns: 184px minmax(0, 1fr);
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-lg); overflow: hidden;
}
.xres-lead { padding: 14px 16px; background: var(--card-2); border-right: 1px solid var(--line); }
.xres-k { font-size: var(--fs-xs); color: var(--faint); }
.xres-v { margin-top: 2px; font-size: var(--fs-2xl); font-weight: 600; line-height: 1.3; color: var(--ink); }
.xres-sub { margin-top: 6px; font-size: var(--fs-sm); font-weight: 600; color: var(--muted); }
.xres-main { display: flex; flex-direction: column; gap: 8px; padding: 14px 16px; min-width: 0; }
.xres-note { font-size: var(--fs); color: var(--ink); }
.xres-count { font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.xres-meta { display: flex; flex-wrap: wrap; gap: 4px 20px; font-size: var(--fs-xs); color: var(--ink); }
.xres-meta-item { display: inline-flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.xres-meta-k { color: var(--faint); }
.xres-rule { padding-top: 8px; border-top: 1px solid var(--line-soft); font-size: var(--fs-xs); color: var(--faint); }

/* 结论的语气：极高 / 高 / 中各一档语义色，文字用深色版；低、未见风险、无法判定保持中性 */
.xres-verdict.tone-critical { border-color: var(--deny-solid); }
.xres-verdict.tone-critical .xres-lead { background: var(--deny-bg); border-right-color: var(--deny-bg); }
.xres-verdict.tone-critical .xres-v,
.xres-verdict.tone-critical .xres-sub { color: var(--deny); }
.xres-verdict.tone-high .xres-lead { background: var(--red-bg); border-right-color: var(--red-bg); }
.xres-verdict.tone-high .xres-v,
.xres-verdict.tone-high .xres-sub { color: var(--red); }
.xres-verdict.tone-medium .xres-lead { background: var(--warn-bg); border-right-color: var(--warn-bg); }
.xres-verdict.tone-medium .xres-v,
.xres-verdict.tone-medium .xres-sub { color: var(--warn); }
.xres-verdict.tone-critical .xres-k,
.xres-verdict.tone-high .xres-k,
.xres-verdict.tone-medium .xres-k { color: var(--muted); }

.xres-dist { display: flex; flex-wrap: wrap; gap: 4px 18px; font-size: var(--fs-sm); color: var(--muted); }
.xres-dist-item { display: inline-flex; align-items: center; gap: 5px; }
.xres-dist-item b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.xres-dot { width: 8px; height: 8px; flex: 0 0 8px; border-radius: 2px; background: var(--line-strong); }
.xres-dot.lv-critical { background: var(--deny-solid); }
.xres-dot.lv-high { background: var(--red-solid); }
.xres-dot.lv-medium { background: var(--warn-solid); }

.xres-hint { margin: 0; }
.xres-none {
  padding: 14px 16px; border: 1px dashed var(--line-strong); border-radius: var(--r);
  font-size: var(--fs-sm); color: var(--muted);
}
.xres-foot { font-size: var(--fs-xs); color: var(--faint); }

/* 命中表 */
.xres-tbl { min-width: 620px; }
.xres-tbl td { vertical-align: top; }
.xres-c-lv, .xres-c-no { width: 1%; white-space: nowrap; }
.xres-c-title { min-width: 180px; max-width: 340px; }
.xres-item { font-weight: 600; }
.xres-no { margin-right: 6px; font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); }
.xres-c-no .xres-no { margin-right: 0; color: var(--ink); }
.xres-seg { font-size: var(--fs-xs); color: var(--faint); }
.xres-base { margin-top: 3px; font-size: var(--fs-xs); color: var(--faint); }
.xres-ev { display: flex; flex-direction: column; gap: 4px; }
.xres-ev-line { line-height: 1.6; overflow-wrap: anywhere; }
.xres-tag {
  display: inline-block; margin-left: 6px; padding: 0 7px;
  border-radius: var(--r-pill); background: var(--chip-bg); color: var(--chip-ink);
  font-size: var(--fs-xs); line-height: 1.7; white-space: nowrap;
}
.xres-rel { margin-top: 4px; font-size: var(--fs-xs); color: var(--muted); }
.xres-rel summary, .xres-fold summary { cursor: pointer; }
.xres-rel ul { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }

/* 折叠区：无法判定 / 不适用 */
.xres-fold { padding-top: 10px; border-top: 1px solid var(--line-soft); font-size: var(--fs-sm); }
.xres-fold summary { color: var(--muted); }
.xres-fold[open] summary { margin-bottom: 8px; }
.xres-list { display: flex; flex-direction: column; gap: 4px; }
.xres-list li {
  display: grid; grid-template-columns: 44px minmax(120px, 280px) minmax(0, 1fr);
  gap: 2px 10px; align-items: baseline;
}
.xres-list-tight { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr)); gap: 4px 20px; }
.xres-list-tight li { grid-template-columns: 44px minmax(0, 1fr); }
.xres-li-why { color: var(--muted); overflow-wrap: anywhere; }
.xres-na-head { margin: 8px 0 4px; font-size: var(--fs-xs); color: var(--faint); }
.xres-na-head:first-of-type { margin-top: 0; }

@media (max-width: 720px) {
  .xres-verdict { grid-template-columns: minmax(0, 1fr); }
  .xres-lead { border-right: none; border-bottom: 1px solid var(--line-soft); }
  .xres-list li { grid-template-columns: 44px minmax(0, 1fr); }
  .xres-li-why { grid-column: 2; }
}

/* ── 规则库页签 ───────────────────────────────────────────────────── */
.xr-root { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.xr-body > * + * { margin-top: 10px; }

/* 版本条 */
.xr-ver {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 10px 16px; flex-wrap: wrap;
  padding: 12px 16px; background: var(--card);
  border: 1px solid var(--line-soft); border-radius: var(--r-xl); box-shadow: var(--shadow-sm);
}
.xr-ver-main { flex: 1 1 320px; min-width: 0; }
.xr-ver-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.xr-ver-id { font-family: var(--mono); font-size: var(--fs-lg); font-weight: 600; }
.xr-ver-name { font-weight: 600; }
.xr-ver-sub { margin-top: 4px; font-size: var(--fs-xs); color: var(--muted); }
.xr-ver-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.xr-ver-line {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 8px; padding: 0 2px; font-size: var(--fs-sm); color: var(--muted);
}
.xr-pending { color: var(--accent-ink); }
.xr-ver-err { margin-top: 8px; }

/* 分区切换：页内二级，做成胶囊，和上面的页签条区分开 */
.xr-secs { display: flex; flex-wrap: wrap; gap: 4px; }
.xr-sec {
  padding: 5px 12px; border: none; border-radius: var(--r-pill);
  background: transparent; color: var(--muted); font-size: var(--fs-sm); cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.xr-sec:hover { background: var(--chip-bg); color: var(--ink); }
.xr-sec.active { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; }
.xr-sec-n { margin-left: 2px; font-size: var(--fs-xs); font-weight: 400; color: var(--faint); font-variant-numeric: tabular-nums; }

.xr-note { max-width: 80em; font-size: var(--fs-sm); line-height: 1.7; color: var(--muted); }
.xr-filter { display: flex; align-items: center; gap: 8px 14px; flex-wrap: wrap; }
.xr-filter .input { width: 220px; }

/* 客群规则表：自己一个滚动容器，表头和规则号粘住 */
.xr-tblwrap {
  max-height: 72vh; overflow: auto;
  background: var(--card); border: 1px solid var(--line-soft); border-radius: var(--r-lg);
}
.xr-tbl { min-width: 980px; }
.xr-tbl th { padding: 7px 10px; vertical-align: bottom; }
.xr-tbl thead th { position: sticky; top: 0; z-index: 2; }
.xr-tbl td { padding: 6px 10px; vertical-align: top; }
.xr-id { font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }
.xr-tbl td.xr-id { position: sticky; left: 0; z-index: 1; background: var(--card); }
.xr-tbl thead th.xr-id { left: 0; z-index: 3; }
.xr-segth { width: 16%; min-width: 150px; }
.xr-segth-n { display: block; font-size: var(--fs-xs); font-weight: 400; color: var(--faint); }
.xr-grp td { padding: 6px 10px; background: var(--card-2); border-bottom: 1px solid var(--line); }
.xr-grp-name { font-size: var(--fs-sm); font-weight: 600; }
.xr-grp-n { margin-left: 8px; font-size: var(--fs-xs); color: var(--faint); }
.xr-namecell { min-width: 240px; }
.xr-name {
  padding: 0; border: none; background: transparent; cursor: pointer;
  color: var(--ink); font-size: var(--fs-sm); line-height: 1.5; text-align: left;
}
.xr-name:hover { color: var(--accent-ink); }
.xr-row.is-open .xr-name { font-weight: 600; }
.xr-row.is-open td { border-bottom-color: transparent; }
.xr-tags { display: inline-flex; gap: 4px; margin-left: 6px; }
.xr-dm { font-size: var(--fs-xs); color: var(--faint); }
.xr-nohit { padding: 28px 12px; text-align: center; color: var(--muted); }

/* 展开的规则说明 */
.xr-tbl .xr-detail td { padding: 8px 12px 12px; background: var(--card-2); }
.xr-dl {
  display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 14px;
  margin: 0; max-width: 84em; font-size: var(--fs-sm);
}
.xr-dl dt { padding-top: 2px; font-size: var(--fs-xs); color: var(--faint); white-space: nowrap; }
.xr-dl dd { margin: 0; line-height: 1.7; overflow-wrap: anywhere; }
.xr-kids { display: flex; flex-direction: column; gap: 6px; }
.xr-no { margin-right: 6px; font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); }
.xr-link { padding: 0; border: none; background: transparent; color: var(--accent); font-size: inherit; cursor: pointer; }
.xr-link:hover { color: var(--accent-ink); text-decoration: underline; }

/* 格子：等级 + 阈值小字。与出厂值不同的左上角一个圆点，未保存的浅底 */
.xr-tbl td.xr-cell { padding: 0; }
.xr-cellbox, .xr-cellbtn {
  position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%; padding: 6px 10px;
  border: none; background: transparent; color: var(--ink);
  font-size: var(--fs-sm); text-align: left;
}
.xr-cellbtn { cursor: pointer; border-radius: var(--r-sm); transition: background-color .12s ease; }
.xr-cellbtn:hover { background: var(--accent-soft); }
.xr-cell.is-dirty .xr-cellbtn { background: var(--accent-soft); }
.xr-cell-top { display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.xr-lv { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-sm); color: var(--ink); white-space: nowrap; }
.xr-lv i { width: 7px; height: 7px; flex: 0 0 7px; border-radius: 50%; background: var(--line-strong); }
.xr-lv.lv-critical { font-weight: 600; }
.xr-lv.lv-critical i { background: var(--deny-solid); }
.xr-lv.lv-high i { background: var(--red-solid); }
.xr-lv.lv-medium i { background: var(--warn-solid); }
.xr-na { font-size: var(--fs-xs); color: var(--faint); }
.xr-th { display: block; font-size: var(--fs-xs); line-height: 1.5; color: var(--muted); font-variant-numeric: tabular-nums; }
.xr-th.is-chg { color: var(--ink); font-weight: 600; }
.xr-dot { position: absolute; top: 4px; left: 3px; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }
.xr-unsaved { font-size: var(--fs-xs); color: var(--accent-ink); }
.xr-cur td { background: var(--accent-soft); }

/* 弹层里的表单（弹层正文默认居中，那是给图片预览用的） */
.xr-mbody { background: var(--card); text-align: left; }
.xr-mbody > .alert { margin-top: 12px; }
.xr-mbody > .xr-note { margin-bottom: 10px; }
.xr-form { display: flex; flex-direction: column; gap: 12px; }
.xr-form .field > span { font-size: var(--fs-sm); color: var(--muted); }
.xr-frow { display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: 6px 12px; align-items: center; }
.xr-frow-top { align-items: start; }
.xr-flabel { font-size: var(--fs-sm); color: var(--muted); }
.xr-fval { display: flex; align-items: center; gap: 6px 10px; flex-wrap: wrap; }
.xr-fval-grow .input { flex: 1 1 auto; }
.xr-num { width: 128px; font-variant-numeric: tabular-nums; }
.xr-short { width: auto; min-width: 140px; }
.xr-opts { display: flex; flex-wrap: wrap; gap: 6px; }
.xr-opt { position: relative; cursor: pointer; }
.xr-opt input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.xr-opt span {
  display: inline-block; padding: 4px 14px;
  border: 1px solid var(--line-strong); border-radius: var(--r);
  font-size: var(--fs-sm); color: var(--ink);
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.xr-opt input:checked + span { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; }
.xr-opt input:focus-visible + span { box-shadow: var(--focus-ring); }
.xr-ce-rest { display: flex; flex-direction: column; gap: 12px; transition: opacity .15s ease; }
.xr-ce-rest.is-off { opacity: .45; }
.xr-factory { padding-top: 10px; border-top: 1px solid var(--line-soft); }
.xr-confirm { display: flex; flex-direction: column; gap: 8px; font-size: var(--fs); line-height: 1.7; }
.xr-fgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.xr-span2 { grid-column: 1 / -1; }
.xr-checks { display: flex; align-items: center; gap: 6px 16px; flex-wrap: wrap; }
.xr-conds { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.xr-cond { display: grid; grid-template-columns: minmax(0, 1.6fr) 108px minmax(0, 1fr) auto; gap: 8px; align-items: center; }

/* 口径修正项：一项一张小卡，开关在右上 */
.xr-fixes { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr)); gap: 12px; }
.xr-fix {
  padding: 12px 14px; background: var(--card);
  border: 1px solid var(--line-soft); border-radius: var(--r-lg); font-size: var(--fs-sm);
}
.xr-fix-head { display: flex; align-items: flex-start; gap: 12px; }
.xr-fix-k { margin-top: 8px; font-size: var(--fs-xs); color: var(--faint); }
.xr-fix p { line-height: 1.7; }
.xr-switch {
  display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto;
  font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; cursor: pointer;
}
.xr-switch input {
  position: relative; flex: 0 0 34px; width: 34px; height: 20px; margin: 0;
  appearance: none; -webkit-appearance: none;
  border-radius: var(--r-pill); background: var(--line-strong); cursor: pointer;
  transition: background-color .15s ease;
}
.xr-switch input::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
  border-radius: 50%; background: var(--card); transition: transform .15s ease;
}
.xr-switch input:checked { background: var(--accent); }
.xr-switch input:checked::after { transform: translateX(14px); }
.xr-switch input:disabled { opacity: .55; cursor: not-allowed; }

/* 试算结果 */
.xr-trial-head { display: flex; align-items: center; gap: 6px 4px; flex-wrap: wrap; font-size: var(--fs-sm); }
.xr-trial-head .muted { margin-left: 10px; }
.xr-arrow { margin: 0 6px; color: var(--faint); }
.xr-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  background: var(--card); border: 1px solid var(--line-soft); border-radius: var(--r-lg); overflow: hidden;
}
.xr-stat { padding: 10px 16px; border-right: 1px solid var(--line-soft); }
.xr-stat:last-child { border-right: none; }
.xr-stat-k { font-size: var(--fs-xs); color: var(--muted); }
.xr-stat-v { font-size: var(--fs-2xl); font-weight: 600; line-height: 1.3; font-variant-numeric: tabular-nums; }
.xr-stat-v span { margin-left: 4px; font-size: var(--fs-sm); font-weight: 400; color: var(--muted); }
.xr-trans { display: flex; flex-wrap: wrap; gap: 8px 22px; font-size: var(--fs-sm); }
.xr-tran { display: inline-flex; align-items: center; }
.xr-tran b { margin: 0 4px 0 8px; font-variant-numeric: tabular-nums; }
.xr-rc { display: flex; flex-direction: column; gap: 2px; }
.xr-fold { font-size: var(--fs-sm); }
.xr-fold summary { color: var(--muted); cursor: pointer; }
.xr-fold[open] summary { margin-bottom: 8px; }

/* 留痕 / 差异清单 */
.xr-log { display: flex; flex-direction: column; margin-bottom: 10px; }
.xr-log li { padding: 7px 0; border-bottom: 1px solid var(--line-soft); font-size: var(--fs-sm); line-height: 1.6; }

@media (max-width: 640px) {
  .xr-frow { grid-template-columns: minmax(0, 1fr); }
  .xr-fgrid { grid-template-columns: minmax(0, 1fr); }
  .xr-cond { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .xr-tblwrap { max-height: none; }
}
/* <<< BLOCK:Y2-ext-rules */
