:root {
    --bom-primary: #2563eb;
    --bom-primary-dark: #1d4ed8;
    --bom-primary-050: #eff6ff;
    --bom-primary-100: #dbeafe;
    --bom-accent: #0d9488;
    --bom-danger: #dc2626;
    --bom-warn: #ea580c;
    --bom-ok: #16a34a;
    --bom-ink: #1f2937;
    --bom-muted: #6b7280;
    --bom-border: #e5e7eb;
    --bom-bg: #f4f6f9;
}

html, body { height: 100%; margin: 0; font-family: Arial, "Microsoft YaHei", "Segoe UI", system-ui, sans-serif; background: var(--bom-bg); color: var(--bom-ink); }

/* 统一主色按钮 */
.btn-primary { background: var(--bom-primary); border-color: var(--bom-primary); }
.btn-primary:hover, .btn-primary:focus { background: var(--bom-primary-dark); border-color: var(--bom-primary-dark); }
.btn-outline-primary { color: var(--bom-primary); border-color: var(--bom-primary); }
.btn-outline-primary:hover { background: var(--bom-primary); border-color: var(--bom-primary); }
a { color: var(--bom-primary); }

/* ---- shell ---- */
.bom-shell { display: flex; min-height: 100vh; }
/* 深色侧栏用带蓝调的墨色而非纯灰，和主色同色系，观感更整体 */
.bom-sidebar {
    width: 220px; flex-shrink: 0;
    background: linear-gradient(180deg, #1e293b 0%, #172033 100%);
    color: #cbd5e1;
    display: flex; flex-direction: column;
    border-right: 1px solid #0f172a;
}
.bom-brand {
    font-size: 1.05rem; font-weight: 700; color: #fff;
    padding: 18px 16px; letter-spacing: .3px;
    border-bottom: 1px solid rgba(148, 163, 184, .18);
}
.bom-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.bom-topbar { height: 54px; background: #fff; border-bottom: 1px solid #e5e7eb; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; }

/* ---- 「已打开页面」页签栏：顶栏下独立一行 ---- */
.page-tabs-shell { display: flex; align-items: stretch; min-width: 0; background: #f8fafc; border-bottom: 1px solid #e5e7eb; }
.page-tabs { flex: 1 1 auto; min-width: 0; display: flex; align-items: flex-end; gap: 2px; padding: 6px 8px 0 12px; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.page-tabs::-webkit-scrollbar { display: none; }
.ptab { display: flex; align-items: center; gap: 6px; padding: 7px 10px; font-size: .84rem; color: #64748b; background: #eef2f7; border: 1px solid #e2e8f0; border-bottom: none; border-radius: 8px 8px 0 0; cursor: pointer; white-space: nowrap; user-select: none; transition: background .12s, color .12s; outline: none; }
.ptab:hover { background: #e2e8f0; color: #1f2937; }
.ptab:focus-visible { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--bom-primary) 38%, transparent); }
.ptab.active { background: #fff; color: var(--bom-primary); font-weight: 600; border-color: #e5e7eb; position: relative; }
.ptab.active::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: #fff; }
.ptab.active::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; background: var(--bom-primary); border-radius: 2px 2px 0 0; }
.ptab-x { display: inline-grid; place-items: center; width: 20px; height: 20px; padding: 0; font-size: .95rem; line-height: 1; color: inherit; background: transparent; border: 0; opacity: .5; border-radius: 50%; }
.ptab-x:hover { opacity: 1; background: #cbd5e1; color: #dc2626; }
.ptab-pin { font-size: .78rem; color: var(--bom-primary); }
.ptab-dirty { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: #f59e0b; box-shadow: 0 0 0 2px #fff; }
.tab-manager-btn { flex: 0 0 auto; display: flex; align-items: center; gap: 5px; margin: 5px 8px 5px 0; padding: 0 10px; color: #475569; background: #fff; border: 1px solid #dbe2ea; border-radius: 7px; font-size: .78rem; }
.tab-manager-btn:hover { color: var(--bom-primary); border-color: color-mix(in srgb, var(--bom-primary) 45%, #dbe2ea); }
.tab-manager-menu { position: fixed; z-index: 1052; top: 88px; right: 12px; width: min(330px, calc(100vw - 24px)); max-height: min(560px, calc(100vh - 110px)); display: flex; flex-direction: column; background: #fff; border: 1px solid #dbe2ea; border-radius: 10px; box-shadow: 0 16px 42px rgba(15,23,42,.18); overflow: hidden; }
.tab-manager-head { display: flex; align-items: center; justify-content: space-between; padding: 11px 13px; color: #334155; border-bottom: 1px solid #eef2f7; }
.tab-manager-head span { min-width: 24px; padding: 1px 7px; color: #64748b; background: #f1f5f9; border-radius: 999px; text-align: center; font-size: .78rem; }
.tab-manager-list { padding: 5px; overflow-y: auto; }
.tab-manager-item { width: 100%; display: flex; align-items: center; gap: 9px; padding: 8px 9px; color: #475569; background: transparent; border: 0; border-radius: 7px; text-align: left; font-size: .86rem; }
.tab-manager-item:hover { background: #f1f5f9; color: #1f2937; }
.tab-manager-item.active { color: var(--bom-primary); background: color-mix(in srgb, var(--bom-primary) 9%, white); font-weight: 600; }
.tab-manager-item > span:nth-child(2) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tab-manager-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 8px; border-top: 1px solid #eef2f7; }
.tab-manager-actions button { padding: 7px 8px; color: #475569; background: #fff; border: 1px solid #dbe2ea; border-radius: 7px; font-size: .8rem; }
.tab-manager-actions button:hover { color: var(--bom-primary); background: #f8fafc; }
.tab-manager-hint { padding: 0 10px 9px; color: #94a3b8; font-size: .72rem; text-align: center; }
/* 手机屏太窄放不下页签栏，走底部标签导航 */
@media (max-width: 640px) { .page-tabs-shell { display: none; } }

/* ---- 商品分类树（参考旧系统类别树） ---- */
.cat-tree-root { padding: 4px 0; }
.ct-node { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-radius: 6px; font-size: .92rem; }
.ct-node:hover { background: #f1f5f9; }
.ct-root { font-size: 1rem; padding-left: 6px !important; }
.ct-toggle { cursor: pointer; color: #94a3b8; font-size: .9rem; width: 18px; text-align: center; }
.ct-toggle:hover { color: var(--bom-primary); }
.ct-toggle-ph { width: 18px; display: inline-block; }
.ct-ico { color: #f59e0b; font-size: 1rem; }
.ct-actions { margin-left: auto; display: none; gap: 4px; }
.ct-node:hover .ct-actions { display: inline-flex; }
.ct-sel { background: #e0f2f1; color: #0f766e; }
.ct-sel:hover { background: #d3ecea; }
/* 分类树节点角标：本分类含子分类的物料数（CategoryTree 组件） */
.ct-count { margin-left: auto; flex: 0 0 auto; font-size: 11px; font-weight: 600; color: #94a3b8; background: #e8edf2; border-radius: 8px; min-width: 22px; padding: 1px 5px; text-align: center; }
.ct-sel .ct-count { color: #0f766e; background: #c8e6e2; }
/* 停用分类（只有分类管理页会显示，IncludeDisabled=true）：灰显但仍可点，
   否则停用过的分类等于从左树消失，想改回启用都找不到入口。 */
.ct-node.ct-off { color: #9aa6b4; }
.ct-node.ct-off .ct-ico { color: #b6c0cc; }
.ct-node.ct-off > span:not(.ct-count) { text-decoration: line-through; text-decoration-color: #c4cdd8; }
/* 隐藏滚动条但保留滚动能力（滚轮/触摸板照常）——侧栏面板用，视觉更干净 */
.no-scrollbar { scrollbar-width: none; -ms-overflow-style: none; }
.no-scrollbar::-webkit-scrollbar { display: none; }

/* 单据编辑页结算区：标签同一水平线 + 加粗着色 */
.settle-row .bom-field label, .settle-row > .col-settle-due > label { display: block; font-weight: 700; color: var(--bom-primary); margin-bottom: 6px; white-space: nowrap; }
.settle-row .dict-hint { color: var(--bom-primary); }
.settle-due { text-align: right; }
.settle-due .sd-val { font-size: 1.35rem; font-weight: 700; color: #dc2626; line-height: 38px; }

/* 数据字典左侧类型分组 */
.dict-group-title { font-size: .76rem; font-weight: 600; color: #94a3b8; letter-spacing: .05em; padding: 10px 6px 4px; border-bottom: 1px solid #f1f5f9; margin-bottom: 4px; }
.dict-group-title:first-child { padding-top: 2px; }

/* ---- 页签右键菜单 ---- */
.ctx-backdrop { position: fixed; inset: 0; z-index: 1050; }
.ctx-menu { position: fixed; z-index: 1051; background: #fff; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.14); padding: 4px; min-width: 140px; }
.ctx-item { display: flex; align-items: center; gap: 8px; padding: 7px 14px; font-size: .86rem; color: #374151; border-radius: 6px; cursor: pointer; white-space: nowrap; }
.ctx-item:hover { background: #f1f5f9; color: var(--bom-primary); }
.ctx-item .bi { font-size: .8rem; opacity: .7; }
.bom-user { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.bom-hamburger { display: none; background: none; border: none; font-size: 1.5rem; color: #374151; cursor: pointer; padding: 2px 8px; line-height: 1; }
.bom-backdrop { display: none; }

/* ---- 桌面端侧栏折叠：点顶栏按钮隐藏/显示左侧导航，内容区全宽（宽表格页用） ---- */
.bom-navtoggle { background: none; border: none; font-size: 1.25rem; color: #475569; cursor: pointer; padding: 2px 8px; line-height: 1; border-radius: 8px; }
.bom-navtoggle:hover { background: #f1f5f9; color: var(--bom-primary); }
@media (min-width: 769px) {
    .bom-shell.nav-collapsed .bom-sidebar { display: none; }
}
@media (max-width: 768px) {
    /* 移动端用抽屉汉堡，折叠按钮隐藏 */
    .bom-navtoggle { display: none; }
}

/* ---- 全局错误兜底卡片（ErrorBoundary） ---- */
.bom-errbox { max-width: 420px; margin: 64px auto; text-align: center; padding: 32px 24px;
  background: #fff; border: 1px solid #eef0f4; border-radius: 14px; box-shadow: 0 6px 24px rgba(30,41,59,.06); }
.bom-errbox > .bi { font-size: 40px; color: #f59e0b; }
.bom-errtitle { font-size: 17px; font-weight: 600; color: #334155; margin-top: 10px; }
.bom-errsub { font-size: 13px; color: #94a3b8; margin: 6px 0 18px; }

/* ---- 列表表头点击排序 ---- */
.th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.th-sort:hover { color: var(--bom-primary); }
.th-sort .sort-ind { color: var(--bom-primary); font-size: .78rem; margin-left: 2px; }
/* 静默刷新：旧表格保留轻微变淡，数据回来直接替换，不整块闪转圈 */
.list-refreshing { opacity: .55; pointer-events: none; transition: opacity .15s; }
.bom-invalid-focus { border-color: #dc2626 !important; box-shadow: 0 0 0 .2rem rgba(220,38,38,.14) !important; }
/* 未保存提示：胸牌式黄底深字。原来是深橙裸文字，放在蓝色渐变单据头上完全看不清 */
.unsaved-hint { display: inline-flex; align-items: center; gap: 6px; color: #92400e; background: #fef3c7; border: 1px solid #f59e0b; border-radius: 999px; padding: 2px 10px; font-size: .78rem; font-weight: 600; white-space: nowrap; }
.unsaved-hint::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #f59e0b; }
.feedback-host { position: fixed; right: 18px; bottom: 18px; z-index: 2000; width: min(430px, calc(100vw - 28px)); display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
.feedback-toast { display: grid; grid-template-columns: auto minmax(0,1fr) auto auto; align-items: center; gap: 10px; padding: 11px 12px; color: #fff; border-radius: 9px; box-shadow: 0 12px 30px rgba(15,23,42,.2); pointer-events: auto; animation: feedback-in .18s ease-out; }
.feedback-toast.success { background: #15803d; }
.feedback-toast.warn { background: #b45309; }
.feedback-toast.error { background: #b91c1c; }
.feedback-toast.info { background: #1d4ed8; }
.feedback-message { min-width: 0; line-height: 1.4; font-size: .86rem; overflow-wrap: anywhere; }
.feedback-retry, .feedback-close { color: inherit; background: transparent; border: 0; }
.feedback-retry { padding: 3px 8px; border: 1px solid rgba(255,255,255,.55); border-radius: 5px; font-size: .78rem; font-weight: 600; }
.feedback-retry:hover { background: rgba(255,255,255,.14); }
.feedback-close { padding: 3px; opacity: .75; }
.feedback-close:hover { opacity: 1; }
@keyframes feedback-in { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 640px) { .feedback-host { right: 14px; bottom: 76px; } }
/* 可点筛选的状态徽章 */
.badge.st-click { cursor: pointer; }
.badge.st-click:hover { filter: brightness(.94); }

/* ---- 单据编辑窗体右侧「商品联动信息区」 ---- */
.prod-side {
    flex: 0 0 300px; align-self: stretch; max-height: 62vh; overflow: auto;
    border: 1px solid #eef1f4; border-radius: 10px; padding: 10px; background: #fbfcfe;
}
/* 明细里可点的商品名 + 当前联动行高亮 */
.ps-linkname { color: var(--bom-primary); cursor: pointer; }
.ps-linkname:hover { text-decoration: underline; }
.ps-line-on { background: #e0f2f1; }
.ps-hint { color: #94a3b8; font-size: .84rem; text-align: center; padding: 36px 8px; line-height: 1.7; }
.ps-hint > .bi { font-size: 30px; display: block; margin-bottom: 8px; }
.ps-title { font-weight: 700; font-size: .9rem; color: #1f2937; margin-bottom: 6px; }
.ps-tabs { gap: 3px; margin-bottom: 8px; flex-wrap: nowrap; }
.ps-tabs .nav-link { padding: 2px 9px; font-size: .8rem; border-radius: 6px; color: #64748b; }
.ps-tabs .nav-link.active { background: var(--bom-primary); color: #fff; }
.ps-imgs { display: flex; flex-wrap: wrap; gap: 6px; }
.ps-imgs img { width: calc(50% - 3px); aspect-ratio: 1/1; object-fit: cover; border-radius: 8px; cursor: zoom-in; border: 1px solid #eef1f4; }
.ps-table { font-size: .78rem; }
.ps-table th { color: #94a3b8; font-weight: 600; white-space: nowrap; }
.ps-table td { white-space: nowrap; }
.ps-pager { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.ps-pager .btn { padding: 1px 8px; }
/* 图片放大：z-index 要压过单据弹窗(1050) */
.ps-preview { position: fixed; inset: 0; z-index: 1100; background: rgba(15,23,42,.72); display: flex; align-items: center; justify-content: center; padding: 24px; cursor: zoom-out; }
.ps-preview img { max-width: 92vw; max-height: 92vh; border-radius: 10px; box-shadow: 0 24px 60px rgba(0,0,0,.4); }
/* 窄屏：联动区落到明细下方，别把录单表格挤没 */
@media (max-width: 1200px) {
    .prod-side { flex: 1 1 100%; max-height: 300px; }
}

/* ---- 单据列表左侧「状态 / 年月」树 ---- */
.doc-tree-title { font-size: .76rem; font-weight: 600; color: #94a3b8; letter-spacing: .05em; padding: 2px 4px 6px; border-bottom: 1px solid #eef1f4; margin-bottom: 4px; }
.dt-node { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 6px 8px; border-radius: 6px; cursor: pointer; font-size: .9rem; }
.dt-node:hover { background: #f1f5f9; }
.dt-node.on { background: #e0f2f1; color: #0f766e; font-weight: 600; }
.dt-node.dt-sub { padding-left: 22px; font-size: .86rem; }
.dt-caret { color: #94a3b8; width: 14px; display: inline-block; }
.dt-caret:hover { color: var(--bom-primary); }
/* 窄屏把树收到列表上方，别把表格挤没了 */
@media (max-width: 900px) {
    .doc-tree { flex: 1 1 100% !important; max-height: 240px !important; }
}

/* ---- 列显隐面板（工具栏「字段」按钮） ---- */
.col-backdrop { position: fixed; inset: 0; z-index: 1040; }
/* 定位交给组件（position:fixed + JS 量按钮矩形，见 ColumnPicker.razor 的 PanelStyle）。
   这里只留外观；宽度必须与组件里的 PanelWidth 常量一致。 */
.col-panel {
    position: fixed; z-index: 1041;
    background: #fff; border: 1px solid #e5e7eb; border-radius: 8px;
    box-shadow: 0 8px 24px rgba(15,23,42,.14); padding: 10px 14px;
    /* 2026-09-03：面板头部加了「恢复默认」之后 190px 装不下，标题和两个链接
       会各自折成两行。给下限放宽并让头部一行排开。 */
    width: 240px; overflow: auto;
}
.col-panel .form-check { margin-bottom: 2px; white-space: nowrap; }
/* 头部一行：标题 + 全选 + 恢复默认，都不换行 */
.col-panel > .d-flex { white-space: nowrap; gap: 4px; }
.col-panel > .d-flex > span { flex: 1 1 auto; min-width: 0; }
.col-panel > .d-flex > .btn-link { flex: 0 0 auto; white-space: nowrap; text-decoration: none; }
.bom-username { color: #374151; font-size: .9rem; }
.bom-content { padding: 20px 24px; flex: 1; overflow: auto; }

/* ---- nav（可折叠一级/二级 + 统一图标）---- */
.bom-nav { padding: 6px 0; }
.bom-nav-group { display: flex; align-items: center; gap: 10px; cursor: pointer; color: #94a3b8; padding: 10px 16px; font-size: .82rem; font-weight: 600; user-select: none; transition: background .12s, color .12s; }
.bom-nav-group:hover { background: #273244; color: #e2e8f0; }
.bom-gico { font-size: 1rem; width: 20px; text-align: center; color: #64d1c9; }
.bom-gtext { flex: 1; letter-spacing: .02em; }
.bom-chev { font-size: .75rem; opacity: .55; transition: transform .18s; }
.bom-nav-group.open .bom-chev { transform: rotate(180deg); }
.bom-nav-sub { padding-bottom: 4px; }
.bom-nav-link { display: flex; align-items: center; gap: 10px; color: #cbd5e1; text-decoration: none; padding: 8px 16px 8px 30px; font-size: .9rem; transition: background .12s, color .12s; }
.bom-nav-link:hover { background: #374151; color: #fff; }
.bom-nav-link.active { background: var(--bom-primary); color: #fff; }
.bom-ico { font-size: .95rem; width: 18px; text-align: center; opacity: .8; }
.bom-nav-link:hover .bom-ico, .bom-nav-link.active .bom-ico { opacity: 1; }

/* ---- 单级模块导航（一级在侧栏，二级进 /module/{key} 图标页）---- */
.bom-nav-top { display: flex; align-items: center; gap: 10px; color: #cbd5e1; text-decoration: none; padding: 11px 16px; font-size: .92rem; font-weight: 500; user-select: none; border-left: 3px solid transparent; transition: background .12s, color .12s; }
.bom-nav-top:hover { background: #273244; color: #fff; }
.bom-nav-top.active { background: var(--bom-primary); color: #fff; border-left-color: #64d1c9; }
.bom-nav-top.active .bom-gico { color: #fff; }

/* ---- 模块启动页：二级功能图标宫格 ---- */
.mod-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 14px; margin-top: 6px; }
.mod-tile { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 20px 8px 16px; background: #fff; border: 1px solid var(--bom-border); border-radius: 12px; text-decoration: none; color: #1f2937; transition: box-shadow .15s, transform .15s, border-color .15s; }
.mod-tile:hover { border-color: var(--bom-primary); box-shadow: 0 8px 20px rgba(37,99,235,.12); transform: translateY(-2px); color: var(--bom-primary); }
.mt-ico { width: 52px; height: 52px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; color: #fff; }
.mt-text { font-size: .88rem; font-weight: 500; text-align: center; }
/* 图标底色循环：同一模块内相邻功能颜色错开，方便肉眼定位 */
.mt-c0 { background: linear-gradient(135deg,#2563eb,#3b82f6); }
.mt-c1 { background: linear-gradient(135deg,#0d9488,#14b8a6); }
.mt-c2 { background: linear-gradient(135deg,#d97706,#f59e0b); }
.mt-c3 { background: linear-gradient(135deg,#7c3aed,#8b5cf6); }
.mt-c4 { background: linear-gradient(135deg,#db2777,#ec4899); }
.mt-c5 { background: linear-gradient(135deg,#475569,#64748b); }
@media (max-width: 640px) { .mod-grid { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 10px; } }

/* ---- login ---- */
/* 登录页：简约浅色——近白底上两团极淡的品牌色光晕，卡片细边浅影 */
.bom-login-wrap {
    min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: 24px;
    background: #f6f8fb;
    background-image:
        radial-gradient(640px 420px at 12% 8%, rgba(37, 99, 235, .09), transparent 62%),
        radial-gradient(560px 400px at 88% 94%, rgba(79, 70, 229, .07), transparent 62%);
}
.bom-login-card {
    width: 384px; background: #fff;
    border: 1px solid #e8ecf3; border-radius: 16px;
    box-shadow: 0 12px 40px rgba(15, 23, 42, .08);
    padding: 40px 36px 32px;
}
.bom-login-logo {
    width: 52px; height: 52px; margin: 0 auto 16px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 14px; color: #fff; font-size: 1.45rem;
    background: linear-gradient(135deg, #2563eb, #4f46e5);
    box-shadow: 0 6px 16px rgba(37, 99, 235, .28);
}
.bom-login-title { text-align: center; font-size: 1.28rem; font-weight: 700; color: #111827; margin-bottom: 6px; letter-spacing: .3px; }
.bom-login-sub { text-align: center; color: #8b95a5; font-size: .84rem; margin-bottom: 28px; letter-spacing: .5px; }
.bom-login-card .form-label { font-size: .84rem; font-weight: 600; color: #4b5563; }
.bom-login-card .form-control {
    border-radius: 10px; border-color: #e2e7ef; background: #fafbfd;
    padding: .55rem .8rem; transition: border-color .15s, box-shadow .15s, background .15s;
}
.bom-login-card .form-control:focus { background: #fff; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, .12); }
.bom-login-card .btn-primary {
    border-radius: 10px; padding: .6rem; font-weight: 600; letter-spacing: 2px;
    background: linear-gradient(135deg, #2563eb, #3b5bdb); border: none;
    box-shadow: 0 4px 12px rgba(37, 99, 235, .22);
}
.bom-login-card .btn-primary:hover:not(:disabled) { filter: brightness(1.06); }
/* ICP 备案 footer：备案审核要求未登录即可见且清晰可读——灰色小字但不淡到看不清 */
.bom-login-footer { margin-top: 20px; text-align: center; color: #6b7280; font-size: .8rem; letter-spacing: .3px; }
.bom-login-footer a { color: #6b7280; text-decoration: none; }
.bom-login-footer a:hover { color: #2563eb; text-decoration: underline; }

/* ---- page bits ---- */
.bom-page-title { font-size: 1.35rem; font-weight: 800; color: #0f172a; letter-spacing: .2px; margin: 0 0 16px; }
.bom-toolbar { display: flex; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; align-items: center; }
.card-surface {
    background: #fff;
    border: 1px solid var(--bom-border);
    border-radius: 12px;
    padding: 16px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 1px 3px rgba(15, 23, 42, .03);
}
.table-sm td, .table-sm th { vertical-align: middle; }

/* 表头：深色加粗，和数据行拉开层级、字段标题一眼可辨 */
.card-surface > table.table thead th {
    font-size: .82rem; font-weight: 800;
    letter-spacing: .2px; color: #0f172a;
    text-transform: none;
    padding-top: 11px; padding-bottom: 11px;
    background: #f8fafc;
    border-bottom: 2px solid var(--bom-border);
}
.card-surface > table.table tbody td { padding-top: 9px; padding-bottom: 9px; }

/* 数字列用等宽字形对齐——金额/数量右对齐时小数点不齐会显得很廉价 */
.table .text-end { font-variant-numeric: tabular-nums; }

/* 明细查询状态徽章：已审核/已确认=蓝，草稿/已保存=灰（参考香橙系统） */
.det-badge { display: inline-block; padding: 2px 10px; border-radius: 6px; font-size: .76rem; font-weight: 700; color: #fff; white-space: nowrap; }
.det-badge-ok { background: #2563eb; }
.det-badge-draft { background: #94a3b8; }

/* 统计图表：横向排行条形图（蓝色渐变，参考香橙系统） */
.bom-bars { display: flex; flex-direction: column; gap: 6px; }
.bom-bar-row { display: flex; align-items: center; gap: 10px; }
.bom-bar-label { width: 220px; flex: 0 0 220px; font-size: .85rem; }
.bom-bar-track { flex: 1 1 auto; background: #eef2f7; border-radius: 5px; height: 22px; overflow: hidden; }
.bom-bar-fill { height: 100%; background: linear-gradient(90deg, #2f6fed, #5b9bff); border-radius: 5px; min-width: 2px; transition: width .3s; }
.bom-bar-fill.neg { background: linear-gradient(90deg, #e03131, #ff6b6b); }
.bom-bar-val { width: 120px; flex: 0 0 120px; text-align: right; font-weight: 600; font-size: .85rem; font-variant-numeric: tabular-nums; }
@media (max-width: 768px) { .bom-bar-label { width: 120px; flex-basis: 120px; } .bom-bar-val { width: 84px; flex-basis: 84px; } }

/* 低于安全库存：整行淡红底 + 左侧红条。
   只把数量标红不够——列表长了以后要扫一眼就能找到哪几行需要补货。
   优先级要高过斑马纹，故用 !important 覆盖 :nth-child(even)。 */
.card-surface > table.table tbody tr.row-lowstock > * { background: #fef2f2 !important; }
.card-surface > table.table tbody tr.row-lowstock > *:first-child { box-shadow: inset 3px 0 0 var(--bom-danger); }
.card-surface > table.table tbody tr.row-lowstock:hover > * { background: #fee2e2 !important; }

/* ---- 单据行内展开明细（采购/销售/出入库/调拨/盘点共用） ---- */

/* 展开中的主行：浅底 + 左侧主色竖条，一眼看出明细属于哪一行。
   竖条只加在首个单元格上——加在 `> *` 会让每个 td 都画一条，整行变成栅格。 */
.card-surface > table.table tbody tr.row-expanded > * { background: var(--bom-primary-050); }
.card-surface > table.table tbody tr.row-expanded > *:first-child { box-shadow: inset 3px 0 0 var(--bom-primary); }

/* 明细行不参与主表的斑马纹和 hover，否则会被误认成一条单据 */
.card-surface > table.table tbody tr.detail-row > *,
.card-surface > table.table tbody tr.detail-row:hover > * { background: #f7f9fc; }

.detail-panel {
    padding: 10px 14px 12px 40px;   /* 左内缩，与展开箭头对齐，形成从属层级 */
    border-bottom: 1px solid var(--bom-border);
}

.detail-table { background: #fff; border: 1px solid var(--bom-border); border-radius: 8px; overflow: hidden; }
.detail-table thead th {
    background: #eef2f7; font-size: .78rem; font-weight: 800;
    color: #0f172a; letter-spacing: .2px;
    padding: 7px 10px; border-bottom: 1px solid var(--bom-border);
}
.detail-table tbody td { padding: 7px 10px; font-size: .88rem; }
.detail-table tbody tr:hover > * { background: var(--bom-primary-050); }
.detail-table tfoot td {
    padding: 7px 10px; font-size: .85rem;
    background: #fafbfc; border-top: 2px solid var(--bom-border);
}
.detail-table .text-end { font-variant-numeric: tabular-nums; }

.btn { border-radius: 8px; font-weight: 500; }
.btn-sm { border-radius: 6px; }
.badge { font-weight: 600; letter-spacing: .2px; padding: .35em .6em; border-radius: 6px; }
.form-control, .form-select { border-radius: 8px; }
.bom-modal-backdrop {
    position: fixed; inset: 0; z-index: 1050;
    background: rgba(15, 23, 42, .55);
    backdrop-filter: blur(2px);
    display: flex; align-items: center; justify-content: center;
    padding: 24px;
    animation: bom-fade .12s ease-out;
}

/* 横长方形：宽 880px、整体高度压到 78vh 以内。
   关键是 flex 列 + 只让 body 滚动——头尾固定，标题和「保存」按钮永远可见，
   不必为了点保存先滚到底。原先整个弹窗一起滚（width:520 + overflow:auto），
   字段一多就变成又窄又高的长条。 */
.bom-modal {
    width: 880px; max-width: calc(100vw - 48px);
    max-height: 78vh;
    display: flex; flex-direction: column;
    background: #fff; border-radius: 14px;
    box-shadow: 0 24px 60px rgba(15, 23, 42, .28), 0 2px 8px rgba(15, 23, 42, .12);
    overflow: hidden;
    animation: bom-pop .14s ease-out;
}

/* 窄弹窗（改密码、单字段确认之类），逐页按需加 .bom-modal-sm */
.bom-modal-sm { width: 460px; }

/* 单据编辑弹窗：整张单（基本信息 + 明细表 + 结算区）要装得下，比表单弹窗再宽再高一档。
   吸底操作条（.doc-actionbar 是 sticky bottom）在这里吸的是弹窗body的底，正好是要的效果。 */
/* 注意特异性：.bom-form-modal 定义在后面，同为单类选择器会盖掉这里，
   所以单据弹窗必须写成 .bom-modal.bom-modal-doc（两个类）才压得住。 */
.bom-modal.bom-modal-doc { width: 1680px; max-width: 98vw; max-height: 94vh; }
.bom-modal-doc .bom-form-body { padding: 14px 18px 0; }
.bom-modal-doc .card-surface { box-shadow: none; border: 1px solid var(--bom-border); }
/* 明细表头不许折行：「不含税单价」被挤成「不含税单/价」两行很难看，宁可让表格自己横向滚 */
.bom-modal-doc thead th, .doc-edit thead th { white-space: nowrap; }
/* 结算区标签本来是 nowrap，长标题会把弹窗顶出横向滚动条；这里允许它收缩 */
.bom-modal-doc .settle-row .col-settle-due > label { white-space: normal; }

/* ================= 精致表单弹窗 =================
   从「香橙科技贸易系统」AppBase 移植，与那套保持同一视觉语言。
   用法：.bom-modal.bom-form-modal + .bom-form-head + .bom-form-body + .bom-fsec 分节。
   与朴素的 .bom-modal-head/.bom-modal-body 并存，逐页按需替换。 */
.bom-form-modal { width: 1080px; max-width: 94vw; }
.bom-form-head {
    display: flex; align-items: center; gap: 12px; padding: 13px 24px;
    background: linear-gradient(135deg, #2f6fed, #4a86f7); color: #fff;
    border-radius: 14px 14px 0 0;
    flex-shrink: 0;
}
/* 蓝色渐变头上的 outline 按钮：透明底+彩字在蓝底上看不清（销售单头部的单据按钮等）。
   统一垫白底，文字颜色沿用各自的 outline 色，悬停微加深。 */
.bom-form-head .btn-outline-primary, .bom-form-head .btn-outline-secondary,
.bom-form-head .btn-outline-success, .bom-form-head .btn-outline-info,
.bom-form-head .btn-outline-dark, .bom-form-head .btn-outline-danger {
    background: rgba(255,255,255,.94);
    border-color: rgba(255,255,255,.94);
}
.bom-form-head .btn-outline-primary:hover, .bom-form-head .btn-outline-secondary:hover,
.bom-form-head .btn-outline-success:hover, .bom-form-head .btn-outline-info:hover,
.bom-form-head .btn-outline-dark:hover, .bom-form-head .btn-outline-danger:hover {
    background: #fff; border-color: #fff;
}
/* 禁用态也要能辨认（只读单据头的置灰单据按钮） */
.bom-form-head .btn:disabled { background: rgba(255,255,255,.72); color: #64748b; border-color: transparent; opacity: 1; }
.bom-form-head .fh-ico {
    width: 36px; height: 36px; border-radius: 10px; background: rgba(255,255,255,.2);
    display: flex; align-items: center; justify-content: center; font-size: 18px;
    flex-shrink: 0;
}
.bom-form-head .fh-title { font-size: 16px; font-weight: 600; line-height: 1.2; }
.bom-form-head .fh-sub { font-size: 12px; opacity: .85; }
/* 标题块要能压缩：长编码不该把关闭按钮挤出去 */
.bom-form-head .fh-main { min-width: 0; flex: 1 1 auto; }
.bom-form-head .fh-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 右上角关闭：蓝底上用半透明白，别用默认的深色 outline（在蓝底上几乎看不见） */
.bom-form-head .modal-close {
    width: 32px; height: 32px; flex: none; margin-left: auto; border-radius: 8px;
    border: 1px solid rgba(255,255,255,.35); background: rgba(255,255,255,.16); color: #fff;
    display: grid; place-items: center; transition: background .15s;
}
.bom-form-head .modal-close:hover { background: rgba(255,255,255,.3); }
/* 表单主体：弹窗高度有限，内容多时这里滚动 */
.bom-form-body { padding: 14px 24px 6px; overflow-y: auto; flex: 1 1 auto; }

/* 分节标题：左侧色条 + 图标 */
.bom-fsec {
    display: flex; align-items: center; gap: 8px;
    font-weight: 600; color: #2758af; font-size: 13.5px;
    margin: 14px 0 10px; padding-left: 10px; border-left: 3px solid #2f6fed;
}
.bom-fsec:first-child { margin-top: 4px; }
.bom-fsec .bi { color: #2f6fed; }

.bom-field { margin-bottom: 11px; }
/* 字段标签：加粗深色（全站表单统一，看着更清楚） */
.bom-field > label { display: block; font-size: 12.5px; color: #1f2937; margin-bottom: 3px; font-weight: 700; }
.bom-field .req { color: #e03131; margin-left: 2px; }
.bom-field .form-control, .bom-field .form-select { height: 38px; border-radius: 8px; border-color: #dfe4ec; font-size: 14px; }
.bom-field textarea.form-control { height: auto; }
.bom-field .form-control:focus, .bom-field .form-select:focus { border-color: #2f6fed; box-shadow: 0 0 0 3px rgba(47,111,237,.12); }

/* ---- 商品图片 ---- */
/* 列表缩略图 */
.prod-thumb {
    width: 34px; height: 34px; border-radius: 6px; object-fit: cover;
    border: 1px solid var(--bom-border); background: #fff; display: block;
}
.prod-thumb-empty {
    display: flex; align-items: center; justify-content: center;
    color: #cbd5e1; background: #f8fafc; font-size: .9rem;
}
.prod-img-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }
/* 编辑弹窗里的图片网格 */
.prod-img-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.prod-img-cell {
    position: relative; width: 104px; height: 104px;
    border: 1px solid var(--bom-border); border-radius: 8px; overflow: hidden; background: #f8fafc;
}
.prod-img-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.prod-img-cell.is-main { border-color: var(--bom-primary); box-shadow: 0 0 0 2px rgba(37,99,235,.18); }
.prod-img-cell .pic-main-tag {
    position: absolute; left: 0; top: 0; background: var(--bom-primary); color: #fff;
    font-size: .62rem; padding: 1px 6px; border-radius: 0 0 6px 0;
}
/* 操作按钮平时藏起来，悬停/聚焦才出现，免得盖住图 */
.prod-img-cell .pic-acts {
    position: absolute; right: 3px; bottom: 3px; display: flex; gap: 3px;
    opacity: 0; transition: opacity .12s;
}
.prod-img-cell:hover .pic-acts, .prod-img-cell:focus-within .pic-acts { opacity: 1; }
.prod-img-cell .pic-acts .btn { padding: 1px 6px; line-height: 1.2; }

/* 下方页签里的图片格子略大些，便于看清 */
.prod-img-cell-lg { width: 132px; height: 132px; }

/* 组合框的小提示图标：告诉用户这个字段有候选值可选 */
.dict-hint { color: #94a3b8; font-size: .78rem; margin-left: 2px; cursor: help; }

/* 订单履行进度徽标（发货/收款/开票、到货/付款/开票）：按完成度上色 */
.fulfill {
    display: inline-block; min-width: 46px; padding: 1px 8px; border-radius: 10px;
    font-size: .78rem; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.fulfill.ff-none { background: #f1f5f9; color: #94a3b8; }              /* 未开始：灰 */
.fulfill.ff-part { background: #fff3e0; color: #c05621; }              /* 部分完成：橙，提示还欠 */
.fulfill.ff-done { background: #e8f5ee; color: #16a34a; }              /* 已结清：绿 */

/* 明细小计行：与数据行拉开区分，数字用等宽对齐 */
.card-surface > table.table tfoot tr.mov-subtotal > * {
    background: #f8fafc;
    font-weight: 700;
    border-top: 2px solid var(--bom-border);
    font-variant-numeric: tabular-nums;
}

/* 只读字段（如自动生成的编码）：一眼看出不是给你填的 */
.bom-field .form-control[readonly] {
    background: #f4f6f9; color: #6b7280; cursor: not-allowed;
    border-style: dashed;
}
.bom-field .form-control[readonly]:focus { border-color: #dfe4ec; box-shadow: none; }

/* 组合框 + 右侧「＋」按钮：贴合成一个整体控件 */
.dict-combo { display: flex; position: relative; }
/* 自绘候选下拉（2026-08-13：点击即弹，替代行为不稳的 datalist） */
.dict-combo .dict-list {
    position: absolute; top: 100%; left: 0; right: 38px; z-index: 2300;
    background: #fff; border: 1px solid #dfe4ec; border-radius: 6px;
    box-shadow: 0 6px 18px rgba(15, 23, 42, .12);
    max-height: 240px; overflow: auto; margin-top: 2px;
}
.dict-combo .dict-item { padding: 6px 10px; cursor: pointer; font-size: .9rem; }
.dict-combo .dict-item:hover { background: #f1f5f9; }
.dict-combo .dict-item.sel { background: #e8f0fe; color: var(--bom-primary); }
.dict-combo .form-control {
    border-top-right-radius: 0; border-bottom-right-radius: 0;
    border-right: none; min-width: 0;
}
.dict-combo .dict-add {
    flex: 0 0 auto; height: 38px; padding: 0 9px;
    border-top-left-radius: 0; border-bottom-left-radius: 0;
    display: flex; align-items: center; border-color: #dfe4ec; color: var(--bom-primary);
}
.dict-combo .dict-add:hover { background: var(--bom-primary); border-color: var(--bom-primary); color: #fff; }
/* 快速新增弹窗盖在商品弹窗之上 */
.dict-add-backdrop { z-index: 2200; }

/* ---- 图片预览（点缩略图放大）---- */
.img-viewer {
    position: fixed; inset: 0; z-index: 2500;
    background: rgba(15, 23, 42, .82);
    display: flex; align-items: center; justify-content: center;
    padding: 40px;
    animation: bom-fade .12s ease-out;
}
.img-viewer > img {
    max-width: 92vw; max-height: 84vh;
    border-radius: 8px; background: #fff;
    box-shadow: 0 24px 60px rgba(0,0,0,.5);
    object-fit: contain;
}
.img-viewer .iv-close {
    position: absolute; top: 16px; right: 20px;
    width: 38px; height: 38px; border-radius: 50%;
    border: none; background: rgba(255,255,255,.16); color: #fff; font-size: 1rem;
    cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.img-viewer .iv-close:hover { background: rgba(255,255,255,.3); }
.img-viewer .iv-nav {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 42px; height: 42px; border-radius: 50%;
    border: none; background: rgba(255,255,255,.16); color: #fff; font-size: 1.2rem;
    cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.img-viewer .iv-nav:hover { background: rgba(255,255,255,.3); }
.img-viewer .iv-prev { left: 18px; }
.img-viewer .iv-next { right: 18px; }
.img-viewer .iv-cap {
    position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%);
    color: #e2e8f0; font-size: .8rem; display: flex; align-items: center; gap: 10px;
    background: rgba(0,0,0,.35); padding: 5px 12px; border-radius: 20px; max-width: 80vw;
}
.img-viewer .iv-idx { color: #94a3b8; }

@keyframes bom-fade { from { opacity: 0; } to { opacity: 1; } }

/* ---- 商品搜索选择器 ---- */
.ppk { position: relative; }
/* 定位(fixed + 坐标)由组件内联样式给出：JS 量输入框视口位置，
   彻底避开表格 overflow 容器的裁剪。这里只管外观。 */
.ppk-drop {
    z-index: 1500;
    background: #fff; border: 1px solid var(--bom-border); border-radius: 8px;
    box-shadow: 0 10px 30px rgba(15,23,42,.15);
    max-height: 280px; overflow-y: auto;
    max-width: 560px;
}
.ppk-item {
    display: flex; gap: 8px; align-items: baseline;
    padding: 6px 10px; cursor: pointer; font-size: .85rem;
}
.ppk-item:hover { background: var(--bom-primary-050); }
.ppk-item.ppk-hi { background: var(--bom-primary-100); }   /* 键盘高亮行 */
.ppk-code { font-weight: 600; color: var(--bom-primary); flex-shrink: 0; }
.ppk-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ppk-unit { color: var(--bom-muted); font-size: .75rem; flex-shrink: 0; }
/* 第二识别键（图号等）在候选行里的样子：等宽字体 + 浅框，与商品名拉开，
   扫一眼就能对上工程师报的那串图号 */
.ppk-key {
    flex-shrink: 0; max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    padding: 1px 7px; border: 1px solid #dbe6f7; border-radius: 5px;
    background: #f2f7ff; color: #2f6fed; font-size: .74rem; font-weight: 600;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.ppk-more { padding: 6px 10px; color: var(--bom-muted); font-size: .78rem; background: #f8fafc; }

/* ---- 单据编辑页吸底操作条：明细行多时不用滚到底找保存按钮 ---- */
.doc-actionbar {
    position: sticky; bottom: 0; z-index: 100;
    background: #fff; border-top: 2px solid var(--bom-border);
    padding: 10px 16px; margin: 0 -16px -16px;
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    box-shadow: 0 -4px 12px rgba(15,23,42,.06);
}
.doc-actionbar .dab-totals { display: flex; gap: 18px; font-size: .88rem; color: var(--bom-muted); flex-wrap: wrap; }
.doc-actionbar .dab-totals b { color: var(--bom-ink); font-variant-numeric: tabular-nums; }
.doc-actionbar .dab-grand b { color: var(--bom-danger); font-size: 1.05rem; }

/* 精致筛选栏 */
.bom-filter { background: #fff; border: 1px solid #eceff4; border-radius: 12px; padding: 14px 16px; margin-bottom: 14px; }
.bom-filter .ff-label { font-size: 12px; color: #6b7280; margin-bottom: 4px; display: block; }
.bom-filter .form-control, .bom-filter .form-select { height: 38px; border-radius: 8px; font-size: 13.5px; }
.bom-filter .wf-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.bom-filter .wf-item { flex: 1 1 130px; min-width: 112px; }
.bom-filter .wf-btns { flex: 0 0 auto; display: flex; gap: 8px; flex-wrap: wrap; }

/* 简版弹窗头：与 .bom-form-head 同款渐变，但不带图标/副标题。
   目前各页都已改用 .bom-form-head；这条留给只有一个标题、不值得配图标的新弹窗。 */
.bom-modal-head {
    flex: 0 0 auto;
    padding: 14px 24px;
    background: linear-gradient(135deg, #2f6fed, #4a86f7);
    color: #fff;
    border-radius: 14px 14px 0 0;
    font-weight: 600; font-size: 16px; letter-spacing: .2px;
}

.bom-modal-body {
    flex: 1 1 auto;
    padding: 16px 24px 6px;
    overflow-y: auto;
}

/* 输入框向 AppBase 的精致风格看齐（圆角/描边/聚焦光晕），
   同样作用于所有还没逐页改造的弹窗。明细表里的 sm 控件不受影响。 */
.bom-modal-body .form-control:not(.form-control-sm),
.bom-modal-body .form-select:not(.form-select-sm) {
    height: 38px; border-radius: 8px; border-color: #dfe4ec; font-size: 14px;
}
.bom-modal-body textarea.form-control { height: auto; }

.bom-modal-foot {
    flex: 0 0 auto;
    padding: 14px 22px;
    border-top: 1px solid var(--bom-border);
    background: #fafbfc;
    display: flex; justify-content: flex-end; gap: 10px;
}

/* 宽弹窗里标签压得更紧，让「宽而矮」真正生效：
   高度省下来靠的是每行更矮 + 一行放更多字段，而不只是把框拉宽 */
.bom-modal .form-label { margin-bottom: 3px; font-size: 12.5px; font-weight: 700; color: #1f2937; }
.bom-modal .form-control, .bom-modal .form-select { border-color: #dfe4ec; }
.bom-modal .form-control:focus, .bom-modal .form-select:focus {
    border-color: #2f6fed;
    box-shadow: 0 0 0 3px rgba(47,111,237,.12);
}

@keyframes bom-fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes bom-pop { from { opacity: 0; transform: translateY(8px) scale(.99) } to { opacity: 1; transform: none } }

/* ---- dashboard KPI ---- */
/* minmax 从 150px 提到 190px：150px 装不下「待审核入库」这类 4 字标签，
   实测会断成「待审核入 / 库」。auto-fit 而非 auto-fill：让卡片撑满整行，
   避免末行只剩一个孤零零的卡片（原先 8+1 的布局）。 */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; }
.kpi {
    /* 现在是 <button>：清掉默认按钮样式 */
    appearance: none; font: inherit; text-align: left; width: 100%;
    background: #fff; border: 1px solid var(--bom-border);
    border-radius: 12px; padding: 16px; cursor: pointer;
    transition: box-shadow .15s, transform .15s;
}
.kpi:hover { box-shadow: 0 4px 14px rgba(15, 23, 42, .08); transform: translateY(-1px); }
.kpi-num { font-size: 1.7rem; font-weight: 700; color: var(--bom-ink); line-height: 1.1; font-variant-numeric: tabular-nums; }
/* 标签不换行：宁可省略号也不断字，断字比截断更难读 */
.kpi-label { color: var(--bom-muted); font-size: .85rem; margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi-warn .kpi-num { color: var(--bom-danger); }

/* 带图标的 KPI 卡（首页） */
.kpi-ico { display: flex; align-items: center; gap: 12px; }
.kpi-ico-badge { flex: 0 0 auto; width: 44px; height: 44px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 1.35rem; }
.kpi-ico-badge.c-blue { background: var(--bom-primary-100); color: var(--bom-primary); }
.kpi-ico-badge.c-teal { background: #ccfbf1; color: #0d9488; }
.kpi-ico-badge.c-amber { background: #ffedd5; color: #ea580c; }
.kpi-ico-badge.c-red { background: #fee2e2; color: #dc2626; }
.kpi-ico-badge.c-green { background: #dcfce7; color: #16a34a; }
.kpi-ico-badge.c-violet { background: #ede9fe; color: #7c3aed; }

/* 提醒卡 */
.alert-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.alert-card {
    /* 现在是 <button>：清掉浏览器默认按钮样式，并让文字左对齐（按钮默认居中） */
    appearance: none; font: inherit; text-align: left; width: 100%;
    display: flex; align-items: center; gap: 12px;
    background: #fff; border: 1px solid var(--bom-border);
    border-left: 4px solid var(--bom-primary);
    border-radius: 12px; padding: 14px 16px; cursor: pointer;
    transition: box-shadow .15s, transform .15s;
}
.alert-card:hover { box-shadow: 0 4px 14px rgba(15, 23, 42, .08); transform: translateY(-1px); }
.alert-card:focus-visible, .kpi:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--bom-primary-100), 0 4px 14px rgba(15, 23, 42, .08);
    border-color: var(--bom-primary);
}
.alert-card.warn { border-left-color: var(--bom-warn); }
.alert-card.danger { border-left-color: var(--bom-danger); }
.alert-card.ok { border-left-color: var(--bom-ok); }
.alert-card .ac-ico { font-size: 1.5rem; }
.alert-card .ac-num { font-size: 1.35rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.alert-card .ac-label { color: var(--bom-muted); font-size: .82rem; margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---- 表格增强：表头吸顶 + 斑马纹 ---- */
.card-surface { position: relative; }
.card-surface > table.table thead th { position: sticky; top: 0; z-index: 2; background: #f8fafc; box-shadow: inset 0 -1px 0 var(--bom-border); }
.table-hover > tbody > tr:hover > * { background: var(--bom-primary-050); }
.table > tbody > tr:nth-child(even) > * { background: #fbfcfe; }
.table > tbody > tr:nth-child(even):hover > * { background: var(--bom-primary-050); }

/* ---- 分页条 ---- */
.bom-pager { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.bom-pager .pg-info { color: var(--bom-muted); font-size: .85rem; }
.bom-pager .pg-spacer { margin-left: auto; }
.bom-pager .form-select-sm { width: auto; }

/* ---- 加载：转圈 + 骨架屏 ---- */
.bom-spinner { display: inline-block; width: 20px; height: 20px; border: 2.5px solid var(--bom-primary-100); border-top-color: var(--bom-primary); border-radius: 50%; animation: bom-spin .7s linear infinite; vertical-align: middle; }
.bom-loading { display: flex; align-items: center; gap: 10px; color: var(--bom-muted); padding: 8px 0; }
@keyframes bom-spin { to { transform: rotate(360deg); } }
.bom-skel-row { height: 38px; border-radius: 6px; margin-bottom: 8px; background: linear-gradient(90deg,#eef1f5 25%,#f6f8fb 37%,#eef1f5 63%); background-size: 400% 100%; animation: bom-shimmer 1.3s ease infinite; }
@keyframes bom-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* ---- 空状态 ---- */
.bom-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px 16px; color: var(--bom-muted); text-align: center; }
.bom-empty i { font-size: 2.6rem; opacity: .35; margin-bottom: 10px; }
.bom-empty .we-text { font-size: .95rem; }
.bom-empty .we-sub { font-size: .82rem; opacity: .8; margin-top: 4px; }

/* ================= 手机 / 窄屏适配（≤768px）================= */
@media (max-width: 768px) {
    /* 顶栏显示汉堡按钮 */
    .bom-hamburger { display: inline-flex; align-items: center; }
    .bom-topbar { padding: 0 12px; }

    /* 侧边栏改为可滑出的抽屉，默认隐藏在屏幕左外侧 */
    .bom-sidebar {
        position: fixed; top: 0; left: 0; bottom: 0;
        z-index: 1200; width: 78vw; max-width: 300px;
        transform: translateX(-100%); transition: transform .25s ease;
        box-shadow: 2px 0 14px rgba(0, 0, 0, .3); overflow-y: auto;
    }
    .bom-sidebar.open { transform: translateX(0); }

    /* 抽屉打开时的半透明遮罩，点击可关闭 */
    .bom-backdrop.show {
        display: block; position: fixed; inset: 0;
        background: rgba(0, 0, 0, .45); z-index: 1100;
    }

    /* 正文更贴边、标题略小 */
    .bom-content { padding: 12px; }
    .bom-page-title { font-size: 1.1rem; margin-bottom: 12px; }

    /* 关键：表格在卡片内横向滚动，不再撑破屏幕 */
    .card-surface { padding: 12px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .card-surface > table { white-space: nowrap; }

    /* 工具栏：搜索框占满一行，按钮自然换行 */
    .bom-toolbar { gap: 8px; }
    .bom-toolbar .form-control,
    .bom-toolbar .form-select { max-width: none !important; flex: 1 1 100%; }
    .bom-toolbar .ms-auto { margin-left: 0 !important; }

    /* 组合查询条件行例外：[且/或][字段][值] 得留在同一行，不能各占满一行 */
    .bom-qb { width: 100%; }
    .bom-qb .form-control,
    .bom-qb .form-select { flex: 0 1 auto; min-width: 0; }
    .bom-qb .form-control { flex: 1 1 auto; }

    /* 登录卡片与弹窗自适应窄屏 */
    .bom-login-card { width: auto; max-width: 92vw; }

    /* 窄屏放弃「宽而矮」：横向没有余地，改为占满并放高，否则 78vh 里塞不下一行两列 */
    .bom-modal-backdrop { padding: 0; align-items: flex-end; }
    .bom-modal, .bom-modal-sm {
        width: 100vw; max-width: 100vw;
        max-height: 92vh;
        border-radius: 14px 14px 0 0;
    }
    .bom-modal-head, .bom-modal-body, .bom-modal-foot { padding-left: 16px; padding-right: 16px; }
}

/* ================= 移动端底部标签栏 + 我的页 ================= */
.mobile-tabbar { display: none; }
.mine-header { background: linear-gradient(135deg, #1e3a8a, #2563eb); color: #fff; padding: 26px 20px; display: flex; align-items: center; gap: 14px; border-radius: 12px; }
.mine-avatar i { font-size: 3rem; opacity: .95; }
.mine-name { font-size: 1.3rem; font-weight: 700; }
.mine-role { color: #cbd5e1; font-size: .85rem; margin-top: 2px; }
.mine-menu { background: #fff; margin: 12px 0; border: 1px solid #eef2f7; border-radius: 12px; overflow: hidden; }
.mine-item { display: flex; align-items: center; gap: 12px; padding: 14px 18px; border-bottom: 1px solid #f1f5f9; color: #1f2937; cursor: pointer; }
.mine-item:last-child { border-bottom: none; }
.mine-item:active { background: #f8fafc; }
.mine-item > i:first-child { font-size: 1.2rem; color: #2563eb; width: 24px; text-align: center; }
.mine-arrow { margin-left: auto; color: #cbd5e1; font-size: .9rem; }
.mine-logout { color: #dc2626; justify-content: center; font-weight: 600; }
.mine-logout > i:first-child { color: #dc2626; }

@media (max-width: 768px) {
    /* 底栏是「基础外壳」，必须待在所有浮层之下。
       它原来是 z-index:1300，压在业务弹窗(1050)、右键菜单(1051)、页签管理(1052)、
       图片放大(1100)、侧栏抽屉(1200) 之上 —— 手机上打开任何弹窗，
       底部 56px 里的「取消 / 确定 / 预览」按钮点下去都会被底栏截走，弹窗等于没法操作。
       2026-08-19 由浏览器端移动视口冒烟发现（点击被 <nav class="mobile-tabbar"> 拦截）。
       降到 1000：仍高于页面内容（最高是 sticky 页脚的 100），低于整个浮层族。 */
    .mobile-tabbar { display: flex; position: fixed; left: 0; right: 0; bottom: 0; height: 56px; background: #fff; border-top: 1px solid #e5e7eb; z-index: 1000; box-shadow: 0 -2px 10px rgba(0,0,0,.05); }
    .mtab { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; color: #94a3b8; text-decoration: none; font-size: .68rem; }
    .mtab i { font-size: 1.35rem; }
    .mtab.active { color: #2563eb; }
    /* 正文底部留出标签栏高度 */
    .bom-content { padding-bottom: 70px !important; }
}

/* ================= 打印报表框架 ================= */
/* 打印专用块在屏幕上隐藏 */
.print-only { display: none; }

@media print {
    /* 隐藏所有屏幕 UI（导航/顶栏/工具栏/按钮/标记了 no-print 的） */
    .bom-sidebar, .bom-topbar, .bom-hamburger, .bom-backdrop, .bom-toolbar, .btn, .no-print, .mobile-tabbar { display: none !important; }
    /* 打印时正文不要给底部标签栏留白 */
    .bom-content { padding-bottom: 0 !important; }
    html, body, .bom-shell, .bom-main, .bom-content { background: #fff !important; margin: 0 !important; padding: 0 !important; display: block !important; }
    .bom-content { padding: 0 !important; overflow: visible !important; }

    /* 单据经常从居中的编辑弹窗直接打印。屏幕态的 fixed/flex 居中、94vh 限高和
       overflow:hidden 若继续生效，会把打印稿推到纸张下半部并裁切。打印时恢复普通文档流。 */
    .bom-modal-backdrop {
        position: static !important; inset: auto !important; z-index: auto !important;
        display: block !important; width: auto !important; height: auto !important;
        min-height: 0 !important; padding: 0 !important;
        background: transparent !important; backdrop-filter: none !important;
        animation: none !important;
    }
    .bom-modal {
        display: block !important; width: auto !important; max-width: none !important;
        height: auto !important; max-height: none !important; min-height: 0 !important;
        overflow: visible !important; border-radius: 0 !important;
        background: #fff !important; box-shadow: none !important;
        animation: none !important; transform: none !important;
    }
    .bom-form-body, .bom-modal-body {
        display: block !important; height: auto !important; max-height: none !important;
        padding: 0 !important; overflow: visible !important;
    }
    /* 从列表弹窗打印时，只输出当前单据，底下的列表/列表抬头不能跟到下一页。 */
    .bom-content:has(> .bom-modal-backdrop .print-doc) > :not(.bom-modal-backdrop) {
        display: none !important;
    }
    .print-only { display: block !important; }
    @page {
        size: A4 portrait;
        margin: 10mm 10mm 14mm;
        @bottom-center {
            content: "Page " counter(page) " / " counter(pages);
            font-family: Arial, "Microsoft YaHei", sans-serif;
            font-size: 8pt;
            color: #555;
        }
    }
    @page bom-landscape {
        size: A4 landscape;
        margin: 10mm 10mm 14mm;
        @bottom-center {
            content: "Page " counter(page) " / " counter(pages);
            font-family: Arial, "Microsoft YaHei", sans-serif;
            font-size: 8pt;
            color: #555;
        }
    }
    /* 宽表通过打印抬头上的标记自动切 A4 横向，单据仍保持 A4 纵向。 */
    body:has(.print-landscape) { page: bom-landscape; }

    /* ---- 单表报表（列表页）：抬头 + 规范表格 ---- */
    .print-report-head { display: block !important; text-align: center; margin-bottom: 12px; break-after: avoid-page; page-break-after: avoid; }
    .print-report-head .prh-title { font-size: 18pt; font-weight: bold; letter-spacing: 2px; }
    .print-report-head .prh-sub { font-size: 10pt; color: #333; margin-top: 4px; }
    .print-report-head .prh-auto-meta { font-size: 8.5pt; color: #555; margin-top: 3px; line-height: 1.35; }
    .bom-page-title { display: none !important; }
    .card-surface { border: none !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; overflow: visible !important; }
    table.table { width: 100% !important; border-collapse: collapse !important; font-size: 10pt !important; }
    table.table th, table.table td { border: 1px solid #333 !important; padding: 4px 6px !important; color: #000 !important; }
    table.table thead th { background: #eee !important; position: static !important; box-shadow: none !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    table.table thead { display: table-header-group; }
    table.table tfoot { display: table-footer-group; }
    table.table tr { break-inside: avoid; page-break-inside: avoid; }
    .table > tbody > tr:nth-child(even) > * { background: #fff !important; }
    body:has(.print-landscape) table.table { font-size: 8.5pt !important; }
    body:has(.print-landscape) table.table th,
    body:has(.print-landscape) table.table td { padding: 3px 4px !important; }

    /* ---- 主从单据报表（2026-08-12 客户定稿：报表打印也统一 Arial，中文由雅黑兜底）---- */
    .print-doc { width: 100%; margin: 0; font-family: Arial, "Microsoft YaHei", "Noto Sans SC", sans-serif; color: #000; font-size: 11pt; line-height: 1.35; }
    .pd-company { text-align: center; font-size: 16pt; font-weight: bold; }
    .pd-title { text-align: center; font-size: 22pt; font-weight: bold; letter-spacing: 6px; margin: 3px 0 14px; }
    .pd-meta { width: 100%; border-collapse: collapse; margin-bottom: 6px; }
    .pd-meta td { padding: 4px 8px; vertical-align: top; }
    .pd-meta .pd-mlabel { color: #333; width: 78px; white-space: nowrap; }
    .pd-table { width: 100%; border-collapse: collapse; }
    .pd-table th, .pd-table td { border: 1px solid #000; padding: 5px 7px; }
    .pd-table thead th { background: #eee !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; text-align: center; }
    .pd-table .pd-num { text-align: right; }
    .pd-table tfoot td { font-weight: bold; }
    .pd-table thead { display: table-header-group; }
    .pd-table tr { break-inside: avoid; page-break-inside: avoid; }
    .pd-sign { display: flex; justify-content: space-between; margin-top: 26px; padding: 0 4px; }
    .pd-foot-time { text-align: right; margin-top: 10px; font-size: 9pt; color: #555; }
    .cd-totals, .md-bottom, .pd-sign, .cd-note { break-inside: avoid; page-break-inside: avoid; }

    /* ---- 对外 B2B 商务单据（销售确认单 / 报价单 / 装箱单）：英文抬头 + 卖买双方区块 ----
       字体 Arial（2026-08-12 客户定稿：系统与报表统一 Arial，与 PDF/Excel 一致），中文由雅黑等兜底 */
    .cd, .md { font-family: Arial, "Microsoft YaHei", "Noto Sans SC", "PingFang SC", "Segoe UI", sans-serif; }
    .cd-head { display: flex; justify-content: space-between; align-items: flex-start; border-bottom: 2px solid #000; padding-bottom: 8px; margin-bottom: 10px; }
    .cd-seller-name { font-size: 15pt; font-weight: bold; }
    .cd-seller div { font-size: 9.5pt; line-height: 1.35; }
    .cd-title { font-size: 19pt; font-weight: bold; letter-spacing: 1px; text-align: right; white-space: nowrap; }
    .cd-parties { display: flex; gap: 10px; margin-bottom: 8px; }
    .cd-party { flex: 1; border: 1px solid #000; padding: 6px 8px; font-size: 9.5pt; line-height: 1.4; }
    .cd-plabel { font-weight: bold; margin-bottom: 2px; }
    .cd-meta { flex: 1; }
    .cd-meta table { width: 100%; border-collapse: collapse; }
    .cd-meta td { padding: 2px 6px; font-size: 9.5pt; border: 1px solid #bbb; }
    .cd-meta .cd-mlabel { font-weight: bold; white-space: nowrap; width: 120px; background: #f3f3f3 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .cd-totals { width: 48%; margin-left: auto; margin-top: 8px; border-collapse: collapse; }
    .cd-totals td { padding: 3px 8px; font-size: 10pt; }
    .cd-totals .cd-tlabel { text-align: right; font-weight: bold; }
    .cd-totals .cd-tval { text-align: right; width: 130px; border-bottom: 1px solid #ccc; }
    .cd-totals .cd-grand td { border-top: 2px solid #000; border-bottom: none; font-size: 12pt; }

    /* ---- 经典版按单据类型配色（2026-08-12 客户定色，参考其 Excel）----
       --doc-c = 强调色（标题/合计），--doc-h/--doc-hf = 表头底色/文字色。
       发票浅绿 #D7E4BD、装箱单更浅绿 #EBF1DE（浅底配黑字）、采购单 #595959 灰；合计行 #FFF2CC。
       表头 + 隔行 #F2F2F2 + TOTAL 米黄底。打印必须带 print-color-adjust，否则浏览器丢背景色。 */
    .cd.doc-confirmation { --doc-c: #1F4E79; --doc-h: #1F4E79; --doc-hf: #fff; }
    .cd.doc-quotation    { --doc-c: #388194; --doc-h: #388194; --doc-hf: #fff; }
    .cd.doc-invoice      { --doc-c: #548235; --doc-h: #D7E4BD; --doc-hf: #000; }
    .cd.doc-packing      { --doc-c: #548235; --doc-h: #EBF1DE; --doc-hf: #000; }
    .cd.doc-purchase     { --doc-c: #595959; --doc-h: #595959; --doc-hf: #fff; }
    .cd[class*="doc-"] .pd-table thead th {
        background: var(--doc-h) !important; color: var(--doc-hf); border-color: #bfbfbf;
        -webkit-print-color-adjust: exact; print-color-adjust: exact;
    }
    .cd[class*="doc-"] .pd-table tbody tr:nth-child(even) td {
        background: #F2F2F2 !important;
        -webkit-print-color-adjust: exact; print-color-adjust: exact;
    }
    .cd[class*="doc-"] .cd-title { color: var(--doc-c); }
    /* 合计区文字一律黑色、高亮行改灰底（2026-08-14 客户 R5-1：米黄改成与隔行同色的灰、文字黑色） */
    .cd[class*="doc-"] .cd-totals .cd-tlabel { color: #000; }
    .cd[class*="doc-"] .cd-totals .cd-grand td {
        background: #F2F2F2 !important; color: #000; border-top: 2px solid var(--doc-c);
        -webkit-print-color-adjust: exact; print-color-adjust: exact;
    }

    /* ---- MFH 新版单据（QuickBooks 风格），配色与经典版同一张单据色表 ---- */
    .md.doc-confirmation { --doc-c: #1F4E79; --doc-h: #1F4E79; --doc-hf: #fff; }
    .md.doc-quotation    { --doc-c: #388194; --doc-h: #388194; --doc-hf: #fff; }
    .md.doc-invoice      { --doc-c: #548235; --doc-h: #D7E4BD; --doc-hf: #000; }
    .md.doc-packing      { --doc-c: #548235; --doc-h: #EBF1DE; --doc-hf: #000; }
    .md.doc-purchase     { --doc-c: #595959; --doc-h: #595959; --doc-hf: #fff; }
    .md { font-size: 10pt; }
    .md-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 14px; }
    .md-co-name { font-size: 15pt; font-weight: bold; }
    .md-title { font-size: 21pt; font-weight: bold; color: var(--doc-c); text-align: right; margin-bottom: 6px; }
    .md-meta { margin-left: auto; border-collapse: collapse; }
    .md-meta td { padding: 1px 6px; font-size: 9.5pt; }
    /* meta 标签黑色（2026-08-14 客户 R5-1：Quote No./Date/Currency/Payment Terms/Valid Until 不要主题色） */
    .md-meta .md-ml { font-weight: bold; text-align: right; color: #000; }
    .md-parties { display: flex; gap: 20px; margin-bottom: 10px; }
    .md-party { flex: 1; }
    .md-plabel { font-weight: bold; color: var(--doc-hf, #fff); background: var(--doc-h, var(--doc-c)) !important; padding: 2px 8px; margin-bottom: 4px;
                 -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .md-info { width: 100%; border-collapse: collapse; margin-bottom: 10px; }
    .md-info td { border: 1px solid #bbb; padding: 3px 8px; font-size: 9.5pt; }
    .md-info .md-il { font-weight: bold; background: #F2F2F2 !important; width: 110px;
                      -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .md-table { width: 100%; border-collapse: collapse; }
    .md-table th, .md-table td { border: 1px solid #bbb; padding: 5px 7px; }
    .md-table thead th { background: var(--doc-h, var(--doc-c)) !important; color: var(--doc-hf, #fff); text-align: center;
                         -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .md-table tbody tr:nth-child(even) td { background: #F2F2F2 !important;
                         -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .md-table .md-num { text-align: right; }
    .md-table tfoot td { border-top: 2px solid var(--doc-c); font-weight: bold; }
    .md-bottom { display: flex; gap: 20px; margin-top: 10px; align-items: flex-start; }
    .md-comments { flex: 1 1 auto; font-size: 9.5pt; }
    .md-totals { flex: 0 0 44%; border-collapse: collapse; }
    .md-totals td { padding: 3px 8px; font-size: 10pt; }
    .md-totals .md-tl { text-align: right; font-weight: bold; color: #000; }
    .md-totals .md-tv { text-align: right; width: 120px; border-bottom: 1px solid #ccc; }
    .md-totals .md-grand td { background: #F2F2F2 !important; color: #000; border-top: 2px solid var(--doc-c); border-bottom: none; font-size: 11.5pt;
                              -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .md-foot { margin-top: 22px; padding-top: 6px; border-top: 1px solid #bbb; font-size: 8.5pt; color: #555; text-align: center; }
    .cd-note { margin-top: 16px; font-style: italic; text-align: center; }
    /* 单据表格上/下方备注（2026-08-14 客户 R5-4）：左对齐、跟表格贴近，多行保留换行 */
    .doc-note-line { margin: 6px 0; font-size: 9.5pt; white-space: pre-line; break-inside: avoid; page-break-inside: avoid; }

    /* 公司 LOGO（单据抬头左上角）与发票收款银行信息块（系统设置 → 公司信息） */
    .doc-logo { max-height: 46px; max-width: 150px; object-fit: contain; margin-right: 10px; align-self: flex-start; }
    .doc-bank { margin-top: 10px; font-size: 9.5pt; text-align: left; font-style: normal; break-inside: avoid; page-break-inside: avoid; }
}

/* ---- 业务主流程 ---- */
.bom-flow { display: flex; align-items: stretch; gap: 4px; flex-wrap: wrap; }

.bom-flow-step {
    flex: 1 1 160px;
    min-width: 150px;
    background: #fff;
    border: 1px solid var(--bom-border);
    border-radius: 10px;
    padding: 12px 14px;
    text-align: left;
    cursor: pointer;
    transition: border-color .15s, box-shadow .15s, background .15s;
}
.bom-flow-step:hover { border-color: var(--bom-primary); box-shadow: 0 4px 14px rgba(37,99,235,.12); }
.bom-flow-step:focus-visible { outline: 2px solid var(--bom-primary); outline-offset: 2px; }
/* 有待办的环节高亮：这一步卡住了活 */
.bom-flow-step.has-pending { border-color: #fdba74; background: #fffbf5; }

.wfs-top { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
/* .wfs-no（流程条上的 1~7 序号）已于 2026-09-04 删除：
   系统导航页挂上全局站号 01–19 后，这七步的编号与那 19 站对不上，
   同一个新员工会在两处看到两套「第 3 步」。详见 Home.razor 里的注释。 */
.wfs-badge {
    margin-left: auto; font-size: .68rem; font-weight: 600;
    padding: 2px 7px; border-radius: 10px;
    background: var(--bom-warn); color: #fff; white-space: nowrap;
}
.wfs-badge.done { background: #e8f5ee; color: var(--bom-ok); }
.wfs-title { font-size: .95rem; font-weight: 700; color: var(--bom-ink); }
.wfs-sub { font-size: .72rem; color: var(--bom-muted); margin-top: 3px; }

.bom-flow-arrow {
    display: flex; align-items: center; color: #cbd5e1; font-size: 1.1rem;
    flex: 0 0 auto; padding: 0 2px;
}
@media (max-width: 720px) {
    /* 窄屏改竖排：箭头跟着转 90 度，不然横箭头指向断行处很怪 */
    .bom-flow { flex-direction: column; }
    .bom-flow-arrow { transform: rotate(90deg); justify-content: center; padding: 2px 0; }
}

/* 「左分类树 + 主列表 + 右面板」三栏（商品/库存/采购统计/销售统计）：
   窄屏改竖排，各栏占满一行——否则固定宽的树和右面板会把中间列表挤扁。
   分类树/右面板限高可滚，放在列表上/下方，手机上照样能筛能看图。 */
@media (max-width: 768px) {
    .bom-list-layout { flex-direction: column; }
    .bom-list-layout > * {
        flex: 1 1 100% !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important;
    }
    .bom-list-aside { max-height: 260px !important; }
}

/* 明细行：同一张单的首行加一条分隔线，视觉上把单据分组 */
.card-surface > table.table tbody tr.line-order-start > * { border-top: 1px solid #dbe2ea; }

/* ---- 主体卡片（仓库 / 供应商 / 客户）----
   点卡片在下方展开明细。卡片本身 no-print，打印仍走同页的 print-only 表格。 */
.bom-card-grid {
    display: grid;
    /* auto-fill + minmax：仓库几个都能排，窄屏自动落行，不写死列数 */
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 14px;
    margin-bottom: 16px;
}

.bom-ecard {
    position: relative;
    background: #fff;
    border: 1px solid var(--bom-border);
    border-left: 3px solid var(--bom-border);
    border-radius: 10px;
    padding: 14px 16px;
    cursor: pointer;
    text-align: left;
    width: 100%;
    transition: box-shadow .15s, border-color .15s, background .15s;
}
.bom-ecard:hover { border-color: var(--bom-primary); box-shadow: 0 4px 14px rgba(37,99,235,.12); }
.bom-ecard:focus-visible { outline: 2px solid var(--bom-primary); outline-offset: 2px; }
.bom-ecard.selected { border-color: var(--bom-primary); border-left-color: var(--bom-primary); background: var(--bom-primary-050); box-shadow: 0 4px 14px rgba(37,99,235,.16); }
/* 停用主体：整卡压暗，一眼区分，但仍可点开看历史数据 */
.bom-ecard.is-off { background: #fafafa; }
.bom-ecard.is-off .bom-ec-name { color: var(--bom-muted); }

/* 「全部仓库」汇总卡：与真实仓库卡区分开，不然像多了一个叫「全部」的仓 */
.bom-ecard-all { border-left-color: var(--bom-accent); background: linear-gradient(180deg, #f8fdfc 0%, #fff 60%); }
.bom-ecard-all .bom-ec-code { color: var(--bom-accent); }
.bom-ecard-all.selected { border-left-color: var(--bom-primary); }

.bom-ec-head { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 10px; }
.bom-ec-code { font-size: .72rem; font-weight: 600; color: var(--bom-muted); letter-spacing: .04em; }
.bom-ec-name { font-size: 1.02rem; font-weight: 700; color: var(--bom-ink); line-height: 1.3; word-break: break-all; }
.bom-ec-badge { margin-left: auto; flex-shrink: 0; }

/* 卡片指标行：种类数 / 库存总量 / 库位数 */
.bom-ec-stats { display: flex; gap: 14px; border-top: 1px dashed var(--bom-border); padding-top: 10px; }
.bom-ec-stat { min-width: 0; }
.bom-ec-sv { font-size: 1.05rem; font-weight: 700; color: var(--bom-ink); line-height: 1.2; font-variant-numeric: tabular-nums; }
.bom-ec-sv.muted { color: #cbd5e1; }
.bom-ec-sl { font-size: .7rem; color: var(--bom-muted); margin-top: 2px; white-space: nowrap; }

/* 卡片副信息（联系人/电话等） */
.bom-ec-meta { font-size: .78rem; color: var(--bom-muted); line-height: 1.7; }
.bom-ec-meta i { width: 14px; text-align: center; margin-right: 4px; opacity: .7; }
.bom-ec-meta .em-empty { color: #cbd5e1; }

/* 选中卡片底部的小箭头，指向下方明细面板 */
.bom-ecard.selected::after {
    content: ""; position: absolute; left: 50%; bottom: -8px; transform: translateX(-50%) rotate(45deg);
    width: 12px; height: 12px; background: #fff;
    border-right: 1px solid var(--bom-primary); border-bottom: 1px solid var(--bom-primary);
}

/* ---- 展开的明细面板 ---- */
.bom-detail-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--bom-border); }
.bom-detail-title { font-size: 1.02rem; font-weight: 700; color: var(--bom-ink); }
.bom-detail-close { margin-left: auto; }
/* 负责人/电话/地址：卡片上不放，收在明细面板顶部 */
.bom-detail-info { display: flex; gap: 18px; flex-wrap: wrap; font-size: .82rem; color: var(--bom-muted); }
.bom-detail-info .di-label { color: #9ca3af; margin-right: 4px; }
.bom-detail-info .di-empty { color: #cbd5e1; }

@media (max-width: 640px) {
    .bom-card-grid { grid-template-columns: 1fr; }
}

/* ---- 统一单据状态徽章（DocStatus 组件）----
   琥珀=待办（草稿/待审批），绿=已完成动作（已确认/已审核/已通过），红=驳回/作废。
   浅底描边款式比实心块柔和，但色相分明，一眼可辨。 */
.badge.st-draft { background: #fef3c7; color: #b45309; border: 1px solid #fcd34d; font-weight: 600; }
.badge.st-done  { background: #d1fae5; color: #047857; border: 1px solid #6ee7b7; font-weight: 600; }
.badge.st-void  { background: #fee2e2; color: #b91c1c; border: 1px solid #fca5a5; font-weight: 600; }
.badge.st-plain { background: #f1f5f9; color: #475569; border: 1px solid #e2e8f0; font-weight: 600; }
.badge.st-draft i, .badge.st-done i, .badge.st-void i { margin-right: 4px; font-size: .85em; }

/* 草稿行：整行淡琥珀底 + 左侧色条，扫一眼就能挑出还没处理的单。
   悬停/选中态（bootstrap hover、row-expanded）优先级更高，不受影响。 */
tr.row-draft > td { background: #fffcf0; }
tr.row-draft > td:first-child { box-shadow: inset 3px 0 0 #f59e0b; }

/* ---- 工作台 ---- */
.wb-cols { display: grid; grid-template-columns: 1.2fr 1fr; gap: 16px; align-items: stretch; }   /* 等高：两张卡片一样高更整齐 */
@media (max-width: 900px) { .wb-cols { grid-template-columns: 1fr; } }
.wb-unit { font-size: .75rem; font-weight: 500; color: #94a3b8; margin: 0 2px; }
.wb-amt { font-size: .95rem; font-weight: 700; color: #475569; }
.wb-todo-list { display: flex; flex-direction: column; }
.wb-todo { display: flex; align-items: center; gap: 10px; padding: 10px 8px; border-bottom: 1px solid #f1f5f9; text-decoration: none; color: var(--bom-ink); border-radius: 8px; transition: background .12s; }
.wb-todo:last-child { border-bottom: none; }
.wb-todo:hover { background: #f8fafc; }
.wb-t-ico { font-size: 1.1rem; color: var(--bom-primary); width: 26px; text-align: center; }
.wb-t-text { flex: 1; font-size: .92rem; font-weight: 500; }
.wb-t-go { font-size: .8rem; color: var(--bom-primary); white-space: nowrap; }
.wb-quick { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; }
.wb-q { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 6px; background: #f8fafc; border: 1px solid var(--bom-border); border-radius: 10px; text-decoration: none; color: var(--bom-ink); font-size: .85rem; font-weight: 500; transition: all .15s; }
.wb-q i { font-size: 1.3rem; color: var(--bom-primary); }
.wb-q:hover { border-color: var(--bom-primary); color: var(--bom-primary); box-shadow: 0 4px 12px rgba(37,99,235,.1); transform: translateY(-1px); }

/* ---- 成交价历史弹窗 ---- */
.ph-last { display: flex; align-items: center; justify-content: space-between; gap: 12px; background: #ecfdf5; border: 1px solid #6ee7b7; border-radius: 10px; padding: 12px 16px; margin-bottom: 14px; }
.ph-last-label { font-size: .82rem; color: #047857; font-weight: 600; }
.ph-last-price { font-size: 1.5rem; font-weight: 800; color: #065f46; margin-top: 2px; }
.ph-last-tax { font-size: .85rem; font-weight: 500; color: #059669; }
tr.ph-same > td { background: #ecfdf5; }

/* ---- 扫码枪录入框（入库/出库编辑页）---- */
.scanbox { display: flex; align-items: center; gap: 8px; background: #f0f9ff; border: 1px dashed #7dd3fc; border-radius: 8px; padding: 8px 12px; margin-bottom: 10px; }
.scanbox-off { background: #f8fafc; border-color: #e2e8f0; }
.sb-ico { font-size: 1.15rem; color: #0284c7; }
.scanbox-off .sb-ico { color: #94a3b8; }
.sb-input { max-width: 280px; }
.sb-msg { font-size: .85rem; font-weight: 600; }
.sb-msg.ok { color: #047857; }
.sb-msg.bad { color: #b91c1c; }

/* 商品搜索下拉里的库存徽标 */
.ppk-stock { font-size: .78rem; font-weight: 600; padding: 1px 8px; border-radius: 999px; white-space: nowrap; }
.ppk-stock.has { background: #d1fae5; color: #047857; }
.ppk-stock.none { background: #fee2e2; color: #b91c1c; }

/* ---- 购销统计横向条形图 ---- */
.hbar-list { display: flex; flex-direction: column; gap: 8px; }
.hbar-row { display: flex; align-items: center; gap: 10px; }
.hbar-label { flex: 0 0 200px; font-size: .85rem; color: var(--bom-ink); text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hbar-track { flex: 1 1 auto; background: #f1f5f9; border-radius: 6px; height: 20px; overflow: hidden; }
.hbar-fill { height: 100%; border-radius: 6px; min-width: 2px; transition: width .3s ease; }
.hbar-val { flex: 0 0 110px; font-size: .85rem; font-weight: 600; color: var(--bom-ink); text-align: right; white-space: nowrap; }
.hb-c0 { background: linear-gradient(90deg,#2563eb,#3b82f6); }
.hb-c1 { background: linear-gradient(90deg,#0d9488,#14b8a6); }
.hb-c2 { background: linear-gradient(90deg,#d97706,#f59e0b); }
.hb-c3 { background: linear-gradient(90deg,#7c3aed,#8b5cf6); }
.hb-c4 { background: linear-gradient(90deg,#db2777,#ec4899); }
.hb-c5 { background: linear-gradient(90deg,#475569,#64748b); }
@media (max-width: 640px) { .hbar-label { flex-basis: 110px; } .hbar-val { flex-basis: 80px; } }

/* 工具栏「待处理 N」筹码：琥珀胶囊，点击切换只看待办；激活态实心 */
.chip-draft { display: inline-flex; align-items: center; gap: 5px; background: #fef3c7; color: #b45309; border: 1px solid #fcd34d; border-radius: 999px; padding: 5px 12px; font-size: .85rem; font-weight: 600; cursor: pointer; white-space: nowrap; transition: background .12s; }
.chip-draft:hover { background: #fde68a; }
.chip-draft.on { background: #f59e0b; color: #fff; border-color: #f59e0b; }
.chip-draft i { font-size: .8em; }
.chip-draft b { font-weight: 800; }


/* ---- 合并页的子页签（库存查询：余额/在途/台账；往来对账：对账/账龄）---- */
.subtabs { display: inline-flex; gap: 4px; background: #f1f5f9; border-radius: 10px; padding: 4px; margin-bottom: 14px; }
.stab { padding: 6px 16px; border-radius: 8px; font-size: .88rem; font-weight: 500; color: #475569; text-decoration: none; transition: all .12s; }
.stab:hover { color: var(--bom-primary); }
.stab.on { background: #fff; color: var(--bom-primary); font-weight: 600; box-shadow: 0 1px 4px rgba(15,23,42,.1); }

/* ---- 手机端查询页（客户欠款 / 商品查询）---- */
.m-search { display: flex; align-items: center; gap: 8px; background: #fff; border: 1px solid var(--bom-border); border-radius: 10px; padding: 8px 12px; margin-bottom: 12px; }
.m-search i { color: #94a3b8; }
.m-search .form-control { border: none; box-shadow: none; padding: 2px 4px; }
.m-sumbar { display: flex; align-items: center; font-size: .85rem; color: var(--bom-muted); padding: 0 4px 8px; }
.m-card { background: #fff; border: 1px solid var(--bom-border); border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; cursor: pointer; }
.m-card:active { background: #f8fafc; }
.m-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.m-title { font-weight: 600; font-size: .95rem; color: var(--bom-ink); }
.m-sub { font-size: .78rem; color: #94a3b8; }
.m-money { font-size: 1.15rem; font-weight: 800; color: #dc2626; }
.m-detail { border-top: 1px dashed #e5e7eb; margin-top: 10px; padding-top: 8px; cursor: default; }
.m-line { display: flex; align-items: center; gap: 8px; padding: 5px 0; font-size: .85rem; border-bottom: 1px solid #f8fafc; }
.m-line:last-child { border-bottom: none; }
.m-ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 40vw; }
.m-seg { display: inline-flex; background: #f1f5f9; border-radius: 8px; padding: 3px; margin-bottom: 6px; gap: 3px; }
.m-seg button { border: none; background: none; padding: 4px 14px; border-radius: 6px; font-size: .82rem; color: #475569; }
.m-seg button.on { background: #fff; color: var(--bom-primary); font-weight: 600; box-shadow: 0 1px 3px rgba(15,23,42,.08); }

/* ---- 系统设置：主题色色板 ---- */
.theme-swatch { width: 40px; height: 40px; border-radius: 10px; border: 2px solid transparent; cursor: pointer; color: #fff; font-size: 1.1rem; display: inline-flex; align-items: center; justify-content: center; transition: transform .12s; }
.theme-swatch:hover { transform: scale(1.08); }
.theme-swatch.on { border-color: #1f2937; box-shadow: 0 0 0 2px #fff inset; }

/* 客户/供应商分析 · 月度迷你柱状图 */
.mt-legend { display:inline-block; width:10px; height:10px; border-radius:2px; vertical-align:middle; margin-right:4px; }
.mt-chart { display:flex; align-items:flex-end; gap:10px; height:180px; padding:8px 4px 0; overflow-x:auto; }
.mt-col { display:flex; flex-direction:column; align-items:center; min-width:34px; height:100%; }
.mt-bars { display:flex; align-items:flex-end; gap:3px; flex:1 1 auto; }
.mt-bar { width:12px; border-radius:3px 3px 0 0; min-height:2px; -webkit-print-color-adjust:exact; print-color-adjust:exact; }
.mt-xlabel { font-size:10px; color:#64748b; margin-top:4px; white-space:nowrap; }

/* ---- 首页业务线经营概览（铝护栏 / 配件两条线并排）----
   两列起步，窄屏落成单列；卡片内部指标用 2×2 网格，手机上仍然读得下来。 */
.bl-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px; }
.bl-card { border: 1px solid var(--bom-border, #e6eaf0); border-radius: 12px; padding: 14px; background: #fff; }
.bl-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.bl-dot { width: 12px; height: 12px; border-radius: 3px; flex: none; }
.bl-name { font-weight: 600; font-size: 1.02rem; }
.bl-code { font-size: .72rem; color: #64748b; border: 1px solid #e2e8f0; border-radius: 4px; padding: 0 5px; }
.bl-share { margin-left: auto; font-weight: 600; color: var(--bom-primary); }
.bl-bar { height: 6px; border-radius: 3px; background: #eef2f7; margin: 8px 0 12px; overflow: hidden; }
.bl-bar-fill { height: 100%; border-radius: 3px; min-width: 2px; -webkit-print-color-adjust: exact; print-color-adjust: exact; }

.bl-metrics { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
.bl-m-num { font-size: 1.12rem; font-weight: 600; line-height: 1.25; }
.bl-m-label { font-size: .76rem; color: #64748b; margin-top: 1px; }

.bl-top { margin-top: 12px; border-top: 1px dashed #e6eaf0; padding-top: 8px; }
.bl-top-h { font-size: .76rem; color: #94a3b8; margin-bottom: 4px; }
.bl-top-row { display: flex; align-items: center; gap: 8px; font-size: .84rem; padding: 2px 0; }
.bl-top-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bl-top-qty { flex: none; color: #64748b; font-variant-numeric: tabular-nums; }
.bl-top-amt { flex: none; font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---- 采购统计右侧商品图片面板 ---- */
.ps-img-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.ps-img-cell { position: relative; border: 1px solid #e6eaf0; border-radius: 8px; overflow: hidden; background: #fafbfc; }
.ps-img-cell.is-main { border-color: var(--bom-primary); }
.ps-img-cell img { width: 100%; height: 110px; object-fit: cover; display: block; }
.ps-img-tag { position: absolute; left: 4px; top: 4px; font-size: .66rem; padding: 0 5px; border-radius: 3px;
              background: var(--bom-primary); color: #fff; }

/* 弹窗里的「开关 + 说明」两列（公司信息等）。
   原先是 d-flex align-items-end 把复选框贴在相邻字段底边，字段一高一矮就错位。 */
.co-flags { display:grid; grid-template-columns:repeat(auto-fit, minmax(230px, 1fr)); gap:10px; }
.co-flag { display:flex; gap:10px; align-items:flex-start; margin:0; padding:11px 13px;
    border:1px solid #e3e9f0; border-radius:9px; background:#f8fafc; cursor:pointer; }
.co-flag:hover { border-color:#c7d6ea; background:#f4f8fd; }
.co-flag.is-locked { cursor:default; opacity:.72; }
.co-flag.is-locked:hover { border-color:#e3e9f0; background:#f8fafc; }
.co-flag .form-check-input { margin:2px 0 0; flex:none; width:17px; height:17px; }
.co-flag > span { display:flex; flex-direction:column; gap:2px; min-width:0; }
.co-flag strong { font-size:13px; font-weight:650; color:#243244; }
.co-flag em { font-style:normal; font-size:11px; line-height:1.55; color:#7a8798; }

/* ================= 表格网格线（2026-09-03 客户要求）=================

   客户原话：「页面都要有框显示，像表格一样，不要白白的那种感觉」。

   改之前全站表格只画横线，一眼望过去是一片白底浮着几行字，
   列多的时候（采购单十几列）对着看很容易串行。这里统一补上竖线，
   让每个字段各占一格。

   两条分寸：
   - 竖线比横线浅（#eef1f5 vs --bom-border）。竖线和横线一样重的话，
     整张表会变成一张网，内容反而被压下去。
   - 隔行浅底 #fcfdfe，很轻，只用来把相邻两行分开，不做成明显的斑马纹——
     库存预警行、展开行那些带背景色的状态行还要压在它上面，底色太重就打架了。
   放在文件末尾：要盖住前面 .card-surface > table.table 那几条既有规则。 */

.card-surface > table.table > thead > tr > th,
.card-surface > table.table > tbody > tr > td,
.card-surface > table.table > tfoot > tr > td {
    border-right: 1px solid #eef1f5;
}
.card-surface > table.table > thead > tr > th { border-right-color: #e3e8ee; }
.card-surface > table.table > thead > tr > th:last-child,
.card-surface > table.table > tbody > tr > td:last-child,
.card-surface > table.table > tfoot > tr > td:last-child { border-right: 0; }

/* 表格外框：白底表格浮在白底卡片上时，边界完全看不出来 */
.card-surface > table.table { border: 1px solid var(--bom-border); border-radius: 8px; overflow: hidden; }

/* 隔行浅底。用 > td 而不是 tr，是为了让状态行（低库存红底、展开行蓝底）
   靠它们自己的 > * 规则盖过来——那几条本来就写在 td 这一层。 */
.card-surface > table.table > tbody > tr:nth-child(even) > td { background: #fcfdfe; }

/* 明细表（单据行内展开）同样补竖线 */
.detail-table > thead > tr > th,
.detail-table > tbody > tr > td,
.detail-table > tfoot > tr > td { border-right: 1px solid #eef1f5; }
.detail-table > thead > tr > th:last-child,
.detail-table > tbody > tr > td:last-child,
.detail-table > tfoot > tr > td:last-child { border-right: 0; }

/* ---- 序号列（2026-09-03 客户要求：各页列表与编辑页明细都要有序号）----
   窄、居中、等宽数字。三位数和一位数上下要对齐，否则翻页时数字看着在跳。 */
.seq-col, td.seq-col, th.seq-col {
    width: 48px; min-width: 48px;
    text-align: center; white-space: nowrap;
    color: #94a3b8; font-variant-numeric: tabular-nums;
}
.card-surface > table.table > tbody > tr > td.seq-col { font-size: .8rem; }
.detail-table > tbody > tr > td.seq-col { color: #a5b0bd; }

/* =====================================================================
   界面收敛（2026-09-04，客户：「界面设计要美观、简洁，样式好看」）

   改之前最扎眼的三件事，都不是"不够花哨"，而是"太花"：

   1) 一条工具条上能同时出现六种按钮配色 —— 蓝实心(查询)、蓝框(导入)、
      绿框(导出)、灰框(模板/打印/字段设置)、橙框(补货建议)、绿实心(新建)。
      颜色一多就等于没有重点，用户反而找不到主操作。
   2) 列表每行三个彩色描边按钮（复制/编辑/删除），十行就是三十个彩色方框，
      整张表被按钮的颜色盖过了数据本身。
   3) 表格列被挤到折行（「无锡华翔电子科技有限公司」折两行、「60天」折两行），
      行高参差不齐。

   处理原则：**颜色留给需要判断的信息（状态、金额、超期），不给常驻的操作按钮。**
   ===================================================================== */

/* ---------- 1. 工具条：一页只留一个实心按钮 ---------- */

/* 所有描边按钮收成同一种中性样式。图标保留各自语义色的余地不大，
   但少了六种边框颜色之后，工具条一眼就能扫完。 */
.bom-toolbar .btn-outline-primary,
.bom-toolbar .btn-outline-success,
.bom-toolbar .btn-outline-danger,
.bom-toolbar .btn-outline-warning,
.bom-toolbar .btn-outline-info,
.bom-toolbar .btn-outline-dark,
.bom-toolbar .btn-outline-secondary,
.bom-page-head .btn-outline-primary,
.bom-page-head .btn-outline-success,
.bom-page-head .btn-outline-danger,
.bom-page-head .btn-outline-warning,
.bom-page-head .btn-outline-info,
.bom-page-head .btn-outline-dark,
.bom-page-head .btn-outline-secondary {
    color: #475569;
    background: #fff;
    border-color: #dbe2ea;
}
.bom-toolbar .btn-outline-primary:hover,
.bom-toolbar .btn-outline-success:hover,
.bom-toolbar .btn-outline-danger:hover,
.bom-toolbar .btn-outline-warning:hover,
.bom-toolbar .btn-outline-info:hover,
.bom-toolbar .btn-outline-dark:hover,
.bom-toolbar .btn-outline-secondary:hover,
.bom-page-head .btn-outline-primary:hover,
.bom-page-head .btn-outline-success:hover,
.bom-page-head .btn-outline-danger:hover,
.bom-page-head .btn-outline-warning:hover,
.bom-page-head .btn-outline-info:hover,
.bom-page-head .btn-outline-dark:hover,
.bom-page-head .btn-outline-secondary:hover {
    color: var(--bom-primary);
    background: #f4f8ff;
    border-color: color-mix(in srgb, var(--bom-primary) 42%, #dbe2ea);
}
.bom-toolbar .btn-outline-primary:focus-visible,
.bom-toolbar .btn-outline-secondary:focus-visible,
.bom-page-head .btn-outline-primary:focus-visible,
.bom-page-head .btn-outline-secondary:focus-visible {
    box-shadow: 0 0 0 3px rgba(37, 99, 235, .16);
}

/* 「查询」原来是实心蓝，和实心绿的「新建」正面抢注意力。
   改成浅底蓝字：还是一眼可见，但让位给真正的主操作。 */
.bom-toolbar .btn-primary {
    color: var(--bom-primary);
    background: #e8f0fe;
    border-color: #cddffb;
}
.bom-toolbar .btn-primary:hover,
.bom-toolbar .btn-primary:focus {
    color: #fff;
    background: var(--bom-primary);
    border-color: var(--bom-primary);
}

/* 新建/新增：全系统唯一的实心按钮，改用主色而不是绿色。
   绿色在表格里已经表示「启用 / 正常」，让它同时兼任「新建」会串味。 */
.bom-toolbar .btn-success,
.bom-page-head .btn-success {
    background: var(--bom-primary);
    border-color: var(--bom-primary);
    box-shadow: 0 1px 2px rgba(37, 99, 235, .24);
}
.bom-toolbar .btn-success:hover,
.bom-toolbar .btn-success:focus,
.bom-page-head .btn-success:hover,
.bom-page-head .btn-success:focus {
    background: var(--bom-primary-dark);
    border-color: var(--bom-primary-dark);
}

/* 按钮更紧凑一档，让一整排在 1440 宽度下排得下。
   原来会折到第二行，而且「新增客户」单独掉到第二行最左边，看着像个孤儿。 */
.bom-toolbar .btn,
.bom-page-head .btn {
    padding: .34rem .68rem;
    font-size: .855rem;
    white-space: nowrap;
}
.bom-toolbar .btn i { margin-right: 2px; }
/* 查询框可以被压缩，按钮不行 —— 该让位的是输入框 */
.bom-toolbar .btn, .bom-toolbar .form-select { flex: 0 0 auto; }
.bom-toolbar { row-gap: 8px; }

/* ---------- 2. 列表行内操作：去掉方框，只留文字 ---------- */

/* 语义色留着（蓝=常规、红=危险、绿=推进），但不再画边框和底色，
   悬停时才浮出来。十行数据的表格因此从「三十个彩色方框」变回「一张表」。 */
.card-surface table .btn-sm[class*="btn-outline-"] {
    border-color: transparent;
    background: transparent;
    padding: .18rem .42rem;
    font-weight: 500;
}
.card-surface table .btn-sm.btn-outline-primary { color: var(--bom-primary); }
.card-surface table .btn-sm.btn-outline-secondary,
.card-surface table .btn-sm.btn-outline-dark { color: #64748b; }
.card-surface table .btn-sm.btn-outline-success { color: #157347; }
.card-surface table .btn-sm.btn-outline-danger { color: var(--bom-danger); }
.card-surface table .btn-sm.btn-outline-warning { color: #a16207; }
.card-surface table .btn-sm[class*="btn-outline-"]:hover {
    background: #eef2f7;
    border-color: transparent;
}
.card-surface table .btn-sm.btn-outline-danger:hover { background: #fdeceb; color: var(--bom-danger); }
.card-surface table .btn-sm.btn-outline-primary:hover { background: #e8f0fe; color: var(--bom-primary-dark); }
/* 相邻两个文字按钮之间给一点呼吸，别糊成一条 */
.card-surface table .btn-sm + .btn-sm { margin-left: 2px; }

/* ---------- 3. 表格：不折行 ---------- */

/* 列被挤窄时 Bootstrap 会把「无锡华翔电子科技有限公司」折成两行、
   「60 天」折成两行，行高参差不齐，扫一列数据要上下找。
   列表容器本来就带 overflow-x:auto，不折行只会出现横向滚动，不会藏内容；
   而且现在每页都能用「字段设置」把用不上的列关掉，宽度是可控的。 */
.card-surface > table.table > thead > tr > th,
.card-surface > table.table > tbody > tr > td { white-space: nowrap; }
/* 明确标了要换行的单元格不受影响（备注、地址这类） */
.card-surface > table.table .wrap-cell { white-space: normal; }

/* ---------- 4. 状态标记：从实心块改成淡底 ---------- */

/* 实心色块在一列里连成一片，比数据本身还抢眼。淡底 + 深字读起来更轻，
   同时保留颜色的判断价值。只改表格里的，其它地方（如弹窗提示）不动。 */
.card-surface table .badge.bg-success { background: #e7f6ec !important; color: #157347; }
.card-surface table .badge.bg-secondary { background: #eef1f5 !important; color: #5a6b7f; }
.card-surface table .badge.bg-danger { background: #fdeceb !important; color: #b42318; }
.card-surface table .badge.bg-warning { background: #fdf3e2 !important; color: #a16207; }
.card-surface table .badge.bg-primary { background: #e8f0fe !important; color: #1d4ed8; }
.card-surface table .badge.bg-info { background: #e6f4f8 !important; color: #0e7490; }
.card-surface table .badge { font-weight: 600; border: 1px solid rgba(15, 23, 42, .06); }

/* ---------- 5. 页面标题与卡片 ---------- */

.bom-page-title {
    display: flex; align-items: center; gap: 10px;
    font-size: 1.28rem; font-weight: 750; letter-spacing: .2px;
    color: #0f172a; margin: 0 0 14px;
}
/* 标题左侧一道主色竖条：列表页原来只有一行裸标题，和下面的工具条挤在一起，
   看不出「这里是页面开头」 */
.bom-page-title::before {
    content: ""; flex: 0 0 auto;
    width: 4px; height: 1.05em; border-radius: 3px;
    background: linear-gradient(180deg, var(--bom-primary), #60a5fa);
}

/* 卡片阴影再收一点：原来的双层阴影在浅灰底上会糊出一圈脏边 */
.card-surface {
    box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
}

/* 空态别占满整块：原来一张空表要留 300px 高的白，页面显得很空旷 */
.bom-empty { padding: 34px 16px; color: #94a3b8; }
.bom-empty i { font-size: 2rem; opacity: .5; }
.bom-empty .we-text { margin-top: 8px; font-size: .9rem; }

/* 主操作按钮永远靠右。
   工具条按钮多的页面（客户/物料/库存）排不下会折行，而「新建」在标记里是最后一个，
   折下去就孤零零贴在第二行最左边，看着像漏放的。给它一个 auto 左边距：
   第一行排得下时富余空间接近 0，看不出区别；折行了就自动贴到右端。 */
.bom-toolbar > .btn-success { margin-left: auto; }

/* ---------- 6. 工作台卡片：色条只留给真的要看的那张 ---------- */

/* 改之前工作台上三行卡片是三种长相：第一行蓝色左条 + 图标、第二行绿色左条 + 图标、
   第三行连左条和图标都没有。而且蓝绿之分是**按行**来的，不是按含义——
   「进行中项目」和「逾期应收账款」凭什么一个蓝一个绿？

   现在：一切正常时所有卡片长得一样（干净）；只有真的需要处理的那几张
   （延期、逾期、超额、待办超时）才亮出左侧色条。色条成了信号，而不是装饰。 */
.alert-card { border-left: 1px solid var(--bom-border); }
.alert-card.warn { border-left: 4px solid var(--bom-warn); }
.alert-card.danger { border-left: 4px solid var(--bom-danger); }
/* .ok = 该项目前没问题，不需要色条把眼睛引过去 */
.alert-card.ok { border-left: 1px solid var(--bom-border); }

/* 三行卡片的圆角、边框、阴影、悬停统一 */
.alert-card, .kpi { border-radius: 12px; }
.alert-card:hover, .kpi:hover {
    box-shadow: 0 6px 18px rgba(15, 23, 42, .07);
    border-color: color-mix(in srgb, var(--bom-primary) 28%, var(--bom-border));
}

/* 数字与标签的层级：数字够大、标签够淡，一眼先看到数 */
.alert-card .ac-num { font-size: 1.42rem; letter-spacing: -.01em; }
.kpi-num { letter-spacing: -.01em; }

/* 不折行的前提：装表格的卡片必须能横向滚动，否则宽表会被裁掉——那是在藏数据。
   全站 216 处 card-surface 里只有 15 处显式写了 overflow-x:auto，
   所以这里用 :has() 精确补给「直接装着表格的那些」，
   不去动装表单、装空态的卡片（给它们加滚动容器会裁掉里面的浮层）。 */
.card-surface:has(> table.table) { overflow-x: auto; }

/* ================= 往来明细对账单（2026-09-04）=================
   一张要发给对方财务、要打印签章的纸。所以：字要小而密（一页装得下）、
   金额右对齐等宽、结构行（期初/期末/尾差）与流水行有区分、打印时把页面上其它东西全隐掉。 */

.stmt-panel { position: relative; }

.stmt-head { display: grid; grid-template-columns: 1fr 1fr auto; gap: 16px; align-items: start;
    padding-bottom: 10px; border-bottom: 1px solid var(--bom-border); }
.stmt-h-label { font-size: .72rem; font-weight: 700; color: #94a3b8; letter-spacing: .05em; }
.stmt-h-name { font-size: 1rem; font-weight: 750; color: #0f172a; margin-top: 2px; }
.stmt-h-sub { font-size: .78rem; color: #64748b; margin-top: 2px; }
.stmt-close { flex: none; width: 28px; height: 28px; border: 0; border-radius: 7px;
    background: transparent; color: #94a3b8; }
.stmt-close:hover { background: #f1f5f9; color: #b42318; }

/* 五个数的等式：这一行是整张单的锚点，任何区间都自证闭合 */
.stmt-eq { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px;
    padding: 9px 12px; margin: 10px 0 4px; border-radius: 8px;
    background: #f8fafc; border: 1px solid #eef1f5;
    font-size: .86rem; color: #475569; font-variant-numeric: tabular-nums; }
.stmt-eq b { color: #0f172a; font-weight: 750; }
.stmt-alltime { font-size: .8rem; color: #64748b; margin-bottom: 8px; font-variant-numeric: tabular-nums; }
.stmt-alltime b { color: #0f172a; }

.stmt-table { font-size: .84rem; }
.stmt-table td, .stmt-table th { font-variant-numeric: tabular-nums; }
/* 结构行（期初余额 / 尾差调整）与流水行拉开：它们不是业务发生，是算式的一部分 */
.stmt-table tbody tr.stmt-struct > td { background: #fbfcfe; color: #475569; font-style: normal; }
.stmt-flag { color: #a16207; font-weight: 700; }
.stmt-note { font-size: .76rem; color: #8a96a4; line-height: 1.7; margin-top: 4px; }

.stmt-sub { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--bom-border); }
.stmt-sub-h { font-size: .84rem; font-weight: 650; color: #334155; margin-bottom: 6px; }

.stmt-foot { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--bom-border);
    font-size: .78rem; color: #64748b; line-height: 1.9; }

/* 签章栏：只在打印稿上 */
.stmt-sign { margin-top: 22px; }
.stmt-sign-tip { font-size: .78rem; color: #334155; margin-bottom: 14px; }
.stmt-sign-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.stmt-sign-row span { border-top: 1px solid #333; padding-top: 6px; font-size: .78rem; }

/* 打印：面板打开时，页面上其它内容全部隐掉，只留这张对账单 */
@media print {
    .stmt-panel { box-shadow: none !important; border: 0 !important; padding: 0 !important; margin: 0 !important; }
    .stmt-eq { background: #fff; border: 1px solid #333; }
    .stmt-table th, .stmt-table td { border: 1px solid #333 !important; }
    .stmt-sub { break-inside: avoid; }
    .stmt-sign { break-inside: avoid; }
}

/* ============================================================
   界面美化 · 间距 / 卡片 / 留白（2026-09-08，客户计划第 5 项）

   接着 2026-09-04 那轮「收敛」往下做。上一轮解决的是**太花**（颜色与边框太多），
   这一轮解决的是**太挤**：标题、工具条、卡片三段贴在一起没有节奏，
   工具条一行放不下时第二行紧贴第一行，内容滚到底直接顶着窗口下沿。

   只改样式，零业务逻辑，也不动任何一处 DOM 结构。
   ============================================================ */

:root {
    /* 间距刻度：全站纵向节奏只用这四个值，不再每页各写各的 8/10/12/14 */
    --bom-sp-1: 8px;
    --bom-sp-2: 12px;
    --bom-sp-3: 16px;
    --bom-sp-4: 24px;
}

/* 内容区底部留白：原来上下都是 20px，滚到底时最后一张卡片贴着窗口下沿，
   看着像内容被截断了。底部给足一屏之外的余量，翻到底也知道「就是这些」。 */
.bom-content { padding: var(--bom-sp-4) var(--bom-sp-4) 40px; }

/* 标题 → 工具条 → 卡片 三段的节奏统一到同一个刻度 */
.bom-page-title { margin-bottom: var(--bom-sp-3); }

/* 工具条：列间距 12px、**行间距 8px**。
   行间距是这轮的重点——供应商页的「新增供应商」被挤到第二行时，
   两行之间没有任何间隙，那颗按钮看起来像是从第一行掉下来的。 */
.bom-toolbar { gap: var(--bom-sp-1) var(--bom-sp-2); margin-bottom: var(--bom-sp-3); }

/* 横向可滚动的表格：让「还能往右滚」这件事看得见。

   采购单列表 14 列、宽 1216px，卡片只有 956px——表格**能滚**（上一轮已加 overflow-x），
   但完全看不出来，「操作」列整列藏在右边，用户不会知道要横拖。

   **先试过 Lea Verou 那套 local/scroll 双层背景阴影，放弃了**：阴影画在容器背景层，
   而表头有浅底、合计行有浅底、偶数行有斑马纹底——它们逐条盖在阴影上，
   最后只在奇数行透出来，成了断断续续的一条，看着像渲染瑕疵。

   改用滚动条本身：声明 ::-webkit-scrollbar 会让浏览器用「占位式」滚动条
   （否则可能是不滚不显的叠加式，截图和部分环境里根本看不到），
   再给轨道一条浅色底——**溢出时才出现，且横贯整个卡片下沿，连续、无伪影**。
   做细做浅：它是提示，不是控件，别抢表格的注意力。
   两种滚动容器都要给：卡片直接装表格的，以及包在 Bootstrap `.table-responsive` 里的。 */
.card-surface:has(> table.table),
.card-surface .table-responsive {
    scrollbar-width: thin;
    scrollbar-color: #cbd5e1 #f1f5f9;
}

.card-surface:has(> table.table)::-webkit-scrollbar,
.card-surface .table-responsive::-webkit-scrollbar { height: 10px; }

.card-surface:has(> table.table)::-webkit-scrollbar-track,
.card-surface .table-responsive::-webkit-scrollbar-track { background: #f1f5f9; border-radius: 999px; }

.card-surface:has(> table.table)::-webkit-scrollbar-thumb,
.card-surface .table-responsive::-webkit-scrollbar-thumb {
    background: #cbd5e1; border-radius: 999px; border: 2px solid transparent; background-clip: content-box;
}

.card-surface:has(> table.table)::-webkit-scrollbar-thumb:hover,
.card-surface .table-responsive::-webkit-scrollbar-thumb:hover { background: #94a3b8; background-clip: content-box; }

/* 合计行与数据行拉开。采购单列表的「本页合计」原来和普通数据行长得一模一样，
   加粗都没有——一行数字混在流水里，读者要靠位置猜它是合计。
   给浅底 + 一条加重的上边框：位置感来自结构，不靠颜色喊。 */
.card-surface > table.table tfoot > tr > *,
.card-surface > table.table tbody > tr.table-light > * {
    background: #f8fafc;
    border-top: 2px solid var(--bom-border);
    font-weight: 700;
    color: #0f172a;
}

/* 纯文本空态（全站 20 处「暂无 xx 数据」只有一行灰字，没有走 .bom-empty）：
   至少给到和 .bom-empty 接近的呼吸，否则在一张卡片里像是漏掉了内容。
   不改这 20 处的结构——它们各自的父级不同，统一改 DOM 的回归面比收益大。 */
.card-surface > .text-muted.text-center,
.card-surface > .table-responsive > .text-muted.text-center {
    padding: 28px 16px;
    font-size: .92rem;
}

/* ---------- 主操作按钮移到标题行（2026-09-08）----------

   原来「新建 xx」是工具条的最后一个元素，靠 margin-left:auto 贴右。
   问题是工具条按钮多的页面（供应商/客户/库存）一行排不下就折行，
   主按钮独占第二行右端，看着像从第一行掉下来的——上一轮加了行间距只是缓解。

   **主按钮和查询条件本来就不是一类东西**：条件会随页面变多变少，
   而「新建」是这一页永远只有一个的入口。把它固定在标题行右端，
   位置就不再随条件多少漂移；物料页早就是这么做的，这轮把其余页面对齐过来。

   .no-print 由各页自己带（打印稿上不需要操作按钮）。 */
.bom-page-head {
    display: flex;
    align-items: center;
    gap: var(--bom-sp-1);
    flex-wrap: wrap;
    margin-bottom: var(--bom-sp-3);
}

.bom-page-head > .bom-page-title { margin-bottom: 0; }

/* 主按钮贴右端；标题与它之间的东西（副标题、次要按钮）按书写顺序排在左边 */
.bom-page-head > .btn-success,
.bom-page-head > .btn-primary { margin-left: auto; }

/* 标题行里已经有元素带 ms-auto（仓库页的「导入」就是），
   主按钮再要一份 auto 会把空白**平分**，次要按钮组悬在正中间。
   这时候把主按钮的 auto 撤掉：由前面那个 ms-auto 统一把整组顶到右端，
   次要按钮紧挨着主按钮，读起来是一组操作而不是两处。 */
.bom-page-head > .ms-auto ~ .btn-success { margin-left: 0; }
