/* ==========================================================================
   雷哥世界 · 整合管理平台  v2.0  全新响应式设计系统
   --------------------------------------------------------------------------
   设计原则
     1. 移动优先：默认按窄屏排版，逐级向上增强
     2. 零横向溢出：任何断点下 body 均不出现横向滚动条
        手段 —— 全局 border-box / 弹性子项 min-width:0 / 表格窄屏转卡片 /
               文字强制断行 / 媒体元素 max-width:100%
     3. 单一数据源：所有日期时间取自 window.SERVER_TIME（服务器时间）
   ========================================================================== */

/* ---------- 1. 设计令牌 ---------- */
:root {
  /* 品牌色 */
  --c-primary:        #3563E9;
  --c-primary-hover:  #2A52C9;
  --c-primary-soft:   #EDF2FF;
  --c-primary-ring:   rgba(53, 99, 233, .18);
  --c-accent:         #7C5CFF;
  --c-accent-soft:    #F3F0FF;

  /* 语义色 */
  --c-success:        #12B76A;
  --c-success-soft:   #E7F8F0;
  --c-warning:        #F79009;
  --c-warning-soft:   #FEF4E6;
  --c-danger:         #F04438;
  --c-danger-soft:    #FEECEB;
  --c-info:           #06AED4;
  --c-info-soft:      #E6F7FC;

  /* 中性色 */
  --n-0:   #FFFFFF;
  --n-25:  #FCFCFD;
  --n-50:  #F7F9FC;
  --n-100: #EFF3F8;
  --n-200: #E1E7EF;
  --n-300: #C9D2DE;
  --n-400: #98A2B3;
  --n-500: #667085;
  --n-600: #4A5568;
  --n-700: #344054;
  --n-800: #1D2939;
  --n-900: #101828;

  /* 圆角 */
  --r-xs: 6px;
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 20px;
  --r-full: 999px;

  /* 阴影 */
  --sh-xs: 0 1px 2px rgba(16, 24, 40, .05);
  --sh-sm: 0 2px 6px rgba(16, 24, 40, .06);
  --sh-md: 0 6px 18px rgba(16, 24, 40, .08);
  --sh-lg: 0 16px 40px rgba(16, 24, 40, .12);

  /* 尺寸 */
  --h-nav:    60px;
  --w-side:   236px;
  --h-bottom: 60px;
  --gap:      16px;
  --pad-page: 20px;

  --ease: cubic-bezier(.4, 0, .2, 1);
}

/* ---------- 2. 基础重置 ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  max-width: 100%;
}

body {
  font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans SC",
               -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  color: var(--n-800);
  background: var(--n-50);
  overflow-x: hidden;              /* 最后一道保险，配合下方各组件规范化 */
  -webkit-font-smoothing: antialiased;
}

img, svg, video, canvas, iframe { max-width: 100%; height: auto; }

button, input, select, textarea {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

a { color: var(--c-primary); text-decoration: none; }

h1, h2, h3, h4, h5, h6, p, figure { margin: 0; }

ul, ol { margin: 0; padding: 0; list-style: none; }

/* 长文本一律可断行，防止撑破容器 */
.clamp, .tbl td, .card-body, .kv-val, .list-title, .text-block {
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* 滚动条美化 */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--n-300); border-radius: var(--r-full); }
::-webkit-scrollbar-thumb:hover { background: var(--n-400); }

/* ---------- 3. 应用骨架 ---------- */
.app {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* 顶部栏 */
.topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  height: var(--h-nav);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  background: var(--n-0);
  border-bottom: 1px solid var(--n-200);
  flex: 0 0 auto;
}
.topbar-brand {
  display: flex; align-items: center; gap: 10px;
  min-width: 0; flex: 1 1 auto;
}
.brand-logo {
  width: 34px; height: 34px; flex: 0 0 auto;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--c-primary), var(--c-accent));
  color: #fff; font-weight: 700; font-size: 15px;
  display: flex; align-items: center; justify-content: center;
}
.brand-text { min-width: 0; }
.brand-title {
  font-size: 15px; font-weight: 700; color: var(--n-900);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand-sub {
  font-size: 11px; color: var(--n-400);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar-actions { display: flex; align-items: center; gap: 6px; flex: 0 1 auto; min-width: 0; }

.icon-btn {
  width: 38px; height: 38px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--n-200); background: var(--n-0);
  border-radius: var(--r-sm); cursor: pointer;
  color: var(--n-600); transition: all .16s var(--ease);
}
.icon-btn:hover { background: var(--n-50); color: var(--n-900); border-color: var(--n-300); }
.icon-btn:active { transform: scale(.96); }

/* 主体区 */
.app-body {
  flex: 1 1 auto;
  display: flex;
  min-width: 0;
  width: 100%;
}

/* 侧边导航（桌面） */
.sidebar {
  display: none;
  width: var(--w-side);
  flex: 0 0 var(--w-side);
  background: var(--n-0);
  border-right: 1px solid var(--n-200);
  padding: 12px 10px;
  overflow-y: auto;
  position: sticky;
  top: var(--h-nav);
  height: calc(100vh - var(--h-nav));
  height: calc(100dvh - var(--h-nav));
}
.nav-group-label {
  font-size: 11px; font-weight: 600; color: var(--n-400);
  letter-spacing: .06em; text-transform: uppercase;
  padding: 14px 12px 6px;
}
.nav-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 10px 12px; margin-bottom: 2px;
  border: none; background: none; cursor: pointer;
  border-radius: var(--r-sm);
  color: var(--n-600); font-size: 14px; font-weight: 500;
  text-align: left; transition: all .16s var(--ease);
}
.nav-item:hover { background: var(--n-50); color: var(--n-900); }
.nav-item.active { background: var(--c-primary-soft); color: var(--c-primary); font-weight: 600; }
.nav-ico { width: 22px; flex: 0 0 22px; display: flex; justify-content: center; font-size: 17px; }
.nav-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-count {
  flex: 0 0 auto; font-size: 11px; font-weight: 700;
  padding: 1px 7px; border-radius: var(--r-full);
  background: var(--c-danger); color: #fff;
}

/* 主内容 */
.main {
  flex: 1 1 auto;
  min-width: 0;                    /* 关键：允许收缩，避免撑破 */
  width: 100%;
  padding: var(--pad-page);
  padding-bottom: calc(var(--pad-page) + var(--h-bottom) + env(safe-area-inset-bottom, 0px));
}

/* 底部导航（移动） */
.bottom-nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 70;
  height: calc(var(--h-bottom) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  display: grid;
  /* 按钮数量随权限变化（无权限的入口不再渲染），
     所以用「列数自适应」而不是写死 5 列，避免出现空位导致图标不居中 */
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--n-200);
}
.btab {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; border: none; background: none; cursor: pointer;
  color: var(--n-400); font-size: 10px; font-weight: 500;
  padding: 0; min-width: 0;
}
.btab-ico { font-size: 20px; line-height: 1; transition: transform .16s var(--ease); }
.btab-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.btab.active { color: var(--c-primary); }
.btab.active .btab-ico { transform: translateY(-2px) scale(1.08); }

/* 抽屉（移动菜单） */
.drawer-mask {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(16, 24, 40, .45);
  opacity: 0; visibility: hidden; transition: all .22s var(--ease);
}
.drawer-mask.open { opacity: 1; visibility: visible; }
.drawer {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 91;
  width: min(84vw, 300px);
  background: var(--n-0);
  padding: 14px 10px;
  overflow-y: auto;
  transform: translateX(-102%);
  transition: transform .26s var(--ease);
  display: flex; flex-direction: column;
}
.drawer.open { transform: translateX(0); }
.drawer .nav-item { font-size: 15px; padding: 11px 12px; }

/* ---------- 4. 页面头 ---------- */
.page-head {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: 12px; margin-bottom: var(--gap);
}
.page-head-main { flex: 1 1 220px; min-width: 0; }
.page-title { font-size: 20px; font-weight: 700; color: var(--n-900); }
.page-desc { font-size: 13px; color: var(--n-500); margin-top: 2px; }
.page-head-actions { display: flex; flex-wrap: wrap; gap: 8px; flex: 0 1 auto; }

/* ---------- 4.5 作用域选择（门店 / 直播间，位于右上角） ---------- */
.scope-bar {
  display: flex; align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 0 1 auto;
}
.scope-bar[hidden] { display: none; }
.scope-group { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 0 1 auto; }
.scope-group[hidden] { display: none; }
.scope-label {
  flex: 0 0 auto;
  font-size: 11.5px; font-weight: 700; color: var(--n-500);
  letter-spacing: .04em; white-space: nowrap;
}
/* 右上角下拉：紧凑、按内容自适应，最长 132px 截断 */
.scope-select {
  flex: 0 1 auto;
  min-width: 0; max-width: 132px;
  height: 32px;
  padding: 0 26px 0 10px;
  border: 1px solid var(--n-200);
  border-radius: var(--r-sm);
  background-color: var(--n-50);
  color: var(--n-800);
  font-size: 12.5px; font-weight: 600; font-family: inherit;
  cursor: pointer;
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23667085' d='M6 8.5L1.5 4h9z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.scope-select:hover { border-color: var(--c-primary); color: var(--c-primary); }
.scope-select:focus {
  outline: none; border-color: var(--c-primary);
  box-shadow: 0 0 0 3px var(--c-primary-ring);
}

/* 窄屏紧凑入口：显示「门店 · 直播间」，点开为选择面板 */
.scope-compact {
  display: none;                    /* 由媒体查询在窄屏切换为 inline-flex */
  align-items: center; gap: 5px;
  height: 32px; max-width: 168px; min-width: 0;
  padding: 0 10px;
  border: 1px solid var(--n-200);
  border-radius: var(--r-sm);
  background: var(--n-50);
  color: var(--n-800);
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer;
}
.scope-compact[hidden] { display: none !important; }
.scope-compact .sc-ico { flex: 0 0 auto; font-size: 13px; line-height: 1; }
.scope-compact .sc-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scope-compact .sc-caret { flex: 0 0 auto; font-size: 10px; color: var(--n-400); }

/* 选择面板（窄屏弹出）用到的chip两组 */
.sheet-group { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.sheet-group + .sheet-group { margin-top: 18px; }
.sheet-group[hidden] { display: none; }
.chip-group { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.chip {
  max-width: 100%;
  padding: 6px 14px;
  border: 1px solid var(--n-200);
  border-radius: var(--r-full);
  background: var(--n-50);
  color: var(--n-600);
  font-size: 13px; font-weight: 600; font-family: inherit;
  line-height: 1.4;
  cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: all .16s var(--ease);
}
.chip:hover { border-color: var(--c-primary); color: var(--c-primary); }
.chip.active {
  background: var(--c-primary); border-color: var(--c-primary); color: #fff;
  box-shadow: 0 2px 6px var(--c-primary-ring);
}

/* ---------- 5. 卡片 ---------- */
.card {
  background: var(--n-0);
  border: 1px solid var(--n-200);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-xs);
  min-width: 0;
  overflow: hidden;
}
.card + .card { margin-top: var(--gap); }
.card-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--n-100);
}
.card-title { font-size: 15px; font-weight: 700; color: var(--n-900); flex: 1 1 auto; min-width: 0; }
.card-count {
  display: inline-block; margin-left: 4px;
  padding: 1px 8px; border-radius: var(--r-full);
  background: var(--n-100); color: var(--n-600);
  font-size: 11.5px; font-weight: 700; vertical-align: 1px;
}
.card-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.card-body { padding: 16px; }
.card-body.tight { padding: 10px; }
.card-body.flush { padding: 0; }

