/* ==========================================================================
   HarbingeWMS 设计系统  app.css
   --------------------------------------------------------------------------
   组织方式（改这里就能改全站，不要再逐页写内联样式）：
     1  设计令牌        颜色 / 圆角 / 阴影 / 间距 / 字阶
     2  覆盖 Bootstrap  变量层（修好 text-* / text-bg-* / bg-* / 表单焦点）
     3  覆盖 Bootstrap  按钮变体（5.3 把颜色编译进了 --bs-btn-*，只能逐个覆盖）
     4  基础排版
     5  图标系统
     6  外壳：顶栏 / 侧栏
     7  页头 / 卡片 / KPI
     8  表格（含数字排版）
     9  表单
     10 状态胶囊 chip / badge
     11 提示条 / 空状态 / 弹窗
     12 工具类
     13 打印
   ========================================================================== */

/* ============================ 1. 设计令牌 ============================ */
:root {
  /* 中性阶（偏冷的灰；n-50/n-100 对齐线上的表头底 #f7f9fc / 菜单 hover #f2f6fb） */
  --n-0:   #ffffff;
  --n-25:  #fcfdfe;
  --n-50:  #f7f9fc;
  --n-100: #f2f6fb;
  --n-150: #eaeff5;
  --n-200: #e1e7ef;
  --n-300: #d4dae2;   /* 线上滚动条色 */
  --n-400: #a4afbe;
  --n-500: #77828f;
  --n-600: #5b6573;
  --n-700: #414b57;   /* 线上侧栏菜单文字色 */
  --n-800: #2a3341;
  --n-900: #1f2937;

  /* 面与线（与线上一致） */
  --bg:       #f5f7fa;
  --surface:  #ffffff;
  --surface-2:#f7f9fc;   /* 线上表头底色 */
  --line:     #e8ebf0;
  --line-strong:#cdd6e1;
  --line-soft:#eef1f5;

  /* 文字层级（全部取自线上色板：正文 ink、表头灰 #5b6573、muted #6b7280） */
  --ink:    #1f2937;   /* 标题 / 强调 = 线上 --ink */
  --text:   #1f2937;   /* 正文 = 线上 body 色 */
  --text-2: #5b6573;   /* 次要 = 线上表头字色 */
  --text-3: #6b7280;   /* 三级 = 线上 --muted（线上 side-group 的 #9aa3af 只有 2.5:1，微调到此） */

  /* 品牌：线上 --brand / --brand-dark；active 取顶栏渐变起点 #0e4374（色板内） */
  --brand:        #185fa5;
  --brand-dark:   #104a82;
  --brand-hover:  #104a82;
  --brand-active: #0e4374;
  --brand-ink:    #104a82;   /* 品牌色当文字用（~9:1） */
  --brand-tint:   #eef5fd;   /* 线上 side-home 底 */
  --brand-tint-2: #e3eefb;   /* 线上 side-home hover */
  --brand-line:   #dbe9f8;   /* 线上 side-home 边 */
  /* 线上顶栏渐变（原样照搬） */
  --brand-grad:   linear-gradient(90deg, #0e4374 0%, #185fa5 58%, #1d6ab0 100%);

  /* 语义色：全部在 --bg 上满足 AA */
  --ok:        #0f7a4d;  --ok-hover: #0c6440;
  --ok-tint:   #e7f4ed;  --ok-line:  #bfe0cd;  --ok-ink:  #0b5c3b;
  --warn:      #b45309;  --warn-hover:#964407;
  --warn-tint: #fdf2e3;  --warn-line:#eed9b6;  --warn-ink:#8a3f08;
  --bad:       #b91c1c;  --bad-hover: #9c1616;
  --bad-tint:  #fdecec;  --bad-line:  #f4cecb;  --bad-ink:  #8f1616;
  --info:      var(--brand);
  --info-tint: var(--brand-tint); --info-line: var(--brand-line); --info-ink: var(--brand-ink);

  /* 圆角：只有 3 档 + 胶囊 */
  --r-sm: 6px;
  --r:    8px;
  --r-lg: 12px;
  --r-pill: 999px;

  /* 阴影：与线上一致（越低越轻，靠边框定形而非靠阴影撑体积） */
  --sh-1: 0 1px 2px rgba(16,24,40,.05), 0 1px 3px rgba(16,24,40,.04);
  --sh-2: 0 4px 14px rgba(16,24,40,.08), 0 1px 3px rgba(16,24,40,.05);
  --sh-3: 0 14px 36px rgba(16, 24, 40, .14), 0 2px 8px rgba(16, 24, 40, .06);

  /* 间距：8pt 栅格 */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px;
  --s-4: 16px; --s-5: 24px; --s-6: 32px;

  /* 字阶：只有 6 档 */
  --fs-xs: 12px; --fs-sm: 13px; --fs: 14px;
  --fs-md: 16px; --fs-lg: 20px; --fs-xl: 24px;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, monospace;

  --topbar-h: 56px;
  --sidebar-w: 236px;

  /* 兼容旧变量名（模板里还有内联 style 在引用） */
  --muted: var(--text-2);
  --card-shadow: var(--sh-1);
  --card-shadow-hover: var(--sh-2);
}

/* ================= 2. 覆盖 Bootstrap 变量（一次性修好工具类） ================= */
/* 这一段是"改一处、全站受益"的关键：text-* / text-bg-* / bg-* / border-* /
   link-* / 表单焦点环 都读这些变量，改完 51 个页面不用动一行模板。 */
:root {
  --bs-primary:   var(--brand);
  --bs-primary-rgb: 24, 95, 165;
  --bs-secondary: #4b5563;
  --bs-secondary-rgb: 75, 85, 99;
  --bs-success:   var(--ok);
  --bs-success-rgb: 15, 122, 77;
  --bs-danger:    var(--bad);
  --bs-danger-rgb: 185, 28, 28;
  --bs-warning:   var(--warn);
  --bs-warning-rgb: 180, 83, 9;
  --bs-info:      var(--brand);
  --bs-info-rgb:  24, 95, 165;
  --bs-light:     var(--n-100);
  --bs-light-rgb: 242, 246, 251;
  --bs-dark:      var(--n-800);
  --bs-dark-rgb:  42, 51, 65;

  --bs-body-bg:     var(--bg);
  --bs-body-color:  var(--text);
  --bs-body-font-size: var(--fs);
  --bs-body-font-family: var(--font);
  --bs-emphasis-color: var(--ink);
  --bs-secondary-color: var(--text-2);
  --bs-tertiary-color:  var(--text-3);
  --bs-border-color: var(--line);
  --bs-border-color-translucent: var(--line);
  --bs-link-color: var(--brand);
  --bs-link-color-rgb: 24, 95, 165;
  --bs-link-hover-color: var(--brand-hover);
  --bs-border-radius: var(--r);
  --bs-border-radius-sm: var(--r-sm);
  --bs-border-radius-lg: var(--r-lg);
  --bs-focus-ring-color: rgba(24, 95, 165, .12);   /* 线上表单焦点环原值 */
}

/* ================= 3. 按钮（Bootstrap 5.3 把颜色编译进了按钮变量） ================= */
.btn {
  --bs-btn-padding-y: 6px;
  --bs-btn-padding-x: 14px;
  --bs-btn-font-size: var(--fs);
  --bs-btn-font-weight: 500;
  --bs-btn-border-radius: var(--r);
  --bs-btn-line-height: 1.5;
  --bs-btn-focus-box-shadow: 0 0 0 3px var(--bs-focus-ring-color);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  transition: background-color .13s ease, border-color .13s ease, color .13s ease, box-shadow .13s ease;
}
.btn:active { transform: translateY(.5px); }
.btn-sm {
  --bs-btn-padding-y: 4px;
  --bs-btn-padding-x: 10px;
  --bs-btn-font-size: var(--fs-sm);
  --bs-btn-border-radius: var(--r-sm);
  min-height: 28px;   /* WCAG 2.5.8 要求可点区域 ≥24px；这里给到 28px 更好按 */
}
.btn-lg { --bs-btn-padding-y: 9px; --bs-btn-padding-x: 20px; --bs-btn-font-size: var(--fs-md); --bs-btn-border-radius: var(--r); }

/* 实心 */
.btn-primary {
  --bs-btn-bg: var(--brand); --bs-btn-border-color: var(--brand);
  --bs-btn-hover-bg: var(--brand-hover); --bs-btn-hover-border-color: var(--brand-hover);
  --bs-btn-active-bg: var(--brand-active); --bs-btn-active-border-color: var(--brand-active);
  --bs-btn-disabled-bg: var(--brand); --bs-btn-disabled-border-color: var(--brand);
  --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff; --bs-btn-disabled-color: #fff;
}
.btn-success {
  --bs-btn-bg: var(--ok); --bs-btn-border-color: var(--ok);
  --bs-btn-hover-bg: var(--ok-hover); --bs-btn-hover-border-color: var(--ok-hover);
  --bs-btn-active-bg: var(--ok-hover); --bs-btn-active-border-color: var(--ok-hover);
  --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}
.btn-danger {
  --bs-btn-bg: var(--bad); --bs-btn-border-color: var(--bad);
  --bs-btn-hover-bg: var(--bad-hover); --bs-btn-hover-border-color: var(--bad-hover);
  --bs-btn-active-bg: var(--bad-hover); --bs-btn-active-border-color: var(--bad-hover);
  --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}
.btn-warning {
  --bs-btn-bg: var(--warn); --bs-btn-border-color: var(--warn);
  --bs-btn-hover-bg: var(--warn-hover); --bs-btn-hover-border-color: var(--warn-hover);
  --bs-btn-active-bg: var(--warn-hover); --bs-btn-active-border-color: var(--warn-hover);
  --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}
.btn-info {
  --bs-btn-bg: var(--brand); --bs-btn-border-color: var(--brand);
  --bs-btn-hover-bg: var(--brand-hover); --bs-btn-hover-border-color: var(--brand-hover);
  --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}
.btn-secondary {
  --bs-btn-bg: #4b5563; --bs-btn-border-color: #4b5563;
  --bs-btn-hover-bg: #3d4653; --bs-btn-hover-border-color: #3d4653;
  --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}

/* 描边：中性描边是全站最常用的次要动作（49 处），做成"看得清但不抢戏" */
.btn-outline-secondary {
  --bs-btn-color: var(--text-2); --bs-btn-border-color: var(--line-strong);
  --bs-btn-hover-bg: var(--n-100); --bs-btn-hover-color: var(--ink);
  --bs-btn-hover-border-color: var(--n-400);
  --bs-btn-active-bg: var(--n-150); --bs-btn-active-color: var(--ink);
  --bs-btn-active-border-color: var(--n-400);
  --bs-btn-disabled-color: var(--text-3); --bs-btn-disabled-border-color: var(--line);
}
.btn-outline-primary {
  --bs-btn-color: var(--brand-ink); --bs-btn-border-color: var(--brand-line);
  --bs-btn-hover-bg: var(--brand-tint); --bs-btn-hover-color: var(--brand-ink);
  --bs-btn-hover-border-color: var(--brand);
  --bs-btn-active-bg: var(--brand-tint-2); --bs-btn-active-color: var(--brand-ink);
  --bs-btn-active-border-color: var(--brand);
}
.btn-outline-success {
  --bs-btn-color: var(--ok-ink); --bs-btn-border-color: var(--ok-line);
  --bs-btn-hover-bg: var(--ok-tint); --bs-btn-hover-color: var(--ok-ink);
  --bs-btn-hover-border-color: var(--ok);
  --bs-btn-active-bg: var(--ok-tint); --bs-btn-active-color: var(--ok-ink);
}
.btn-outline-danger {
  --bs-btn-color: var(--bad-ink); --bs-btn-border-color: var(--bad-line);
  --bs-btn-hover-bg: var(--bad-tint); --bs-btn-hover-color: var(--bad-ink);
  --bs-btn-hover-border-color: var(--bad);
  --bs-btn-active-bg: var(--bad-tint); --bs-btn-active-color: var(--bad-ink);
}
.btn-outline-warning {
  --bs-btn-color: var(--warn-ink); --bs-btn-border-color: var(--warn-line);
  --bs-btn-hover-bg: var(--warn-tint); --bs-btn-hover-color: var(--warn-ink);
  --bs-btn-hover-border-color: var(--warn);
}
.btn-outline-info {
  --bs-btn-color: var(--brand-ink); --bs-btn-border-color: var(--brand-line);
  --bs-btn-hover-bg: var(--brand-tint); --bs-btn-hover-color: var(--brand-ink);
}
.btn-outline-light {
  --bs-btn-color: var(--text-2); --bs-btn-border-color: var(--line-strong);
  --bs-btn-hover-bg: var(--n-100); --bs-btn-hover-color: var(--ink);
}
.btn-link {
  --bs-btn-color: var(--brand); --bs-btn-hover-color: var(--brand-hover);
  --bs-btn-font-weight: 500; text-decoration: none;
}
.btn-link:hover { text-decoration: underline; text-underline-offset: 2px; }

/* ============================ 4. 基础排版 ============================ */
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font);
  font-size: var(--fs);
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6 { color: var(--ink); font-weight: 650; letter-spacing: -.005em; }
h1 { font-size: var(--fs-xl); } h2 { font-size: var(--fs-lg); }
h3 { font-size: 18px; } h4 { font-size: var(--fs-md); }
h5, h6 { font-size: var(--fs); }
a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-hover); text-decoration: underline; text-underline-offset: 2px; }

