/* 收银端样式：PC 全屏布局 */

/* 顶栏高度只在这里写一次 —— 它被三处用到：顶栏自身的高度、断网红带的吸顶偏移、
   收银台三栏的高度（calc(100vh - 顶栏)）。三处各写各的数字，改一处必漏另两处。 */
:root { --topbar-h: 56px; }

/* ---------- 登录页 ---------- */
.login-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #2b4a8f 0%, #4a7cf7 100%);
}
.login-box { background: #fff; border-radius: 14px; padding: 40px 36px; width: 380px; box-shadow: 0 8px 30px rgba(0,0,0,.2); }
.login-title { text-align: center; font-size: 22px; font-weight: 700; margin-bottom: 6px; color: #2b4a8f; }
.login-sub { text-align: center; color: #999; font-size: 13px; margin-bottom: 26px; }
/* 本机已锁定的门店：只读，刻意不做成下拉框 —— 收银员没得选才不会选错 */
.store-locked {
  padding: 9px 12px; border-radius: 6px; background: #eef3ff;
  color: #2b4a8f; font-weight: 700; font-size: 15px;
}

/* ---------- 顶栏 ---------- */
/* 顶栏吸顶（2026-09-23 用户要求）：页面内容长了往下滚时菜单栏会滚出视野，
   想换个页面得先滚回顶部 —— 收银台忙的时候这一步很烦。
   用 sticky 而不是 fixed：fixed 会把顶栏**抽出文档流**，下面每个页面的首屏高度
   都得跟着重算（收银台三栏就是 calc(100vh - 顶栏)）；sticky 仍占着原来的位置，
   只在滚动时吸附，对既有布局零副作用。
   z-index 要高于断网红带（.net-alert = 900）：两条都会吸顶，万一重叠，
   最不该被盖住的就是换页入口。 */
.topbar {
  height: var(--topbar-h); background: #2b4a8f; color: #fff; display: flex;
  align-items: center; padding: 0 20px; gap: 18px;
  position: sticky; top: 0; z-index: 910;
}
.topbar .shop-name { font-size: 17px; font-weight: 700; }
/* 门店徽标：紧贴店名显示（负 margin 抵掉 .topbar 的 18px gap，让它读起来是
   "小区超市 · 逸翠湾店"一整体）。用暖色区别于右侧菜单，收银员抬头一眼可辨。 */
/* 字号**必须与 .shop-name 一致（17px）**：这两个词是并列的"店招 · 分店"，
   大小不一致会让人以为分店名是次要信息。实际恰恰相反——收银员确认"我在哪个店"
   靠的就是分店名，它不能比写死的店招还小。区分靠颜色与「·」分隔，不靠字号。 */
.topbar .store-badge { font-size: 17px; font-weight: 700; color: #ffe08a; margin-left: -12px; }
/* 门店没识别出来（多半是旧凭证）：只换警示色。
   ⚠️ **不要在这里缩小字号或降粗细** —— 店名是收银员用来确认"我在哪个店"的，
   恰恰是"没配标识/没识别出来"的时候最容易记错账，那时它必须同样醒目。
   （本机没配标识原先在这里挂一行小字，2026-09-14 改成"每次进收银台弹窗"，
     小字没人看 —— 见 app.js 的 storeWarnShow。） */
.topbar .store-badge.store-badge-warn { color: #ffc107; }
/* 断网常驻提示条（2026-09-20）：吸顶，保证任何页面、任何滚动位置都看得见。
   用警示红而不是橙色 —— 这是"现在收不了银"级别的状态，不是普通提醒。 */
.net-alert {
  /* ⚠️ top 必须**让开顶栏那 56px**（--topbar-h），不能写 0：顶栏现在也是吸顶的，
     两条都写 top:0 会叠在同一个位置，红带把菜单栏整个盖住 —— 断网时最不该
     看不见的就是换页入口。写变量而不是 56px，改顶栏高度时这里自动跟着走。 */
  position: sticky; top: var(--topbar-h); z-index: 900;
  background: #c0392b; color: #fff; text-align: center;
  padding: 9px 14px; font-size: 14px; font-weight: 700; letter-spacing: .3px;
}
.topbar .menu { display: flex; gap: 6px; flex: 1; }
.topbar .menu a {
  color: rgba(255,255,255,.75); text-decoration: none; padding: 7px 14px;
  border-radius: 6px; font-size: 14px; cursor: pointer;
}
.topbar .menu a.active { background: rgba(255,255,255,.18); color: #fff; }
.topbar .user { font-size: 13px; color: rgba(255,255,255,.8); }

/* ---------- 收银台三栏 ---------- */
.cashier-wrap { display: flex; height: calc(100vh - var(--topbar-h)); overflow: hidden; }

/* 左栏：商品 */
.panel-left { width: 44%; background: #fff; border-right: 1px solid #e8eaef; display: flex; flex-direction: column; }
.pos-search { padding: 12px 14px; border-bottom: 1px solid #eef0f3; }
.pos-search .input { font-size: 16px; height: 44px; }
.cat-tabs { display: flex; gap: 8px; padding: 10px 14px; overflow-x: auto; border-bottom: 1px solid #f0f1f4; flex-shrink: 0; }
.cat-tabs .cat {
  padding: 5px 14px; border-radius: 16px; background: #f1f3f7; color: #555;
  cursor: pointer; white-space: nowrap; font-size: 13px;
}
.cat-tabs .cat.active { background: #4a7cf7; color: #fff; }
.product-list { flex: 1; overflow-y: auto; padding: 10px 14px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; align-content: start; }
.product-item {
  border: 1px solid #e8eaef; border-radius: 8px; padding: 10px 12px; cursor: pointer;
  transition: border-color .15s, background .15s;
  display: flex; gap: 8px; align-items: center;
}
.product-item:hover { border-color: #4a7cf7; background: #f7faff; }
.product-item.selected { border-color: #22a06b; background: #f0faf4; }
.product-item .p-name { font-size: 14px; font-weight: 600; line-height: 1.4; height: 40px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.product-item .p-spec { font-size: 12px; color: #999; margin-top: 3px; }
.product-item .p-price { color: #e5484d; font-size: 16px; font-weight: 700; margin-top: 6px; }
.product-item .p-price span { font-size: 12px; font-weight: 400; }
.product-item .p-stock { font-size: 11px; color: #aaa; margin-left: 6px; }
.product-item .p-stock.zero { color: #e5484d; }
/* 收银台商品卡片：文字在左，固定尺寸正方形图片靠右（无图显示虚线占位） */
.product-item .p-text { flex: 1; min-width: 0; }
.product-item .p-img { width: 80px; height: 80px; object-fit: cover; border-radius: 6px; background: #f5f6f8; flex-shrink: 0; display: block; }
.product-item .p-img-empty { width: 80px; height: 80px; display: flex; align-items: center; justify-content: center; color: #bbb; font-size: 12px; border: 1px dashed #e0e3e8; box-sizing: border-box; }

/* 收银台：点哪儿都只响应点击，不产生文本选区、不落闪烁光标。
   现象：点商品名时卡片上闪一个编辑光标（个别内核/兼容模式浏览器默认可点文本会落光标）。
   -webkit-/-ms- 前缀不能省：360、QQ 等兼容模式内核仍只认带前缀的写法。
   caret-color: transparent 是兜底——浏览器开了「光标浏览」(F7) 时，user-select 拦不住光标，
   只有改光标颜色能让它不可见。

   两个写法不是随手写的，别"统一"成一种：
   - 中栏（购物车）和右栏（结算）**整栏没有输入框**，直接禁在容器上 —— 以后往里加
     元素自动生效，不会再漏一个「收款方式」这种。
   - 左栏**有搜索框**（.pos-search .input），所以只能逐个禁它里面纯点击的卡片和分类标签。
     ⚠️ 绝不能图省事给 .cashier-wrap 或 .panel-left 整栏加 user-select: none：
     它会继承进搜索框，收银员在框里就选不中、改不了字了。 */
.product-item,
.cat-tabs .cat,
.panel-mid,
.panel-right {
  user-select: none; -webkit-user-select: none; -ms-user-select: none;
  caret-color: transparent;
}

/* 中栏：购物车 */
.panel-mid { width: 36%; background: #fff; border-right: 1px solid #e8eaef; display: flex; flex-direction: column; }
.panel-title { padding: 12px 16px; font-size: 14px; font-weight: 600; color: #555; border-bottom: 1px solid #f0f1f4; display: flex; justify-content: space-between; }
.cart-list { flex: 1; overflow-y: auto; }
.cart-row { display: flex; align-items: center; padding: 12px 16px; border-bottom: 1px solid #f6f7f9; gap: 10px; }
.cart-row .c-name { flex: 1; font-size: 14px; }
.cart-row .c-name .c-spec { color: #aaa; font-size: 12px; }
.cart-row .c-price { color: #e5484d; font-weight: 600; font-size: 14px; width: 90px; text-align: right; }
.qty-box { display: flex; align-items: center; gap: 6px; }
.qty-box button { width: 26px; height: 26px; border-radius: 5px; border: 1px solid #d5d9e0; background: #fff; cursor: pointer; font-size: 15px; line-height: 1; }
.qty-box button:hover { border-color: #4a7cf7; color: #4a7cf7; }
.qty-box .qty { width: 36px; text-align: center; font-size: 15px; font-weight: 600; }
.cart-empty { text-align: center; color: #bbb; padding: 60px 0; }

/* 右栏：结算 */
.panel-right { width: 20%; background: #f8f9fb; padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.sum-line { display: flex; justify-content: space-between; font-size: 14px; color: #555; }
.sum-line .v { font-weight: 600; color: #333; }
.sum-total { display: flex; justify-content: space-between; align-items: baseline; padding: 10px 0; border-top: 1px dashed #d5d9e0; }
.sum-total .v { color: #e5484d; font-size: 28px; font-weight: 700; }
.pay-methods { display: flex; flex-wrap: wrap; gap: 8px; }
.pay-methods .pm {
  flex: 1; min-width: 70px; padding: 8px 4px; text-align: center; border: 1px solid #d5d9e0;
  border-radius: 6px; background: #fff; cursor: pointer; font-size: 13px;
}
.pay-methods .pm.active { border-color: #4a7cf7; color: #4a7cf7; background: #f0f5ff; font-weight: 600; }

/* ---------- 小票打印 ---------- */
.receipt-print { width: 72mm; font-family: "Courier New", monospace; font-size: 12px; color: #000; padding: 4px 2px; }
.receipt-print .rp-center { text-align: center; }
.receipt-print .rp-shop { font-size: 16px; font-weight: 700; }
.receipt-print .rp-row { display: flex; justify-content: space-between; }
.receipt-print .rp-line { border-top: 1px dashed #999; margin: 6px 0; }
/* 小票明细表（2026-09-20 起：原来是没有表头的 flex 行）。
   `table-layout: fixed` 让列宽可预测 —— 小票纸只有 72mm，列宽跑偏就打折行了。
   商品列不定宽（吃掉剩下的宽度）+ 数字列写死，明细行短，不用怕"打字时列动"。 */
.receipt-print .rp-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.receipt-print .rp-table th, .receipt-print .rp-table td {
  padding: 1px 0; font-weight: 400; text-align: left; vertical-align: top;
  overflow-wrap: anywhere;
}
.receipt-print .rp-table th { border-bottom: 1px dashed #999; }
.receipt-print .rp-table .num { text-align: right; white-space: nowrap; }
.receipt-print .rp-table th:nth-child(2), .receipt-print .rp-table td:nth-child(2) { width: 52px; }
.receipt-print .rp-table th:nth-child(3), .receipt-print .rp-table td:nth-child(3) { width: 48px; }
.receipt-print .rp-table th:nth-child(4), .receipt-print .rp-table td:nth-child(4) { width: 58px; }

@media print {
  body * { visibility: hidden; }
  .receipt-print, .receipt-print * { visibility: visible; }
  .receipt-print { position: absolute; left: 0; top: 0; }
}

/* ---------- 管理页面通用 ---------- */
.page-wrap { padding: 20px; max-width: 1200px; margin: 0 auto; }
.page-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; flex-wrap: wrap; gap: 10px; }
.page-head h2 { font-size: 18px; }
.page-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }

/* 标签页/页顶的「口径说明」：明确这一页看哪个店。
   为什么需要：库存页把入库/盘点/库存列表合成一页后**三个标签的口径不同**
   （入库与盘点只看本店、库存列表三店横向对比），不写清楚过几个月就会有人问
   "怎么这里只看得到一家店"。2026-09-19 定。 */
.scope-note {
  background: #f4f7ff; border-left: 3px solid #4a7cf7; color: #3a4a6b;
  padding: 8px 12px; border-radius: 4px; font-size: 12.5px; line-height: 1.75;
  margin-bottom: 14px;
}
.scope-note b { color: #2b4fa8; }

/* 标签 */
.tag { display: inline-block; padding: 2px 10px; border-radius: 10px; font-size: 12px; }
.tag-green { background: #e6f7ef; color: #22a06b; }
.tag-red { background: #fdeaea; color: #e5484d; }
.tag-gray { background: #f0f1f4; color: #777; }
.tag-blue { background: #e8f0fe; color: #2b6de8; }
.tag-yellow { background: #fdf6e3; color: #b07c10; }
/* 下面几个色是给操作记录页的类型标签用的：原先只有 5 种颜色，而类型有 9 个，
   必然撞色 —— 「删除/停用」和「退款」就都占了红，两类完全不同的操作扫一眼分不出
   （2026-09-16 用户提的）。现在一个类型一个颜色，见 pages/logs.js 的 tagMap。 */
.tag-purple { background: #f1ebfd; color: #7b52d3; }  /* 删除/停用 */
.tag-orange { background: #fff1e6; color: #c2410c; }  /* 改价 */
.tag-cyan { background: #e4f6fb; color: #0e7490; }    /* 上下架 */
.tag-pink { background: #fdeaf3; color: #be185d; }    /* 员工变更 */
/* 调拨（2026-09-21 补）：这个类型原先**漏在 tagMap 里**，走 `|| 'tag-gray'` 兜底成了灰，
   与刻意用灰的「登录」撞色 —— 用户看到的是「调拨和登录都是灰色，能分开吗」。
   选橄榄绿是因为其余 9 个色已经占满了红/橙/黄/绿/青/蓝/紫/玫红/灰，
   色环上只剩黄绿这一段（≈86°）空着，离入库的绿(≈155°)、盘点的黄(≈40°)都隔得开。 */
.tag-olive { background: #edf5d9; color: #4d7c0f; }   /* 调拨 */

/* 商品列表：光标停在「进价」「售价」上弹的改价历史。
   position:fixed —— 表格是 table-layout:auto，插在表格里会把列宽顶歪（踩过这个坑）。
   pointer-events:none —— 否则光标落到提示框上会触发 mouseleave，提示框一闪一闪。 */
.price-tip {
  position: fixed; z-index: 120; pointer-events: none;
  min-width: 250px; max-width: 360px;
  background: #fff; border: 1px solid #e2e5ec; border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .13);
  padding: 8px 10px; font-size: 12px;
}
.price-tip-head { font-weight: 600; color: #333; font-size: 13px; margin-bottom: 6px; }
.price-tip-row { display: flex; gap: 8px; align-items: baseline; padding: 2px 0; color: #555; }
.price-tip-row .t { color: #999; flex-shrink: 0; }
.price-tip-row .s { color: #999; margin-left: auto; white-space: nowrap; }
.price-tip-empty { color: #999; }

/* 时间线（订单状态流转） */
.tl { margin-top: 12px; padding-left: 8px; }
.tl-item { display: flex; gap: 12px; padding-bottom: 14px; position: relative; }
.tl-dot { width: 10px; height: 10px; border-radius: 50%; background: #4a7cf7; margin-top: 5px; flex-shrink: 0; }
.tl-dot.last { background: #22a06b; }
.tl-body { font-size: 13px; }

/* 盘点行高亮 */
.hl { background: #fffbe6 !important; animation: hl-pulse 1.2s ease; }

/* 商品候选下拉（入库页选择商品） */
.cand {
  position: absolute; left: 0; right: 0; top: calc(100% + 2px); z-index: 20;
  background: #fff; border: 1px solid #d5d9e0; border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0,0,0,.12); max-height: 280px; overflow-y: auto;
}
.cand-item { display: flex; gap: 10px; align-items: center; padding: 9px 12px; cursor: pointer; font-size: 13px; }
.cand-item:hover, .cand-item.selected { background: #f0f5ff; }
.cand-item .cand-name { flex: 1; }
.cand-item .cand-barcode { color: #999; font-size: 12px; }
.cand-item .cand-price { color: #e5484d; }
.cand-empty { padding: 12px; text-align: center; color: #999; font-size: 13px; }
@keyframes hl-pulse { 0% { background: #fff3b0; } 100% { background: #fffbe6; } }

/* 统计卡片（报表页） */
.stat-cards { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; }
.stat-card { background: #fff; border-radius: 10px; padding: 16px; text-align: center; box-shadow: 0 1px 3px rgba(0,0,0,.05); }
.stat-card .v { font-size: 22px; font-weight: 700; color: #2b4a8f; }
.stat-card.warn .v { color: #e5484d; }
.stat-card .l { font-size: 12px; color: #999; margin-top: 4px; }

/* ---------- 菜单权限灰显 ---------- */
.topbar .menu a.disabled { color: rgba(255,255,255,.35); cursor: not-allowed; }
.topbar .menu a.disabled:hover { background: transparent; }

/* ---------- 员工管理：权限勾选胶囊 ---------- */
.perm-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.perm-item {
  display: flex; align-items: center; gap: 4px; padding: 4px 10px;
  border: 1px solid #d5d9e0; border-radius: 6px; font-size: 13px; cursor: pointer;
}
.perm-item.checked { border-color: #4a7cf7; background: #f0f5ff; color: #2b6de8; }
.perm-item.disabled { opacity: .5; cursor: not-allowed; }
.perm-tip { font-size: 12px; color: #b7791f; background: #fdf6e3; border-radius: 6px; padding: 6px 10px; margin-top: 8px; }

/* 编辑弹窗价格字段旁的「历史」链接 */
.hist-link {
  margin-left: 8px;
  cursor: pointer;
  font-size: 12px;
  color: #4a7cf7;
  font-weight: normal;
  text-decoration: underline;
}

/* 商品编辑弹窗：图片上传预览 */
.p-upload-preview { width: 120px; height: 120px; object-fit: cover; border-radius: 8px; border: 1px solid #e8eaef; background: #f5f6f8; }
.p-upload-placeholder {
  width: 120px; height: 120px; display: flex; align-items: center; justify-content: center;
  color: #bbb; font-size: 12px; border: 1px dashed #d5d9e0; border-radius: 8px; background: #fafbfc;
}
.p-upload-actions { display: flex; align-items: center; gap: 10px; margin-top: 8px; }

/* ---------- 商品/分类编辑弹窗（2026-09-19 压紧凑） ---------- */

/* 左图右字段：图片右边本来全是空白，把规格/单位/分类/价格/开关提上来 ——
   原先一列到底要下滑才看得到保存按钮，而这个弹窗每天要开好几次。 */
.p-edit-main { display: flex; gap: 18px; align-items: flex-start; }
.p-edit-pic { width: 120px; flex: none; }
.p-edit-pic .p-upload-actions { flex-direction: column; align-items: stretch; gap: 6px; }
.p-edit-fields { flex: 1; min-width: 0; }
/* 各店预警值：门店名当表头、输入框按列排（原先一个店一行、三行太占高度） */
.p-level-row { display: flex; gap: 14px; }
.p-level-col { flex: 1; min-width: 0; }
.p-level-name { font-size: 12px; color: #666; margin-bottom: 4px; }

/* ---------- 日期区间选择器（components/date-range.js） ---------- */
.dr { position: relative; display: inline-block; }

/* 触发胶囊：左侧灰色标签 + 右侧当前值 + 展开箭头 */
.dr-trigger {
  display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
  height: 34px; padding: 0 12px 0 14px;
  border: none; border-radius: 17px; background: #f0f1f4;
  font-family: inherit; font-size: 13px; color: #333; cursor: pointer;
  transition: background .15s;
}
.dr-trigger:hover, .dr-open .dr-trigger { background: #e6e8ee; }
.dr-label { color: #666; }
.dr-value { font-weight: 600; }
.dr-caret { color: #666; flex-shrink: 0; transition: transform .15s; }
.dr-open .dr-caret { transform: rotate(180deg); }

/* 下拉面板 */
.dr-panel {
  position: absolute; top: calc(100% + 6px); z-index: 30;
  background: #fff; border: 1px solid #e8eaef; border-radius: 12px;
  box-shadow: 0 6px 24px rgba(0,0,0,.14); overflow: hidden; cursor: default;
  max-width: calc(100vw - 24px);
}
.dr-panel.dr-left { left: 0; }
.dr-panel.dr-right { right: 0; }
.dr-body { display: flex; }

/* 左侧预设列表 */
.dr-presets { width: 132px; flex-shrink: 0; padding: 10px 8px; border-right: 1px solid #eef0f3; }
.dr-preset {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 10px; border-radius: 8px; font-size: 13px; color: #333;
  cursor: pointer; user-select: none;
}
.dr-preset:hover { background: #f5f6fa; }
.dr-preset.active { background: #f0f1f4; font-weight: 600; }
.dr-check { color: #333; flex-shrink: 0; }

/* 右侧双月日历 */
.dr-cals { display: flex; gap: 18px; padding: 12px 16px; overflow-x: auto; }
.dr-cal { width: 238px; flex-shrink: 0; }
.dr-cal-head { display: flex; align-items: center; justify-content: space-between; height: 28px; margin-bottom: 4px; }
.dr-cal-title { font-size: 14px; font-weight: 600; color: #333; }
.dr-nav {
  width: 24px; height: 24px; flex-shrink: 0; border-radius: 6px;
  display: flex; align-items: center; justify-content: center; color: #666; cursor: pointer;
}
.dr-nav:hover { background: #f5f6fa; color: #333; }
.dr-nav-off, .dr-nav-off:hover { color: #d5d9e0; background: transparent; cursor: not-allowed; }
.dr-nav-hidden { visibility: hidden; }

.dr-week { display: grid; grid-template-columns: repeat(7, 1fr); }
.dr-week span { height: 28px; line-height: 28px; text-align: center; font-size: 12px; font-weight: 600; color: #333; }

/* 日期格子：格子本身画区间底色（无 gap 才能连成横带），内层圆点画端点 */
.dr-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.dr-cell { height: 34px; display: flex; align-items: center; justify-content: center; font-size: 13px; color: #333; }
.dr-cell.dr-in { background: #f0f1f4; }
.dr-cell.dr-edge-l { border-top-left-radius: 17px; border-bottom-left-radius: 17px; }
.dr-cell.dr-edge-r { border-top-right-radius: 17px; border-bottom-right-radius: 17px; }
.dr-day { width: 30px; height: 30px; line-height: 30px; text-align: center; border-radius: 50%; cursor: pointer; }
.dr-cell:not(.dr-disabled) .dr-day:hover { background: #e2e5eb; }
.dr-cell.dr-disabled .dr-day { color: #c8ccd4; cursor: not-allowed; }
.dr-cell.dr-disabled .dr-day:hover { background: transparent; }
.dr-cell.dr-start .dr-day, .dr-cell.dr-end .dr-day { background: #1a1a1a; color: #fff; font-weight: 600; }

/* 底部：当前区间 + 取消/确定 */
.dr-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 10px 16px; border-top: 1px solid #eef0f3;
}
.dr-foot-text { font-size: 13px; color: #666; white-space: nowrap; }
.dr-foot-btns { display: flex; gap: 8px; flex-shrink: 0; }

/* ---------- 小程序管理（小程序运营后台）的标签页与预览提示 ---------- */
/* 标签页：一个菜单项里装几块内容（顶栏菜单已经十项了，再加会挤爆） */
.tabs {
  display: flex; gap: 4px; border-bottom: 1px solid #eef0f3;
  padding: 0 4px; margin-bottom: 14px;
}
.tabs .tab {
  padding: 10px 16px; font-size: 14px; color: #666; cursor: pointer;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tabs .tab.on { color: #4a7cf7; border-bottom-color: #4a7cf7; font-weight: 600; }
.tabs .tab .badge {
  display: inline-block; min-width: 17px; height: 17px; line-height: 17px;
  padding: 0 4px; margin-left: 5px; border-radius: 9px; background: #e5484d;
  color: #fff; font-size: 11px; text-align: center; vertical-align: 1px;
}
/* 界面预览提示条：后端未接入时挂在页面顶部，别让人以为是坏掉了 */
.preview-note {
  background: #fff8e1; border: 1px solid #ffe082; border-radius: 8px;
  padding: 10px 14px; margin-bottom: 14px; font-size: 13px; color: #7a5c00; line-height: 1.7;
}
.preview-note b { color: #b45309; }

/* 订单列表的「配送地址」列：整列只放地址，形状才稳定（名字电话在详情里） */
/* 订单列表的配送地址：**截断**而不是换行。地址字段允许 200 字，一换行这一行就比
   别的行高，翻页时整页高度跟着跳（2026-09-23 用户定）。
   ⚠️ 为什么地址可以截断、商品名不行：地址看不全**不影响算账**（`title` 悬停可看全），
   商品名看不全**入库照着点货会拿错**；两者的代价不对称，所以处理方式也不同。 */
.o-addr-list {
  display: block; max-width: 260px; line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.o-none { color: #ccc; }

/* 订单行里的"选配送员"下拉：窄一点，别把表格撑开。
   未接单时旁边还有"下一步"按钮，两者会换行 —— 下留一点间距，别贴在一起。 */
.select-courier { width: 132px; padding: 4px 8px; font-size: 13px; height: auto; margin: 0 4px 3px 0; }

/* 订单列表里的"已退 ¥x"：部分退款的单状态仍是「已完成」，退过钱得单独标出来。
   ⚠️ 必须是**行内**（span）跟状态标签并排，**不能另起一行** —— 另起一行会让这一行
   比别的行高 11px，同一张表两种行高，翻页时整页总高度跟着跳（2026-09-23 用户实测：
   48×17 行 + 59×3 行）。排不下时宁可让状态列变宽，那由表格自己分配列宽，
   不该变成第二行。 */
.refund-mark { font-size: 12px; color: #e5484d; margin-left: 6px; white-space: nowrap; }

/* 表格里"只显示一行、超出省略"的格子。
   为什么要截断：内容长短不一时行高会忽高忽低（用户 2026-09-14 明确要求"显示不下别撑大"），
   翻页时每页总高度还会跟着跳。**完整内容用 `title` 悬停看，或在详情弹层里看。**
   两个类截断行为一样，只差在**宽度怎么定** —— 取决于那张表是哪种布局：
   - `.cell-clip`  自动布局的表：必须给个 max-width。自动布局下 td 会被内容顶宽，
                   而 td 上的 max-width 各浏览器表现不一致，套一层块级 div 才稳。
   - `.cell-trunc` **固定布局**的表（`table-layout:fixed`）：td 本来就有确定宽度，
                   块级 div 直接用满它、随窗口宽窄自适应。
   ⚠️ 别混用，两种走偏的方式实测过：
   · 自动布局的表套 `.cell-trunc` → 截不断（td 被内容顶宽，div 跟着一起变宽）；
   · 固定布局的表套 `.cell-clip` → 截得过早（列比 max-width 宽时也停在 max-width）；
   · **自动布局 + 宽列 + 写死 max-width** 最坑：窄窗口时那个下限反过来把列顶宽、
     整个表格撑破容器（实测 1024 窗口下操作记录行高从 48 变 55）。 */
.cell-clip, .cell-trunc {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cell-clip { max-width: 340px; }

/* 退款操作条：左边是"要退多少现金"（收银员照着拿钱），右边是按钮 */
.refund-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 12px; padding: 10px 14px; border-radius: 8px;
  background: #fff5f5; border: 1px solid #ffd9d9; font-size: 14px;
}
.refund-bar .refund-amount { font-size: 20px; font-weight: 600; color: #e5484d; margin-left: 4px; }
.refund-bar .refund-hint { font-size: 12px; color: #999; }

/* 退款明细行：商品名 | 数量 | 最多退几件 | 单价。
   上限必须常驻显示 —— 只在 placeholder 里写的话，一填数字提示就没了。 */
.refund-line { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.refund-line .rl-name { width: 170px; }
.refund-line .rl-qty { width: 74px; }
.refund-line .rl-max { font-size: 12px; color: #e5484d; width: 92px; }
.refund-line .rl-price { font-size: 12px; color: #999; }