/* ---------- 6. 栅格 ---------- */
.grid { display: grid; gap: var(--gap); min-width: 0; }
.grid-kpi { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
.grid-kpi.max-760 { max-width: 760px; }
.grid-2   { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid-3   { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.grid-auto{ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

.stack { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.row   { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; min-width: 0; }
.row-between { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between; min-width: 0; }
.spacer { flex: 1 1 auto; min-width: 0; }

/* ---------- 7. KPI 卡片（横排：图标 + 大数字，对齐 PC 设计稿 .kpi） ---------- */
.kpi {
  display: flex; align-items: center; gap: 13px;
  background: var(--n-0);
  border: 1px solid var(--n-200);
  border-radius: var(--r-lg);
  padding: 14px 16px;
  min-width: 0;
  box-shadow: var(--sh-xs);
  transition: box-shadow .2s var(--ease), transform .2s var(--ease);
}
.kpi:hover { box-shadow: var(--sh-sm); transform: translateY(-1px); }
.kpi-ico {
  width: 46px; height: 46px; flex: 0 0 46px; border-radius: 13px;
  display: flex; align-items: center; justify-content: center; font-size: 21px;
}
.kpi-body { min-width: 0; flex: 1 1 auto; }
.kpi-value {
  font-size: 23px; font-weight: 800; color: var(--n-900); line-height: 1.15;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}
.kpi-unit { font-size: 12px; font-weight: 600; color: var(--n-500); margin-left: 3px; }
.kpi-label {
  font-size: 12px; color: var(--n-500); font-weight: 500; margin-top: 3px;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kpi-foot { font-size: 11px; color: var(--n-400); margin-top: 2px; }

/* ---------- 8. 按钮 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 15px;
  border-radius: var(--r-sm);
  border: 1px solid var(--n-200);
  background: var(--n-0);
  color: var(--n-700);
  font-size: 13.5px; font-weight: 600;
  cursor: pointer; white-space: nowrap;
  transition: all .16s var(--ease);
  max-width: 100%;
}
.btn:hover:not(:disabled) { background: var(--n-50); border-color: var(--n-300); }
.btn:active:not(:disabled) { transform: scale(.98); }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.btn-primary {
  background: var(--c-primary); border-color: var(--c-primary); color: #fff;
  box-shadow: 0 1px 3px var(--c-primary-ring);
}
.btn-primary:hover:not(:disabled) { background: var(--c-primary-hover); border-color: var(--c-primary-hover); }
.btn-success { background: var(--c-success); border-color: var(--c-success); color: #fff; }
.btn-success:hover:not(:disabled) { filter: brightness(.94); }
.btn-danger  { background: var(--c-danger);  border-color: var(--c-danger);  color: #fff; }
.btn-danger:hover:not(:disabled)  { filter: brightness(.94); }
.btn-ghost   { background: transparent; border-color: transparent; color: var(--n-600); }
.btn-ghost:hover:not(:disabled) { background: var(--n-100); }
.btn-sm { padding: 6px 11px; font-size: 12.5px; border-radius: var(--r-xs); }
.btn-block { width: 100%; }

/* ---------- 9. 表单 ---------- */
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field-label { font-size: 12.5px; font-weight: 600; color: var(--n-700); }
.field-label .req { color: var(--c-danger); margin-left: 2px; }
.field-hint { font-size: 11.5px; color: var(--n-400); }

.input, .select, .textarea {
  width: 100%; min-width: 0;
  padding: 9px 12px;
  border: 1px solid var(--n-300);
  border-radius: var(--r-sm);
  background: var(--n-0);
  color: var(--n-900);
  font-size: 14px;
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
  appearance: none;
}
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--c-primary);
  box-shadow: 0 0 0 3px var(--c-primary-ring);
}
.input::placeholder, .textarea::placeholder { color: var(--n-400); }
.textarea { min-height: 78px; resize: vertical; }
.select {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23667085' d='M6 8.5L1.5 4h9z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 32px;
}

/* ---------- 7.1 移动端输入控件：字号必须 ≥ 16px ----------
   低于 16px 时，iOS Safari 与部分安卓内核（含微信/QQ 内置浏览器）会在
   **输入框获得焦点时自动放大整个页面**，且失焦后**不会恢复** ——
   表现就是「点一下搜索框，页面整体右移并放大，输入完也回不来，内容显示不全」。
   这是移动端最高频的投诉点之一，根因就是字号，不是布局。
   16px 是这些内核对「无需放大」的唯一判定阈值。                        */
@media (max-width: 900px), (hover: none) and (pointer: coarse) {
  .input, .select, .textarea,
  input, select, textarea { font-size: 16px; }
  /* 去掉移动端 300ms 双击缩放延迟，避免误触发缩放 */
  a, button, .btn, .chip, .nav-item, .btab, .tab, .seg-btn,
  input, select, textarea, label { touch-action: manipulation; }
}

.form-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.form-grid .span-all { grid-column: 1 / -1; }

/* 工具栏 */
.toolbar {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end;
  padding: 12px 16px;
  border-bottom: 1px solid var(--n-100);
  background: var(--n-25);
}
.toolbar .field { flex: 1 1 150px; min-width: 0; }
.toolbar .field.narrow { flex: 0 1 130px; }

/* ---------- 10. 表格 → 窄容器卡片 ----------
   关键设计：表格形态由「内容区真实可用宽度」决定，而不是整个视口宽度。
   桌面端侧栏占位、弹窗内嵌等场景下内容区会明显变窄，若只看视口宽度，
   表格右列会被 overflow-x:hidden 静默裁切（即“出屏”）。
   这里用容器查询按容器宽度自适应，任何容器都不会出现横向溢出。 */
.tbl-wrap { width: 100%; min-width: 0; max-width: 100%; }

/* 查询容器：表格在这些元素内部时，按它们的可用宽度判定形态 */
#pageRoot,
.card-body,
.modal-body,
.list-item,
.sub-panel {
  container-type: inline-size;
}

.tbl {
  width: 100%;
  max-width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  table-layout: auto;
}
.tbl th {
  text-align: left;
  font-size: 12px; font-weight: 600; color: var(--n-500);
  padding: 10px 11px;
  background: var(--n-25);
  border-bottom: 1px solid var(--n-200);
  white-space: normal;              /* 允许表头折行，降低最小宽度 */
}
.tbl td {
  padding: 11px 11px;
  border-bottom: 1px solid var(--n-100);
  color: var(--n-700);
  vertical-align: middle;
  overflow-wrap: anywhere;          /* 长文本换行而非撑宽表格 */
  min-width: 0;
}
.tbl tbody tr:hover { background: var(--n-25); }
.tbl tbody tr:last-child td { border-bottom: none; }
.tbl .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tbl .act { text-align: right; white-space: nowrap; }
.tbl .act .btn { margin-left: 4px; }

/* ---------- 10.1 单行 / 折行单元格工具 ---------- */
/* 单行不换行，超出用省略号（悬停看 title 全文） */
.cut {
  display: block; min-width: 0; max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 允许折行，最多 2 行（不用 -webkit-line-clamp：它会让 scrollWidth 大于 clientWidth，
   在逐元素审计里会被判为「内容被裁切」；用 max-height 精确等于 2 倍行高更干净） */
.wrap2 {
  display: block; min-width: 0; max-width: 100%;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
  line-height: 1.55;
  max-height: 3.1em;      /* = 2 行 × 1.55 */
  overflow: hidden;
}
/* 状态徽标横排（不换行、不竖排） */
.cell-badges { display: flex; align-items: center; gap: 4px; flex-wrap: nowrap; min-width: 0; }

/* ---------- 10.2 工单表：固定列宽，关键列永远单行 ----------
   工单表列数多（10 列），若用自动列宽，内容会把表格撑到 1200px+，
   容器不够宽时就触发「转卡片」，于是所有字段竖排 —— 这正是用户反馈的问题。
   改为 table-layout: fixed + 百分比列宽后，表格宽度恒等于容器宽度，
   永不溢出，列宽也不会被内容挤变形；宽度不够时由 .cut 省略号兜底。      */
.tbl.wo { table-layout: fixed; font-size: 13px; }
.tbl.wo th, .tbl.wo td { padding: 9px 8px; min-width: 0; }
.tbl.wo th { white-space: nowrap; }        /* 表头不竖排（创建人/操作人） */
.tbl.wo td { overflow: hidden; }
.tbl.wo .wo-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; }
.tbl.wo .act .btn { margin: 0 2px; }

/* 列数多，容器 ≥880px 就维持表格形态（其它表格仍走 1080px 转卡片阈值）
   880px ≈ 1280px 视口下的内容区宽度，保证常见 PC 分辨率不会突然变成卡片堆叠。 */
@supports (container-type: inline-size) {
  @container (min-width: 880px) {
    .tbl.wo thead { display: table-header-group; }
    .tbl.wo { display: table; width: 100%; }
    .tbl.wo tbody { display: table-row-group; }
    .tbl.wo tr {
      display: table-row;
      border: none; border-radius: 0; margin: 0; padding: 0;
      box-shadow: none; background: none;
    }
    .tbl.wo tbody tr:hover { background: var(--n-25); }
    .tbl.wo td {
      display: table-cell; width: auto;
      text-align: left; vertical-align: middle;
      border-bottom: 1px solid var(--n-100);
      padding: 9px 8px;
    }
    .tbl.wo td::before { content: none; }
    .tbl.wo td.num { text-align: right; }
    .tbl.wo td.act { text-align: center; }
    /* 表头与内容同向对齐：数字右对齐、操作居中（此前表头 .act 被全局规则改成右对齐，
       和居中的按钮组错开将近 46px，是「表头与内容对不上」的主因） */
    .tbl.wo th.num { text-align: right; }
    .tbl.wo th.act { text-align: center; }
    /* 表头/单元格左缘与卡片标题对齐：
       卡片标题内边距 16px，单元格内边距只有 8px，两者差 8px。
       用 text-indent 补齐（不影响固定表格布局，不会造成横向溢出）。 */
    .tbl.wo th:first-child,
    .tbl.wo td:first-child { text-indent: 8px; }
    /* 这些列必须单行 */
    .tbl.wo td.num, .tbl.wo td.act { white-space: nowrap; }
  }
}

/* 表格转卡片后的完整样式（移动端与窄容器共用同一套规则） */
@supports (container-type: inline-size) {
  @container (max-width: 1080px) {
    .tbl thead { display: none; }
    .tbl, .tbl tbody, .tbl tr, .tbl td { display: block; width: 100%; }
    .tbl tr {
      border: 1px solid var(--n-200);
      border-radius: var(--r-md);
      margin: 0 0 10px;
      padding: 6px 12px;
      background: var(--n-0);
      box-shadow: var(--sh-xs);
    }
    .tbl tbody tr:hover { background: var(--n-0); }
    .tbl td {
      display: flex; align-items: flex-start; justify-content: space-between;
      gap: 14px;
      padding: 7px 0;
      border-bottom: 1px dashed var(--n-100);
      text-align: right;
    }
    .tbl td:last-child { border-bottom: none; }
    .tbl td::before {
      content: attr(data-label);
      flex: 0 0 auto; max-width: 46%;
      font-size: 12.5px; font-weight: 600; color: var(--n-500);
      text-align: left;
      padding-right: 8px;
    }
    .tbl td > * { min-width: 0; }
    .tbl .num, .tbl .act { text-align: right; white-space: normal; }
    .tbl .act { justify-content: flex-end; flex-wrap: wrap; }
    .tbl .act::before { margin-right: auto; }
  }
}

/* 兼容不支持容器查询的旧内核：手机窄屏同样整表转卡片 */
@media (max-width: 860px) {
  .tbl thead { display: none; }
  .tbl, .tbl tbody, .tbl tr, .tbl td { display: block; width: 100%; }
  .tbl tr {
    border: 1px solid var(--n-200);
    border-radius: var(--r-md);
    margin: 0 0 10px;
    padding: 6px 12px;
    background: var(--n-0);
    box-shadow: var(--sh-xs);
  }
  .tbl tbody tr:hover { background: var(--n-0); }
  .tbl td {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 14px;
    padding: 7px 0;
    border-bottom: 1px dashed var(--n-100);
    text-align: right;
  }
  .tbl td:last-child { border-bottom: none; }
  .tbl td::before {
    content: attr(data-label);
    flex: 0 0 auto; max-width: 46%;
    font-size: 12.5px; font-weight: 600; color: var(--n-500);
    text-align: left;
    padding-right: 8px;
  }
  .tbl td > * { min-width: 0; }
  .tbl .num, .tbl .act { text-align: right; white-space: normal; }
  .tbl .act { justify-content: flex-end; flex-wrap: wrap; }
  .tbl .act::before { margin-right: auto; }
}

/* ---------- 11. 列表项 / 键值 ---------- */
.list { display: flex; flex-direction: column; gap: 10px; }
.list-item {
  border: 1px solid var(--n-200);
  border-radius: var(--r-md);
  padding: 12px 14px;
  background: var(--n-0);
  min-width: 0;
}
.list-head { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; min-width: 0; }
.list-title { font-size: 14px; font-weight: 600; color: var(--n-900); flex: 1 1 auto; min-width: 0; }
.list-meta { font-size: 12px; color: var(--n-500); margin-top: 4px; }

.kv { display: grid; grid-template-columns: minmax(84px, auto) 1fr; gap: 6px 12px; min-width: 0; }
.kv-k { font-size: 12.5px; color: var(--n-500); }
.kv-val { font-size: 13.5px; color: var(--n-800); min-width: 0; }
@media (max-width: 480px) {
  .kv { grid-template-columns: 1fr; gap: 2px 0; }
  .kv-k { margin-top: 6px; }
}

/* ---------- 12. 徽标 / 状态 ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 9px;
  border-radius: var(--r-full);
  font-size: 11.5px; font-weight: 600;
  white-space: nowrap; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis;
}
.badge-gray   { background: var(--n-100);        color: var(--n-600); }
.badge-blue   { background: var(--c-primary-soft); color: var(--c-primary); }
.badge-purple { background: var(--c-accent-soft);  color: var(--c-accent); }
.badge-green  { background: var(--c-success-soft); color: #04794A; }
.badge-yellow { background: var(--c-warning-soft); color: #B54708; }
.badge-red    { background: var(--c-danger-soft);  color: #B42318; }
.badge-cyan   { background: var(--c-info-soft);    color: #0E7490; }

/* ---------- 13. 标签页 ---------- */
.tabs {
  display: flex; gap: 4px; flex-wrap: nowrap;
  overflow-x: auto; overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  border-bottom: 1px solid var(--n-200);
  padding: 0 8px;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  flex: 0 0 auto;
  padding: 11px 14px;
  border: none; background: none; cursor: pointer;
  font-size: 13.5px; font-weight: 600; color: var(--n-500);
  border-bottom: 2px solid transparent;
  white-space: nowrap; transition: all .16s var(--ease);
}
.tab:hover { color: var(--n-800); }
.tab.active { color: var(--c-primary); border-bottom-color: var(--c-primary); }

/* ---------- 14. 弹窗 ---------- */
.modal-mask {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(16, 24, 40, .5);
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  opacity: 0; visibility: hidden; transition: all .2s var(--ease);
}
.modal-mask.open { opacity: 1; visibility: visible; }
.modal {
  width: 100%; max-width: 620px;
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);
  background: var(--n-0);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-lg);
  display: flex; flex-direction: column;
  min-width: 0;
  transform: translateY(12px) scale(.98);
  transition: transform .2s var(--ease);
}
.modal-mask.open .modal { transform: none; }
.modal-head {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px; border-bottom: 1px solid var(--n-100);
  flex: 0 0 auto;
}
.modal-title { font-size: 16px; font-weight: 700; color: var(--n-900); flex: 1 1 auto; min-width: 0; }
.modal-body { padding: 18px; overflow-y: auto; flex: 1 1 auto; min-width: 0; }
.modal-foot {
  display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end;
  padding: 14px 18px; border-top: 1px solid var(--n-100);
  flex: 0 0 auto;
}
.modal-foot .btn { flex: 0 1 auto; }

/* 窄屏：弹窗变底部抽屉，天然不溢出 */
@media (max-width: 640px) {
  .modal-mask { padding: 0; align-items: flex-end; }
  .modal {
    max-width: 100%;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    max-height: 92vh;
    max-height: 92dvh;
    transform: translateY(100%);
  }
  .modal-mask.open .modal { transform: none; }
  .modal-foot { padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
  .modal-foot .btn { flex: 1 1 auto; }
}

/* ---------- 15. 提示 ---------- */
.toasts {
  position: fixed;
  top: calc(var(--h-nav) + 10px); left: 50%; transform: translateX(-50%);
  z-index: 300;
  display: flex; flex-direction: column; gap: 8px;
  width: min(92vw, 420px);
  pointer-events: none;
}
.toast-item {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 11px 14px;
  border-radius: var(--r-md);
  background: var(--n-0);
  border: 1px solid var(--n-200);
  box-shadow: var(--sh-md);
  font-size: 13.5px; font-weight: 500;
  animation: toastIn .22s var(--ease);
  min-width: 0;
}
.toast-item.ok   { border-left: 3px solid var(--c-success); }
.toast-item.err  { border-left: 3px solid var(--c-danger); }
.toast-item.warn { border-left: 3px solid var(--c-warning); }
.toast-item.info { border-left: 3px solid var(--c-primary); }
.toast-item > span { min-width: 0; overflow-wrap: anywhere; }
@keyframes toastIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }

/* ---------- 16. 空状态 / 加载 ---------- */
.empty {
  padding: 46px 20px; text-align: center; color: var(--n-400);
}
.empty-ico { font-size: 38px; margin-bottom: 10px; opacity: .6; }
.empty-txt { font-size: 13.5px; }

.skeleton {
  background: linear-gradient(90deg, var(--n-100) 25%, var(--n-50) 37%, var(--n-100) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.3s ease-in-out infinite;
  border-radius: var(--r-sm);
}
@keyframes shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.spinner {
  width: 18px; height: 18px; flex: 0 0 auto;
  border: 2px solid var(--n-200); border-top-color: var(--c-primary);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- 17. 商品图 ---------- */
.photo-grid { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
.photo-item {
  position: relative; aspect-ratio: 1 / 1;
  border: 1px solid var(--n-200); border-radius: var(--r-md);
  overflow: hidden; background: var(--n-50);
}
.photo-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-del {
  position: absolute; top: 4px; right: 4px;
  width: 22px; height: 22px; border-radius: 50%;
  border: none; background: rgba(16, 24, 40, .6); color: #fff;
  font-size: 12px; cursor: pointer; display: flex; align-items: center; justify-content: center;
}

/* ---------- 18. 分段控件 ---------- */
.seg {
  display: inline-flex; padding: 3px; gap: 2px;
  background: var(--n-100); border-radius: var(--r-sm);
  max-width: 100%; overflow-x: auto; scrollbar-width: none;
}
.seg::-webkit-scrollbar { display: none; }
.seg-btn {
  flex: 0 0 auto; padding: 6px 13px; border: none; background: none; cursor: pointer;
  border-radius: var(--r-xs); font-size: 12.5px; font-weight: 600; color: var(--n-500);
  white-space: nowrap; transition: all .16s var(--ease);
}
.seg-btn.active { background: var(--n-0); color: var(--c-primary); box-shadow: var(--sh-xs); }

/* ---------- 19. 响应式断点 ---------- */
@media (min-width: 1024px) {
  .sidebar { display: block; }
  .bottom-nav { display: none; }
  .main {
    padding: 24px 28px;
    max-width: 1600px;
  }
  .topbar { padding: 0 24px; }
  .topbar .menu-btn { display: none; }
  .page-title { font-size: 22px; }
}

/* 右上角作用域选择：≥ 901px 用内联下拉，以下收成紧凑入口 */
@media (max-width: 900px) {
  .scope-bar { display: none !important; }
  .scope-compact:not([hidden]) { display: inline-flex; }
}
@media (min-width: 901px) {
  .scope-compact { display: none !important; }
}
/* 极窄屏再让出空间：服务器时钟（概览页标题处也有服务器日期）、
   退出登录（抽屉里同样有）依次收起，保证右上角选择器不被挤掉 */
@media (max-width: 600px) {
  #srvClock { display: none; }
}
@media (max-width: 430px) {
  #logoutBtn { display: none; }
  .topbar { gap: 8px; padding: 0 10px; }
  .brand-logo { width: 30px; height: 30px; font-size: 13px; }
  .brand-title { font-size: 14px; }
  .scope-compact { max-width: 132px; }
}

@media (min-width: 768px) and (max-width: 1023px) {
  .sidebar { display: none; }
  .main { padding: 20px; padding-bottom: calc(20px + var(--h-bottom) + 8px); }
}

@media (max-width: 767px) {
  :root { --pad-page: 14px; --gap: 12px; }
  .page-title { font-size: 18px; }
  .card-head, .card-body { padding: 13px; }
  .toolbar { padding: 11px 13px; }
  .kpi-value { font-size: 20px; }
  .tabs { padding: 0 4px; }
}

@media (max-width: 380px) {
  :root { --pad-page: 11px; --gap: 10px; }
  .brand-sub { display: none; }
  .kpi-value { font-size: 18px; }
}

/* ---------- 20. 业务扩展组件（v2.0 新增） ---------- */

/* 文本工具类 */
.dim        { color: var(--n-400); font-size: 12.5px; }
.mono       { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12.5px; }
.miss       { color: var(--c-danger); }
.ok-text    { color: var(--c-success); }
.danger-text{ color: var(--c-danger); }
.sec-title  { font-size: 13.5px; font-weight: 700; color: var(--n-900); margin: 0 0 10px; }
.link-btn   { background: none; border: none; padding: 0; font: inherit; color: var(--c-primary);
              cursor: pointer; text-decoration: underline dotted; }
.pre-box    { background: var(--n-50); border: 1px solid var(--n-200); border-radius: var(--r-sm);
              padding: 10px 12px; font-size: 12.5px; white-space: pre-wrap; overflow-wrap: anywhere;
              margin: 0 0 14px; max-height: 220px; overflow-y: auto; }

/* 快捷入口卡片 */
.quick-card, .op-card {
  display: flex; align-items: center; gap: 12px; text-align: left;
  padding: 14px; border: 1px solid var(--n-200); background: var(--n-0);
  border-radius: var(--r-md); cursor: pointer; min-width: 0;
  transition: all .16s var(--ease); box-shadow: var(--sh-xs);
}
.quick-card:hover, .op-card:hover { border-color: var(--c-primary); box-shadow: var(--sh-sm); transform: translateY(-1px); }
.quick-ico, .op-ico {
  width: 38px; height: 38px; flex: 0 0 38px; border-radius: var(--r-sm);
  display: flex; align-items: center; justify-content: center; font-size: 19px;
}
.quick-text, .op-name { min-width: 0; }
.quick-text { display: flex; flex-direction: column; gap: 1px; }
.quick-name, .op-name { font-size: 14px; font-weight: 700; color: var(--n-900); }
.quick-desc, .op-desc { font-size: 11.5px; color: var(--n-400); }
.op-card { flex-direction: column; align-items: flex-start; }
.op-card .op-ico { margin-bottom: 8px; }
.op-card.danger:hover { border-color: var(--c-danger); }

/* VIP 标识 */
.vip-tag {
  display: inline-block; margin-right: 6px; vertical-align: middle;
  background: linear-gradient(135deg, #ef4444, #dc2626); color: #fff;
  font-size: 10.5px; font-weight: 700; letter-spacing: .5px;
  padding: 1px 6px; border-radius: 4px;
}

/* 复选框行 / 药丸 */
.chk-line { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13.5px; font-weight: 500; color: var(--n-700); }
.chk-line input[type=checkbox] { width: 17px; height: 17px; flex: 0 0 auto; accent-color: var(--c-primary); }
.chk-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; background: var(--n-50); border: 1px solid var(--n-200);
  border-radius: var(--r-full); cursor: pointer; font-size: 13px; max-width: 100%;
}
.chk-pill input { width: 15px; height: 15px; accent-color: var(--c-primary); flex: 0 0 auto; }
.chk-pill span { overflow-wrap: anywhere; }

/* 自动补全下拉 */
.combo-drop {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 30;
  margin-top: 4px; max-height: 250px; overflow-y: auto;
  background: var(--n-0); border: 1px solid var(--n-200);
  border-radius: var(--r-sm); box-shadow: var(--sh-md);
  display: none;
}
.combo-drop.open { display: block; }
.combo-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 12px; font-size: 13px; cursor: pointer; min-width: 0;
  border-bottom: 1px solid var(--n-100);
}
.combo-item:last-child { border-bottom: none; }
.combo-item:hover { background: var(--c-primary-soft); }
.combo-item > * { min-width: 0; overflow-wrap: anywhere; }
.combo-empty { padding: 10px 12px; font-size: 12.5px; color: var(--n-400); }

/* 货柜位置选择（v3 紧凑型）：柜名一行小芯片；A~F 选中后才展开一行「位置/方位」双下拉 */
.loc-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.loc-chip {
  padding: 6px 13px; border: 1px solid var(--n-300); border-radius: var(--r-full);
  background: var(--n-0); color: var(--n-700); font-size: 13px; font-weight: 500;
  cursor: pointer; transition: all .12s var(--ease); min-width: 0;
}
.loc-chip:hover { border-color: var(--c-primary); color: var(--c-primary); }
.loc-chip.on {
  background: var(--c-primary); border-color: var(--c-primary);
  color: #fff; font-weight: 600;
}
.loc-sub { margin-top: 8px; display: flex; gap: 8px; }
.loc-sub.hidden { display: none; }
.loc-sub .select { flex: 1 1 0; min-width: 0; }

/* 异地发货清单：逐店指定「接收确认人」 */
.xb-confirmer {
  display: flex; align-items: flex-start; gap: 10px;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px dashed var(--n-200);
}
.xb-conf-k {
  flex: 0 0 auto; font-size: 12px; font-weight: 600; color: var(--n-500);
  line-height: 34px;
}

/* 提示条 */
.alert { padding: 12px 14px; border-radius: var(--r-md); font-size: 13px; line-height: 1.7; margin-bottom: 12px; }
.alert-title { font-weight: 700; margin-bottom: 4px; }
.alert-warn   { background: var(--c-warning-soft); border: 1px solid #FCD9A6; color: #B54708; }
.alert-danger { background: var(--c-danger-soft);  border: 1px solid #FBC7C3; color: #B42318; }
.notice { padding: 10px 12px; background: var(--n-50); border: 1px solid var(--n-200);
          border-radius: var(--r-sm); font-size: 12.5px; color: var(--n-500); line-height: 1.7; }

/* 子面板 */
.sub-panel { padding: 12px; background: var(--n-50); border: 1px solid var(--n-200); border-radius: var(--r-md); }
.sub-panel + .sub-panel { margin-top: 12px; }

/* 同步状态条 */
.sync-bar { display: flex; flex-wrap: wrap; gap: 10px 22px; padding: 14px 16px; background: var(--n-25); }
.sync-item { display: flex; align-items: center; gap: 8px; font-size: 13px; min-width: 0; flex-wrap: wrap; }
.sync-item .dim { font-size: 12px; }

/* 开关 */
.switch { position: relative; display: inline-block; width: 42px; height: 24px; flex: 0 0 42px; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch-slider {
  position: absolute; inset: 0; cursor: pointer;
  background: var(--n-300); border-radius: var(--r-full); transition: background .2s var(--ease);
}
.switch-slider::before {
  content: ''; position: absolute; left: 3px; top: 3px;
  width: 18px; height: 18px; background: #fff; border-radius: 50%;
  box-shadow: var(--sh-xs); transition: transform .2s var(--ease);
}
.switch input:checked + .switch-slider { background: var(--c-success); }
.switch input:checked + .switch-slider::before { transform: translateX(18px); }

/* 关联 / 跟进行 */
.rel-row, .follow-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  padding: 10px 12px; background: var(--n-50);
  border: 1px solid var(--n-200); border-radius: var(--r-sm); margin-bottom: 8px;
}
.rel-name { flex: 1 1 auto; min-width: 0; font-weight: 600; overflow-wrap: anywhere; }
.rel-phone { font-size: 12px; color: var(--n-400); }
.rel-cand {
  display: block; width: 100%; text-align: left; margin-bottom: 6px;
  padding: 9px 12px; background: var(--n-50); border: 1px solid var(--n-200);
  border-radius: var(--r-sm); cursor: pointer; font-size: 13px; color: var(--n-800);
}
.rel-cand:hover { background: var(--c-primary-soft); border-color: var(--c-primary); }
.follow-row { display: block; }
.follow-text { font-size: 13.5px; color: var(--n-800); overflow-wrap: anywhere; }
.follow-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
               font-size: 11.5px; color: var(--n-400); margin-top: 6px; }
.follow-meta .btn { margin-left: auto; }

/* 时间线（工单历史） */
.timeline { display: flex; flex-direction: column; gap: 12px; }
.tl-item { position: relative; padding: 12px 14px; background: var(--n-50);
           border: 1px solid var(--n-200); border-radius: var(--r-md); min-width: 0; }
.tl-head { display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
           justify-content: space-between; font-size: 12.5px; color: var(--n-600); margin-bottom: 6px; }
.tl-body { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; font-size: 12.5px; }
.tl-result { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--n-200);
             font-size: 13px; color: var(--n-700); white-space: pre-wrap; overflow-wrap: anywhere; }

/* 门店区块 / 直播间卡片 */
.store-block { border: 1px solid var(--n-200); border-radius: var(--r-md); overflow: hidden; margin-bottom: 14px; }
.store-block-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 14px; background: var(--n-50); font-weight: 700; font-size: 14px; color: var(--n-900);
}
.plat-card { padding: 12px; background: var(--n-25); border: 1px solid var(--n-100); border-radius: var(--r-sm); min-width: 0; }

/* 权限矩阵 */
.perm-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; }
.perm-row { display: flex; align-items: center; justify-content: space-between; gap: 10px;
            padding: 8px 12px; background: var(--n-50); border: 1px solid var(--n-200);
            border-radius: var(--r-sm); font-size: 13px; min-width: 0; }
.perm-row > span { min-width: 0; overflow-wrap: anywhere; }
.perm-row .select { max-width: 130px; padding: 5px 26px 5px 10px; font-size: 12.5px; }

/* 窄表单列 */
.form-narrow { max-width: 400px; display: flex; flex-direction: column; gap: 14px; }

@media (max-width: 640px) {
  .form-narrow { max-width: 100%; }
  .perm-row { flex-direction: column; align-items: stretch; }
  .perm-row .select { max-width: 100%; }
  .store-block-head { font-size: 13.5px; }
  .quick-ico, .op-ico { width: 34px; height: 34px; flex: 0 0 34px; font-size: 17px; }
}

/* ---------- 22. 入库货柜位置 / 确认收货 ---------- */
.cab-wrap { display: flex; flex-direction: column; gap: 16px; }
.cab-ask { font-size: 18px; font-weight: 700; color: var(--n-900); line-height: 1.5; text-align: center; }
.cab-prod { font-size: 14px; color: var(--n-600); text-align: center; margin-top: -10px; word-break: break-word; }

.cab-sentence {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px;
  padding: 18px 14px;
  background: var(--c-primary-soft);
  border: 1px solid var(--n-200); border-radius: var(--r-lg);
  font-size: 17px; font-weight: 600; color: var(--n-800);
}
.cab-word { white-space: nowrap; }
/* 选了「冰箱」：冰箱是独立整柜，没有层也没有方位 —— 直接把「的 / 层 / 方位」收起来。
   ⚠️ 用一条 CSS 管住，别去重建 DOM：独立「货柜位置」弹窗和
   「确认物流并收货」向导第 4 步共用这套标记，改一处两边同时生效。 */
.cab-sentence.fridge .cab-word,
.cab-sentence.fridge .cab-sel-floor,
.cab-sentence.fridge .cab-sel-side { display: none; }
.cab-sel {
  font-size: 16px; font-weight: 700; color: var(--n-900);
  padding: 10px 12px; min-height: 46px; max-width: 100%;
  background: var(--n-0); border: 2px solid var(--c-primary);
  border-radius: var(--r-md); cursor: pointer;
}
.cab-sel:focus { outline: none; box-shadow: 0 0 0 3px var(--c-primary-ring); }

.cab-preview { text-align: center; font-size: 15px; color: var(--n-600); }
.cab-preview strong { color: var(--c-primary); font-size: 17px; }

.cab-hints {
  display: flex; flex-direction: column; gap: 6px;
  padding: 14px 16px;
  background: var(--n-50); border: 1px solid var(--n-200);
  border-radius: var(--r-md);
  font-size: 13px; line-height: 1.7; color: var(--n-600);
}

.pkg-list { display: flex; flex-direction: column; gap: 8px; }
/* 物流信息单：运单号点开可折叠看「最新一条」物流状态。
   ⚠️ 卡片底色/边框从 .pkg-row 挪到 .pkg-item —— 展开面板才会像是
      「长在这张卡片里」；.pkg-row 退回成透明的一行。
      注意别再给 .pkg-item 加 cursor:pointer：现在整行不是 label 了，
      点中间是「展开」，点左边才是「勾选」，光标得说实话。 */
.pkg-item {
  background: var(--n-50); border: 1px solid var(--n-200);
  border-radius: var(--r-md); overflow: hidden;
}
.pkg-item:hover { border-color: var(--n-300); }
.pkg-row { display: flex; align-items: center; gap: 10px; padding: 12px 14px; }
.pkg-pick {
  flex: 0 0 auto; display: flex; align-items: center;
  padding: 3px 1px 3px 0; cursor: pointer;
}
.pkg-ck { width: 18px; height: 18px; accent-color: var(--c-primary); cursor: pointer; }
/* 展开按钮：把 button 的默认外观全部抹掉，只当一块可点的文字区 */
.pkg-main {
  flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px;
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; text-align: left; color: inherit; cursor: pointer;
}
.pkg-main strong { font-size: 14px; color: var(--n-900); overflow-wrap: anywhere; }
.pkg-sub { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12.5px; }
.pkg-more {
  display: inline-flex; align-items: center; gap: 3px;
  color: var(--c-primary); font-weight: 600; white-space: nowrap;
}
.pkg-chev { font-style: normal; font-size: 10px; line-height: 1; transition: transform .18s var(--ease); }
.pkg-toggle[aria-expanded="true"] .pkg-chev { transform: rotate(180deg); }
.pkg-num { flex: 0 0 auto; font-size: 13px; color: var(--n-600); white-space: nowrap; }

/* 展开面板。
   ⚠️ 三态只用「一枚 6px 小圆点 + 文案」区分，**不给整块铺底色** ——
      整块色块会被当成「通知条」，之前货柜位置那块就是这么翻车的。
      is-miss 也不把文字染成 --c-warning（#F79009 白底上对比度只有 2.5:1，
      看不清），改用加粗 + 橙色圆点，靠「！」和措辞表达严重性。 */
.pkg-trace { border-top: 1px dashed var(--n-200); background: var(--n-0); padding: 10px 14px 12px; }
.tr-line {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 13.5px; font-weight: 600; color: var(--n-800); line-height: 1.5;
}
.tr-line strong { font-weight: 700; color: var(--n-900); }
/* ⚠️ 必须给 min-width:0 —— 它是 .tr-line 的 flex 子项，默认 min-width:auto
   会拒绝收缩，遇到长英文/单号类的连续串会顶破面板宽度。 */
.tr-msg { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.pkg-trace.is-miss .tr-line { font-weight: 700; }
.tr-dot {
  flex: 0 0 auto; width: 7px; height: 7px; margin-top: 6px;
  border-radius: var(--r-full); background: var(--n-400);
}
.pkg-trace.is-ok  .tr-dot { background: var(--c-success); }
.pkg-trace.is-run .tr-dot { background: var(--c-info); }
.pkg-trace.is-miss .tr-dot { background: var(--c-warning); }
.tr-node {
  margin-top: 5px; padding-left: 15px;
  font-size: 12.5px; line-height: 1.65; color: var(--n-600); overflow-wrap: anywhere;
}
.tr-meta { margin-left: 6px; color: var(--n-400); white-space: nowrap; }

.cmp { display: flex; flex-direction: column; border: 1px solid var(--n-200); border-radius: var(--r-md); overflow: hidden; }
.cmp-row { display: flex; gap: 12px; padding: 11px 14px; background: var(--n-0); border-bottom: 1px solid var(--n-100); }
.cmp-row:last-child { border-bottom: none; }
.cmp-key { background: var(--c-primary-soft); }
.cmp-k { flex: 0 0 72px; font-size: 13px; color: var(--n-500); }
.cmp-v { flex: 1 1 auto; min-width: 0; font-size: 14.5px; font-weight: 600; color: var(--n-900); overflow-wrap: anywhere; }

/* 商品图（平台 CDN 外链，只存 URL、不落本地文件） */
.pd-thumb { display: flex; justify-content: center; margin-bottom: 14px; }
.pd-thumb img {
  max-width: 180px; max-height: 180px; width: auto; height: auto;
  border-radius: var(--r-md); border: 1px solid var(--n-200);
  background: var(--n-0); object-fit: contain;
}

/* 「确认物流并收货」三步向导 + 商品详情页唯一主按钮 */
.btn-lg { min-height: 48px; padding: 12px 20px; font-size: 16px; font-weight: 600; }
.pd-cta { min-height: 52px; font-size: 17px; font-weight: 700; letter-spacing: .5px; margin-top: 4px; }

.rc-step {
  display: flex; flex-direction: column; gap: 10px;
  padding: 14px 16px;
  background: var(--n-0); border: 1px solid var(--n-200);
  border-radius: var(--r-lg);
}
.rc-step-h { display: flex; align-items: center; gap: 8px; font-size: 14.5px; font-weight: 600; color: var(--n-800); }
.rc-step-n {
  flex: 0 0 22px; width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--c-primary); color: #fff; font-size: 13px; font-weight: 700;
}
.rc-gate { text-align: center; font-weight: 600; color: var(--n-500); }
.rc-gate.ok { color: var(--c-success); }
.field-hint.ok { color: var(--c-success); }

.cmp-tip { margin-top: 12px; line-height: 1.8; }
.cmp-tip.danger {
  color: var(--c-danger); font-size: 14.5px; font-weight: 600;
  padding: 12px 14px;
  background: var(--c-danger-soft); border: 1px solid var(--c-danger);
  border-radius: var(--r-md);
}
.cmp-tip.ok {
  color: var(--c-success); font-weight: 600;
  padding: 12px 14px;
  background: var(--c-success-soft); border: 1px solid var(--c-success);
  border-radius: var(--r-md);
}

/* ============================ 异地发货 ============================
   ⚠️ 配色只用设计令牌，别写死色值：整站会跟着 :root 一起变。
   ⚠️ 提示条（.xs-hint）**不铺满底色**，只留左边一条细竖线 + 浅底：
      铺满的色块会被当成"告警横幅"，而这里多数时候只是说明文字。
   ------------------------------------------------------------------ */
.xs-hint {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  margin: 0 16px 12px; padding: 10px 14px;
  font-size: 13px; line-height: 1.7; color: var(--n-700);
  background: var(--n-50); border-left: 3px solid var(--c-primary);
  border-radius: var(--r-sm);
}
.xs-hint b { color: var(--n-900); }
.xs-hint .btn { margin-left: auto; }
.xs-hint-warn { border-left-color: var(--c-warning); background: var(--c-warning-soft); }
.xs-hint-warn b { color: var(--n-900); display: block; margin-bottom: 2px; }
.xs-hint-warn span { display: block; font-size: 12.5px; color: var(--n-700); }

/* 注意：这里刻意**不**用 --c-warning 上色 —— #F79009 在浅底上对比度不足，
   小字会看不清。改用中性深色 + 依据措辞表达严重性。 */
.xs-warn-txt { color: var(--n-800); font-weight: 700; }

.xs-sub { font-size: 12px; line-height: 1.55; color: var(--n-500); font-weight: 400; overflow-wrap: anywhere; }
.xs-sub.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .2px; }
/* ⚠️ 必须带 .xs-sub 前缀提高优先级：`.ok-text` 单独写会被上面的 `.xs-sub`
   盖掉（两者优先级相同，靠源码顺序决定，而 .xs-sub 在后面）——
   结果就是"刚保存了什么"那行永远是灰的，跟普通说明文字分不开。 */
.xs-sub.ok-text { color: var(--c-success); font-weight: 600; }
.xs-rule { color: var(--c-primary); font-weight: 600; }

/* 表格列宽：客户名/商品名是长文本，给它们让位；其余列收紧 */
.xs-tbl td, .xs-tbl th { vertical-align: top; }
/* ⚠️ 第二列才是「客户名称」（第一列是本次选择复选框），
   原来写 :first-child 会把复选框那格撑到 110px，整列被拉宽还挤掉商品名。 */
.xs-tbl td:nth-child(2) { min-width: 110px; }

/* 发放状态勾选框。
   ⚠️ 勾中后只改文字颜色和加粗，**不给整行铺绿底** —— 一片绿会盖掉
     同一行里"应发到哪个店"这种更要紧的信息。 */
.xs-ck-wrap {
  display: inline-flex; align-items: flex-start; gap: 7px;
  padding: 4px 6px; border-radius: var(--r-sm);
  cursor: pointer; text-align: left; font-size: 13px; color: var(--n-600);
  line-height: 1.4;
}
.xs-ck-wrap:hover { background: var(--n-50); }
.xs-ck-wrap .xs-ck { width: 18px; height: 18px; flex: 0 0 auto; margin-top: 1px;
                     accent-color: var(--c-success); cursor: pointer; }
.xs-ck-wrap.on { color: var(--c-success); font-weight: 700; }
.xs-ck-wrap.on .xs-sub { color: var(--n-500); font-weight: 400; }
.xs-ck-txt { display: block; }
.xs-ck-wrap .xs-ck:disabled { cursor: not-allowed; }

/* 刚勾上「已发放」的那一行：留在原位但整行降低对比度，
   让人一眼看出"这行已经处理过了"，同时还能点回来撤销。
   ⚠️ 只降透明度，不铺色块 —— 铺色会盖掉同行的「应发到哪个店」。 */
.xs-tbl tr.xs-done td { opacity: .55; }
.xs-tbl tr.xs-done td:last-child { opacity: 1; }

/* 客户取货点：未设置的下拉用虚线边 + 灰字，一眼能扫出"还没填" */
.xs-pick {
  width: 100%; min-width: 104px; font-size: 13px; padding: 6px 8px;
  border-radius: var(--r-sm);
}
.xs-pick.unset { border-style: dashed; color: var(--n-500); }

.xs-cust-tip {
  margin: 0 0 12px; padding: 10px 14px; font-size: 13px; line-height: 1.7;
  background: var(--c-primary-soft); border-radius: var(--r-sm); color: var(--n-700);
}
.xs-cust-tip b { color: var(--n-900); }
.xs-cust-tip > span { margin-left: 12px; }

/* 历史记录的日期快捷筛选 */
.xs-chips { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.xs-chip {
  border: 1px solid var(--n-200); background: var(--n-0); color: var(--n-600);
  border-radius: var(--r-full); padding: 3px 11px; font-size: 12.5px; cursor: pointer;
  transition: all .15s var(--ease);
}
.xs-chip:hover { border-color: var(--c-primary); color: var(--c-primary); }
.xs-chip.on { background: var(--c-primary); border-color: var(--c-primary); color: #fff; font-weight: 600; }

.xs-pager {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 12px 16px; font-size: 13px; color: var(--n-600);
  border-top: 1px solid var(--n-100);
}

/* ==========================================================================
   异地发货：本次选择条 + 批量清单
   ========================================================================== */

/* 已选操作条。未选时低调、选了之后整条变蓝底，让人不会漏掉"还有没发的" */
.xs-selbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  margin: 0 16px 12px; padding: 10px 14px; font-size: 13px;
  color: var(--n-600); background: var(--n-50);
  border: 1px solid var(--n-200); border-radius: var(--r-sm);
  transition: all .18s var(--ease);
}
.xs-selbar.on { background: var(--c-primary-soft); border-color: var(--c-primary); }
.xss-n b { color: var(--c-primary); font-size: 15px; }
.xss-t { font-size: 12.5px; color: var(--n-500); }
.xs-selbar .btn-primary { margin-left: auto; }

/* 行首复选框：只做选择，不写库 */
.xs-sel-ck, .xs-sel-all { width: 18px; height: 18px; accent-color: var(--c-primary); cursor: pointer; }
.xs-sel-ck:disabled, .xs-sel-all:disabled { cursor: not-allowed; }
/* 已勾选的行给一点底色，方便在长列表里回看"我选了哪几条" */
.xs-tbl tr.xs-picked > td { background: var(--c-primary-soft); }

/* ---------- 按客户归拢（2026-09-28）：一位客户一行 + 可展开的明细行 ---------- */
.xs-grp .xs-cust-ck { width: 18px; height: 18px; accent-color: var(--c-primary); cursor: pointer; }
.xs-grp .xs-cust-ck:disabled { cursor: not-allowed; }
.xs-grp tr.xs-cust > td { border-top: 1px solid var(--n-200); }
.xs-grp tr.xs-cust:first-child > td { border-top: 0; }
.xs-grp .xs-exp { padding: 3px 10px; font-size: 12.5px; white-space: nowrap; }
/* 明细行收起：display:none 的优先级必须压过窄屏的「.tbl tr{display:block}」，
   所以用两个类（.xs-det.off）而不是 HTML 的 hidden 属性 */
.xs-grp tr.xs-det.off { display: none; }
.xs-grp tr.xs-det > td { padding: 0; background: var(--n-50); border-top: 0; }
.xs-det-in { padding: 9px 14px 11px 30px; text-align: left; }
.xs-det-hd { font-size: 12.5px; color: var(--n-500); margin-bottom: 6px; }
.xs-det-hd b { color: var(--c-primary); font-size: 13px; }
.xs-det-warn { margin-left: 8px; color: var(--c-warning); font-weight: 600; }
.xs-cust-warn { color: var(--c-warning); font-weight: 600; }
.xs-ditem {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 5px 8px; border-radius: var(--r-sm); cursor: pointer;
  font-size: 13px;
}
.xs-ditem:hover { background: var(--n-100); }
.xs-ditem.on { background: var(--c-primary-soft); }
.xs-ditem .xs-sel-ck { margin-top: 1px; }
.xdi-name { flex: 1 1 auto; min-width: 0; color: var(--n-800); overflow-wrap: anywhere; }
.xdi-qty { flex: 0 0 auto; color: var(--n-500); font-size: 12.5px;
           font-variant-numeric: tabular-nums; }
.xdi-qty b { color: var(--c-primary); font-size: 13px; }

/* 发货清单弹窗 */
.xb-tip {
  margin: 0 0 12px; padding: 11px 14px; font-size: 13px; line-height: 1.75;
  background: var(--c-primary-soft); border-radius: var(--r-sm); color: var(--n-700);
}
.xb-tip b { color: var(--n-900); }
.xb-sub { margin-top: 4px; font-size: 12.5px; color: var(--n-500); }
.xb-group {
  border: 1px solid var(--n-200); border-radius: var(--r-sm);
  margin-bottom: 10px; overflow: hidden;
}
.xb-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  padding: 9px 13px; background: var(--n-50);
  border-bottom: 1px solid var(--n-100); font-size: 13px;
}
.xb-route { font-weight: 700; color: var(--n-900); }
.xb-arrow { color: var(--c-primary); margin: 0 5px; font-weight: 700; }
.xb-sum { margin-left: auto; font-size: 12.5px; color: var(--n-500); }
/* 客户整块滚动（原来是「按商品」一长条）；接收确认人芯片留在下方不跟着滚 */
.xb-custs { max-height: 40vh; overflow: auto; }
.xb-cust + .xb-cust { border-top: 1px solid var(--n-100); }
.xb-cust-hd {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px;
  padding: 8px 13px 5px; background: var(--n-0);
}
.xb-cust-n { font-weight: 700; color: var(--n-900); font-size: 13px; }
.xb-cust-m { font-weight: 400; color: var(--n-500); font-size: 12px; margin-left: 6px; }
.xb-cust-s { margin-left: auto; font-size: 12.5px; color: var(--n-500);
             font-variant-numeric: tabular-nums; }
.xb-cust-s b { color: var(--c-primary); }
/* 缩进让「商品属于上面那位客户」一眼可见，不然两层分组看不出来 */
.xb-cust .xb-item { padding-left: 28px; }
.xb-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 7px 13px; font-size: 13px; border-bottom: 1px solid var(--n-100);
}
.xb-item:last-child { border-bottom: 0; }
.xb-name { flex: 1 1 auto; min-width: 0; color: var(--n-800); overflow-wrap: anywhere; }
.xb-qty { flex: 0 0 auto; font-weight: 700; color: var(--c-primary);
          font-variant-numeric: tabular-nums; }