.small, small { font-size: var(--fs-xs); }
.text-muted { color: var(--text-2) !important; }
.fw-semibold { font-weight: 600 !important; }
hr { border-color: var(--line); opacity: 1; }

/* 数字：仓库系统里数字能不能"一眼竖着比"是效率问题，不是审美问题 */
.num, td.num, th.num, .tabular {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.mono { font-family: var(--mono); font-size: .94em; letter-spacing: -.01em; }
.text-end.num { text-align: right; }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: #d4dae2; border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: #bcc4cf; }
::-webkit-scrollbar-track { background: transparent; }

/* ============================ 5. 图标系统 ============================ */
.i {
  width: 16px; height: 16px; flex: none;
  display: inline-block; vertical-align: -.15em;
  color: inherit;
}
.i-sm { width: 14px; height: 14px; }
.i-lg { width: 20px; height: 20px; }
.i-xl { width: 24px; height: 24px; }
a .i, button .i { pointer-events: none; }

/* ============================ 6. 外壳 ============================ */
/* 顶栏：线上版的深蓝渐变（用户钦定"原来的颜色舒服"）。白字 + 半透白控件，
   与白色侧栏形成"深色导航带 / 浅色工作区"的经典业务软件格局。 */
.app-top {
  position: sticky; top: 0; z-index: 1030;
  height: var(--topbar-h);
  background: var(--brand-grad);
  box-shadow: 0 1px 0 rgba(255,255,255,.06) inset, 0 2px 10px rgba(13,43,74,.22);
}
.app-top__inner {
  height: 100%; display: flex; align-items: center; gap: var(--s-2);
  padding: 0 var(--s-5) 0 var(--s-4);
}
.app-brand {
  display: flex; align-items: center; gap: 10px;
  text-decoration: none; color: #fff; min-width: 0;
}
.app-brand:hover { text-decoration: none; color: #fff; }
.app-brand__mark {
  width: 32px; height: 32px; border-radius: 9px; flex: none;
  background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.18);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
}
.app-brand__mark .i { width: 18px; height: 18px; }
.app-brand__text { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.app-brand__name { font-weight: 700; font-size: var(--fs); letter-spacing: .4px; white-space: nowrap; }
.app-brand__sub { font-size: 11px; color: rgba(255,255,255,.62); white-space: nowrap; }
.app-top__spacer { flex: 1 1 auto; }
.app-top__btn, .app-top__icon {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 32px; min-width: 32px; padding: 0 9px;
  border: 1px solid transparent; border-radius: var(--r-sm);
  background: transparent; color: rgba(255,255,255,.78);
  font-size: var(--fs-sm); text-decoration: none; cursor: pointer;
  transition: background-color .13s ease, color .13s ease, border-color .13s ease;
}
.app-top__btn:hover, .app-top__icon:hover {
  background: rgba(255,255,255,.14); color: #fff; text-decoration: none;
  border-color: transparent;
}
.app-user { display: flex; align-items: center; gap: var(--s-2); padding-right: var(--s-1); }
.app-user__name { font-size: var(--fs-sm); font-weight: 550; color: rgba(255,255,255,.88); white-space: nowrap; }
.app-top__sep { width: 1px; height: 22px; background: rgba(255,255,255,.22); margin: 0 var(--s-1); }
/* 深蓝顶栏上的键盘焦点环用白色，否则看不见 */
.app-top a:focus-visible, .app-top button:focus-visible { outline-color: #fff; }

/* 侧栏（线上行为：白底；hover 浅蓝 + 字变品牌色；active 实心品牌蓝 + 白字 + 投影） */
.sidebar {
  background: var(--surface);
  border-right: 1px solid var(--line);
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  max-width: var(--sidebar-w);
  padding: var(--s-3) 0 var(--s-6);
  position: sticky; top: var(--topbar-h);
  height: calc(100vh - var(--topbar-h));
  overflow-y: auto; overscroll-behavior: contain;
}
.side-group {
  font-size: 11px; font-weight: 600; letter-spacing: .07em;
  color: var(--text-3);   /* 微调点：线上 #9aa3af 只有 2.5:1，加深到线上 --muted 同值 */
  padding: var(--s-4) var(--s-5) 5px;
  text-transform: none;
}
.side-group:first-child { padding-top: var(--s-1); }
.sidebar a.menu-link {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  margin: 1px var(--s-3); padding: 7px 10px;
  border-radius: var(--r);
  color: var(--n-700); font-size: var(--fs-sm); font-weight: 500;
  text-decoration: none;
  transition: background-color .12s ease, color .12s ease;
}
.sidebar a.menu-link .mi {
  width: 18px; height: 18px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--n-500);
}
.sidebar a.menu-link .mi .i { width: 16px; height: 16px; }
.sidebar a.menu-link:hover { background: #f2f6fb; color: var(--brand); text-decoration: none; }
.sidebar a.menu-link:hover .mi { color: var(--brand); }
.sidebar a.menu-link.active {
  background: var(--brand); color: #fff; font-weight: 600;
  box-shadow: 0 2px 8px rgba(24,95,165,.3);
}
.sidebar a.menu-link.active .mi { color: #fff; }
.sidebar a.menu-link.active::before {
  content: ""; position: absolute; left: -12px; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 18px; border-radius: 0 3px 3px 0; background: #fff;
}
.side-home {
  display: flex; align-items: center; gap: 10px;
  margin: 0 var(--s-3) var(--s-2); padding: 9px 12px;
  border-radius: 10px;
  color: var(--brand-dark); font-weight: 600; font-size: var(--fs-sm);
  text-decoration: none; background: var(--brand-tint); border: 1px solid var(--brand-line);
}
.side-home .mi { color: var(--brand); display: inline-flex; }
.side-home:hover { background: var(--brand-tint-2); color: var(--brand-dark); text-decoration: none; }
.side-home.active { background: var(--brand-tint-2); border-color: var(--brand); color: var(--brand-dark); }
.sidebar-toggle { display: none; }

.main {
  /* 关键：主区必须"吃掉剩余宽度"，且外壳永不允许换行。
     历史故障（2026-09-26，前三轮改版都带着这个 bug）：侧栏是固定 236px，
     主区却还挂着 Bootstrap 的 col-md-10（83.33%），两者相加 > 100%，
     .row 默认 flex-wrap:wrap 把主内容换到下一行、落在全高侧栏之下 ——
     首屏一片空白，用户表现为"除了主页，里面都打不开"。
     实测：窗口 ≤1366px 全中招（1920 屏 150% 缩放 = 1280 CSS px，极常见），
     而 1440 及以上正常，所以只在 1440 下验收是查不出来的。 */
  flex: 1 1 0%;
  width: auto;
  padding: var(--s-5) var(--s-5) var(--s-6);
  max-width: 1560px;
  min-width: 0;
}
.app-shell { flex-wrap: nowrap; }   /* 外壳栅格：固定侧栏 + 自适应主区，禁止换行 */

@media (max-width: 991.98px) {
  .main { padding: var(--s-4) var(--s-4) var(--s-5); }
  .app-top__inner { padding: 0 var(--s-4); }
}
@media (max-width: 767.98px) {
  .app-shell { flex-wrap: wrap; }        /* 窄屏：侧栏全宽 + 主区在下方（正常堆叠） */
  .main { flex: 1 1 100%; width: 100%; }
  .sidebar {
    display: none; position: static; height: auto; width: 100%;
    flex: 0 0 100%; max-width: 100%;
    border-right: none; border-bottom: 1px solid var(--line);
    padding-bottom: var(--s-4);
  }
  .sidebar.open { display: block; }
  .sidebar-toggle { display: inline-flex; }
  .app-brand__sub { display: none; }
  .app-user__name { display: none; }
}

/* ============================ 7. 页头 / 卡片 / KPI ============================ */
.page-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: var(--s-3); flex-wrap: wrap;
  margin-bottom: var(--s-5);
}
.page-head__main { min-width: 0; }
.page-head h1, .page-head h2, .page-head h3, .page-head h4, .page-head h5 {
  margin: 0; font-size: var(--fs-lg); font-weight: 650; letter-spacing: -.01em; line-height: 1.3;
}
.page-head__sub { color: var(--text-2); font-size: var(--fs-sm); margin-top: 4px; }
.page-head__actions { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }

.crumb-back {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--text-3); font-size: var(--fs-sm); text-decoration: none;
  margin-bottom: 6px;
  min-height: 24px;   /* 可点区域下限（WCAG 2.5.8） */
}
.crumb-back:hover { color: var(--brand); text-decoration: none; }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
}
.card-body { padding: var(--s-4) var(--s-4); }
.card-header {
  background: transparent; border-bottom: 1px solid var(--line);
  padding: var(--s-3) var(--s-4); font-weight: 600; color: var(--ink);
}
.card-footer { background: transparent; border-top: 1px solid var(--line); padding: var(--s-3) var(--s-4); }

.card-stat { transition: box-shadow .16s ease, border-color .16s ease; }
.card-stat:hover { box-shadow: var(--sh-2); }
.card-stat .card-body { padding: var(--s-4); }
.card-stat h6 { font-weight: 600; color: var(--ink); }
.card-clickable { cursor: pointer; }
.card-clickable:hover { border-color: var(--line-strong); }

.stat-icon {
  width: 40px; height: 40px; border-radius: 10px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--n-100); color: var(--text-2);
}
.stat-icon .i { width: 20px; height: 20px; }
.stat-icon--brand { background: var(--brand-tint); color: var(--brand-ink); }
.stat-icon--ok    { background: var(--ok-tint);    color: var(--ok-ink); }
.stat-icon--warn  { background: var(--warn-tint);  color: var(--warn-ink); }
.stat-icon--bad   { background: var(--bad-tint);   color: var(--bad-ink); }
.stat-icon--info  { background: var(--brand-tint); color: var(--brand-ink); }
/* 线上色板里没有紫色 —— 第四色改用线上 VIEWER 徽章的暖灰族（#5f5e5a） */
.stat-icon--violet{ background: #f1f0ed;           color: #5f5e5a; }

.kpi-value {
  font-size: var(--fs-xl); font-weight: 680; line-height: 1.15;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.kpi-label { font-size: var(--fs-sm); color: var(--text-2); }
.kpi-foot { font-size: var(--fs-xs); color: var(--text-3); }

/* ============================ 8. 表格 ============================ */
.table {
  --bs-table-bg: transparent;
  --bs-table-border-color: var(--line-soft);
  margin-bottom: 0;
  color: var(--text);
  font-size: var(--fs-sm);
}
.table > thead th {
  background: var(--surface-2);
  color: var(--text-2);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .02em;
  white-space: nowrap;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line) !important;
  border-top: 0;
  vertical-align: middle;
}
.table > tbody td {
  padding: 9px 12px;
  vertical-align: middle;
  border-color: var(--line-soft);
  font-size: var(--fs-sm);
}
.table > tbody td, .table > tbody th { border-bottom: 1px solid var(--line-soft); }
/* 全站表格一律用等宽数字：仓库系统里"数字能不能竖着对齐扫"是效率问题，
   不是审美问题。font-variant-numeric 只影响数字字形，对中文/字母无副作用，
   所以可以安全地整表施加，不必逐个单元格改。 */
.table > thead th, .table > tbody td { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.table-sm > :not(caption) > * > * { padding: 6px 10px; }
.table-hover > tbody > tr:hover > * { background: #f6f9fd; --bs-table-accent-bg: #f6f9fd; }
.table thead.sticky-top th { position: sticky; top: var(--topbar-h); z-index: 2; }
.table-responsive { border-radius: var(--r); }
/* 去掉竖线：现代业务系统的惯例是靠横向分隔 + 对齐来读表，不靠网格 */
.table-bordered { --bs-table-border-color: var(--line-soft); }
.table-bordered > :not(caption) > * > * { border-width: 0 0 1px 1px; }
.table-bordered > :not(caption) > * > *:first-child { border-left: 0; }

.table-actions { display: flex; align-items: center; gap: var(--s-3); justify-content: flex-end; flex-wrap: wrap; }
.table-actions a {
  font-size: var(--fs-sm); text-decoration: none; white-space: nowrap;
  margin-right: 0; display: inline-flex; align-items: center; gap: 4px;
  min-height: 24px;   /* 行内动作链接也要够大才点得准（WCAG 2.5.8） */
}
.table-actions--left { justify-content: flex-start; }
td.tight { width: 1%; white-space: nowrap; }

/* 表格里的第一列（单据号）用等宽，垂直扫读时更容易对齐 */
.table .row-key { font-family: var(--mono); font-size: 12.5px; color: var(--ink); font-weight: 500; }
.table .row-key a { color: var(--ink); }
.table .row-key a:hover { color: var(--brand); }

/* ============================ 9. 表单 ============================ */
.form-label { font-size: var(--fs-sm); font-weight: 550; color: var(--ink); margin-bottom: 5px; }
.form-control, .form-select {
  border-radius: var(--r); border-color: var(--line-strong);
  font-size: var(--fs); padding: 6px 10px; color: var(--text);
  background-color: var(--surface);
}
.form-control-sm, .form-select-sm { font-size: var(--fs-sm); padding: 3px 8px; border-radius: var(--r-sm); }
.form-control:focus, .form-select:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--bs-focus-ring-color);
}
.form-control::placeholder { color: var(--n-400); }
.form-text { font-size: var(--fs-xs); color: var(--text-2); }
.form-check-input { border-color: var(--n-400); }
.form-check-input:checked { background-color: var(--brand); border-color: var(--brand); }
.form-check-input:focus { box-shadow: 0 0 0 3px var(--bs-focus-ring-color); }
.form-check-label { font-size: var(--fs-sm); }
.input-group-text {
  background: var(--n-50); border-color: var(--line-strong);
  color: var(--text-2); font-size: var(--fs-sm);
}
/* 必填：用一个小星号而不是满屏红框 */
.form-label.required::after { content: " *"; color: var(--bad); font-weight: 400; }

/* 表单分组：把"一段有标题的字段区"标准化，编辑页靠它建立节奏 */
.form-section { border-top: 1px solid var(--line); padding-top: var(--s-4); margin-top: var(--s-5); }
.form-section:first-child { border-top: 0; margin-top: 0; padding-top: 0; }
.form-section__title {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--fs-sm); font-weight: 650; color: var(--ink);
  margin-bottom: var(--s-3);
}
.form-section__title .i { color: var(--text-3); }
.form-section__hint { font-size: var(--fs-xs); color: var(--text-2); margin: -6px 0 var(--s-3); }

