/* ==========================================================================
   components.css — 运输明细 × 发票 核对工具 · 组件样式
   --------------------------------------------------------------------------
   规则：
     1. 值一律 var(--...)，本文件不出现任何硬编码色值（#fff / #000 除外）
     2. 无 :has() / 嵌套 / container query（Chromium 100 基线）
     3. 类名约定已在 Spec 与前端对齐，改动需同步
     4. 每个交互组件覆盖：default / hover / focus-visible / active /
        disabled / loading / error / empty
   ========================================================================== */

/* ==========================================================================
   0. 基础
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  background: var(--color-bg);
  color: var(--color-fg);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; font-weight: var(--weight-semibold); line-height: var(--leading-title); }
p { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--color-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ==========================================================================
   1. 布局骨架 —— 顶部 48px 应用条 + 面包屑，无左侧导航
   ========================================================================== */

.app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.topbar {
  height: var(--topbar-height);
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-6);
  padding: 0 var(--layout-gutter);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
}

.topbar__brand {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-title);
  color: var(--color-fg);
  white-space: nowrap;
}

.topbar__nav {
  display: flex;
  gap: var(--space-1);
}

.topbar__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 32px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  color: var(--color-fg-2);
  text-decoration: none;
  transition: background var(--motion-fast) var(--ease-standard),
              color var(--motion-fast) var(--ease-standard);
}
.topbar__link:hover { background: var(--color-surface-2); color: var(--color-fg); text-decoration: none; }
.topbar__link.is-active { background: var(--color-accent-bg); color: var(--color-accent); font-weight: var(--weight-medium); }

.topbar__spacer { flex: 1; }

.topbar__user {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-base);
  color: var(--color-muted);
}

.breadcrumb {
  height: var(--breadcrumb-height);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--layout-gutter);
  font-size: var(--text-sm);
  color: var(--color-muted);
}
.breadcrumb__sep { color: var(--color-meta); }
.breadcrumb__current { color: var(--color-fg-2); }

.page {
  flex: 1;
  width: 100%;
  max-width: var(--layout-max);
  margin: 0 auto;
  padding: 0 var(--layout-gutter) var(--space-12);
}

.page__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-4) 0 var(--space-6);
}
.page__title { font-size: var(--text-xl); letter-spacing: var(--tracking-title); }
.page__sub { font-size: var(--text-base); color: var(--color-muted); }

/* ==========================================================================
   2. 按钮 .btn
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 36px;
  padding: 0 var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background var(--motion-fast) var(--ease-standard),
              border-color var(--motion-fast) var(--ease-standard),
              color var(--motion-fast) var(--ease-standard);
}

.btn--primary {
  background: var(--color-accent);
  color: var(--color-accent-on);
  border-color: var(--color-accent);
}
.btn--primary:hover  { background: var(--color-accent-hover); border-color: var(--color-accent-hover); }
.btn--primary:active { background: var(--color-accent-active); border-color: var(--color-accent-active); }

.btn--secondary {
  background: var(--color-surface);
  color: var(--color-fg);
  border-color: var(--color-border-strong);
}
.btn--secondary:hover  { background: var(--color-surface-2); }
.btn--secondary:active { background: var(--color-surface-3); }

.btn--ghost {
  background: transparent;
  color: var(--color-fg-2);
  border-color: transparent;
}
.btn--ghost:hover  { background: var(--color-surface-2); color: var(--color-fg); }
.btn--ghost:active { background: var(--color-surface-3); }

.btn--danger {
  background: var(--color-danger);
  color: var(--color-accent-on);
  border-color: var(--color-danger);
}
.btn--danger:hover  { background: var(--color-danger); opacity: 0.9; }
.btn--danger:active { opacity: 0.82; }

.btn--sm { height: 28px; padding: 0 var(--space-3); font-size: var(--text-sm); }

.btn:disabled,
.btn.is-disabled {
  background: var(--color-surface-3);
  color: var(--color-muted);
  border-color: var(--color-border);
  cursor: not-allowed;
  opacity: 1;
}

.btn.is-loading { cursor: progress; }
.btn.is-loading .i { animation: spin 900ms linear infinite; }

@keyframes spin { to { transform: rotate(360deg); } }

/* 键盘聚焦环由全局 :focus-visible 提供，这里只保证圆角一致 */
.btn:focus-visible { border-radius: var(--radius-md); }