/* 件数才是发货口径，份数只是对照 —— 份数一行要弱化，别跟件数抢注意力 */
.xb-qty b { color: var(--c-primary); }
.xb-rule { display: inline-block; margin-left: 6px; padding: 1px 6px;
           border-radius: 999px; background: var(--n-100); color: var(--n-600);
           font-size: 11.5px; font-weight: 600; }

/* ==========================================================================
   站内消息
   ========================================================================== */

/* 顶栏铃铛 + 未确认角标 */
.msg-btn { position: relative; }
.msg-ico { font-size: 15px; line-height: 1; }
.msg-badge {
  position: absolute; top: -5px; right: -5px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--c-danger); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 1;
  border-radius: var(--r-full); border: 2px solid var(--n-0);
}
/* ⚠️ 必须显式写这条：上面给 .msg-badge 设了 display:inline-flex，
   作者样式会**盖掉浏览器默认的 [hidden]{display:none}** ——
   结果就是没有未确认消息时，铃铛上永远挂着一个红色的「0」。
   （JS 里 el.hidden=true 是对的，属性也生效了，只是视觉上被 CSS 顶回来了。） */
.msg-badge[hidden] { display: none; }

.msg-tip {
  margin: 0 0 12px; padding: 10px 14px; font-size: 13px; line-height: 1.7;
  background: var(--c-warning-soft); border-left: 3px solid var(--c-warning);
  border-radius: var(--r-sm); color: var(--n-700);
}
.msg-list { display: block; }
.msg-card {
  border: 1px solid var(--n-200); border-radius: var(--r-sm);
  padding: 12px 14px; margin-bottom: 10px; background: var(--n-0);
}
.msg-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.msg-title { font-size: 14px; font-weight: 700; color: var(--n-900); }
.msg-meta {
  display: flex; flex-wrap: wrap; gap: 4px 14px;
  margin-top: 6px; font-size: 12.5px; color: var(--n-500);
}
.msg-items {
  margin-top: 9px; border-top: 1px dashed var(--n-200); padding-top: 8px;
}
.msg-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 4px 0; font-size: 13px;
}
.mi-name { flex: 1 1 auto; min-width: 0; color: var(--n-800); overflow-wrap: anywhere; }
.mi-qty { flex: 0 0 auto; font-weight: 700; color: var(--c-primary);
          font-variant-numeric: tabular-nums; }
