:root {
  --primary: #6c5ce7;
  --primary-dark: #5b4bd1;
  --primary-light: #efecfd;
  --success: #17a04a;
  --success-light: #e6f7ec;
  --danger: #e74c3c;
  --danger-light: #fdecea;
  --warning: #d9832a;
  --warning-light: #fdf1e3;
  --info: #0d9488;
  --info-light: #e3f5f3;
  --accent: #2f6fed;
  --accent-light: #e8f0fe;
  --pending: #c2255c;
  --pending-light: #fce8f0;
  --text: #1f2430;
  --text-muted: #8a8f9c;
  --border: #e8e9ee;
  --bg-page: #f3f4f8;
  --radius: 8px;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: "Microsoft YaHei", "Segoe UI", sans-serif;
  background: var(--bg-page);
  color: var(--text);
  font-size: 14px;
}
.hidden { display: none !important; }
html.site-booting #authView,
html.site-booting #mainView {
  visibility: hidden;
}

/* ---------- 登录/注册 ----------
   2026-09-02改版："高大上"登录页——原来是一张320px小白卡片，改成左右分栏
   的大卡片：左边深色品牌区(按当前渠道著色，呼应下面channel-banner那套
   "颜色=渠道"的既有约定，用户扫一眼底色就知道自己在哪个通道，跟原来
   "怕客户搞混渠道"的诉求是一致的，不是新引入的东西)，右边白色表单区。
   2026-09-03按客户给的参考图再调一版：品牌区换成卖点文案+勾选清单，
   警示/通知条从登录页拿掉(客户明确要求)——合规提示本来就还留在登录后
   主界面的topbar里(见.topbar-compliance)，不是彻底去掉，只是不在登录页
   这个"第一印象"页面上出现。表单里的id/name/class(loginForm/
   loginUsername/...)一个没动，app.js/quickfort.js/jcexcustom.js的登录
   逻辑零改动。 */
/* 2026-09-03客户反馈"浏览器背景现在是白色"——原来只在两个角落叠了两团
   很淡的光晕，大部分视口面积基本还是--bg-page那个接近白色的浅灰，看着
   跟没加颜色一样。改成整页铺一层看得出来的浅紫渐变，两团光晕加大加浓
   做点缀，卡片本身还是白色，靠这层背景色把卡片"衬"出来，不是让背景
   本身抢戏。 */
.auth-view {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 16px;
  background:
    radial-gradient(circle at 12% 8%, rgba(124,58,237,0.22), transparent 50%),
    radial-gradient(circle at 88% 92%, rgba(47,111,237,0.20), transparent 50%),
    linear-gradient(160deg, #e7e3fb 0%, #dfe0f8 45%, #d8e2f8 100%);
}
.auth-shell { width: 100%; max-width: 1100px; }
.auth-card {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  background: #fff;
  border-radius: 24px;
  overflow: hidden;
  box-shadow: 0 30px 70px rgba(20,16,60,0.22), 0 2px 6px rgba(20,16,60,0.08);
}

/* 左侧深色品牌区：底色按渠道变(auth-view上的channel-jcex/channel-qft/
   channel-jcex-custom决定，具体靠下面--auth-accent这个渠道专属的强调色)，
   叠一层细密点阵纹理+两团柔光，营造"全球物流网络"的质感——纯CSS渐变
   实现，不引入任何图片/字体外部请求(国内访问Google Fonts这类外链常常
   很慢甚至连不上，这几天调硅谷服务器已经踩够这个坑了，登录页的字体/
   背景绝不能依赖外链)。 */
.auth-hero {
  position: relative;
  padding: 58px 50px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  color: #fff;
  background:
    radial-gradient(circle at 88% 8%, rgba(255,255,255,0.14) 0%, transparent 42%),
    radial-gradient(circle at 6% 96%, var(--auth-accent, var(--primary)) 0%, transparent 46%),
    linear-gradient(150deg, #2a1f6b 0%, #3b2f92 52%, #4c3ab0 100%);
  overflow: hidden;
}
.auth-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255,255,255,0.16) 1px, transparent 1px);
  background-size: 22px 22px;
  opacity: 0.3;
  pointer-events: none;
}
.channel-jcex .auth-hero { --auth-accent: rgba(217,131,42,0.55); }
.channel-qft .auth-hero { --auth-accent: rgba(13,148,136,0.55); }
.channel-jcex-custom .auth-hero { --auth-accent: rgba(47,111,237,0.55); }
.channel-walmart .auth-hero { --auth-accent: rgba(23,160,74,0.55); }