/* ==========================================================================
   3. 表单 .field / .input / .select
   ========================================================================== */

.field { display: flex; flex-direction: column; gap: var(--space-2); }

.field__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-fg-2);
  letter-spacing: var(--tracking-caps);
}
.field__label--req::after {
  content: "必填";
  margin-left: var(--space-2);
  padding: 1px var(--space-1);
  border-radius: var(--radius-sm);
  background: var(--color-danger-bg);
  color: var(--color-danger);
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  letter-spacing: 0;
}

.input,
.select {
  height: 36px;
  padding: 0 var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  color: var(--color-fg);
  transition: border-color var(--motion-fast) var(--ease-standard),
              box-shadow var(--motion-fast) var(--ease-standard);
}
.input::placeholder { color: var(--color-muted); }
.input:hover,
.select:hover { border-color: var(--color-muted); }
.input:focus,
.select:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: var(--focus-ring);
}
.input:disabled,
.select:disabled {
  background: var(--color-surface-3);
  color: var(--color-muted);
  border-color: var(--color-border);
  cursor: not-allowed;
}

.select {
  appearance: none;
  padding-right: var(--space-8);
  background-image: none;
  cursor: pointer;
}

.field--error .input,
.field--error .select {
  border-color: var(--color-danger);
}
.field--error .input:focus,
.field--error .select:focus {
  box-shadow: 0 0 0 3px var(--color-danger-bg);
}

.field__hint {
  font-size: var(--text-sm);
  color: var(--color-muted);
}
.field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-danger);
}

/* 登录表单容器 */
.form-stack { display: flex; flex-direction: column; gap: var(--space-5); }

/* ==========================================================================
   4. 卡片 .card
   ========================================================================== */

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.card--flush { padding: 0; overflow: hidden; }

.card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border-soft);
}
.card__title { font-size: var(--text-lg); }

/* ==========================================================================
   5. 结论横幅 .banner —— SPEC §8 三态 × 异常正交编码
      只允许用 --verdict-* 别名，不得自行挑色
   ========================================================================== */

.banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border: 1px solid var(--banner-border);
  border-radius: var(--radius-lg);
  background: var(--banner-bg);
  color: var(--banner-fg);
}

/* 20px 图标 + 32px 语义浅底圆：补视觉权重，不引入 24px 尺寸档 */
.banner__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--badge-icon-size);
  height: var(--badge-icon-size);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  border: 1px solid var(--banner-border);
  color: var(--banner-fg);
}

.banner__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }

.banner__title {
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-title);
  color: var(--banner-fg);
}

/* 边界说明必须与主句同组，保证复制时一起带走 */
.banner__boundary {
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--color-fg-2);
}

.banner__actions { flex: none; display: flex; align-items: center; gap: var(--space-2); }

/* 三态 */
.banner--pass {
  --banner-fg: var(--verdict-pass-fg);
  --banner-bg: var(--verdict-pass-bg);
  --banner-border: var(--verdict-pass-border);
}
.banner--gap {
  --banner-fg: var(--verdict-gap-fg);
  --banner-bg: var(--verdict-gap-bg);
  --banner-border: var(--verdict-gap-border);
}
.banner--cannot {
  --banner-fg: var(--verdict-cannot-fg);
  --banner-bg: var(--verdict-cannot-bg);
  --banner-border: var(--verdict-cannot-border);
}
.banner--error {
  --banner-fg: var(--color-danger);
  --banner-bg: var(--color-danger-bg);
  --banner-border: var(--color-danger-border);
}

/* 降级态横幅 —— 【v3 已停用，勿启用】
   v3 按客户要求把结果页砍成三块，降级从"白底描边横幅"降为"结论下方一行 12px 提示"，
   对应样式是 .banner__hint（在同一文件后面），不是这一条。
   保留原因：v1.1 若要恢复结构性禁绿，这里是现成的；删了就只剩"再加回来"。
   保留风险：留着会让人以为它还能被打开 —— 所以在此显式标注停用，
   并请注意：**启用它必须同时改 DESIGN.md §9.5 屏 4 与走查 2.5d 的断言**。 */
.banner--degraded {
  --banner-fg: var(--verdict-degraded-fg);
  --banner-bg: var(--verdict-degraded-bg);
  --banner-border: var(--verdict-degraded-border);
}