.msg-total {
  margin-top: 5px; padding-top: 6px; border-top: 1px dashed var(--n-200);
  font-size: 12.5px; color: var(--n-600); font-weight: 600;
}
.msg-act {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--n-100);
}
.msg-later-tip { font-size: 12.5px; color: var(--c-warning); font-weight: 600; }
.msg-foot { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--n-100); }
.msg-foot-label { display: block; margin-bottom: 6px; font-size: 12.5px; color: var(--n-500); }
.msg-recip { display: flex; flex-wrap: wrap; gap: 6px; }
.mr-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: var(--r-full);
  font-size: 12.5px; background: var(--n-50);
  border: 1px solid var(--n-200); color: var(--n-600);
}
.mr-chip.ok { background: var(--c-success-soft); border-color: var(--c-success); color: var(--c-success); font-weight: 600; }
.mr-chip.later { background: var(--c-warning-soft); border-color: var(--c-warning); color: var(--n-700); }
.mr-chip.wait { color: var(--n-500); }
.mr-time { font-size: 11.5px; opacity: .8; font-variant-numeric: tabular-nums; }
.xs-pager span { margin: 0 4px; }

@media (max-width: 640px) {
  .cab-ask { font-size: 16.5px; text-align: left; }
  .cab-prod { text-align: left; }
  .cab-sentence { gap: 6px; padding: 14px 10px; font-size: 15px; }
  .cab-sel { font-size: 15px; padding: 9px 10px; min-height: 44px; }
  .cmp-k { flex: 0 0 60px; }
  /* 物流信息单：窄屏把留白收一点，让 15 位运单号 + 公司 + 发货量还能一行放下 */
  .pkg-row { padding: 11px 12px; gap: 8px; }
  .pkg-num { font-size: 12.5px; }
  .pkg-trace { padding: 9px 12px 11px; }
  .tr-line { font-size: 13px; }
  .tr-node { font-size: 12px; }
  .pd-thumb img { max-width: 140px; max-height: 140px; }
  .rc-step { padding: 12px; }
  .rc-step-h { font-size: 14px; }
  .pd-cta { font-size: 16px; }
  /* 异地发货：窄屏把提示条和勾选框收紧，保证「客户/店铺/商品/数量」四列在抽屉里也读得顺 */
  .xs-hint { margin: 0 12px 10px; padding: 9px 12px; font-size: 12.5px; }
  .xs-hint .btn { margin-left: 0; }
  .xs-ck-wrap { padding: 2px 4px; font-size: 12.5px; }
  .xs-pick { min-width: 88px; font-size: 12.5px; padding: 5px 6px; }
  .xs-pager { padding: 10px 12px; }
  .xs-cust-tip { font-size: 12.5px; padding: 9px 12px; }
  .xs-cust-tip > span { display: block; margin-left: 0; }
  /* 已选条：窄屏下按钮独占一行、整条要够挤得下不溢出 */
  .xs-selbar { margin: 0 12px 10px; padding: 9px 12px; gap: 7px 9px; font-size: 12.5px; }
  .xs-selbar .btn { padding: 5px 10px; font-size: 12.5px; }
  .xs-selbar .btn-primary { margin-left: 0; flex: 1 1 100%; }
  .xss-n b { font-size: 14px; }
  /* 发货清单 */
  .xb-tip { font-size: 12.5px; padding: 9px 12px; }
  .xb-custs { max-height: 46vh; }
  .xb-head { padding: 8px 11px; gap: 4px 8px; }
  .xb-sum { margin-left: 0; flex: 1 1 100%; }
  .xb-item { padding: 6px 11px; font-size: 12.5px; }
  .xb-cust .xb-item { padding-left: 18px; }
  .xb-cust-s { margin-left: 0; flex: 1 1 100%; }
  /* 客户归拢明细：窄屏少缩进，横向空间要留给商品名 */
  .xs-det-in { padding: 8px 11px 10px 13px; }
  .xs-ditem { padding: 5px 6px; }
  .xdi-qty { font-size: 12px; }
  /* 消息卡片 */
  .msg-card { padding: 11px 12px; }
  .msg-title { font-size: 13.5px; }
  .msg-meta { font-size: 12px; gap: 3px 10px; }
  .msg-act .btn { padding: 5px 10px; font-size: 12.5px; }
  /* 手机上点确认是高频动作 → 主按钮占满整行，别让人瞄不准 */
  .msg-act .btn-primary { flex: 1 1 100%; }
  .mr-chip { font-size: 12px; padding: 3px 8px; }
  .msg-badge { min-width: 15px; height: 15px; font-size: 10px; top: -4px; right: -4px; }
}