/* 粘性操作条：长表单底部动作不随滚动消失 */
.sticky-actions {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap;
  margin: var(--s-5) calc(-1 * var(--s-4)) calc(-1 * var(--s-4));
  padding: var(--s-3) var(--s-4);
  background: var(--surface);
  border-top: 1px solid var(--line);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}
/* 不在卡片里、直接挂在页面上的用法（如整页表单的底部按钮） */
.sticky-actions--page {
  margin: var(--s-5) 0 0;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-2);
}

/* 标签页 / 分段导航：多个页面在用，改样式比改模板划算 */
.nav-tabs { border-bottom: 1px solid var(--line); }
.nav-tabs .nav-link {
  color: var(--text-2); font-size: var(--fs-sm); font-weight: 500;
  border: 0; border-bottom: 2px solid transparent;
  padding: 8px 12px; border-radius: 0;
}
.nav-tabs .nav-link:hover { color: var(--ink); border-bottom-color: var(--line-strong); }
.nav-tabs .nav-link.active {
  color: var(--brand-ink); border-bottom-color: var(--brand);
  background: transparent; font-weight: 600;
}
.nav-pills { gap: 4px; }
.nav-pills .nav-link {
  color: var(--text-2); font-size: var(--fs-sm); font-weight: 500;
  padding: 6px 12px; border-radius: var(--r-sm);
}
.nav-pills .nav-link:hover { background: var(--n-100); color: var(--ink); }
.nav-pills .nav-link.active { background: var(--brand); color: #fff; }

/* ============================ 10. 状态胶囊 chip / badge ============================ */
/* 统一为"浅底 + 深字 + 一根发丝边"。满色实心 pill 一片铺开时噪音极大，
   而且 Bootstrap 默认的 text-bg-* 本身就不过 AA（如 text-bg-warning 只有 1.63:1）。 */
.badge, .chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font-size: var(--fs-xs); font-weight: 550; line-height: 1.5;
  letter-spacing: .01em; white-space: nowrap;
  vertical-align: baseline;
}
.chip .i { width: 12px; height: 12px; }
.badge { background: var(--n-100); color: var(--text-2); border-color: var(--line); }