/* 弱提示行：净重偏低但未达强提示阈值（low_weight_count）
   刻意不做成 pill —— pill 是"确定要处理"，弱提示是"偏低但可能正常"，
   两者可信度不同，同形态会让用户等权对待。中性色 + 纯文字。

   注意：当前不启用（team-lead 裁定：弱提示只放段 C 段头 + 导出件，不进横幅）。
   保留原因：横幅是最高视觉区，弱档是宽带、几乎每批都会有若干行，
   长期挂着会变成背景噪音，把同位置的琥珀 pill 存在感一起稀释。
   若上线实测发现用户确实错过弱提示，重新启用此样式即可，不必重写。 */
.banner__soft-note {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* 降级说明：与 boundary_note 同级、同一视觉组，可被一起复制 */
.banner__degraded-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--color-warn);
}
.banner__degraded-reasons {
  margin: var(--space-1) 0 0;
  padding-left: var(--space-4);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--color-fg-2);
}

/* 通过态 + 存在异常行：绿底横幅内追加琥珀常驻 pill（不得纯绿） */
.banner__anomaly-pill {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: var(--space-2);
  height: 26px;
  padding: 0 var(--space-3);
  border: 1px solid var(--anomaly-pill-border);
  border-radius: var(--radius-pill);
  background: var(--anomaly-pill-bg);
  color: var(--anomaly-pill-fg);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

/* 横幅右侧范围数字行 */
.banner__scope {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* 口径声明条 —— L1，永久可见、不可折叠 */
.boundary-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-info-border);
  border-radius: var(--radius-md);
  background: var(--color-info-bg);
  color: var(--color-fg-2);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
}
.boundary-note .i { color: var(--color-info); margin-top: 1px; }
.boundary-note__link {
  flex: none;
  background: none;
  border: 0;
  padding: 0;
  color: var(--color-info);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: underline;
  cursor: pointer;
}

/* 样本不足时的补充声明（anomaly_check_enabled = false） */
.boundary-note__extra {
  display: block;
  margin-top: var(--space-2);
  color: var(--color-warn);
}

/* ==========================================================================
   6. KPI 四格条 .kpi —— 一条被 hairline 切开的四格，不是四张卡片
   ========================================================================== */

.kpi {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.kpi__cell {
  padding: var(--space-4) var(--space-5);
  border-left: 1px solid var(--color-border-soft);
}
.kpi__cell:first-child { border-left: 0; }

.kpi__label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-muted);
  letter-spacing: var(--tracking-caps);
}

.kpi__value {
  display: block;
  margin-top: var(--space-2);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  color: var(--color-fg);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-title);
}

.kpi__unit {
  margin-left: var(--space-1);
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  color: var(--color-muted);
}

.kpi__note {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* 吨位差方向：不用色相编码，方向由符号 + 方向文字承担（见 tokens.css） */
.kpi__value--diff { color: var(--color-diff); }

.kpi__dir {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-diff-muted);
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   7. 三列证据条 .evidence-row —— divide-x 三格，不用三张卡片
   ========================================================================== */

.evidence-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.evidence-row__cell {
  padding: var(--space-4) var(--space-5);
  border-left: 1px solid var(--color-border-soft);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  text-align: left;
  background: none;
  border-top: 0;
  border-right: 0;
  border-bottom: 0;
  cursor: pointer;
}
.evidence-row__cell:first-child { border-left: 0; }
.evidence-row__cell:hover { background: var(--color-surface-2); }
.evidence-row__cell.is-active { box-shadow: inset 0 -2px 0 0 var(--color-accent); }

.evidence-row__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-fg-2);
  letter-spacing: var(--tracking-caps);
}

.evidence-row__dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--color-muted);
}
.evidence-row__dot--ok   { background: var(--color-success); }
.evidence-row__dot--warn { background: var(--color-warn); }
.evidence-row__dot--bad  { background: var(--color-danger); }
.evidence-row__dot--na   { background: var(--color-unverifiable); }

.evidence-row__value {
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  color: var(--color-fg);
  font-variant-numeric: tabular-nums;
}

.evidence-row__desc {
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--color-muted);
}

/* ==========================================================================
   8. 吨位咬合引文块 .reconcile —— 上下 hairline 框住，非卡片
   ========================================================================== */

