/* 1号库 WMS的的达科技管理系统 - 标准列表页规范
   主色绿 #00A859（菜单选中 / 添加·保存·查询按钮）
   辅色橙 #FF7F00（审核·导出按钮 / 徽章提醒）
   logo、登录页、首页重点卡片：绿→橙 135° 渐变；其余一律纯色 */
:root {
  --primary: #00A859;
  --primary-dark: #008A49;
  --primary-light: #E6F7EF;
  --accent: #FF7F00;
  --accent-light: #FFF3E6;
  --danger: #E5484D;
  --danger-light: #FDECEC;
  --warn: #F5A623;
  --warn-light: #FEF6E7;
  --text: #1F2D3D;
  --text-2: #5A6B7D;
  --text-3: #90A0B0;
  --border: #E4E9F0;
  --bg: #F5F6F7;              /* 内容区浅灰（规范指定） */
  --card: #FFFFFF;
  --radius: 10px;
  --grad: linear-gradient(135deg, #00A859 0%, #FF7F00 100%);   /* 唯一允许的渐变 */
  --shadow: 0 1px 3px rgba(31, 45, 61, .06), 0 4px 14px rgba(31, 45, 61, .05);

  /* ---------- 全站字号总开关（2026-09-13 用户口径） ----------
     用户要求：全站文字比原字号「小 1 号」，批量按钮「小 2 号」。
     做法：所有写死的 font-size 都写成 calc(基准px - var(--fs-step))，
           批量按钮再乘 2（见下方「表格右上角工具条」那节的 .bulk-btn）。
     ⇒ 想整体调小/调大，只改这一个数字：0px = 原始字号，2px = 再小一号。
       不要在别处单独改字号，否则这个总开关会失灵。 */
  --fs-step: 1px;
}
/* ---------- 主题色（「页面设置」里切换，其余色值保持纯色派生） ---------- */
html[data-theme="blue"] {
  --primary: #1677FF; --primary-dark: #0958D9; --primary-light: #E8F1FF;
  --grad: linear-gradient(135deg, #1677FF 0%, #00C2A8 100%);
}
html[data-theme="purple"] {
  --primary: #6E4AE2; --primary-dark: #5636C4; --primary-light: #F0EBFF;
  --grad: linear-gradient(135deg, #6E4AE2 0%, #E24AA8 100%);
}
html[data-theme="orange"] {
  --primary: #FF7F00; --primary-dark: #E67200; --primary-light: #FFF3E6;
  --accent: #00A859; --accent-light: #E6F7EF;
  --grad: linear-gradient(135deg, #FF7F00 0%, #00A859 100%);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
  background: var(--bg); color: var(--text); font-size: calc(14px - var(--fs-step));
}

/* 版式：全宽顶部导航栏 + 下方「侧边菜单栏 / 内容区」。配色沿用品牌绿 #00A859 / 橙 #FF7F00，未做改动。 */
.layout { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
.app-body { flex: 1; display: flex; min-height: 0; }

/* ---------- 顶部导航栏（高度为原 58px 的一半 = 29px，内部元素同步缩小） ---------- */
.topbar {
  height: 29px; background: #fff; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 14px; flex-shrink: 0; gap: 12px;
}
.brand { display: flex; align-items: center; gap: 7px; min-width: 0; }
.brand .logo-icon { width: 22px; height: 22px; border-radius: 6px; font-size: calc(13px - var(--fs-step)); }
.brand-text { min-width: 0; display: flex; align-items: baseline; gap: 6px; }
.topbar-right { display: flex; align-items: center; gap: 7px; }
/* 顶栏右侧的日期 + 星期（在齿轮图标左边） */
.top-date { font-size: calc(11px - var(--fs-step)); color: var(--text-3); white-space: nowrap; letter-spacing: .2px; }
/* 顶栏「公司切换器」（2026-09-13）：一个账号可绑多家公司，切换后按新公司取数。
   绑 1 家显示只读胶囊，2 家以上才给下拉 —— 别让人以为单击能切。 */
.top-company { display: flex; align-items: center; }
.tc-static {
  font-size: calc(11px - var(--fs-step)); color: var(--text-2); white-space: nowrap;
  padding: 1px 7px; border: 1px solid var(--border); border-radius: 9px;
}
.tc-sel {
  font-size: calc(11px - var(--fs-step)); color: var(--text-2); font-family: inherit;
  height: 19px; padding: 0 4px; max-width: 140px;
  border: 1px solid var(--border); border-radius: 9px;
  background: #fff; cursor: pointer; transition: all .15s;
}
.tc-sel:hover, .tc-sel:focus { border-color: var(--primary); color: var(--primary); outline: none; }
.round-btn {
  width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--border);
  background: #fff; color: var(--text-2); font-size: calc(11px - var(--fs-step)); cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
  font-family: inherit; transition: all .15s;
}
.round-btn:hover { border-color: var(--primary); color: var(--primary); }
.round-btn.solid {
  background: var(--primary); border-color: var(--primary); color: #fff;
  font-size: calc(11px - var(--fs-step)); font-weight: 700;
}
.round-btn.solid:hover { background: var(--primary-dark); border-color: var(--primary-dark); color: #fff; }
.user-menu-wrap { position: relative; }
.user-menu {
  position: absolute; right: 0; top: 28px; width: 172px; background: #fff;
  border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow);
  padding: 6px; z-index: 60;
}
.user-menu .um-head { padding: 8px 10px; border-bottom: 1px solid var(--border); margin-bottom: 6px; display: flex; flex-direction: column; gap: 2px; }
.user-menu .um-head b { font-size: calc(13px - var(--fs-step)); }
.user-menu .um-head span { font-size: calc(11px - var(--fs-step)); color: var(--text-3); }
.user-menu a { display: block; padding: 8px 10px; border-radius: 7px; font-size: calc(13px - var(--fs-step)); color: var(--text-2); cursor: pointer; }
.user-menu a:hover { background: var(--primary-light); color: var(--primary-dark); }
.user-menu a.um-danger:hover { background: var(--danger-light); color: var(--danger); }

/* ---------- 侧边栏（宽度 194px = 原 216px 缩窄 1/10） ---------- */
.sidebar {
  width: 194px; background: #FFFFFF; border-right: 1px solid var(--border);
  display: flex; flex-direction: column; flex-shrink: 0;
}
.nav > a.nav-home {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: 8px; color: var(--text-2); text-decoration: none;
  font-size: calc(14px - var(--fs-step)); margin-bottom: 10px; transition: all .15s;
}
.nav > a.nav-home .ico { font-size: calc(15px - var(--fs-step)); width: 20px; text-align: center; }
.nav > a.nav-home:hover { background: var(--primary-light); color: var(--primary-dark); }
/* 菜单选中 = 主色绿 */
.nav > a.nav-home.active { background: var(--primary); color: #fff; font-weight: 600; }
.logo { display: flex; align-items: center; gap: 10px; padding: 18px 16px 14px; }
.logo-icon {
  width: 40px; height: 40px; border-radius: 10px; background: var(--grad);
  color: #fff; font-size: calc(22px - var(--fs-step)); font-weight: 700; display: flex;
  align-items: center; justify-content: center;
}
/* 2026-09-13：顶栏副标题「1号库」已去掉，.logo-sub 规则一并删除（登录页那处是内联字号，不受影响） */
.logo-title { font-weight: 700; font-size: calc(12px - var(--fs-step)); white-space: nowrap; }
.nav { flex: 1; padding: 10px 12px; overflow-y: auto; }
.nav-group { margin-bottom: 8px; }
.nav-group > a {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: 8px; color: var(--text-2); text-decoration: none;
  font-size: calc(14px - var(--fs-step)); transition: all .15s;
}
.nav-group > a:hover { background: var(--primary-light); color: var(--primary-dark); }
.nav-group > a.active { background: var(--primary); color: #fff; font-weight: 600; }
.nav-group > a .ico { font-size: calc(15px - var(--fs-step)); width: 20px; text-align: center; }
/* 侧栏字号 2026-09-13 统一为两档，且**标题档必须 ≥ 内容档**：
     标题档 14px 基准（渲染 13px）= 一级分组标题 .nav-label（与顶部「首页」同档）
     标题档 13px 基准（渲染 12px）= 三级子组标题 .nav-subtitle
     内容档 13px 基准（渲染 12px）= 所有叶子菜单（二级 / 三级 / 更深）
   原先把子组标题压到 11px、子组叶子压到 12px，出现「下级字号比上级大」的倒挂。
   ⚠️ 注意 --fs-step=1px：写 13px 实际渲染 12px，写 14px 渲染 13px。 */
.nav-label {
  padding: 10px 12px 6px; font-size: calc(14px - var(--fs-step)); color: var(--text-3);
  font-weight: 700; letter-spacing: .5px; text-transform: uppercase;
}
.nav-items { padding-left: 6px; }
.nav-items a {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px 9px 14px;
  border-radius: 8px; color: var(--text-2); text-decoration: none;
  margin-bottom: 1px; font-size: calc(13px - var(--fs-step)); transition: all .15s;
}
.nav-items a .ico { font-size: calc(15px - var(--fs-step)); width: 20px; text-align: center; }
.nav-items a:hover { background: var(--primary-light); color: var(--primary-dark); }
/* 菜单选中 = 主色绿（实心，与分组标题行保持一致） */
.nav-items a.active { background: var(--primary); color: #fff; font-weight: 600; }
.nav-items a.active .ico { color: #fff; }
.nav-subgroup { margin: 4px 0 8px 8px; }
/* 侧栏字号 2026-09-13 统一为两档：标题档 12px / 内容档 13px
   （原先把子组标题压到 11px、子组叶子压到 12px，出现「下级比上级字号大」的倒挂） */
.nav-subtitle { padding: 6px 10px 4px 14px; font-size: calc(13px - var(--fs-step)); color: var(--text-3); font-weight: 600; letter-spacing: .3px; }
.nav-subgroup .nav-items { padding-left: 6px; border-left: 1px dashed var(--border); margin-left: 4px; }
.nav-subgroup .nav-items a { padding: 7px 10px 7px 14px; font-size: calc(13px - var(--fs-step)); }
.nav-group.active > .nav-label { color: var(--primary); }
.nav-group.active > .nav-items {
  border-left: 2px solid var(--primary); margin-left: 10px; padding-left: 10px;
}

/* ---------- 侧边栏菜单折叠 ---------- */
.nav-label, .nav-subtitle {
  cursor: pointer; user-select: none;
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
}
.nav-label:hover, .nav-subtitle:hover { color: var(--primary); }
.nav-arrow {
  font-size: calc(11px - var(--fs-step)); color: var(--text-3); flex: none;
  transition: transform .22s ease, color .15s;
}
.nav-label:hover .nav-arrow, .nav-subtitle:hover .nav-arrow { color: var(--primary); }
.nav-group.collapsed > .nav-label .nav-arrow,
.nav-subgroup.collapsed > .nav-subtitle .nav-arrow { transform: rotate(-90deg); }
/* 分组标题里的「模块总览页」入口：文字整块可点进页面，右侧只留折叠箭头（点箭头才折叠） */
.nav-label > a.nl-home {
  color: inherit; text-decoration: none; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nav-label > .nav-arrow { padding: 3px 5px; margin: -3px -5px -3px 0; border-radius: 4px; }
.nav-label > .nav-arrow:hover { color: var(--primary); background: var(--primary-light); }
.nav-group.active > .nav-label > a.nl-home { color: var(--primary); }
/* 子组标题同样可以「文字进页面 + 箭头管折叠」（如「合同资料 › 客户合同」）：
   可点的标题用 text-2 比普通灰标题略深，好认出它是链接。
   ⚠️ 这个 a 在 .nav-items 里，会被 `.nav-items a{ padding:9px 10px 9px 14px }` 命中 →
   左右各多出 14/10px 内边距，标题文字（如「供应商合同」5 字）就被挤出盒子，
   必须显式复位 padding，只留上下 4px 扩大点击区。 */
.nav-subtitle > a.nl-home {
  color: var(--text-2); text-decoration: none; flex: 1; min-width: 0;
  padding: 4px 0; margin: -4px 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nav-subtitle > .nav-arrow { padding: 3px 5px; margin: -3px -5px -3px 0; border-radius: 4px; }
.nav-subtitle > .nav-arrow:hover { color: var(--primary); background: var(--primary-light); }
/* 三级及更深的叶子项：圆点图标不必占满 20px，内边距也收窄 ——
   否则 5 字科目名（承运商合同）会被挤成两行（实测可用宽度只剩 57px，5×12=60px）。 */
.nav-subgroup .nav-subgroup .nav-items a:not(.nl-home) { gap: 6px; padding: 7px 8px 7px 12px; }

/* ---------- 权限裁剪（按角色隐藏无权菜单） ----------
   ⚠️ `.nav-items a` / `.nav-label` / `.nav-subtitle` 都是 display:flex，
   光靠 HTML 的 [hidden] 属性（UA 样式 display:none）盖不住，必须显式 !important，
   否则无权菜单会"隐藏失败"照旧显示出来。 */
.nav .nav-group[hidden], .nav .nav-subgroup[hidden],
.nav .nav-items a[hidden], .nav .nav-label[hidden], .nav .nav-subtitle[hidden] {
  display: none !important;
}
/* 无权的「标题即入口」链接（`.nl-home`）：不隐藏、退化成灰色文字，
   否则分组标题会变空白；点击由 route() 守卫拦下并提示。 */
.nav a.nl-home[data-noPerm="1"] { opacity: .38; cursor: not-allowed; }
.nav-subgroup .nav-subgroup .nav-items a:not(.nl-home) .ico { width: 12px; font-size: calc(13px - var(--fs-step)); }
.collapse-wrap { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .25s ease; }
.nav-group.collapsed > .collapse-wrap,
.nav-subgroup.collapsed > .collapse-wrap { grid-template-rows: 0fr; }
.collapse-wrap > .nav-items { overflow: hidden; min-height: 0; }
.nav-group.collapsed, .nav-subgroup.collapsed { margin-bottom: 2px; }

/* ---------- 主区 ---------- */
.main-wrap { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.user-chip {
  font-size: calc(12px - var(--fs-step)); color: #fff; background: var(--primary);
  padding: 5px 12px; border-radius: 20px;
}
/* 内容区下内边距 40px → 10px（2026-09-13：让列表表格贴近底部固定栏的分页器）
   再配合 .content > *:last-child 去掉卡片外边距、.card.pager-docked 收窄卡片下内边距 */
/* 2026-10-04：内容区改 flex 纵向布局，最后一个卡片 flex-grow 撑满剩余高度 ——
   数据少/空态时白卡不再只有半截、下面拖一截灰底（翟总「页面显示全页，不要显示半页」）。
   flex-shrink:0 保持块级布局「内容多就滚」的原行为，防止卡片被压缩。 */
.content { flex: 1; overflow-y: auto; padding: 16px 20px 10px; display: flex; flex-direction: column; }
.content > * { flex-shrink: 0; }
.content > *:last-child { margin-bottom: 0; flex-grow: 1; }

/* ---------- 卡片/通用 ---------- */
.card {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 18px; margin-bottom: 16px;
}
.card-title { font-size: calc(15px - var(--fs-step)); font-weight: 700; margin-bottom: 14px; display: flex; align-items: center; justify-content: space-between; }
.card-title .sub { font-size: calc(12px - var(--fs-step)); color: var(--text-3); font-weight: 400; }

.grid-kpi { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; margin-bottom: 16px; }
.kpi {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 16px 18px; position: relative; overflow: hidden;
}
.kpi .k-label { font-size: calc(12px - var(--fs-step)); color: var(--text-2); margin-bottom: 6px; }
.kpi .k-value { font-size: calc(26px - var(--fs-step)); font-weight: 700; letter-spacing: -0.5px; }
.kpi .k-extra { font-size: calc(11px - var(--fs-step)); color: var(--text-3); margin-top: 4px; }
.kpi::after {
  content: ""; position: absolute; right: -20px; top: -20px; width: 70px; height: 70px;
  border-radius: 50%; opacity: .1;
}
.kpi.k-green .k-value { color: var(--primary); }
.kpi.k-green::after { background: var(--primary); }
.kpi.k-orange .k-value { color: var(--accent); }
.kpi.k-orange::after { background: var(--accent); }
.kpi.k-red .k-value { color: var(--danger); }
.kpi.k-red::after { background: var(--danger); }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.grid-3-2 { display: grid; grid-template-columns: 3fr 2fr; gap: 16px; }
@media (max-width: 1100px) { .grid-2, .grid-3-2 { grid-template-columns: 1fr; } }

/* ---------- 按钮 ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 6px; border: none; cursor: pointer;
  padding: 8px 16px; border-radius: 8px; font-size: calc(13px - var(--fs-step)); transition: all .15s;
  background: var(--primary); color: #fff; font-family: inherit;
}
.btn:hover { background: var(--primary-dark); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn.accent, .btn.warn { background: var(--accent); }
.btn.accent:hover, .btn.warn:hover { background: #E67200; }
.btn.info { background: #2E90FA; }
.btn.info:hover { background: #1B7FE8; }
.btn.ghost { background: #fff; color: var(--text-2); border: 1px solid var(--border); }
.btn.ghost:hover { color: var(--primary); border-color: var(--primary); }
.btn.danger { background: var(--danger); color: #fff; border: 1px solid var(--danger); }
.btn.danger:hover { background: #C7363B; }
.btn.danger-o { background: #fff; color: var(--danger); border: 1px solid var(--danger); }
.btn.danger-o:hover { background: var(--danger-light); }
.btn.sm { padding: 4px 10px; font-size: calc(12px - var(--fs-step)); border-radius: 6px; }
/* 操作按钮区 / 条件搜索框里的按钮用紧凑尺寸（参考图按钮高约 26px） */
.page-actions .btn, .filter-bar .btn { padding: 6px 13px; font-size: calc(12px - var(--fs-step)); border-radius: 6px; }
.btn-link { background: none; border: none; color: var(--primary); cursor: pointer; font-size: calc(13px - var(--fs-step)); padding: 2px 6px; }
.btn-link:hover { text-decoration: underline; }
.btn-link.warn { color: var(--accent); }
.btn-link.danger { color: var(--danger); }   /* v486：行内「删除/红冲」红色文字链（发票台账等） */

/* ---------- 表格（参考图：更紧凑的行高与字号） ---------- */
.table-wrap { overflow-x: auto; }
/* ---------- 表体独立滚动（fit）：工具栏 + 表头常驻，只有表格内容滚动 ----------
   app.js → fitListTables() 给列表页的 .table-wrap 动态限高（max-height = 视口剩余高度），
   限高后才能纵向滚动；表头 position:sticky 也必须有「可纵向滚动的祖先」才生效
   （原 .table-wrap 只有 overflow-x:auto 时自己就是滚动容器，表头纵向粘不住）。
   工具栏在表格上方、不受影响，于是这两行就钉在卡片里不动了。
   行数不够（没超出一屏）时不会限高，滚动条也不出现，页面照旧整体滚。 */
.table-wrap.tbl-scrolling { overflow: auto; overscroll-behavior: contain; }
/* 🔄 v579（2026-10-25「固定在表头」）曾把表头整行 sticky 钉顶；同日翟总看到竖滚后
   整条浅绿表头一直占着顶部，拍板「整个系统固定，只固定方格」—— v579d 撤整行钉顶，
   全系统回到：只有勾选/首列方格横向钉左（全局 .col-chk/.col-first left:0 规则）、
   操作列钉右（全局 .col-ops right:0），表头行随内容正常滚动。 */
table.tbl { width: 100%; border-collapse: collapse; font-size: calc(12px - var(--fs-step)); }
.tbl th {
  /* 🔄 v442（2026-10-19 翟总「表头样式对齐参考 TMS」+ 追加拍板「不参考颜色」）：
     只对齐 TMS 表头的**版式**——行高略抬（8px）、字重 600、通栏细分隔线（横竖），
     颜色不跟 TMS 的蓝，保留品牌绿（浅绿底 + 深绿字）。 */
  text-align: left; padding: 8px 10px; background: var(--primary-light); color: var(--primary-dark);
  font-weight: 600; font-size: calc(12px - var(--fs-step)); border-bottom: 1px solid var(--primary);
  border-right: 1px solid rgba(0, 168, 89, .25); white-space: nowrap;
}
.tbl th:last-child { border-right: none; }
.tbl td { padding: 6px 10px; font-size: calc(12px - var(--fs-step)); border-bottom: 1px solid #F0F3F7; white-space: nowrap; }
/* ---------- 操作列宽度（2026-09-19 用户口径：操作列宽度减半 → 不再均分剩余宽度） ----------
   系统所有表格的「操作」列几乎都在最后一列：width:1% + td 已有 nowrap = 该列收缩到按钮
   实际宽度（约为原先被拉伸宽度的一半以下），省下的空间均分给数据列。
   个别「操作」不在最后一列的表（如波次池）不受影响，仍走自动布局。 */
.tbl th:last-child, .tbl td:last-child { width: 1%; }
.tbl tr:hover td { background: #FAFCFE; }
.tbl .num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl tr.clickable { cursor: pointer; }

/* ---------- 徽章 ---------- */
.badge {
  display: inline-block; padding: 2px 10px; font-size: calc(12px - var(--fs-step)); border-radius: 20px;
  background: var(--bg); color: var(--text-2);
}
.badge.green { background: var(--primary-light); color: var(--primary-dark); }
.badge.orange { background: var(--accent-light); color: var(--accent); }
.badge.red { background: var(--danger-light); color: var(--danger); }
.badge.gray { background: #F0F2F5; color: var(--text-3); }
.badge.yellow { background: var(--warn-light); color: #B97A00; }
.badge.blue { background: var(--primary-light); color: var(--primary-dark); }

/* 开关 */
.switch { position: relative; display: inline-block; width: 44px; height: 22px; }
.switch input { opacity: 0; width: 0; height: 0; }
.slider { position: absolute; cursor: pointer; inset: 0; background: var(--text-3); border-radius: 22px; transition: .2s; }
.slider::before { position: absolute; content: ""; height: 18px; width: 18px; left: 2px; bottom: 2px; background: #fff; border-radius: 50%; transition: .2s; }
.switch input:checked + .slider { background: var(--primary); }
.switch input:checked + .slider::before { transform: translateX(22px); }

/* ---------- 表单 ---------- */
.form-row { display: flex; gap: 14px 16px; margin-bottom: 14px; flex-wrap: wrap; }
.form-item { display: flex; flex-direction: column; gap: 5px; }
.form-item label { font-size: calc(12px - var(--fs-step)); color: var(--text-2); font-weight: 500; }
/* 🔄 v92（2026-10-23 翟总拍板：出库订单详情红框信息条为基准，版式+颜色同步所有弹窗）
   只读信息概览条：normalizeModalShell 运行时给「无输入控件」的 .form-row 自动加
   .modal-info 类 → 统一浅蓝灰底+圆角边框、label 灰小字在上、值深色加粗在下、
   状态徽标与合计数字同排；含 input/select/textarea 的编辑表单行不受影响。 */
.form-row.modal-info {
  background: linear-gradient(180deg, #F8FAFD, #F2F5FA);
  border: 1px solid #E3E9F2; border-radius: 10px;
  padding: 12px 18px 13px; gap: 12px 36px; margin-bottom: 14px;
}
.form-row.modal-info > .form-item { gap: 3px; flex: 0 1 auto; min-width: 72px; }
.form-row.modal-info > .form-item > label { font-size: 12px; color: #8A94A6; font-weight: 500; }
.form-row.modal-info > .form-item > div { font-size: 13px; font-weight: 600; color: var(--text); line-height: 1.55; word-break: break-all; }
.form-row.modal-info > .form-item > div b { font-weight: 700; }
.form-row.modal-info > .form-item > div .badge { font-weight: 500; }
.form-row.modal-info .fz12 { font-size: 12px; color: var(--text-2); font-weight: 500; }
.form-row.modal-info .fz12 b { color: var(--text); font-weight: 700; }
/* 🔄 v660（2026-10-29 翟总截图「重新排版」）：entityForm 顶部 formTip 说明块 ——
   独立块级容器，不进 .form-row/.modal-info 的 flex 体系（否则富文本被拆成匿名 flex 项、
   收缩到 min-content 挤成「一字一行」竖排窄列），按正常文本流排版。 */
.form-tip {
  background: linear-gradient(180deg, #F8FAFD, #F2F5FA);
  border: 1px solid #E3E9F2; border-radius: 10px;
  padding: 11px 16px; margin-bottom: 14px;
  font-size: 13px; line-height: 1.8; color: var(--text);
  word-break: break-word;
}
.form-tip b { font-weight: 700; }
/* v425（2026-10-18 翟总「重新排版、美化排版，整个系统」）：弹窗表单字段撑满整行。
   原 .form-item 无 flex，输入框按 min-width:140px 自然宽度挤在左侧、右侧大片留白；
   现在弹窗体内的字段按 flex-basis 230px 均分行宽（880px 弹窗一行 3 个自动摊满，
   窄屏自动降为 2 个/1 个），全系统所有 entityForm 弹窗同时生效。 */
.modal-body .form-row > .form-item { flex: 1 1 230px; min-width: 0; }
.modal-body .form-row > .form-item .ipt { width: 100%; min-width: 0; box-sizing: border-box; }
/* v426（翟总「根据字体重新排版」）：按内容长度分三档宽度，日期/数字自动窄档，
   f.w 亦可显式指定（narrow/half/full）。 */
.modal-body .form-row > .form-item.fi-narrow { flex: 1 1 170px; max-width: 280px; }
.modal-body .form-row > .form-item.fi-half { flex: 2 1 340px; }
.modal-body .form-row > .form-item.fi-full { flex: 1 1 100%; }
/* 分组分节标题（v425：entityForm 的 secHead 由行内样式改为正式样式类） */
.form-sec {
  flex: 1 1 100%; min-width: 0;
  display: flex; align-items: center; gap: 8px;
  margin: 6px 0 2px; padding: 0 0 7px;
  border-bottom: 1px solid var(--border);
  font-weight: 600; font-size: calc(13px - var(--fs-step)); color: var(--text-1);
  letter-spacing: .5px;
}
.form-sec::before {
  content: ""; width: 3px; height: 13px; border-radius: 2px;
  background: var(--primary); flex: none;
}
.form-sec:first-child { margin-top: 0; }
/* 审核「查看详情」的只读字段：灰底块，一眼区别于可编辑的 .ipt 输入框 */
.ro-grid { display: flex; flex-wrap: wrap; gap: 12px 16px; }
.ro-item { flex: 1 1 220px; min-width: 170px; }
.ro-val { font-size: calc(13px - var(--fs-step)); color: var(--text); background: var(--bg); border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px; min-height: 30px; word-break: break-all; }
/* 「查看详情」直接复用编辑表单再整体置灰：去掉"可输入"观感，读起来像一份档案 */
.ro-form input:disabled, .ro-form select:disabled, .ro-form textarea:disabled {
  background: var(--bg); border-color: transparent; box-shadow: none;
  color: var(--text); -webkit-text-fill-color: var(--text); opacity: 1; cursor: default;
}
.ro-form select:disabled { appearance: none; -webkit-appearance: none; }
.ro-form button:disabled { display: none; }
.ro-trail { margin: 16px 0 10px; padding-top: 12px; border-top: 1px dashed var(--border);
  font-size: calc(12px - var(--fs-step)); color: var(--text-2); letter-spacing: .5px; }
input.ipt, select.ipt, textarea.ipt {
  border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px;
  font-size: calc(13px - var(--fs-step)); font-family: inherit; background: #fff; color: var(--text);
  outline: none; min-width: 140px;
  transition: border-color .12s, box-shadow .12s, background .12s;
}
input.ipt:hover, select.ipt:hover, textarea.ipt:hover { border-color: #B9C6CE; }
input.ipt:focus, select.ipt:focus, textarea.ipt:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(0,168,89,.1); background: #fff; }
input.ipt::placeholder, textarea.ipt::placeholder { color: #AAB7BF; }
input.ipt[readonly] { background: var(--bg); color: var(--text-2); }
/* v425：日期控件统一高度观感（去掉浏览器默认的左右内距突兀感） */
input.ipt[type="date"] { min-height: 36px; }
/* ---------- 条件搜索框（参考图版式：外框 + 左上标题 + 4 列网格 + 右下 查询/重置） ---------- */
.filter-bar {
  position: relative; display: grid; grid-template-columns: repeat(4, minmax(210px, 1fr));
  gap: 9px 18px; align-items: center; background: #fff;
  border: 1px solid var(--border); border-radius: 8px;
  padding: 34px 16px 14px; margin: 4px 0 12px;
}
.filter-bar::before {
  content: "条件搜索"; position: absolute; left: 16px; top: 10px;
  font-size: calc(12px - var(--fs-step)); font-weight: 600; color: var(--text-2); letter-spacing: .6px;
}
.filter-bar .fl-item { display: flex; align-items: center; gap: 8px; min-width: 0; }
.filter-bar .fl-label { font-size: calc(12px - var(--fs-step)); color: var(--text-3); white-space: nowrap; flex: none; }
.filter-bar .fl-item .ipt { flex: 1; min-width: 90px; }
.filter-bar .fl-actions { grid-column: 1 / -1; display: flex; justify-content: flex-end; gap: 8px; margin-top: 2px; }
@media (max-width: 1280px) { .filter-bar { grid-template-columns: repeat(3, minmax(200px, 1fr)); } }
@media (max-width: 960px) { .filter-bar { grid-template-columns: repeat(2, minmax(180px, 1fr)); } }
@media (max-width: 680px) { .filter-bar { grid-template-columns: 1fr; } }

/* ---------- 操作按钮区 / 查询筛选区（列表页统一版式） ---------- */
.page-actions { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.page-actions .pa-btns { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.page-actions .pa-hint { margin-left: auto; font-size: calc(12px - var(--fs-step)); color: var(--text-3); }
/* 卡片头部：标题在左，操作按钮统一收进右对齐的 .hdr-actions，避免 flex-between 把多个子元素摊开 */
.flex-between > .card-title { flex: 0 1 auto; margin-bottom: 0; }
.hdr-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
/* 页头归一化后整个操作组挪到左侧，margin-left:auto 必须复位，否则又会被推到右边 */
.page-actions .hdr-actions { margin-left: 0; }
/* 操作按钮区内的按钮保持紧凑（旧页头的按钮自带下边距） */
.page-actions .pa-btns button { margin-bottom: 0; }

/* ---------- 模态框 ---------- */
.modal-mask {
  position: fixed; inset: 0; background: rgba(15, 25, 35, .45);
  /* 🔄 v584（2026-10-25 翟总「点击确认导入不能导入系统」）：100 → 4000。
     批量导入/固定模板导入等自建弹窗遮罩是 inline z-index:1000~3000，
     标准弹窗(uiConfirm 二次确认/编辑表单)若还压在 100，会被整个盖住 ——
     点「确认导入」后弹出的「操作确认」框看不见、点不到，导入就此卡死。
     提到 4000：盖过一切自建遮罩(≤3000)，仍低于 加载层/日期面板/下拉(9999)。 */
  z-index: 4000; padding: 40px 16px; overflow-y: auto;
  display: none;
}
.modal-mask:not([hidden]) {
  display: flex; align-items: flex-start; justify-content: center;
}
.modal {
  background: #fff; border-radius: 14px; width: 640px; max-width: 96vw;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .25); animation: pop .18s ease;
  max-height: calc(100vh - 80px); display: flex; flex-direction: column;
}
.modal.wide { width: 880px; }
.modal.narrow { width: 460px; }
/* 🆕 v396（2026-10-15）：超宽弹窗 —— 配送计划「详情」（装车主体 + 明细 14 列）用。
   14 列在 `.modal.wide` 880px 下每列仅约 63px，地址列会被挤成省略号 → 加宽到 1240px。
   窄屏仍保底 96vw，明细表自带 overflow-x:auto 兜底。 */
.modal.modal-xl { width: min(1240px, 96vw); }
@keyframes pop { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
.modal-head {
  padding: 15px 20px; border-bottom: 1px solid var(--border);
  display: flex; justify-content: space-between; align-items: center; font-weight: 700; font-size: calc(15px - var(--fs-step));
  background: linear-gradient(180deg, #FBFCFD, #F6F8FA);
  border-radius: 14px 14px 0 0;
}
.modal-close { background: none; border: none; font-size: calc(18px - var(--fs-step)); cursor: pointer; color: var(--text-3); line-height: 1; }

/* ---------- 弹窗窗口按钮（最小化 / 最大化 / 关闭）----------
   2026-09-17 用户口径：所有弹窗右上角统一加「− ▢ ×」三连（原来只有一个 ×）。
   由 JS 的 mountModalWinBtns() 注入，不要求各弹窗自己写 —— 52 处 modal-head
   写法各异，逐个改必漏；统一后处理才能「系统所有界面都加上」。 */
.modal-winbtns { display: flex; align-items: center; gap: 2px; margin-left: auto; flex: 0 0 auto; }
.modal-winbtns > button {
  background: none; border: none; cursor: pointer; color: var(--text-3);
  width: 28px; height: 28px; border-radius: 6px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  transition: background .12s, color .12s;
}
.modal-winbtns > button:hover { background: #EEF2F6; color: var(--text-1); }
.modal-winbtns > button.modal-close:hover { background: #FDECEC; color: #E24B4A; }
.modal-winbtns svg { display: block; }

/* 最大化：铺满可视区（留一点边距，视觉上仍是「浮在上面」而不是全屏页面） */
.modal-mask.maxed { padding: 0; }
.modal-mask.maxed .modal,
.modal.maxed { width: 96vw !important; max-width: 96vw; height: calc(100vh - 24px); max-height: calc(100vh - 24px); border-radius: 10px; }
.modal-mask.maxed .modal-body { flex: 1; }

/* ---------- 入库订单新增弹窗：表头 7 字段单排（2026-09-17 用户口径）----------
   订单日期 / 客户简称 / 入库类型 / 商品类型 / 发货省 / 发货市 / 发货区 排成一排。
   `.modal.wide` 只有 880px，7 格每格仅约 111px，时间控件会被压扁 → 单独加宽到 1200px。
   窗口再窄时不挤坏版式，改为整行横向滚动（配合弹窗自带的「最大化」按钮）。 */
.modal.inb-wide { width: min(1200px, 96vw); }
.inb-head-row {
  display: grid; grid-template-columns: repeat(7, minmax(128px, 1fr));
  gap: 10px; overflow-x: auto; padding-bottom: 2px;
}
/* 注意两个坑：
   ① 标签不能用 flex —— 会把「标签文字」和「必填 *」当成两个 flex item 竖着排，星号掉到第二行；
   ② 标签上的 white-space:nowrap 必须保留（防止「订单日期 *」被拆行），但这样控件就不会自动换行，
      所以控件得显式 display:block 才能落到第二行，否则控件与标签挤在一行并把整行撑出横向滚动。 */
.inb-head-row > label {
  display: block; min-width: 0;
  font-size: calc(12px - var(--fs-step)); color: var(--text-2); white-space: nowrap;
}
.inb-head-row > label .ipt {
  display: block; width: 100%; min-width: 0; box-sizing: border-box; margin-top: 4px;
}

/* 最小化：弹窗收成左下角一条小条，点它即还原。
   注意 mask 仍要挡住背后（否则点「还原」时下面的页面被误操作），故只改 modal 自身。 */
.modal-mask.minned { padding: 0; background: transparent; pointer-events: none; }
.modal-mask.minned .modal,
.modal.minned {
  position: fixed; left: 20px; bottom: 20px; width: 260px !important; height: 46px;
  max-height: 46px; overflow: hidden; border-radius: 10px; cursor: pointer;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .28); pointer-events: auto;
  animation: none;
}
.modal-mask.minned .modal-body,
.modal-mask.minned .modal-foot { display: none; }
.modal-mask.minned .modal-head { padding: 12px 14px; border-bottom: none; }
.modal-mask.minned .modal-winbtns > button.modal-max,
.modal-mask.minned .modal-winbtns > button.modal-close { display: none; }
/* 最小化后标题可能很长，截断 */
.modal-mask.minned .modal-head > :first-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.modal-body { padding: 18px 20px; overflow-y: auto; background: #FCFDFE; }
.modal-foot { padding: 13px 20px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 10px; background: #FBFCFD; border-radius: 0 0 14px 14px; }
/* 弹窗底部左角的「归属公司 / 归属事业部」（2026-09-16 用户口径：从表单主体挪进底部按钮行，小号字）。
   margin-right:auto 把它顶到最左，取消/保存照旧靠右；min-width:0 是必须的 ——
   全局 `input.ipt { min-width:140px }` 会让这两个下拉撑得很宽，底部行装不下。 */
.org-inline {
  display: flex; align-items: center; gap: 6px; margin-right: auto;
  min-width: 0; flex-wrap: wrap; row-gap: 4px;
}
.org-inline .org-lb { font-size: calc(12px - var(--fs-step)); color: var(--text-2); white-space: nowrap; }
.org-inline select.ipt {
  min-width: 0; width: auto; max-width: 168px; padding: 4px 6px;
  font-size: calc(12px - var(--fs-step)); border-radius: 6px;
}

/* ---------- Toast ---------- */
#toastBox { position: fixed; top: 18px; right: 18px; z-index: 10001; display: flex; flex-direction: column; gap: 8px; }
.toast {
  background: #fff; border-radius: 10px; box-shadow: 0 6px 24px rgba(0,0,0,.14);
  padding: 12px 18px; font-size: calc(13px - var(--fs-step)); display: flex; align-items: center; gap: 8px;
  animation: slideIn .25s ease; border-left: 4px solid var(--primary); min-width: 240px;
}
.toast.err { border-left-color: var(--danger); }
.toast.warn { border-left-color: var(--accent); }
@keyframes slideIn { from { transform: translateX(30px); opacity: 0; } to { transform: none; opacity: 1; } }

/* ---------- 库位格子 ---------- */
.zone-tabs { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.zone-tab {
  padding: 7px 16px; border-radius: 20px; border: 1px solid var(--border);
  background: #fff; cursor: pointer; font-size: calc(13px - var(--fs-step)); color: var(--text-2);
}
.zone-tab.active { background: var(--primary); color: #fff; border-color: var(--primary); }
.loc-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.loc-cell {
  width: 92px; height: 62px; border-radius: 8px; border: 1px solid var(--border);
  background: #fff; cursor: pointer; padding: 6px 8px; font-size: calc(11px - var(--fs-step));
  display: flex; flex-direction: column; justify-content: space-between; transition: all .12s;
}
.loc-cell:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.loc-cell .lc-code { font-weight: 700; font-size: calc(11px - var(--fs-step)); color: var(--text); }
.loc-cell.used { background: var(--primary-light); border-color: var(--primary); }
.loc-cell.empty { border-style: dashed; color: var(--text-3); }
.loc-cell.off { background: #F0F2F5; color: var(--text-3); }
.loc-legend { display: flex; gap: 16px; font-size: calc(12px - var(--fs-step)); color: var(--text-2); margin: 12px 0; align-items: center; flex-wrap: wrap; }
.legend-dot { width: 12px; height: 12px; border-radius: 4px; display: inline-block; margin-right: 5px; vertical-align: -1px; }

/* ---------- 图表 ---------- */
.chart { width: 100%; height: 320px; }
.chart-sm { width: 100%; height: 280px; }

/* ---------- 分页器（‹ 1 2 3 ›，当前页加绿框） ---------- */
.pager { display: flex; gap: 8px; align-items: center; justify-content: flex-end; margin-top: 14px; font-size: calc(13px - var(--fs-step)); color: var(--text-2); }
.pager button {
  min-width: 30px; height: 30px; padding: 0 8px; border-radius: 6px;
  border: 1px solid var(--border); background: #fff; color: var(--text-2);
  font-size: calc(13px - var(--fs-step)); font-family: inherit; cursor: pointer; transition: all .15s;
}
.pager button:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); }
.pager button:disabled { cursor: default; opacity: .45; }
.pager button.on {
  border-color: var(--primary); color: var(--primary); font-weight: 700;
  background: #fff; opacity: 1;
}
/* 部分老页面用 .pagination 内联分页器（按钮带 .btn.ghost.sm）——
   这里用更高优先级的选择器把它们统一成与 .pager 相同的外观，省去逐个改渲染函数。
   .card .pagination button (0,2,1) 高于 .btn.sm / .btn.ghost (0,2,0)。 */
.pagination { display: flex; gap: 8px; align-items: center; justify-content: flex-end; margin-top: 14px; }
.card .pagination button, .pager button {
  min-width: 30px; height: 30px; padding: 0 8px; border-radius: 6px;
  border: 1px solid var(--border); background: #fff; color: var(--text-2);
  font-size: calc(13px - var(--fs-step)); font-family: inherit; cursor: pointer; transition: all .15s;
}
.card .pagination button:hover:not(:disabled), .pager button:hover:not(:disabled) {
  border-color: var(--primary); color: var(--primary); background: #fff;
}
.card .pagination button:disabled, .pagination button:disabled { cursor: default; opacity: .45; }
/* 老分页器里「当前页」是那个不带 .ghost 的实心按钮 —— 改用线框的样式：白底 + 绿框 + 绿字 */
.card .pagination button:not(.ghost) {
  border-color: var(--primary); color: var(--primary); font-weight: 700;
  background: #fff; opacity: 1;
}

/* ---------- 录入凭证（标准凭证模板） ---------- */
.voucher-card { padding: 0; }
.voucher-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px; border-bottom: 1px solid var(--border); flex-wrap: wrap; gap: 14px;
}
.voucher-title { font-size: calc(22px - var(--fs-step)); font-weight: 700; color: var(--text); letter-spacing: 2px; }
.voucher-subtitle { font-size: calc(12px - var(--fs-step)); color: var(--text-3); margin-top: 4px; }
.voucher-meta { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.vmeta { display: flex; align-items: center; gap: 8px; font-size: calc(13px - var(--fs-step)); color: var(--text-2); }
.vmeta label { color: var(--text-3); font-size: calc(12px - var(--fs-step)); }
.vmeta input.ipt { padding: 6px 8px; min-width: 0; }
.voucher-table { width: 100%; border-collapse: collapse; }
.voucher-table th {
  /* v442：版式与 .tbl th 对齐（行高 8px / 字重 600 / 同分隔线），颜色保留品牌绿 */
  background: var(--primary-light); padding: 8px 10px; color: var(--primary-dark);
  font-size: calc(12px - var(--fs-step)); border-bottom: 1px solid var(--primary); font-weight: 600;
}
.voucher-table td { padding: 6px 10px; border-bottom: 1px solid #F0F3F7; }
.voucher-table td .ipt { width: 100%; min-width: 0; padding: 7px 8px; }
.voucher-table td .ipt.num { text-align: right; }
.voucher-table .seq { text-align: center; color: var(--text-3); font-size: calc(12px - var(--fs-step)); }
.voucher-table .voucher-total td { background: #F8FAFC; border-top: 2px solid var(--border); padding: 10px 8px; }
.voucher-tools { padding: 12px 18px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 14px; }
.voucher-foot {
  padding: 16px 18px; display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; flex-wrap: wrap;
}
.voucher-foot-left { flex: 1; }
.voucher-foot-right { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.voucher-foot .form-row { align-items: flex-end; }
.voucher-foot .form-row .form-item { margin-bottom: 0; }
@media (max-width: 1100px) {
  .voucher-foot { flex-direction: column; align-items: flex-start; }
}
.drop-zone {
  border: 2px dashed var(--border); border-radius: 14px; padding: 44px 20px;
  text-align: center; color: var(--text-2); cursor: pointer; transition: all .15s;
}
.drop-zone:hover, .drop-zone.drag { border-color: var(--primary); background: var(--primary-light); }
.drop-zone .dz-icon { font-size: calc(40px - var(--fs-step)); margin-bottom: 10px; }
.import-stat { display: flex; gap: 12px; flex-wrap: wrap; margin: 14px 0; }
.import-stat .st {
  background: var(--bg); border-radius: 10px; padding: 12px 18px; text-align: center; min-width: 130px;
}
.import-stat .st b { font-size: calc(22px - var(--fs-step)); display: block; }
.import-stat .st span { font-size: calc(12px - var(--fs-step)); color: var(--text-2); }
.err-list {
  background: var(--danger-light); border-radius: 8px; padding: 12px 14px;
  font-size: calc(12px - var(--fs-step)); color: var(--danger); max-height: 200px; overflow-y: auto;
}
.ok-list { background: var(--primary-light); border-radius: 8px; padding: 12px 14px; font-size: calc(13px - var(--fs-step)); color: var(--primary-dark); }

.progressbar { height: 6px; background: var(--border); border-radius: 4px; overflow: hidden; margin: 8px 0; }
.progressbar > div { height: 100%; background: var(--primary); transition: width .3s; }

.empty-tip { text-align: center; color: var(--text-3); padding: 40px 0; font-size: calc(13px - var(--fs-step)); }
.tag-mono { font-family: "SF Mono", Consolas, monospace; font-size: calc(12px - var(--fs-step)); }
/* 🔄 2026-10-24（翟总：物流码太长）：超长编码列截断显示 —— 悬停 title 看全码、点击复制（app.js wmsCopyCode） */
.clip-code { display: inline-block; max-width: 148px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; cursor: pointer; }
.clip-code:hover { color: var(--primary-dark); text-decoration: underline; }
.flex-between { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.mt8 { margin-top: 8px; } .mt14 { margin-top: 14px; }
.text-green { color: var(--primary-dark); } .text-orange { color: var(--accent); }
.text-red { color: var(--danger); } .text-gray { color: var(--text-3); }
.fz12 { font-size: calc(12px - var(--fs-step)); }

.radio-row { display: flex; gap: 16px; align-items: center; padding: 7px 0; font-size: calc(13px - var(--fs-step)); }
.radio-row label { display: flex; align-items: center; gap: 6px; cursor: pointer; color: var(--text-2); }
.radio-row input[type="radio"] { accent-color: var(--primary); cursor: pointer; }

/* ==================================================================
   标准列表页规范（多页签 / 表格工具栏 / 操作列 / 分页器）
   ================================================================== */

/* ---------- ① 顶部多页签（参考图：灰底条 + 胶囊页签 + 两端滚动箭头）
   2026-09-13：整条高度 42px → 30px，页签本体 28px → 22px（用户选「更窄」档） ---------- */
.tab-wrap {
  display: flex; align-items: center; height: 30px; padding: 0 6px;
  background: #F2F4F7; border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.tab-nav {
  width: 20px; height: 20px; flex: none; border: none; background: none; cursor: pointer;
  color: var(--text-3); font-size: calc(15px - var(--fs-step)); line-height: 1; border-radius: 5px; font-family: inherit;
}
.tab-nav:hover { background: rgba(0, 0, 0, .06); color: var(--primary); }
.tab-bar {
  flex: 1; display: flex; align-items: center; gap: 5px; height: 100%; padding: 0 4px;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
}
.tab-bar::-webkit-scrollbar { height: 0; }
.tab {
  display: flex; align-items: center; gap: 6px; height: 22px; flex: none;
  padding: 0 9px; border-radius: 11px; font-size: calc(12px - var(--fs-step));
  color: var(--text-2); cursor: pointer; white-space: nowrap;
  background: #E5E9EF; border: none; font-family: inherit;
  transition: background .15s, color .15s, box-shadow .15s;
}
.tab::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #BCC4D0; flex: none; }
.tab:hover { background: #DBE0E8; color: var(--primary-dark); }
.tab.on {
  background: #fff; color: var(--primary-dark); font-weight: 600;
  box-shadow: 0 1px 3px rgba(16, 24, 40, .12);
}
.tab.on::before { background: var(--primary); }
.tab .tab-x {
  width: 13px; height: 13px; border-radius: 50%; font-size: calc(11px - var(--fs-step)); line-height: 1;
  display: flex; align-items: center; justify-content: center; color: var(--text-3);
  flex: none;
}
.tab .tab-x:hover { background: rgba(0, 0, 0, .10); color: var(--text); }
.tab.on .tab-x { color: var(--primary-dark); }

/* ---------- ③ 表格右上角工具条：左＝操作按钮（添加/批量删除/批量导入），右＝刷新/列设置/导出/全屏 ---------- */
.tbl-tools {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 6px; margin: 2px 0 8px;
}
/* 操作按钮组（从卡片头部搬过来，见 app.js enhanceOneTable ⑤）：靠左，与右侧「导出」同一条线 */
.tbl-tools .tt-acts {
  display: flex; align-items: center; gap: 8px; margin-right: auto;
  min-width: 0; flex-wrap: wrap;
}
.tbl-tools .tt-acts > * { display: flex; align-items: center; gap: 8px; margin-left: 0; }
.tbl-tools .tt-acts .btn { height: 28px; padding: 0 11px; font-size: calc(11px - var(--fs-step)); border-radius: 6px; }
/* 批量按钮（文案以「批量」开头，由 app.js 的 markBulkBtns() 打标）：字号比全站再小一号
   —— 用户口径「批量按钮比原字体小 2 号」。与上行选择器同权重，靠声明在后覆盖；
   没被收进工具条的场景由第一个选择器兜底。 */
.bulk-btn, .tbl-tools .tt-acts .bulk-btn { font-size: calc(11px - var(--fs-step) * 2); }
/* 搬进本行的副标题提示（表说明），放按钮右侧，过窄时省略号收尾，不挤走右侧工具按钮 */
.tbl-tools .tt-acts .pa-hint {
  display: block; flex: 0 1 auto; min-width: 0; font-size: calc(11px - var(--fs-step)); color: var(--text-3);
  line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tt-btn {
  display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 9px;
  border: 1px solid var(--border); background: #fff; border-radius: 6px;
  font-size: calc(11px - var(--fs-step)); color: var(--text-2); cursor: pointer; font-family: inherit;
  transition: all .15s; white-space: nowrap;
}
.tt-btn:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-light); }
.tt-btn .tt-ico { font-size: calc((12px - var(--fs-step)) * 2 / 3); line-height: 1; }

/* ---------- ③-2 「条件搜索」面板可折叠：工具栏放大镜（🔍）切换，默认收起 ---------- */
.filter-bar.fl-collapsed { display: none; }
.tbl-tools .tt-mag { padding: 0 8px; flex: none; }
.tbl-tools .tt-mag svg { display: block; width: 10px; height: 10px; }   /* 原 15px，按 2/3 缩 */
.tbl-tools .tt-mag.on { border-color: var(--primary); color: var(--primary); background: var(--primary-light); }
.tt-wrap { position: relative; display: inline-flex; }
.tt-menu {
  position: absolute; right: 0; top: 32px; min-width: 168px; max-height: 300px; overflow-y: auto;
  background: #fff; border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 8px 28px rgba(31, 45, 61, .14); padding: 6px; z-index: 80;
}
.tt-menu .tt-mi {
  display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 7px;
  font-size: calc(12px - var(--fs-step)); color: var(--text-2); cursor: pointer; white-space: nowrap;
}
.tt-menu .tt-mi:hover { background: var(--primary-light); color: var(--primary-dark); }
.tt-menu .tt-mi input { accent-color: var(--primary); cursor: pointer; margin: 0; }
.tt-menu .tt-sep { height: 1px; background: var(--border); margin: 5px 2px; }

/* 卡片全屏时铺满屏幕 */
.card.card-fullscreen { position: fixed; inset: 0; z-index: 900; margin: 0; border-radius: 0; overflow: auto; padding: 18px 22px; }

/* ---------- ④ 勾选列 / 排序表头 / 固定右侧操作列 ---------- */
.tbl th.col-chk, .tbl td.col-chk { width: 40px; text-align: center; padding-left: 10px; padding-right: 10px; }
.tbl th.col-chk input, .tbl td.col-chk input { cursor: pointer; accent-color: var(--primary); margin: 0; vertical-align: middle; }
/* 勾选列固定左侧（2026-09-13）：与「操作列固定右侧」左右对称 —— 横向滚动时勾选框不动。
   表头左上角那一格会同时被 sticky top（见 .tbl-scrolling 那条）和 sticky left 命中，
   两个方向的偏移量是不同属性、不冲突，于是自动双钉。
   背景必须配套写死：sticky 单元格若不透明，横滚时下面的字会透出来。 */
.tbl th.col-chk, .tbl td.col-chk {
  position: sticky; left: 0; z-index: 2;
  box-shadow: 6px 0 8px -6px rgba(31, 45, 61, .18);
}
/* 🔄 2026-10-07 v291（翟总「勾选列固定左边不动」）：WMS 通用列表的勾选列也挂 col-chk 了。
   sticky 列必须不透明，否则横向滚动时右侧内容会从冻结格底下透出来。
   td 白底（hover 行由 .tbl tr:hover td 特异性更高自动覆盖为 #FAFCFE）；th 用表头同款底色。 */
.tbl td.col-chk { background: #fff; }
/* v442：表头加深底描边后，冻结勾选列表头必须同色，否则横滚时露色差 */
.tbl th.col-chk { background: var(--primary-light); }
.tbl td.col-chk { background: #fff; }
.tbl tr:hover td.col-chk { background: #FAFCFE; }

/* 🔄 2026-10-22 翟总「整个系统按红框图固定左右两边」：没有勾选列的表（报表类，
   如仓库日报）首列数据列也要钉左 —— 由 app.js enhanceOneTable ①-b 统一打 col-first。
   钉法与 col-chk 完全对称，只是不限宽（数据列内容不居中）。
   注意本块必须放在 row-over-plan / 超收标红等整行变色规则**之前**，
   让那些行色在 hover 态能盖过这里的白底。 */
.tbl th.col-first, .tbl td.col-first {
  position: sticky; left: 0; z-index: 2;
  box-shadow: 6px 0 8px -6px rgba(31, 45, 61, .18);
}
.tbl th.col-first { background: var(--primary-light); }
.tbl td.col-first { background: #fff; }
.tbl tr:hover td.col-first { background: #FAFCFE; }

/* 🔄 v292 翟总「收货不能大于计划件数」：复核工单详情超收标红。
   输入框即时红框 + 整行浅红底（双重点出是哪一行），保存/确认时前端先拦、后端再兜。
   特异性实算（2026-10-07 独立核验）：行红底 (0,2,2) 与 .tbl tr:hover td(L320, 0,2,2) 同级，
   靠**源顺序**（本规则在其后）取胜；hover 态由下面 (0,3,2) 那条兜住，红底不会被 #FAFCFE 盖掉。
   输入框红框 (0,2,1) > input.ipt(L361, 0,1,1)；与 input.ipt:focus(L366, 0,2,1) 同级但靠源顺序取胜
   —— ⚠️ 本规则**必须保持在 L366 之后**，挪到前面聚焦时会被绿晕压掉。 */
.tbl input.qty-over-plan { border-color: #E24B4A; box-shadow: 0 0 0 2px rgba(226, 75, 74, .18); }
.tbl tr.row-over-plan > td { background: var(--danger-light); }
.tbl tr.row-over-plan:hover > td { background: var(--danger-light); }
.tbl th.sortable { cursor: pointer; user-select: none; }
.tbl th.sortable .sort-ind { opacity: .3; margin-left: 4px; font-size: calc(11px - var(--fs-step)); }
.tbl th.sortable:hover { color: var(--primary-dark); }
.tbl th.sortable:hover .sort-ind { opacity: .8; }
.tbl th.sorted { color: var(--primary); }
.tbl th.sorted .sort-ind { opacity: 1; }

.tbl th.col-ops, .tbl td.col-ops {
  position: sticky; right: 0; z-index: 2;
  box-shadow: -6px 0 8px -6px rgba(31, 45, 61, .18);
  /* 操作列不许被其它列挤压缩窄（2026-09-15）：行内按钮数量随审核状态变化，
     待提交态「编辑/删除/提交审核」三个按钮合计约 103px，而 auto 布局在列多时
     会把它压到 84px → 按钮溢出黏在一起。
     2026-09-16 改成写死下限 118px（原来是 max-content）：max-content 只管"不被压"，
     只读态只有一个「查看」按钮时整列就只有 39px 宽，太局促（用户口径「所有操作格再宽一点」）。
     min-width 是**下限**，按钮多时 auto 布局仍会按内容把列撑开，两不耽误。
     🔄 v532f（2026-10-23 翟总截图「系统操作变短一半」）：150 → 75px。
     下限砍半后：按钮少的页（只读查看/编辑查看两枚）整列明显收窄；
     按钮多的页（编辑/删除/提交审核 103px）auto 布局仍按内容撑开，不挤不溢。 */
  min-width: 75px;
  white-space: nowrap;
  /* 操作列两侧留白加大（2026-09-16 用户口径「所有操作格再宽一点」）：
     行内按钮本来就小（整列按 2/3 缩过），再贴着列边界就跟右侧邻列黏在一起，
     鼠标点起来也局促。左右各留 18px，视觉上把这一列单独"框"出来。
     全站列表页共用这一个类（app.js 的 enhanceOpsCol 统一注入），改一处即全站生效。 */
  padding-left: 18px;
  padding-right: 18px;
}
/* v442：冻结的操作列表头与表头同色（版式对齐 TMS、颜色保留品牌绿） */
.tbl th.col-ops { background: var(--primary-light); }
.tbl td.col-ops { background: #fff; }
.tbl tr:hover td.col-ops { background: #FAFCFE; }
/* 行内按钮容器改成 inline-flex（2026-09-16）：审核流往 td 里追加的「提交审核 / 撤回 / 审核通过」
   是**容器外的兄弟节点**（见 app.js 的 audit-act），原来 .row-acts 是 block 级 flex，
   于是它自己占一行、审核按钮被挤到第二行 → 每行两行按钮、行高翻倍。
   改成 inline-flex 后两者在同一行排下来（td 本身 white-space:nowrap）。
   列宽已给到 150px 下限，装得下「编辑/删除/提交审核」。 */
.col-ops .row-acts { display: inline-flex; align-items: center; vertical-align: middle; gap: calc(6px * 2 / 3); }
.tbl td.col-ops > .btn, .tbl td.col-ops > .audit-act { vertical-align: middle; }

/* ---------- ④-2 拖动表头右边界调列宽（2026-09-13，全列可调、不记忆） ----------
   手柄由 app.js → enhanceColResize() 插进每个表头单元格；拖动逻辑见 colFreeze / pointerdown。
   ① th 需要定位上下文，手柄才能贴在右边界上。sticky 的 col-chk / col-ops 用更高优先级
      的 position:sticky 覆盖，不受影响。
   ② 一旦拖过（.col-freeze），表格切成 table-layout:fixed + <colgroup> 固定列宽，
      这时内容超宽不会再撑开列 → 补 ellipsis 免得文字溢出到邻格。 */
.tbl th { position: relative; }
.col-resizer {
  position: absolute; top: 0; right: 0; width: 7px; height: 100%;
  cursor: col-resize; z-index: 6; user-select: none; touch-action: none;
}
.col-resizer::before {
  content: ""; position: absolute; top: 2px; bottom: 2px; right: 2px; width: 1px;
  background: transparent; transition: background .12s;
}
.col-resizer:hover::before { background: var(--primary); }
body.col-resizing { cursor: col-resize !important; user-select: none; }
body.col-resizing .col-resizer::before { background: var(--primary); }
.tbl.col-freeze td:not(.col-ops):not(.col-chk) { overflow: hidden; text-overflow: ellipsis; }

/* 审核流注入的行内按钮（提交审核 / 撤回 / 审核通过 / 驳回）
   走的是 .btn.sm，与 .act 不是同一套，必须单独同规格缩放，否则同一列里两种大小 */
.tbl td.col-ops .audit-act {
  height: calc(26px * 2 / 3); padding: 0 calc(10px * 2 / 3);
  border-radius: 4px; font-size: calc((12px - var(--fs-step)) * 2 / 3);
}

/* ---------- ⑤ 标准操作按钮：编辑（绿）/ 查看（描边绿）/ 删除（红）/ 更多 ---------- */
/* 操作列按钮：整体按 2/3 缩（字号/高度/内边距/圆角一起缩，避免"小字撑大框"的空旷感） */
.act {
  display: inline-flex; align-items: center; height: calc(26px * 2 / 3); padding: 0 calc(10px * 2 / 3);
  border-radius: 4px; font-size: calc((12px - var(--fs-step)) * 2 / 3); cursor: pointer; font-family: inherit;
  border: 1px solid transparent; background: #fff; color: var(--text-2);
  white-space: nowrap; transition: all .15s; text-decoration: none;
}
/* v254/v255：子表「商品名称」前的「选」按钮 → 打开选择商品弹窗（可勾选多条批量添加） */
.iiPick {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; margin-right: 4px; vertical-align: middle;
  border: 1px solid var(--primary); border-radius: 4px; background: var(--primary);
  color: #fff; cursor: pointer; font-size: 14px; line-height: 1; font-family: inherit;
  padding: 0; transition: all .15s;
}
.iiPick:hover { background: var(--primary-dark); border-color: var(--primary-dark); }

.act-edit { background: var(--primary); border-color: var(--primary); color: #fff; }
.act-edit:hover { background: var(--primary-dark); border-color: var(--primary-dark); color: #fff; }
.act-view { background: #fff; border-color: var(--primary); color: var(--primary); }
.act-view:hover { background: var(--primary-light); }
.act-del { background: #fff; border-color: var(--danger); color: var(--danger); }
.act-del:hover { background: var(--danger-light); }
.act-more { background: #fff; border-color: var(--border); color: var(--text-2); }
.act-more:hover { border-color: var(--primary); color: var(--primary); }
.act-wrap { position: relative; display: inline-block; }
/* 用 fixed 定位，避免被 .table-wrap{overflow:auto} 裁剪（坐标在 JS 里算） */
.act-menu {
  position: fixed; min-width: 118px; z-index: 950;
  background: #fff; border: 1px solid var(--border); border-radius: 9px;
  box-shadow: 0 8px 26px rgba(31, 45, 61, .16); padding: 5px;
  display: flex; flex-direction: column; gap: 2px;
}
.act-menu .act-menu-btn {
  text-align: left; border: none; background: none; padding: 7px 10px; border-radius: 6px;
  font-size: calc(12px - var(--fs-step)); color: var(--text-2); cursor: pointer; font-family: inherit; white-space: nowrap;
}
.act-menu .act-menu-btn:hover { background: var(--primary-light); color: var(--primary-dark); }
.act-menu .act-menu-btn.act-danger { color: var(--danger); }
.act-menu .act-menu-btn.act-danger:hover { background: var(--danger-light); color: var(--danger); }

/* 页面设置：主题色选择 */
.theme-dot { transition: outline-color .15s, transform .15s; outline: 3px solid transparent; outline-offset: 2px; }
.theme-dot:hover { transform: translateY(-2px); }
.theme-dot.on { outline-color: var(--primary); }
.tbl td.col-ops .fz12.text-gray { font-size: calc(12px - var(--fs-step)); }

/* ---------- ⑥ 底部分页：共 N 条 + 页码 + 每页 10/20/50 ---------- */
.pager {
  display: flex; align-items: center; gap: 8px; margin-top: 14px;
  font-size: calc(13px - var(--fs-step)); color: var(--text-2); flex-wrap: wrap;
}
.pager .pg-total { color: var(--text-2); }   /* 2026-09-13：去掉 margin-right:auto —— 分页栏信息整体靠右 */
.pager .pg-size { display: flex; align-items: center; gap: 6px; color: var(--text-3); font-size: calc(12px - var(--fs-step)); }
.pager select.pg-size-sel {
  height: 30px; border: 1px solid var(--border); border-radius: 6px; padding: 0 6px;
  font-size: calc(13px - var(--fs-step)); color: var(--text-2); background: #fff; font-family: inherit;
  outline: none; cursor: pointer;
}
.pager select.pg-size-sel:focus { border-color: var(--primary); }
.pager .pg-nums { display: flex; align-items: center; gap: 8px; }

/* ---------- ⑥-2 底部固定菜单栏：分页器 + 表格横向滚动条 ----------
   DOM 位置在 .main-wrap 内、.content 之后，靠 flex 排在主区最下方，
   不参与 .content 的滚动，所以任何时候都可见（不是 position:fixed，不会盖住内容）。
   两件东西会上提到这里：
     ① 主列表的分页器（原来贴在卡片最下面，页面一长就要滚到底才看得到）；
     ② 宽表格的横向滚动条（同理，见 app.js buildHScroll）。 */
.bottom-bar {
  flex: none; display: flex; align-items: center; gap: 14px; min-height: 42px;
  padding: 0 18px 0 14px; background: #fff; border-top: 1px solid var(--border);
  box-shadow: 0 -2px 10px rgba(31, 45, 61, .07); z-index: 40;
  position: sticky; bottom: 0;   /* 🔄 v399：布局撑破一屏时也恒贴视口底（兜底） */
}
.bottom-bar[hidden] { display: none; }
/* 底栏左侧常驻「系统设置」入口（2026-09-13 从侧栏挪来）：点击向上弹出菜单 */
.bb-sys { position: relative; flex: none; }
.bb-sys[hidden] { display: none; }
.bb-sys-btn {
  display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 9px;
  border: 1px solid var(--border); border-radius: 6px; background: #fff;
  color: var(--text-2); font-size: calc(12px - var(--fs-step)); font-family: inherit; cursor: pointer;
  transition: all .15s;
}
.bb-sys-btn:hover { border-color: var(--primary); color: var(--primary); }
.bb-sys-menu {
  position: absolute; left: 0; bottom: calc(100% + 6px); min-width: 132px;
  background: #fff; border: 1px solid var(--border); border-radius: 9px;
  box-shadow: 0 8px 26px rgba(31, 45, 61, .16); padding: 5px;
  display: flex; flex-direction: column; gap: 2px;
}
.bb-sys-menu[hidden] { display: none; }
.bb-sys-menu a {
  display: flex; align-items: center; gap: 6px; padding: 7px 10px; border-radius: 6px;
  font-size: calc(12px - var(--fs-step)); color: var(--text-2); text-decoration: none; white-space: nowrap;
}
.bb-sys-menu a[hidden] { display: none; }
.bb-sys-menu a:hover { background: var(--primary-light); color: var(--primary-dark); }
.bb-sys-menu a.active { color: var(--primary-dark); font-weight: 600; }
.bb-slot { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 14px; }
.bb-slot[hidden] { display: none; }
.bottom-bar .bb-pager { flex: 1 1 auto; min-width: 0; }
.bottom-bar .pager { width: 100%; margin: 0; padding: 6px 0; }
/* 分页器被上提到底栏后，表格所在卡片收窄下内边距，让表格贴近分页栏 */
.card.pager-docked { padding-bottom: 10px; }

/* 横向滚动条（自绘，不依赖系统滚动条，任何浏览器/系统都恒定可见） */
.bottom-bar .bb-hscroll {
  flex: 0 1 46%; min-width: 180px; max-width: 560px;
  display: flex; align-items: center; gap: 4px; height: 22px;
}
.bottom-bar .bb-hscroll[hidden] { display: none; }
.bottom-bar .bb-hs-btn {
  width: 18px; height: 18px; flex: none; padding: 0; border: none; background: none;
  color: #949BA6; font-size: calc(14px - var(--fs-step)); line-height: 1; border-radius: 4px;
  font-family: inherit; cursor: pointer;
}
.bottom-bar .bb-hs-btn:hover { background: rgba(0, 0, 0, .06); color: var(--primary); }
.bottom-bar .bb-hs-track {
  flex: 1 1 auto; position: relative; height: 6px; border-radius: 3px;
  background: #EDF0F4; cursor: pointer;
}
.bottom-bar .bb-hs-thumb {
  position: absolute; top: 0; left: 0; height: 6px; border-radius: 3px;
  background: #9AA1AC; transition: background .15s;
}
.bottom-bar .bb-hs-track:hover .bb-hs-thumb,
.bottom-bar .bb-hscroll.dragging .bb-hs-thumb { background: var(--primary); }
.bottom-bar .bb-hscroll.dragging { cursor: grabbing; }

/* ⚠️ 这里只能用 ::-webkit-scrollbar，**不能**同时写 scrollbar-width/scrollbar-color：
   Chrome 一旦看到标准属性就走标准滚动条，会整条忽略下面的 ::-webkit-scrollbar 规则
   （横向就藏不住了，会和底栏自绘条重复）。Firefox 不支持伪元素，会退回原生条，可接受。 */

/* 表体限高后（.tbl-scrolling）出现纵向滚动条：走细条样式 */
.table-wrap.tbl-scrolling::-webkit-scrollbar { width: 9px; height: 8px; background: transparent; }
.table-wrap.tbl-scrolling::-webkit-scrollbar-track { background: transparent; }
.table-wrap.tbl-scrolling::-webkit-scrollbar-thumb { background: #C9D0DA; border-radius: 6px; }
.table-wrap.tbl-scrolling::-webkit-scrollbar-thumb:hover { background: #A7B0BE; }

/* 已上提到底部栏的滚动容器：隐藏它自己那条**横向**滚动条，避免与底栏自绘条重复
   （纵向那条要留着，表体限高后用户得看得见） */
.hs-docked::-webkit-scrollbar { height: 0; }
.table-wrap.tbl-scrolling.hs-docked::-webkit-scrollbar { height: 0; }

/* ---------- ⑦ 渐变：仅用于 logo / 登录页 / 首页重点卡片 ---------- */
.grad-bg { background: var(--grad) !important; color: #fff; }
.kpi.k-hero { background: var(--grad); }
.kpi.k-hero .k-label { color: rgba(255, 255, 255, .88); }
.kpi.k-hero .k-value { color: #fff !important; }
.kpi.k-hero .k-extra { color: rgba(255, 255, 255, .8); }
.kpi.k-hero::after { background: rgba(255, 255, 255, .28) !important; opacity: 1; }
.entry-ico { background: var(--grad) !important; color: #fff !important; }

/* ---------- ⑧ 状态标签：正常/合作=绿、终止/停用=红、待处理=橙 ---------- */
.badge.green { background: var(--primary-light); color: var(--primary-dark); }
.badge.red, .badge.danger { background: var(--danger-light); color: var(--danger); }
.badge.orange { background: var(--accent-light); color: var(--accent); }

/* ---------- 系统设置 · 角色权限页（左角色列表 + 右权限树） ---------- */
.role-wrap { display: flex; gap: 16px; align-items: flex-start; }
.role-list { width: 236px; flex: none; }
.role-item {
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 9px;
  margin-bottom: 8px; cursor: pointer; transition: all .15s;
}
.role-item:hover { border-color: var(--primary); background: var(--primary-light); }
.role-item.on { border-color: var(--primary); background: var(--primary-light); box-shadow: 0 0 0 2px rgba(0, 168, 89, .12); }
.role-item .ri-name { font-size: calc(13px - var(--fs-step)); font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.role-item .ri-meta { font-size: calc(11px - var(--fs-step)); color: var(--text-3); margin-top: 4px; }

.perm-panel { flex: 1; min-width: 0; border-left: 1px solid var(--border); padding-left: 16px; }
.perm-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.perm-toolbar .btn { padding: 5px 12px; font-size: calc(12px - var(--fs-step)); }
.pt-ro {
  display: flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: calc(12px - var(--fs-step)); color: var(--text-2); background: var(--warn-light);
  border-radius: 7px; padding: 7px 10px; margin-bottom: 10px;
}
.pt-ro input { accent-color: var(--primary); }
.perm-tree { max-height: 64vh; overflow: auto; padding: 2px 4px 8px 0; }
.pt-node { border-left: 2px solid #EEF2F6; padding-left: 10px; margin: 6px 0; }
.pt-node .pt-node { border-left-color: #F3F6F9; }
.pt-head { padding: 4px 0; font-size: calc(12px - var(--fs-step)); font-weight: 600; color: var(--text); }
.pt-head label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.pt-head input { accent-color: var(--primary); }
.pt-pages { display: flex; flex-wrap: wrap; gap: 6px; padding: 3px 0 7px 2px; }
.pt-pg {
  display: flex; align-items: center; gap: 5px; cursor: pointer;
  font-size: calc(12px - var(--fs-step)); color: var(--text-2); background: #F7F9FB;
  border: 1px solid transparent; border-radius: 6px; padding: 4px 9px;
}
.pt-pg:hover { background: var(--primary-light); }
.pt-pg.on { background: var(--primary-light); border-color: var(--primary); color: var(--primary-dark); font-weight: 600; }
.pt-pg input { accent-color: var(--primary); }

/* ---------- 经营看板（首页）：时间档位分段控件 + 模块页签 ---------- */
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--card); }
.seg button { border: 0; border-left: 1px solid var(--border); background: transparent; color: var(--text-2); font-size: calc(13px - var(--fs-step)); padding: 6px 16px; cursor: pointer; font-family: inherit; }
.seg button:first-child { border-left: 0; }
.seg button:hover { color: var(--primary); }
.seg button.on { background: var(--primary); color: #fff; font-weight: 600; }
.seg button.on:hover { color: #fff; }
.biz-tabs { display: flex; gap: 24px; border-bottom: 1px solid var(--border); }
.biz-tabs button { border: 0; background: transparent; padding: 9px 0; font-size: calc(14px - var(--fs-step)); color: var(--text-2); cursor: pointer; border-bottom: 2px solid transparent; font-family: inherit; }
.biz-tabs button:hover { color: var(--primary); }
.biz-tabs button.on { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }
.biz-tabs button .fz12 { margin-left: 6px; }
.biz-note { font-size: calc(12px - var(--fs-step)); color: var(--text-3); margin-top: 8px; line-height: 1.8; }

/* ================= 库位二维码 ================= */
.qr-thumb { display: inline-flex; flex-direction: column; align-items: center; gap: 4px; }
.qr-thumb .tag-mono { font-size: calc(12px - var(--fs-step)); }
.qr-thumb svg { display: block; }
#locQrPrev svg { display: block; }

/* ================= 仓库温层（2026-09-15） =================
   表单里「温层」改为多选：一行一个温层，勾中才可填该层的库区数/库位数上限；
   列表里「库区数/库位数上限」一列按温层分行（.tz-cell）。 */
.tz-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 10px; margin-bottom: 6px;
  border: 1px solid var(--border); border-radius: 8px; background: #FAFBFC;
}
.tz-row .tz-chk { min-width: 72px; display: inline-flex; align-items: center; gap: 4px; font-weight: 600; cursor: pointer; }
.tz-row .tz-lbl { color: var(--text-3); font-size: calc(12px - var(--fs-step)); }
/* 🔴 必须带 min-width:0 + flex:none：全局 `input.ipt { min-width:140px }` 会把这两个
   数字框撑到 140px 以上，在 flex 行里还会被拉长成一条宽带，视觉上根本不像输入框。 */
.tz-row input.ipt[type="number"] { width: 92px; min-width: 0; flex: 0 0 auto; padding: 5px 8px; }
.tz-row input[type="number"]:disabled { background: #F0F2F5; color: var(--text-3); }
.tz-cell { white-space: nowrap; line-height: 1.75; font-size: calc(13px - var(--fs-step)); }
.tz-cell b { color: var(--primary-dark); font-weight: 600; }
/* 温层徽章竖排（2026-09-16 用户口径：仓库列表一列里多个温层要上下排，不要横着挤） */
.tz-vert { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }

/* ================= 多选勾选组（2026-09-16） =================
   客户类型等多值字段：勾选式，与仓库温层的勾选（.tz-row/.tz-chk）同一套交互口径。
   值用「、」拼成一个字段存库，与仓库主表 storage_type 兼容列同一种存法。 */
.ms-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 2px 0; }
.ms-chk {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  padding: 5px 12px; border: 1px solid var(--border); border-radius: 16px;
  background: #FAFBFC; font-size: calc(13px - var(--fs-step)); line-height: 1.2;
  user-select: none; transition: all .15s;
}
.ms-chk input { margin: 0; cursor: pointer; }
.ms-chk.on { border-color: var(--primary); background: var(--primary-light); color: var(--primary-dark); font-weight: 600; }

/* ---------- M02：数据化菜单的两种新节点（append-only，不改任何现有规则） ----------
   ① .nav-reserved —— 🚧 预留位（二/三阶段才落地）：灰标、不可点、不进 PAGES，
      点了也没有反应，避免用户以为「功能坏了」。
   ② .nav-badge    —— 一级组标题上的 🚧 角标（配送管理 = 二阶段、结算与财务 = 三阶段）。 */
.nav-reserved {
  display: flex; align-items: center; gap: 8px; padding: 7px 10px 7px 14px;
  font-size: calc(13px - var(--fs-step)); color: #b6bfc6; cursor: not-allowed;
  user-select: none;
}
.nav-subgroup .nav-reserved { padding: 7px 10px 7px 14px; }
.nav-badge { font-size: calc(11px - var(--fs-step)); opacity: .85; }

/* ============================================================================
   v293（2026-10-07）物流码显示 + 打印标签
   物流码是一托一码，一行可能好几个（逗号分隔），用等宽字体便于扫码枪核对；
   .lc-cell 允许折行，不撑破复核详情 12 列表格。
   ============================================================================ */
.lc-cell { font-family: "SF Mono", Consolas, monospace; font-size: calc(11px - var(--fs-step));
  line-height: 1.5; word-break: break-all; }
td.pd-cell { font-family: "SF Mono", Consolas, monospace;
  font-size: calc(12px - var(--fs-step)); white-space: nowrap; }

/* ============================================================================
   v356（2026-10-11 翟总「系统所有页面改为全页」）：
   列表卡片内的表格区域撑满整页 —— 表头贴顶、分页器贴底，中间全是表格区。
   此前 fitListTables 只在「行数超屏」时限高滚动；行少/空态时表格只有半截，
   卡片下方拖一大片空白（盘点管理等空表页尤其明显）。
   实现链路：.content 已是 flex 纵向 + 最后一张卡 flex-grow 撑满（2026-10-04），
   这里再把「最后一张含表格的卡」改成 flex 纵向，让 .table-wrap 吃掉剩余高度。
   :has 守卫保证不含直出表格的卡片（表单/图表卡）不受影响。
   ============================================================================ */
.content > .card:last-child:has(> .table-wrap) { display: flex; flex-direction: column; }
.content > .card:last-child:has(> .table-wrap) > .table-wrap { flex: 1 1 auto; min-height: 0; }
/* 空态提示在撑满的表格区里垂直居中，视觉上不再「顶着一行字下面全空」 */
.content > .card:last-child:has(> .table-wrap) > .table-wrap .empty-tip {
  display: flex; align-items: center; justify-content: center; min-height: 320px; height: 100%;
}

/* ============================================================================
   🆕 v396（2026-10-15 翟总「配送计划参考」）：
   配送计划「详情」弹窗 —— 参考客户 TMS 的「装车主体 + 配送计划」两段式。
   装车主体 12 个只读格走三列网格；明细 14 列沿用 .tbl。
   ============================================================================ */
.plan-grid { display: grid; grid-template-columns: repeat(3, minmax(190px, 1fr)); gap: 6px 18px; }
.plan-grid .plan-ro { min-width: 0; }
.plan-grid .plan-ro > label { display: block; line-height: 1.4; }
.plan-grid .plan-ro > div { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ============================================================================
   🆕 v412（2026-10-17 翟总「司机投单 + 卸货排队 + 装卸扫码」）：
   场站作业看板 —— 排队/叫号/卸货/完成四列，卡片式；上排 6 个时效 KPI。
   ============================================================================ */
.dock-toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.dock-toolbar .ipt { padding: 6px 8px; }
.dock-kpis { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; margin-bottom: 12px; }
.dock-kpi { background: var(--card, #fff); border: 1px solid var(--line, #e8ebe9); border-radius: 10px; padding: 9px 12px; }
.dock-kpi .k { font-size: 12px; color: var(--muted, #6b7280); }
.dock-kpi .v { font-size: 22px; font-weight: 700; line-height: 1.35; }
.dock-cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.dock-col { background: var(--bg2, #f7f9f8); border-radius: 12px; padding: 10px; min-height: 180px; }
.dock-col .ch { font-size: 13px; font-weight: 700; margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center; }
.dock-col .cnt { background: var(--primary, #00A859); color: #fff; border-radius: 10px; padding: 0 8px; font-size: 12px; }
.dock-card { background: var(--card, #fff); border: 1px solid var(--line, #e8ebe9); border-radius: 10px; padding: 10px; margin-bottom: 8px; }
.dock-card.on { border-color: var(--primary, #00A859); box-shadow: inset 0 0 0 1px var(--primary, #00A859); }
.dock-card .row1 { display: flex; justify-content: space-between; align-items: center; }
.dock-card .qno { font-size: 20px; font-weight: 700; color: var(--primary, #00A859); letter-spacing: 1px; }
.dock-card .dock { font-size: 11px; background: #E1F5EE; color: #0F6E56; padding: 2px 6px; border-radius: 6px; }
.dock-card .plate { font-size: 15px; font-weight: 700; margin-top: 2px; }
.dock-card .sub { font-size: 11px; color: var(--muted, #6b7280); margin-top: 2px; word-break: break-all; }
.dock-card .wait { font-size: 12px; margin-top: 6px; }
.dock-card .acts { margin-top: 8px; }
.btn.xs { padding: 4px 10px; font-size: 12px; border-radius: 8px; }
.bars { display: flex; gap: 10px; align-items: flex-end; height: 96px; padding: 8px 4px 0; }
.bar-wrap { flex: 1; text-align: center; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; }
.bar { background: var(--primary, #00A859); border-radius: 4px 4px 0 0; width: 100%; }
.bl { font-size: 10px; color: #888; margin-top: 4px; }
.ch2 { font-size: 13px; font-weight: 700; margin-bottom: 8px; }
@media (max-width: 1100px) {
  .dock-cols { grid-template-columns: repeat(2, 1fr); }
  .dock-kpis { grid-template-columns: repeat(3, 1fr); }
}

/* 🔄 v488（2026-10-20 翟总「整个系统红框内的上下按键都取消」）：
   全站隐藏 number 输入框右侧的原生上下步进按钮（Chrome/Edge spinner），
   数字仍可直接键入或粘贴，只是不再显示小箭头。 */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

/* ============================================================================
   🔄 v618 侧栏窄条（全系统默认整页）—— 2026-10-27 翟总拍板
   ----------------------------------------------------------------------------
   口径：所有页面默认铺满整屏 —— 侧栏收起成 48px 图标窄条，顶栏「☰」一键展开/收起，
        选择记进 localStorage（wms_side_mini），下次打开保持。
   实现约束：
     ① 整节包在 @media (min-width: 901px) 里 —— 移动端（≤900px 抽屉化）零影响：
        手机上 body.side-mini 这个类照样存在，但下面的规则一条都不生效，
        wms_mobile.css 的 `body.mob .sidebar{width:82vw}` 抽屉逻辑原样跑。
     ② 文字是**裸文本节点**（`<a><span class="ico">📦</span>入库管理</a>`），
        display:none 抓不到 —— 用 font-size:0 把文字收成 0 宽，再用 .ico 还原字号，
        这样图标留在原位且居中对齐，无需改 wms_ui.js 的渲染结构。
     ③ 分组标题的文字和图标在**同一个 span** 里（`<span>📦 入库管理</span>`），
        font-size:0 会连图标一起收掉 —— 所以由 app.js 把图标抠出来写进
        data-mini-ico，窄条下用 ::before 顶替；DOM 结构不动，展开态版式不受影响。
   ============================================================================ */
@media (min-width: 901px) {

  /* ---------- 1. 宽度过渡（收起/展开不闪） ---------- */
  .sidebar { transition: width .18s ease; overflow-x: hidden; }
  body.side-mini .sidebar { width: 48px; }

  /* ---------- 2. 首页入口：只留图标 ---------- */
  body.side-mini .nav { padding: 10px 6px; }
  body.side-mini .nav > a.nav-home {
    justify-content: center; gap: 0; padding: 10px 0; font-size: 0;
    margin-bottom: 8px; overflow: hidden;
  }
  body.side-mini .nav > a.nav-home .ico {
    width: auto; font-size: calc(16px - var(--fs-step)); line-height: 1;
  }

  /* ---------- 3. 分组标题：图标顶上（data-mini-ico 由 app.js 写入） ---------- */
  body.side-mini .nav-label {
    justify-content: center; gap: 0; padding: 10px 0 8px;
    font-size: 0; overflow: hidden;
  }
  body.side-mini .nav-label > span { display: none; }
  body.side-mini .nav-label > .nav-arrow { display: none; }
  body.side-mini .nav-label::before {
    content: attr(data-mini-ico);
    display: block; width: 100%; text-align: center;
    font-size: calc(16px - var(--fs-step)); line-height: 1.15;
  }
  /* 无图标兜底（data-mini-ico 为空时用一个小圆点，避免整行空白点不到） */
  body.side-mini .nav-label[data-mini-ico=""]::before { content: "•"; color: var(--text-3); }

  /* ---------- 4. 子项列表整列不显示（窄条只做「大分类导航」） ---------- */
  body.side-mini .nav-group > .collapse-wrap,
  body.side-mini .nav-group > .nav-items,
  body.side-mini .nav-subgroup > .collapse-wrap,
  body.side-mini .nav-subgroup > .nav-items { display: none !important; }

  /* ---------- 5. 窄条下的点击区 / 悬停反馈 ---------- */
  body.side-mini .nav-label,
  body.side-mini .nav > a.nav-home { border-radius: 8px; cursor: pointer; }
  body.side-mini .nav-label:hover { background: var(--primary-light); color: var(--primary-dark); }
  body.side-mini .nav-group { margin-bottom: 4px; }
  body.side-mini .nav-group.active > .nav-label { background: var(--primary-light); }
  body.side-mini .nav-badge { display: none !important; }

  /* ---------- 6. 顶栏「☰」按钮（index.html 里那枚，桌面端才显示） ---------- */
  #sideMiniBtn {
    flex: none; margin-right: 2px; font-size: calc(13px - var(--fs-step));
    line-height: 1; letter-spacing: 0; padding: 0;
  }
}

/* 移动端（≤900px）隐藏这枚按钮：手机上用 wms_mobile.js 注入的 #mobMenuBtn 开抽屉 */
@media (max-width: 900px) {
  #sideMiniBtn { display: none !important; }
}

/* 🔄 v660（2026-10-29 翟总截图「有点宽，宽度减半」）：入库单明细行（新建/编辑共用 wmsAddItem）
   的输入框被全局 input.ipt{min-width:140px} 统一撑到 140px；本规则对 .ii-row 放开
   min-width，让 app.js 里 70px 级的行内宽度生效 —— 只作用明细行，出库行/其它弹窗零影响 */
.ii-row td .ipt { min-width: 0; }

/* 🔄 v661（2026-10-29 翟总「系统数据根据内容宽窄调整字段及格式」）：
   入库单明细录入表原先写死 min-width:1060px，把 70px 的输入框硬拉成等宽大列；
   改 .tbl-fit 后列宽随内容（表头文字/输入框）自然收放，表格整体宽度=内容总宽，
   容器不够时才横向滚动。列表页本就走 table-layout:auto，不受影响。 */
.tbl.tbl-fit { width: auto; min-width: 0; }
.tbl.tbl-fit th, .tbl.tbl-fit td { width: 1px; white-space: nowrap; }

/* 🔄 v677（翟总「系统每页下面增加合计，件数，体积，重量等能合计的合计」）：列表表尾合计行 */
.tbl tr.sum-row td {
  background: #f2f7f3;
  font-weight: 700;
  border-top: 2px solid #d5e3d8;
  color: #1f3d2b;
  white-space: nowrap;
}

/* 🔄 v717（翟总 2026-10-31 14:16 截图红框「去调方框」）：入库单详情弹窗明细行
   可编辑控件去方框 —— 无边框透明底，看上去像普通单元格文本；悬停淡绿底、
   聚焦绿下划线提示可编辑。只作用于 #ibdTbl（app_ledger.js wmsInboundDetail
   明细表），不动全局 .ipt；border-bottom 预留 1px 透明，聚焦时不跳动。 */
#ibdTbl input.ipt, #ibdTbl select.ipt {
  border: none; border-bottom: 1px solid transparent;
  background: transparent; border-radius: 0; box-shadow: none;
}
#ibdTbl input.ipt:hover, #ibdTbl select.ipt:hover { background: #f2f7f3; }
#ibdTbl input.ipt:focus, #ibdTbl select.ipt:focus {
  border-bottom-color: var(--primary); background: #fff; box-shadow: none; outline: none;
}

/* 🔄 v746（翟总 2026-10-31 18:22 截图红框「删除」）：撤销 v726 —— 底部 #ibdHBar 同步条整条删除，
   明细表 #ibdTblWrap 恢复自带横向滚动条（本体横滚，竖向滚动条照旧 max-height:360px 内部滚）。 */
