:root {
  --bg: #12141c;
  --panel: #1c1f2b;
  --panel2: #232738;
  --line: #2e3348;
  --text: #e8eaf2;
  --muted: #9aa0b5;
  --accent: #e8b34b;
  --accent2: #4b7bec;
  --green: #2ecc71;
  --red: #e74c3c;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
  background: var(--bg); color: var(--text);
  font-family: "PingFang SC", "Microsoft YaHei", -apple-system, sans-serif;
  font-size: 14px;
}
a { color: var(--accent); text-decoration: none; }
header {
  display: flex; align-items: center; gap: 16px;
  padding: 12px 20px; background: var(--panel);
  border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 10;
}
header h1 { font-size: 18px; color: var(--accent); letter-spacing: 1px; }
header .stats { color: var(--muted); font-size: 13px; }
header .spacer { flex: 1; }
.btn {
  display: inline-block; border: none; cursor: pointer; border-radius: 6px;
  padding: 8px 14px; font-size: 14px; background: var(--panel2); color: var(--text);
  border: 1px solid var(--line); transition: filter .15s;
}
.btn:hover { filter: brightness(1.2); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn.primary {
  background: var(--accent);
  color: #1a1a1a;
  font-weight: 700;
  border-color: var(--accent);
  padding: 8px 20px;
  box-shadow: 0 2px 8px rgba(212, 175, 55, 0.3);
  font-size: 14px;
}
.btn.primary:hover {
  filter: brightness(1.15);
  box-shadow: 0 4px 12px rgba(212, 175, 55, 0.45);
}
.btn.blue { background: var(--accent2); border-color: var(--accent2); color: #fff; }
.btn.green { background: var(--green); border-color: var(--green); color: #08280f; font-weight: 600; }
.btn.red { background: var(--red); border-color: var(--red); color: #fff; }
.btn.sm { padding: 4px 9px; font-size: 12px; border-radius: 5px; }
/* 第三百零四轮·第四节：台卡上那枚「收款」键（待收款任务在卡片上持续可见，不是弹窗提醒） */
.btn.warn { background: var(--accent); border-color: var(--accent); color: #1a1408; font-weight: 700; }
input, select, textarea {
  background: #10121a; color: var(--text); border: 1px solid var(--line);
  border-radius: 6px; padding: 7px 10px; font-size: 14px; outline: none;
}
input:focus, select:focus { border-color: var(--accent2); }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--line); }
th { color: var(--muted); font-weight: 500; font-size: 12px; white-space: nowrap; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
.panel { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 14px; }
.muted { color: var(--muted); }
.green { color: var(--green); }
.red { color: var(--red); }
.gold { color: var(--accent); }
.tag { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 12px; }
.tag.pending { background: #4a3b12; color: var(--accent); }
.tag.paid { background: #12432a; color: var(--green); }
.tag.gold { background: #4a3b12; color: #f0c96a; border: 1px solid #8a6d1f; }
.toast {
  position: fixed; top: 64px; left: 50%; transform: translateX(-50%);
  background: #22263a; border: 1px solid var(--accent2); color: var(--text);
  padding: 10px 20px; border-radius: 8px; z-index: 999; box-shadow: 0 6px 24px rgba(0,0,0,.5);
  display: none;
}
.toast.err { border-color: var(--red); }
.tabs { display: flex; gap: 8px; padding: 14px 20px 0; flex-wrap: wrap; }
.tabs .tab {
  padding: 8px 18px; border-radius: 8px 8px 0 0; cursor: pointer;
  background: var(--panel); color: var(--muted); border: 1px solid var(--line); border-bottom: none;
}
.tabs .tab.active { color: var(--accent); background: var(--panel2); font-weight: 600; }
.tabs .tab.dropdown { position: relative; user-select: none; }
.drop-menu {
  display: none; position: absolute; top: calc(100% + 2px); left: 0; z-index: 50;
  background: var(--panel2); border: 1px solid var(--line); border-radius: 8px;
  min-width: 130px; padding: 6px 0; box-shadow: 0 8px 24px rgba(0,0,0,.45);
}
.tab.dropdown.open .drop-menu { display: block; }
.drop-item { display: block; padding: 8px 16px; color: var(--text); white-space: nowrap; }
.drop-item:hover { background: var(--panel); color: var(--accent); }
/* 第百八十七轮：导航改成三级横栏，本页的下拉弹层整套退役（admin.html 里再没有 .tab.dropdown）。
   R158 那四条「专给弹层里的子项擦屁股」的覆盖规则随之作废——弹层没了，它们要压的锯齿也没了，
   留着就是死样式（R126 的 class 未引用尺子也会把它们揪出来），所以整块删掉。
   下面三条新规则全部限定在 #baseMgmtBar ＋ #empNav 之内，只调「第二、三级栏的外观」：
   栏的上下留白压薄、三级栏的按钮矮半格，一眼能看出层级；父级项带一条下边线，表明它不是页面而是组。
   全局那五条 .tabs / .tabs .tab / .tabs .tab.active / .drop-menu / .drop-item 一条都没改
   （前台订台卡片 booking.js 还在用 .drop-menu/.drop-item），选中态仍走 .tabs .tab.active 那条老规则。 */
#baseMgmtBar, #empNav .emp-sub-bar { padding: 6px 20px 0; }
#empNav .emp-sub-bar .tab { padding: 5px 14px; font-size: 13px; }
#empNav .tab[data-bar] { border-bottom: 1px solid var(--line); }
.tab-body { padding: 16px 20px; }
.form-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.form-row label { color: var(--muted); }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 16px; }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 14px; }
.card .k { color: var(--muted); font-size: 12px; margin-bottom: 6px; }
.card .v { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }
.modal-mask {
  position: fixed; inset: 0; background: rgba(0,0,0,.6); z-index: 100;
  display: none; align-items: center; justify-content: center; padding: 16px 0;
}
.modal-mask.show { display: flex; }
.modal {
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  padding: 20px; min-width: 340px; max-width: 520px; width: 92%;
  position: relative; max-height: calc(100vh - 32px); display: flex; flex-direction: column;
}
.modal h3 { margin-bottom: 14px; color: var(--accent); }
.modal > h3 { cursor: move; user-select: none; }
.modal .form-grid { display: grid; grid-template-columns: 90px 1fr; gap: 10px; align-items: center; }
.modal .actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; flex: 0 0 auto; }
.modal .modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 6px; margin-right: -6px; }
.modal .modal-body + .actions { border-top: 1px solid var(--line); padding-top: 14px; }
.modal .modal-x {
  position: absolute; top: 12px; right: 14px; width: 28px; height: 28px; padding: 0;
  border: 1px solid var(--line); border-radius: 8px; background: transparent;
  color: var(--muted); font-size: 17px; line-height: 1; cursor: pointer;
}
.modal .modal-x:hover { color: var(--accent); border-color: var(--accent); }

/* ---- 第百二十七轮：员工弹窗「跳点设置」折叠面板（.comm-panel/.comm-head/.comm-arrow/.comm-body）
        随该模块一并删除——全站已无引用 ---- */

/* ---- 第七十二轮：新增/编辑员工弹窗——每项「第一行固定标题 + 第二行可填充格」逐项竖排 ---- */
.emp-item { margin: 0 0 10px; }
.emp-item-title { color: var(--gold, #f0c96a); font-size: 13px; margin: 0 0 4px; font-weight: 600; }
.emp-item-inputs { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.emp-item-inputs input, .emp-item-inputs select, .emp-item-inputs textarea { min-width: 0; }
.emp-item-inputs > input, .emp-item-inputs > textarea { flex: 1; }
.emp-item-inputs > input[type="number"] { flex: 0 1 auto; width: 130px; }
.emp-item-note { color: var(--muted); font-size: 12px; margin-top: 4px; line-height: 1.6; }
/* 第七十二轮优化：薪资项两列并排（基本工资|社保补贴 / 全勤补贴|餐补 / 月休天数|超休罚款 / 少休奖励）；加班费改分档独立整行 */
.emp-item-grid { display: grid; grid-template-columns: 1fr 1fr; column-gap: 18px; }
.emp-item-grid .emp-item-inputs > input[type="number"] { flex: 1; width: auto; }
.tier-row { display: flex; align-items: center; gap: 6px; width: 100%; }
.tier-row input { flex: 1; }
.tier-row .tier-unit { color: var(--muted); font-size: 12px; white-space: nowrap; }
.tier-row { display: grid; grid-template-columns: 58px 1fr 1fr; gap: 8px; align-items: center; margin-top: 8px; }
.tier-row.head { margin-top: 10px; color: var(--muted); font-size: 12px; }
.tier-row input { width: 100%; }

/* ---- 第七十二轮E：员工明细目录同步列表——行内编辑单元格 / 类目列点击开弹窗 ---- */
#empDetailTable td.eedit { cursor: text; }
#empDetailTable td.emodal { cursor: pointer; }
#empDetailTable td.eedit:hover, #empDetailTable td.emodal:hover { background: rgba(240, 201, 106, .08); }
#empDetailTable td.editing { padding: 2px 4px; }
#empDetailTable td.editing input, #empDetailTable td.editing select {
  width: 100%; min-width: 0; box-sizing: border-box;
}

/* ============ POS ============ */
/* 内嵌点单区（商品网格/购物车 .pos-wrap .cat-tabs .prod-grid .cart-* 等）已随功能整体移除 */

/* ============ 第九轮：前台工作台（现「房台实时状态」） ============ */
.spacer { flex: 1; }
header .who { color: var(--muted); font-size: 13px; }
header .who b { color: var(--accent); }

.stats-bar {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px; padding: 12px 20px 0;
}
.stat-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 14px; border-left: 4px solid var(--line);
}
.stat-card .k { color: var(--muted); font-size: 12px; margin-bottom: 4px; }
.stat-card .v { font-size: 26px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.1; }
.stat-card .v.sm { font-size: 15px; font-weight: 600; padding-top: 6px; }
.stat-card.total { border-left-color: var(--accent2); }
.stat-card.reserved { border-left-color: var(--accent); }
.stat-card.free { border-left-color: var(--green); }
.stat-card.merged { border-left-color: #a55eea; }
.stat-card.repair { border-left-color: var(--red); }
.stat-card.opened { border-left-color: #26c6da; }

.board-toolbar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 12px 20px 6px; color: var(--muted);
}
.board-toolbar label { display: flex; align-items: center; gap: 6px; }
.board-toolbar .chk { cursor: pointer; }
/* 第两百四十五轮：看板一行小字「当前场次：xx/xx 晚场（进行中）」 */
.slot-now { font-size: 12px; color: var(--muted); }
.slot-now.on { color: var(--green); }
.legend { display: flex; gap: 10px; padding: 0 20px 8px; flex-wrap: wrap; }
.legend .lg { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 5px; }
.legend .lg::before { content: ""; width: 10px; height: 10px; border-radius: 3px; background: var(--line); }
.legend .lg.free::before { background: var(--green); }
.legend .lg.reserved::before { background: var(--accent); }
.legend .lg.opened::before { background: #26c6da; }
.legend .lg.merged::before { background: #a55eea; }
.legend .lg.repair::before { background: var(--red); }

.board {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px; padding: 4px 20px 24px;
}
.tcard {
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px; border-top: 3px solid var(--line); display: flex; flex-direction: column; gap: 6px;
  min-height: 168px;
}
.tcard.free { border-top-color: var(--green); }
.tcard.reserved { border-top-color: var(--accent); background: #211f18; }
.tcard.opened { border-top-color: #26c6da; background: #16222a; cursor: pointer; }
.tcard.merged { border-top-color: #a55eea; background: #1e1a28; }
.tcard.repair { border-top-color: var(--red); opacity: .72; }
.tcard.opened:hover { border-color: #26c6da; }
.tc-top { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.tc-no { font-size: 24px; font-weight: 800; letter-spacing: 1px; color: var(--text); }
.tc-state { font-size: 11px; padding: 2px 8px; border-radius: 10px; background: var(--panel2); color: var(--muted); white-space: nowrap; }
.tcard.free .tc-state { background: #12432a; color: var(--green); }
.tcard.reserved .tc-state { background: #4a3b12; color: var(--accent); }
.tcard.opened .tc-state { background: #0f3b45; color: #26c6da; }
.tcard.merged .tc-state { background: #33244d; color: #c39bf5; }
.tcard.repair .tc-state { background: #4a1c17; color: #ff8b7d; }
.tc-name { color: var(--muted); font-size: 12px; }
.tc-info { flex: 1; font-size: 12px; color: var(--text); line-height: 1.5; }
.tc-info .muted { color: var(--muted); }
.tc-btns { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; position: relative; }
.tc-btns .btn { flex: 1; }
.tc-btns .dropdown { flex: 1; position: relative; }
.tc-btns .dropdown .btn { width: 100%; }
.tcard .drop-menu { left: auto; right: 0; min-width: 120px; }
/* 第三百零四轮·第四节：台卡上那枚持续可见的「客人已点单，请确定」标记 */
.cash-flag { color: var(--accent); font-weight: 700; }
/* 待收款清单弹窗：一张意向一行，行内只显商品名×数量·单价·应收（内部格服务端就没下发） */
.cash-item {
  border: 1px solid var(--line); background: var(--panel2); border-radius: 10px;
  padding: 8px 10px; margin-bottom: 8px; font-size: 13px;
}
.cash-head { color: var(--text); margin-bottom: 4px; }
.cash-lines { color: var(--muted); font-size: 12px; line-height: 1.6; }
.cash-ops { display: flex; gap: 6px; align-items: center; margin-top: 6px; flex-wrap: wrap; }
.cash-ops .cash-note { flex: 1; min-width: 140px; }
#cashList { max-height: 52vh; overflow-y: auto; }

.dropdown { position: relative; }
.cs-item {
  font-size: 12px; background: var(--panel2); border: 1px solid var(--line);
  border-radius: 8px; padding: 3px 8px; color: var(--text);
}
.tag.charge { background: #4a1c17; color: #ff8b7d; }

.merge-pick { display: flex; gap: 8px; flex-wrap: wrap; max-height: 240px; overflow-y: auto; }
.merge-pick .pick {
  border: 1px solid var(--line); background: var(--panel2); border-radius: 8px;
  padding: 6px 10px; cursor: pointer; font-size: 13px; color: var(--muted);
}
.merge-pick .pick.on { border-color: var(--accent); color: var(--accent); background: #2a2415; }
.liquor-list { max-height: 220px; overflow-y: auto; margin-top: 10px; }
.modal .form-row { margin-bottom: 8px; }
.form-row input[type="date"], .form-row input, .form-row select { min-width: 120px; }

/* ============ 第二十轮：员工明细表格列宽拖拽（已并入第四十轮通用拖拽） ============ */

/* ============ 第二十一轮：客户档案表格列宽拖拽（已并入第四十轮通用拖拽） ============ */

/* ---------- 第三十六轮：房台订单详情布局（参考图） ---------- */
.pos-crumb {
  display: flex; align-items: center; gap: 10px; padding: 12px 20px;
  background: var(--panel2); border-bottom: 1px solid var(--line);
}
.pos-crumb .crumb-sep { color: var(--muted); }
.pos-crumb .crumb-cur { font-size: 15px; color: var(--text); }
.btn.teal { background: #0e7d74; color: #fff; border-color: #0e7d74; }
.btn.orange { background: #e67e22; color: #fff; border-color: #e67e22; }
.btn.yellow { background: #f1c40f; color: #3a2e00; border-color: #f1c40f; font-weight: 600; }
#tsTable td:last-child, #tsTable th:last-child { white-space: nowrap; }
/* 存酒登记：分组表头（分类标签芯片已于第五十八轮移除；第六十一轮前台存酒弹窗同款表格共用） */
#stProdTable .st-cat-head td, #flqProdTable .st-cat-head td { background: rgba(255, 255, 255, .05); font-size: 14px; }
/* 存酒登记：「▾ 选择」完整名单弹层（不受已填文字过滤，可反复重选） */
.st-picker {
  position: fixed; z-index: 999; max-height: 300px; overflow-y: auto; min-width: 240px;
  background: #1c2333; border: 1px solid var(--border, #333); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .45); padding: 4px;
}
.st-pick-row { padding: 7px 12px; border-radius: 6px; cursor: pointer; font-size: 14px; color: var(--text, #e8ecf4); }
.st-pick-row:hover { background: rgba(255, 255, 255, .09); }

.detail-panel { margin: 14px 20px 0; overflow: hidden; padding: 0; }
.dp-head {
  padding: 12px 16px; background: var(--panel2);
  border-bottom: 1px solid var(--line); font-weight: 700; color: var(--accent);
}
.dp-row { display: flex; border-bottom: 1px solid var(--line); }
.dp-row:last-child { border-bottom: none; }
.dp-row .k {
  flex: 0 0 150px; padding: 12px 16px; color: var(--muted);
  background: rgba(255, 255, 255, .02); border-right: 1px solid var(--line);
  font-size: 13px;
}
.dp-row .v { flex: 1; padding: 12px 16px; font-size: 13px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.dp-row .v.stack { display: block; overflow-x: auto; }
.dp-row .v input, .dp-row .v select {
  background: var(--panel2); border: 1px solid var(--line); color: var(--text);
  border-radius: 6px; padding: 6px 10px; font-size: 13px;
}
.dp-row .v .lbl { color: var(--muted); }

.order-table { width: 100%; min-width: 980px; border-collapse: collapse; font-size: 13px; }
.order-table th, .order-table td {
  border: 1px solid var(--line); padding: 10px 12px; text-align: left; vertical-align: top;
}
.order-table th { background: var(--panel2); color: var(--muted); font-weight: 600; white-space: nowrap; }
.order-table td .ono { color: #7fb2ff; font-weight: 600; }
.order-table td .otime { color: var(--muted); font-size: 12px; }
.order-table .items-cell span { display: inline-block; margin: 0 6px 4px 0; }
.order-table .gift-mark { color: #ff5d5d; font-weight: 700; }
.order-table tfoot td { background: rgba(255, 255, 255, .02); font-weight: 700; }
.order-table .ops { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }

.pos-actionbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; gap: 10px; justify-content: center; flex-wrap: wrap;
  padding: 12px 20px; background: var(--panel2); border-top: 1px solid var(--line);
}

/* ============ 第四十轮：所有列表通用列宽拖拽（不受文字撑开，拉窄覆盖/拉宽显露） ============ */
table:not(.receipt):not(.receipt-preview) thead th { position: relative; }
table:not(.receipt):not(.receipt-preview) thead th::after {
  content: "";
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  cursor: col-resize;
  background: transparent;
}
table:not(.receipt):not(.receipt-preview) thead th:hover::after { background: var(--accent); }
table:not(.receipt):not(.receipt-preview) thead th.resizing::after { background: var(--green); }
/* 拖过的表格切为 fixed 布局：列宽以像素为准，文字超出的直接覆盖隐藏 */
table.colz, table.colz th, table.colz td { white-space: nowrap; }
table.colz th, table.colz td { overflow: hidden; text-overflow: clip; }

/* ============ 第百一十轮：仓库余量表头可点击排序（默认仍是「自有结存」降序） ============ */
/* 排序箭头用 ::before —— ::after 已被上面第 40 轮的 4px 列宽拖拽热区占用，故本列右内边距让出 18px。 */
.sk-sort-th { cursor: pointer; user-select: none; }
.sk-sort-th:hover { color: var(--accent); }
#stockBal thead th[data-sk] { padding-right: 18px; color: var(--accent); }
#stockBal thead th[data-sk]::before {
  content: "▼"; position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  font-size: 9px; color: var(--accent);
}
#stockBal thead th[data-sk="asc"]::before { content: "▲"; }

/* ============ 第四十一轮：前台存酒列表 / 取酒弹窗 ============ */
.stk-filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.stk-filters input[type="date"] { min-width: 140px; }
.stk-wrap { max-height: 56vh; overflow: auto; border: 1px solid var(--line); border-radius: 8px; }
#stkTable { min-width: 900px; }
#stkTable td { vertical-align: top; padding: 12px 10px; }
.stk-phone { color: #4f8dff; font-weight: 600; }
.stk-sub { color: var(--muted); font-size: 12px; margin-top: 4px; }
.stk-red { color: #e74c3c; font-size: 12px; margin-top: 6px; cursor: pointer; }
.stk-btns { display: flex; gap: 6px; flex-wrap: wrap; }
.stk-btns .btn { padding: 6px 10px; font-size: 12px; }
.btn.red { background: #d9534f; border-color: #d9534f; color: #fff; }
.btn.blue { background: #2f7ed8; border-color: #2f7ed8; color: #fff; }
.stk-pager { display: flex; gap: 6px; justify-content: center; margin-top: 10px; flex-wrap: wrap; }
.stk-pager button {
  min-width: 30px; padding: 5px 8px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--panel2); color: var(--text); cursor: pointer;
}
.stk-pager button.on { background: #6c5ce7; border-color: #6c5ce7; color: #fff; }
.stk-pager .dots { border: none; background: none; cursor: default; }
.tk-form { display: grid; grid-template-columns: 120px 1fr; row-gap: 16px; column-gap: 12px; align-items: start; padding: 8px 0 4px; }
.tk-form > label { text-align: right; color: var(--muted); padding-top: 6px; }
.tk-form .tv { color: var(--text); padding-top: 6px; }
.tk-form input[type="text"], .tk-form input:not([type]) , .tk-form input[type="number"] { padding: 8px 10px; }
.tk-star { color: #e74c3c; margin-right: 2px; }
.tk-req { display: flex; gap: 18px; flex-wrap: wrap; }
/* ===== R42：点单 · 选择商品弹窗 ===== */
.pk-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 6px 0 10px; border-bottom: 1px solid var(--line); }
.pk-bar input { flex: 0 0 240px; padding: 8px 10px; background: var(--panel2); border: 1px solid var(--line); border-radius: 6px; color: var(--text); }
.pk-bar .pk-sum { margin-left: auto; color: var(--accent); font-weight: 600; white-space: nowrap; }
/* 第两百零三轮：点单弹窗底下新长的「收款方式」那一行（窄屏实测 156px）+ 底部按钮，
   必须和商品区一起挤进 .modal 的定高框（max-height: calc(100vh-32px)）。
   flex 项默认 min-height:auto 会按内容撑住不肯缩，所以这里显式给一个下限：
   空间不够时商品区先缩到 180px（它自己 overflow:auto，照常滚动），
   再挤不下就让整个弹窗滚 —— 否则收款方式整行会溢出到圆角框外面（本机 612×588 实测：子项合计 781px > 框高 568px）。 */
.pk-body { display: flex; gap: 12px; margin-top: 10px; height: min(60vh, 620px); flex: 0 1 auto; min-height: 180px; }
.modal.pick-modal { overflow-y: auto; }      /* 极矮屏的兜底：整窗可滚，那一行不会被裁在框外 */
.pk-cats { flex: 0 0 132px; overflow: auto; border: 1px solid var(--line); border-radius: 8px; background: var(--panel2); padding: 6px; }
.pk-cats .cat { display: block; padding: 9px 10px; border-radius: 6px; cursor: pointer; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pk-cats .cat:hover { color: var(--text); background: var(--panel); }
.pk-cats .cat.on { background: #0e7d74; color: #fff; font-weight: 600; }
.pk-main { flex: 1; overflow: auto; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); }
.pk-table { width: 100%; min-width: 760px; border-collapse: collapse; font-size: 13px; table-layout: fixed; }
.pk-table th { position: sticky; top: 0; background: var(--panel2); color: var(--muted); font-weight: 600; padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--line); z-index: 1; }
.pk-table td { padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.pk-table tbody tr:hover td { background: rgba(255, 255, 255, .03); }
.pk-c-nm { width: auto; }
.pk-c-op { width: 340px; }
.pk-nm { font-weight: 700; }
.pk-meta { color: #e74c3c; font-size: 12px; margin-top: 2px; }
.pk-qty { width: 64px; padding: 6px 8px; background: var(--panel2); border: 1px solid var(--line); border-radius: 6px; color: var(--text); text-align: center; }
.pk-check { width: 18px; height: 18px; accent-color: #0e7d74; cursor: pointer; }
.pk-btns { display: flex; gap: 8px; align-items: center; white-space: nowrap; }
.pk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; padding: 10px; }
.pk-tile { border: 1px solid var(--line); border-radius: 8px; background: var(--panel2); padding: 10px; display: flex; flex-direction: column; gap: 6px; }
.pk-tile.has { border-color: #0e7d74; box-shadow: 0 0 0 1px #0e7d74 inset; }
.pk-tile .t-nm { font-weight: 700; }
.pk-tile .t-meta { color: #e74c3c; font-size: 12px; }
/* 第两百零三轮：点单弹窗底部那一行「收款方式」（十档单选，没权限的那几档显出来但点不动） */
.pk-pay { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; flex: 0 0 auto; margin-top: 12px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel2); }
.pk-pay-t { color: var(--accent); font-weight: 600; white-space: nowrap; }
.pk-pay-need { margin-left: 6px; padding: 2px 6px; border-radius: 4px; background: #7d2b1e; color: #ffd9d0; font-size: 12px; font-weight: 600; }
.pk-pay-box { display: flex; gap: 8px; flex-wrap: wrap; }
.pk-way { padding: 7px 16px; border: 1px solid var(--line); border-radius: 18px; background: var(--panel); color: var(--text); font-size: 13px; cursor: pointer; user-select: none; white-space: nowrap; }
.pk-way:hover { border-color: #0e7d74; }
.pk-way.on { background: #0e7d74; border-color: #0e7d74; color: #fff; font-weight: 600; }
.pk-way.off { opacity: .38; cursor: not-allowed; }
.pk-way.off:hover { border-color: var(--line); }
.pk-pay-none { color: #e74c3c; font-size: 12px; }
.pk-pay-tip { margin-left: auto; color: var(--muted); font-size: 12px; }
.pk-pay-tip.warn { color: #e74c3c; font-weight: 600; }
/* 第两百零六轮：点单弹窗那一格「分销抵扣码」（选填）。宽度窄、字距拉开，为的是念数字时不出错。 */
.pk-off-in { width: 132px; padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); color: var(--text); font-size: 16px; letter-spacing: 4px; text-align: center; }
.pk-off .pk-pay-tip.ok { color: #0e7d74; font-weight: 600; }
.tk-req label { color: var(--text); cursor: pointer; }
.skd-body { font-size: 13px; line-height: 1.9; }
.skd-body .row b { color: var(--gold, #d4af37); font-weight: 600; }
.skd-body table { margin-top: 8px; }

/* ---------- 打印设置（R43） ---------- */
.prn-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 6px 10px; border: 1px solid var(--line); border-radius: 8px; padding: 10px; background: var(--panel2); }
.prn-grid label { display: flex; align-items: center; gap: 6px; font-size: 13px; white-space: nowrap; }
.prn-switch { position: relative; display: inline-block; width: 46px; height: 24px; vertical-align: middle; }
.prn-switch input { opacity: 0; width: 0; height: 0; }
.prn-slider { position: absolute; inset: 0; background: #666; border-radius: 999px; transition: .2s; cursor: pointer; }
.prn-slider::before { content: ""; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px; background: #fff; border-radius: 50%; transition: .2s; }
.prn-switch input:checked + .prn-slider { background: #2ecc71; }
.prn-switch input:checked + .prn-slider::before { transform: translateX(22px); }

/* ---------- 第八十四轮：销售商品列表「门店商品添加」弹窗（参照截图整页） ---------- */
/* 第九十六轮：本弹窗固定按「加长」高度显示——四个子页之间切换、以及「规格」在 单品/套餐/多规格 三态之间
   切换时，窗口都不再随内容多少而伸缩；没有数据的子页下方就是留白，之后新增的分组行/规格行/字段都在
   这片留白里往下排（内容超出可视区时由 .modal-body 自己滚动，底部「保存」始终钉在最下方）。 */
.modal.sp-add { max-width: 980px; height: calc(100vh - 32px); max-height: calc(100vh - 32px); }
.sp-add .sp-warn { color: #e66; font-size: 12.5px; font-weight: 400; }
.sp-add .sp-tabs { padding: 0 0 10px; margin: 0 0 4px; border-bottom: 1px solid var(--line); }
.sp-add .modal-body { margin-top: 4px; }
.sp-add .sp-page { min-height: 100%; }
.sp-field { display: grid; grid-template-columns: 138px 1fr; gap: 12px; align-items: start; padding: 13px 2px; border-bottom: 1px dashed var(--line); }
.sp-field:last-child { border-bottom: none; }
/* ---------- 第百八十四轮之后回修：门店商品「商品信息」页三对字段并排 ----------
   .sp-field-pair ＝ 一行两栏的外层容器（名称｜单位、跳点分类｜提成分类、市场价｜会员价 三对共用它）。
   · 左右两栏等宽（1fr 1fr），列间不留间距 ⇒ 两栏各自的 dashed 下边框接成同一条横线，视觉连续；
   · 栏内标签列由单栏的 138px 收到 68px（这一页的标签最长就「享受会员类型折扣」那种，半栏里 68px 足够）；
   · 三对走同一份列宽声明，所以左标签／左输入／右标签／右输入四列上下严格对齐；
   · min-width:0 ＋ 输入框 max-width 让长提示文字在栏内自己折行，不把半栏撑破。 */
.sp-field-pair { display: grid; grid-template-columns: 1fr 1fr; }
.sp-field-pair > .sp-field { grid-template-columns: 138px 1fr; min-width: 0; border-bottom: 1px dashed var(--line); }
/* 第两百一十一轮：pair 栏内标签列由 68px 抬到 138px，与单栏 .sp-field 严格同宽
   ⇒ 弹窗里所有左侧标题（所属门店／商品名称／商品单位／跳点分类／提成分类／商品分类／市场价／会员价…）
   在同一 x 处右对齐、自上而下一条直线；pair 里的输入框靠 max-width:100% 自己收缩，不再撑破半栏。 */
.sp-field-pair > .sp-field .sp-lab { overflow: hidden; text-overflow: ellipsis; }
.sp-field-pair > .sp-field .sp-ctl input,
.sp-field-pair > .sp-field .sp-ctl select { max-width: 100%; }
.sp-lab { text-align: right; color: var(--muted); padding-top: 6px; font-size: 13px; }
.sp-lab i { color: #e66; font-style: normal; margin-right: 2px; }
.sp-ctl { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.sp-col { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.sp-ctl label.chk { color: var(--text); display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.sp-hint { color: var(--muted); font-size: 12px; }
.sp-page-sep { height: 6px; }
.sp-tg { display: inline-flex; align-items: center; gap: 6px; min-width: 68px; height: 26px; padding: 0 5px; border-radius: 999px; background: #4a4a55; border: 1px solid var(--line); color: #cfcfd6; cursor: pointer; font-size: 12px; user-select: none; }
.sp-tg .knob { width: 16px; height: 16px; border-radius: 50%; background: #fff; order: 0; flex: 0 0 auto; }
.sp-tg .txt { order: 1; }
.sp-tg.on { background: #6c5ce7; border-color: #6c5ce7; color: #fff; }
.sp-tg.on .knob { order: 1; }
.sp-tg.on .txt { order: 0; }
/* ---------- 第百七十七轮：门店商品「双边提成」落到商品级 ----------
   ① .sp-dual-inline：开关跟在「跳点分类」那一行标题后面，做成一颗小胶囊，避免和下拉抢位；
   ② #spDualBlocks + .sp-dual-card：开关打开后露出的两张配置块（订台人蓝框、销售人员紫框，对照布局图状态B），
      每块都是「下拉选模式 + 数值 + 单位」，数值框在模式留空时禁用；
   ③ .sp-dual-note：两块下面的口径说明，讲清「两份各拿各的、双边行入基数但不乘费率」。 */
.sp-dual-inline { display: inline-flex; align-items: center; gap: 7px; padding: 3px 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--panel2); }
.sp-dual-inline b { color: var(--text); font-size: 12.5px; font-weight: 600; }
#spDualBlocks { display: grid; gap: 8px; margin: 10px 0 2px; }
#spDualBlocks .sp-dual-card { grid-template-columns: 118px 1fr; gap: 10px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel2); }
#spDualBlocks .sp-dual-card .sp-lab { color: var(--text); padding-top: 5px; font-weight: 600; }
#spDualBlocks .sp-dual-card.booker { border-color: #3b82f6; }
#spDualBlocks .sp-dual-card.promo { border-color: #a855f7; }
#spDualBlocks .sp-dual-card input:disabled { opacity: .45; cursor: not-allowed; }
.sp-unit { color: var(--muted); font-size: 12px; margin-left: -4px; }
.sp-dual-note { padding: 8px 12px 10px; border: 1px dashed var(--line); border-radius: 10px; color: var(--muted); font-size: 12px; line-height: 1.8; }
.sp-dual-note b { color: var(--text); }
.sp-save { width: 100%; margin-top: 12px; padding: 12px 0; border: 0; border-radius: 8px; background: #16a085; color: #fff; font-size: 15px; font-weight: 600; cursor: pointer; flex: 0 0 auto; }
.sp-save:hover { background: #12907a; }
/* 窄屏（或弹窗被压缩）时标题行在上、填写行在下，避免字段横向溢出 */
@media (max-width: 880px) {
  .sp-field { grid-template-columns: 1fr; gap: 4px; }
  .sp-lab { text-align: left; padding-top: 0; }
  .sp-field .sp-ctl, .sp-field .sp-col { min-width: 0; max-width: 100%; }
  .sp-field input:not([type]), .sp-field input[type=text], .sp-field input[type=number],
  .sp-field select, .sp-field textarea { max-width: 100%; }
  /* 第百八十四轮之后回修：窄屏时三对并排回退成上下堆叠（一对变两行），
     栏内也照单栏那样「标题在上、填写在下」，绝不横向溢出 */
  .sp-field-pair { grid-template-columns: 1fr; }
  .sp-field-pair > .sp-field { grid-template-columns: 1fr; gap: 4px; }
}
/* ---------- 第八十六轮：套餐「规格设置」= 必选单品 + 搭配商品分组表 ---------- */
/* 第九十八轮：撤掉 138px 左缩进，把腾出的横向空间给放大的两个数字框（可选种类上限 / 出库数量），整表仍不超出加长弹窗宽度 */
.pkg-tbl { width: auto; min-width: 720px; max-width: 100%; margin: 4px 0 0 0; border-collapse: collapse; font-size: 13px; }
.pkg-tbl th, .pkg-tbl td { border: 1px solid var(--line); padding: 6px 8px; text-align: center; vertical-align: middle; }
.pkg-tbl thead th { background: var(--panel2); color: var(--text); font-weight: 600; line-height: 1.25; }
.pkg-tbl tbody tr { cursor: move; }
.pkg-tbl tbody tr.drag-over { outline: 2px dashed var(--accent); outline-offset: -2px; }
.pkg-tbl input[type=checkbox] { width: 15px; height: 15px; cursor: pointer; }
/* 第百零四轮：分组表末尾多一列「操作」（每行一个「删除」键），8 列声明宽重排为 34/138/188/158/140/126/84/72＝940，
   仍是加长弹窗内宽；两个数字框保持第九十八轮放大的尺寸不动，将两个下拉各让出一点横向空间（分组名称 140→120、可选商品 200→170） */
.pkg-tbl .pkg-name { width: 120px; }
/* 第九十八轮：两个数字框放大到约三倍（宽 46/40 → 138/120，字号 14 → 16、内边距同步加大），好点也好读 */
.pkg-tbl .pkg-mk { width: 138px; padding: 9px 12px; font-size: 16px; }
.pkg-tbl .pkg-oq { width: 120px; padding: 9px 12px; font-size: 16px; }
.pkg-tbl .pkg-opt { min-width: 188px; }
.pkg-tbl select { width: 200px; }
.pkg-tbl .pkg-req { width: 108px; }
/* 第百零二轮：分组名称与可选商品改用**和必选单品一样的原生下拉**——选中项直接显示在框内，
   要换别的点开重选即可（不再有芯片、× 与只读锁定），整列候选一次看全；
   字号与内边距跟两个数字框同档（16px / 9px），保证在表格里也看得清；
   两框宽度按「<th> 声明宽 − td 左右内边距 16 − 边框 2」取值，整表仍不超出加长弹窗内宽 */
.pkg-tbl .pkg-search { width: 170px; }
.pkg-tbl .pkg-name, .pkg-tbl .pkg-search { padding: 9px 8px; font-size: 16px; }
.pkg-empty { color: var(--muted); font-size: 12px; padding: 8px 0; }
.pkg-total { display: block; margin: 8px 0 0 0; line-height: 1.6; }
.sp-tg.sm { min-width: 52px; height: 24px; font-size: 12px; }
/* 第百零四轮：每行末尾的「删除」= 只把这一行从待保存列表里撤掉（当场不写库），尺寸要够小才塞得进 72px 的操作列 */
.pkg-tbl .pkg-del { padding: 4px 9px; font-size: 12px; border-radius: 5px; cursor: pointer; }
@media (max-width: 880px) { .pkg-tbl, .pkg-total { margin-left: 0; } }

/* ---------- 第八十七轮：多规格「规格设置」= 商品规格表（规格名/规格值）+ 价格 + 价格详情 ---------- */
.spec-tbl { width: 100%; min-width: 520px; border-collapse: collapse; font-size: 13px; }
.spec-tbl th, .spec-tbl td { border: 1px solid var(--line); padding: 8px 10px; vertical-align: middle; }
.spec-tbl thead th { background: var(--panel2); color: var(--text); font-weight: 600; text-align: left; }
.spec-tbl .spec-cname { width: 210px; }
.spec-tbl input.spec-rname { width: 180px; }
.spec-tbl tfoot td { background: var(--panel2); }
.spec-del { display: inline-flex; align-items: center; gap: 6px; color: var(--text); cursor: pointer; }
.spec-del input { width: 15px; height: 15px; cursor: pointer; }
.spec-add { border: 0; background: none; color: #2f6fd8; font-size: 13px; cursor: pointer; padding: 0; }
.spec-add:hover { text-decoration: underline; }
.spec-vchips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.spec-vchip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px; border-radius: 4px; border: 1px solid var(--line); background: var(--panel2); font-size: 12px; color: var(--text); cursor: pointer; }
.spec-vchip.on { border-color: #2f6fd8; color: #2f6fd8; background: #eef4fd; }
.spec-vchip b { color: var(--muted); font-weight: 700; cursor: pointer; }
.spec-vchip b:hover { color: var(--red); }
.spec-tbl input.spec-vadd { width: 150px; }
.spec-rdel { border: 0; background: none; color: var(--red); font-size: 12px; cursor: pointer; }
.spec-price { width: 100%; max-width: 760px; }
.spec-detail { width: 100%; max-width: 760px; min-height: 20px; border: 1px solid var(--line); border-radius: 4px; background: var(--panel2); padding: 8px 10px; font-size: 13px; color: var(--text); white-space: pre-wrap; }
.spec-detail.ph { color: var(--muted); }

/* ---------- 第八十八轮：前台点单改引用门店销售商品（选规格 / 选配套商品 子弹窗） ---------- */
.btn.purple { background: #6c5ce7; color: #fff; border-color: #6c5ce7; }
.pk-tag {
  margin-left: 8px; padding: 1px 6px; border-radius: 4px; font-size: 11px; font-weight: 400;
  background: var(--panel2); color: var(--muted); border: 1px solid var(--line);
}
.pk-picked { margin-top: 4px; font-size: 12px; color: var(--accent); }
/* 第百七十四轮：点单弹窗里双边提成商品行的「推销人」一格（下拉＝在职员工＋其他（临时工）手填姓名） */
.pk-promo { display: flex; gap: 6px; align-items: center; margin-top: 6px; font-size: 12px; color: var(--muted); }
.pk-promo-t { color: var(--accent); white-space: nowrap; }
.pk-promo-sel { max-width: 190px; padding: 5px 8px; background: var(--panel2); border: 1px solid var(--line); border-radius: 6px; color: var(--text); }
.pk-promo-name { width: 150px; padding: 5px 8px; background: var(--panel2); border: 1px solid var(--line); border-radius: 6px; color: var(--text); }
.pk-pick-body { max-height: min(58vh, 520px); overflow-y: auto; padding-right: 6px; }
.pkp-grp { border: 1px solid var(--line); border-radius: 8px; background: var(--panel2); padding: 10px 12px; margin-bottom: 10px; }
.pkp-h { color: var(--accent); font-weight: 600; margin-bottom: 8px; }
.pkp-h .muted { color: var(--muted); font-weight: 400; font-size: 12px; margin-left: 6px; }
.pkp-items { display: flex; flex-wrap: wrap; gap: 8px; }
.pkp-it {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 6px; background: var(--panel); color: var(--text);
  padding: 7px 12px; font-size: 13px;
}
.pkp-it b { color: #e74c3c; font-weight: 600; font-size: 12px; }
.pkp-it:hover { border-color: #0e7d74; }
.pkp-it.on { border-color: #0e7d74; background: #0e7d74; color: #fff; }
.pkp-it.on b { color: #ffe9b8; }

/* ---------- 第百零五轮：基础资料 → 会员类型设置（列＝会员名称 | 备注 | 操作） ---------- */
/* tr.mt-new 是表头下面那行空白录入格（填完点「添加会员」保存；旁侧「删除」只清空这一格，不动库里数据）；
   已保存行点「编辑」变 tr.mt-edit（会员名称与备注在本行改成输入框，点「保存」才写库，点「取消」本次无效）。
   输入框撑满各自单元格（列宽由 admin.html 的 th 声明 260 / 自适应 / 150），操作格两键并排。
   刻意不给本表加 max-height / overflow：行多了照旧由页面滚动，与其它档案表格口径一致。 */
#mtypeTable td { vertical-align: middle; }
#mtypeTable input { width: 100%; min-width: 0; }
#mtypeTable tr.mt-new td { background: var(--panel2); }
#mtypeTable tr.mt-edit td { background: rgba(75, 123, 236, .08); }
#mtypeTable .btn + .btn { margin-left: 6px; }

/* ---------- 第百零六轮：全站「可输入下拉框」整列候选弹层（common.js cbOpen） ----------
   替代原生 <datalist> 弹层：框里已有文字时点一下也要列出全部候选（原生只会按已填文字过滤）。
   候选来源不变（仍读页面里的 <datalist>），所以各模块灌数据与校验逻辑一行都不用动。
   z-index 1100：必须压过 .modal-mask(100)，否则「编辑采购价格」这类弹窗内的下拉会被盖住。
   max-height / overflow-y 只给这个弹层自己，绝不给任何业务表格（R96 固定弹窗高度契约）。 */
.cb-panel {
  position: fixed; z-index: 1100; max-height: 320px; overflow-y: auto; min-width: 180px;
  background: #1c2333; border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .45); padding: 4px;
}
.cb-row { padding: 7px 12px; border-radius: 6px; cursor: pointer; font-size: 14px; color: var(--text); }
.cb-row:hover { background: rgba(255, 255, 255, .09); }
.cb-row.on { background: rgba(75, 123, 236, .22); }
.cb-row .muted { color: var(--muted); font-size: 12px; }
.cb-row.cb-empty { color: var(--muted); cursor: default; font-size: 13px; }
.cb-row.cb-empty:hover { background: none; }
/* 被接管的输入框：右侧画一个下拉箭头，提示「点一下就能整列选」 */
input.cbx {
  padding-right: 26px; cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M0 0h10L5 6z' fill='%238b95a8'/></svg>");
  background-repeat: no-repeat; background-position: right 8px center;
}

/* ---------- 第百零七轮：新主标签「挂账与赠送管理」（挂账管理 / 赠送明细） ----------
   两张截图都是「一张单据一行、行内再嵌明细」的版式，故：
   · .cg-tbl 用固定布局保住 th 声明宽（列宽拖拽 colzApply 也会接管，口径与其它表一致）；
   · .cg-sum 是截图顶部那条汇总语（总挂账／总补账／总剩余未补），赠送明细复用同一条样式；
   · .cg-order 是「点单订单信息」列里的嵌套小卡：截图把它画成框中框，红字只给「挂账人／挂账金额／未补账」三处；
   · .cg-total 是表尾合计行（挂账笔数与三项金额），刻意不用 sticky，避免与列宽拖拽的 colgroup 打架。
   溢出仍交给外层 div[overflow-x] 横向滚动，不给业务表格加 max-height（与 R96 契约一致）。 */
.cg-tbl { width: 100%; table-layout: fixed; border-collapse: collapse; }
.cg-tbl th, .cg-tbl td { vertical-align: top; }
.cg-tbl td { word-break: break-all; }
.cg-tbl .cg-orders { padding: 6px; background: rgba(255, 255, 255, .02); }
.cg-sum {
  margin: 10px 0 12px; padding: 10px 14px; border-radius: 8px;
  background: var(--panel2); border-left: 3px solid var(--accent);
  font-size: 14px; line-height: 1.6;
}
.cg-no { font-weight: 600; color: var(--accent); }
.cg-sub { font-size: 12px; margin-top: 2px; }
.cg-link { color: var(--accent2); font-weight: 600; }
.cg-red { color: var(--red); font-weight: 600; }
.cg-green { color: var(--green); font-weight: 600; }
.cg-order {
  border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px;
  margin: 4px 0; background: var(--panel);
}
.cg-ohead { font-size: 13px; margin-bottom: 4px; }
.cg-orow { font-size: 12px; color: var(--muted); line-height: 1.9; display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.cg-orow b { color: var(--text); font-weight: 600; margin-right: 6px; }
.cg-orow .cg-red, .cg-orow .cg-green { margin-right: 6px; }
.cg-orow .btn { margin-left: auto; }
.cg-total td { background: var(--panel2); font-weight: 600; border-top: 1px solid var(--line); }
.cg-cont td { border-top: 1px dashed var(--line); }
.cg-remark { color: var(--muted); font-size: 12px; }
.cg-rp-info {
  background: var(--panel2); border-radius: 8px; padding: 10px 12px; margin: 10px 0 12px;
  font-size: 13px; line-height: 1.9;
}
.cg-rp-info span { color: var(--muted); margin-right: 4px; }
.cg-rp-info b { color: var(--text); margin-right: 10px; }
.cg-rp-info .cg-red { color: var(--red); }

/* ================= 第百二十三轮：员工月度提成三个子表（工资汇总／过程汇总／部门汇总） =================
   .mc-tabs 是面板内部的子表切换条（照 .sp-add .sp-tabs 的做法：去掉全站 .tabs 的外边距，改底部一条分隔线），
   .mc-det 是「提成分类明细」的就地展开行——只在被点开的行出现，默认 display:none 由 admin.js 控制；
   .mc-cats 里的 h5/小表格都沿用全站 table 与 .muted 既有样式，这里只补内边距与字号，不动任何既有规则。
   第百五十四轮：「员工月度提成过程汇总」「部门月度提成汇总」两个子表连同切换条整块移除后，
   这三组选择器（.mc-tabs / .mc-det / .mc-cats）在 html、js、后端里都不再出现，按「不允许留未使用样式」
   的死代码体检口径一并删除；本面板剩下的工资汇总表只用下面第百五十二/百五十三轮那几条 #mcSumPanel 规则。 */

/* ============ 第百五十二轮：「员工月度提成工资汇总」表头允许换行 ============
   列宽拖拽本身是第百四十轮的全站通用机制（common.js 接管表头右边框，拖过即切 fixed 布局并写 localStorage），
   但那一轮为了「拉窄覆盖文字」把 table.colz th 定成了 white-space:nowrap——本表列名是
   「提成一类销售金额 / 提成一类提成金额」这类长标题，拉窄后会被裁掉看不见。
   这里只给本表（#mcSumPanel 的 table.mc-sum）的表头解开 nowrap：列宽不够时标题自动折行显示；
   单元格里的金额仍保持单行（￥600.00 / ￥790.20 中间断行更难读），且只影响这一张表，其它表格样式一字未动。
   第百七十三轮：弹性员工提成管理的「工资汇总」是另一张独立面板 #ptcMcSumPanel（结构与本表完全同构、
   同样用 table.mc-sum），所以这三条规则各多带一个选择器，把同一套折行口径原样套过去；
   既有 #mcSumPanel 那一条一字未改，全职那张表的外观保持原样。 */
#mcSumPanel table.mc-sum thead th,
#ptcMcSumPanel table.mc-sum thead th { white-space: normal; word-break: break-word; line-height: 1.35; }
#mcSumPanel table.mc-sum td,
#ptcMcSumPanel table.mc-sum td { white-space: nowrap; }

/* ============ 第百五十三轮：本表新增「跳点档位」列 ============
   档位文字是一长串「≥门槛→比例%」用分号接起来的，比金额宽得多，所以这一格允许折行（多档一行一档），
   并给个上下限让没拖过列宽时不至于把整张表撑爆；金额列仍按上面的规则保持单行。只影响本表这一列。
   第百七十三轮：弹性那张同构表（#ptcMcSumPanel）也有「跳点档位」这一列，选择器同样多带一条。 */
#mcSumPanel table.mc-sum td.mc-tier,
#ptcMcSumPanel table.mc-sum td.mc-tier {
  white-space: normal; word-break: break-word; line-height: 1.4;
  font-size: 12px; min-width: 110px; max-width: 240px;
}

/* ================= 第百一十三轮：前台独立登录页（/front） =================
   只服务新建的 web/front.html（body.front-login），不涉及任何既有页面，
   所以这里的规则都是新类名，管理员后台与原「房台实时状态」页的外观一字未变。 */
body.front-login {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 24px 14px; background:
    radial-gradient(1000px 520px at 50% -12%, #26304a 0%, var(--bg) 62%) no-repeat, var(--bg);
}
.fl-wrap { width: 100%; max-width: 380px; }
.fl-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  padding: 26px 22px 20px; box-shadow: 0 12px 34px rgba(0, 0, 0, .38);
}
.fl-brand { font-size: 38px; text-align: center; line-height: 1; margin-bottom: 6px; }
.fl-card h1 { font-size: 19px; color: var(--accent); text-align: center; letter-spacing: 1px; }
.fl-sub { color: var(--muted); font-size: 12px; text-align: center; margin: 8px 0 20px; line-height: 1.7; }
.fl-field { margin-bottom: 12px; }
.fl-field label { display: block; color: var(--muted); font-size: 12px; margin-bottom: 5px; }
.fl-field input {
  width: 100%; padding: 12px 13px; font-size: 16px;   /* 16px：iOS Safari 聚焦输入框不再自动放大页面 */
  background: var(--panel2); color: var(--text); border: 1px solid var(--line); border-radius: 9px;
}
.fl-field input:focus { outline: none; border-color: var(--accent); }
/* 注意选择器权重：登录按钮带 .btn.primary 两个类（(0,2,0)，定义在本文件第 35 行），
   单写 `.fl-ok{padding:13px 0}` 只有 (0,1,0)，会被 .btn.primary 的 padding:8px 20px、font-size:14px 盖掉，
   实测按钮只有 38px 高（需求 3.1 要求手机手指可点 ≥44px）。这里用 `.fl-card .fl-ok` 提到 (0,2,0) 并靠
   源序在后生效，同时补 min-height，手机与 PC 都是整行大按钮。 */
.fl-card .fl-ok {
  width: 100%; margin-top: 6px; padding: 13px 0; font-size: 16px;
  border-radius: 9px; min-height: 48px;
}
.fl-err { color: var(--red); font-size: 13px; min-height: 18px; margin: 10px 0 0; line-height: 1.6; }
.fl-tip { color: var(--muted); font-size: 12px; line-height: 1.75; margin-top: 14px; }
.fl-tip b { color: var(--text); }
.fl-addr { margin-top: 16px; text-align: center; font-size: 11px; word-break: break-all; }

/* ================= 第百四十五轮：弹性兼职员工——弹窗性质标识 + 兼职考勤面板 =================
   口径：只在 #empArchPt 本节内新增样式，全职那套（.emp-item / EMP_COLS 列表 / 考勤工资面板）一字未改。 */
.pt-nature { margin: 0 0 12px; padding: 8px 12px; font-size: 13px; line-height: 1.7;
  background: #211f18; border: 1px solid var(--line); border-radius: 6px; color: var(--text); }
.pt-nature .tag { margin: 0 6px; }
.pt-nature .muted { font-size: 12px; }
/* 第百七十八轮（认微信不认设备）：旧「弹性上班时间」开关那一行（.pt-flex-row）与上下班时间并排那一行
   （.pt-time-pair / .pt-sep）随弹窗里那两格录入一起退役——样式只被已删的 UI 用过，按「删 UI 连带删样式」
   的规矩整段摘掉，不留孤儿规则（守卫见 tests/test_slim_dead_code_r126.py 的 Test5）。 */
/* 第百七十一轮「基本薪资」一格：模式下拉（日薪／月薪）＋金额框＋单位，同一行排开、窄屏自动换行。
   只新增这一节，全职薪资那套（.emp-item / 工资面板）样式一字未改。 */
.pt-pay-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pt-pay-row select { flex: 0 0 auto; min-width: 92px; }
.pt-pay-row input[type="number"] { flex: 1; min-width: 130px; }
/* 兼职「补录打卡」「罚款单价」两个面板弹窗的字段标题：视觉与 .emp-item-title 完全一致，
   但类名独立——「弹窗字段必须同步进员工列表目录」那份契约（test_emp_modal_r72）只管全职员工档案弹窗，
   兼职面板的临时录入格（兼职人员／日期／迟到罚款…）不属于那一套目录。 */
.pt-item-title { color: var(--gold, #f0c96a); font-size: 13px; margin: 0 0 4px; font-weight: 600; }
/* 考勤面板：每人一张卡（卡头口径行 + 逐日明细表 + 月合计行） */
.pt-att-card { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; margin: 0 0 12px; background: #1b1a15; }
.pt-att-card > h4 { margin: 0 0 6px; font-size: 15px; color: var(--accent); }
.pt-att-card .pt-att-rule { color: var(--muted); font-size: 12px; line-height: 1.7; margin: 0 0 8px; }
.pt-att-card .pt-att-sum { font-size: 13px; margin: 8px 0 0; line-height: 1.8; }
.pt-att-card .pt-att-sum b { color: var(--gold, #f0c96a); }
#ptAttBody table { width: 100%; }
#ptAttBody th, #ptAttBody td { white-space: nowrap; }
#ptAttBody td.pt-ok { color: var(--green); }
#ptAttBody td.pt-fine { color: #ff8b7d; font-weight: 600; }
#ptAttBody td.pt-flex { color: var(--accent); }

/* ================= 第百一十三轮：手机端触屏自适应（需求 3.1） =================
   口径：宽屏（≥721px）一条都不生效 —— PC 端维持原来大屏布局，完全不改动；
   只有窄屏（手机竖屏）才把房台卡片改竖排单列、把按钮放大到手指可点（≥44px）。
   规则全部走类名覆盖，不新增 DOM、不改 HTML 结构，所以 / 、/desk、/admin 三页共用。 */
/* 指令 20261101023 要求 1：后台窄屏那条文字介绍（原来挂在页头下方那一块上）整块下架——HTML 节点已删，
   这里默认那条「PC 绝不占位」与窄屏露出的三档样式一并摘掉，不留死规则。 */

@media (max-width: 720px) {
  /* --- 页头：标题一行、操作员与退出按钮另起一行，按钮加大 --- */
  header { flex-wrap: wrap; gap: 8px 10px; padding: 10px 12px; }
  header h1 { font-size: 16px; width: 100%; }
  header .stats { font-size: 12px; width: 100%; }
  header .spacer { display: none; }
  header .who { font-size: 12px; flex: 1; }
  header .btn, header a.btn { min-height: 44px; padding: 10px 16px; font-size: 15px; }

  /* --- 今日统计卡片：两列，字小一号，仍完整显示 --- */
  .stats-bar { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; padding: 10px 12px 0; }
  .stat-card { padding: 8px 10px; }
  .stat-card .v { font-size: 19px; }
  .stat-card .v.sm { font-size: 13px; }

  /* --- 看板工具条与图例：换行排布，日期/场次控件整行可点 --- */
  .board-toolbar { gap: 8px 12px; padding: 10px 12px 6px; }
  .board-toolbar label { font-size: 13px; }
  .board-toolbar input, .board-toolbar select { min-height: 40px; font-size: 15px; }
  .board-toolbar .btn { min-height: 44px; padding: 10px 16px; font-size: 15px; }
  .legend { padding: 0 12px 8px; gap: 8px; }

  /* --- 房台卡片竖排：一列一张，占满屏宽，按钮够大 --- */
  .board { grid-template-columns: 1fr; gap: 10px; padding: 4px 12px 20px; }
  .tcard { min-height: 0; padding: 12px; gap: 8px; }
  .tc-no { font-size: 21px; }
  .tc-info { font-size: 13px; }
  .tc-btns { gap: 8px; }
  .tc-btns .btn, .tc-btns .dropdown .btn, .tc-btns .cs-item {
    min-height: 46px; padding: 11px 12px; font-size: 16px; border-radius: 9px;
  }
  .tcard .drop-menu { min-width: 160px; }
  .tcard .drop-menu .cs-item { min-height: 44px; display: flex; align-items: center; }

  /* --- 房台订单详情（点单页）：键值行改上下排，底部操作栏按钮放大 --- */
  .pos-crumb { padding: 10px 12px; gap: 8px; }
  .pos-crumb .btn { min-height: 44px; padding: 10px 14px; font-size: 15px; }
  .detail-panel { margin: 10px 12px 0; }
  .dp-row { flex-direction: column; }
  .dp-row .k { flex: none; width: auto; padding: 8px 12px 0; border-right: none; }
  .dp-row .v { padding: 6px 12px 10px; font-size: 14px; }
  .dp-row .v input, .dp-row .v select { min-height: 40px; font-size: 15px; }
  .pos-actionbar { gap: 8px; padding: 10px 12px; }
  .pos-actionbar .btn { flex: 1 1 28%; min-height: 48px; padding: 12px 6px; font-size: 15px; }

  /* --- 弹窗：占满屏宽、内边距收紧，控件按手指尺寸放大 --- */
  .modal-mask { padding: 10px 8px; align-items: flex-start; }
  .modal { min-width: 0; width: 100%; max-width: 100%; padding: 16px 14px; max-height: calc(100vh - 20px); }
  .modal h3 { font-size: 16px; margin-bottom: 12px; }
  .modal .form-grid { grid-template-columns: 82px 1fr; gap: 8px; }
  .modal input, .modal select { min-height: 42px; font-size: 16px; }
  .modal .actions { gap: 8px; }
  .modal .actions .btn { flex: 1; min-height: 46px; font-size: 16px; }
  .modal .btn, .modal button.btn { min-height: 42px; }
  .form-row { flex-wrap: wrap; }
  .form-row label { display: flex; align-items: center; gap: 6px; flex: 1 1 100%; }
  .form-row input, .form-row select { min-height: 42px; font-size: 16px; flex: 1; min-width: 0; }
  .tk-form label { font-size: 13px; }
  .tk-form input { min-height: 42px; font-size: 16px; }
  #tmWhole { width: 100% !important; }

  /* --- 点单「选择商品」弹窗：分类条改横向滑动，明细表在容器内左右滑动 --- */
  .pk-bar input { flex: 1 1 100%; }
  .pk-bar .btn { flex: 1; min-height: 44px; font-size: 15px; }
  .pk-bar .pk-sum { margin-left: 0; width: 100%; font-size: 13px; }
  .pk-body { flex-direction: column; height: auto; }
  .pk-cats { flex: none; display: flex; gap: 6px; overflow-x: auto; max-height: none; }
  .pk-cats .cat { padding: 10px 14px; font-size: 14px; }
  .pk-main { max-height: 46vh; }

  /* --- 后台窄屏那条文字介绍：指令 20261101023 要求 1 整块下架，节点与这三档样式一并摘掉（不留死规则） --- */
}

/* ---------- 第百八十三轮：营销分销的两块后台管理页（sec-referral / sec-referral_set） ----------
   全部走 .rf- 前缀、只在这两节里用，不碰任何既有选择器：
   · .rf-cards／.rf-card 是总览那一屏的八张数据卡（.t 标题／.v 数值／.s 小注，.warn 只给「待办提现」那张）；
   · .rf-tbl 与 .cg-tbl 同一口径：fixed 布局保住 th 声明宽，列宽拖拽照旧接管，
     横向溢出仍由外层 div[overflow-x] 负责，不给业务表格加 max-height（R96 契约）；
   · .rf-sum 是「逐笔流水／提现审批」顶部那条合计语，复用 .cg-sum 的观感但独立一份类名，
     免得以后改动分销文案时连带挂账那两页；
   · .rf-click 是「一行一月」那张表的可点行（点月份换成逐人拆分），只给 cursor 与 hover，不加边框；
   · .rf-note／.rf-ops 是流水表最后两列（备注／操作），窄屏靠外层滚动、不在行内折行。
   ⚠ 负数一律用既有的 .red（本文件早已定义），这里不再新增「红字」类，避免与 .cg-red 分裂。 */
.rf-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 10px; margin: 12px 0 4px;
}
.rf-card {
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px;
  background: var(--panel2);
}
.rf-card .t { font-size: 12px; color: var(--muted); }
.rf-card .v { font-size: 20px; font-weight: 700; margin-top: 2px; }
.rf-card .s { font-size: 12px; color: var(--muted); margin-top: 2px; line-height: 1.5; }
.rf-card.warn { border-color: var(--red); }
.rf-card.warn .v { color: var(--red); }
.rf-rule { margin: 10px 0 0; font-size: 12px; line-height: 1.7; }
.rf-tbl { width: 100%; table-layout: fixed; border-collapse: collapse; }
.rf-tbl th, .rf-tbl td { vertical-align: top; }
.rf-tbl td { word-break: break-all; }
.rf-tbl td input { margin-top: 4px; }
.rf-sum {
  margin: 10px 0 12px; padding: 10px 14px; border-radius: 8px;
  background: var(--panel2); border-left: 3px solid var(--accent);
  font-size: 14px; line-height: 1.6;
}
.rf-node-head { font-size: 14px; line-height: 1.9; margin-bottom: 4px; }
.rf-sub { margin: 12px 0 6px; font-size: 13px; }
.rf-line { font-size: 13px; line-height: 1.9; }
.rf-note { color: var(--muted); font-size: 12px; }
.rf-ops { white-space: nowrap; }
.rf-ops .btn { margin: 0 4px 4px 0; }
.rf-click { cursor: pointer; }
.rf-click:hover { background: rgba(255, 255, 255, .04); }

/* ================= 第百八十四轮：双边提成管理（员工管理 → 双边提成管理） =================
   全部走 .dc- 前缀，只在这一节里用，不碰任何既有选择器：
   · .dc-tbl 与 .rf-tbl／.cg-tbl 同一口径：fixed 布局保住 th 声明的那九列宽度、列宽拖拽照旧接管，
     横向溢出仍由外层 div[overflow-x:auto] 负责，不给业务表格加 max-height（R96 契约）；
   · .dc-tag 是「销售人员」那一格的身份证标——员工绿标、外部灰标，同一格并排一眼二分
     （样张口径：员工显示本名＋绿标「员工」，手填名＋灰标「外部」）；
   · .dc-none 是「— 未选推销人」：这一格刻意用弱化色而不是留空白，缺推销人这件事本身要看得出来；
   · .dc-total 是「总提成＝订台＋销售」那一列，金色加粗；
   · .dc-sum 是表底那条绿色合计行（笔数／双边消费／订台提成／销售提成／总提成），
     数值随筛选联动，所以这里只管观感、不算数——第一格那句「本页合计」用弱化色，别混成金额。
   ⚠ 金额右对齐＋等宽数字由既有的 td.num 提供（本文件第 60 行），这里不重复定义；
      负数继续用既有 .red，不新增「红字」类。 */
table.dc-tbl { width: 100%; table-layout: fixed; border-collapse: collapse; }
table.dc-tbl td { vertical-align: top; word-break: break-all; }
.dc-pname { margin-right: 4px; }
.dc-tag {
  display: inline-block; padding: 1px 6px; border-radius: 9px;
  font-size: 11px; line-height: 1.6; border: 1px solid var(--line);
}
.dc-tag-emp { color: var(--green); border-color: #2c7a4b; background: #12432a; }
.dc-tag-ext { color: var(--muted); border-color: var(--line); background: var(--panel2); }
.dc-none { color: var(--muted); }
.dc-total { color: var(--accent); font-weight: 600; }
tr.dc-sum td {
  border-top: 2px solid #2c7a4b; border-bottom: none;
  background: #123a26; color: var(--green); font-weight: 600;
}
tr.dc-sum td:first-child { color: var(--muted); font-weight: 500; }

/* ---------- 第百九十三轮：「员工月度提成工资汇总」新增的「详细」列 与 「提成明细」弹窗 ----------
   两处都只写带 id 前缀的 scoped 规则：主表那一格（#mcSumPanel td.cd-op）与弹窗内部（#cdModal …），
   一条都不改全站 table／.modal 的公共口径，弹性页那张同构表（#ptcMcSumPanel）也不受这些选择器命中。 */
#mcSumPanel td.cd-op { text-align: center; }
/* 弹窗里十二列：字号压一档、单元格不换行，宽度不够由外层 overflow-x:auto 横向滚（全站同一口径） */
#cdModal table.cd-tab { font-size: 13px; }
#cdModal table.cd-tab th, #cdModal table.cd-tab td { white-space: nowrap; }
/* 表头第二行＝每一列一个筛选框：小尺寸，min-width 74px 够敲下「>=100」这种区间写法 */
#cdModal tr.cd-filter td { padding: 4px; }
#cdModal tr.cd-filter input {
  width: 100%; min-width: 74px; box-sizing: border-box; font-size: 12px; padding: 3px 6px;
}
/* 表底那一行＝当前筛出来的这几行的合计，配色沿用双边台账那张表的表底（tr.dc-sum） */
#cdModal tfoot td { border-top: 2px solid #2c7a4b; background: #123a26; color: var(--green); font-weight: 600; }

/* ================= 第两百零一轮：微信机器人（服务号管理屏，#sec-wxgz） =================
   全部走 .wx- 前缀、只在这一节里用，一条都不改全站 table／.modal／.tabs 的公共口径：
   · .wx-sum 顶在页首与出站箱上方那条状态条，观感沿用 .rf-sum（同一份 panel2＋金色左边），
     但不复用那个类名——分销以后改文案不该把这一屏一起改掉；
   · .wx-ov-line 是概览那一横条里的分行，配置状态／模板配置／五张表计数各占一行；
   · .wx-chip 是小徽章：ok 绿、warn 黄、bad 红，只在这三种语义上用，不参与任何计算；
   · .wx-page 是「共 N 条 · 第 x–y 条」＋上一页／下一页那一行，靠右排、不换行；
   ⚠ 表体继续用既有的 .rf-tbl（fixed 布局＋列宽拖拽接管），横向溢出交给外层 div[overflow-x:auto]，
      不给业务表格加 max-height（第百九十六轮那份契约）；负数与错误文案继续用既有 .red。 */
.wx-sum {
  margin: 10px 0 12px; padding: 10px 14px; border-radius: 8px;
  background: var(--panel2); border-left: 3px solid var(--accent);
  font-size: 13px; line-height: 1.6;
}
.wx-ov-line { display: flex; flex-wrap: wrap; gap: 6px 8px; margin: 4px 0; }
.wx-ov-line code { font-size: 12px; }
.wx-chip {
  display: inline-block; padding: 2px 9px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--panel2);
  font-size: 12px; line-height: 1.7; color: var(--muted);
}
.wx-chip b { color: var(--text); font-weight: 600; }
.wx-chip.ok { color: var(--green); border-color: #2c7a4b; }
.wx-chip.warn { color: var(--accent); border-color: var(--accent); }
.wx-chip.bad { color: var(--red); border-color: var(--red); }
/* 第两百八十七轮·审计台「进度」那一列的五态（老板逐字：待执行灰／执行中蓝／已办绿／已拒绝红，
   后补独立第五态「办砸」橙红，与「已拒」分开——红色那一格是「这句我们没受理」，
   橙红那一格是「受理了、办了、办坏了」，两件事不能同一个颜色）。
   ⚠只在这一列用，不加全站语义；颜色一律取既有令牌，唯一的新值是那枚橙红。 */
.wx-chip.wait { color: var(--muted); border-style: dashed; }
.wx-chip.run { color: var(--accent2); border-color: var(--accent2); }
.wx-chip.err { color: #ef6c3a; border-color: #a8481f; }
/* 超 10 分钟还没 ack ⇒ 黄框（老板逐字「防卡死没人管」）。框在徽章上，不整行染色：
   这一屏是台账，染色会让人误读成「这一行是错误数据」。 */
.wx-chip.late { box-shadow: 0 0 0 2px var(--accent); }
/* 第两百八十八轮·件一（拼接施工单）第六态「已记段」：这一句已经拼进那张单、但还没封口，
   所以它【没有受理号】（段那一句按规矩绝不进队列）。颜色沿用执行中那枚蓝（都是「还在路上」），
   边框换成【点线】与另外两态分开：wait 虚线＝进了队列没人领，run 实线＝有人正办，
   seg 点线＝连队列都还没进。三种「还没完」在台账上是三件事，不许一个框形。
   ⚠只用既有令牌，没加新色值；也只在这一列用，不参与任何计算。 */
.wx-chip.seg { color: var(--accent2); border-style: dotted; }
.wx-page {
  display: flex; align-items: center; gap: 8px; margin: 6px 0 10px;
  font-size: 12px; white-space: nowrap;
}
/* 正则那一格是代码体：等宽、别被 break-all 切成一行一个字符以外的怪形状 */
.wx-rule-code { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; }
/* AI／出站留痕：默认收着，点开才读；行是原样文本，横向滚动而不是撑破版面 */
.wx-ai-log-box { margin: 6px 0 2px; font-size: 12px; color: var(--muted); }
.wx-ai-log-box summary { cursor: pointer; }
.wx-ai-log {
  margin: 6px 0 0; padding: 6px 8px; max-height: 260px; overflow: auto;
  background: var(--panel2); border: 1px solid var(--line); border-radius: 6px;
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px;
  line-height: 1.55; color: var(--text); white-space: pre;
}

/* ================= 第两百零九轮：AI系统管理那七个子目录的排版 =================
   仍全部走 .wx- 前缀、只在这一节里用，一条都不碰全站 .tabs／.panel／.form-row 的公共口径：
   · .wx-grp 是区头（七个子目录各一条），.wx-grp-head 左边一块金色竖条、右侧 .wx-own 是「谁负责这一摊」；
     .wx-own 同时用在页签里（<i class="wx-own">），所以两处都得是「不撑高、不换行」的小字；
   · .wx-lead 是区头下面那一句导语，只负责排版，不参与任何计算；
   · .wx-checks／.wx-half 是「勾一屏」与「左右两栏」两种排布：前者一条一行、后者各占一半（窄屏自己换行）；
   · .wx-say-* 是文案池那两族（播报／单据）的行：一行＝一句正文＋一个「开」＋一颗「删」；
   · .wx-query-* 是十项查询目录的卡片网格：没勾的那一项灰着，勾了才描绿边；
   · ⚠ .wx-stale 标灰、.wx-dup 标黄只是「大概要去核一下」，不是错误，所以都用低饱和的字色，
     绝不覆盖 .red 的语义（负数与错误文案继续只用既有那个 .red）。 */
.wx-grp { margin: 18px 0 8px; }
.wx-grp-head {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0 6px 10px; border-left: 3px solid var(--accent);
  font-size: 14px; font-weight: 600; color: var(--text);
}
.wx-own {
  display: inline-block; padding: 1px 8px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--panel2);
  font-size: 11px; font-weight: 400; font-style: normal; line-height: 1.7; color: var(--muted);
  white-space: nowrap;
}
.wx-lead { margin: 4px 0 10px 12px; font-size: 12px; line-height: 1.7; color: var(--muted); }
.wx-sub-h { margin: 12px 0 6px; font-size: 13px; font-weight: 600; color: var(--text); }
.wx-checks { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 6px 0 10px; }
.wx-check {
  display: flex; align-items: center; gap: 6px; min-width: 240px;
  font-size: 13px; line-height: 1.9; color: var(--text);
}
.wx-check input { flex: none; }
.wx-half { flex: 1 1 320px; min-width: 260px; }
.wx-say-scene { margin: 10px 0 14px; padding-left: 10px; border-left: 2px solid var(--line); }
.wx-say-h { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 13px; font-weight: 600; }
.wx-say-h .muted { font-weight: 400; font-size: 12px; }
.wx-say-line { display: flex; align-items: center; gap: 8px; margin: 5px 0; }
.wx-say-line .wx-say-text { flex: 1 1 auto; min-width: 200px; font-size: 13px; }
.wx-say-on { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); white-space: nowrap; }
.wx-say-var { cursor: pointer; }
.wx-say-var:hover { color: var(--accent); border-color: var(--accent); }
.wx-say-var code { color: var(--accent); }
.wx-query-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 10px; }
.wx-query-item {
  display: flex; flex-direction: column; gap: 5px; padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel2);
  font-size: 12px; color: var(--muted);
}
.wx-query-item.on { border-color: #2c7a4b; }
.wx-query-h { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--text); }
.wx-query-p { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.wx-query-p select { max-width: 100%; font-size: 12px; }
/* 行状态：30 天没再同步＝灰（这条名单怕是要过期了）；同一类型里撞名＝黄（要去核一下是谁） */
tr.wx-stale td, .wx-check.wx-stale { color: var(--muted); opacity: .6; }
tr.wx-dup td { background: #2a2410; }


/* 第两百一十轮 5.1：模拟打印机目录窗口（打印设置页内）的场景 chip 条。
   只新增选择器、不改既有规则——.spec-vchip 那一套长得一样但名字属于「多规格设置」，
   借到打印页会让以后读 CSS 的人以为打印页跟规格有关，所以另起一组 .prn-cat-*。 */
.prn-cat-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.prn-cat-chip {
  display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 4px;
  border: 1px solid var(--line); background: var(--panel2); font-size: 12px;
  color: var(--text); cursor: pointer;
}
.prn-cat-chip.on { border-color: #2f6fd8; color: #2f6fd8; background: #eef4fd; }
.prn-cat-content { white-space: pre-line; font-size: 12px; color: var(--muted); }

/* ================= 指令 20261101017（样板两项）＋ 20261101018（整体迁移）：手机端后台左侧那一列常驻菜单目录 =================
   老板口径逐字（017）：「手机端后台左侧要像参考图一样，显示菜单目录；点击主菜单后，在它下面展开子菜单；
   子菜单点击进入对应功能」「不是顶部横排；不是抽屉滑出；不是简单竖排子项；必须一眼看出是左侧菜单目录」。
   018 追加逐字：「顶部菜单全部迁移到左侧显示」「不再保留手机端顶部主菜单横排按钮」「左侧菜单样式必须与
   刚确认过的『基础资料／商品管理』样板一致」「电脑端显示保持不变」。
   ⇒ 排法与交互照 017 那一列一个字没改（常驻、不遮全屏、没有遮罩、点一行在它下面展开、手风琴互斥），
     018 只改两件事：①这一列里的行数＝顶部那一排入口按钮的现状（admin.js 扫 #mainTabs 建，名字现取）；
                     ②顶部那一排按钮在手机端整栏下架（下面 body.mp-side-on #mainTabs 那一条）。
     上一轮那「滑进来／点遮罩收回」的抽屉仍然作废——这一列一直挂在屏幕左边。
   ⚠只借参考图的【排法与交互】，不借它的内容：主菜单每一行的文字与顺序都由 admin.js 从入口按钮现场取，
     子菜单＝页面上那批既有 .tab 节点本体，这一列里一个字都没写死＝要求 9／10。
   断点取 767（＝common.js 里 BAR_MQ_PHONE 那条 "(max-width: 767px)" 的同值），不是上面第百一十三轮那档 720：
   admin.js 里这一节的开关量的是 barDevice()==="phone"，两头必须同一条线，
   否则会出现「JS 认它是手机、CSS 还给它摆横排」那种半截状态。电脑与平板（768 起）拿不到本节任何一条＝要求 8。
   只动这一列与那一排入口的摆法：页面自己内部那几条分区页签条（#supArchTabs／#prTabs／#staffTabs／#empArchTabs／
   #ptCommTabs）一条规则都没碰，员工管理那两级的形状就是样板那两栏的形状＝要求 10。
   ⚠这一族 !important 只加在【容器】（#mainTabs 那一排入口栏、.mp-side-bar 那一栏子菜单）上，
     一条都不许长在子项（.tab）上：
     这一列接管的每一栏，行内 style.display 都要被 switchTab 每切一页写一次（#costSaleTabs 只在借道那一档写 none、
     #empNav 跟着组走），这一列要按「展开／收起」摆，就得压得住那一次行内写入；
     而没权限的那些子项正是靠元素上的行内 display:none 藏着（admin.js 的 admPermGate 与 gateCostSaleArchTabs 那两处、
     还有员工管理那一条按权限藏父级的），容器级压不动它 ⇒ 这一列长不出「本来没权限的那一格」＝要求 5，
     本轮权限口径一字未改。 */
@media (max-width: 767px) {
  /* 指令 20261101021 要求 1／2：这一列的宽度在这一轮整整减一半（42vw／160px → 21vw／80px），
     字号与行高跟着缩（14→11、13→11），内边距跟着收＝「整体更紧凑」；
     --mp-side-fold-w 是收起之后只剩那一枚箭头时这一列占的宽度（同一枚变量给 body 让位用，两头不会脱节）。 */
  :root { --mp-side-w: min(21vw, 80px); --mp-side-fold-w: 22px; }
  /* 内容整体往右让出这一列（admin.js 给 body 挂上 mp-side-on 这个类名才让；电脑平板没这个类＝原样） */
  body.mp-side-on { padding-left: var(--mp-side-w); }
  /* 手机端不再保留顶部那一排主菜单按钮＝要求 9。⚠节点一个都不搬、不改：权限门控与切页高亮都按
     「#mainTabs .tab」这把选择器找它们（admin.js 的 admPermGate 与 switchTab），搬走就断；这里只是不再摆出来。 */
  body.mp-side-on #mainTabs { display: none !important; }
  /* 指令 20261101021 要求 4／5：页头那一排在手机端整条不再摆——「手机扫码／内置工作群／返回房台实时状态」
     三枚入口就此下线，「管理后台」标题与「当前登录」由 admin.js 搬进左列最上方（节点本体搬家，一个没删）。
     ⚠认的是 body 上那一枚手机端才有的类名，不是 @media 本身：desk.html 那一份页头（自己那一套标题与统计）
       拿不到这个类名，别的页面这一档一个字都没受影响＝边界「其他页面不受影响」。 */
  body.mp-side-on header { display: none; }
  #mpSideMenu {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 1200; width: var(--mp-side-w);
    display: flex; flex-direction: column;
    overflow-y: auto; background: var(--panel); border-right: 1px solid var(--line);
  }
  /* 最上方那一块＝搬来的标题＋当前登录，右侧一枚「往左收起」的箭头（要求 5／2） */
  .mp-side-top {
    display: flex; align-items: flex-start; gap: 2px;
    padding: 5px 3px 5px 5px; background: var(--panel2); border-bottom: 1px solid var(--line);
  }
  .mp-side-titles { flex: 1 1 auto; min-width: 0; }
  .mp-side-top h1 { font-size: 11px; line-height: 1.2; font-weight: 600; color: var(--accent); word-break: break-all; }
  .mp-side-top span { display: block; font-size: 10px; line-height: 1.3; color: var(--muted); word-break: break-all; }
  .mp-side-fold {
    flex: 0 0 auto; width: 16px; min-height: 26px; cursor: pointer; color: var(--muted);
    display: flex; align-items: center; justify-content: center;
  }
  .mp-side-fold::before { content: "‹"; font-size: 15px; }
  /* 收起之后整列只留这一枚「往右展开」的箭头（要求 2）：展开时它自己不摆，收起时上面那三块不摆 */
  .mp-side-unfold {
    display: none; width: 100%; min-height: 40px; cursor: pointer; color: var(--muted);
    align-items: center; justify-content: center;
  }
  .mp-side-unfold::before { content: "›"; font-size: 16px; }
  /* 折叠态＝只换 body 与这一列的宽度，并把三块内容收掉：一条 !important 都不加（谁都不压行内样式） */
  body.mp-side-collapsed #mpSideMenu { width: var(--mp-side-fold-w); }
  body.mp-side-collapsed { padding-left: var(--mp-side-fold-w); }
  body.mp-side-collapsed .mp-side-top,
  body.mp-side-collapsed .mp-side-list,
  body.mp-side-collapsed .mp-side-foot { display: none; }
  body.mp-side-collapsed .mp-side-unfold { display: flex; }
  /* 中间那一块＝13 行主菜单目录；不许被 flex 压扁（flex: 0 0 auto），整列超出屏幕时由 #mpSideMenu 自己滚 */
  .mp-side-list { flex: 0 0 auto; }
  /* 最下方那一块＝搬来的「退出登录」，红色＝和普通菜单一眼分开（要求 3；键的接线与显隐一个字没改）。
     margin-top: auto ＝目录不满一屏时把它顶到屏幕最下沿；超出时自动归零，跟着最后一行排，不挡滚动。 */
  .mp-side-foot { flex: 0 0 auto; margin-top: auto; border-top: 1px solid var(--line); padding: 6px 4px; }
  #mpSideMenu .mp-side-foot .btn {
    display: block; width: 100%; min-height: 30px; padding: 5px 2px; font-size: 11px;
    background: #3a1a17; border-color: var(--red); color: #ff8a7a;
  }
  /* 主菜单那一行：整行点得，右侧一枚箭头表示开／收（收起 › ／展开 ⌄，跟参考图同一读法） */
  .mp-side-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 6px 4px; font-size: 11px; font-weight: 600; color: var(--text);
    background: var(--panel2); border-bottom: 1px solid var(--line); cursor: pointer;
    min-height: 30px; box-sizing: border-box;
  }
  .mp-side-head::after { content: "›"; font-size: 11px; color: var(--muted); }
  /* 展开着的那一行＝整行强调色底＋深色字（参考图那枚「当前展开的主菜单」读法） */
  .mp-side-open > .mp-side-head { background: var(--accent); border-color: var(--accent); color: #1c1f2b; }
  .mp-side-open > .mp-side-head::after { content: "⌄"; color: #1c1f2b; }
  /* 没有子菜单的那一行（一级按钮自己就是某一页）：形状与主菜单行一模一样，只是右侧不给箭头——
     它展开不出东西，别画一个点不动的把手。 */
  #mpSideMenu .mp-side-leaf > .mp-side-head::after { content: ""; }
  /* 子菜单＝就住在这组下面的那一栏（页面上那一栏节点本体搬进来的），收起时整栏不见，展开才排出来 */
  #mpSideMenu .mp-side-bar { display: none !important; }
  #mpSideMenu .mp-side-open > .mp-side-bar { display: block !important; padding: 0; margin: 0; gap: 0; }
  /* 栏在手机端这一列里一律竖着排（搬进来那一栏本体，以及员工管理组里的二级栏与三条三级栏＝同一个样板形状）；
     这里不加 !important：三级栏那三条的显隐仍由页面自己的 empBarSync 写行内，谁被选中展开哪一条归它判。 */
  #mpSideMenu .tabs { display: block; padding: 0; margin: 0; gap: 0; }
  /* 套在一栏里面的那一层（员工管理组的三级栏）往里缩一格＝两级读得出层级（随宽度减半一并收小） */
  #mpSideMenu .mp-side-bar .tabs { padding-left: 6px; }
  /* 子项＝排在主菜单下面的一列，前面一枚 › 缩进；行内样式（权限那两处）压得过这一条，故这里不加 !important */
  #mpSideMenu .tabs .tab {
    position: relative; width: auto; box-sizing: border-box; border: none; border-radius: 0;
    border-bottom: 1px solid var(--line); padding: 6px 3px 6px 14px;
    min-height: 30px; display: flex; align-items: center; font-size: 11px; background: var(--panel);
    white-space: normal; line-height: 1.2; box-shadow: none;
  }
  #mpSideMenu .tabs .tab::before {
    content: "›"; position: absolute; left: 4px; color: var(--muted);
  }
  #mpSideMenu .tabs .tab.active {
    background: var(--accent); color: #1c1f2b; font-weight: 600; box-shadow: none;
  }
  #mpSideMenu .tabs .tab.active::before { color: #1c1f2b; }
  /* ================= 指令 20261101023：手机端右侧内容区整体缩小 =================
     老板口径逐字：「右侧显示的『相关内容』全部缩小一倍」「包含但不限于：字体／标题／表格文字／按钮／输入框／卡片／间距／整体内容区显示」
     「让右侧内容区更紧凑，更适合手机查看」「电脑端完全不变」。
     ⇒ 落点只有一处＝内容区总壳 .tab-body（admin.html 那 26 个 section 实测全住在它里面：inside=26／outside=0）。
       用 CSS 的 zoom 把整棵子树按同一个系数摆＝字体／标题／表格／按钮／输入框／卡片／间距一次全缩、比例一致；
       不逐类改字号，也不与 780 那一档（max-width:720，desk.html 与 admin.html 共用）那些「触屏放大到 42–46px」的规则抢行内样式，
       一条 !important 都不加，任何元素自己的 display 一个字没改。
     ⚠只挂 body.mp-side-on：这一枚类名只有 admin.html 在手机档拿得到（mpBuildSideMenu 在非手机档内部直接 return）
       ⇒ 电脑档（pc-side-on）／平板档（两枚类名都没有）／desk.html 与 index.html（根本不引 admin.js）
         一条都拿不到＝要求 10「电脑端完全不变」＋边界「其他页面不受影响」。
     ⚠左列 #mpSideMenu 挂在 body 上、不在 .tab-body 里 ⇒ 021 已确认的那一列（80px／11px／收起展开／列顶标题／列底退出）一个字节不变。
     ⚠--mp-content-shrink 是这一轮唯一的旋钮：0.75＝每格按四分之三摆（基准字 14px→10.5px、面板内边距 14px→10.5px），
       同一行放得下的内容宽度从 310px 变成约 413px＝「更紧凑」的来源。要再狠改小它、要回到原样改成 1，只改这一处。 */
  body.mp-side-on { --mp-content-shrink: 0.75; }
  body.mp-side-on .tab-body { zoom: var(--mp-content-shrink); }
}

/* ================= 指令 20261101019（电脑版两个目录样板）＋ 20261101022（整体迁移）：电脑版后台左侧那一列 =================
   老板口径逐字（019）：「电脑版也要像手机版一样改成左侧菜单方式」「本轮先做两个目录样板：基础资料／商品管理」
   「点击主菜单后，在它下面展开子菜单」「子菜单点击进入对应功能」「电脑版当前其他目录暂不动」
   「不要一次性迁移全部目录」「手机版已确认的效果保持不变」。
   022 追加逐字：「将电脑端后台目录全部迁移到左侧显示，逻辑和手机端一致」「左侧显示全部主菜单」
   「顶部不再保留这些主菜单按钮」「不再只做两个目录样板」「手机端现有左侧菜单逻辑保持不变」。
   ⇒ 形状与交互照手机端那一列（017 定样）一条不改：常驻挂在屏幕左边、不遮全屏、没有遮罩、点一行在它下面展开、
     手风琴互斥、收起 ›／展开 ⌄、子项前面一枚 › 缩进；这一档只把宽度与字号按电脑版摆（同一读法，不是另一套设计）。
   ⚠022 起顶部那一排在电脑端【整栏下架】（下面 body.pc-side-on #mainTabs 那一条，与手机端 018 同一写法）：
     13 枚主菜单全部由左侧那一列接管＝022 要求 5「顶部不再保留这些主菜单按钮」。⚠走 CSS 不走搬节点：
     admPermGate 的门控与 switchTab 的高亮都按「#mainTabs .tab」这把选择器找那 13 枚，搬走就断（要求 6 的破口）。
     下架之后 admin.js 里 019 那条「点顶部那枚入口＝左列跟着展开」的捕获监听没有落点，随那一轮一并摘掉。
   断点取 992（＝common.js 里 BAR_MQ_TABLET 那条 "(max-width: 991px)" 的另一头，与 admin.js 的
   barDevice()==="desktop" 同一条线）：手机（≤767）与平板（768–991）拿不到本节任何一条＝要求 8／9。
   ⚠这一族的 !important 与手机端同一纪律：只加在【容器】（顶部那一排入口栏 #mainTabs、搬进来的那一栏
     .pc-side-bar）上，一条都不许长在子项（.tab）上——商品管理那一栏的行内 display 每切一页被 switchTab 写一次，
     这一列要按「展开／收起」摆就得压得住那一次行内写入；而没权限的那几格正是靠元素上的行内 display:none 藏着
     （admPermGate 与 gateCostSaleArchTabs 那两处），容器级压不动它 ⇒ 这一列长不出「本来没权限的那一格」＝要求 6。
   ⚠z-index 取 90，比手机端那一列的 1200 低一档：电脑版有整屏弹窗（.modal-mask＝fixed inset 0／z-index 100），
     左列若浮在它上面会挡住弹窗左缘；取 90＝弹窗一开左列退到遮罩后面（模态该有的样子），
     仍压得过页头那条 sticky（z-index 10）与表格吸顶表头（z-index 1）。 */
@media (min-width: 992px) {
  :root { --pc-side-w: 200px; }
  /* 内容整体往右让出这一列（admin.js 给 body 挂上 pc-side-on 这个类名才让；手机平板没这个类＝原样） */
  body.pc-side-on { padding-left: var(--pc-side-w); }
  /* 022 要求 5：顶部那一排主菜单按钮在电脑端不再摆（＝手机端 018 那一条的同一写法，只换类名）。
     ⚠节点一枚不搬：门控与切页高亮都按「#mainTabs .tab」这把选择器找它们；这里只是不再摆出来。 */
  body.pc-side-on #mainTabs { display: none !important; }
  #pcSideMenu {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 90; width: var(--pc-side-w);
    overflow-y: auto; background: var(--panel); border-right: 1px solid var(--line);
  }
  /* 主菜单那一行：整行点得，右侧一枚箭头表示开／收（收起 › ／展开 ⌄，与手机端同一读法） */
  .pc-side-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 13px 12px; font-size: 14px; font-weight: 600; color: var(--text);
    background: var(--panel2); border-bottom: 1px solid var(--line); cursor: pointer;
    min-height: 46px; box-sizing: border-box;
  }
  .pc-side-head::after { content: "›"; font-size: 14px; color: var(--muted); }
  /* 没有子菜单的那一行（一级按钮自己就是某一页）：形状与主菜单行一模一样，只是右侧不给箭头——
     它展开不出东西，别画一个点不动的把手（＝手机端 .mp-side-leaf 同一条口径）。 */
  #pcSideMenu .pc-side-leaf > .pc-side-head::after { content: ""; }
  /* 展开着的那一行＝整行强调色底＋深色字（参考图那枚「当前展开的主菜单」读法） */
  .pc-side-open > .pc-side-head { background: var(--accent); border-color: var(--accent); color: #1c1f2b; }
  .pc-side-open > .pc-side-head::after { content: "⌄"; color: #1c1f2b; }
  /* 子菜单＝就住在这组下面的那一栏（页面上那一栏节点本体搬进来的），收起时整栏不见，展开才排出来 */
  #pcSideMenu .pc-side-bar { display: none !important; }
  #pcSideMenu .pc-side-open > .pc-side-bar { display: block !important; padding: 0; margin: 0; gap: 0; }
  /* 栏在这一列里一律竖着排（与手机端那一列同一条口径）；这里不加 !important：
     栏里子项的显隐仍归权限那两处行内 display:none 管，压不得。 */
  #pcSideMenu .tabs { display: block; padding: 0; margin: 0; gap: 0; }
  /* 套在一栏里面的那一层（员工管理那一组里的二级栏与三条三级栏＝022 起整块搬进这一列）往里缩一格＝两级读得出层级；
     这里不加 !important：三级栏那三条的显隐仍由页面自己的 empBarSync 写行内，谁被选中展开哪一条归它判。 */
  #pcSideMenu .pc-side-bar .tabs { padding-left: 12px; }
  /* 子项＝排在主菜单下面的一列，前面一枚 › 缩进 */
  #pcSideMenu .tabs .tab {
    position: relative; width: auto; box-sizing: border-box; border: none; border-radius: 0;
    border-bottom: 1px solid var(--line); padding: 11px 8px 11px 24px;
    min-height: 42px; display: flex; align-items: center; font-size: 13px; background: var(--panel);
    white-space: normal; line-height: 1.25; box-shadow: none;
  }
  #pcSideMenu .tabs .tab::before {
    content: "›"; position: absolute; left: 10px; color: var(--muted);
  }
  #pcSideMenu .tabs .tab.active {
    background: var(--accent); color: #1c1f2b; font-weight: 600; box-shadow: none;
  }
  #pcSideMenu .tabs .tab.active::before { color: #1c1f2b; }
}

/* 指令 20261102009・补尺：高消播报「消息推送选择」那两枚勾选框按自然尺寸画。:267 那行
   .form-row input { min-width: 120px } 量的是日期／文本／下拉那一族宽控件，勾选框住在同一行里就被撑成
   120px 的一格空白——文字挪到框前面之后，那 120px 正横在「服务号」与「机器人」两枚框之间。
   ⚠刻意不走 !important（第两百零五轮那套的钉子：带 !important 只许压容器，落子项会盖掉权限门控的行内 display:none）＝多带一层 .form-row 把特异性压过去。 */
.form-row input.wx-deal-chan { min-width: auto; width: auto; }