.reconcile {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) 0;
  border-top: 1px solid var(--color-border-soft);
  border-bottom: 1px solid var(--color-border-soft);
  background: var(--color-surface-2);
  padding-left: var(--space-4);
  padding-right: var(--space-4);
  font-size: var(--text-md);
  line-height: var(--leading-body);
  color: var(--color-fg-2);
}
.reconcile__mark {
  flex: none;
  width: 8px;
  height: 8px;
  margin-top: 8px;
  border-radius: var(--radius-pill);
  background: var(--color-muted);
}
.reconcile--ok   .reconcile__mark { background: var(--color-success); }
.reconcile--warn .reconcile__mark { background: var(--color-warn); }
.reconcile--bad  .reconcile__mark { background: var(--color-danger); }

.reconcile__num { font-variant-numeric: tabular-nums; font-weight: var(--weight-medium); color: var(--color-fg); }
.reconcile__toggle {
  margin-left: auto;
  flex: none;
  background: none;
  border: 0;
  padding: 0;
  color: var(--color-accent);
  font-size: var(--text-sm);
  cursor: pointer;
  text-decoration: underline;
}

/* ==========================================================================
   9. 疑似配对横条 .pairbar —— 系统不判定，交人工裁决
   ========================================================================== */

.pairbar {
  border: 1px solid var(--pair-border);
  border-radius: var(--radius-lg);
  background: var(--pair-bg);
  overflow: hidden;
}

.pairbar__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--pair-border);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--pair-fg);
}
.pairbar__count {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}

.pairbar__item {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--pair-border);
}
.pairbar__item:last-child { border-bottom: 0; }

.pairbar__side {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.pairbar__side-label {
  font-size: var(--text-xs);
  color: var(--color-muted);
  letter-spacing: var(--tracking-caps);
}
.pairbar__raw {
  font-family: var(--font-mono);
  font-size: var(--text-md);
  color: var(--color-fg);
  font-variant-numeric: tabular-nums;
}
.pairbar__norm {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}
.pairbar__arrow { flex: none; color: var(--color-meta); }
.pairbar__reason {
  flex: none;
  font-size: var(--text-sm);
  color: var(--color-muted);
}
.pairbar__actions { margin-left: auto; flex: none; display: flex; gap: var(--space-2); }

/* ==========================================================================
   10. 表格 .t-table —— 冻结表头 + 冻结行号列
   ========================================================================== */

.t-table__wrap {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  overflow: auto;
  max-height: 560px;
}

.t-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--text-base);
  line-height: var(--leading-table);
}

.t-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  height: var(--table-header-height);
  padding: 0 var(--table-cell-px);
  background: var(--table-header-bg);
  color: var(--table-header-fg);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-caps);
  text-align: left;
  white-space: nowrap;
  border-bottom: 1px solid var(--color-border);
}

.t-table tbody td {
  height: var(--table-row-height);
  padding: 0 var(--table-cell-px);
  border-bottom: 1px solid var(--table-divider);
  color: var(--color-fg);
  vertical-align: middle;
}

.t-table tbody tr:last-child td { border-bottom: 0; }
.t-table tbody tr:hover td { background: var(--table-row-hover-bg); }
.t-table tbody tr.is-selected td { background: var(--table-row-selected-bg); }

.t-table .is-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* 冻结行号列 */
.t-table .t-table__rownum {
  position: sticky;
  left: 0;
  z-index: 1;
  width: var(--col-rownum-width);
  background: var(--color-surface);
  border-right: 1px solid var(--color-border-soft);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--color-fg-2);
}
.t-table thead .t-table__rownum { z-index: 3; background: var(--table-header-bg); }

/* 证据编号：源表行号 / 车牌 / 发票号，可点 */
.evidence {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0;
  background: none;
  border: 0;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--evidence-fg);
  text-decoration: underline;
  text-decoration-style: dotted;
  text-decoration-color: var(--evidence-decoration);
  text-underline-offset: 3px;
  cursor: pointer;
}
.evidence:hover {
  color: var(--evidence-hover-fg);
  text-decoration-color: var(--evidence-hover-decoration);
}
.evidence__more { color: var(--color-muted); text-decoration: none; font-family: var(--font-sans); }

