* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, "PingFang SC", sans-serif; background: #f5f5f5; color: #333; font-size: 14px; }
.hidden { display: none !important; }
.view { min-height: 100vh; }
.login-card { max-width: 360px; margin: 15vh auto; background: #fff; border-radius: 12px; padding: 24px; box-shadow: 0 1px 4px rgba(0,0,0,0.05); }
.login-card h1 { font-size: 22px; text-align: center; margin-bottom: 6px; }
.sub { color: #999; font-size: 13px; text-align: center; margin-bottom: 16px; }
label { display: block; margin-bottom: 12px; font-size: 13px; color: #666; }
input { width: 100%; margin-top: 6px; padding: 10px 12px; border: 1px solid #ddd; border-radius: 8px; font-size: 16px; }
.btn { background: #e8657f; color: #fff; border: 0; border-radius: 8px; padding: 10px 18px; font-size: 14px; cursor: pointer; }
.btn-plain { background: none; border: 0; color: #e8657f; cursor: pointer; font-size: 13px; padding: 4px 8px; }
.err { color: #e64340; font-size: 13px; margin-top: 10px; min-height: 18px; }
#view-main { display: flex; }
.side { width: 200px; background: #fff; border-right: 1px solid #eee; min-height: 100vh; padding: 16px 0; flex-shrink: 0; }
.brand { font-weight: 700; font-size: 16px; padding: 8px 20px 20px; color: #e8657f; }
.side nav a { display: block; padding: 12px 20px; color: #555; cursor: pointer; text-decoration: none; }
.side nav a.on { background: #fdf0f3; color: #e8657f; font-weight: 600; }
.main { flex: 1; padding: 20px; overflow-x: auto; }
.head { justify-content: space-between; margin-bottom: 16px; }
h2 { font-size: 18px; }
.row { display: flex; align-items: center; gap: 8px; }
table { width: 100%; border-collapse: collapse; background: #fff; border-radius: 12px; overflow: hidden; box-shadow: 0 1px 4px rgba(0,0,0,0.05); }
th, td { padding: 10px 12px; border-bottom: 1px solid #f0f0f0; text-align: left; vertical-align: top; }
th { background: #fafafa; color: #666; font-weight: 500; font-size: 13px; }
.meta { color: #999; font-size: 12px; }
.empty { text-align: center; color: #aaa; padding: 60px 0; }
.badge { font-size: 11px; padding: 2px 8px; border-radius: 10px; background: #eee; color: #666; }
.badge.open { background: #e8f5e9; color: #2e7d32; }
.badge.locked { background: #f5f5f5; color: #999; }
.topbar { display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: #fff; font-weight: 600; }
.card { background: #fff; border-radius: 12px; padding: 16px; margin-bottom: 12px; box-shadow: 0 1px 4px rgba(0,0,0,0.05); }
/* 触控设备(平板/手机手指操作)加大触控目标; pointer:coarse 不命中桌面鼠标, 不破坏桌面观感 */
@media (pointer: coarse) {
  .btn { min-height: 44px; padding: 12px 20px; }
  .btn-plain { padding: 10px 12px; }
  .side nav a { padding: 14px 20px; }
}
@media (max-width: 720px) {
  #view-main { flex-direction: column; }
  .side { width: 100%; min-height: auto; border-right: 0; border-bottom: 1px solid #eee; }
  .side nav { display: flex; overflow-x: auto; }
  .side nav a { white-space: nowrap; }
  .main { padding: 12px; }
  .login-card { margin-left: 12px; margin-right: 12px; }
}
.pick-row { justify-content: flex-start; padding: 6px 0; border-bottom: 1px solid #f5f5f5; }
.pick-row label { display: flex; align-items: center; gap: 8px; flex: 1; margin: 0; font-size: 14px; color: #333; }
.pick-row input[type="checkbox"] { width: auto; margin: 0; }
.pick-row .byhand-label { flex: 0 0 auto; margin: 0 4px 0 8px; gap: 4px; font-size: 12px; color: #666; }
.pick-row .byhand-label input[type="checkbox"] { width: auto; margin: 0; }
.price-input { width: 90px; padding: 6px 8px; border: 1px solid #ddd; border-radius: 6px; font-size: 13px; margin: 0; }
/* 批量选款/搭配组/异常阈值 */
textarea { width: 100%; margin: 8px 0; padding: 10px 12px; border: 1px solid #ddd; border-radius: 8px; font-size: 14px; min-height: 80px; resize: vertical; font-family: inherit; }
.actions { margin: 8px 0; flex-wrap: wrap; }
#batch-file { width: auto; margin: 0; padding: 6px; font-size: 13px; }
.short-input { width: 140px; margin: 0; }
.combo-row { flex-wrap: wrap; padding: 6px 0; border-bottom: 1px solid #f5f5f5; }
.combo-sort-input { width: 70px; padding: 4px 6px; border: 1px solid #ddd; border-radius: 6px; font-size: 13px; margin: 0; }
.btn-plain.danger { color: #e64340; }
.group { border-left: 4px solid #e8657f; }
.order { border-top: 1px solid #f0f0f0; padding-top: 8px; margin-top: 8px; }
.order.cancelled { opacity: 0.5; }
.line { color: #666; font-size: 13px; margin: 4px 0; }
.badge.submitted { background: #fff3e0; color: #e65100; }
.badge.confirmed { background: #e8f5e9; color: #2e7d32; }
.badge.cancelled { background: #f5f5f5; color: #999; }
/* 已退回(2026-09-29, 线下订单那一格加的)。⚠️ 原先这五档徽章里**没有 rejected** ——
   少了这条的话「已退回」是一个默认灰底徽章, 与「已取消」长得**一模一样**, 而两者要人做的事
   完全不同(一个等客户改单重提, 一个是终态)。红色与 .err 同源: 这一档是要有人去处理的。 */
.badge.rejected { background: #fdecea; color: #b91c1c; }
/* 已发货(2026-10-01 发货回传, 线下订单那一格加的)。蓝色与代理端 .badge.shipped 同一对值 ——
   "在路上"这一档在两端要是同一个颜色, 运营和代理对同一张单说的才是同一种话。 */
.badge.shipped { background: #e0f2fe; color: #0369a1; }
/* 发货中(2026-10-06)。与代理端 .badge.shipping 逐字同一对值, 理由同上。
   ⚠️ 不给它底色的话它会落进 .badge 默认浅灰 = 「已取消」那一档的颜色。 */
.badge.shipping { background: #f0f9ff; color: #0369a1; }
h3 { font-size: 15px; }

/* ==================== 补货模块（代理管理 + 补货上架） ====================
   2026-09-24 从 web/replenish/admin.css 里**只把本页没有的那些**并进来 —— 就是搬过来的那两格
   用到的类。品牌方后台已有的同名类一律不动: 动手前先按类名逐个 grep 过, 这一段里除了 .view,
   其它类名在本文件里**一个都没有过**(.msg/.hint/.tbl/.link 全是新增), 所以不存在"谁覆盖谁"。

   ⚠️ 下面几条**不是**可有可无的装饰: 本页有两条全局**元素**规则与搬过来的那套版式是冲突的 ——
      `label { display: block; margin-bottom: 12px }` 与 `input { width: 100%; margin-top: 6px }`
      (它们服务的是登录/新建场次那种"标签在上、控件在下"的纵向表单)。
      这里每条规则都带类名 ⇒ 优先级天然盖得住, **不依赖书写顺序** —— 所以它们放在哪儿都行。
   （原文件里的 `.view.active > * + *` 没有搬: 那是给"一个 view 里多张 card"补间距的,
     本页每一格(pane)里的 card 自带 margin-bottom: 12px(见上面 .card), 再来一条会重复。） */
/* ⚠️ 这几条**必须限定在 #pane-replenish 里**, 不能光写 .filters ——
   web/admin/analytics.html 也加载 admin.css, 而它顶栏那个筛选条**同样叫 .filters**
   (那条归 analytics.css 管: margin-left:auto / gap:12px / 里面的 .f-label)。
   光写 .filters 的话两页会互相牵动: 特别是下面那条 `.filters select`, 会把分析页三个下拉的
   padding/border 改掉, 还带一个 `font: inherit`(连浏览器给 <select> 的默认字体都换掉)。
   加 `#pane-replenish` 前缀就彻底隔开了 —— 这个 id 只存在于 /admin/ 这张页面上。
   (2026-09-24 动手前 grep 过 admin.css 里的类名, 但**没 grep 同目录的 analytics.css** ——
    那条 .filters 是在那儿发现的; 教训: "同名类先比对"要比对的是**同一个页面加载的全部 css**。) */
#pane-replenish .filters { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
/* 筛选行要的是「标签在左、控件在右」的一行一组 —— 与本页 label 的默认纵向排布相反,
   所以这三组得显式横过来, 并把 label 自己的下边距去掉。 */
#pane-replenish .filters label { display: flex; flex-direction: row; align-items: center; gap: 6px; margin: 0; font-size: 13px; }
/* width/margin 显式写回: 本页全局那条 `input { width:100%; margin-top:6px }` 用在横向筛选行里
   会把每个输入框撑满一整行、还各往下错 6px,"三个筛选项并排"当场就没了。 */
#pane-replenish .filters input, #pane-replenish .filters select { width: auto; margin: 0; padding: 6px 8px; border: 1px solid #d1d5db; border-radius: 6px; font: inherit; font-size: 13px; background: #fff; }
/* 类目是**只读**的(补货只做童鞋) —— 灰底是给操作员的"这个改不了"的视觉信号 */
#pane-replenish .filters input[readonly] { background: #f3f4f6; color: #6b7280; }
#pane-replenish .filters-note { font-size: 12px; color: #9ca3af; }
/* 新建代理那张卡里的横向表单: 一行放不下就换行(窄屏 / 浏览器放大到 200%),
   按钮与输入框**底对齐** —— 默认的 center 会让它浮在标签文字中间, 看着像跟哪个字段都不挨着。
   (label 的 margin-bottom 与 input 的 width/margin-top 同 .filters 那条的理由: 把全局的纵向表单样式收掉。) */
.new-agent .row { flex-wrap: wrap; align-items: flex-end; }
.new-agent label { margin-bottom: 0; }
.new-agent input, .new-agent select { width: auto; margin-top: 0; }
/* 表格: 搬过来的那两张表带 class="tbl"。上面那条全局 `table`(阴影/圆角/overflow) 仍会生效 ——
   它按标签选; 这里补的是"有边框、单元格有分隔线"的另一种版式, 与场次那张无边框表各自独立。 */
.tbl { width: 100%; border-collapse: collapse; background: #fff; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; }
.tbl th, .tbl td { padding: 10px 12px; border-bottom: 1px solid #f0f1f3; text-align: left; }
.tbl th { background: #fafbfc; font-weight: 600; font-size: 13px; }
/* 行内输入框(代理表里的折扣率/收货地址)：宽度交回给 HTML 上的 size, 别撑满整格 ——
   同上, 是本页那条全局 `input { width:100%; margin-top:6px }` 的锅: 它在表格里会把
   「折扣率」撑成几百像素宽、把「收货地址」撑成一大条, 一列一个巨无霸。
   (2026-09-24 真 Edge 截图里实测到的, 假 DOM 验不出来 —— 它不管版式。) */
.tbl input, .tbl select { width: auto; margin-top: 0; }
.hint { margin: 0 0 10px; color: #4b5563; font-size: 13px; }
/* 行内按钮（代理表里的「保存」「改密码」）: 无框灰字。
   本页原先只有 .btn / .btn-plain 两种按钮, 缺了这条就是一个浏览器默认样式的灰按钮。 */
.link { border: 0; background: none; color: #6b7280; cursor: pointer; font: inherit; }
/* ⭐ 2026-10-07 缩小（用户：「代理管理那里一条代理那个占的框太大了…一条条小一点。因为我明天要见很多代理」）。
   ⚠️ 从 90px 缩到 56px，但**真正让行变矮的是那个 display**：
      原来是 `display: block` ⇒ 码独占一行、三颗按钮被挤到**下一行** ⇒ 一格 ~120px。
      改成 `inline-block` + `vertical-align: middle` ⇒ 码和按钮**同一行**，一格掉到 ~60px（砍一半）。
   ⚠️ 56 这个数是**留了"当场扫"的余地**：手机凑近还能扫出来。用户要是只靠「下载码」发人、
      不需要转屏给代理扫，可以再小（40 左右）—— 但那就扫不动了，是一条**取舍**，别默默改。
   ⚠️ 加了浅边框：缩到 56 之后没边框的码在白底上会"飘"。 */
.qr { width: 24px; height: 24px; display: inline-block; vertical-align: middle; border: 1px solid #eef0f2; border-radius: 4px; cursor: zoom-in; }
/* 码取不到时的占位(见 replenish.js 的 loadCodes): 灰底虚线框 + "码取不到", 原因挂在 title 上。
   它是一个 <span> 而**不是** <img> —— 没有 src 的 <img> 在 Chromium 里会画一个破图小图标,
   看的人分不清是没配好还是网断了。尺寸写全, 不依赖 .qr(那个是给真图片用的)。
   ⚠️ 与 .qr 同尺寸、同 display: 两态**换来换去不能改变行高**，否则"码取不到"的那一行会突然变高。 */
.qr-fail { width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; border: 1px dashed #d1d5db; border-radius: 4px; background: #f3f4f6; color: #6b7280; font-size: 8px; line-height: 1.15; text-align: center; }

/* ⭐ 操作那一格**不许换行**（2026-10-07）。
   ⚠️ 这是"行变矮"的**真正机关**：那一格实测只有 141px 宽，而「40 的码 + 下载码/保存/改密码」
   要 ~160px ⇒ 不禁换行的话后两颗按钮会折到第二行，行高立刻从 ~55 涨到 ~97（真浏览器量出来的数）。
   禁掉之后，表格会**给它让宽**（宁可挤别的列），而不是让它折行。
   ⚠️ 代价要认：整张表因此更宽，窄屏上会横向滚动。这一页本来就是店里的电脑在看，划算。 */
.ops { white-space: nowrap; }
/* ⭐ 按钮**包成一个固定宽的块**（2026-10-07，这条是让行真正变矮的机关）。
   ⚠️ 为什么不能就让三颗按钮平铺在码右边：那一格**实测只有 141px 宽**，而
      「40 的码 + 下载码/保存/改密码」要 ~160px ⇒ 后两颗折到第二行 ⇒ 行高 97px（真浏览器量出来的）。
   ⚠️ 试过 `nowrap` 逼表格让宽 —— **不行，而且更坏**：表格被撑到 1040px 之后，别的列反过来
      被挤折行，行高**涨到 101**，还顺带把「客户折扣」那条 e2e 弄挂了。
   ⇒ 正解是**让按钮自己折成两行、并钉死宽度**：块宽 78px 刚好放下「下载码 保存」，
      「改密码」落第二行 ⇒ 块高 = 两行 ≈ 40px ≈ 码高 ⇒ **一格 ~53px**，且那格不需要变宽。
   ⚠️ 78 这个数是按当前三个按钮的字宽配的。**改按钮文字就要回来重量**（见 e2e 里那条"行要矮"）。 */
.ops-btns { display: inline-block; vertical-align: middle; white-space: nowrap; }
.ops-btns .link { padding: 0; margin: 0 5px 0 0; line-height: 1.5; }
/* ⭐ 代理名**不许折行**（2026-10-07）。名字一折，「天津市代理张倩」占三行 ⇒ 它就成了**新的行高瓶颈**
   （量出来：码那格已经是 48px 了，行还是 69px —— 撑高的是名字）。
   ⚠️ 代价：这一列变宽 ⇒ 整张表更宽。实测表宽从 1040 到 ~1130，仍在 1280 屏的版心里（左侧栏 200）。
   窄屏/放大时会横向滚动 —— 与 .ops 那条同一个取舍：这一页是店里的电脑在看。 */
.agent-name { white-space: nowrap; }
/* ⭐ 「序号」列（2026-10-08）。用户原话：「代理这里也弄个序列号嘛，**我好知道有多少个了**」
   ⇒ 它的用途就是**最后一行那个数字 = 代理总数**，所以必须一眼扫得到。
   ⚠️ 但**不许抢**代理编号的注意力：灰、等宽数字、右对齐。
   ⚠️ `tabular-nums` 不能省：默认比例数字下 1 和 11 宽度不同，那一列看着参差。
   ⚠️ 用 `#pane-agents` 限定（与上面 .off 那几条同款）：/admin/analytics.html 也加载本文件，
      一个叫 `.sn` 的裸类名迟早撞上（那个文件顶上就有一条一模一样的告诫）。 */
#pane-agents .sn { color: #9ca3af; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
/* 上架结果 / 已上架总览那两句话。pre-line 是给"有几个款号没上架"那一段用的: 那一整段是**一个**
   textContent(款号来自操作员粘贴, 用 textContent 才是安全的), 里面的换行只有 pre-line 画得出来;
   默认的 normal 会把它们塌成空格, 几种成因挤成一行, "能分辨是哪一种"当场就没了。
   成功那一句没有换行, pre-line 对它没有任何影响。 */
.msg { font-size: 13px; color: #065f46; white-space: pre-line; }
/* ⚠️ 颜色跟着语义走, 见 replenish.js 的 setMsg。别把 .msg 当成"永远是绿的"。
   .msg 是默认(成功)态; 下面三条按 setMsg 传进来的 kind 生效(.msg.warn 比 .msg 更具体, 不靠顺序)。
   .mute 是**中性**态(既不是成功也不是问题, 如"还没上架过款"): 那种话用成功绿说是错的口径 ——
   绿色在这里的含义是"客户都能看到"。 */
.msg.warn { color: #b45309; }
.msg.err { color: #b91c1c; }
.msg.mute { color: #6b7280; }
/* 模式那两格的颜色。⚠️ 目前**没有元素在用它们**: 代理表里"模式"是一个 <select>, 不是带这两个
   class 的标签。跟着一起搬过来只是因为它俩与上面那套配色同源, 删掉省不了事、留着不误伤谁;
   哪天表格把下拉换成文字标签, 颜色就已经在位了。 */
.mode-direct { color: #065f46; }
.mode-isolated { color: #92400e; }

/* ==================== 全款列表（补货上架那一格的主体，2026-09-28） ====================
   ⚠️ 全部限定在 #pane-replenish 里（同上面 .filters 那条的理由：/admin/analytics.html 也加载
   本文件，类名一律先假定会撞）。下面这些类名在本页加载的两份 css 里 grep 过，都是新增的。
   最要紧的一条：**码的颜色 = 当前状态，码外面的蓝框 = 选中** —— 两个信号必须一眼分得开。
   用一个信号表达两件事（比如"蓝色=选中"同时"蓝色=已上架"），用户就分不清这个码现在到底上了没有，
   而这一格的全部动作都建立在那个判断上。 */
#pane-replenish .chip { border: 1px solid #d1d5db; background: #fff; color: #374151; border-radius: 14px;
  padding: 5px 12px; font: inherit; font-size: 13px; cursor: pointer; }
/* 搜索框给个下限: 这一行现在挤了 5 样东西(搜索/季节/说明/四个状态档), 不给下限的话
   输入框会被压到 100 出头, placeholder 直接被切掉半句(2026-09-28 真 Edge 截图里看到的)。
   挤不下时让它整体换行, 而不是把输入框压瘪。 */
#pane-replenish #style-search { min-width: 170px; }
/* 当前选中的那个档：底色 + 白字，与"未选中"的档一眼分得开 */
#pane-replenish .chip.on { background: #e8657f; border-color: #e8657f; color: #fff; font-weight: 600; }
#pane-replenish #style-filters { display: inline-flex; gap: 6px; }
#pane-replenish .pick { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 13px; color: #374151; }
/* 全局那条 `input { width:100%; margin-top:6px }` 会把勾选框撑成一整行 —— 与 .tbl input 同款地收回来。
   ⚠️ 两条都要: `.pick input` 是"表头那个 label 里包着的框"(全选本页), `input.pick` 是**款行前那个框**
   (它的 class 就在 input 自己身上)。只写前者的话, 后者被撑成 400 多像素宽、把款号一路挤到右边 ——
   而假 DOM 不管版式, 这条是 2026-09-28 真 Edge 里量出来的(box=444x13)。 */
#pane-replenish input.pick, #pane-replenish .pick input { width: auto; margin: 0; }
#pane-replenish #styles-head { flex-wrap: wrap; gap: 12px; }
#pane-replenish #styles-count { font-size: 13px; }
#pane-replenish #styles-pager { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; font-size: 13px; }
#pane-replenish #styles-body { border-top: 1px solid #f0f1f3; }
#pane-replenish .style-row { border-bottom: 1px solid #f0f1f3; padding: 8px 0; }
#pane-replenish .style-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* 款号本身可点 = 展开（与左边那个 ▸ 是同一个动作、同一个处理分支） */
#pane-replenish .style-row .i-id { font-weight: 600; color: #111827; cursor: pointer; }
#pane-replenish .style-row .meta { color: #6b7280; font-size: 13px; }
#pane-replenish .style-row .enabled { color: #065f46; font-size: 13px; }
/* 「看不到」那一档的行：整行压暗一点，与能操作的款分开 */
#pane-replenish .style-row.orphan .style-main { background: #fffbeb; border-radius: 6px; padding: 6px 8px; }
#pane-replenish .sku-grid { margin: 6px 0 2px 30px; }
#pane-replenish .sku-color { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 3px 0; }
#pane-replenish .color-name { min-width: 56px; text-align: left; color: #374151; }
#pane-replenish .sku { display: inline-flex; align-items: center; gap: 4px; border: 1px solid transparent;
  border-radius: 6px; padding: 2px 7px; font-size: 13px; cursor: pointer; }
/* 圆点是状态（● 已上架 / ○ 未上架）。用 before 画、不写进文字里：文字那边只留尺码，
   测试与复制出来的内容都是"26"而不是"●26" */
#pane-replenish .sku::before { content: ''; width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
#pane-replenish .sku.up { color: #065f46; background: #ecfdf5; }
#pane-replenish .sku.up::before { background: #16a34a; }
#pane-replenish .sku.off { color: #6b7280; background: #f3f4f6; }
#pane-replenish .sku.off::before { background: #fff; border: 1px solid #9ca3af; }
/* ⭐ 选中 = 蓝框（与上面的颜色**完全无关**的一个信号，两者可以同时成立）。
   用 outline 而不是 border：border 会把元素撑大（一排码会跟着跳），outline 不占布局。 */
#pane-replenish .sku.sel { outline: 2px solid #2563eb; outline-offset: 1px; }
/* ⚠️ **部分上架**（同一个规格下有的行上了、有的没上 —— 历史遗留的过渡态）：颜色仍是绿
   （客户买得到），但**不许绿得像"两行都上了"**：加一圈琥珀色虚线边。
   它是过渡态、点一下就统一，可"看起来一样"的代价是操作员以为这一格没问题了 ——
   而那正是"只关了一半、客户照样买得到"那个坑本身。
   （用 border 而不是 outline：outline 已经被"选中"占用了，两个信号不能抢同一个通道。） */
#pane-replenish .sku.partial { border-color: #f59e0b; border-style: dashed; }

/* ==================== 代理管理那一行的两个开关 + 展开的客户折扣（2026-09-29） ====================
   ⚠️ 全部限定在 #pane-agents 里，理由与上面 #pane-replenish / #pane-rp-orders 两段**逐字相同**：
      /admin/analytics.html 也加载本文件，类名一律先假定会撞（.cust-line 这种名字谁都能起）。
   复用的类（.tbl / .hint / .link）本页都已经有，新加的只有下面几个。 */
/* 整行可点 = "点它看客户折扣"。与 #pane-rp-orders 的 .rp-row 同一个信号（灰底 + 手型光标），
   两处的交互是同一件事，观感必须一致 —— 否则运营得为每一格重新学一遍。 */
#pane-agents tbody tr[data-id] { cursor: pointer; }
#pane-agents tbody tr[data-id]:hover { background: #fafbfc; }
/* 展开标记（编号前面那个三角）。它是"这一行还能点"的唯一提示 —— 少了它，整行可点这件事
   在屏幕上没有任何迹象（本仓对"点了没反应"的判据：那不是交互，那是个谜）。 */
#pane-agents .cust-caret { color: #9ca3af; font-size: 12px; }
/* 展开行：淡底，让它读起来是"上面那一行的一部分"（两张白底的行贴在一起会被当成两个代理）。
   ⚠️ 上面那条手型光标/悬停**不会**落到它头上 —— 那条选择器是按 `tr[data-id]` 匹配的，
   而展开行只有 `data-cust`（没有 data-id）。版式与 JS（replenish.js 里那句 `cust-row` 判断）
   两侧各自独立地把它排除掉：任一侧漏了，另一侧还在。 */
#pane-agents .cust-row td { background: #fafbfc; }
#pane-agents .cust-line { display: flex; align-items: baseline; gap: 16px; padding: 4px 0; font-size: 13px; }
/* 手机号（客户在这一格里的唯一身份，见 replenish.js 的 customersHtml）：给个固定最小宽度，
   几行的折扣/警告才能**对齐** —— 参差不齐时一眼看不出谁贵谁便宜，而这一格就是拿来比的。 */
#pane-agents .cust-phone { min-width: 130px; color: #111827; }
#pane-agents .cust-disc { min-width: 70px; font-weight: 600; }
/* ⚠️ 亏本那一行**必须一眼看得出来**（用户原话：「亏本的一眼标出来」）—— 用红色，且给足对比度。
   别改成"加个 ✗ 图标"那种：这一格里每一行都长得差不多，颜色是唯一能在扫一眼时跳出来的信号。 */
#pane-agents .cust-loss { color: #b91c1c; }
/* 两个开关的勾选框：本页那条全局 `input { width:100%; margin-top:6px }` 会把它们撑满整格
   （与 .tbl input 同款地收回来 —— 那条只作用于 .tbl 里的 input，这里的框也在 .tbl 里，
   所以本来就被它盖住了；显式再写一遍是为了**不依赖**那条的写法，将来有人改它会一并想这里）。 */
#pane-agents .sw { width: auto; margin: 0; }

/* ⭐ 「清单显示客户价」那一格（2026-10-13）：展开行里**每个客户那一行的最后一格**。
   ⚠️ 样式照隔壁 .cust-line / .sw 既有的那套写（同一个容器、同一档灰字、同样把全局的
   `input { width:100% }` 收回来），别另起一套 —— 这两格在同一行里并排，长得不一样读的人
   会以为它们是两件事。 */
/* 整块那句解释：与抬头上那句（客户折扣（N 个客户））同档灰字，紧跟其后。 */
#pane-agents .cust-spp-hint { margin-top: 2px; }
/* 一个 <label>（框 + 七个字）：**点字也能勾**（真浏览器里 label 会把点击转给里面的控件）。 */
#pane-agents .cust-spp { display: flex; align-items: baseline; gap: 6px; color: #4b5563; cursor: pointer; }
/* ⚠️ 与上面 .sw 那条同一个原因收回来：不收的话那个框会撑满这一格（.tbl input 那条其实已经盖住了，
   显式再写一遍是为了**不依赖**那条的写法 —— 见上面那段注释）。 */
#pane-agents .cust-spp input { width: auto; margin: 0; }
/* ⭐ 停用的代理：**整行变灰**（2026-10-08 用户原话：「允许我删除或者**暂停使用变成灰色**」）。
   ⚠️ 走**颜色**、不走 `opacity`: 整行半透明会把字一起糊掉（用户要的是"这条不用了", 不是"这条看不见"）——
      灰行照样要读得出编号和名字, 否则运营没法照着它去核对"停的是不是这一个"。
      用 #9ca3af（本文件里 .cust-caret / .filters-note 已经在用的那个灰）: 与正文的 #333 一眼分得开,
      而 13px 的字在这个灰上仍然读得出来。
   ⚠️ 输入框/下拉**也要一起变浅**: 只改 td 的文字颜色的话, 那几格里还是白底黑字的控件,
      整行看起来"没怎么变"（而这一行的全部用处就是"扫一眼就知道它停用了"）。
      同一个手势本文件里已有先例: #pane-replenish .filters input[readonly] 的灰底 = 这一格现在不用管。
   ⚠️ 码图给透明度而不是改颜色: 24px 的图没法"把文字调灰", 压到半透明就够了（还是个码, 不刺眼）。
      `.qr-fail`（取不到码时的那个 <span>）一起带上: 不然它在一行里会显得特别亮。 */
#pane-agents tbody tr.off td { color: #9ca3af; }
#pane-agents tbody tr.off input, #pane-agents tbody tr.off select { color: #9ca3af; background: #f9fafb; }
#pane-agents tbody tr.off .qr, #pane-agents tbody tr.off .qr-fail { opacity: .45; }

/* ==================== 线下订单（2026-09-29） ====================
   ⚠️ 全部限定在 #pane-rp-orders 里，理由与上面 #pane-replenish 那一段**逐字相同**：
   /admin/analytics.html 也加载本文件，而它顶栏那个筛选条同样叫 .filters。
   这里复用的类（.card / .filters / .tbl / .msg / .badge）本页都已经有，所以新加的类只有
   下面这几个 —— 复用那几个的前提是**逐个看过它们在本文件里的写法**：
   .tbl 的边框与内边距、.msg 的三态颜色都是现成的，这一格不需要覆盖它们。
   ⚠️ 但 **.mute 不是**：本文件里的那条是 `.msg.mute`（限定在 .msg 上），单独一个 `.mute`
      在**本页加载的两份 css 里都不存在**（grep 过）—— 拿它当"灰色小字"用的话什么都不会发生，
      而失败形态是"这句辅文和正文一样黑"，看着只是版式有点闷，没人会去查。
      ⇒ 下面补一条**限定在本格**的 `.mute`。⚠️ 不写成全局裸 `.mute`：pane-replenish 那一格
      也用了这个类名（#styles-count），全局加一条会顺手改掉**别人那一格**的观感 ——
      那是另一处的事，不在这条改动的范围里（看着像顺手做好事，实际是把一次改动的影响面
      从一个 pane 扩到全页）。 */
#pane-rp-orders .filters { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
/* 与 #pane-replenish 的两条同款：本页有一条全局 `label { display:block; margin-bottom:12px }`
   与 `input { width:100%; margin-top:6px }`（服务登录/新建场次那种纵向表单）。
   筛选行要的是「标签在左、控件在右」的一行一组，不显式写回的话每个输入框都会撑满一整行。 */
#pane-rp-orders .filters label { display: flex; flex-direction: row; align-items: center; gap: 6px; margin: 0; font-size: 13px; }
#pane-rp-orders .filters input, #pane-rp-orders .filters select { width: auto; margin: 0; padding: 6px 8px; border: 1px solid #d1d5db; border-radius: 6px; font: inherit; font-size: 13px; background: #fff; }
#pane-rp-orders .filters-note { font-size: 12px; color: #9ca3af; }
/* 辅助文字（列表头上那句"筛选后 N 单"、"N 行 · M 件"、翻页到头那一侧的灰字）。
   见上面那段说明：单独一个 .mute 在本文件里**本来没有**，所以这条是必须的，不是重复。
   ⚠️ **只给颜色，不给字号**：这三处落在三种不同的容器里（标题行 / 表格单元格 / 翻页器），
      字号各自由所在那一处决定；在这里写死一个 13px 会让表格里那一列比同一行的别的格子小一号。 */
#pane-rp-orders .mute { color: #6b7280; }
/* 统计卡：两个数字**必须一眼分得出主次** —— 大的是"线下盘子有多大"，小的是"要处理的"。
   同样字号的话，看的人会把"待审核 3"当成总数的一部分读（这一格的口径本身就是它最容易出错的地方，
   版式上不能再加一层歧义）。 */
#pane-rp-orders .rp-stats-main { font-size: 22px; font-weight: 600; color: #111827; }
#pane-rp-orders .rp-stats-sub { margin-top: 6px; font-size: 13px; color: #6b7280; }
/* 列表头那一行（"筛选后 3 单" + 翻页器）。与 #styles-head 同款：翻页器靠右，中间留白。 */
#pane-rp-orders .row.head { flex-wrap: wrap; gap: 12px; align-items: center; }
#pane-rp-orders #rp-pager { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; font-size: 13px; }
/* 明细卡与列表之间留一道缝：两张卡都是白底圆角，贴在一起会被读成同一张卡上的两段。 */
#pane-rp-orders .rp-detail { border-left: 4px solid #e8657f; }
/* 可点的行 = "点它看明细"。灰底 + 手型光标，与不可点的行一眼分得开；
   已经打开的那一行（.on）用左侧色条标出来 —— 与明细卡上那条色条是同一个信号（"这两样是一对"）。 */
#pane-rp-orders .rp-row { cursor: pointer; }
#pane-rp-orders .rp-row:hover { background: #fafbfc; }
#pane-rp-orders .rp-row.on { background: #fff5f7; }
#pane-rp-orders .rp-row.on td:first-child { box-shadow: inset 3px 0 0 #e8657f; }
/* 金额列右对齐 + 等宽数字：扫一列金额比大小时，左对齐的位数参差不齐，一眼看不出哪个大
   （tabular-nums 让每个数字占同样宽，"1" 与 "8" 不会一宽一窄）。 */
#pane-rp-orders .rp-amount { text-align: right; font-variant-numeric: tabular-nums; }
/* ⭐ ERP 侧改动回传（2026-10-03 批次三）——
   ① 数量列里那句标注（被删 / 被减量）：琥珀色 = "这行跟原来不一样了，看一眼"。
      没被改过的行就是原来的数字，颜色与位置都不变（判据在 rp-orders-pure.js 的 erpQtyText）。 */
#pane-rp-orders .rp-qty .rp-erp-note { color: #b45309; }
#pane-rp-orders .rp-qty { white-space: nowrap; }
/* ⭐③ **列表行**上那一句「⚠ 少 N 双」（2026-10-05）：运营扫列表时不用点进去就知道这单被聚水潭动过。
   同一个琥珀色（同一条判据：这是"跟原来不一样了"的信号），但**不覆盖"几行几件"那几个字** ——
   它只是多加一句，判据在 rp-orders-pure.js 的 erpCutText（空串 ⇒ 整块不画）。
   ⚠️ 与代理端 `.rp-erp-cut` 是**同一个视觉**（那边在 agent.css）：运营与代理看的是同一件事。 */
#pane-rp-orders .rp-erp-cut { color: #b45309; white-space: nowrap; }
/* ② 表下面那两句：ERP 现量（第二个合计口径）/ 整单取消的说明。
   前一句只在**真被改过**时才画（没改过的单一个字都不多）；后一句只用灰底，不用红 ——
   它不是说"你操作错了"，是说"这单在 ERP 里没了"。 */
#pane-rp-orders .rp-erp-total { color: #b45309; }
/* ⭐ 运费（2026-10-07）：列表那一列 + 明细那一行。
   列表那一格复用 .rp-amount（右对齐 + 等宽数字）—— 它紧挨着「金额」，两列都是钱，
   位数对齐了才扫得出哪单多收了；这里只补"不许折行"（¥12.5 折成两行会让整行变高）。
   明细那一行没有自己的样式（就一行普通的 .line）。 */
#pane-rp-orders .rp-freight { white-space: nowrap; }
#pane-rp-orders .rp-cancel { background: #f3f4f6; color: #374151; padding: 6px 10px; border-radius: 6px; }
/* ==================== 打印: 只出「归集(按商家)」这一张卡 ==================== */
.print-head { display: none; }

@media print {
  /* 侧栏/返回栏/所有操作按钮不上纸 */
  .side, .topbar, .btn, .btn-plain, .actions, .row.actions { display: none !important; }
  body { background: #fff; }
  /* overflow:auto 在分页介质上会裁掉超出一屏的内容 */
  .main { padding: 0; overflow: visible; }
  .view { min-height: auto; }
  /* 场次详情里其余卡片(选款定价/批量选款/搭配组/异常阈值)是操作区, 纸上只留归集单 */
  #session-detail > .card { display: none !important; }
  #session-detail > #collect-card { display: block !important; }
  #collect-card { box-shadow: none; border: 1px solid #ccc; }
  .card { box-shadow: none; }
  table { box-shadow: none; }
  .group { border: 1px solid #eee; border-left: 4px solid #e8657f; padding: 8px; break-inside: avoid; }
  .print-head { display: block; margin-bottom: 10px; }
  .print-head .meta { margin-left: 8px; }
}

/* ⭐ 解绑痕迹（2026-10-06）：归属那一格下面那句「已于 … 由代理解除绑定」。
   琥珀色 = 与全站其余"要看一眼"的信号同一个色（.rp-erp-note / .rp-erp-cut 都是它），
   而不是红色 —— 红色在本页是「已退回」那一档的意思，这两件事不是一回事。 */
.unbound-note { margin-top: 6px; color: #b45309; font-size: 12px; }



/* ── 2026-10-21：聚水潭单 / 员工下单账号 两格 ─────────────────────────────
   这两格复用「线下订单」的 .filters / .rp-stats-* / .row.head 类，但上面那些规则
   只挂在 #pane-rp-orders 下（有意限定作用域）。不补这一段的话统计卡没有字号差、
   筛选器会退化成竖排（全局 label/input 是登录表单那套纵向样式）。 */
#pane-jst-orders .filters, #pane-staff-accounts .filters { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
#pane-jst-orders .filters label, #pane-staff-accounts .filters label { display: flex; flex-direction: row; align-items: center; gap: 6px; margin: 0; font-size: 13px; }
#pane-jst-orders .filters input, #pane-jst-orders .filters select,
#pane-staff-accounts .filters input, #pane-staff-accounts .filters select { width: auto; margin: 0; padding: 6px 8px; border: 1px solid #d1d5db; border-radius: 6px; font: inherit; font-size: 13px; background: #fff; }
#pane-jst-orders .filters-note, #pane-staff-accounts .filters-note { font-size: 12px; color: #9ca3af; }
#pane-jst-orders .rp-stats-main { font-size: 22px; font-weight: 600; color: #111827; }
#pane-jst-orders .rp-stats-sub { margin-top: 6px; font-size: 13px; color: #6b7280; }
#pane-jst-orders .row.head { flex-wrap: wrap; gap: 12px; align-items: center; }
#pane-jst-orders #jo-pager { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; font-size: 13px; }
#pane-jst-orders .mute { color: #6b7280; }
#pane-jst-orders tr[data-jst] { cursor: pointer; }
#pane-jst-orders tr[data-jst]:hover { background: #fafbfc; }