.auth-hero-badge {
  position: relative;
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 25px;
  border-radius: 13px;
  background: rgba(255,255,255,0.14);
  border: 1px solid rgba(255,255,255,0.22);
  margin-bottom: 26px;
}
.auth-hero-headline {
  position: relative;
  margin: 0 0 16px;
}
.auth-hero-headline .line1 {
  display: block;
  font-size: 24px;
  font-weight: 700;
  color: rgba(255,255,255,0.88);
  margin-bottom: 8px;
}
.auth-hero-headline .line2 {
  display: block;
  font-size: 31px;
  font-weight: 800;
  line-height: 1.35;
  background: linear-gradient(90deg, #ffd77a, #ffb454);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.auth-hero-desc {
  position: relative;
  margin: 0 0 28px;
  font-size: 15px;
  line-height: 1.75;
  color: rgba(255,255,255,0.72);
  max-width: 380px;
}
.auth-hero-checklist {
  position: relative;
  list-style: none;
  margin: 0 0 32px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.auth-hero-checklist li {
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 15px;
  color: rgba(255,255,255,0.9);
}
.auth-hero-checklist li::before {
  content: "\2713";
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 800;
  border-radius: 50%;
  background: rgba(255,255,255,0.16);
  color: #ffd77a;
}
.auth-hero .channel-switcher { position: relative; justify-content: flex-start; margin: 0; }
.auth-hero .channel-switcher-btn {
  background: rgba(255,255,255,0.08);
  border-color: rgba(255,255,255,0.16);
  color: rgba(255,255,255,0.72);
}
.auth-hero .channel-switcher-btn:hover { background: rgba(255,255,255,0.16); color: #fff; }
.auth-hero .channel-switcher-btn.active { color: #16193a; }
.auth-hero .channel-switcher-btn.active.jcex { background: var(--warning); }
.auth-hero .channel-switcher-btn.active.qft { background: var(--info); }
.auth-hero .channel-switcher-btn.active.jcex-custom { background: var(--accent); }
.auth-hero .channel-switcher-btn.active.walmart { background: var(--success); }

.auth-box {
  background: #fff;
  padding: 58px 52px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.auth-welcome {
  position: relative;
  font-size: 27px;
  font-weight: 800;
  margin: 0 0 16px;
  padding-bottom: 14px;
  color: var(--text);
}
.auth-welcome::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 38px;
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--primary), var(--accent));
}
.auth-box-sub {
  margin: 0 0 28px;
  font-size: 14.5px;
  color: var(--text-muted);
}
.auth-tabs {
  display: flex;
  margin-bottom: 18px;
  background: var(--bg-page);
  border-radius: 999px;
  padding: 3px;
}
.auth-tab {
  flex: 1;
  padding: 8px;
  border: none;
  background: none;
  cursor: pointer;
  font-size: 14px;
  color: var(--text-muted);
  border-radius: 999px;
  transition: background 0.15s, color 0.15s;
}
.auth-tab.active {
  color: #fff;
  background: var(--primary);
  font-weight: bold;
}
.auth-form label {
  display: block;
  margin: 18px 0 7px;
  color: #555;
  font-size: 14px;
  font-weight: 600;
}
.auth-form label:first-child { margin-top: 0; }
.auth-form input {
  width: 100%;
  padding: 14px 16px;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  font-size: 16px;
  background: #fafafc;
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}
.auth-form input:focus {
  outline: none;
  border-color: var(--primary);
  background: #fff;
  box-shadow: 0 0 0 3px var(--primary-light);
}
/* 输入框带图标：图标绝对定位在左边，输入框自己留出左内边距避开图标；
   密码框右边多一个"显示/隐藏密码"小按钮，同样绝对定位，不占布局空间。 */
.auth-field { position: relative; }
.auth-field input { padding-left: 44px; }
.auth-field-icon {
  position: absolute;
  left: 15px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  color: var(--text-muted);
  pointer-events: none;
}
.auth-field-icon svg { width: 18px; height: 18px; }
.auth-field-toggle {
  position: absolute;
  right: 7px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--text-muted);
  border-radius: 7px;
}
.auth-field-toggle:hover { background: var(--bg-page); color: var(--text); }
.auth-field-toggle svg { width: 19px; height: 19px; }
.auth-field-toggle .icon-eye-off { display: none; }
.auth-field-toggle.is-visible .icon-eye { display: none; }
.auth-field-toggle.is-visible .icon-eye-off { display: block; }
.auth-field-pwd input { padding-right: 42px; }

.auth-form .btn {
  width: 100%;
  margin-top: 28px;
  padding: 15px 18px;
  font-size: 16px;
  border-radius: 10px;
}
.auth-msg { margin-top: 12px; font-size: 13px; color: var(--danger); min-height: 18px; }

/* 卡片是左右分栏，窄屏(手机/小窗口)放不下，堆成上下两栏，左侧品牌区
   自动缩成一条紧凑的顶部横幅，卖点清单收窄到跟标题一样宽。 */
@media (max-width: 760px) {
  .auth-card { grid-template-columns: 1fr; }
  .auth-hero { padding: 34px 30px; }
  .auth-hero-desc { max-width: none; }
  .auth-box { padding: 36px 30px; }
}

/* ---------- 按钮 ---------- */
.btn {
  padding: 7px 16px;
  border: 1px solid var(--border);
  background: #fff;
  border-radius: 7px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
  display: inline-block;
  /* 2026-08-28客户要求给按钮加立体感，但不要太花——统一用"底部一条实色
     阴影"模拟按钮的厚度，点下去(:active)阴影变薄、按钮整体往下挪1px，
     模拟真的被按下去的手感；抬起来(:hover)只是略微提亮，不加额外阴影
     变化，避免动效太多显得花哨。*/
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.10);
  transition: filter 0.1s, background 0.1s, box-shadow 0.08s, transform 0.08s;
}
.btn:hover { background: #f6f6fa; }
.btn:active { transform: translateY(1px); box-shadow: 0 1px 0 rgba(0, 0, 0, 0.10); }
.btn:disabled {
  color: #b7bac2; cursor: not-allowed; background: #f5f5f7; border-color: var(--border);
  box-shadow: none; transform: none;
}

.btn-primary { background: var(--primary); color: #fff; border-color: var(--primary); box-shadow: 0 2px 0 var(--primary-dark); }
.btn-primary:hover { background: var(--primary-dark); }
.btn-primary:active { box-shadow: 0 1px 0 var(--primary-dark); }
.btn-primary:disabled { background: #d3ccf9; border-color: #d3ccf9; color: #fff; }

.btn-success { background: var(--success); color: #fff; border-color: var(--success); box-shadow: 0 2px 0 #0f7a38; }
.btn-success:hover { background: var(--success); filter: brightness(1.08); }
.btn-success:active { box-shadow: 0 1px 0 #0f7a38; }

.btn-warning { background: var(--warning); color: #fff; border-color: var(--warning); box-shadow: 0 2px 0 #a8681f; }
.btn-warning:hover { background: var(--warning); filter: brightness(1.08); }
.btn-warning:active { box-shadow: 0 1px 0 #a8681f; }

.btn-outline { background: #fff; color: var(--primary); border-color: var(--primary); box-shadow: 0 2px 0 var(--primary-light); }
.btn-outline:hover { background: var(--primary-light); }
.btn-outline:active { box-shadow: 0 1px 0 var(--primary-light); }

.btn-small { padding: 5px 12px; font-size: 12px; border-radius: 6px; }

/* ---------- 顶栏/主界面 ---------- */
.topbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  background: #fff;
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(20,20,40,0.03);
}
.compliance-banner {
  background: var(--danger-light);
  color: var(--danger);
  font-size: 12px;
  line-height: 1.6;
  padding: 8px 18px;
  border-bottom: 1px solid var(--border);
  font-weight: 500;
}
/* 2026-08-28客户要求：合规提示不要单独占一整条横幅，挪到topbar里"当前
   账号"那一行，居中显示——用flex:1顶替原来topbar-spacer的位置，既占满
   左右两组按钮之间的剩余空间(文字在这段空间里居中)，又保留了原来spacer
   "把版本号/退出登录推到最右边"的效果，不用额外加spacer元素。 */
.topbar-compliance {
  flex: 1;
  min-width: 0;
  text-align: center;
  color: var(--danger);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.4;
}
/* 2026-09-08新增：原来跟账号/余额/功能按钮挤在顶栏一行的严禁刷单提示，
   挪到页面底部。2026-09-09客户反馈：挪到文档末尾要滚动到底才看得到，
   等于没人会注意——改成position:fixed浮动在视口底部，不管滚动到哪都
   一直看得见；z-index比.modal(100)低，弹窗打开时会盖住它(符合预期，
   弹窗本身内容优先)，比.toast(200)低，toast弹出时也会盖在它上面。 */
.app-footer-compliance {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: block;
  padding: 12px 20px;
  text-align: center;
  color: var(--danger);
  background: var(--danger-light);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.5;
  box-shadow: 0 -2px 10px rgba(20,16,40,0.12);
  z-index: 90;
}
.app-footer-fixed {
  display: contents;
}
.app-footer-fixed > .app-footer-alert-ticker {
  display: none;
}
.app-footer-alert-ticker {
  flex: none;
  overflow: hidden;
  width: 100%;
  color: #8a3b00;
  background: #fff4cf;
  border-bottom: 1px solid #f3c86a;
  font-size: 16px;
  font-weight: 700;
  line-height: 40px;
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(20,16,40,0.08);
}
.app-footer-alert-track {
  display: flex;
  width: max-content;
  will-change: transform;
  animation: app-footer-alert-scroll 48s linear infinite;
}
.app-footer-alert-ticker:hover .app-footer-alert-track {
  animation-play-state: paused;
}
.app-footer-alert-group {
  display: flex;
  flex: none;
}
.app-footer-alert-item {
  display: inline-block;
  padding: 0 44px;
}
.app-footer-alert-item + .app-footer-alert-item::before {
  content: "◆";
  margin-right: 44px;
  color: var(--danger);
}
@keyframes app-footer-alert-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .app-footer-alert-track { animation-duration: 80s; }
}
.notice-banner {
  background: var(--danger-light);
  color: var(--danger);
  font-size: 16px;
  font-weight: 700;
  line-height: 1.6;
  text-align: center;
  padding: 14px 18px;
  border-bottom: 2px solid var(--danger);
}
/* 2026-08-28客户要求：怕用户在佳成物流/速丰捷运两个页面搞混渠道、提交
   错地方，两边各用不同颜色的显眼大字标出"当前渠道"，登录页和主界面都放，
   不用等登录进去才看到。 */
.channel-banner {
  font-size: 22px;
  font-weight: 800;
  text-align: center;
  padding: 10px 18px;
  border-radius: 6px;
  margin: 0 0 10px;
}
.auth-box .channel-banner { margin: 0 0 14px; }
.channel-banner.channel-jcex { background: var(--warning-light); color: var(--warning); border: 2px solid var(--warning); }
.channel-banner.channel-qft { background: var(--info-light); color: var(--info); border: 2px solid var(--info); }
.channel-banner.channel-jcex-custom { background: var(--accent-light); color: var(--accent); border: 2px solid var(--accent); }
.channel-banner.channel-walmart { background: var(--success-light); color: var(--success); border: 2px solid var(--success); }

/* 三渠道居中切换器(2026-08-28新增第三条"佳成定制"通道后，把原来分散在
   topbar角落/登录页小字的"切换到X"链接统一成一个居中的三按钮组，三个
   页面都用同一个组件：当前所在页面对应的按钮做成高亮态、不可点(标出
   "你在这里")，另外两个是可以点击跳转的链接。 */
.channel-switcher {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 0 0 14px;
}
.auth-box .channel-switcher { margin: 0 0 16px; }
.channel-switcher-btn {
  padding: 7px 18px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.channel-switcher-btn:hover { background: var(--bg-page); }
.channel-switcher-btn.active {
  cursor: default;
  color: #fff;
  border-color: transparent;
}
.channel-switcher-btn.active.jcex { background: var(--warning); }
.channel-switcher-btn.active.qft { background: var(--info); }
.channel-switcher-btn.active.jcex-custom { background: var(--accent); }
.channel-switcher-btn.active.walmart { background: var(--success); }
.topbar-item { color: var(--text-muted); font-size: 13px; }
.topbar-item.balance {
  color: var(--primary);
  font-weight: bold;
  background: var(--primary-light);
  padding: 4px 12px;
  border-radius: 999px;
}
.topbar-item.version { color: #c0c2cc; font-size: 12px; }
.topbar-spacer { flex: 1; }

.tabs {
  display: flex;
  gap: 4px;
  padding: 10px 18px 0;
  background: #fff;
  border-bottom: 1px solid var(--border);
}
.tab-btn {
  padding: 9px 20px;
  border: none;
  background: none;
  cursor: pointer;
  font-size: 14px;
  color: var(--text-muted);
  /* 2026-08-29客户反馈"点击标签页出现一个椭圆形状不好看"——找到了，
     这不是焦点框，是选中态(.tab-btn.active)那圈浅色背景本身：之前
     border-radius用的是999px(完全圆角/胶囊形)，配合选中态的背景色，
     视觉上就是一个圆滚滚的椭圆。改成小圆角(6px)，看起来是常规的
     "标签页顶部圆角"效果，不是一整颗胶囊/椭圆。 */
  border-radius: 6px 6px 0 0;
  position: relative;
  top: 1px;
}
/* 2026-08-29客户反馈：点击标签页按钮后上面会出现一圈浏览器默认的
   焦点轮廓(button天生带的，配合这里的圆角样式看起来像一个椭圆)，
   去掉这个默认轮廓，当前选中的标签本来就已经用active那一整套样式
   (背景色+底部色条)清楚标出来了，不需要再叠一层浏览器焦点框。
   单加outline:none在有的浏览器/情况下还不够干净——Firefox对button
   有一层独立的内层虚线焦点框(::-moz-focus-inner)，不受outline控制，
   得单独清掉；这里outline/box-shadow/moz-focus-inner一起处理，
   :focus和:focus-visible都覆盖，避免只改对一部分场景。 */
.tab-btn:focus,
.tab-btn:focus-visible {
  outline: none;
  box-shadow: none;
}
.tab-btn::-moz-focus-inner {
  border: 0;
  padding: 0;
}
.tab-btn.active {
  color: var(--primary);
  font-weight: bold;
  background: var(--primary-light);
  border-bottom: 2px solid var(--primary);
}

.tab-panel { padding: 16px; }

.toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 12px;
  background: #fff;
  padding: 12px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}
.toolbar select, .search-row select, .pagination-row select {
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
  background: #fafafc;
  color: var(--text);
}
.toolbar select:focus, .pagination-row select:focus { outline: none; border-color: var(--primary); }
.toolbar input[type="date"], .toolbar input.time-part {
  padding: 7px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
  background: #fafafc;
  color: var(--text);
}
.toolbar input[type="date"]:focus, .toolbar input.time-part:focus {
  outline: none;
  border-color: var(--primary);
}
/* 时/分/秒用type=number而不是datetime-local的内置时间子控件：后者鼠标
   滚轮在时/分/秒格子上会各自无限循环(59再往下滚回00转圈)，前者原生就会
   在min/max边界处停住，不会绕回去，更符合直觉。 */
.toolbar input.time-part { width: 60px; text-align: center; font-size: 15px; padding: 7px 4px; }
.toolbar .time-sep { color: var(--text-muted); margin: 0 -4px; }
.search-row {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  margin-bottom: 12px;
  background: #fff;
  padding: 12px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  flex-wrap: wrap;
}
.search-row textarea {
  width: 320px;
  font-family: inherit;
  font-size: 13px;
  padding: 7px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  resize: vertical;
}
.search-row textarea:focus { outline: none; border-color: var(--primary); }
.inline-label { color: #555; font-size: 13px; }
.summary-label { color: var(--text-muted); font-size: 12px; margin-left: auto; }
.pagination-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 10px 0 2px;
}
.pagination-row button:disabled { opacity: 0.5; cursor: not-allowed; }

/* ---------- 表格 ---------- */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #fff;
  max-height: 68vh;
  overflow-y: auto;
}
table { border-collapse: collapse; width: 100%; font-size: 13px; }
thead th {
  position: sticky;
  top: 0;
  background: #f7f7fb;
  color: var(--text-muted);
  font-weight: 600;
  text-align: center;
  padding: 10px 8px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
tbody td {
  padding: 9px 8px;
  border-bottom: 1px solid #f1f1f5;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 260px;
}
tbody td.left { text-align: left; }
tbody tr:hover { background: #fafaff; }
tbody tr.row-bad td { color: var(--danger); }
tbody tr.row-selected { background: var(--primary-light); }
tbody td.editable-cell { cursor: pointer; border-bottom-style: dashed; border-bottom-color: var(--border); }
tbody td.editable-cell:hover { background: var(--primary-light); }
#walmartOrderTable {
  width: 100%;
  min-width: 0;
  table-layout: fixed;
  font-size: 12px;
}
#walmartOrderTable th:nth-child(1) { width: 4%; }
#walmartOrderTable th:nth-child(2) { width: 8.5%; }
#walmartOrderTable th:nth-child(3) { width: 6.5%; }
#walmartOrderTable th:nth-child(4) { width: 8.5%; }
#walmartOrderTable th:nth-child(5) { width: 6%; }
#walmartOrderTable th:nth-child(6) { width: 5.5%; }
#walmartOrderTable th:nth-child(7) { width: 4.5%; }
#walmartOrderTable th:nth-child(8) { width: 10%; }
#walmartOrderTable th:nth-child(9) { width: 7.5%; }
#walmartOrderTable th:nth-child(10) { width: 7%; }
#walmartOrderTable th:nth-child(11) { width: 9%; }
#walmartOrderTable th:nth-child(12) { width: 6%; }
#walmartOrderTable th:nth-child(13) { width: 9%; }
#walmartOrderTable th:nth-child(14) { width: 8%; }
#walmartOrderTable thead th,
#walmartOrderTable tbody td {
  max-width: none;
  padding: 6px 3px;
  overflow: hidden;
  text-overflow: ellipsis;
}
#walmartOrderTable .btn-small { padding: 4px 7px; font-size: 11px; }
#walmartOrderTable .editable-cell { min-width: 0; }
.walmart-order-table-wrap { overflow-x: hidden; }
#walmartOrderTable .badge {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
}
#walmartOrderTable .walmart-example-body td {
  background: #fff9df;
  color: #806100;
  font-size: 12px;
  border-bottom: 1px solid #eadb9e;
}
#walmartOrderTable .walmart-order-seq {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
#walmartOrderTable .walmart-cell-error {
  color: var(--danger);
  background: #fff4f4;
}
.walmart-buyer-modal-box { max-height: 88vh; overflow-y: auto; }
.walmart-order-global-search {
  margin-left: auto;
  width: 270px;
  min-width: 190px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fafafc;
  color: var(--text);
  font-size: 13px;
}
.walmart-order-global-search:focus { outline: none; border-color: var(--primary); background: #fff; }
.walmart-api-key-help {
  margin: 10px 0 12px;
  padding: 10px 12px;
  border: 1px solid #d9cdfd;
  border-radius: 8px;
  background: #f8f5ff;
  color: #4b3a78;
  font-size: 13px;
  line-height: 1.65;
}
.walmart-api-key-help p { margin: 4px 0 0; }
.walmart-buyer-detail-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px 14px;
  margin-top: 14px;
}
.walmart-buyer-detail-item {
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 8px 10px;
  min-width: 0;
}
.walmart-buyer-detail-item.wide { grid-column: 1 / -1; }
.walmart-buyer-detail-label { color: var(--text-muted); font-size: 12px; margin-bottom: 3px; }
.walmart-buyer-detail-value { white-space: normal; word-break: break-word; }
tbody td.trace-cell {
  text-align: left;
  /* 2026-08-29客户要求"物流轨迹列宽度再增加三分之一"：这一列真正控制
     宽度的是这里的max-width(表头<th>没有单独设宽度，是靠这个类撑开的)。
     480px按三分之一涨到640px。 */
  max-width: 640px;
  white-space: normal;
}
/* 2026-08-29：之前直接把display:flex写在<td class="trace-cell">上，
   佳成物流页面表现为"轨迹列跟备注列没黏一起、整行断开"，把<th>上冲突的
   min-width去掉后当时看着好了，但速丰捷运页面清缓存重刷后同样的断行
   问题依然存在——根因其实是display:flex直接加在<td>上这件事本身：不同
   浏览器对"表格单元格被设成flex"这种混合布局的行高/边框计算处理不一致，
   会导致这一行跟正常单元格的边框对不上，具体哪页哪行更明显还跟内容长度
   有关，不是靠调宽度能稳定解决的。现在把<td>本身改回普通table-cell(不再
   直接扣display:flex)，flex布局改到内部这个.trace-inner包裹层上，
   彻底避开这个浏览器兼容性坑，三个页面共用同一个类，一次改全部生效。 */
tbody td.trace-cell .trace-inner {
  display: flex;
  align-items: flex-start;
  gap: 6px;
}
tbody td.trace-cell .btn { flex-shrink: 0; }
tbody td.trace-cell span {
  white-space: normal;
  word-break: break-word;
}
.inline-edit-input {
  width: 100%;
  padding: 4px 6px;
  border: 1px solid var(--primary);
  border-radius: 5px;
  font-size: 13px;
  text-align: center;
  background: #fff;
}
.inline-edit-input:focus { outline: none; }

/* ---------- 状态徽标(圆角小标签，跟画风一致的地方) ---------- */
.badge {
  display: inline-block;
  padding: 3px 11px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.badge-success { background: var(--success-light); color: var(--success); }
.badge-info { background: var(--info-light); color: var(--info); }
.badge-warning { background: var(--warning-light); color: var(--warning); }
.badge-danger { background: var(--danger-light); color: var(--danger); }
.badge-pending { background: var(--pending-light); color: var(--pending); }
.badge-muted { background: #f1f1f5; color: var(--text-muted); }

/* ---------- 弹窗 ---------- */
.modal {
  position: fixed;
  inset: 0;
  background: rgba(20,16,40,0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}
.modal-box {
  background: #fff;
  padding: 22px 26px;
  border-radius: 14px;
  width: 320px;
  box-shadow: 0 12px 40px rgba(20,16,40,0.18);
}
.modal-box.account-result-box { width: min(440px, 92vw); }
.modal-box h2 { margin: 0 0 8px; font-size: 16px; }
.modal-box .hint { color: var(--text-muted); font-size: 12px; margin: 0 0 12px; }
.signoff-count-highlight {
  color: #dc2626;
  font-weight: 800;
  font-size: 20px;
  line-height: 1.3;
}
.modal-box label { display: block; margin: 8px 0 4px; font-size: 13px; color: #555; }
.modal-box input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  background: #fafafc;
}
.modal-box input:focus { outline: none; border-color: var(--primary); background: #fff; }
.modal-box .copy-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}
.modal-box .copy-row input {
  flex: 1;
  min-width: 0;
  width: auto;
}
.modal-box .copy-row .btn {
  flex: 0 0 auto;
}
/* 2026-08-29新增签收模式选择弹窗用了radio——.modal-box input默认给所有
   input都设了width:100%+padding，是给文本框准备的，单选框套上这套样式
   会被拉伸变形、把后面的文字挤到换行，两个选项看着高低不齐。这里单独
   把radio/checkbox摘出来用原生大小，label也改成横向对齐，单选框和文字
   在同一行、两个选项左边缘对齐。 */
.modal-box input[type="radio"],
.modal-box input[type="checkbox"] {
  width: auto;
  padding: 0;
  background: none;
  border: none;
}
.modal-box label:has(input[type="radio"]),
.modal-box label:has(input[type="checkbox"]) {
  display: flex;
  align-items: center;
  gap: 6px;
}
.modal-status { min-height: 18px; font-size: 12px; color: var(--warning); margin-top: 8px; white-space: pre-line; }
.modal-actions { display: flex; gap: 8px; margin-top: 14px; }
.modal-actions .btn { flex: 1; }

.modal-box-wide { width: min(900px, 92vw); }
.admin-center-modal-box {
  width: min(1800px, 96vw);
  max-height: 92vh;
  overflow: auto;
  padding: 24px 28px;
}
.modal-header-row { display: flex; align-items: center; gap: 8px; }
.modal-header-row h2 { flex: 1; margin: 0; }
.modal-table-wrap { max-height: 60vh; margin-top: 10px; }

/* 充值流水：四块模块同一套两列网格，左右外沿对齐。 */
.recharge-ledger-modal-box {
  width: calc(100vw - 16px) !important;
  max-width: none;
  height: 94vh;
  max-height: 94vh;
  padding: 14px 16px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: auto minmax(140px, 28vh) minmax(0, 1fr);
  gap: 10px 12px;
  overflow: hidden;
}
.recharge-ledger-modal-box > .modal-header-row {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
}
.recharge-ledger-modal-box > .modal-header-row h2 {
  flex: none;
  white-space: nowrap;
  margin: 0;
}
.recharge-ledger-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  justify-content: flex-end;
}
.recharge-ledger-top,
.recharge-ledger-body {
  display: contents;
}
.recharge-ledger-col-head {
  min-height: 58px;
  flex-shrink: 0;
}
.recharge-ledger-modal-box .recharge-ledger-col-head .hint {
  font-size: 11px;
}
.recharge-ledger-col {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.recharge-ledger-modal-box .modal-section-title {
  margin: 0;
  padding: 0;
  border: none;
  height: 24px;
  line-height: 24px;
  flex-shrink: 0;
}
.recharge-ledger-modal-box .hint {
  margin: 2px 0 0;
  line-height: 1.35;
  flex-shrink: 0;
}
.recharge-fund-cards {
  display: flex;
  justify-content: center;
  align-items: stretch;
  gap: 8px;
  width: auto;
  min-width: 0;
  margin: 0;
}
.recharge-fund-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 4px 12px;
  font-size: 12px;
  color: var(--text-muted);
  text-align: center;
  background: var(--surface, #fff);
  min-width: 108px;
  flex: 1 1 0;
  max-width: 180px;
}
.recharge-fund-card strong {
  display: block;
  margin-top: 2px;
  font-size: 18px;
  line-height: 1.2;
  color: var(--text);
}
.recharge-fund-card-balance {
  border-color: rgba(22, 163, 74, 0.35);
  background: rgba(22, 163, 74, 0.06);
}
.recharge-fund-card-balance strong { color: #16a34a; }
#rechargeFundModal { z-index: 130; }
#rechargeFundModal select {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  background: #fafafc;
}
.recharge-ledger-modal-box .table-wrap {
  overflow-x: hidden;
  overflow-y: auto;
}
.recharge-ledger-modal-box .recharge-ledger-operator-wrap,
.recharge-ledger-modal-box .recharge-fund-wrap,
.recharge-ledger-modal-box .recharge-ledger-daily-wrap,
.recharge-ledger-modal-box .recharge-ledger-detail-wrap {
  flex: 1;
  min-height: 0;
  max-height: none;
  margin-top: 6px;
}
.recharge-fund-income { color: #16a34a; }
.recharge-fund-expense { color: #dc2626; }
.recharge-ledger-modal-box table {
  width: 100%;
  table-layout: fixed;
  font-size: 12px;
}
.recharge-ledger-modal-box thead th,
.recharge-ledger-modal-box tbody td {
  padding: 5px 3px;
  max-width: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.recharge-ledger-modal-box .recharge-ledger-daily-wrap table { font-size: 11px; }
.recharge-ledger-modal-box .recharge-ledger-daily-wrap th,
.recharge-ledger-modal-box .recharge-ledger-daily-wrap td {
  padding: 4px 2px;
}
.recharge-ledger-modal-box .recharge-ledger-daily-wrap th:first-child,
.recharge-ledger-modal-box .recharge-ledger-daily-wrap td:first-child {
  width: 108px;
}
.recharge-ledger-modal-box .recharge-ledger-daily-wrap th:last-child,
.recharge-ledger-modal-box .recharge-ledger-daily-wrap td:last-child {
  width: 40px;
}
.recharge-ledger-modal-box .recharge-ledger-detail-wrap th:first-child,
.recharge-ledger-modal-box .recharge-ledger-detail-wrap td:first-child {
  width: 148px;
}
.recharge-ledger-modal-box .recharge-daily-settled td {
  background: rgba(22, 163, 74, 0.12);
}
.recharge-ledger-modal-box .recharge-daily-settle {
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: #16a34a;
  cursor: pointer;
}
.recharge-ledger-modal-box .recharge-daily-settle:disabled {
  cursor: default;
  opacity: 1;
}
.recharge-ledger-modal-box .recharge-ledger-detail-wrap td:last-child {
  white-space: normal;
  word-break: break-all;
}

@media (max-width: 1100px) {
  .recharge-ledger-modal-box {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    max-height: 92vh;
    overflow: auto;
  }
  .recharge-ledger-top,
  .recharge-ledger-body {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
}

#authorizedRechargeModal .modal-box {
  width: min(560px, 94vw);
}
#authorizedRechargeModal .authorized-recharge-kinds {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 18px;
  margin: 6px 0 10px;
}
#authorizedRechargeModal .authorized-recharge-kinds label {
  margin: 0;
}
#authorizedRechargeModal input[type="text"],
#authorizedRechargeModal input[type="number"] {
  width: 100%;
  margin-top: 5px;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 8px;
  background: var(--surface);
  color: var(--text);
  box-sizing: border-box;
}
.authorized-recharge-records { margin-top: 12px; font-size: 12px; }
.authorized-recharge-record-list {
  max-height: 240px;
  overflow-y: auto;
  margin-top: 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 8px;
  color: var(--muted);
}
.authorized-recharge-record {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  padding: 5px 0;
  border-bottom: 1px solid var(--border);
}
.authorized-recharge-record:last-child { border-bottom: 0; }
.authorized-recharge-record b { color: var(--text); }
.admin-dashboard-content { margin-top: 10px; }
.admin-dashboard-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin: 14px 0; }
.admin-dashboard-card { border: 1px solid var(--border); border-radius: 10px; padding: 16px; background: var(--surface); min-width: 0; }
.admin-dashboard-card h3 { margin: 0 0 10px; font-size: 15px; }
.admin-dashboard-card pre { margin: 0 0 8px; white-space: pre-wrap; word-break: break-word; font: 13px/1.65 inherit; color: var(--text); }
.admin-dashboard-card table { font-size: 13px; }
@media (max-width: 900px) { .admin-dashboard-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .admin-dashboard-grid { grid-template-columns: 1fr; } }

/* 2026-09-03新增：这条规则原来只在dock.css里(对接端"其它设置"弹窗拆分
   两段用)，客户网页端新增"管理中心"弹窗(管理的用户/仪表盘两段)也要用
   同样的分段小标题，直接照抄一份过来，跟dock.css那条保持一致。 */
.modal-section-title {
  margin: 16px 0 6px;
  font-size: 13px;
  color: var(--text-muted);
  border-top: 1px solid var(--border);
  padding-top: 12px;
}
.modal-box .modal-section-title:first-of-type { border-top: none; padding-top: 0; }

/* ---------- toast ---------- */
.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: #2b2b38;
  color: #fff;
  padding: 10px 20px;
  border-radius: 999px;
  font-size: 13px;
  max-width: 80vw;
  z-index: 200;
  box-shadow: 0 6px 20px rgba(0,0,0,0.2);
}
.toast.error { background: var(--danger); }
.toast.success { background: var(--success); }

/* ---------- 手机端轻量适配(2026-09-04新增) ----------
   客户要求先只保证基础的查询/转账/查看在手机上能正常用，不追求跟桌面端
   完全一致的信息密度——批量导入表格、逐格双击编辑这类工作流本来就是给
   电脑端用的，手机上进得去、不错位、不用横向滑动整个页面就够了，没有
   照搬桌面版整套工具栏去改。表格本身列多(8~13列)不硬塞成手机卡片布局，
   靠原有.table-wrap的overflow-x:auto在表格自己的框里左右滑动，跟桌面端
   逻辑一致，改动量最小。
   登录页(.auth-card/.auth-form)之前已经有一版760px的响应式，这里不重复
   处理。 */
@media (max-width: 640px) {
  /* topbar塞了"账号/余额/积分互转/充值记录/修改密码/合规提示/版本号/
     退出登录"一整排，桌面端够宽不会挤，手机上原来是不换行的
     (display:flex没设wrap)，窄屏会被压变形甚至横向溢出——这里允许换行，
     且合规提示单独占一整行(flex-basis:100%)，不然它自己flex:1会在按钮
     缝隙里挤成又窄又高的一条，中文标点全部竖排着挤在一起不可读。 */
  .topbar { flex-wrap: wrap; row-gap: 8px; }
  .topbar-compliance { flex-basis: 100%; order: 5; }
  .app-topbar { padding: 10px 14px; }

  .toolbar, .search-row { padding: 10px; gap: 6px; }
  /* 搜索框原来固定320px宽，比不少手机屏幕(比如320px宽的机型)还宽，
     虽然外层.search-row已经flex-wrap，固定宽度的子项本身还是会把这一整行
     撑宽，导致整个页面出现横向滚动条(不止这一个框能滑，是整页跟着滑)。 */
  .search-row textarea { width: 100%; }
  /* iOS Safari对<16px的输入框会在聚焦时自动放大整个页面(误以为字太小
     看不清)，用户点一下搜索框/弹窗输入框页面突然放大、还得自己手动缩小，
     体验很怪——这里统一兜底成16px消除这个自动放大，不是单纯为了好看。 */
  .toolbar select, .search-row select, .pagination-row select,
  .toolbar input[type="date"], .toolbar input.time-part, .search-row textarea,
  .modal-box input, .modal-box select {
    font-size: 16px;
  }
  .toolbar input.time-part { width: 46px; }
  .walmart-order-global-search { width: 100%; margin-left: 0; font-size: 16px; }

  /* 弹窗(积分互转/修改密码等)原来固定320px——大多数手机够放，极少数
     320px宽的老机型贴着边缘会溢出，加个92vw兜底；宽版弹窗(充值记录/
     管理中心)原来是min(900px,92vw)，手机上900px这个上限没意义，改成
     几乎贴满屏幕更好用。 */
  .modal-box { width: min(320px, 92vw); padding: 20px; }
  .modal-box-wide { width: min(100%, 96vw); }

  /* 按钮原来7px上下内边距，手指点击稍显局促，手机上加大一点更好点中。 */
  .btn { padding: 9px 14px; }
}
.legacy-jcex-nav {
  display: none !important;
}
