/* ============================================================
   CsgtecERP - Back-office Component Layer
   ------------------------------------------------------------
   规则（严格执行样式标准）：
   1. 本文件不得修改 style.css，必须在其之后加载。
   2. 禁止出现任何硬编码新色值。所有颜色一律 var() 引用
      style.css 的 Design Tokens 或由其派生。
   3. 圆角只用 --r-sm/--r/--r-md/--r-lg/--r-xl/--r-full
   4. 阴影只用 --shadow-sm/md/lg/xl/brand/brand-lg/glass
   5. 过渡只用 --t-fast/--t/--t-slow + --ease-out-expo/quart
   ============================================================ */

/* ===== Token 修补 + 后台语义扩展 =====
   注：style.css 中 .badge-primary / .btn-primary 引用了 var(--white)
   但 :root 未定义该变量，此处补齐，属缺陷修复而非规范变更。 */
:root {
    --white: #FFFFFF;

    /* 语义色：直接映射 style.css 已有的 code-* 色板，不新增颜色 */
    --ok: var(--code-green);
    --warn: var(--code-orange);
    --danger: var(--code-red);
    --info: var(--code-blue);
    --pending: var(--code-yellow);
    --special: var(--code-purple);

    /* 语义色的低透明度背景（由品牌/语义色派生） */
    --ok-bg: rgba(126, 232, 160, 0.1);
    --warn-bg: rgba(255, 166, 87, 0.1);
    --danger-bg: rgba(255, 123, 114, 0.1);
    --info-bg: rgba(121, 192, 255, 0.1);
    --pending-bg: rgba(227, 179, 65, 0.1);
    --special-bg: rgba(210, 168, 255, 0.1);
    --brand-bg: rgba(15, 82, 186, 0.1);
    --brand-bg-strong: rgba(15, 82, 186, 0.18);

    /* 后台布局尺寸 */
    --nav-w: 232px;
    --nav-w-mini: 64px;
    --top-h: 56px;
    --page-pad: 24px;

    /* 后台字体阶（比官网更紧凑，适配高密度表单） */
    --fs-xs: 11px;
    --fs-sm: 12px;
    --fs: 13px;
    --fs-md: 14px;
    --fs-lg: 16px;
    --fs-xl: 20px;

    --mono: 'JetBrains Mono', 'Fira Code', ui-monospace, Consolas, monospace;
}

/* ===== 后台基座 ===== */
body.erp {
    background: var(--bg-deep);
    font-size: var(--fs-md);
    line-height: 1.5;
    overflow: hidden;
}
body.erp * { scrollbar-width: thin; scrollbar-color: var(--border-light) transparent; }
body.erp ::-webkit-scrollbar { width: 8px; height: 8px; }
body.erp ::-webkit-scrollbar-track { background: transparent; }
body.erp ::-webkit-scrollbar-thumb {
    background: var(--border-light);
    border-radius: var(--r-full);
}
body.erp ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.18); }

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -0.3px; }

/* ============================================================
   登录页
   ============================================================ */
.login-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-deep);
    position: relative;
    overflow: hidden;
}
.login-page::before {
    content: '';
    position: absolute;
    width: 900px; height: 900px;
    top: -300px; right: -200px;
    background: radial-gradient(circle, rgba(15, 82, 186, 0.14) 0%, transparent 62%);
    pointer-events: none;
}
.login-page::after {
    content: '';
    position: absolute;
    width: 700px; height: 700px;
    bottom: -280px; left: -180px;
    background: radial-gradient(circle, rgba(64, 128, 232, 0.08) 0%, transparent 62%);
    pointer-events: none;
}
.login-card {
    position: relative;
    z-index: 2;
    width: 100%;
    max-width: 420px;
    padding: 40px;
    background: rgba(22, 27, 34, 0.78);
    backdrop-filter: blur(24px) saturate(1.4);
    -webkit-backdrop-filter: blur(24px) saturate(1.4);
    border: 1px solid var(--border-light);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-glass);
}
.login-brand { text-align: center; margin-bottom: 32px; }
.login-mark {
    width: 56px; height: 56px;
    margin: 0 auto 16px;
    border-radius: var(--r-md);
    background: var(--grad-brand);
    box-shadow: var(--shadow-brand);
    display: flex; align-items: center; justify-content: center;
    font-size: 22px; font-weight: 900; color: var(--white);
    letter-spacing: -1px;
}
.login-title {
    font-size: 30px; font-weight: 800;
    color: var(--text-primary);
    letter-spacing: -0.5px;
}
.login-sub {
    font-size: var(--fs); color: var(--text-muted);
    margin-top: 6px; letter-spacing: 0.3px;
}
.login-error {
    display: none;
    padding: 10px 14px;
    margin-bottom: 16px;
    background: var(--danger-bg);
    border: 1px solid rgba(255, 123, 114, 0.25);
    border-radius: var(--r-sm);
    color: var(--danger);
    font-size: var(--fs);
}
.login-error.show { display: block; }
.login-foot {
    margin-top: 24px;
    text-align: center;
    font-size: var(--fs-sm);
    color: var(--text-dim);
}
.login-ver {
    margin-top: 4px;
    text-align: center;
    font-size: var(--fs-xs);
    color: var(--text-dim);
    opacity: 0.75;
    letter-spacing: 0.5px;
}

/* ============================================================
   应用外壳
   ============================================================ */
.erp-shell {
    display: grid;
    grid-template-columns: var(--nav-w) 1fr;
    grid-template-rows: var(--top-h) 1fr;
    grid-template-areas: "nav top" "nav main";
    height: 100vh;
    transition: grid-template-columns var(--t);
}
.erp-shell.mini { grid-template-columns: var(--nav-w-mini) 1fr; }

/* ---------- 侧边导航 ---------- */
.erp-nav {
    grid-area: nav;
    background: var(--bg-deep);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.nav-brand {
    height: var(--top-h);
    flex-shrink: 0;
    display: flex; align-items: center; gap: 10px;
    padding: 0 16px;
    border-bottom: 1px solid var(--border);
}
.nav-mark {
    width: 30px; height: 30px; flex-shrink: 0;
    border-radius: var(--r-sm);
    background: var(--grad-brand);
    box-shadow: var(--shadow-brand);
    display: flex; align-items: center; justify-content: center;
    font-size: var(--fs); font-weight: 900; color: var(--white);
    letter-spacing: -0.5px;
}
.nav-name {
    font-size: var(--fs-md); font-weight: 700;
    color: var(--text-primary); letter-spacing: -0.3px;
    white-space: nowrap;
}
.nav-logo {
    height: 30px; width: auto; flex-shrink: 0;
    max-width: 100%;
    display: block;
}
/* 夜晚模式：logo 自动转为纯白色（任意图变纯白剪影，深色背景下清晰可见） */
[data-theme="dark"] .nav-logo { filter: brightness(0) invert(1); }
.erp-shell.mini .nav-name { display: none; }

.nav-scroll { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 12px 0 20px; }
.nav-group { margin-bottom: 4px; }
.nav-group-title {
    padding: 12px 18px 6px;
    font-size: var(--fs);
    font-weight: 700;
    letter-spacing: 1.4px;
    color: var(--text-secondary);
    text-transform: uppercase;
    white-space: nowrap;
    display: flex; align-items: center; justify-content: space-between;
    cursor: pointer; user-select: none;
}
.nav-group-title .ng-caret { opacity: 0.7; transition: transform var(--t-fast); flex: none; }
/* 分组标题：中文与英文缩写保持一个空格的间距，避免被 letter-spacing 撑大 */
.nav-group-title .grp-label { display: inline-flex; align-items: baseline; min-width: 0; }
.nav-group-title .grp-label .grp-en { margin-left: 0.25em; }
/* 分组标题中的英文缩写（如 SMS/PMS/MES）调浅，仅用透明度派生，不引入新色值 */
.nav-group-title .grp-en { opacity: 0.55; letter-spacing: normal; }
.nav-group.collapsed .ng-caret { transform: rotate(-90deg); }
.nav-group.collapsed .nav-group-body { display: none; }
.erp-shell.mini .nav-group-title {
    padding: 12px 0 6px;
    text-align: center;
    font-size: 0;
}
.erp-shell.mini .nav-group-title::after {
    content: '';
    display: block;
    width: 20px; height: 1px;
    margin: 0 auto;
    background: var(--border-light);
}
.erp-shell.mini .nav-group-title .ng-caret { display: none; }
.erp-shell.mini .nav-group.collapsed .nav-group-body { display: block; }
.erp-shell.mini .nav-subgroup-title .sub-caret { display: none; }
.erp-shell.mini .nav-subgroup.collapsed .nav-subgroup-body { display: block; }

/* 二级分类（子分组）：在一级分组内再分组，标题样式与一级分组标题（nav-group-title）保持一致 */
.nav-subgroup { margin: 4px 14px; }
.nav-subgroup-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 6px 10px 4px;
  font-size: var(--fs);
  font-weight: 700;
  letter-spacing: 1.4px;
  color: var(--text-secondary);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.nav-subgroup-title > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.sub-caret { flex-shrink: 0; opacity: 0.5; transition: transform 0.15s ease; }
.nav-subgroup.collapsed .sub-caret { transform: rotate(-90deg); }
.nav-subgroup.collapsed .nav-subgroup-body { display: none; }
.nav-subgroup .nav-item { margin-left: 0; margin-right: 0; }

.nav-item {
    display: flex; align-items: center; justify-content: flex-start; gap: 11px;
    height: 38px;
    margin: 1px 10px;
    /* padding-bottom 2px：中文按字体度量天生低于行盒中心约 1px，底部多 2px 把内容区整体上移 1px 补偿（按钮/输入框同理） */
    padding: 0 12px 2px;
    border-radius: var(--r-sm);
    font-size: var(--fs-md);
    font-weight: 500;
    color: var(--text-secondary);
    cursor: pointer;
    transition: var(--t-fast);
    position: relative;
    white-space: nowrap;
    text-align: left;
}
.nav-item i {
    width: 16px; flex-shrink: 0;
    font-size: var(--fs-md);
    text-align: center;
    transition: var(--t-fast);
}
.nav-item .ic { flex: 0 0 auto; width: 18px; display: flex; align-items: center; justify-content: center; }
.nav-item .ic svg { display: block; }
.nav-item .nav-label { flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item:hover {
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-primary);
}
.nav-item.active {
    background: var(--brand-bg-strong);
    color: var(--brand-light);
    font-weight: 600;
}
.nav-item.active i { color: var(--brand-light); }
.nav-item.active::before {
    content: '';
    position: absolute;
    left: -10px; top: 50%;
    transform: translateY(-50%);
    width: 3px; height: 18px;
    background: var(--grad-brand);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
}
.nav-badge {
    flex: none !important;
    margin-left: auto;
    height: 18px;
    padding: 0 6px;
    border-radius: var(--r-full);
    background: var(--brand);
    color: var(--white);
    font-size: 10px; font-weight: 700;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--mono);
}
/* 侧边栏待办/未读数量徽标（红色，参考钉钉/企微风格） */
.nav-count {
    flex: none !important;
    margin-left: auto;
    min-width: 18px; height: 18px;
    padding: 0 5px;
    border-radius: var(--r-full);
    background: var(--danger);
    color: var(--white);
    font-size: 10px; font-weight: 700;
    line-height: 1;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--mono);
}
/* 未实装模块（stage != 1）置灰，点击进入"建设中"提示页 */
.nav-item[data-stage]:not([data-stage="1"]) { opacity: 0.5; }
.erp-shell.mini .nav-item { justify-content: center; padding: 0; margin: 1px 8px; }
.erp-shell.mini .nav-item .nav-label,
.erp-shell.mini .nav-badge,
.erp-shell.mini .nav-count { display: none; }

.nav-foot {
    flex-shrink: 0;
    padding: 10px;
    border-top: 1px solid var(--border);
}
.nav-collapse {
    width: 100%; height: 34px;
    border: none; border-radius: var(--r-sm);
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    font-size: var(--fs);
    display: flex; align-items: center; justify-content: center; gap: 8px;
    transition: var(--t-fast);
}
.nav-collapse:hover { background: rgba(255, 255, 255, 0.05); color: var(--text-primary); }
.erp-shell.mini .nav-collapse span { display: none; }

/* ---------- 顶栏 ---------- */
.erp-top {
    grid-area: top;
    background: rgba(15, 20, 25, 0.8);
    backdrop-filter: blur(20px) saturate(1.3);
    -webkit-backdrop-filter: blur(20px) saturate(1.3);
    border-bottom: 1px solid var(--border);
    display: flex; align-items: center; justify-content: space-between;
    padding: 0 20px;
    z-index: 100;
}
.top-left { display: flex; align-items: center; gap: 14px; min-width: 0; }
.crumb {
    display: flex; align-items: center; gap: 7px;
    font-size: var(--fs); color: var(--text-muted);
    white-space: nowrap; overflow: hidden;
}
.crumb i { font-size: 9px; color: var(--text-dim); }
.crumb .crumb-now { color: var(--text-primary); font-weight: 600; }

.top-right { display: flex; align-items: center; gap: 8px; }
.top-btn {
    width: 34px; height: 34px;
    border: 1px solid var(--border-light);
    border-radius: var(--r-sm);
    background: rgba(255, 255, 255, 0.06);
    backdrop-filter: blur(8px);
    color: var(--text-secondary);
    font-size: var(--fs-md);
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    transition: var(--t-fast);
    position: relative;
}
.top-btn:hover {
    border-color: rgba(255, 255, 255, 0.2);
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.1);
}
.top-btn .dot-flag {
    position: absolute; top: 6px; right: 6px;
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--danger);
    box-shadow: 0 0 0 2px var(--bg-dark);
}

.top-user {
    display: flex; align-items: center; gap: 9px;
    height: 34px; padding: 0 10px 2px 5px;
    border: 1px solid var(--border-light);
    border-radius: var(--r-sm);
    background: rgba(255, 255, 255, 0.06);
    cursor: pointer;
    transition: var(--t-fast);
}
.top-user:hover { border-color: rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.1); }
.avatar {
    width: 24px; height: 24px; flex-shrink: 0;
    border-radius: var(--r-full);
    background: var(--grad-brand);
    color: var(--white);
    font-size: var(--fs-xs); font-weight: 700;
    display: flex; align-items: center; justify-content: center;
}
.avatar-lg { width: 40px; height: 40px; font-size: var(--fs-md); }
.top-user-meta { display: flex; flex-direction: column; line-height: 1.25; }
.top-user-name { font-size: var(--fs); font-weight: 600; color: var(--text-primary); }
.top-user-role { font-size: 10px; color: var(--text-muted); }

/* ---------- 主内容区 ---------- */
.erp-main {
    grid-area: main;
    overflow-y: auto;
    background: var(--bg-dark);
    padding: var(--page-pad);
}
.page { max-width: 100%; margin: 0 auto; animation: pageIn 0.4s var(--ease-out-expo); }
.executive-page {
    min-height: 100%;
    display: flex;
    flex-direction: column;
}
.executive-page .kpi-grid { flex-shrink: 0; }
.executive-page > .field-row {
    flex: 1 1 0;
    min-height: 0;
}
.executive-page > .field-row:last-child { margin-bottom: 0; }
.executive-page .panel {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}
.executive-page .panel + .panel { margin-top: 0; }
.executive-page .panel-head { flex-shrink: 0; }
.executive-page .panel-body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}
.executive-page .panel-body .panel-fill-list {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    min-height: 0;
}
.executive-page .panel-body .panel-fill-list > *:last-child { margin-bottom: 0 !important; }
.executive-page .panel-body .empty {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

/* 经营看板 · 五个数据块合并为一个 100% 宽高标签页容器 */
.executive-page > .exec-tab-wrap {
    flex: 1 1 0;
    min-height: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
}
.exec-tab-wrap .tabs { margin-bottom: 0; padding: 8px 14px 0; flex-shrink: 0; }
.exec-tab-wrap .tab { padding: 11px 16px; }
.exec-tab-body { flex: 1 1 auto; min-height: 0; position: relative; }
.exec-tab-pane { display: none; height: 100%; min-height: 0; }
.exec-tab-pane.active { display: flex; flex-direction: column; }
.exec-tab-pane.active > .panel-fill-list { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 16px 18px; }
.exec-tab-pane.active > .empty {
    flex: 1 1 auto;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
}
/* 客户订单分析 tab 内部布局（下拉条 + 统计卡 + 折线图） */
.cus-analysis-bar { flex-shrink: 0; padding: 14px 18px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 12px; }
.cus-analysis-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 16px 18px; overflow: auto; }
.cus-analysis-body .cus-stat-row { flex-shrink: 0; }
.cus-analysis-body .cus-chart-title { flex-shrink: 0; }
.cus-analysis-body .cus-chart-box { flex: 1 1 auto; min-height: 220px; margin-top: 10px; position: relative; }
@keyframes pageIn {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

.page-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 16px; margin-bottom: 20px; flex-wrap: wrap;
}
.page-title {
    font-size: var(--fs-xl); font-weight: 800;
    color: var(--text-primary); letter-spacing: -0.4px;
}
.page-title .ic { display: inline-flex; align-items: center; vertical-align: -0.18em; margin-right: 3px; }
.page-sub { font-size: var(--fs); color: var(--text-muted); margin-top: 5px; }
.page-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* 财务报表（fin-report）—— 分区小标题的边距（表格保持通栏，不加左右边距） */
.rpt-sub { margin: 14px 0 8px 16px; font-size: var(--fs); font-weight: 600; color: var(--text-primary); }

/* ============================================================
   面板 / 卡片
   ============================================================ */