/* 表格内金额/吨位单元格 */
.t-table .cell-num {
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* 表格内差值方向：同样不用色相，符号本身即方向 */
.t-table .cell-num--diff { color: var(--color-diff); }

/* 已排除的汇总行 */
.t-table tr.is-summary td {
  background: var(--table-excel-total-bg);
  color: var(--color-muted);
  font-style: normal;
}

/* ==========================================================================
   11. 结果分组 .result-row —— 段头 + 可折叠体
   ========================================================================== */

.result-group { margin-top: var(--space-6); }

.result-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3) 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--color-border);
  text-align: left;
  cursor: pointer;
}

.result-row__dot {
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: var(--radius-pill);
  background: var(--color-muted);
}
.result-row__dot--gap     { background: var(--color-danger); }
.result-row__dot--anomaly { background: var(--color-warn); }
.result-row__dot--pair    { background: var(--color-unverifiable); }
.result-row__dot--ok      { background: var(--color-success); }

.result-row__title {
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  color: var(--color-fg);
}
.result-row__count {
  font-size: var(--text-sm);
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}
.result-row__spacer { flex: 1; }
.result-row__chevron { color: var(--color-muted); transition: transform var(--motion-base) var(--ease-standard); }
.result-row[aria-expanded="true"] .result-row__chevron { transform: rotate(90deg); }

.result-group__body { padding-top: var(--space-3); }

/* ==========================================================================
   12. 徽章 .badge / .pill
   ========================================================================== */

.badge,
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0 var(--space-2);
  height: 22px;
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: 1;
  white-space: nowrap;
  border: 1px solid transparent;
  font-variant-numeric: tabular-nums;
}

.pill--success { background: var(--color-success-bg); color: var(--color-success); border-color: var(--color-success-border); }
.pill--warn    { background: var(--color-warn-bg);    color: var(--color-warn);    border-color: var(--color-warn-border); }
.pill--danger  { background: var(--color-danger-bg);  color: var(--color-danger);  border-color: var(--color-danger-border); }
.pill--info    { background: var(--color-info-bg);    color: var(--color-info);    border-color: var(--color-info-border); }
.pill--cannot  { background: var(--color-unverifiable-bg); color: var(--color-unverifiable); border-color: var(--color-unverifiable-border); }
.pill--neutral { background: var(--color-surface-2);  color: var(--color-fg-2);    border-color: var(--color-border); }

/* 降级态 pill：白底 + 描边 + 深色文字，无填充，强度低于绿（AC-05 禁止绿色） */
.pill--degraded {
  background: var(--verdict-degraded-bg);
  color: var(--verdict-degraded-fg);
  border-color: var(--verdict-degraded-border);
}

/* 描边型 pill（用于横幅内的异常计数，弱于实底 pill） */
.pill--outline-warn {
  background: var(--anomaly-pill-bg);
  color: var(--anomaly-pill-fg);
  border-color: var(--anomaly-pill-border);
}

/* ==========================================================================
   13. 投放区 .dropzone
   ========================================================================== */

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 132px;
  padding: var(--space-5);
  border: 1px dashed var(--dropzone-border);
  border-radius: var(--radius-lg);
  background: var(--dropzone-bg);
  color: var(--color-muted);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--motion-fast) var(--ease-standard),
              background var(--motion-fast) var(--ease-standard);
}
.dropzone:hover { border-color: var(--dropzone-hover-border); background: var(--dropzone-hover-bg); }

.dropzone.is-dragover {
  border-color: var(--dropzone-active-border);
  border-style: solid;
  background: var(--dropzone-active-bg);
}

.dropzone.is-error {
  border-color: var(--dropzone-error-border);
  background: var(--dropzone-error-bg);
}

.dropzone.is-disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.dropzone__icon { color: var(--color-muted); }
.dropzone__title { font-size: var(--text-base); font-weight: var(--weight-medium); color: var(--color-fg-2); }
.dropzone__hint  { font-size: var(--text-sm); color: var(--color-muted); }

/* ==========================================================================
   14. 文件行 .file-row
   ========================================================================== */

.file-list { display: flex; flex-direction: column; margin-top: var(--space-3); }

.file-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--table-row-height);
  padding: 0 var(--space-2);
  border-bottom: 1px solid var(--color-border-soft);
  font-size: var(--text-base);
}
.file-row:last-child { border-bottom: 0; }
.file-row:hover { background: var(--color-surface-2); }

.file-row__icon { flex: none; color: var(--color-muted); }

.file-row__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--color-fg);
}