/* 「服务器数据同步」卡片（系统设置 → 管理员） */
.sync-form { max-width: 700px; display: flex; flex-direction: column; gap: 14px; }
.sync-form .row { gap: 10px; flex-wrap: wrap; align-items: center; }
.sync-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 2px; }
.sync-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 4px 18px; }
.sync-grid > div {
  display: flex; justify-content: space-between; gap: 10px;
  padding: 7px 0; font-size: 13px;
  border-bottom: 1px dashed var(--n-200);
}
.sync-grid .k { color: var(--n-500); }
.sync-grid .v { font-weight: 600; color: var(--n-900); font-variant-numeric: tabular-nums; }
.sync-ok { color: var(--c-success); font-weight: 600; }
.sync-bad { color: var(--c-danger); font-weight: 600; }
/* 降级完成（连不上服务器、改用了本机旧副本）—— 必须写在 .sync-ok 之后，
   同优先级下后者胜出，才能把绿勾颜色压成警告色 */
.sync-ok.sync-degraded { color: var(--c-warning); }
/* 降级警告：连不上服务器、改用本机旧副本 —— 必须比「成功」更醒目 */
.sync-warn {
  padding: 10px 13px; font-size: 13px; line-height: 1.6; color: var(--c-warning);
  background: var(--n-25); border: 1px solid var(--n-200); border-left: 3px solid var(--c-warning);
  border-radius: var(--r-md); overflow-wrap: anywhere;
}
/* 同步进行中的实时进度行：一次同步要 1~3 分钟，必须让用户看得见「在动」 */
.sync-live {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 13px; font-size: 13px; line-height: 1.6; color: var(--n-700);
  background: var(--n-25); border: 1px solid var(--n-200); border-left: 3px solid var(--c-primary);
  border-radius: var(--r-md); overflow-wrap: anywhere;
}
.sync-live::before {
  content: ''; flex: 0 0 13px; width: 13px; height: 13px;
  border: 2px solid var(--n-300); border-top-color: var(--c-primary);
  border-radius: 50%; animation: synSpin .8s linear infinite;
}
@keyframes synSpin { to { transform: rotate(360deg); } }
.sync-log {
  max-height: 190px; overflow: auto; margin-top: 8px;
  padding: 10px 12px; background: var(--n-50); border: 1px solid var(--n-200);
  border-radius: var(--r-md);
  font-size: 12.5px; line-height: 1.75; color: var(--n-600);
  white-space: pre-wrap; overflow-wrap: anywhere;
}