.panel {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
    transition: var(--t);
}
.panel + .panel { margin-top: 16px; }
.panel-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border);
}
.panel-title {
    font-size: var(--fs-md); font-weight: 700;
    color: var(--text-primary);
    display: flex; align-items: center; gap: 8px;
}
.panel-title i { color: var(--brand-light); font-size: var(--fs); }
.panel-body { padding: 18px; }
.panel-body.flush { padding: 0; }
.panel-foot {
    padding: 12px 18px;
    border-top: 1px solid var(--border);
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
}

/* ============================================================
   KPI 卡片
   ============================================================ */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 14px;
    margin-bottom: 14px;
}
.kpi-grid.cols-5 {
    grid-template-columns: repeat(5, 1fr);
    grid-auto-rows: 1fr;
}
.kpi-grid.cols-5 .kpi { display: flex; flex-direction: column; justify-content: space-between; }

/* 工作台页面模块间距统一（参考 KPI 卡片间距 14px） */
.page > .panel { margin-bottom: 14px; }
.page > .panel:last-child { margin-bottom: 0; }
.page > .field-row { margin-bottom: 14px; }
.kpi {
    position: relative;
    overflow: hidden;
    padding: 18px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    transition: var(--t);
}
.kpi::before {
    content: '';
    position: absolute; top: 0; left: 0; right: 0;
    height: 2px; background: var(--grad-brand);
    transform: scaleX(0); transform-origin: left;
    transition: transform var(--t);
}
.kpi:hover {
    transform: translateY(-4px);
    border-color: var(--border-brand);
    box-shadow: 0 0 30px rgba(15, 82, 186, 0.15), var(--shadow-lg);
}
.kpi:hover::before { transform: scaleX(1); }
.kpi-top {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 12px;
}
.kpi-label {
    font-size: var(--fs-sm); color: var(--text-muted);
    font-weight: 500; letter-spacing: 0.2px;
}
.kpi-icon {
    width: 32px; height: 32px;
    border-radius: var(--r-sm);
    background: var(--brand-bg);
    color: var(--brand-light);
    display: flex; align-items: center; justify-content: center;
    font-size: var(--fs-md);
    transition: var(--t-fast);
}
.kpi:hover .kpi-icon { background: var(--grad-brand); color: var(--white); transform: scale(1.08); }
.kpi-value {
    font-family: var(--mono);
    font-size: 26px; font-weight: 800;
    color: var(--text-primary);
    letter-spacing: -1px; line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.kpi-value .unit { font-size: var(--fs); font-weight: 600; color: var(--text-muted); margin-left: 3px; }
.kpi-foot {
    margin-top: 9px;
    font-size: var(--fs-sm);
    color: var(--text-muted);
    display: flex; align-items: center; gap: 5px;
}
.kpi-delta { font-weight: 700; font-family: var(--mono); display: inline-flex; align-items: center; gap: 3px; }
/* 中国习惯：涨红跌绿 */
.kpi-delta.up { color: var(--danger); }
.kpi-delta.down { color: var(--ok); }
.kpi-delta.flat { color: var(--text-muted); }

/* 语义化 KPI 顶条 */
.kpi.k-ok::before { background: var(--ok); }
.kpi.k-warn::before { background: var(--warn); }
.kpi.k-danger::before { background: var(--danger); }
.kpi.k-ok .kpi-icon { background: var(--ok-bg); color: var(--ok); }
.kpi.k-warn .kpi-icon { background: var(--warn-bg); color: var(--warn); }
.kpi.k-danger .kpi-icon { background: var(--danger-bg); color: var(--danger); }
.kpi.k-ok:hover .kpi-icon { background: var(--ok); color: var(--bg-deep); }
.kpi.k-warn:hover .kpi-icon { background: var(--warn); color: var(--bg-deep); }
.kpi.k-danger:hover .kpi-icon { background: var(--danger); color: var(--bg-deep); }

/* 工作台快捷入口卡片（跳转手机端操作页） */
.kpi-link { cursor: pointer; }
.kpi-link .kpi-value { display: flex; align-items: center; gap: 6px; }
.mobile-ops .kpi-link .kpi-value { font-size: 18px; font-weight: 700; }

/* ============================================================
   工具栏
   ============================================================ */
.toolbar {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
}
.toolbar-spacer { flex: 1; }
/* 列表排序按钮组（物料管理等模块的排序工具条） */
.sort-group { display: inline-flex; align-items: center; gap: 4px; }
.sort-group .sort-lbl { font-size: 12px; color: var(--text-dim); margin-right: 2px; }
.sort-group .sort-btn { padding: 4px 10px 6px; font-size: 12px; line-height: 1.4; }
.sort-group .sort-btn.sort-active { background: var(--brand); border-color: var(--brand); color: #fff; }
.sort-group .sort-btn.sort-active:hover { background: var(--brand); color: #fff; }

/* 生产工单：状态多选 chips（样式对齐库存建议物料类型筛选） */
.mfg-status-chips { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.mfg-status-chip {
  padding: 3px 12px; font-size: 12px; line-height: 1.5; border-radius: 999px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text);
  cursor: pointer; user-select: none; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s;
}
.mfg-status-chip:hover { border-color: var(--brand); }
.mfg-status-chip.active { background: var(--brand-soft, rgba(37,99,235,.12)); border-color: var(--brand); color: var(--brand); font-weight: 600; }
.search-box { position: relative; }
.search-box .ic {
    position: absolute; left: 11px; top: 50%;
    transform: translateY(-50%);
    font-size: var(--fs); color: var(--text-dim);
    pointer-events: none;
}
.search-box input { padding-left: 32px !important; width: 240px; }
/* 搜索关键字命中片段：浅色底 + 微弱描边，克制地标出「这行是被哪一段命中的」 */
.kw-hit { background: var(--brand-bg-strong); border-radius: 2px; }
/* MRP 采购建议量被「最小起订量」上调时的角标 */
.moq-flag { margin-left: 2px; padding: 0 3px; font-size: 10px; line-height: 1.4; font-weight: 600; color: var(--warn); border: 1px solid var(--warn); border-radius: 3px; cursor: help; vertical-align: super; }
.filter-item { display: flex; align-items: center; gap: 6px; }
.filter-label { font-size: var(--fs-sm); color: var(--text-dim); white-space: nowrap; }

/* 工具栏内联筛选字段（如库存查询的仓库下拉） */
.tb-field { display: inline-flex; align-items: center; gap: 6px; }
.tb-field-label { font-size: var(--fs-sm); color: var(--text-dim); white-space: nowrap; }
.tb-field .combobox { width: 180px; }

/* 筛选按钮 */
#btnFilter.filter-active {
    background: var(--brand-bg-strong);
    border-color: var(--border-brand);
    color: var(--brand-light);
}
.filter-badge {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 16px; height: 16px; padding: 0 4px;
    border-radius: var(--r-full);
    background: var(--brand);
    color: var(--white);
    font-size: 10px; font-weight: 700;
    font-family: var(--mono);
}

/* ============================================================
   弹窗筛选面板
   ============================================================ */
.filter-headline {
    font-size: var(--fs-md);
    color: var(--text-secondary);
    margin-bottom: 16px;
}
.filter-headline .filter-logic {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 2px 8px;
    background: var(--brand-bg);
    border: 1px solid var(--border-brand);
    border-radius: var(--r-sm);
    color: var(--brand-light);
    font-weight: 600;
    cursor: default;
}
.filter-list { display: flex; flex-direction: column; gap: 10px; }
.filter-empty-tip {
    padding: 28px 16px;
    text-align: center;
    color: var(--text-muted);
    font-size: var(--fs-md);
    border: 1px dashed var(--border-light);
    border-radius: var(--r-sm);
    background: rgba(255, 255, 255, 0.02);
}
.filter-empty-tip .ic { display: block; margin: 0 auto 10px; font-size: 28px; color: var(--text-dim); }
.filter-line {
    display: grid;
    grid-template-columns: 170px 120px 1fr 32px;
    gap: 10px;
    align-items: center;
}
.filter-line .sel,
.filter-line .inp { height: 36px; }
.filter-value-cell { min-width: 0; }
.filter-value-cell .filter-empty { padding-left: 4px; }
/* 范围筛选（between）：开始 ~ 结束 两个日期/时间框 */
.filter-range { display: flex; align-items: center; gap: 8px; min-width: 0; }
.filter-range .date-wrap { flex: 1; min-width: 0; }
.filter-range .inp { flex: 1; min-width: 0; }
.filter-range-sep { flex: none; color: var(--text-dim); }
.filter-add {
    margin-top: 12px;
    width: auto;
    align-self: flex-start;
}
.filter-summary {
    margin-top: 14px;
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

/* ============================================================
   表单控件
   ============================================================ */
.field { margin-bottom: 16px; }
.field-label {
    display: block;
    font-size: var(--fs); font-weight: 600;
    color: var(--text-secondary);
    margin-bottom: 7px;
}
.field-label .req { color: var(--danger); margin-left: 3px; }
.field-hint { font-size: var(--fs-sm); color: var(--text-dim); margin-top: 5px; }
.field-err { font-size: var(--fs-sm); color: var(--danger); margin-top: 5px; display: none; }
.field.invalid .field-err { display: block; }
.field.invalid .inp,
.field.invalid .sel { border-color: var(--danger); }

.inp, .sel, textarea.inp {
    width: 100%;
    height: 36px;
    padding: 0 12px 2px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-light);
    border-radius: var(--r-sm);
    color: var(--text-primary);
    font-size: var(--fs-md);
    font-family: inherit;
    transition: var(--t-fast);
    outline: none;
}
textarea.inp { height: auto; min-height: 84px; padding: 9px 12px; resize: vertical; line-height: 1.6; }
.inp::placeholder, textarea.inp::placeholder { color: var(--text-dim); }
.inp:hover, .sel:hover { border-color: rgba(255, 255, 255, 0.2); }
.inp:focus, .sel:focus, textarea.inp:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(15, 82, 186, 0.15);
    background: var(--bg-surface);
}
.inp:disabled, .sel:disabled, textarea.inp:disabled {
    opacity: 0.45; cursor: not-allowed; background: var(--bg-dark);
}
.field.locked .field-label::after {
    content: '（已锁定）';
    color: var(--text-dim);
    font-size: var(--fs-sm);
    font-weight: 400;
    margin-left: 6px;
}
.inp[readonly] { background: var(--bg-dark); color: var(--text-secondary); user-select: none; cursor: default; }
.inp.mono, .inp.num { font-family: var(--mono); }
.inp.text-right { text-align: right; }

.sel {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    padding-right: 30px;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23ffffff' stroke-opacity='0.48' stroke-width='1.6'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 14px;
}
.sel::-ms-expand { display: none; }
.sel option { background: var(--bg-elevated); color: var(--text-primary); }
/* 原生下拉统一强制隐藏浏览器默认箭头，仅保留 .sel 自定义箭头（避免箭头重复） */
select.sel,
select.inp.sel { -webkit-appearance: none; -moz-appearance: none; appearance: none; }

/* 可搜索下拉 combobox（复用 .inp 视觉 token） */
.combobox { position: relative; width: 100%; }
.combobox-ctrl {
    display: flex; align-items: center;
    height: 36px; padding: 0 12px 2px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-light);
    border-radius: var(--r-sm);
    transition: var(--t-fast);
    cursor: pointer;
}
.combobox .combobox-input,
.combobox .combobox-input[readonly] {
    flex: 1; min-width: 0; height: 100%;
    border: none; outline: none; background: transparent;
    color: var(--text-primary); font-size: var(--fs-md); font-family: inherit; padding: 0;
    caret-color: transparent; cursor: pointer;
    background-image: none;
}
.combobox-input::placeholder { color: var(--text-dim); opacity: 1; }
input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(1); cursor: pointer; }
.combobox-caret {
    display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center;
    color: var(--text-primary); pointer-events: none; transition: transform var(--t-fast);
}
.combobox-caret svg { display: block; }
.combobox.open .combobox-caret { transform: rotate(180deg); }
/* 面板改为向上展开时，箭头保持朝下（指示内容在触发元素上方），避免方向误导 */
.combobox.open.combobox-up .combobox-caret { transform: rotate(0deg); }
.combobox.open .combobox-ctrl {
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(15, 82, 186, 0.15);
    background: var(--bg-surface);
}
.combobox-panel {
    position: fixed; z-index: 3000; top: 0; left: 0;
    max-height: 320px; overflow-y: auto;
    min-width: 120px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-lg);
    padding: 4px;
}
.combobox-search {
    display: flex; align-items: center; gap: 6px;
    padding: 10px 8px; margin: -4px -4px 4px -4px;
    border-bottom: 1px solid var(--border-light);
}
.combobox-search-icon { color: var(--text-dim); display: flex; align-items: center; }
.combobox-search-input {
    flex: 1 1 auto; min-width: 0;
    background: transparent; border: none; outline: none;
    color: var(--text-primary); font-size: var(--fs-md);
}
.combobox-search-input::placeholder { color: var(--text-dim); opacity: 1; }
.combobox-list { list-style: none; margin: 0; padding: 0; }
.combobox-opt {
    padding: 8px 10px; border-radius: var(--r-sm);
    font-size: var(--fs-md); color: var(--text-secondary);
    cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.combobox-opt:hover, .combobox-opt.active { background: var(--bg-elevated); color: var(--text-primary); }
.combobox-empty { padding: 10px; text-align: center; color: var(--text-dim); font-size: var(--fs-sm); }
/* ---------- 多选模式（field.multiple）----------
   选项前置勾选框 + 面板底部「已选 N 项 / 清空 / 确定」。
   底部操作条用 sticky 吸底：面板本身是 overflow-y:auto 的滚动容器，
   写成普通块元素会被长列表挤到视口外，必须先滚动到底才能点「确定」。 */
.combobox-opt.is-multi { display: flex; align-items: center; gap: 8px; }
.combobox-opt.is-multi .cb-opt-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cb-check {
    flex: none; position: relative;
    width: 14px; height: 14px; border-radius: 3px;
    border: 1px solid var(--border-light);
    background: transparent;
    transition: var(--t-fast);
}
.combobox-opt.checked .cb-check { background: var(--brand); border-color: var(--brand); }
.combobox-opt.checked .cb-check::after {
    content: ''; position: absolute; left: 4px; top: 1px;
    width: 4px; height: 8px;
    border: solid #fff; border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
.combobox-opt.checked { color: var(--text-primary); }
.combobox-foot {
    position: sticky; bottom: -4px; z-index: 2;
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    margin: 4px -4px -4px -4px; padding: 8px;
    background: var(--bg-surface);
    border-top: 1px solid var(--border-light);
    border-radius: 0 0 var(--r-md) var(--r-md);
}
.cb-count { font-size: var(--fs-sm); color: var(--text-dim); white-space: nowrap; }
.cb-foot-btns { display: inline-flex; gap: 6px; flex: none; }
.cb-btn {
    height: 26px; padding: 0 12px 2px; border-radius: var(--r-sm);
    border: 1px solid var(--border-light); background: transparent;
    color: var(--text-secondary); font-size: var(--fs-sm); font-family: inherit;
    cursor: pointer; transition: var(--t-fast);
    display: inline-flex; align-items: center; justify-content: center;
}
.cb-btn:hover { background: var(--bg-elevated); color: var(--text-primary); }
.cb-btn-primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.cb-btn-primary:hover { background: var(--brand); color: #fff; filter: brightness(1.08); }
[data-theme="light"] .combobox-panel { background: var(--bg-surface); border-color: var(--border); }
[data-theme="light"] .combobox-opt { color: var(--text-secondary); }
[data-theme="light"] .combobox-opt:hover,
[data-theme="light"] .combobox-opt.active { background: var(--bg-elevated); color: var(--text-primary); }
.combobox.is-disabled .combobox-ctrl { opacity: 0.45; cursor: not-allowed; background: var(--bg-dark); }

.field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px 16px;
}
.field-row.c2 { grid-template-columns: repeat(2, 1fr); }
.field-row.c3 { grid-template-columns: repeat(3, 1fr); }
.field-row.c4 { grid-template-columns: repeat(4, 1fr); }
.field-row .full { grid-column: 1 / -1; }

/* 采购订单明细区间距（table.tb 无下边距，需手动补足层级感） */
#itemsZone #addItem { margin-top: 12px; }
/* 采购订单明细合计行（与 .field 16px 节奏一致，避免紧贴「添加明细」按钮） */
.po-total {
    margin-top: 16px;
    text-align: right;
    font-size: var(--fs-md);
    color: var(--text-secondary);
}
.po-total b { color: var(--text-primary); font-size: var(--fs-lg); font-weight: 700; }

/* 明细页脚：最长到货期（左） + 金额合计（右） */
.po-foot {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; flex-wrap: wrap; margin-top: 16px;
}
.po-foot .po-total { margin-top: 0; }
.po-lead { font-size: var(--fs-md); color: var(--text-secondary); }
.po-lead b { color: var(--text-primary); font-size: var(--fs-lg); font-weight: 700; }
.po-lead .lead-via { margin-left: 6px; font-size: var(--fs-sm); color: var(--text-muted); }
/* 预计成本含税合计：与「含税合计」区分，用信息色（蓝/青）强调，一眼区分「销售额」与「预估成本」 */
.po-total.est-cost b { color: var(--info); }
/* 毛利率：正毛利绿色，负毛利标红（.neg 由前端按正负切换） */
.po-total.est-margin b { color: var(--ok); }
.po-total.est-margin b.neg { color: var(--danger); }

/* 表单分区标题（基础信息 / 收货信息 / 销售明细） */
.form-sec {
  margin: 18px 0 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: .02em;
  padding-left: 10px;
  border-left: 3px solid var(--border-brand);
}

/* 表单行：标签与控件的分隔与间距（系统设置 / 审批详情等复用） */
.form-row { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.form-row .lbl { font-size: 13px; font-weight: 600; color: var(--text-secondary); }
.form-row .inp { width: 100%; }
.form-row .form-val { font-size: var(--fs-md); color: var(--text-primary); padding: 2px 0; }
/* 横向布局：窄屏以下自动改为纵向堆叠 */
.form-row.inline { flex-direction: row; align-items: center; gap: 12px; }
.form-row.inline .lbl { width: 96px; flex-shrink: 0; }
.form-row.inline .inp { flex: 1; width: auto; }

/* 表单附件区（物料「资料图纸上传」等）：虚线外壳 + 已选文件列表 */
.file-zone {
    border: 1px dashed var(--border-light);
    border-radius: var(--r-sm);
    padding: 10px 12px;
    background: var(--bg-surface);
}
.file-zone-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.file-zone-head .b { cursor: pointer; }
.file-tip { flex: 1; min-width: 160px; line-height: 1.5; }
.file-list { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.file-empty { font-size: var(--fs-sm); color: var(--text-dim); padding: 2px; }
.file-zone.drag { border-color: var(--accent, #2563eb); background: var(--bg-elevated); }
/* 报销明细行的「报销证明」：单行紧凑上传条（参考简道云附件控件）
   —— 一个细边框输入框样式的条：左侧放已上传文件的类型小方块（图片显示缩略图），
      右侧一个上传图标；空态就是个空白框，点空白任意位置即可选文件。 */
.proof-cell { vertical-align: middle; padding-top: 2px; padding-bottom: 2px; }
.zone-mini {
    position: relative;
    display: flex; align-items: center; gap: 4px;
    min-height: 32px; padding: 2px 2px 2px 6px;
    border: 1px solid var(--border-light);
    border-radius: var(--r-sm);
    background: var(--bg-surface);
    cursor: pointer;
}
/* 整框热区：一个 opacity:0 的原生 file input 铺满整块。
   点框内任意空白 = 直接点 input 本身，浏览器原生弹选择框；
   不走脚本 input.click()、也不走 label[for] 关联（这两种在嵌套结构里都可能静默失效）。 */
.zone-mini .zone-file {
    position: absolute; top: 0; right: 0; bottom: 0; left: 0;
    width: 100%; height: 100%; opacity: 0; z-index: 0;
    cursor: pointer; font-size: 0; border: none; padding: 0;
}
.zone-mini .file-list,
.zone-mini .file-zone-head { position: relative; z-index: 1; }
.zone-mini .file-list { flex: 1 1 auto; min-width: 0; margin-top: 0; flex-direction: row; flex-wrap: wrap; gap: 3px; align-items: center; pointer-events: none; }
.zone-mini .file-empty { font-size: 11px; padding: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.zone-mini:focus-within { border-color: var(--accent, #2563eb); }
.zone-mini .file-zone-head { flex: 0 0 auto; order: 2; gap: 0; flex-wrap: nowrap; pointer-events: none; }
.zone-mini .mini-pick {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; border-radius: var(--r-sm);
    color: var(--text-dim);
}
.zone-mini:hover .mini-pick { color: var(--accent, #2563eb); background: var(--bg-elevated); }
/* 文件小方块：PDF 红标 / 图片缩略图，尺寸固定，不撑高行 */
.zone-mini .file-chip {
    position: relative; display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 22px; border-radius: 3px; overflow: hidden; flex: 0 0 auto;
    background: #e5484d; color: #fff; font-size: 8px; font-weight: 700; letter-spacing: .2px;
    pointer-events: auto;
}
.zone-mini .file-chip .chip-thumb { width: 100%; height: 100%; object-fit: cover; }
.zone-mini .file-chip.img { background: var(--bg-elevated); border: 1px solid var(--border-light); }
.zone-mini .file-chip .chip-open { position: absolute; inset: 0; }
.zone-mini .file-chip .chip-rm {
    position: absolute; top: -1px; right: -1px; width: 12px; height: 12px; padding: 0;
    border: none; border-radius: 50%; background: rgba(0,0,0,.55); color: #fff;
    font-size: 10px; line-height: 12px; text-align: center; cursor: pointer;
    opacity: 0; transition: opacity .12s;
}
.zone-mini .file-chip:hover .chip-rm { opacity: 1; }
.file-item {
    display: flex; align-items: center; gap: 10px;
    padding: 6px 8px;
    border: 1px solid var(--border-light); border-radius: var(--r-sm);
    background: var(--bg-elevated);
}
.file-ico { display: inline-flex; color: var(--text-dim); flex-shrink: 0; }
.file-thumb {
    width: 28px; height: 28px; flex-shrink: 0; object-fit: cover;
    border-radius: var(--r-sm); border: 1px solid var(--border-light);
}
.file-thumb-ext {
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 9px; font-weight: 700; color: var(--text-dim);
    background: var(--bg-dark);
}
.file-name {
    flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: var(--fs-sm); color: var(--text-primary); text-decoration: none;
}
.file-name:hover { color: var(--brand); text-decoration: underline; }
.file-size { flex-shrink: 0; font-size: var(--fs-sm); color: var(--text-dim); }
.file-item .b-icon { flex-shrink: 0; }

/* 列表单元格链接（如物料「物料编码」→ 打开详情弹框） */
.td-link {
    color: var(--brand);
    cursor: pointer;
    text-decoration: none;
}
.td-link:hover { text-decoration: underline; }

/* 采购明细导入弹窗 */
.imp-note { font-size: var(--fs-sm); color: var(--text-secondary); margin: 4px 0 12px 10px; line-height: 1.6; }
.imp-note b { color: var(--text-primary); font-weight: 600; }
.imp-actions { display: flex; gap: 8px; margin: 4px 0; }
.ta { width: 100%; min-height: 120px; resize: vertical; font-family: inherit; line-height: 1.55; }
.imp-preview { max-height: 300px; overflow: auto; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border-light); }
.imp-summary { margin-bottom: 8px; font-size: var(--fs-sm); color: var(--text-secondary); }
.row-bad { background: var(--danger-bg); }

/* 勾选 / 单选 */
.check {
    display: inline-flex; align-items: center; gap: 8px;
    cursor: pointer; user-select: none;
    font-size: var(--fs-md); color: var(--text-secondary);
}
.check input { position: absolute; opacity: 0; width: 0; height: 0; }
.check-box {
    width: 16px; height: 16px; flex-shrink: 0;
    border: 1.5px solid var(--border-light);
    border-radius: 4px;
    background: var(--bg-elevated);
    display: flex; align-items: center; justify-content: center;
    transition: var(--t-fast);
}
.check-box::after {
    content: '';
    width: 8px; height: 4px;
    border-left: 2px solid var(--white);
    border-bottom: 2px solid var(--white);
    transform: rotate(-45deg) scale(0);
    transition: transform var(--t-fast);
    margin-top: -2px;
}
.check:hover .check-box { border-color: var(--brand-light); }
.check input:checked ~ .check-box {
    background: var(--brand); border-color: var(--brand);
}
.check input:checked ~ .check-box::after { transform: rotate(-45deg) scale(1); }
.check input:indeterminate ~ .check-box { background: var(--brand); border-color: var(--brand); }

/* 勾选组：表单项里的多选（如「影响范围」可多选）。横向铺开，窄屏自动换行 */
.check-group {
    display: flex; flex-wrap: wrap; gap: 8px 20px;
    padding: 7px 10px; min-height: 34px;
    border: 1px solid var(--border); border-radius: var(--radius-sm, 6px);
    background: var(--bg-elevated);
}
.check-group:focus-within { border-color: var(--brand); }
.check-group .check { color: var(--text-primary); }
.check input:indeterminate ~ .check-box::after {
    width: 8px; height: 0;
    border-left: none; border-bottom: 2px solid var(--white);
    transform: rotate(0) scale(1); margin-top: 0;
}
.check input:disabled ~ .check-box { opacity: 0.4; cursor: not-allowed; }

/* 开关 */
.switch { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; user-select: none; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
    width: 34px; height: 19px; flex-shrink: 0;
    border-radius: var(--r-full);
    background: var(--bg-elevated);
    border: 1px solid var(--border-light);
    position: relative;
    transition: var(--t-fast);
}
.switch-track::after {
    content: '';
    position: absolute; top: 2px; left: 2px;
    width: 13px; height: 13px;
    border-radius: 50%;
    background: var(--text-muted);
    transition: var(--t-fast);
}
.switch input:checked ~ .switch-track {
    background: var(--brand); border-color: var(--brand);
}
.switch input:checked ~ .switch-track::after {
    transform: translateX(15px);
    background: var(--white);
}
.switch-label { font-size: var(--fs); color: var(--text-secondary); }

/* ============================================================
   按钮（补充 style.css 的 .btn 体系，尺寸更紧凑）
   ============================================================ */
.b {
    height: 34px;
    /* padding-bottom 2px：中文按字体度量天生低于行盒中心约 1px，底部多 2px 把内容区整体上移 1px 补偿，使文字视觉居中 */
    padding: 0 14px 2px;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    font-size: var(--fs-md);
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    transition: var(--t-fast);
    white-space: nowrap;
    position: relative;
    overflow: hidden;
}
.b i { font-size: var(--fs); }
.b:disabled { opacity: 0.45; cursor: not-allowed; pointer-events: none; }
.b-sm { height: 28px; padding: 0 10px 2px; font-size: var(--fs); }
.b-lg { height: 42px; padding: 0 24px 2px; font-size: var(--fs-lg); }
.b-block { width: 100%; }

.b-primary {
    background: var(--grad-brand);
    color: var(--white);
    box-shadow: var(--shadow-brand);
}
.b-primary:hover { transform: translateY(-2px); box-shadow: var(--shadow-brand-lg); }
.b-primary:active { transform: translateY(0); }

.b-ghost {
    background: rgba(255, 255, 255, 0.06);
    border-color: var(--border-light);
    color: var(--text-secondary);
    backdrop-filter: blur(8px);
}
.b-ghost:hover {
    border-color: rgba(255, 255, 255, 0.2);
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.1);
}

.b-text {
    background: transparent;
    color: var(--text-secondary);
    padding: 0 8px 2px;
}
.b-text:hover { color: var(--brand-light); background: var(--brand-bg); }

.b-danger {
    background: var(--danger-bg);
    border-color: rgba(255, 123, 114, 0.3);
    color: var(--danger);
}
.b-danger:hover { background: var(--danger); color: var(--bg-deep); border-color: var(--danger); }

.b-danger-ghost {
    background: transparent;
    border-color: var(--danger);
    color: var(--danger);
}
.b-danger-ghost:hover { background: var(--danger); color: var(--bg-deep); }

.b-warn {
    background: var(--warn-bg);
    border-color: rgba(255, 166, 87, 0.3);
    color: var(--warn);
}
.b-warn:hover { background: var(--warn); color: var(--bg-deep); border-color: var(--warn); }

.b-ok {
    background: var(--ok-bg);
    border-color: rgba(126, 232, 160, 0.3);
    color: var(--ok);
}
.b-ok:hover { background: var(--ok); color: var(--bg-deep); border-color: var(--ok); }

.b-icon { width: 30px; height: 30px; padding: 0; }
.b-icon.b-sm { width: 26px; height: 26px; }

.b-loading { color: transparent !important; pointer-events: none; }
.b-loading::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 14px; height: 14px;
    margin: -7px 0 0 -7px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-top-color: var(--white);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.b-group { display: inline-flex; gap: 6px; }

/* ============================================================
   数据表格
   ============================================================ */
.table-wrap { overflow-x: auto; }
table.tb {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: var(--fs-md);
}
table.tb.process-tbl { table-layout: fixed; }
table.tb thead th {
    position: sticky; top: 0; z-index: 5;
    background: var(--bg-elevated);
    padding: 10px 14px;
    text-align: left;
    font-size: var(--fs-sm);
    font-weight: 700;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    text-transform: uppercase;
    white-space: nowrap;
    border-bottom: 1px solid var(--border-light);
    user-select: none;
}
table.tb thead th.sortable { cursor: pointer; transition: var(--t-fast); }
table.tb thead th.sortable:hover { color: var(--text-primary); }
table.tb thead th .sort-i { margin-left: 5px; font-size: 9px; opacity: 0.4; }
table.tb thead th.sorted-asc .sort-i,
table.tb thead th.sorted-desc .sort-i { opacity: 1; color: var(--brand-light); }

table.tb tbody td {
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    color: var(--text-secondary);
    vertical-align: middle;
}
table.tb tbody tr { transition: background var(--t-fast); }
table.tb tbody tr:hover td { background: rgba(255, 255, 255, 0.028); }
table.tb tbody tr.selected td { background: var(--brand-bg); }
table.tb tbody tr.row-zero td { background: var(--danger-bg); }
table.tb tbody tr:last-child td { border-bottom: none; }
table.tb tbody tr.clickable { cursor: pointer; }

table.tb .td-main { color: var(--text-primary); font-weight: 600; }
table.tb .td-ellipsis { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
table.tb .td-code {
    font-family: var(--mono);
    font-size: var(--fs);
    color: var(--brand-light);
    letter-spacing: -0.2px;
}
table.tb .td-c { text-align: center; padding-left: 0; padding-right: 0; }
/* 列表行勾选列：窄、居中，复选框自带间距；表头全选框同规格 */
table.tb .td-sel { width: 42px; min-width: 42px; text-align: center; padding-left: 0; padding-right: 0; }
table.tb thead th.td-sel { background: var(--bg-elevated); }
table.tb .td-sel input[type="checkbox"], table.tb thead th.td-sel input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; accent-color: var(--brand); vertical-align: middle; }
/* 生产退料明细：固定列宽（选择框30px固定 + 其余百分比，合计100%分配给剩余宽度） */
table.tb.sm.mfg-rt-items { table-layout: fixed; }
table.tb.sm.mfg-rt-items td, table.tb.sm.mfg-rt-items th { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 物料列含编码+名称，允许换行避免被压成一团（其余数字/短文本保持 nowrap） */
table.tb.sm.mfg-rt-items td:nth-child(2) { white-space: normal; word-break: break-all; }
table.tb.sm.mfg-rt-items .td-act { white-space: nowrap; }
table.tb .td-num {
    font-family: var(--mono);
    text-align: right;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}
table.tb .td-dim { color: var(--text-muted); font-size: var(--fs); }
table.tb .td-unit { color: var(--text-secondary); font-size: var(--fs); white-space: nowrap; }
/* 行序号列（BOM 子项等明细编辑表最左侧）：居中、弱化、等宽数字，增删行后由 JS 重排 */
table.tb .td-idx { text-align: center; color: var(--text-muted); font-size: var(--fs); font-variant-numeric: tabular-nums; white-space: nowrap; }
table.tb .td-act { text-align: right; white-space: nowrap; }
/* 生产入库页：操作列右对齐（覆盖 #tbl 的居中规则） */
table.tb.qm-stockin-tbl tbody td.td-act,
table.tb.qm-stockin-tbl thead th.td-act { text-align: center; }
/* 操作列内的图标按钮组随列右对齐（td-act 的 text-align 对 flex 子元素无效，需 justify-content） */
table.tb tbody td.td-act .row-acts { justify-content: flex-end; }
/* 库存查询「查看」列：单图标按钮，居中而非右对齐 */
table.tb#tbl thead th.th-act,
table.tb#tbl tbody td.td-act { text-align: center; }
table.tb .td-nowrap { white-space: nowrap; }
/* 长内容单行省略：配合 .td-nowrap 使用，超宽列不再把整表撑出横向滚动（配合 title 悬停看全文） */
table.tb .td-ellip { max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
/* 文本列单行省略（价格差异调整「调整原因」等）：配方与 .td-ellip 相同。
   ⚠️ max-width 不可省——实测（chromium 无头）：自动布局表格里只写 nowrap+overflow+ellipsis
   不触发省略，列会被长文本撑到 ~40%（30 字原因文本 → 462px/39.9%），配 max-width 后
   列稳定在声明百分比宽度并正常省略（scrollWidth>clientWidth 时出省略号） */
table.tb .t-ellipsis { max-width: 180px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb .col-check { width: 40px; text-align: center; }
/* 库存明细弹框：仓库/库位分布表固定列宽（仓库15/库位15/数量15/锁定15/含税单价20/含税总额20，合计100%） */
table.tb.sm.stock-dist { table-layout: fixed; }
table.tb.sm.stock-dist thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.sm.stock-dist tbody td:not(.td-act) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* BOM 物料清单列表：固定百分比列宽（物料编码10/物料名称40/版本10/子项10/设计工时10/状态10/操作10，合计100%） */
table.tb.bom-list { table-layout: fixed; }
table.tb.bom-list thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.bom-list tbody td:not(.td-act) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.wh-warehouse { table-layout: fixed; }
table.tb.wh-warehouse thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.wh-warehouse tbody td:not(.td-act) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb .col-idx { width: 52px; color: var(--text-dim); font-family: var(--mono); font-size: var(--fs); }

/* 销售出库列表：固定百分比列宽（出库单号12/销售单号12/客户22/出库仓库12/出库日期12/数量10/状态10/操作10） */
table.tb.iss-tbl { table-layout: fixed; }
table.tb.iss-tbl thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.iss-tbl tbody td:not(.td-act) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 入库/出入库流水列表：固定百分比列宽（单据号9.5/业务时间14.5/类型9/物料编码9.5/物料名称16.5或24.5/
   仓库7.5/库位8.5/变动数量9/结存数量8.5/单价8，合计100%）
   宽度按 1440 视口（表格 ~1160px）下各列内容 + 左右 14px 内边距恰好放下校准，
   保证每列左右留白一致；容器更窄时由 min-width 触发横向滚动而非列内省略裁字 */
table.tb.led-tbl { table-layout: fixed; min-width: 1155px; }
table.tb.led-tbl thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.led-tbl tbody td:not(.td-act) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 采购订单列表：固定百分比列宽（采购单号7/供应商20/预计到货7/采购物料25/数量8/含税合计8/状态12/操作13）
   状态列标签强制单行，避免双标签换行导致行高不统一、行分割线错位 */
table.tb.pur-tbl { table-layout: fixed; }
table.tb.pur-tbl thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.pur-tbl tbody td:not(.td-act):not(.status-cell) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.pur-tbl tbody td.status-cell { display: table-cell; white-space: nowrap; vertical-align: middle; }
table.tb.pur-tbl tbody td.status-cell .tag { margin-right: 4px; }
table.tb.pur-tbl tbody td.status-cell .tag:last-child { margin-right: 0; }

/* 销售订单列表：固定百分比列宽（多选4/单号7/客户15/预计交货7/物料27/数量6/含税合计10/状态8/操作16）
   状态列标签强制单行，避免双标签换行导致行高不统一、行分割线错位 */
table.tb.sal-tbl { table-layout: fixed; }
table.tb.sal-tbl thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.sal-tbl tbody td:not(.td-act):not(.status-cell) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.sal-tbl tbody td.status-cell { display: table-cell; white-space: nowrap; vertical-align: middle; }
table.tb.sal-tbl tbody td.status-cell .tag { margin-right: 4px; }
table.tb.sal-tbl tbody td.status-cell .tag:last-child { margin-right: 0; }

/* 生产工单列表：固定百分比列宽（工单号15/成品35/计划数量8/已产数量8/状态14/计划交期8/操作12，合计 100%）
   状态列标签强制单行，避免多标签换行导致行高不统一、行分割线错位 */
table.tb.mfg-o-tbl { table-layout: fixed; }
table.tb.mfg-o-tbl thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.mfg-o-tbl tbody td:not(.td-act):not(.status-cell) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.mfg-o-tbl tbody td.status-cell { display: table-cell; white-space: nowrap; vertical-align: middle; }
/* 状态列 20%：3 tag 极端（状态 + SN + 齐料）≈204px 完整显示——这类「在产未领完」工单排序最靠前，标签不能被裁；
   超出时尾部省略，而非溢出盖住「计划交期」列（td 默认 overflow:visible） */
table.tb.mfg-o-tbl tbody td.status-cell { overflow: hidden; text-overflow: ellipsis; }
table.tb.mfg-o-tbl tbody td.status-cell .tag { margin-right: 4px; }
table.tb.mfg-o-tbl tbody td.status-cell .tag:last-child { margin-right: 0; }
/* 操作列按钮最多 7 个（查看/打印/编辑/下达/报工/取消/删除），.fc 默认 nowrap，
   窄屏下后面的按钮会被裁掉（表现为「功能没了」）→ 允许换行兜底 */
table.tb.mfg-o-tbl tbody td.td-act .row-acts { flex-wrap: wrap; }

/* 劳动合同列表（与 sal-tbl 保持一致） */
table.tb.hr-tbl { table-layout: fixed; }
table.tb.hr-tbl thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.hr-tbl tbody td:not(.td-act):not(.status-cell) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.hr-tbl tbody td.status-cell { display: table-cell; white-space: nowrap; vertical-align: middle; }
table.tb.hr-tbl tbody td.status-cell .tag { margin-right: 4px; }
table.tb.hr-tbl tbody td.status-cell .tag:last-child { margin-right: 0; }

/* 个人报销列表：8 列等宽，每列 12.5%（合计 100%）
   fixed 布局避免自动布局按内容比例分配余量导致各列留白不均；
   列宽小于内容时按 ellipsis 截断（部门/报销人等长文本），配合 title 悬停看全文。
   状态列标签强制单行（仅一个当前状态标签），避免换行导致行高不统一。
   ⚠️ 操作列 12.5%（约 145px @1440）放不下 5 个 30px 图标按钮（约 180px）→ 允许换行兜底，
      避免窄屏下按钮被裁掉表现为「功能没了」（同 mfg-o-tbl 处理） */
table.tb.reimb-tbl { table-layout: fixed; }
table.tb.reimb-tbl thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.reimb-tbl tbody td:not(.td-act):not(.status-cell) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.reimb-tbl tbody td.status-cell { display: table-cell; white-space: nowrap; vertical-align: middle; }
table.tb.reimb-tbl tbody td.status-cell .tag:last-child { margin-right: 0; }
table.tb.reimb-tbl tbody td.td-act .row-acts { flex-wrap: wrap; }
/* 价税合计 / 支付方式 / 状态 三列右对齐（表头与单元格同向，读数列对齐到列尾） */
table.tb.reimb-tbl thead th.ta-r,
table.tb.reimb-tbl tbody td.ta-r { text-align: right; }

table.tb.dense tbody td { padding: 7px 12px; }
/* 采购订单详情：采购明细固定列宽（13 列，按「该列内容/表头实测宽 + 等量左右留白」分配，合计 100%）
   物料编码7.6/扶梯物料号9.3/直梯物料号9.4/物料名称16.8/单位4/缺料4.4/数量6.9/到货6.9/
   不含税单价7.9/税率5.6/含税金额6.8/价格变动6.7/交付日期7.7
   仅作用于 detail 明细表，不影响共用 .tb.sm 的其他表格 */
table.tb.sm.pur-dtl-items { table-layout: fixed; }
/* 列多且窄：左右内边距统一收到 10px（默认 14px），13 列共省出 104px 给内容；
   每列「内容宽 + 2×10px 留白」口径一致，因此各列视觉左右边距相同 */
table.tb.sm.pur-dtl-items thead th { padding-left: 10px; padding-right: 10px; }
table.tb.sm.pur-dtl-items tbody td { padding-left: 10px; padding-right: 10px; }
table.tb.sm.pur-dtl-items thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.sm.pur-dtl-items tbody td:not(.td-act) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 明细表「物料名称」单元格：最多 3 行 + 省略号，完整内容由 td 的 title 悬停查看。
   共用类 .dtl-nm —— 采购订单详情(pur-dtl-items) 与 销售订单详情(sal-dtl-items) 同口径。
   ⚠ 钳制容器必须是内层 div：td 自身设 display:-webkit-box 会退出 table-cell，
   导致该列不被整行等高拉伸、行分隔线错位（见 .workbuddy/memory 铁律）。 */
table.tb.sm tbody td .dtl-nm {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3;
  overflow: hidden; word-break: break-all; overflow-wrap: anywhere;
}
/* 采购订单详情 物料名称列（第4列）：允许换行，列宽仍锁 18%（table-layout: fixed），不撑宽整表。
   实测（xxw 弹框 1280 / 表格 1238 / 列 223px / 内容区 203px / 字号 14px）：
   一行约 14 个汉字，或约 22 个英数字符（ASCII 9.0px、空格 3.83px），行高 22.4px；
   3 行上限 ≈ 42 个汉字 / 66 个英数字符。窗口更窄时按比例减少。 */
table.tb.sm.pur-dtl-items tbody td:nth-child(4) { white-space: normal; word-break: break-all; overflow-wrap: anywhere; overflow: visible; text-overflow: clip; }
/* 销售订单详情：销售明细固定列宽（12 列，口径与 pur-dtl-items 一致）
   物料编码8.8/扶梯物料号8.0/直梯物料号7.6/物料名称17.5/单位4.0/数量7.0/已发数量7.2/
   单价(不含税)9.0/预计单位成本8.6/税率4.4/含税金额7.6/备注10.3 —— 合计 100%。
   ⚠ 2026-10-29 前这 12 列合计 104%，table-layout:fixed 下浏览器按比例压缩，导致表头与
   物料编码普遍被切（「单价(不…」「预计单…」「80000324…」）；现已归一到 100%，并把详情
   弹框由 xw(1080) 放到 xxw(1280)（与采购详情同宽）。
   实测（xxw / 表格 1238px）：除「直梯物料号」长料号与备注长文本按设计走 title 兜底外，
   表头全部完整；物料编码 109px / 单价 111px / 预计成本 106px / 含税金额 94px 均不截断。
   仅作用于 detail 明细表，不影响共用 .tb.sm 的其他表格 */
table.tb.sm.sal-dtl-items { table-layout: fixed; }
table.tb.sm.sal-dtl-items thead th { padding-left: 10px; padding-right: 10px; }
table.tb.sm.sal-dtl-items tbody td { padding-left: 10px; padding-right: 10px; }
table.tb.sm.sal-dtl-items thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.sm.sal-dtl-items tbody td:not(.td-act) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 销售订单详情 物料名称列（第4列）：与采购详情同口径 —— 最多 3 行 + 悬停看全（.dtl-nm）。
   实测（xxw 弹框 / 表格 1238px）：名称列 17.5% ≈ 217px、内容区 197px，
   一行约 14 个汉字（约 21 个英数字符）；3 行上限 ≈ 42 个汉字 / 63 个字符。
   列宽固定，换行不撑宽整表。 */
table.tb.sm.sal-dtl-items tbody td:nth-child(4) { white-space: normal; word-break: break-all; overflow-wrap: anywhere; overflow: visible; text-overflow: clip; }
/* 采购订单「修改交付日期」弹框明细表：固定列宽 + 名称换行列；其余列 ellipsis（含 date input 不溢出）。
   口径与 pur-dtl-items 一致：列宽 = 内容 + 左右各约 14px，物料名称(第2列)吸收余量并允许换行 */
table.tb.sm.pur-dd-items { table-layout: fixed; }
table.tb.sm.pur-dd-items thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.sm.pur-dd-items tbody td:not(:nth-child(2)) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.sm.pur-dd-items tbody td:nth-child(2) { white-space: normal; word-break: break-word; overflow: visible; }
table.tb.sm.pur-dd-items tbody td.inp-cell { overflow: visible; padding: 6px 8px; }
table.tb.sm.pur-dd-items tbody td.inp-cell .inp { width: 100%; box-sizing: border-box; }
table.tb.dense thead th { padding: 7px 12px; }
/* 库位管理弹框：库位列表固定列宽（编码20/名称40/库区40；操作列自适应，不加 width）。仅作用于 loc-tbl */
table.tb.dense.loc-tbl { table-layout: fixed; }
table.tb.dense.loc-tbl thead th:not(.td-act) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.dense.loc-tbl tbody td:not(.td-act) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 行内操作按钮：默认淡出，hover 行时点亮 */
table.tb tbody tr .row-acts { opacity: 0.55; transition: opacity var(--t-fast); }
table.tb tbody tr:hover .row-acts { opacity: 1; }

/* ============================================================
   状态徽章
   ============================================================ */
.tag {
    display: inline-flex; align-items: center; gap: 5px;
    vertical-align: middle;
    height: 21px;
    padding: 0 9px;
    border-radius: var(--r-full);
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: 0.3px;
    white-space: nowrap;
    border: 1px solid transparent;
}
.tag::before {
    content: '';
    width: 5px; height: 5px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}
.tag.no-dot::before { display: none; }
.tag-ok { background: var(--ok-bg); color: var(--ok); border-color: rgba(126, 232, 160, 0.22); }
.tag-warn { background: var(--warn-bg); color: var(--warn); border-color: rgba(255, 166, 87, 0.22); }
.tag-danger { background: var(--danger-bg); color: var(--danger); border-color: rgba(255, 123, 114, 0.22); }
.tag-info { background: var(--info-bg); color: var(--info); border-color: rgba(121, 192, 255, 0.22); }
.tag-pending { background: var(--pending-bg); color: var(--pending); border-color: rgba(227, 179, 65, 0.22); }
/* 可点击的齐料/缺料标签（列表、生产看板）：点此跳生产领料页预填本工单 */
.tag-clickable { cursor: pointer; transition: filter 0.12s ease; }
.tag-clickable:hover { filter: brightness(0.94); }
.tag-clickable:active { filter: brightness(0.86); }

/* 销售订单「可发提示」弹窗 */
.sal-ready-pop { display: flex; flex-direction: column; gap: 12px; }
.sal-ready-banner { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 12px; border-radius: 8px; line-height: 1.5; }
.sal-ready-banner.ok { background: var(--ok-bg); color: var(--ok); }
.sal-ready-banner.warn { background: var(--warn-bg); color: var(--warn); }
.sal-ready-banner .tag { flex: none; }
.sal-ready-sum { font-size: 13px; }
.sal-ready-pop .tb { margin: 0; }
.sal-ready-pop .tb th, .sal-ready-pop .tb td { padding: 7px 10px; }

/* 列表状态列：业务状态 + 发票标签并排展示；table-cell 避免 fixed 表格中 flex td 行高错位 */
.tb td.status-cell { display: table-cell; white-space: nowrap; vertical-align: middle; }
.tb td.status-cell .tag { margin-right: 4px; }
.tb td.status-cell .tag:last-child { margin-right: 0; }
.tag-special { background: var(--special-bg); color: var(--special); border-color: rgba(210, 168, 255, 0.22); }
.tag-brand { background: var(--brand-bg); color: var(--brand-light); border-color: var(--border-brand); }
/* 主色标签（终态如「已付款」）：三处 STATUSTAG 里用到 primary，此前 CSS 未定义 →
   只有 .tag 基础样式（透明底 + 无文字色），浅色主题下看起来就是白/灰一片 */
.tag-primary { background: var(--brand-bg); color: var(--brand-light); border-color: var(--border-brand, rgba(15, 82, 186, 0.35)); }
.tag-mute { background: rgba(255, 255, 255, 0.06); color: var(--text-muted); border-color: var(--border-light); }
/* 停用：红色 + 禁止符号（圆环+斜杠），比纯圆点更贴合「禁用/停用」语义 */
.tag-stop { background: var(--danger-bg); color: var(--danger); border-color: rgba(255, 123, 114, 0.22); }
.tag-stop .tag-ico { width: 9px; height: 9px; flex-shrink: 0; }

/* 供应商列表：严格按比例列宽（编码8% 名字32% 税号15% 联系人8% 联系电话12% 评级5% 状态10% 操作15%） */
table.tb.wh-supplier { table-layout: fixed; }
table.tb.wh-supplier thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.wh-supplier tbody td:not(.td-act):not(.status-cell) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.wh-supplier tbody td.status-cell { white-space: nowrap; }

/* 客户列表：严格按比例列宽（编码8% 名字30% 税号15% 联系人8% 联系电话11% 评级8% 状态8% 操作17%） */
table.tb.wh-customer { table-layout: fixed; }
table.tb.wh-customer thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.wh-customer tbody td:not(.td-act):not(.status-cell) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.wh-customer tbody td.status-cell { white-space: nowrap; }

/* 缺料分析(MRP)列表：严格按比例列宽。
   列宽由 pages/mrp.js 的 <th style="width:N%"> 定义，共 12 列、合计 100%
   （2026-10-16 新增「扶梯物料号/直梯物料号」两列、移除「来源/采购建议量/在制数/货期」四列后重新分配）：
   勾选4 编码9 名称16 扶梯8 直梯8 供应商12.5 单位5 缺料7.5 毛需求7.5 库存7.5 在途7.5 可用7.5
   table-layout:fixed 下百分比按比例生效，故各列 width 之和必须正好 100%，
   否则右侧留白或撑出横向滚动条（tests/frontend.test.js 有守卫）。
   表头/单元格统一 nowrap + ellipsis：超宽内容省略号截断，完整内容用 title 悬停查看。
   数字列(.num)与单位列(.uom-col)例外：左右内边距收窄为 6px/8px（数字右对齐、单位仅 1~3 字符，
   无需 14px 呼吸距）。数字列另给 min-width:88px 兜底——窗口再窄也优先保数字完整
   （表格整体横向滚动，不截数字）；88px = 千分位 9 字符（如 10,709.00 ≈72px）+ 14px 内边距 + 2px 余量。
   单位列收窄内边距后 5% 宽（约 46~58px）即可容纳「单位」表头与「PCS」等值。 */
table.tb.mrp-tbl { table-layout: fixed; }
table.tb.mrp-tbl thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.mrp-tbl tbody td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.mrp-tbl thead th.num { min-width: 88px; padding-left: 6px; padding-right: 8px; }
table.tb.mrp-tbl tbody td.num { padding-left: 6px; padding-right: 8px; }
table.tb.mrp-tbl thead th.uom-col { padding-left: 6px; padding-right: 8px; }
table.tb.mrp-tbl tbody td.uom-col { padding-left: 6px; padding-right: 8px; }
/* 库存建议表：百分比列宽严格生效(table-layout:fixed)，内容超长按列宽省略号截断；
   th/td 左右 padding 统一继承 .tb 的 14px，使每列左右边距一致 */
table.tb.pur-sa-tbl { table-layout: fixed; }
table.tb.pur-sa-tbl thead th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.pur-sa-tbl tbody td:not(.td-act) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
table.tb.pur-sa-tbl tbody td.td-ellipsis { max-width: none; }
/* 物料名称：2 行截断（覆盖 mrp-tbl 全局 nowrap+ellipsis），不影响其余数字列 */
table.tb.mrp-tbl tbody td.mat-name {
  white-space: normal;
  overflow: hidden;
  vertical-align: top;
}
table.tb.mrp-tbl tbody td.mat-name .clamp2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-all;
  line-height: 1.4;
}

/* ============================================================
   分页
   ============================================================ */
.pager {
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px; padding: 12px 16px;
    border-top: 1px solid var(--border);
    flex-wrap: wrap;
}
.pager-info { font-size: var(--fs); color: var(--text-muted); }
.pager-info b { color: var(--text-primary); font-family: var(--mono); font-weight: 700; }
.pager-ctrl { display: flex; align-items: center; gap: 5px; }
.pg {
    min-width: 28px; height: 28px;
    padding: 0 7px 2px;
    border: 1px solid var(--border-light);
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--text-secondary);
    font-size: var(--fs);
    font-family: var(--mono);
    cursor: pointer;
    transition: var(--t-fast);
    display: inline-flex; align-items: center; justify-content: center;
}
.pg:hover:not(:disabled) { border-color: var(--brand); color: var(--brand-light); background: var(--brand-bg); }
.pg.active {
    background: var(--grad-brand);
    border-color: transparent;
    color: var(--white);
    font-weight: 700;
    box-shadow: var(--shadow-brand);
}
.pg:disabled { opacity: 0.3; cursor: not-allowed; }
.pg-dots { color: var(--text-dim); padding: 0 3px; font-size: var(--fs); }
.pager .sel {
  width: auto; height: 28px; font-size: var(--fs); padding: 0 26px 2px 9px;
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
}

/* 分页：每页条数自定义下拉（根本解决 Windows Chrome/Edge 原生 select 箭头无法隐藏问题） */
.ps-select { position: relative; display: inline-block; vertical-align: middle; }
.pager .ps-select-trigger.sel {
  width: auto; min-width: 66px; height: 28px;
  padding: 0 26px 2px 9px;
  font-size: var(--fs);
  text-align: left;
  display: inline-flex; align-items: center;
  background-color: var(--bg-elevated);
}
.pager .ps-select-trigger.sel:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px rgba(15, 82, 186, 0.15); background: var(--bg-surface); }
.ps-select-menu {
  position: absolute; bottom: calc(100% + 4px); right: 0;
  min-width: 100%;
  background: var(--bg-elevated);
  border: 1px solid var(--border-light);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow);
  z-index: 100;
  overflow: hidden;
}
.ps-select-item {
  padding: 8px 12px;
  cursor: pointer;
  color: var(--text-primary);
  font-size: var(--fs);
  white-space: nowrap;
}
.ps-select-item:hover { background: var(--brand-bg); color: var(--brand-light); }
.ps-select-item[data-selected] { background: var(--brand-bg-strong); color: var(--brand-light); font-weight: 700; }
.ps-custom-wrap { padding: 8px; }
.ps-custom-wrap .ps-custom-input { width: 92px; }
.ps-custom-tip { margin-top: 6px; font-size: 12px; color: var(--text-dim); white-space: nowrap; }

/* ============================================================
   Tab
   ============================================================ */
.tabs {
    display: flex; gap: 2px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 18px;
    overflow-x: auto;
}
.tab {
    padding: 9px 16px 10px;
    font-size: var(--fs-md);
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    position: relative;
    transition: var(--t-fast);
    white-space: nowrap;
    background: transparent; border: none;
    font-family: inherit;
}
.tab::after {
    content: '';
    position: absolute; bottom: -1px; left: 0; right: 0;
    height: 2px; background: var(--grad-brand);
    transform: scaleX(0);
    transition: transform var(--t-fast);
}
.tab:hover { color: var(--text-primary); }
.tab.active { color: var(--brand-light); }
.tab.active::after { transform: scaleX(1); }
.tab-count {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: var(--r-full);
    background: rgba(255, 255, 255, 0.08);
    font-size: 10px;
    font-family: var(--mono);
}
.tab.active .tab-count { background: var(--brand-bg-strong); color: var(--brand-light); }

/* ============================================================
   模态框
   ============================================================ */
.mask {
    position: fixed; inset: 0; z-index: 2000;
    background: rgba(0, 0, 0, 0.62);
    backdrop-filter: blur(3px);
    display: flex; align-items: center; justify-content: center;
    padding: 24px;
    opacity: 0;
    animation: maskIn 0.22s var(--ease-out-quart) forwards;
}
@keyframes maskIn { to { opacity: 1; } }
.mask.closing { animation: maskOut 0.18s var(--ease-out-quart) forwards; }
@keyframes maskOut { to { opacity: 0; } }
/* 叠层子弹窗的透明遮罩：不吃掉下层弹窗的可见度（openModal 的 transparentMask:true） */
.mask.mask-clear { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
/* alignTo 定位：垂直方向改为顶端对齐，padding-top 由 JS 按锚点动态计算；
   水平仍保持居中（mask 是 flex 纵轴为 cross-axis，故用 align-items，勿用 stretch） */
.mask.mask-align-top { align-items: flex-start; }

.modal {
    width: 100%;
    max-width: 520px;
    max-height: calc(100vh - 48px);
    background: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-xl);
    display: flex; flex-direction: column;
    transform: translateY(16px) scale(0.98);
    animation: modalIn 0.3s var(--ease-out-expo) forwards;
}
@keyframes modalIn { to { transform: translateY(0) scale(1); } }
.mask.closing .modal { animation: modalOut 0.18s var(--ease-out-quart) forwards; }
@keyframes modalOut { to { transform: translateY(10px) scale(0.98); opacity: 0; } }

.modal-w { max-width: 760px; }
.modal-xw { max-width: 1080px; }
/* 超宽弹框：列数多的明细表（如采购订单详情的 13 列明细）需要更多横向空间 */
.modal-xxw { max-width: 1280px; }
/* 全屏弹框：占满整个视口（含遮罩去掉内边距） */
.mask.is-fullscreen-mask { padding: 0; }
.modal.is-fullscreen {
  width: 100%;
  max-width: none;
  max-height: none;
  height: 100%;
  border-radius: 0;
}
.modal-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.modal-title { font-size: var(--fs-lg); font-weight: 700; color: var(--text-primary); }
.modal-head-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.modal-action {
  width: 28px; height: 28px;
  border: none; border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-size: var(--fs-md);
  display: flex; align-items: center; justify-content: center;
  transition: var(--t-fast);
}
.modal-action:hover { background: rgba(255, 255, 255, 0.08); color: var(--text-primary); }
.modal-close {
    width: 28px; height: 28px;
    border: none; border-radius: var(--r-sm);
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    font-size: var(--fs-md);
    display: flex; align-items: center; justify-content: center;
    transition: var(--t-fast);
}
.modal-close:hover { background: rgba(255, 255, 255, 0.08); color: var(--text-primary); }
.modal-body { padding: 20px; overflow-y: auto; flex: 1; }
/* 弹框内所有文字统一白色（功能性语义色：必填星号/错误/状态标签除外） */
.modal-body { color: var(--white); }
.modal-body .field-label,
.modal-body .field-hint,
.modal-body .inp[readonly],
.modal-body .inp::placeholder,
.modal-body .combobox-empty,
.modal-body table.tb thead th,
.modal-body table.tb tbody td,
.modal-body .td-dim,
.modal-body .td-code,
.modal-body .col-idx,
.modal-body .con-meta,
.modal-body .con-empty,
.modal-body .modal-close {
  color: var(--white);
}
/* 明细列表（弹框内）表头：半透明毛玻璃底色，避免滚动时与内容重叠看不清
   sticky 表头若不遮挡，内容会从下方透出造成叠加。用 rgba 半透明 + backdrop-filter 模糊营造质感，
   深色底 #1C2333→rgba(28,35,51,.72)，白天底 #F2F5FA→rgba(242,245,250,.72)。 */
.modal-body table.tb thead th {
  background: rgba(28, 35, 51, 0.72);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
[data-theme="light"] .modal-body table.tb thead th {
  background: rgba(242, 245, 250, 0.72);
}
.modal-body table.tb thead th { box-shadow: 0 1px 0 var(--border-light); }
/* 明细表：列间距收窄 50%（水平内边距 14px → 7px，垂直内边距不变） */
.modal-body table.tb thead th { padding-left: 7px; padding-right: 7px; }
.modal-body table.tb tbody td { padding-left: 7px; padding-right: 7px; }
/* 弹框内日期字段输入框右对齐 */
.modal-body .date-field { text-align: left; }
.date-wrap { position: relative; display: block; }
.date-wrap > input[type="date"] { width: 100%; }
.date-overlay {
    position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
    color: var(--text-dim); font-size: var(--fs-md);
    pointer-events: none; user-select: none;
    transition: opacity var(--t-fast);
    z-index: 1;
}
/* 隐藏 Chrome 原生日期段（年/月/日），空值时始终透明，让 yyyy/mm/dd overlay 不被重叠 */
.date-wrap.is-empty input[type="date"]::-webkit-datetime-edit,
.date-wrap.is-empty input[type="date"]::-webkit-datetime-edit-fields-wrapper,
.date-wrap.is-empty input[type="date"]::-webkit-datetime-edit-text,
.date-wrap.is-empty input[type="date"]::-webkit-datetime-edit-year-field,
.date-wrap.is-empty input[type="date"]::-webkit-datetime-edit-month-field,
.date-wrap.is-empty input[type="date"]::-webkit-datetime-edit-day-field { color: transparent; opacity: 0; }
/* overlay 显隐由 JS inline style 控制（onchange/onfocus/onblur），CSS 仅负责定位与样式 */
.modal-foot {
    display: flex; align-items: center; justify-content: flex-end;
    gap: 9px;
    padding: 14px 20px;
    border-top: 1px solid var(--border);
    flex-shrink: 0;
}
.modal-foot.between { justify-content: space-between; }

/* 确认框图标 */
.confirm-body { display: flex; gap: 14px; align-items: flex-start; }
.confirm-icon {
    width: 38px; height: 38px; flex-shrink: 0;
    border-radius: var(--r-full);
    display: flex; align-items: center; justify-content: center;
    font-size: var(--fs-lg);
}
.confirm-icon.warn { background: var(--warn-bg); color: var(--warn); }
.confirm-icon.danger { background: var(--danger-bg); color: var(--danger); }
.confirm-icon.info { background: var(--brand-bg); color: var(--brand-light); }
.confirm-text h4 { font-size: var(--fs-md); font-weight: 700; color: var(--text-primary); margin-bottom: 5px; }
.confirm-text p { font-size: var(--fs); color: var(--text-secondary); line-height: 1.65; }

/* ============================================================
   抽屉
   ============================================================ */
.drawer-mask { align-items: stretch; justify-content: flex-end; padding: 0; }
.drawer {
    width: 100%;
    max-width: 520px;
    height: 100vh;
    max-height: 100vh;
    background: var(--bg-surface);
    border-left: 1px solid var(--border-light);
    border-radius: 0;
    box-shadow: var(--shadow-xl);
    display: flex; flex-direction: column;
    transform: translateX(100%);
    animation: drawerIn 0.35s var(--ease-out-expo) forwards;
}
@keyframes drawerIn { to { transform: translateX(0); } }
.mask.closing .drawer { animation: drawerOut 0.22s var(--ease-out-quart) forwards; }
@keyframes drawerOut { to { transform: translateX(100%); } }
.drawer-w { max-width: 760px; }

/* ============================================================
   下拉菜单
   ============================================================ */
.dd { position: relative; display: inline-block; }
.dd-menu {
    position: absolute;
    top: calc(100% + 6px); right: 0;
    min-width: 172px;
    padding: 5px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-light);
    border-radius: var(--r-sm);
    box-shadow: var(--shadow-lg);
    z-index: 1500;
    opacity: 0;
    transform: translateY(-6px);
    pointer-events: none;
    transition: opacity var(--t-fast), transform var(--t-fast);
}
.dd.open .dd-menu { opacity: 1; transform: translateY(0); pointer-events: auto; }
.dd-item {
    display: flex; align-items: center; gap: 9px;
    padding: 8px 10px 10px;
    border-radius: 5px;
    font-size: var(--fs-md);
    color: var(--text-secondary);
    cursor: pointer;
    transition: var(--t-fast);
    white-space: nowrap;
}
.dd-item i { width: 14px; font-size: var(--fs); text-align: center; }
.dd-item:hover { background: rgba(255, 255, 255, 0.06); color: var(--text-primary); }
.dd-item.danger { color: var(--danger); }
.dd-item.danger:hover { background: var(--danger-bg); }
.dd-sep { height: 1px; background: var(--border); margin: 5px 0; }
.dd-label {
    padding: 7px 10px 4px;
    font-size: var(--fs-xs);
    color: var(--text-dim);
    letter-spacing: 1px;
    text-transform: uppercase;
    font-weight: 700;
}

/* ============================================================
   空状态 / 加载
   ============================================================ */
.empty {
    padding: 56px 20px;
    text-align: center;
}
.empty-icon {
    width: 60px; height: 60px;
    margin: 0 auto 16px;
    border-radius: var(--r-full);
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--border);
    display: flex; align-items: center; justify-content: center;
    font-size: 24px;
    color: var(--text-dim);
}
.empty h4 { font-size: var(--fs-md); font-weight: 600; color: var(--text-secondary); margin-bottom: 6px; }
.empty p { font-size: var(--fs); color: var(--text-dim); margin-bottom: 18px; }

.skeleton {
    background: linear-gradient(90deg,
        rgba(255, 255, 255, 0.03) 25%,
        rgba(255, 255, 255, 0.07) 50%,
        rgba(255, 255, 255, 0.03) 75%);
    background-size: 200% 100%;
    animation: shimmer 1.4s infinite;
    border-radius: var(--r-sm);
    height: 14px;
}
@keyframes shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

.loading-line {
    position: fixed; top: 0; left: 0; right: 0;
    height: 2px; z-index: 3000;
    background: transparent;
    overflow: hidden;
    display: none;
}
.loading-line.on { display: block; }
.loading-line::after {
    content: '';
    position: absolute;
    left: -40%; width: 40%; height: 100%;
    background: var(--grad-brand);
    animation: bar 1s var(--ease-out-quart) infinite;
}
@keyframes bar {
    0% { left: -40%; }
    100% { left: 100%; }
}

/* ============================================================
   Toast
   ============================================================ */
.toast-wrap {
    position: fixed;
    top: 68px; left: 50%; right: auto;
    transform: translateX(-50%);
    z-index: 4000;
    display: flex; flex-direction: column; align-items: center; gap: 9px;
    pointer-events: none;
}
.toast {
    min-width: 260px; max-width: 380px;
    display: flex; align-items: flex-start; gap: 10px;
    padding: 12px 14px;
    background: rgba(28, 35, 51, 0.92);
    backdrop-filter: blur(16px) saturate(1.4);
    -webkit-backdrop-filter: blur(16px) saturate(1.4);
    border: 1px solid var(--border-light);
    border-radius: var(--r-sm);
    box-shadow: var(--shadow-glass);
    pointer-events: auto;
    transform: translateY(-120%);
    animation: toastIn 0.4s var(--ease-out-expo) forwards;
}
@keyframes toastIn { to { transform: translateY(0); } }
.toast.out { animation: toastOut 0.25s var(--ease-out-quart) forwards; }
@keyframes toastOut { to { transform: translateY(-120%); opacity: 0; } }
.toast-icon { font-size: var(--fs-md); flex-shrink: 0; margin-top: 1px; }
.toast-msg { flex: 1; font-size: var(--fs-md); color: var(--text-primary); line-height: 1.5; }
.toast-msg small { display: block; color: var(--text-muted); font-size: var(--fs); margin-top: 3px; }
.toast.ok { border-left: 2px solid var(--ok); }
.toast.ok .toast-icon { color: var(--ok); }
.toast.err { border-left: 2px solid var(--danger); }
.toast.err .toast-icon { color: var(--danger); }
.toast.warn { border-left: 2px solid var(--warn); }
.toast.warn .toast-icon { color: var(--warn); }
.toast.info { border-left: 2px solid var(--brand-light); }
.toast.info .toast-icon { color: var(--brand-light); }

/* ---------- 表单内嵌联系人列表（供应商/客户） ---------- */
#contactsList { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.con-item { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 11px; background: var(--bg-elevated); border: 1px solid var(--border-light); border-radius: var(--r-sm); }
.con-info { min-width: 0; }
.con-name { font-weight: 600; color: var(--text-primary); }
.con-meta { font-size: var(--fs); color: var(--text-muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.con-empty { color: var(--text-muted); font-size: var(--fs); padding: 6px 2px; }

/* ============================================================
   审批时间线（为行政审批模块预置）
   ============================================================ */
.timeline { position: relative; padding-left: 26px; }
.timeline::before {
    content: '';
    position: absolute;
    left: 9px; top: 6px; bottom: 6px;
    width: 1px;
    background: var(--border-light);
}
.tl-item { position: relative; padding-bottom: 20px; }
.tl-item:last-child { padding-bottom: 0; }
.tl-node {
    position: absolute;
    left: -26px; top: 2px;
    width: 19px; height: 19px;
    border-radius: 50%;
    background: var(--bg-surface);
    border: 2px solid var(--border-light);
    display: flex; align-items: center; justify-content: center;
    font-size: 9px;
    color: var(--text-dim);
    z-index: 1;
}
.tl-item.done .tl-node { border-color: var(--ok); color: var(--ok); background: var(--ok-bg); }
.tl-item.reject .tl-node { border-color: var(--danger); color: var(--danger); background: var(--danger-bg); }
.tl-item.current .tl-node {
    border-color: var(--brand-light);
    color: var(--brand-light);
    background: var(--brand-bg);
    box-shadow: 0 0 0 4px rgba(15, 82, 186, 0.14);
}
.tl-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.tl-title { font-size: var(--fs-md); font-weight: 600; color: var(--text-primary); }
.tl-time { font-size: var(--fs-sm); color: var(--text-dim); font-family: var(--mono); }
.tl-body { font-size: var(--fs); color: var(--text-secondary); margin-top: 5px; line-height: 1.65; }
.tl-quote {
    margin-top: 7px;
    padding: 8px 11px;
    background: var(--bg-elevated);
    border-left: 2px solid var(--border-light);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
    font-size: var(--fs);
    color: var(--text-secondary);
}

/* ============================================================
   描述列表（详情展示）
   ============================================================ */
.desc {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 0;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    overflow: hidden;
}
.desc-item {
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    border-right: 1px solid var(--border);
}
.desc-k { font-size: var(--fs-sm); color: var(--text-muted); margin-bottom: 4px; }
.desc-v { font-size: var(--fs-md); color: var(--text-primary); font-weight: 500; word-break: break-all; }
.desc-v.num { font-family: var(--mono); }
/* 整行占位（长文本，如「事由 / 原因」）；desc 是 auto-fit 网格，跨全部列 */
.desc-item.desc-wide { grid-column: 1 / -1; }
.desc-v.desc-text { font-weight: 400; line-height: 1.75; white-space: pre-wrap; word-break: break-word; }

/* ============================================================
   工具类
   ============================================================ */
.f { display: flex; }
.fc { display: flex; align-items: center; }
.fb { display: flex; align-items: center; justify-content: space-between; }
.fw { flex-wrap: wrap; }
.g4 { gap: 4px; } .g6 { gap: 6px; } .g8 { gap: 8px; } .g12 { gap: 12px; } .g16 { gap: 16px; }
.flex1 { flex: 1; }
.mt8 { margin-top: 8px; } .mt12 { margin-top: 12px; } .mt16 { margin-top: 16px; } .mt24 { margin-top: 24px; }
.mb0 { margin-bottom: 0; } .mb8 { margin-bottom: 8px; } .mb12 { margin-bottom: 12px; } .mb16 { margin-bottom: 16px; }
.tr { text-align: right; } .tc { text-align: center; }
.t-dim { color: var(--text-dim); }
.t-mute { color: var(--text-muted); }
.t-sec { color: var(--text-secondary); }
.t-pri { color: var(--text-primary); }
.t-brand { color: var(--brand-light); }
.t-ok { color: var(--ok); } .t-warn { color: var(--warn); } .t-danger { color: var(--danger); } .t-info { color: var(--info); }
/* 价格变动：红涨绿跌（中国习惯），用于审批详情等处的涨价/降价比例。
   ⚠️ 必须带 .modal-body table.tb tbody td 前缀：弹窗内表格有
   「.modal-body table.tb tbody td { color: var(--white) }」规则，优先级更高会盖掉颜色 */
.t-diff-up { color: var(--danger); font-weight: 600; }
.t-diff-down { color: var(--ok); font-weight: 600; }
/* 缺料列：=0 灰色（不缺）；>0 复用 .t-diff-up 红加粗 */
.t-short-zero { color: var(--text-secondary); }
.modal-body table.tb tbody td.t-diff-up { color: var(--danger); }
.modal-body table.tb tbody td.t-diff-down { color: var(--ok); }
.modal-body table.tb tbody td.t-short-zero { color: var(--text-secondary); }
.fs-sm { font-size: var(--fs-sm); } .fs-xs { font-size: var(--fs-xs); }
.fw6 { font-weight: 600; } .fw7 { font-weight: 700; }

/* BOM 表单：批量粘贴客户物料号导入区 */
.batch-zone { margin-top: 16px; }
.batch-zone .inp { width: 100%; }
.batch-opt, .batch-actions { flex-wrap: wrap; }
.batch-opt { margin-bottom: 8px; }
.batch-actions { margin-top: 8px; }
.batch-zone .radio { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }
.nowrap { white-space: nowrap; }
.hidden { display: none !important; }
.divider { height: 1px; background: var(--border); margin: 16px 0; }
.vdivider { width: 1px; height: 18px; background: var(--border-light); }

/* ============================================================
   响应式
   ============================================================ */
@media (max-width: 1024px) {
    .erp-shell { grid-template-columns: var(--nav-w-mini) 1fr; }
    .erp-shell .nav-name,
    .erp-shell .nav-item .nav-label,
    .erp-shell .nav-badge,
    .erp-shell .nav-collapse span { display: none; }
    .erp-shell .nav-item { justify-content: center; padding: 0; margin: 1px 8px; }
    .erp-shell .nav-group-title { padding: 12px 0 6px; font-size: 0; text-align: center; }
    .erp-shell .nav-group-title::after {
        content: ''; display: block; width: 20px; height: 1px;
        margin: 0 auto; background: var(--border-light);
    }
    .search-box input { width: 180px; }
}
@media (max-width: 768px) {
    :root { --page-pad: 14px; }
    .erp-shell { grid-template-columns: 0 1fr; }
    .erp-nav {
        position: fixed; left: 0; top: 0; bottom: 0;
        width: var(--nav-w); z-index: 1600;
        transform: translateX(-100%);
        transition: transform var(--t);
        box-shadow: var(--shadow-xl);
    }
    .erp-nav.open { transform: translateX(0); }
    .erp-nav .nav-name,
    .erp-nav .nav-item .nav-label,
    .erp-nav .nav-badge,
    .erp-nav .nav-collapse span { display: initial; }
    .erp-nav .nav-item { justify-content: flex-start; padding: 0 12px 2px; margin: 1px 10px; }
    .erp-nav .nav-group-title { padding: 12px 18px 6px; font-size: var(--fs); text-align: left; }
    .erp-nav .nav-group-title::after { display: none; }
    .top-user-meta { display: none; }
    .search-box input { width: 100%; }
    .search-box { flex: 1; }
    .kpi-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
    .kpi-grid.cols-5 { grid-template-columns: repeat(2, 1fr); grid-auto-rows: auto; }
    .kpi-grid.cols-5 .kpi { display: block; }
    .kpi-value { font-size: 20px; }
    .field-row, .field-row.c2, .field-row.c3, .field-row.c4 { grid-template-columns: 1fr; }
    .toast-wrap { left: 14px; right: 14px; top: 62px; transform: none; align-items: stretch; }
    .toast { min-width: 0; max-width: none; }
    .modal { max-width: none; }
}

/* ==================== 批量导入 / 条件批量修改 ==================== */
.bulk-tip {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 10px 12px; margin-bottom: 14px;
  background: var(--bg-surface); border: 1px solid var(--border-light); border-left: 3px solid var(--brand);
  border-radius: var(--r-sm); color: var(--text-secondary); font-size: var(--fs-sm); line-height: 1.6;
}
.bulk-tip svg { flex: none; margin-top: 2px; color: var(--brand-light); }
.bulk-tip b { color: var(--text-primary); font-weight: 600; }

.bulk-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.bulk-spacer { flex: 1; }
.bulk-mode { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); color: var(--text-muted); }
.bulk-mode .sel { width: auto; }

.bulk-label { font-size: var(--fs-sm); color: var(--text-muted); margin-bottom: 6px; }

/* 导出字段勾选（导出弹框）：三列网格 + 内部滚动。
   销售订单一行 34 个字段、采购订单 26 个，平铺会撑满一屏且难以扫读，
   故固定列宽 + 限高滚动，分组标题独占整行。
   选择器必须带 .multi-box：index.html 的内联 <style> 里定义了
   `.multi-box{display:flex;flex-wrap:wrap}`，且内联样式在 erp.css 之后加载，
   同权重会覆盖，只写 .export-cols 会被压成 flex 平铺（实测踩过）。 */
.multi-box.export-cols {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px 18px;
  max-height: 46vh; overflow-y: auto; padding: 12px 14px;
  border: 1px solid var(--border-light); border-radius: var(--r-sm);
  background: var(--bg-surface); margin-bottom: 10px;
}
.export-cols .check { min-width: 0; font-size: var(--fs-md); }
.export-cols .check > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.export-cols .exp-group {
  grid-column: 1 / -1; margin-top: 2px; padding-bottom: 4px;
  border-bottom: 1px dashed var(--border-light);
  font-size: var(--fs-sm); font-weight: 600; color: var(--text-secondary);
}
.export-cols .exp-group:first-child { margin-top: 0; }
@media (max-width: 900px) { .multi-box.export-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.bulk-paste {
  width: 100%; min-height: 200px; resize: vertical;
  font-family: var(--mono); font-size: 13px; line-height: 1.5;
}

.bulk-result { margin-top: 14px; }
.bulk-summary {
  padding: 10px 12px; background: var(--bg-surface); border: 1px solid var(--border-light);
  border-radius: var(--r-sm); font-size: var(--fs-sm); color: var(--text-secondary); line-height: 1.7;
}
.bulk-summary b { font-weight: 700; }

.bulk-err-box, .bulk-prev-box {
  margin-top: 10px; padding: 10px 12px; max-height: 220px; overflow: auto;
  background: var(--bg-dark); border: 1px solid var(--border-light); border-radius: var(--r-sm);
}
.bulk-err-title { font-size: var(--fs-xs); color: var(--text-muted); margin-bottom: 6px; }
.bulk-err-line {
  font-family: var(--mono); font-size: 12.5px; color: var(--danger); padding: 2px 0; line-height: 1.5;
  border-bottom: 1px solid var(--border);
}
.bulk-err-line:last-child { border-bottom: none; }
.bulk-prev-row { font-size: var(--fs-sm); color: var(--text-secondary); padding: 3px 0; border-bottom: 1px solid var(--border); }
.bulk-prev-row:last-child { border-bottom: none; }

/* 批量修改：范围 + 字段值 */
.bulk-range { display: flex; align-items: center; gap: 8px; padding: 7px 0; font-size: var(--fs-sm); color: var(--text-secondary); cursor: pointer; }
.bulk-range input { width: 16px; height: 16px; accent-color: var(--brand); }

.batch-items { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }
.batch-item { display: flex; align-items: center; gap: 10px; }
/* 字段下拉是 combobox（root 无 .batch-field 类，靠 data-name 定位），固定宽 180px */
.batch-item .batch-field, .batch-item > .combobox[data-name="batch-field"] { flex: none; width: 180px; }
.batch-item .batch-value { flex: 1; display: flex; }
.batch-item .batch-value .inp, .batch-item .batch-value .sel, .batch-item .batch-value .combobox { width: 100%; }
.batch-item .bval { width: 100%; }
.batch-item .batch-delitem { flex: none; }

/* ============================================================
   白天模式（<html data-theme="light">）补充覆盖
   覆盖 style.css / erp.css 中硬编码的「白色玻璃层」以及登录卡片、
   弹窗强制白字、日期图标反色、下拉箭头、骨架屏 / Toast / 抽屉等浅色化。
   ============================================================ */
[data-theme="light"] body.erp { background: var(--bg-deep); }

/* 顶栏：深色玻璃 → 与主内容区同灰 */
[data-theme="light"] .erp-top {
    background: var(--bg-deep);
    border-bottom-color: rgba(15, 23, 42, 0.10);
}
[data-theme="light"] ::selection { background: rgba(15, 82, 186, 0.15); color: var(--text-primary); }

/* 登录卡片：深色玻璃 → 浅色玻璃 */
[data-theme="light"] .login-card {
  background: rgba(255, 255, 255, 0.88);
  border-color: rgba(15, 23, 42, 0.1);
  box-shadow: 0 8px 40px rgba(15, 23, 42, 0.12);
}

/* 顶栏 / 用户框 / 幽灵按钮等白色玻璃层 → 浅色层 */
[data-theme="light"] .top-btn,
[data-theme="light"] .top-user,
[data-theme="light"] .b-ghost,
[data-theme="light"] .btn-ghost,
[data-theme="light"] .lang-toggle,
[data-theme="light"] .mobile-menu-btn,
[data-theme="light"] .tag-mute,
[data-theme="light"] .tab-count,
[data-theme="light"] .code-copy:hover {
  background: rgba(15, 23, 42, 0.04);
  border-color: rgba(15, 23, 42, 0.12);
  color: var(--text-secondary);
}
[data-theme="light"] .top-btn:hover,
[data-theme="light"] .top-user:hover,
[data-theme="light"] .b-ghost:hover,
[data-theme="light"] .btn-ghost:hover,
[data-theme="light"] .lang-toggle:hover,
[data-theme="light"] .mobile-menu-btn:hover {
  background: rgba(15, 23, 42, 0.08);
  color: var(--text-primary);
}

/* 白天模式：彩色状态标签背景/边框加深，使色彩更明显（由 style.css 白天 code-* 深色变量派生） */
[data-theme="light"] .tag-ok { background: color-mix(in srgb, var(--ok) 14%, transparent); border-color: color-mix(in srgb, var(--ok) 28%, transparent); }
[data-theme="light"] .tag-warn { background: color-mix(in srgb, var(--warn) 14%, transparent); border-color: color-mix(in srgb, var(--warn) 28%, transparent); }
[data-theme="light"] .tag-danger { background: color-mix(in srgb, var(--danger) 14%, transparent); border-color: color-mix(in srgb, var(--danger) 28%, transparent); }
[data-theme="light"] .tag-info { background: color-mix(in srgb, var(--info) 14%, transparent); border-color: color-mix(in srgb, var(--info) 28%, transparent); }
[data-theme="light"] .tag-pending { background: color-mix(in srgb, var(--pending) 14%, transparent); border-color: color-mix(in srgb, var(--pending) 28%, transparent); }
[data-theme="light"] .tag-special { background: color-mix(in srgb, var(--special) 14%, transparent); border-color: color-mix(in srgb, var(--special) 28%, transparent); }
[data-theme="light"] .tag-brand { background: color-mix(in srgb, var(--brand) 14%, transparent); border-color: var(--border-brand); color: var(--brand); }
[data-theme="light"] .tag-primary { background: color-mix(in srgb, var(--brand) 14%, transparent); border-color: var(--border-brand, rgba(15, 82, 186, 0.35)); color: var(--brand); }
[data-theme="light"] .tag-stop { background: color-mix(in srgb, var(--danger) 14%, transparent); border-color: color-mix(in srgb, var(--danger) 28%, transparent); }

[data-theme="light"] .dd-item:hover {
  background: rgba(15, 23, 42, 0.05);
  color: var(--text-primary);
}
[data-theme="light"] .nav-item:hover,
[data-theme="light"] .nav-collapse:hover {
  background: rgba(15, 23, 42, 0.05);
  color: var(--text-primary);
}

/* 表单控件 hover 边框 */
[data-theme="light"] .inp:hover,
[data-theme="light"] .sel:hover { border-color: rgba(15, 23, 42, 0.2); }

/* 表格行 hover / 选中 */
[data-theme="light"] table.tb tbody tr:hover td { background: rgba(15, 23, 42, 0.025); }
[data-theme="light"] table.tb tbody tr.selected td { background: var(--brand-bg); }

/* 筛选空提示 / 骨架屏 */
[data-theme="light"] .filter-empty-tip { background: rgba(15, 23, 42, 0.02); }
[data-theme="light"] .skeleton {
  background: linear-gradient(90deg,
    rgba(15, 23, 42, 0.04) 25%,
    rgba(15, 23, 42, 0.08) 50%,
    rgba(15, 23, 42, 0.04) 75%);
}

/* 弹窗：强制白字 → 深色字（弹窗背景已是浅色 surface） */
[data-theme="light"] .modal { background: #FFFFFF; }
[data-theme="light"] .mask { background: rgba(15, 23, 42, 0.42); backdrop-filter: blur(3px); }
/* 浅色主题下的透明遮罩：必须与上面同特异性且在其后，否则会被盖回深色 */
[data-theme="light"] .mask.mask-clear { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
[data-theme="light"] .modal-body { color: var(--text-primary); }
[data-theme="light"] .modal-body .field-label,
[data-theme="light"] .modal-body .field-hint,
[data-theme="light"] .modal-body .inp[readonly],
[data-theme="light"] .modal-body .inp::placeholder,
[data-theme="light"] .modal-body .combobox-empty,
[data-theme="light"] .modal-body table.tb thead th,
[data-theme="light"] .modal-body table.tb tbody td,
[data-theme="light"] .modal-body .td-dim,
[data-theme="light"] .modal-body .td-code,
[data-theme="light"] .modal-body .col-idx,
[data-theme="light"] .modal-body .con-meta,
[data-theme="light"] .modal-body .con-empty,
[data-theme="light"] .modal-body .modal-close {
  color: var(--text-primary);
}

/* 下拉菜单 / 抽屉 / Toast 浅色化 */
[data-theme="light"] .dd-menu { background: #FFFFFF; border-color: rgba(15, 23, 42, 0.12); }
[data-theme="light"] .drawer { background: #FFFFFF; border-left-color: rgba(15, 23, 42, 0.1); }
[data-theme="light"] .toast {
  background: rgba(255, 255, 255, 0.96);
  border-color: rgba(15, 23, 42, 0.1);
  box-shadow: 0 8px 32px rgba(15, 23, 42, 0.12);
}
[data-theme="light"] .toast-msg { color: var(--text-primary); }
[data-theme="light"] .toast-msg small { color: var(--text-muted); }

/* 日期图标反色仅在夜晚模式需要 */
[data-theme="light"] input[type="date"]::-webkit-calendar-picker-indicator { filter: none; }

/* 下拉箭头：夜晚白 → 白天深 */
[data-theme="light"] .sel {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%230F172A' stroke-opacity='0.5' stroke-width='1.6'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
}

/* 空状态图标 / 加载条底色调浅 */
[data-theme="light"] .empty-icon { background: rgba(15, 23, 42, 0.03); border-color: rgba(15, 23, 42, 0.08); }
[data-theme="light"] .loading-line::after { background: var(--grad-brand); }

/* 红底徽章文字在浅背景下改为白字以保证对比 */

/* 加载动画圈在浅背景下用品牌色 */
[data-theme="light"] .b-loading::after { border-color: rgba(15, 23, 42, 0.25); border-top-color: var(--brand); }

/* ============================================================
 * 一物一码（序列号追溯）辅助布局类（仅尺寸/布局，复用既有变量，不新增色值）
 * ============================================================ */
.scan-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
.scan-trace { border-left: 1px solid var(--border); padding-left: 18px; }
@media (max-width: 960px) {
  .scan-layout { grid-template-columns: 1fr; }
  .scan-trace { border-left: none; padding-left: 0; }
}
.scan-col { min-width: 0; }
.scan-input-wrap { display: flex; align-items: center; gap: 8px; border: 1px solid var(--border); border-radius: var(--r); padding: 0 10px; background: var(--bg-elevated); }
.scan-input { flex: 1; border: none; background: transparent; padding: 12px 4px; font-size: 16px; outline: none; color: var(--text-primary); }
.scan-ic { color: var(--text-muted); display: flex; }
.next-panel { margin-top: 12px; padding: 12px; border: 1px solid var(--border); border-radius: var(--r); background: var(--bg-elevated); }
.next-panel.next-done { border-color: var(--border-brand); }
.next-panel.next-error { border-color: var(--code-red); }
.next-step { font-size: var(--fs-sm); margin-bottom: 4px; }
.order-card { padding: 12px; border: 1px solid var(--border); border-radius: var(--r); background: var(--bg-elevated); }
.order-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 3px 0; font-size: var(--fs-sm); }
.order-steps { margin-top: 8px; }
.stepper { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.step { display: flex; align-items: center; gap: 6px; padding: 4px 10px; border: 1px solid var(--border); border-radius: var(--r-full); background: var(--bg-surface); font-size: var(--fs-sm); }
.step-done { border-color: var(--border-brand); }
.step-current { font-weight: 600; border-color: var(--brand); }
.step-dot { width: 18px; height: 18px; border-radius: var(--r-full); display: inline-flex; align-items: center; justify-content: center; background: var(--bg-elevated); color: var(--text-muted); }
.step-pending .step-dot { background: var(--bg-surface); }
.step-arrow { color: var(--text-dim); }
.step-name { font-size: var(--fs-sm); color: var(--text-secondary); }
.recent-list { display: flex; flex-direction: column; gap: 4px; max-height: 280px; overflow: auto; }
.sn-list { max-height: 280px; overflow: auto; border: 1px solid var(--border); border-radius: var(--r); background: var(--bg-elevated); padding: 8px; }
.recent-item { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border: 1px solid var(--border); border-radius: var(--r-sm); font-size: var(--fs-sm); background: var(--bg-surface); }
.trace-result { padding: 12px; border: 1px solid var(--border); border-radius: var(--r); background: var(--bg-elevated); min-height: 80px; }
.trace-head { margin-bottom: 8px; }
.step-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; }
.step-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  background: var(--bg-soft, var(--bg-surface));
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
}
.step-idx { width: 24px; height: 24px; flex: 0 0 24px; border-radius: var(--r-full); display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border); font-size: var(--fs-sm); color: var(--text-muted); }
.step-row .inp[name="step_name"] { flex: 1; min-width: 0; }
.step-code { max-width: 140px; flex: 0 0 140px; }
.step-hint { flex: 0 0 auto; display: inline-flex; align-items: center; min-width: 48px; justify-content: center; }
.step-row [data-rm] { flex: 0 0 auto; }

/* 审批链弹框：条件行 / 审批人行 共用布局 */
.wf-lines { display: flex; flex-direction: column; gap: 8px; }
.wf-line { display: flex; align-items: center; gap: 8px; }
.wf-empty { font-size: var(--fs-sm); color: var(--text-dim); margin: 2px 0; }
.wf-cb-sm { flex: 0 0 116px; min-width: 0; }
.wf-cb-grow { flex: 1; min-width: 0; }
/* 生效条件行：字段 / 运算符 / 值 = 25% / 25% / 50%
   （flex-basis:0 + grow 1:1:2，可用空间已扣除删除按钮 30px 与 3×8px 间距） */
.wf-cond-f, .wf-cond-o { flex: 1 1 0; min-width: 0; }
.wf-cond-v { flex: 2 1 0; min-width: 0; }

/* 审批链：单个审批节点块（会签/或签时一个节点含多个审批人行） */
.wf-node { display: flex; flex-direction: column; gap: 6px; padding: 6px 0; border-bottom: 1px dashed var(--border); }
.wf-node:last-child { border-bottom: none; }

/* 详情弹框只读字段：统一 label/value 紧凑行距 */
.f-label { display: block; font-size: var(--fs-sm); color: var(--text-dim); margin-bottom: 2px; line-height: 1.3; }
.ro-box { min-height: 20px; line-height: 1.4; color: var(--text-primary); }
.sn-title { font-size: 2em; line-height: 1.5; vertical-align: middle; }

/* 系统设置 · Logo 编辑器 */
.logo-edit { display: flex; gap: 20px; align-items: flex-start; margin-bottom: 8px; }
.logo-prev {
  width: 120px; height: 120px; flex-shrink: 0;
  border: 1px dashed var(--border); border-radius: var(--r);
  background: var(--bg-soft); display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.logo-img { max-width: 100%; max-height: 100%; object-fit: contain; }
.logo-empty {
  width: 56px; height: 56px; border-radius: var(--r-sm);
  background: var(--grad-brand); box-shadow: var(--shadow-brand);
  display: flex; align-items: center; justify-content: center;
  font-size: 26px; font-weight: 900; color: var(--white); letter-spacing: -0.5px;
}
.logo-side { flex: 1; min-width: 0; }
.row.gap { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }


/* ===== 系统设置 · 系统模式单选卡片 ===== */
.mode-radios { display: flex; gap: 12px; flex-wrap: wrap; }
.mode-card {
  flex: 1 1 220px; min-width: 0;
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-surface);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.mode-card:hover { border-color: var(--border-light); }
.mode-card input[type="radio"] { accent-color: var(--brand); width: 16px; height: 16px; flex-shrink: 0; }
.mode-card-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mode-name { font-size: var(--fs-md); font-weight: 600; color: var(--text-primary); }
.mode-desc { font-size: var(--fs-sm); color: var(--text-muted); }
.mode-card:has(input:checked) {
  border-color: var(--border-brand);
  background: var(--brand-bg-strong);
}
/* 系统设置：保存按钮与上方表单（含系统模式卡片）拉开间距 */
.form-actions { margin-top: 24px; }

/* ========== 劳动合同模块 ========== */
.salary-tbl { margin-top: 6px; }
.salary-tbl th, .salary-tbl td { padding: 4px 6px; }
.salary-tbl input.inp { text-align: right; }
.salary-tbl .total-row td { background: var(--brand-bg-strong); font-weight: 700; }
.salary-tbl .total-row input.inp { font-weight: 700; color: var(--text-primary); }
/* 关联面试搜索提示框 */
.combo-hint {
  position: absolute;
  z-index: 50;
  background: #fff;
  border: 1px solid var(--border-light);
  border-radius: 6px;
  box-shadow: 0 6px 20px rgba(0,0,0,.12);
  max-height: 240px;
  overflow: auto;
  min-width: 280px;
  margin-top: 2px;
}
.combo-hint .combo-opt { padding: 7px 10px; cursor: pointer; font-size: var(--fs-sm); border-bottom: 1px solid var(--border-light); }
.combo-hint .combo-opt:hover { background: var(--brand-bg-strong); }
.combo-hint .combo-opt.mute { color: var(--text-muted); cursor: default; }
/* 详情查看 */
.view-detail .kv { display: flex; gap: 10px; padding: 4px 0; border-bottom: 1px dashed var(--border-light); }
.view-detail .kv > span { width: 96px; flex: none; color: var(--text-muted); }
.view-detail .kv > b { font-weight: 500; }

/* ============================================================
   首次部署安装向导（全屏，渲染于应用外壳之外）
   ============================================================ */
.install-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--page-pad);
  background: var(--bg-deep);
}
.install-card {
  width: 100%;
  max-width: 660px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  padding: 28px 32px 24px;
}
.install-head { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.install-logo {
  width: 48px; height: 48px; border-radius: var(--r-md);
  background: var(--brand); color: var(--white);
  display: flex; align-items: center; justify-content: center;
  font-size: 24px; font-weight: 800;
}
.install-title { font-size: 20px; font-weight: 800; color: var(--text-primary); }
.install-sub { font-size: var(--fs-sm); color: var(--text-muted); }
.install-steps { display: flex; gap: 10px; margin-bottom: 18px; }
.istep {
  flex: 1; display: flex; align-items: center; gap: 6px; justify-content: center;
  font-size: var(--fs-sm); color: var(--text-muted);
  padding: 8px; border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--bg-elevated);
}
.istep span {
  width: 18px; height: 18px; border-radius: var(--r-full);
  background: var(--brand-bg); color: var(--brand-light);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
}
.install-actions { display: flex; gap: 12px; justify-content: flex-end; margin-top: 18px; }
.install-tip { margin-top: 12px; font-size: var(--fs-sm); min-height: 18px; color: var(--text-muted); }
.install-tip.ok { color: var(--ok); }
.install-tip.err { color: var(--danger); }
.install-tip.busy { color: var(--brand-light); }
.install-done { text-align: center; padding: 24px 0 8px; }
.install-done-icon {
  width: 56px; height: 56px; border-radius: var(--r-full);
  background: var(--ok-bg); color: var(--ok);
  display: flex; align-items: center; justify-content: center;
  font-size: 30px; font-weight: 800; margin: 0 auto 14px;
}
.install-done h3 { font-size: var(--fs-xl); margin-bottom: 8px; color: var(--text-primary); }
.install-done p { color: var(--text-muted); font-size: var(--fs-sm); }
.install-done-sub { margin: 12px 0 18px; line-height: 1.8; }

/* ===== 经营看板 (Executive Dashboard) ===== */
.page-sub { font-size: 13px; color: var(--text-muted, #888); margin-top: 2px; }
.delta { display: inline-flex; align-items: center; gap: 2px; font-size: 12px; font-weight: 700; padding: 1px 6px; border-radius: 6px; vertical-align: middle; }
.delta.up { color: #0a7d3b; background: rgba(10,125,59,.10); }
.delta.down { color: #c0392b; background: rgba(192,57,43,.10); }
.delta.na { color: #8a8a8a; background: rgba(0,0,0,.05); font-weight: 500; }
.progress { height: 8px; background: var(--bg-elevated); border-radius: 5px; overflow: hidden; }
.progress-fill { height: 100%; background: var(--grad-brand); border-radius: 5px; transition: width .45s ease; }
.kpi.k-bad .kpi-value { color: #c0392b; }

/* ===== 数字输入框：隐藏原生上下调节箭头（全站生效） ===== */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

/* ================= 消息中心（顶部铃铛 + 消息抽屉） ================= */
.msg-bell {
    position: relative;
    flex: none;
}

.msg-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: var(--danger);
    color: #fff;
    font-size: 11px;
    line-height: 16px;
    text-align: center;
    font-weight: 600;
    box-shadow: 0 0 0 2px var(--bg-dark);
}

/* hidden 属性在部分浏览器会被 flex 布局忽略，显式补 display:none */
.msg-badge[hidden] { display: none; }

.msg-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
}

.msg-spacer { flex: 1; }

.msg-list {
    max-height: 52vh;
    overflow: auto;
    border: 1px solid var(--border-light);
    border-radius: var(--r-sm);
}

.msg-item {
    display: flex;
    gap: 10px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border-light);
    cursor: pointer;
    transition: var(--t-fast);
}

.msg-item:last-child { border-bottom: none; }
.msg-item:hover { background: var(--brand-bg); }

.msg-dot {
    flex: none;
    width: 7px;
    height: 7px;
    margin-top: 6px;
    border-radius: 50%;
    background: transparent;
}

.msg-item.unread .msg-dot { background: var(--danger); }
.msg-item.unread .msg-title { font-weight: 600; }

.msg-main { flex: 1; min-width: 0; }

.msg-title {
    font-size: var(--fs-md);
    color: var(--text-primary);
}

.msg-body {
    margin-top: 3px;
    font-size: var(--fs-sm);
    color: var(--text-secondary);
    word-break: break-all;
}

.msg-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 5px;
    font-size: 12px;
    color: var(--text-secondary);
    opacity: .85;
}

.msg-tag {
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--brand-bg);
}

.msg-empty {
    padding: 28px;
    text-align: center;
    font-size: var(--fs-sm);
    color: var(--text-secondary);
}

.msg-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-top: 10px;
}

.msg-pager-text {
    font-size: var(--fs-sm);
    color: var(--text-secondary);
}

/* ---------- 通知配置（系统管理 → 通知配置） ---------- */
.nc-event {
    padding: 16px 0;
    border-bottom: 1px solid var(--border-light);
}
.nc-event:last-child { border-bottom: none; }
.nc-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
}
.nc-biz { font-weight: 600; color: var(--text-primary); }
.nc-dot { color: var(--text-tertiary); }
.nc-act { color: var(--text-secondary); }
.nc-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    min-height: 20px;
    margin-bottom: 12px;
}
.nc-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 4px 3px 10px;
    background: var(--brand-bg);
    border: 1px solid var(--brand-border, var(--border-light));
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
    color: var(--brand-fg, var(--text-primary));
}
.nc-x {
    border: none;
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    padding: 0 4px;
    border-radius: 4px;
}
.nc-x:hover { color: var(--danger); background: var(--danger-bg, rgba(0,0,0,.06)); }
.nc-empty { font-size: var(--fs-sm); color: var(--text-tertiary); }
.nc-add {
    display: flex;
    align-items: center;
    gap: 8px;
}
.nc-add .combobox { flex: 1; max-width: 360px; }
.nc-spacer { flex: 1; }
.tag-default, .tag-custom {
    font-size: 11px;
    padding: 1px 8px;
    border-radius: 999px;
    margin-left: 4px;
}
.tag-default { background: var(--bg-tertiary, #f1efea); color: var(--text-secondary); }
.tag-custom { background: var(--brand-bg); color: var(--brand-fg, var(--text-primary)); }



/* ===== 库存盘点 · 录入实盘：按需添加盘点行 ===== */
.chk-add {
    display: grid;
    grid-template-columns: minmax(220px, 2.4fr) minmax(180px, 1.8fr) 110px 110px minmax(140px, 1.4fr) auto;
    gap: 10px;
    align-items: center;
    padding: 10px 12px;
    margin-bottom: 8px;
    background: var(--bg-tertiary, #f7f6f3);
    border: 1px dashed var(--border-light, #e2ded6);
    border-radius: var(--r-sm);
}
.chk-add .combobox { min-width: 0; }
.chk-add .inp { width: 100%; }
.chk-add #caBook { background: var(--bg-secondary, #fff); color: var(--text-secondary); }
@media (max-width: 900px) {
    .chk-add { grid-template-columns: 1fr 1fr; }
    .chk-add .ca-mat { grid-column: 1 / -1; }
}

.chk-add + .ca-hint {
    margin: -2px 0 8px;
    padding: 0 2px;
    min-height: 18px;
}

/* ── 经营看板·客户订单分析面板 ── */
.cus-stat-row { display: flex; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.cus-stat { flex: 1 1 0; min-width: 120px; background: var(--bg-elevated, #f7f6f3); border: 1px solid var(--border-light, #e8e4dd); border-radius: 8px; padding: 12px 14px; }
.cus-stat-label { font-size: 12px; color: var(--text-secondary); margin-bottom: 6px; }
.cus-stat-value { font-size: 22px; font-weight: 700; color: var(--text-primary, #1e293b); line-height: 1.1; }
.cus-stat-value .unit { font-size: 13px; font-weight: 500; margin-left: 3px; color: var(--text-secondary); }
.cus-stat-sub { font-size: 11px; color: var(--text-muted); margin-top: 6px; }
.cus-stat.k-bad .cus-stat-value { color: var(--danger); }
.cus-chart-title { font-size: 13px; color: var(--text-secondary); margin-bottom: 10px; font-weight: 600; }
.cus-chart-box { position: relative; height: 220px; }
@media (max-width: 900px) {
  .cus-stat-row { flex-direction: column; }
}

/* ============================================================
   成本查询页（sal-cost-query）专属设计层
   原则：不引入新色值，全部引用 style.css / erp.css 既有 token
   ============================================================ */

/* 成本查询：工具栏内物料选择 combobox 宽度（对齐标准 .toolbar 布局） */
.toolbar .cb-wrap { min-width: 280px; width: 30%; }

/* 统计条：4 张 metric 卡 */
.cost-tip { background: var(--info-bg); color: var(--info); padding: 8px 12px; font-size: 12px; line-height: 1.6; border-radius: var(--r); margin: 4px 0 12px; border: 1px solid rgba(121, 192, 255, 0.22); }
.cost-tip b { font-weight: 500; }
.cost-stats { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 10px; margin: 14px 0 10px; }
.cost-stats .stat-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-light);
  border-radius: var(--r);
  padding: 9px 14px;
}
.cost-stats .stat-card.stat-warn { background: var(--danger-bg); }
.cost-stats .stat-label { font-size: 11px; color: var(--text-secondary); }
.cost-stats .stat-val { font-size: 18px; font-weight: 500; color: var(--text-primary); letter-spacing: -0.3px; margin-top: 2px; }
.cost-stats .stat-val.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* 应付/进项：4 张统计卡 + 状态 chips（2026-10-20 改版提案「先做在本地」） */
.stat-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 14px 0 10px; }
.stat-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-light);
  border-radius: var(--r);
  padding: 10px 14px;
  display: flex; flex-direction: column; gap: 2px;
}
.stat-card .sc-k { font-size: 12px; color: var(--text-secondary); }
.stat-card .sc-v { font-size: 20px; font-weight: 600; color: var(--text-primary); font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -0.4px; }
.stat-card .sc-s { font-size: 11px; color: var(--text-muted); }
.stat-card.accent-warn { border-color: var(--warn); }
.stat-card.accent-warn .sc-v { color: var(--danger); }
.stat-card.accent-blue .sc-v { color: var(--brand-light); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 15px;
  font-size: var(--fs-md); font-weight: 500;
  color: var(--text-muted);
  background: var(--bg-surface);
  border: 1px solid var(--border-light);
  border-radius: var(--r-full);
  cursor: pointer; transition: var(--t-fast);
  font-family: inherit;
}
.chip:hover { color: var(--text-primary); border-color: var(--border); }
.chip b { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; }
.chip.active { color: #fff; background: var(--brand); border-color: var(--brand); }
.chip.chip-warn.active { background: var(--warn); border-color: var(--warn); }
.chip.chip-ok.active { background: var(--ok); border-color: var(--ok); }
.chip.chip-blue.active { background: var(--brand-light); border-color: var(--brand-light); }

/* 成本查询表：在通用 table.tb 基础上，强化主物料行 + BOM 树形引导线 + 子项降级 */
table.tb.cost-tbl { width: 100%; }
/* 数字列右对齐（与列表页 .td-num 口径一致） */
table.tb.cost-tbl th.num,
table.tb.cost-tbl td.num { text-align: right; }
/* 操作列右对齐 */
table.tb.cost-tbl td.actions { text-align: right; }
/* 来源列右对齐 */
table.tb.cost-tbl td.src-cell { text-align: right; }
/* 主物料行：品牌色背景 + 左边条，编码/成本加粗（hover 保持品牌底色） */
table.tb.cost-tbl tr.mat-row > td { background: var(--brand-bg); }
table.tb.cost-tbl tr.mat-row { box-shadow: inset 2px 0 0 0 var(--brand-light); }
table.tb.cost-tbl tr.mat-row:hover > td { background: var(--brand-bg-strong, rgba(15, 82, 186, 0.18)); }
table.tb.cost-tbl tr.mat-row td.code,
table.tb.cost-tbl tr.mat-row td.num.cost-main { color: var(--text-primary); font-weight: 500; }
/* 子项降级：编码/成本为次级色，与主行拉开对比 */
table.tb.cost-tbl tr:not(.mat-row) td.code,
table.tb.cost-tbl tr:not(.mat-row) td.num.cost-main { color: var(--text-muted); }
/* 名称单元格：内部 flex 容器占满列宽（td 本身保持 table-cell，避免破坏表格列宽），
   名称超出列宽才省略号，完整文字在 title */
.name-flex { display: flex; align-items: center; min-width: 0; }
.name-flex .mat-toggle,
.name-flex .tree-line { flex: none; }
.name-flex .mat-name {
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
table.tb.cost-tbl .mat-name { font-weight: 500; color: var(--text-primary); }
table.tb.cost-tbl tr:not(.mat-row) .mat-name { font-weight: 400; color: var(--text-muted); }

/* 树形引导线：每个层级一个竖向标记，末级带 L 形连接 */
.tree-line { display: inline-flex; align-items: center; height: 1.25em; vertical-align: middle; margin-right: 2px; }
.tree-line .tl-anc { display: inline-block; width: 13px; height: 100%; border-left: 1px solid var(--border-light); }
.tree-line .tl-cur { display: inline-block; width: 13px; height: 100%; border-left: 1px solid var(--border-light); border-bottom: 1px solid var(--border-light); }

/* 主行折叠开关 */
.mat-toggle { display: inline-flex; align-items: center; justify-content: center; width: 16px; margin-right: 5px; vertical-align: middle; cursor: pointer; color: var(--brand-light); font-size: 11px; user-select: none; }
.sub-count { color: var(--text-muted); font-size: 11px; margin-left: 6px; }

/* 待录入：输入框 + 标准保存按钮（对齐 ERP 按钮体系） */
.cost-input-group { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.cost-input-group input.inp {
  width: 68px; border-radius: var(--r-sm);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}
.cost-input-group .b { flex: none; }

/* 来源标签旁「含N待录」小标记 */
.tag-note { margin-left: 4px; }
/* ── 经营看板 2026-10-20：趋势工具条 / 指标 chips / 排名表 / 分栏详情 ── */
.exec-toolbar {
  flex-shrink: 0; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 16px; border-bottom: 1px solid var(--border); font-size: 12px;
}
.exec-toolbar-sep { width: 1px; height: 18px; background: var(--border); }
.exec-seg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--r-sm); overflow: hidden; }
.exec-seg .seg {
  border: none; background: transparent; color: var(--text-secondary);
  padding: 5px 12px; font-size: 12px; cursor: pointer;
}
.exec-seg .seg + .seg { border-left: 1px solid var(--border); }
.exec-seg .seg.active { background: var(--grad-brand); color: #fff; }
.exec-chips { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.exec-chips .chip {
  border: 1px solid var(--border); background: transparent; color: var(--text-secondary);
  border-radius: 999px; padding: 4px 12px; font-size: 12px; cursor: pointer;
  transition: all 0.15s ease;
}
.exec-chips .chip:hover { border-color: var(--brand); color: var(--brand); }
.exec-chips .chip.active { background: var(--brand); border-color: var(--brand); color: #fff; }

/* 主趋势图 + 明细表 */
.exec-chart-main { flex: 1 1 52%; min-height: 240px; margin: 14px 16px 0; position: relative; }
/* 图表渲染失败提示：追加在画布旁边（不覆盖 innerHTML，画布要留着才能恢复） */
.exec-chart-fail {
  padding: 10px 14px; font-size: 12px; color: var(--danger);
  background: var(--bg-elevated, #f1efe9); border: 1px dashed var(--danger);
  border-radius: var(--r-md); margin-top: 8px;
}
.exec-chart-box { position: relative; flex: 1 1 auto; min-height: 200px; margin: 10px 14px 14px; }
.exec-table-wrap { flex: 1 1 auto; min-height: 120px; overflow: auto; padding: 0 16px 16px; }
/* 看板表格：直接复用系统 table.tb（表头 sticky/字号/边框/Hover 全部继承），
   这里只补「列数多 → 更紧凑」「数字列右对齐」「合计行」「负值标红」四点 */
table.exec-table { font-size: var(--fs-sm); }
table.exec-table thead th, table.exec-table tbody td { padding: 8px 10px; }
table.exec-table tbody tr:hover td { background: var(--bg-elevated); }
table.exec-table tbody tr.selected td { background: var(--brand-bg); }
table.exec-table tfoot td {
  padding: 9px 10px; font-weight: 700;
  border-top: 1px solid var(--border-light); background: var(--bg-elevated);
}
table.exec-table .neg { color: var(--danger); }
table.exec-table .td-num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── 经营看板 2026-10-23 补：现金流页（本月收入/支出饼图 + 今年每月收支曲线）── */
/* 内容高度超过可视区（统计条 + 双饼图 + 曲线 + 明细表）→ 整页滚动，
   不套用 trend 页那种「各块互相挤压」的 flex 分配（会把饼图压扁） */
.exec-tab-pane.active[data-pane="cashflow"] { overflow: auto; }
.exec-tab-pane[data-pane="cashflow"] > .exec-table-wrap { flex: 0 0 auto; overflow: visible; padding-bottom: 20px; }
.cf-stat-row { flex: 0 0 auto; padding: 14px 16px 0; margin-bottom: 0; }
.cf-pie-row { flex: 0 0 auto; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 8px; }
.cf-pie-box { min-height: 300px; margin: 12px 14px 0; display: flex; flex-direction: column; }
.cf-line-box { min-height: 300px; margin: 12px 14px 0; display: flex; flex-direction: column; }
.cf-box-head {
  flex: 0 0 auto; font-size: 13px; font-weight: 600; color: var(--text-primary);
  padding: 0 4px 8px; display: flex; align-items: center; gap: 6px;
}
.cf-box-head .t-dim { font-weight: 400; font-size: 12px; margin-left: auto; }
/* Chart.js responsive + maintainAspectRatio:false 需要父级有确定高度 */
.cf-canvas-wrap { position: relative; flex: 1 1 auto; min-height: 190px; }
.cf-line-canvas { min-height: 240px; }
/* 自定义图例：名称 + 金额 + 占比（比内置图例信息量更大） */
.cf-legend { flex: 0 0 auto; max-height: 120px; overflow: auto; padding: 4px 4px 0; }
.cf-legend-row {
  display: grid; grid-template-columns: 12px minmax(0, 1fr) auto 52px;
  align-items: center; gap: 8px; font-size: 12px; padding: 3px 0;
  border-bottom: 1px dashed var(--border-light, rgba(0, 0, 0, 0.06));
}
.cf-legend-row:last-child { border-bottom: none; }
.cf-legend-row i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.cf-legend-name { color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cf-legend-val { color: var(--text-primary); font-variant-numeric: tabular-nums; }
.cf-legend-pct { color: var(--text-muted); text-align: right; font-variant-numeric: tabular-nums; }
.cf-legend-total { font-weight: 700; border-top: 1px solid var(--border-light, rgba(0, 0, 0, 0.1)); margin-top: 2px; }
.cf-legend-total .cf-legend-name,
.cf-legend-total .cf-legend-val { color: var(--text-primary); }
.cf-legend-empty { font-size: 12px; color: var(--text-muted); padding: 6px 4px; }
@media (max-width: 900px) {
  .cf-pie-row { grid-template-columns: 1fr; }
}

/* 左右分栏：排名表 + 实体详情 */
.exec-split { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 0; }
.exec-split > .exec-table-wrap { border-right: 1px solid var(--border); padding-top: 12px; }
.exec-detail { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: auto; padding: 14px 0 16px; }
.exec-detail-head { flex-shrink: 0; padding: 0 16px 10px; font-size: 13px; color: var(--text-primary); }
.exec-detail-head .t-dim { font-weight: 400; margin-left: 6px; }
.exec-detail .cus-stat-row { padding: 0 16px; }
.exec-detail .empty { flex: 1 1 auto; }

@media (max-width: 900px) {
  .exec-split { grid-template-columns: 1fr; }
  .exec-split > .exec-table-wrap { border-right: none; border-bottom: 1px solid var(--border); }
}

/* ── 经营看板 2026-10-20 补：销售总览 / 采购总览 / 业务数据（四列等宽 25%）── */
/* 总览页铺满可视区，不出现「外层 + 网格」双滚动 */
.exec-tab-pane.active.exec-ov-pane { overflow: hidden; }
.exec-overview-grid {
  flex: 1 1 auto; height: 100%; min-height: 0;
  display: grid;
  /* 业务数据：9 张 → 每张 1/3 宽 × 1/3 高 */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: repeat(3, minmax(0, 1fr));
  gap: 12px;
  padding: 12px 14px 14px;
}
/* 销售总览 / 采购总览：4 张 → 每张 50% 宽 × 50% 高 */
#ovSalesGrid, #ovPurchaseGrid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
}
.ov-card {
  display: flex; flex-direction: column; gap: 8px;
  min-height: 0; overflow: hidden; padding: 13px 14px 12px;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--bg-surface, #fff);
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
/* hover 与系统 .kpi 保持一致：品牌色描边 + 系统阴影，不引入私有色值 */
.ov-card:hover { border-color: var(--border-brand); box-shadow: var(--shadow-md); }
.ov-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }
.ov-label {
  display: inline-flex; align-items: center; gap: 6px; min-width: 0;
  font-size: 12px; color: var(--text-secondary); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ov-label .ic { flex-shrink: 0; }
.ov-margin { font-size: 13px; font-weight: 700; color: var(--brand); }
.ov-card.ov-bad .ov-value, .ov-card.ov-bad .ov-margin { color: var(--danger); }
/* 金额可能很长（千万/亿级）：允许换行完整显示，不再以省略号截断（完整值仍走 title 提示） */
.ov-value {
  font-size: 20px; font-weight: 700; line-height: 1.15; letter-spacing: -0.2px;
  color: var(--text-primary);
  overflow-wrap: anywhere; word-break: break-word;
}
.ov-unit { margin-left: 4px; font-size: 12px; font-weight: 400; color: var(--text-secondary); }
.ov-delta { font-size: 11px; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.ov-delta-na { color: var(--text-secondary); }
/* 走势区弹性占满卡片剩余高度：卡片是 50%/33% 等高网格，固定 34px 会留大片空白 */
.ov-spark { flex: 1 1 auto; min-height: 34px; margin: 2px 0 0; display: flex; flex-direction: column; }
.ov-spark-svg { width: 100%; flex: 1 1 auto; min-height: 34px; display: block; }
.ov-spark-empty { flex: 1 1 auto; min-height: 34px; display: flex; align-items: center; font-size: 11px; color: var(--text-secondary); }
.ov-spark-foot { font-size: 11px; color: var(--text-secondary); flex-shrink: 0; }
.ov-spark-foot b { color: var(--text-primary); font-weight: 600; }
/* 总览卡迷你折线：时间轴（两端月份）+ 悬停当月数据浮层 */
.ov-spark-wrap { position: relative; flex: 1 1 auto; min-height: 34px; display: flex; flex-direction: column; }
.ov-spark-axis { display: flex; justify-content: space-between; font-size: 10px; color: var(--text-secondary); font-variant-numeric: tabular-nums; margin-top: 1px; flex-shrink: 0; line-height: 1.2; }
.ov-spark-cursor { position: absolute; top: 0; bottom: 14px; width: 1px; background: var(--border-brand); pointer-events: none; display: none; z-index: 2; }
.ov-spark-tip { position: fixed; z-index: 9999; pointer-events: none; background: rgba(15,23,42,0.92); color: #fff; font-size: 11px; line-height: 1.45; padding: 4px 8px; border-radius: 6px; white-space: nowrap; box-shadow: 0 4px 14px rgba(0,0,0,0.25); }
.ov-spark-tip b { font-weight: 700; color: #fff; }
/* 双线走势（业务类型卡：销售额 + 销售毛利）图例 */
.ov-legend { display: flex; align-items: center; gap: 12px; font-size: 10px; color: var(--text-secondary); flex-shrink: 0; margin-top: 2px; line-height: 1.2; }
.ov-legend i { display: inline-block; width: 11px; height: 3px; border-radius: 2px; margin-right: 3px; vertical-align: middle; }
.ov-sub { margin-top: auto; font-size: 11px; color: var(--text-secondary); line-height: 1.5; }
.ov-bars { display: flex; flex-direction: column; gap: 5px; padding-top: 2px; }
.ov-bar-row { display: grid; grid-template-columns: 64px 1fr auto; align-items: center; gap: 8px; font-size: 11px; }
.ov-bar-name { color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ov-bar-track { height: 6px; background: var(--bg-elevated, #f1efe9); border-radius: 3px; overflow: hidden; }
.ov-bar-fill { display: block; height: 100%; background: var(--grad-brand); border-radius: 3px; }
.ov-bar-val { color: var(--text-primary); font-variant-numeric: tabular-nums; }
/* 中等屏：业务数据降为 2 列（销售/采购仍是 2×2）；窄屏改单列自适应高度并允许滚动 */
@media (max-width: 1280px) {
  .exec-overview-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .exec-tab-pane.active.exec-ov-pane { overflow: auto; }
  .exec-overview-grid,
  #ovSalesGrid, #ovPurchaseGrid {
    height: auto; min-height: 100%;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    grid-auto-rows: minmax(180px, auto);
  }
}

/* 客户/产品详情统计卡：数字不再溢出卡片边界（5 个 stat 挤在一行时最常见） */
.cus-stat { flex: 1 1 150px; min-width: 150px; }
.cus-stat-value {
  font-size: clamp(16px, 1.5vw, 22px);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* 总览卡补充：可点击（业务类型卡）/ 存量指标的占比条 */
.ov-card.ov-clickable { cursor: pointer; }
.ov-card.ov-clickable:hover { background: var(--bg-elevated, #faf9f6); }
.ov-gauge { display: flex; flex-direction: column; justify-content: center; gap: 5px; flex: 1 1 auto; min-height: 34px; height: auto; }
.ov-gauge-head { display: flex; align-items: baseline; justify-content: space-between; font-size: 11px; color: var(--text-secondary); }
.ov-gauge-head b { font-size: 12px; color: var(--text-primary); }
.ov-gauge-foot { font-size: 10px; color: var(--text-secondary); }
.ov-gauge .ov-bar-track { display: block; }

/* ===== 物料编辑：安全库存/最高库存「自动计算」工具条 ===== */
.stock-calc-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin: 2px 0 4px; padding: 8px 10px;
  background: var(--bg-elevated, #faf9f6);
  border: 1px solid var(--border-light); border-radius: 8px;
}
.stock-calc-bar .sc-item { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--text-dim); }
.stock-calc-bar .sc-review { width: 64px; height: 26px; padding: 2px 6px; }
.sc-z-chip {
  border: 1px solid var(--border-light); background: var(--white, #fff); color: var(--text-secondary);
  border-radius: 999px; padding: 2px 10px; font-size: var(--fs-xs); cursor: pointer; line-height: 1.6;
}
.sc-z-chip:hover { border-color: var(--brand); color: var(--brand); }
.sc-z-chip.active { background: var(--brand); border-color: var(--brand); color: var(--white, #fff); }
.stock-calc-out { font-size: var(--fs-sm); color: var(--text-secondary); line-height: 1.8; margin-top: 2px; }
.stock-calc-out b { color: var(--brand); }