.file-row__meta {
  flex: none;
  font-size: var(--text-sm);
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

.file-row__remove {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--radius-md);
  color: var(--color-muted);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--motion-fast) var(--ease-standard);
}
.file-row:hover .file-row__remove,
.file-row__remove:focus-visible { opacity: 1; }
.file-row__remove:hover { background: var(--color-surface-3); color: var(--color-fg); }

.file-row__error { color: var(--color-danger); font-size: var(--text-sm); }

/* ==========================================================================
   15. 进度 .progress
   ========================================================================== */

.progress {
  height: 4px;
  width: 100%;
  border-radius: var(--radius-pill);
  background: var(--progress-track);
  overflow: hidden;
}

.progress__bar {
  height: 100%;
  width: 0;
  border-radius: var(--radius-pill);
  background: var(--progress-bar);
  transition: width var(--motion-base) var(--ease-standard);
}

.progress__label {
  display: flex;
  justify-content: space-between;
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

/* 处理中：旋转图标 + 文案，不显示不确定态进度条动画 */
.progress-status {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  font-size: var(--text-base);
  color: var(--color-fg-2);
}
.progress-status .i { color: var(--color-accent); animation: spin 900ms linear infinite; }

/* ==========================================================================
   16. 分段控件 .tabs
   ========================================================================== */

.tabs {
  display: inline-flex;
  padding: 2px;
  gap: 2px;
  background: var(--color-surface-2);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
}

.tabs__item {
  height: 30px;
  padding: 0 var(--space-3);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-fg-2);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--motion-fast) var(--ease-standard),
              color var(--motion-fast) var(--ease-standard);
}
.tabs__item:hover { color: var(--color-fg); }
.tabs__item.is-active {
  background: var(--color-surface);
  color: var(--color-accent);
  box-shadow: var(--elev-ring);
}
.tabs__count {
  margin-left: var(--space-1);
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
}
.toolbar__spacer { flex: 1; }

/* ==========================================================================
   17. 分页 .pagination
   ========================================================================== */

.pagination {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) 0;
  font-size: var(--text-sm);
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}
.pagination__spacer { flex: 1; }

.pagination__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 28px;
  padding: 0 var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  color: var(--color-fg-2);
  font-size: var(--text-sm);
  cursor: pointer;
}
.pagination__btn:hover:not(:disabled) { background: var(--color-surface-2); }
.pagination__btn:disabled { color: var(--color-muted); border-color: var(--color-border); cursor: not-allowed; }
.pagination__btn.is-active {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-on);
}

/* ==========================================================================
   18. 空状态 .empty-state —— 不写「暂无数据」，给下一步动作
   ========================================================================== */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-12) var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.empty-state__title {
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  color: var(--color-fg);
}

.empty-state__desc {
  max-width: 62ch;
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--color-muted);
}

/* ==========================================================================
   19. 列映射面板 .field-mapping —— needs_confirm 状态
   ========================================================================== */

.mapping-panel {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  overflow: hidden;
}

.mapping-panel__head {
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface-2);
}

.mapping-panel__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-title);
  color: var(--color-fg);
}

.mapping-panel__meta {
  margin-top: var(--space-2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-fg-2);
}

.mapping-panel__body { padding: var(--space-5) var(--space-6); }

.field-mapping {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}
.field-mapping th {
  padding: 0 0 var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-muted);
  letter-spacing: var(--tracking-caps);
  text-align: left;
}
.field-mapping td {
  padding: var(--space-2) var(--space-3) var(--space-2) 0;
  border-top: 1px solid var(--color-border-soft);
  vertical-align: middle;
}
.field-mapping__raw {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  color: var(--color-fg);
}
.field-mapping__sample {
  font-size: var(--text-sm);
  color: var(--color-muted);
}
.field-mapping tr.is-unmapped .field-mapping__raw { color: var(--color-danger); }

/* 前 5 行原样预览 —— 验映射的唯一有效手段 */
.preview-note {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-5) 0 var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-fg-2);
}
.preview-note__hint { font-weight: var(--weight-regular); color: var(--color-muted); }

/* sticky 底部操作条 */
.sticky-actions {
  position: sticky;
  bottom: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-6);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
}
.sticky-actions__hint { font-size: var(--text-sm); color: var(--color-warn); }
.sticky-actions__spacer { flex: 1; }