/* ---------- 21. 商品详情页（重排版） ----------
   版面：商品图+状态 ｜ 关键信息 ｜ 客户订单明细
        → 货柜位置（整行居中放大）
        → SKU规格 ｜ 取货规则（并排暖色卡）
        → 待核销用户 → 主操作 → 物流单照片
   配色沿用 :root 令牌：主色=品牌蓝，暖色卡用 --c-warning-soft（与「待处理」提示同色系），
   未填写等缺失值统一走 .miss（--c-danger）。 */
.pd { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

/* 提前收货（待补物流）醒目横幅：暖黄底 + 琥珀左边线，配色口径与 .alert-warn 一致
   （#B54708 深琥珀，不用 --c-warning —— 浅底对比度不足，见 1307 行注释） */
.pd-adv-banner {
  padding: 10px 14px;
  border-radius: var(--r-md, 10px);
  background: var(--c-warning-soft);
  border: 1px solid #FCD9A6;
  border-left-width: 4px;
  color: #B54708;
  font-size: 13px;
  line-height: 1.55;
}
.pd-adv-banner strong { font-weight: 700; }

/* 库存页顶部「可补物流」提醒条（每日集中检查发现平台已录入物流） */
.adv-alert {
  margin: 10px 16px 0;
  padding: 9px 14px;
  border-radius: var(--r-md, 10px);
  background: var(--c-warning-soft);
  border: 1px solid #FCD9A6;
  border-left-width: 4px;
  color: #B54708;
  font-size: 13px;
  line-height: 1.55;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.adv-alert strong { font-weight: 700; }
.adv-alert-names { font-weight: 500; }
.adv-alert .btn { margin-left: auto; flex: none; }

/* 顶部三栏 */
.pd-head {
  display: grid;
  grid-template-columns: 112px minmax(0, 1fr) 188px;
  gap: 16px;
  align-items: start;
  min-width: 0;
}
.pd-media { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.pd-thumb { display: block; margin: 0; }
.pd-thumb img {
  display: block;
  width: 112px; height: 112px;
  max-width: none; max-height: none;
  object-fit: contain;
  border-radius: var(--r-md);
  border: 1px solid var(--n-200);
  background: var(--n-0);
}
.pd-thumb-empty {
  width: 112px; height: 112px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-md);
  border: 1px dashed var(--n-300);
  background: var(--n-50);
  color: var(--n-400);
  font-size: 11.5px; line-height: 1.5; text-align: center;
}
.pd-status {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 6px 8px;
}
.pd-status-k { font-size: 12.5px; color: var(--n-500); white-space: nowrap; }

/* 关键信息：键列左侧一条细「行标尺」，数值成列对齐 */
.pd-kv {
  display: grid;
  grid-template-columns: 68px minmax(0, 1fr);
  gap: 9px 0;
  align-content: start;
  min-width: 0;
}
.pd-kv-k {
  padding-left: 9px;
  border-left: 2px solid var(--n-200);
  font-size: 13px; color: var(--n-500); line-height: 1.45;
}
.pd-kv-v {
  font-size: 13.5px; color: var(--n-800); line-height: 1.45;
  font-variant-numeric: tabular-nums;
  min-width: 0; overflow-wrap: anywhere;
}
.pd-kv-v.strong { font-weight: 700; color: var(--n-900); }

/* 客户订单明细（置顶右栏，不加面板底，保持轻） */
.pd-orders { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.pd-orders-h { font-size: 13.5px; font-weight: 700; color: var(--n-900); }
.pd-orders-peek { font-size: 12.5px; line-height: 1.75; color: var(--n-600); }
.pd-orders-peek strong { color: var(--c-primary); font-weight: 700; }
.pd-orders-btn { align-self: flex-start; margin-top: 2px; }

/* 货柜位置：全页信息焦点。
   ⚠️ 只用「小字题头 + 大号数值 + 留白 + 一条通栏细线」做层级，
   **不要加底色色块** —— 试过给它加淡蓝填充，效果像老式「通知条」，
   用户反馈"又土又落后"。
   ⚠️ 也**不要把标签做成和大数值一样大**：两者分不出主次，等于没重点。
   改成上下两行（题头在上、数值在下）是为窄屏考虑：内联写法会让标签独占一行、
   数值再折成「偏左／侧】」这种断在半截的样子。
   分隔线用 --n-200：--n-100 在白底上几乎看不见，等于没画。
   也试过「题头上方一枚 32×3 短强调条」，在 644px 宽的桌面弹窗里像掉了个零件，
   不如通栏细线稳。 */
.pd-loc {
  display: flex; flex-direction: column; align-items: center;
  gap: 6px;
  padding: 18px 0 6px;
  border-top: 1px solid var(--n-200);
  text-align: center;
}
.pd-loc-k {
  font-size: 12.5px; font-weight: 600; color: var(--n-500);
  /* text-indent 抵消末字后的字距，让题头真正居中 */
  letter-spacing: 2.5px; text-indent: 2.5px;
}
.pd-loc-v {
  font-size: 22px; font-weight: 700; color: var(--n-900);
  letter-spacing: .5px; line-height: 1.35;
  overflow-wrap: anywhere;
  text-wrap: balance;          /* 万不得已换行时，两行长度自动均衡 */
}
.pd-loc-v.miss { font-size: 17px; font-weight: 600; color: var(--n-400); }

/* SKU规格 ｜ 取货规则：并排两格，暖色底 + 内嵌浅格 */
.pd-cards {
  display: grid; grid-template-columns: 1fr 1fr;
  background: var(--c-warning-soft);
  border: 1px solid #F6E2C0;
  border-radius: var(--r-md);
  overflow: hidden;
}
.pd-card { padding: 13px 14px; min-width: 0; }
.pd-card + .pd-card { border-left: 1px solid #F6E2C0; }
.pd-card-h {
  text-align: center; margin-bottom: 9px;
  font-size: 14px; font-weight: 700; color: var(--n-800);
}
.pd-card-v {
  padding: 12px;
  background: #F3E8D5;
  border: 1px solid #EBD9BA;
  border-radius: var(--r-sm);
  text-align: center;
  font-size: 13.5px; font-weight: 600; color: var(--n-800);
  white-space: pre-wrap; overflow-wrap: anywhere;
}

/* 详情页里的小节标题：间距交给 .pd 的 gap，不再自带下边距 */
.pd-sec { margin: 2px 0 0; font-size: 13.5px; font-weight: 700; color: var(--n-900); }

/* 窄屏：顶部三栏折成两栏，「客户订单明细」独占一行 */
@media (max-width: 640px) {
  .pd { gap: 14px; }
  .pd-head { grid-template-columns: 100px minmax(0, 1fr); gap: 14px; }
  .pd-thumb img, .pd-thumb-empty { width: 100px; height: 100px; }
  .pd-status { gap: 4px 6px; }

  /* 「查看订单明细」必须保持「小 + 靠右」。
     ⚠️ 绝不能在窄屏把它拉成整行按钮 —— 那样它就和大块的「确认物流并收货」
     长得一模一样，用户根本分不出哪个是主操作（这是明确的反馈意见）。 */
  .pd-orders {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px 10px;
    align-items: center;
    padding-top: 12px;
    border-top: 1px dashed var(--n-200);
  }
  .pd-orders-h { grid-area: 1 / 1; }
  .pd-orders-btn {
    grid-area: 1 / 2;
    justify-self: end; align-self: center; margin-top: 0;
  }
  .pd-orders-peek { grid-area: 2 / 1 / 3 / -1; }

  /* 货柜位置在窄屏沿用桌面同款「无底色」处理：
     字号已是全页最大，再配合上下留白就足够突出，不加填充色块。
     数值压到 19px 是量出来的：当前口径下最长的柜位串是
     「【A柜】第【地面】上的【偏右侧  ➡️】」≈17.2em。
     390 手机可用宽度 346px：20px 时 344px 会折行，19px 时 327px 一行放得下。
     实测 19px 下 390 屏**所有**柜位串都是一行（含「地面」类），
     而「冰箱」现在只展示【冰箱】三个字，短得很。
     19px 与主按钮 16px 仍差 3px，依旧是全页最大字号，够"最显眼"了。 */
  .pd-loc { padding: 16px 0 4px; }
  .pd-loc-k { font-size: 12px; letter-spacing: 2px; text-indent: 2px; }
  .pd-loc-v { font-size: 19px; }

  .pd-card { padding: 11px 10px; }
  .pd-card-h { font-size: 13px; margin-bottom: 7px; }
  .pd-card-v { padding: 10px 8px; font-size: 12.5px; }
}

/* ---------- 22. 打印 ---------- */
@media print {
  .topbar, .sidebar, .bottom-nav, .drawer, .drawer-mask, .page-head-actions, .toolbar, .scope-bar, .scope-compact { display: none !important; }
  .main { padding: 0; }
  .card { border: 1px solid #ccc; box-shadow: none; }
}

/* 2026-09-28：平台侧已签收的包裹（pkg.received）→ 灰显+禁勾，签收不可逆 */
.pkg-item.is-signed { opacity: .55; }
.pkg-item.is-signed .pkg-ck { cursor: not-allowed; }
.pkg-item.is-signed .pkg-num { color: var(--c-ok, #16a34a); }