.text-bg-secondary { background: var(--n-100) !important; color: var(--text-2) !important; border-color: var(--line); }
.text-bg-light     { background: var(--n-50) !important;  color: var(--text-2) !important; border-color: var(--line); }
.text-bg-success   { background: var(--ok-tint) !important;   color: var(--ok-ink) !important;   border-color: var(--ok-line); }
.text-bg-warning   { background: var(--warn-tint) !important; color: var(--warn-ink) !important; border-color: var(--warn-line); }
.text-bg-danger    { background: var(--bad-tint) !important;  color: var(--bad-ink) !important;  border-color: var(--bad-line); }
.text-bg-info      { background: var(--brand-tint) !important;color: var(--brand-ink) !important;border-color: var(--brand-line); }
.text-bg-primary   { background: var(--brand-tint) !important;color: var(--brand-ink) !important;border-color: var(--brand-line); }
.text-bg-dark      { background: var(--n-800) !important; color: #fff !important; border-color: var(--n-800); }

/* 需要"实心强调"时显式加这个类，不要靠默认色 */
.chip--solid { background: var(--brand) !important; color: #fff !important; border-color: var(--brand); }
.chip--solid-ok { background: var(--ok) !important; color: #fff !important; border-color: var(--ok); }
.chip--solid-bad { background: var(--bad) !important; color: #fff !important; border-color: var(--bad); }
/* 纯文字徽标（不占地方）：用于行内的"入库单/出库单"这类分类词 */
.chip--plain { background: transparent !important; color: var(--text-3) !important; border-color: var(--line-strong); }

/* 模板里有大量 `class="badge bg-warning"` 这种写法：只设了背景、没设文字色，
   于是文字继承深色，落在深琥珀/深红底上对比度只有 ~2:1（不合格）。
   这里统一兜住 —— 比逐个去改几十处模板稳，也不会漏。
   注意只作用于 .badge，不碰纯装饰用的 <div class="bg-success">。 */
.badge.bg-success, .badge.bg-warning, .badge.bg-danger,
.badge.bg-info, .badge.bg-primary, .badge.bg-secondary, .badge.bg-light {
  border: 1px solid transparent;
}
.badge.bg-success   { background: var(--ok-tint) !important;    color: var(--ok-ink) !important;    border-color: var(--ok-line); }
.badge.bg-warning   { background: var(--warn-tint) !important;  color: var(--warn-ink) !important;  border-color: var(--warn-line); }
.badge.bg-danger    { background: var(--bad-tint) !important;   color: var(--bad-ink) !important;   border-color: var(--bad-line); }
.badge.bg-info      { background: var(--brand-tint) !important; color: var(--brand-ink) !important; border-color: var(--brand-line); }
.badge.bg-primary   { background: var(--brand-tint) !important; color: var(--brand-ink) !important; border-color: var(--brand-line); }
.badge.bg-secondary { background: var(--n-100) !important;      color: var(--text-2) !important;    border-color: var(--line); }
.badge.bg-light     { background: var(--n-50) !important;       color: var(--text-2) !important;    border-color: var(--line); }
.badge.bg-dark      { background: var(--n-800) !important;      color: #fff !important;             border-color: var(--n-800); }

/* 角色徽章：与线上完全一致的实心三色 */
.badge-role-ADMIN    { background: #791f1f !important; color: #fff !important; border-color: #791f1f; }
.badge-role-OPERATOR { background: #185fa5 !important; color: #fff !important; border-color: #185fa5; }
.badge-role-VIEWER   { background: #5f5e5a !important; color: #fff !important; border-color: #5f5e5a; }

/* ============================ 11. 提示条 / 空状态 / 弹窗 ============================ */
.alert {
  display: flex; align-items: flex-start; gap: var(--s-2);
  border-radius: var(--r); border-width: 1px; border-style: solid;
  padding: var(--s-3) var(--s-4);
  font-size: var(--fs-sm); box-shadow: none;
}
.alert .i { margin-top: 2px; }
.alert-danger  { background: var(--bad-tint);  border-color: var(--bad-line);  color: var(--bad-ink); }
.alert-warning { background: var(--warn-tint); border-color: var(--warn-line); color: var(--warn-ink); }
.alert-success { background: var(--ok-tint);   border-color: var(--ok-line);   color: var(--ok-ink); }
.alert-info    { background: var(--brand-tint);border-color: var(--brand-line);color: var(--brand-ink); }
.alert-secondary, .alert-light { background: var(--n-50); border-color: var(--line); color: var(--text-2); }
.alert a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.alert .btn-close { margin-left: auto; filter: none; opacity: .55; }
.alert .btn-close:hover { opacity: .9; }

.empty-tip {
  color: var(--text-3); text-align: center;   /* 微调点：线上 #a2abb6 只有 2.3:1，加深到线上 --muted 同值 */
  padding: var(--s-6) var(--s-4);
  font-size: var(--fs-sm);
}
.empty {
  text-align: center; padding: var(--s-6) var(--s-4); color: var(--text-2);
}
.empty__icon {
  width: 44px; height: 44px; margin: 0 auto var(--s-3);
  border-radius: var(--r-lg); background: var(--n-100); color: var(--n-500);
  display: flex; align-items: center; justify-content: center;
}
.empty__icon .i { width: 22px; height: 22px; }
.empty__title { font-weight: 600; color: var(--ink); margin-bottom: 4px; }
.empty__desc { font-size: var(--fs-sm); color: var(--text-2); }

.modal-content {
  border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-3);
}
.modal-header, .modal-footer { border-color: var(--line); padding: var(--s-3) var(--s-4); }
.modal-body { padding: var(--s-4); }
.modal-title { font-size: var(--fs-md); font-weight: 650; }

.dropdown-menu {
  border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--sh-2); padding: 4px; font-size: var(--fs-sm);
}
.dropdown-item { border-radius: var(--r-sm); padding: 6px 10px; }
.dropdown-item:hover, .dropdown-item:focus { background: var(--n-100); color: var(--ink); }

pre.code-block {
  background: #1f2937; color: #e5e7eb;   /* 线上原值 */
  padding: var(--s-3); border-radius: var(--r);
  font-size: var(--fs-xs); line-height: 1.65; overflow: auto;
  font-family: var(--mono);
}

/* 提示气泡（原 JS 里内联写死样式，挪到这里好统一） */
.app-tip {
  position: fixed; left: 50%; top: var(--s-4); transform: translateX(-50%);
  background: var(--n-900); color: #fff;
  padding: 8px 16px; border-radius: var(--r);
  font-size: var(--fs-sm); z-index: 2000;
  box-shadow: var(--sh-3); max-width: 80vw;
}

/* ============================ 12. 工具类 ============================ */
/* 关键值行：`标签 → 值` 的通用排版（详情页到处都是这种对） */
.kv { display: grid; grid-template-columns: minmax(96px, auto) 1fr; gap: 6px var(--s-3); }
.kv__k { color: var(--text-2); font-size: var(--fs-sm); }
.kv__v { color: var(--text); font-size: var(--fs-sm); }

.meta { color: var(--text-2); font-size: var(--fs-sm); }
.meta-2 { color: var(--text-3); font-size: var(--fs-xs); }
.divider { height: 1px; background: var(--line); margin: var(--s-4) 0; border: 0; }
.toolbar { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.toolbar--end { justify-content: flex-end; }

.copyable { cursor: pointer; border-bottom: 1px dashed transparent; transition: background .12s ease, border-color .12s ease; border-radius: 3px; }
.copyable:hover { background: #eef4fb; border-bottom-color: var(--brand); }   /* 线上原值 */
.copyable:active { background: #e2edf9; }

/* 原模板里已经在用 min-w-0 / flex-none，但 Bootstrap 并没有这两个类 —— 等于一直没生效 */
.min-w-0 { min-width: 0; }
.flex-none { flex: none; }

/* KPI 卡做成链接：整块可点，但不要链接的下划线与变蓝 */
a.kpi, a.card { text-decoration: none; color: inherit; display: block; }
a.kpi:hover, a.card:hover { text-decoration: none; color: inherit; }

/* 列表末行去掉分隔线，避免和卡片底边叠成双线 */
.tight-list > li:last-child { border-bottom: 0 !important; }

/* 状态圆点：用在"多个状态并列"的紧凑位置，比整块 chip 轻 */
.dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; flex: none; background: var(--n-400); }
.dot--ok { background: var(--ok); }
.dot--warn { background: var(--warn); }
.dot--bad { background: var(--bad); }
.dot--info { background: var(--brand); }

/* 独立的小号动作链接（`<a class="small">查看 / 确认</a>` 这类）也够得着：
   WCAG 2.5.8 要求指针目标 ≥24×24，而 13px 文字裸链接只有 19px 高。 */
main a.small { display: inline-flex; align-items: center; min-height: 24px; }
td > a.small { display: inline-flex; align-items: center; min-height: 24px; }

/* 让 Bootstrap 的灰色工具类不再降低对比度 */
.text-secondary { color: var(--text-2) !important; }
.bg-light { background-color: var(--n-50) !important; }
.bg-white { background-color: var(--surface) !important; }
.border { border-color: var(--line) !important; }

/* ============================ 12b. 登录页 ============================ */
.auth {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: var(--s-5);
  background: var(--bg);
}
.auth__card {
  width: 100%; max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-2);
  padding: var(--s-6) var(--s-5) var(--s-5);
}
.auth__head { text-align: center; margin-bottom: var(--s-5); }
.auth__mark {
  width: 40px; height: 40px; margin: 0 auto var(--s-3); border-radius: 10px;
  /* 与顶栏的半透白 mark 区分开：浅色登录页上用实心品牌蓝 */
  background: var(--brand); border-color: transparent; color: #fff;
}
.auth__mark .i { width: 22px; height: 22px; }
.auth__title { font-size: 18px; font-weight: 650; margin: 0 0 4px; letter-spacing: -.01em; }
.auth__sub { color: var(--text-2); font-size: var(--fs-sm); margin: 0; }
.auth__submit { height: 40px; font-weight: 600; letter-spacing: .1em; }
.auth__foot { text-align: center; color: var(--text-3); font-size: var(--fs-xs); margin: var(--s-5) 0 0; }

/* ============================ 13. 外壳配色沿革 ============================ */
/* 2026-09-26 三易其稿后的定论：外壳配色以线上版（bonded-warehouse.cn）为准 ——
   深蓝渐变顶栏 (#0e4374→#185fa5→#1d6ab0) + 白色侧栏 + 实心品牌蓝 active 菜单。
   第一次改版曾把顶栏改浅色、第二轮试过深蓝黑外壳，均被用户否掉：
   "还是原来的颜色舒服"。样式以第 6 节为准，此节仅作记录。 */

/* ============================ 14. 微交互层（第二轮深化） ============================ */
/* 键盘焦点环：鼠标用户无感，键盘用户刚需。之前只有表单控件有焦点样式，
   链接和按钮靠浏览器默认虚线 —— 在深色外壳上几乎看不见。 */
a:focus-visible, button:focus-visible, .btn:focus-visible,
.menu-link:focus-visible, .side-home:focus-visible,
.app-top__btn:focus-visible, .app-top__icon:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
.form-control:focus-visible, .form-select:focus-visible { outline: none; }

/* 页面进入：4px 位移 + 淡入，180ms —— 感知到"页面换了"但说不出哪里动了，
   这就是"质感"的来源。尊重系统的减弱动效设置。 */
@keyframes app-page-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
.main > * { animation: app-page-in .18s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .main > * { animation: none; }
  * { transition-duration: .01ms !important; }
}

/* KPI 卡：悬浮时轻微浮起，告诉用户"整块可点" */
a.kpi { transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease; }
a.kpi:hover { transform: translateY(-2px); box-shadow: var(--sh-2); border-color: var(--line-strong); }
a.kpi:active { transform: translateY(0); }

/* 选中文字的颜色跟随品牌浅蓝（线上 brand-line），不用系统默认蓝 */
::selection { background: var(--brand-line); color: var(--ink); }

/* ============================ 15. 登录页分屏（第二轮深化） ============================ */
/* 左：品牌区（线上浅蓝族 tint 渐变）；右：表单。窄屏时品牌区隐藏，退化为单卡。 */
.auth--split { padding: 0; align-items: stretch; flex-direction: row; }
.auth__panel {
  flex: 1 1 46%; min-width: 0;
  display: flex; align-items: center; justify-content: center;
  padding: var(--s-6);
  background:
    radial-gradient(120% 90% at 15% 10%, rgba(24, 95, 165, .10) 0%, transparent 55%),
    linear-gradient(158deg, #eef5fd 0%, #f6f9fd 62%);
  border-right: 1px solid var(--line);
  color: var(--text);
}
.auth__panel-inner { max-width: 380px; }
.auth__panel-mark {
  width: 48px; height: 48px; border-radius: 12px; margin-bottom: var(--s-5);
  background: var(--brand); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 8px 24px rgba(24, 95, 165, .28);
}
.auth__panel-mark .i { width: 26px; height: 26px; }
.auth__panel-title { font-size: 22px; font-weight: 650; letter-spacing: -.01em; color: var(--ink); margin: 0 0 6px; }
.auth__panel-sub { font-size: var(--fs-sm); color: var(--text-2); margin: 0 0 var(--s-5); }
.auth__points { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.auth__points li {
  display: flex; align-items: center; gap: 10px;
  font-size: var(--fs-sm); color: var(--text-2);
}
.auth__points .i { width: 15px; height: 15px; color: var(--brand); flex: none; }
.auth__form-side {
  flex: 1 1 54%; min-width: 0;
  display: flex; align-items: center; justify-content: center;
  padding: var(--s-6) var(--s-5);
}
.auth--split .auth__card {
  max-width: 380px; border: none; box-shadow: none; padding: var(--s-5);
}
.auth--split .auth__head { text-align: left; }
.auth--split .auth__mark { display: none; }  /* 品牌标识已在左 panel 里，右侧不重复 */
.auth--split .auth__foot { text-align: left; }
@media (max-width: 860px) {
  .auth__panel { display: none; }
  .auth--split .auth__card { max-width: 400px; }
  .auth--split .auth__mark { display: flex; }
  .auth--split .auth__head { text-align: center; }
  .auth--split .auth__foot { text-align: center; }
}

/* ============================ 16. 打印 ============================ */
@media print {
  .sidebar, .app-top, .no-print, .alert, form, .btn, .sticky-actions,
  .sidebar-toggle, .table-actions, .app-tip { display: none !important; }
  .main { width: 100% !important; flex: 0 0 100% !important; max-width: 100% !important; padding: 0 !important; }
  body { background: #fff; color: #000; font-size: 12px; }
  .card, .card-stat { box-shadow: none !important; border: none !important; }
  .card-body { padding: 0 !important; }
  table { font-size: 11px; }
  .table > thead th { background: #f2f2f2 !important; color: #000 !important; }
  .badge, .chip { border: 1px solid #999 !important; background: #fff !important; color: #000 !important; }
  a[href]:after { content: none !important; }
  a { color: #000 !important; text-decoration: none !important; }
  .page-head { margin-bottom: 10px; }
}