/* ==========================================================================
   20. 抽屉 .drawer —— 源表原始行字段
   ========================================================================== */

.drawer__scrim {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  background: var(--color-scrim);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--motion-slow) var(--ease-standard);
}
.drawer__scrim.is-open { opacity: 1; pointer-events: auto; }

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-drawer);
  width: 420px;
  max-width: 92vw;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-left: 1px solid var(--color-border);
  box-shadow: var(--elev-overlay);
  transform: translateX(100%);
  transition: transform var(--motion-slow) var(--ease-standard);
}
.drawer.is-open { transform: translateX(0); }

.drawer__head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
}
.drawer__title { font-size: var(--text-md); font-weight: var(--weight-semibold); }
.drawer__sub { font-size: var(--text-sm); color: var(--color-muted); }
.drawer__close {
  margin-left: auto;
  flex: none;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  border-radius: var(--radius-md);
  color: var(--color-muted);
  cursor: pointer;
}
.drawer__close:hover { background: var(--color-surface-2); color: var(--color-fg); }

.drawer__body { flex: 1; overflow: auto; padding: var(--space-4) var(--space-5); }

/* 原始字段键值对：原表头名 + 原值，一律等宽不改写 */
.raw-fields { display: flex; flex-direction: column; }
.raw-fields__row {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border-soft);
  font-size: var(--text-base);
}
.raw-fields__row:last-child { border-bottom: 0; }
.raw-fields__key {
  flex: none;
  width: 132px;
  color: var(--color-muted);
  font-size: var(--text-sm);
}
.raw-fields__val {
  flex: 1;
  min-width: 0;
  word-break: break-all;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-fg);
}

/* ==========================================================================
   21. 登录页 —— 5:7 非对称，左藏青信息板 + 右白底表单
   ========================================================================== */

.auth {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 5fr 7fr;
}

.auth__aside {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--space-12) var(--space-10);
  background: var(--color-accent);
  color: var(--color-accent-on);
}

.auth__title {
  font-size: var(--text-3xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-title);
  line-height: var(--leading-title);
  max-width: 22ch;
}

.auth__points {
  margin: var(--space-6) 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  opacity: 0.86;
}

.auth__version { font-size: var(--text-sm); opacity: 0.6; }

.auth__main {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-10);
  background: var(--color-surface);
}

.auth__form { width: 100%; max-width: var(--layout-form-max); }
.auth__form-title { font-size: var(--text-xl); letter-spacing: var(--tracking-title); }
.auth__form-sub { margin-top: var(--space-2); font-size: var(--text-base); color: var(--color-muted); }
.auth__form-body { margin-top: var(--space-8); }

/* ==========================================================================
   22. 错误页 / 失败态 .error-panel
   ========================================================================== */

.error-panel {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border: 1px solid var(--color-danger-border);
  border-radius: var(--radius-lg);
  background: var(--color-danger-bg);
}

.error-panel__icon { flex: none; color: var(--color-danger); }
.error-panel__title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  color: var(--color-danger);
}
.error-panel__desc {
  margin-top: var(--space-2);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--color-fg-2);
}
.error-panel__list {
  margin: var(--space-3) 0 0;
  padding-left: var(--space-5);
  font-size: var(--text-sm);
  color: var(--color-fg-2);
  line-height: var(--leading-body);
}

/* 解析失败清单（cannot_verify 横幅内的次级列表，用红） */
.failed-parses { margin-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.failed-parse {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-fg-2);
}
.failed-parse__file { font-family: var(--font-mono); color: var(--color-fg); }
.failed-parse__kind { color: var(--color-danger); font-weight: var(--weight-medium); }

/* ==========================================================================
   23. 上传页两栏
   ========================================================================== */

.upload-grid {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: var(--space-6);
  align-items: start;
}

.upload-grid__col { display: flex; flex-direction: column; gap: var(--space-2); }

.upload-grid__label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-fg-2);
  letter-spacing: var(--tracking-caps);
}
.upload-grid__count { margin-left: auto; color: var(--color-muted); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   24. 历史记录列表
   ========================================================================== */

.history-table .t-table__wrap { max-height: none; }

.history-actions {
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
  opacity: 0;
  transition: opacity var(--motion-fast) var(--ease-standard);
}
.t-table tbody tr:hover .history-actions,
.history-actions:focus-within { opacity: 1; }
