* { box-sizing: border-box; margin: 0; padding: 0; }
:root {
  --blue:#2563eb; --blue-d:#1d4ed8; --green:#059669; --orange:#ea580c;
  --red:#dc2626; --line:#e5e7eb; --bg:#f6f7f9; --text:#1f2937; --muted:#6b7280;
}
body {
  font-family: "Microsoft YaHei", "PingFang SC", "Segoe UI", sans-serif;
  background: var(--bg); color: var(--text); font-size: 15px; line-height: 1.6;
}
.app { display: flex; min-height: 100vh; }

/* 侧边栏 */
.sidebar { width: 190px; background:#1e293b; color:#cbd5e1; flex-shrink:0; }
.brand { font-size:19px; font-weight:700; color:#fff; padding:20px 18px; border-bottom:1px solid #334155; }
.brand span { font-size:12px; font-weight:400; color:#64748b; margin-left:6px; }
.nav-item { display:block; padding:13px 18px; cursor:pointer; border-left:3px solid transparent; user-select:none; }
.nav-item:hover { background:#273449; color:#fff; }
.nav-item.active { background:#0f172a; color:#fff; border-left-color:var(--blue); }
.nav-in.active { border-left-color:var(--green); }
.nav-out.active { border-left-color:var(--orange); }

/* 主区 */
.main { flex:1; padding:26px 30px; overflow:auto; }
.view { display:none; }
.view.active { display:block; }
h1 { font-size:22px; margin-bottom:18px; display:flex; align-items:center; gap:14px; }
h2 { font-size:16px; margin:26px 0 12px; display:flex; align-items:center; gap:12px; }
h2 small { font-weight:400; color:var(--muted); font-size:13px; }
.hint { color:var(--muted); font-size:13px; margin-bottom:12px; }

/* 统计卡片 */
.cards { display:grid; grid-template-columns:repeat(auto-fit,minmax(155px,1fr)); gap:14px; }
.card { background:#fff; border:1px solid var(--line); border-radius:10px; padding:18px; }
.card .num { font-size:30px; font-weight:700; line-height:1.2; }
.card .lbl { color:var(--muted); font-size:13px; margin-top:4px; }
.card.warn .num { color:var(--red); }
.card.in .num { color:var(--green); }
.card.out .num { color:var(--orange); }

/* 工具栏 */
.toolbar { display:flex; gap:10px; align-items:center; margin-bottom:14px; flex-wrap:wrap; }
.search { flex:1; min-width:240px; }
.sep { color:var(--muted); }
input, select, textarea {
  padding:9px 12px; border:1px solid #d1d5db; border-radius:7px;
  font-size:15px; font-family:inherit; background:#fff;
}
input:focus, select:focus, textarea:focus { outline:none; border-color:var(--blue); box-shadow:0 0 0 3px #dbeafe; }
.chk { display:flex; align-items:center; gap:6px; color:var(--muted); cursor:pointer; white-space:nowrap; }
.chk input { width:16px; height:16px; }

/* 按钮 */
.btn { padding:9px 17px; border:1px solid #d1d5db; background:#fff; border-radius:7px;
       cursor:pointer; font-size:14px; font-family:inherit; }
.btn:hover { background:#f3f4f6; }
.btn.primary { background:var(--blue); border-color:var(--blue); color:#fff; }
.btn.primary:hover { background:var(--blue-d); }
.btn.green { background:var(--green); border-color:var(--green); color:#fff; }
.btn.orange { background:var(--orange); border-color:var(--orange); color:#fff; }
.btn.lg { padding:13px 34px; font-size:17px; }
.btn.sm { padding:5px 11px; font-size:13px; }
.btn.danger { color:var(--red); }

/* 表格 */
table { width:100%; border-collapse:collapse; background:#fff;
        border:1px solid var(--line); border-radius:10px; overflow:hidden; }
th, td { padding:11px 13px; text-align:left; border-bottom:1px solid var(--line); }
th { background:#f9fafb; font-weight:600; font-size:13px; color:#374151; white-space:nowrap; }
tr:last-child td { border-bottom:none; }
tbody tr:hover { background:#f9fafb; }
td.num, th.num { text-align:right; font-variant-numeric:tabular-nums; }
.qty { font-weight:700; font-size:16px; }
.qty.low { color:var(--red); }
.qty.zero { color:var(--muted); }
.tag { padding:2px 9px; border-radius:20px; font-size:12px; font-weight:600; }
.tag.in { background:#d1fae5; color:#065f46; }
.tag.out { background:#ffedd5; color:#9a3412; }
.tag.take { background:#ede9fe; color:#5b21b6; }
.empty { text-align:center; color:var(--muted); padding:44px; background:#fff;
         border:1px dashed var(--line); border-radius:10px; }

/* 出入库表单 */
.form-wrap { background:#fff; border:1px solid var(--line); border-radius:10px;
             padding:24px; max-width:640px; }
.field { margin-bottom:17px; }
.field label { display:block; margin-bottom:6px; font-size:14px; font-weight:600; }
.field label .req { color:var(--red); }
.field input, .field select, .field textarea { width:100%; }
.field .tip { font-size:12px; color:var(--muted); margin-top:5px; }
.row2 { display:grid; grid-template-columns:1fr 1fr; gap:15px; }
.picked { background:#eff6ff; border:1px solid #bfdbfe; border-radius:8px;
          padding:13px 15px; margin-bottom:16px; }
.picked .nm { font-weight:700; font-size:16px; }
.picked .meta { color:var(--muted); font-size:13px; margin-top:3px; }
.suggest { border:1px solid var(--line); border-radius:8px; max-height:230px;
           overflow:auto; margin-top:6px; background:#fff; }
.suggest div { padding:10px 13px; cursor:pointer; border-bottom:1px solid #f3f4f6; }
.suggest div:hover { background:#eff6ff; }

/* 弹窗 */
.modal-mask { display:none; position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:50; }
.modal-mask.show { display:flex; align-items:center; justify-content:center; }
.modal { background:#fff; border-radius:12px; padding:26px; width:min(600px,92vw);
         max-height:88vh; overflow:auto; }
.modal h3 { font-size:19px; margin-bottom:18px; }
.modal-btns { display:flex; gap:10px; justify-content:flex-end; margin-top:22px; }

/* 提示条 */
#toast { position:fixed; top:22px; left:50%; transform:translateX(-50%); z-index:99; }
.toast-item { background:#1e293b; color:#fff; padding:13px 24px; border-radius:9px;
              margin-bottom:9px; box-shadow:0 6px 18px rgba(0,0,0,.2); font-size:15px; }
.toast-item.ok { background:var(--green); }
.toast-item.err { background:var(--red); }

/* ============ 登录页 ============ */
.login-mask {
  position: fixed;
  inset: 0;
  background: #0f172a;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}
.login-box {
  width: 320px;
  background: #fff;
  border-radius: 10px;
  padding: 32px 28px 24px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .35);
}
.login-title {
  font-size: 20px;
  font-weight: 600;
  text-align: center;
  margin-bottom: 24px;
  color: #1e293b;
}
.login-box label {
  display: block;
  font-size: 13px;
  color: #64748b;
  margin: 12px 0 5px;
}
.login-box input {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  font-size: 14px;
  box-sizing: border-box;
}
.login-box input:focus {
  outline: none;
  border-color: #2563eb;
}
.login-err {
  min-height: 20px;
  font-size: 13px;
  color: #dc2626;
  margin: 10px 0 2px;
}
.btn.block {
  display: block;
  width: 100%;
  padding: 10px;
  font-size: 15px;
}
.login-foot {
  margin-top: 14px;
  text-align: center;
  font-size: 12px;
  color: #94a3b8;
}

/* ============ 侧边栏底部的当前用户 ============ */
.sidebar {
  display: flex;
  flex-direction: column;

  /* 侧栏钉在屏幕上，不跟着右边的内容一起长。
     原来 .app 是 flex，侧栏被拉到和主区一样高 —— 商品列表有 129 行时它就有
     129 行那么高，底下的「改密码 / 退出」自然掉到整页最下面，得滚到底才够得着。
     align-self 收掉那个拉伸，再给一屏的高度，sticky 才有得吸。 */
  position: sticky;
  top: 0;
  align-self: flex-start;
  height: 100vh;
  overflow-y: auto;          /* 屏幕矮到菜单都装不下时，让侧栏自己滚 */
}
.sidebar nav {
  flex: 1;                   /* 把 userbar 顶到侧栏底部 */
}
.userbar {
  border-top: 1px solid rgba(255, 255, 255, .12);
  padding: 14px 18px 16px;
}
.uname {
  color: #e2e8f0;
  font-size: 14px;
  font-weight: 500;
}
.urole {
  color: #94a3b8;
  font-size: 12px;
  margin-top: 2px;
}
.ulinks {
  margin-top: 8px;
  display: flex;
  gap: 14px;
}
.ulinks a {
  color: #94a3b8;
  font-size: 12px;
  cursor: pointer;
  text-decoration: none;
}
.ulinks a:hover {
  color: #e2e8f0;
  text-decoration: underline;
}

/* 按角色隐藏菜单。
   这里原来只写了 [data-manager]，而「员工账号 / 操作日志 / 系统与备份」标的是
   data-owner —— 结果 JS 明明给它们加上了 hidden-role，CSS 里却没有对应的规则，
   店员照样看得见这三项。后端拦得住接口，但菜单摆在那儿本身就是错的。 */
.nav-item[data-manager].hidden-role,
.nav-item[data-owner].hidden-role {
  display: none;
}

.tag-manager, .tag-clerk {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 3px;
  font-size: 12px;
}
.tag-manager { background: #dbeafe; color: #1d4ed8; }
.tag-clerk   { background: #f1f5f9; color: #475569; }
.row-off { opacity: .5; }

/* ============ 录单页 ============ */
.order-head {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 14px 16px;
  margin-bottom: 12px;
}
.field.inline { flex: 1; min-width: 200px; margin: 0; }
.field.inline.narrow { flex: 0 0 150px; min-width: 150px; }
.field.inline label { display: block; font-size: 12px; color: #64748b; margin-bottom: 4px; }
.field.inline input, .field.inline select {
  width: 100%; padding: 7px 10px; border: 1px solid #cbd5e1;
  border-radius: 5px; font-size: 14px; box-sizing: border-box;
}

/* 客户 / 商品搜索选择器 */
.picker { position: relative; }
.picker-list {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 30;
  background: #fff; border: 1px solid #cbd5e1; border-radius: 6px;
  box-shadow: 0 6px 20px rgba(0,0,0,.12); max-height: 260px; overflow-y: auto;
  display: none;
}
.picker-list.show { display: block; }
.picker-list div { padding: 8px 12px; cursor: pointer; font-size: 14px; border-bottom: 1px solid #f1f5f9; }
.picker-list div:last-child { border-bottom: none; }
.picker-list div:hover, .picker-list div.on { background: #eff6ff; }
.picker-list .muted { color: #94a3b8; font-size: 12px; }
.picker-list .mk { color: #2563eb; }
/* 候选列表最底下那行「＋ 新建…」：和候选区分开，不然会被当成搜到的结果点错 */
.picker-list .pick-new {
  color: #2563eb; font-weight: 600; background: #f8fafc;
  border-top: 1px solid #e2e8f0;
}
.picker-list .pick-new:hover { background: #eff6ff; }

.order-tools { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.order-tools .grow { flex: 1; }

/* 录单明细表 */
.line-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.line-table th {
  background: #f1f5f9; color: #475569; font-weight: 600; font-size: 12px;
  text-align: left; padding: 8px 8px; border-bottom: 1px solid #e2e8f0; white-space: nowrap;
}
.line-table td { padding: 5px 8px; border-bottom: 1px solid #f1f5f9; vertical-align: middle; }
.line-table tr.bad { background: #fff7ed; }
.line-table tr.bad td:first-child { box-shadow: inset 3px 0 0 #f97316; }
.line-table input {
  width: 100%; padding: 5px 7px; border: 1px solid #cbd5e1;
  border-radius: 4px; font-size: 14px; box-sizing: border-box;
}
.line-table input.num { text-align: right; }
.line-table input:focus { outline: none; border-color: #2563eb; }
.line-table .amt { text-align: right; font-variant-numeric: tabular-nums; color: #334155; }
.line-table .op { text-align: center; }
.line-table .del {
  border: none; background: none; color: #94a3b8; cursor: pointer; font-size: 16px; padding: 2px 6px;
}
.line-table .del:hover { color: #dc2626; }
.line-name { display: flex; flex-direction: column; gap: 2px; }
.line-name b { font-weight: 500; }
.line-name small { color: #94a3b8; font-size: 12px; }
.price-src { font-size: 11px; padding: 1px 5px; border-radius: 3px; white-space: nowrap; }
.src-customer { background: #dcfce7; color: #15803d; }
.src-default  { background: #f1f5f9; color: #64748b; }
.src-none     { background: #fef3c7; color: #b45309; }

.order-foot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 14px; padding-top: 14px; border-top: 2px solid #e2e8f0;
}
.totals { font-size: 15px; color: #334155; }
.totals b { font-size: 20px; color: #0f172a; margin: 0 4px; }

/* 粘贴对话框 */
.paste-box {
  width: 100%; min-height: 200px; font-family: Consolas, Menlo, monospace;
  font-size: 13px; padding: 10px; border: 1px solid #cbd5e1; border-radius: 6px;
  box-sizing: border-box; line-height: 1.6;
}
.paste-tip { background: #f8fafc; border-left: 3px solid #94a3b8; padding: 8px 12px;
             font-size: 12px; color: #64748b; margin: 10px 0; line-height: 1.7; }

.tag-ordered  { background:#dbeafe; color:#1d4ed8; padding:1px 7px; border-radius:3px; font-size:12px; }
.tag-received { background:#dcfce7; color:#15803d; padding:1px 7px; border-radius:3px; font-size:12px; }
.tag-void     { background:#fee2e2; color:#b91c1c; padding:1px 7px; border-radius:3px; font-size:12px; }
.gap-neg { color:#dc2626; font-weight:600; }
.gap-pos { color:#15803d; font-weight:600; }

/* 行内商品候选浮层：整页共用一个，fixed 贴到当前输入框下方 */
.line-suggest {
  position: fixed;
  z-index: 900;
  /* 高度和上下翻转由 lsPlace() 按屏幕剩余空间算，这里不写死 —— 写死 300px
     的话，录到第十几行时浮层会直接掉到屏幕外面 */
  overflow-y: auto;
}
.line-suggest div { line-height: 1.5; }
.line-suggest .muted { display: block; }

.mini-link {
  font-size: 12px; color: #2563eb; cursor: pointer; margin-left: 8px; font-weight: normal;
}
.mini-link:hover { text-decoration: underline; }
.walkin-badge {
  display: inline-block; background: #fef3c7; color: #b45309;
  padding: 1px 7px; border-radius: 3px; font-size: 12px; margin-right: 6px;
}

/* ============ 「添加一行」跟着录入位置 ============ */
.empty-lines {
  text-align: center;
  padding: 44px 20px 40px;
  border: 1px dashed #cbd5e1;
  border-radius: 8px;
  background: #fafbfc;
}
.empty-word { color: #64748b; font-size: 15px; margin-bottom: 16px; }
.empty-tip  { color: #94a3b8; font-size: 12px; margin-top: 14px; }

.add-row {
  border-top: 1px dashed #e2e8f0;
  padding: 0;
}
.btn.add-line {
  width: 100%;
  border: none;
  background: transparent;
  color: #2563eb;
  padding: 11px 0;
  font-size: 14px;
  border-radius: 0;
}
.btn.add-line:hover { background: #eff6ff; }
.empty-lines .btn.add-line {
  width: auto;
  padding: 9px 22px;
  border-radius: 6px;
  background: #2563eb;
  color: #fff;
}
.empty-lines .btn.add-line:hover { background: #1d4ed8; }

/* 已选定的商品名：提示可以双击重选 */
.line-name.editable { cursor: pointer; border-radius: 4px; padding: 2px 4px; margin: -2px -4px; }
.line-name.editable:hover { background: #f1f5f9; }
.line-name.editable:hover b { text-decoration: underline dotted #94a3b8; }

/* 数量 / 单价：不要浏览器自带的上下箭头。
   剩下的 number 输入（点货页实收数量）也一并去掉 —— 箭头容易误点，
   鼠标滚轮划过还会偷偷改数字，开单和点货都经不起这种误操作。 */
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type=number] { -moz-appearance: textfield; appearance: textfield; }

/* ============ 盘点 ============ */
.qty-edit {
  cursor: pointer;
  border-bottom: 1px dashed #94a3b8;
  color: #0f172a;
  font-variant-numeric: tabular-nums;
}
.qty-edit:hover { color: #2563eb; border-bottom-color: #2563eb; background: #eff6ff; }
.qty-edit.low  { color: #b45309; }
.qty-edit.zero { color: #94a3b8; }

.take-now {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  padding: 12px 16px;
  margin-bottom: 4px;
  display: flex;
  align-items: baseline;
  gap: 10px;
  color: #64748b;
  font-size: 13px;
}
.take-now b { font-size: 22px; color: #0f172a; font-variant-numeric: tabular-nums; }
.take-now .u { color: #94a3b8; }

.take-tags { margin-top: 7px; display: flex; flex-wrap: wrap; gap: 6px; }
.take-tags a {
  font-size: 12px;
  padding: 3px 9px;
  border: 1px solid #cbd5e1;
  border-radius: 12px;
  color: #475569;
  cursor: pointer;
}
.take-tags a:hover { background: #eff6ff; border-color: #2563eb; color: #2563eb; }

/* 单位下拉：和旁边的输入框长得一样 */
.field select {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  font-size: 14px;
  box-sizing: border-box;
  background: #fff;
}
.field select:focus { outline: none; border-color: #2563eb; }
#pUnitOther { margin-top: 6px; }

/* 来源列里的原价对比 */
.price-base {
  margin-top: 3px;
  font-size: 11px;
  color: #94a3b8;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.price-base .off-down { color: #dc2626; margin-left: 3px; }
.price-base .off-up   { color: #15803d; margin-left: 3px; }

/* ============ 录单表格：固定列宽 ============
   商品名长短差别很大（「刀片」和「圣戈班杰科轻质抹灰石膏」），
   自适应布局会让商品列一直撑，把数量单价推到屏幕最右边，
   录单时眼睛要横扫一大段才找得到要填的框。固定列宽就不会。 */
.line-table.fixed { table-layout: fixed; }

.line-table .c-no    { width: 36px;  color: #94a3b8; }
.line-table .c-name  { width: auto; }
.line-table .c-qty   { width: 116px; }
.line-table .c-price { width: 96px; }
.line-table .c-base  { width: 104px; }
.line-table .c-amt   { width: 96px; }
.line-table .c-op    { width: 72px; }

/* 商品名太长时截断，鼠标放上去有完整名称 */
.line-table .c-name .line-name b {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.line-table .c-name .line-name small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 原价列 */
.c-base .base-num { color: #64748b; font-variant-numeric: tabular-nums; }
.c-base .off-down { color: #dc2626; margin-left: 5px; font-size: 12px; }
.c-base .off-up   { color: #15803d; margin-left: 5px; font-size: 12px; }
.c-base .muted    { color: #cbd5e1; }

/* ============ 录单区域宽度与密度 ============
   两个极端都试过：铺满 1900px 时一行横跨大半个屏幕，核对要转头；
   收到 780px 又在宽屏上右边空一大片，界面显得干瘪。
   1120px 是个合适的中间值 —— 一眼扫得完一行，又不至于空荡。 */
.order-head,
.order-tools,
.order-foot,
#sellLines,
#poLines {
  max-width: 1120px;
}
.line-table.fixed { max-width: 1120px; }

/* 数字列给足宽度，其余留给商品名 */
.line-table .c-no    { width: 40px; }
.line-table .c-name  { width: auto; }
.line-table .c-qty   { width: 130px; }
.line-table .c-price { width: 108px; }
.line-table .c-base  { width: 124px; }
.line-table .c-amt   { width: 112px; }
.line-table .c-op    { width: 78px; }

/* 录单行要经得起长时间盯着看，行高和输入框都放宽些 */
.line-table td { padding: 9px 10px; }
.line-table th { padding: 10px 10px; font-size: 13px; }
.line-table input {
  padding: 8px 10px;
  font-size: 15px;
}
.line-name b { font-size: 15px; }
.line-name small { font-size: 12.5px; margin-top: 3px; }
.line-table .amt { font-size: 15px; }

.c-base .base-num { font-size: 14px; }

/* 商品名太长时截断，鼠标放上去看全名 */
.line-table .c-name .line-name b,
.line-table .c-name .line-name small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 窄屏（笔记本）下不受限，该占满还是占满 */
@media (max-width: 1180px) {
  .order-head, .order-tools, .order-foot,
  #sellLines, #poLines, .line-table.fixed { max-width: 100%; }
}

/* 三级角色标签 */
.tag-owner   { background: #fef3c7; color: #b45309; padding: 1px 7px; border-radius: 3px; font-size: 12px; }
.tag-manager { background: #dbeafe; color: #1d4ed8; padding: 1px 7px; border-radius: 3px; font-size: 12px; }
.tag-clerk   { background: #f1f5f9; color: #475569; padding: 1px 7px; border-radius: 3px; font-size: 12px; }

/* ============ 客户报价单 ============ */
.quote-tools { display: flex; gap: 10px; align-items: flex-start; margin: 12px 0 10px; }
.quote-tools .picker { position: relative; }
.quote-tools .picker input {
  width: 100%; padding: 8px 11px; border: 1px solid #cbd5e1;
  border-radius: 6px; font-size: 14px; box-sizing: border-box;
}
.quote-tools .picker input:focus { outline: none; border-color: #2563eb; }
.quote-tools .picker-list { max-height: 240px; }
.quote-body {
  /* 从弹窗搬到整页之后，列表可以吃掉一屏的大半 —— 弹窗里那个 46vh 是被
     弹窗自身的高度逼出来的，页面上没这个约束 */
  max-height: calc(100vh - 300px);
  min-height: 240px;
  overflow-y: auto;
  border: 1px solid #e2e8f0; border-radius: 6px;
}

/* 报价单页标题左边的返回 */
.back-link {
  font-size: 13px; font-weight: 400; color: #2563eb; cursor: pointer;
  padding: 3px 9px; border: 1px solid #dbeafe; border-radius: 6px; background: #eff6ff;
}
.back-link:hover { background: #dbeafe; }
h1 small { font-weight: 400; font-size: 13px; color: #94a3b8; }
.quote-body .line-table { table-layout: auto; max-width: none; }
.quote-body .line-table th {
  position: sticky; top: 0; background: #f1f5f9; z-index: 2;
}

/* 被送回去的那一行闪一下黄，一秒退掉 */
@keyframes lineFlash {
  from { background: #fde68a; }
  to   { background: transparent; }
}
.line-table tr.line-flash td { animation: lineFlash 1.2s ease-out; }

/* 未匹配行下面那排候选。
   它们是没有 href 的 <a>，浏览器对这种不给手型光标、不给下划线，颜色也从
   外层那句橙字继承下来 —— 结果「点一下确认是哪个：」和三个候选长得一模一样，
   看上去整句都是提示文字。做成能看出边界的小按钮，鼠标移上去再变色。 */
/* 选择器要压过上面 .line-table .c-name .line-name small 的 nowrap + ellipsis，
   否则候选排不下时会被截成「中财 红八角盒 中财 红线…」，后面两个直接点不到 */
.line-table .c-name .line-name small.cand-tip {
  color: #f97316;
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}
.cand {
  display: inline-block;
  cursor: pointer;
  padding: 1px 9px;
  margin: 2px 0;
  border: 1px solid #fdba74;
  border-radius: 12px;
  background: #fff;
  color: #c2410c;
  font-weight: 600;
  line-height: 1.8;
  transition: background .12s, border-color .12s;
}
.cand:hover { background: #ffedd5; border-color: #f97316; color: #9a3412; }
.cand:active { background: #fed7aa; }
.cand .muted { color: #a8a29e; font-weight: 400; }

/* 数量框和单位并排。输入框是 width:100%，不包一层 flex 的话单位会被挤到下一行 */
.line-table .qty-cell { display: flex; align-items: center; gap: 5px; }
.line-table .qty-cell .u {
  color: #94a3b8; font-size: 12px; white-space: nowrap; flex: none;
}

/* 在线状态的小圆点：绿=在线，灰=不在线 */
.dot-on  { color: #16a34a; font-size: 11px; }
.dot-off { color: #cbd5e1; font-size: 11px; }

/* 弹窗里的勾选项 */
.check { display: flex; align-items: center; gap: 8px; cursor: pointer; margin: 4px 0 10px; }
.check input { width: auto; margin: 0; }

/* 数量后面的单位下拉（能整包卖的商品才有） */
.line-table .qty-cell .u-sel {
  width: auto; flex: none; padding: 4px 2px; font-size: 12px;
  border: 1px solid #cbd5e1; border-radius: 4px; background: #fff;
  color: #475569; cursor: pointer;
}
.line-table .qty-cell .u-sel:focus { outline: none; border-color: #2563eb; }

/* 商品表单里的整包卖法一块 */
.pack-box {
  border: 1px solid #e2e8f0; border-radius: 8px;
  padding: 12px 14px; margin: 4px 0 12px; background: #f8fafc;
}
.pack-title { font-weight: 600; font-size: 13px; color: #475569; margin-bottom: 4px; }
.row3 { display: flex; gap: 12px; }
.row3 .field { flex: 1; margin: 0; }

/* 行内商品浮层：高亮只认 .on 这一个来源。
   :hover 再画一层的话，键盘光标停在第 1 条、鼠标恰好停在第 4 条上，
   屏幕上就有两条是蓝的 —— 回车到底选哪个，看的人没法判断。
   鼠标划过会把 .on 带过去（见 lsSetCursor），所以这里撤掉 :hover 不会失去反馈。 */
.line-suggest div:hover:not(.on) { background: transparent; }

/* 删除前的影响清单 */
table.kv { width: 100%; margin: 10px 0 4px; border-collapse: collapse; font-size: 14px; }
table.kv td { padding: 6px 0; border-bottom: 1px solid #f1f5f9; }
table.kv td:last-child { text-align: right; }
table.kv tr:last-child td { border-bottom: none; }
.warn-box {
  background: #fef2f2; border: 1px solid #fecaca; color: #991b1b;
  border-radius: 6px; padding: 10px 12px; font-size: 13px; line-height: 1.7; margin-top: 8px;
}

/* 报价单里「还没加进来的」候选块。排在列表上面、占位置，不做浮层 —— 浮层会盖住
   下面正要改价的行，而这两块内容恰恰是要对着看的 */
.quote-cands {
  border-bottom: 2px solid #e2e8f0;
  background: #f8fafc;
}
.quote-cands-title {
  padding: 7px 12px 4px; font-size: 12px; color: #64748b;
}
.quote-cand {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 12px; border-top: 1px solid #eef2f7;
}
.quote-cand .mk { color: #2563eb; font-weight: 500; flex: 1; }
.quote-cand .muted { color: #94a3b8; font-size: 12px; white-space: nowrap; }

/* 单据查询的工具栏塞了单号、客户、出单人、类型、两个日期，窄屏要能换行，
   三个输入框也不必抢成一样宽 —— 单号最长，客户次之，出单人最短 */
#view-orders .toolbar { flex-wrap: wrap; }
#view-orders #ordQ        { flex: 2 1 200px; }
#view-orders #ordPartner  { flex: 2 1 160px; }
#view-orders #ordOperator { flex: 1 1 120px; }

/* 操作日志工具栏：两个下拉各自够宽，关键词框吃掉剩下的空间，窄屏换行 */
#view-audit .toolbar { flex-wrap: wrap; }
#view-audit #auditUser,
#view-audit #auditAction { flex: 0 1 160px; }
#view-audit #auditQ      { flex: 2 1 220px; }

/* 商品管理工具栏：搜索框占大头，两个下拉各自够宽就行，窄屏换行 */
#view-goods .toolbar { flex-wrap: wrap; }
#view-goods #goodsQ { flex: 3 1 240px; }
/* 现在 input 外面包了一层 .picker（下拉浮层要定位在它上面），
   所以撑宽度的是外层那个盒子，input 自己填满它 */
#view-goods #goodsBrandBox,
#view-goods #goodsCatBox { flex: 1 1 120px; position: relative; }
#view-goods #goodsBrandBox input,
#view-goods #goodsCatBox input { width: 100%; }

/* ============ 送货单 ============ */
.modal.modal-wide { width: min(920px, 96vw); }
.receipt-wrap { max-height: 62vh; overflow: auto; background: #f8fafc;
                padding: 14px; border-radius: 8px; }

.receipt {
  background: #fff; color: #000; padding: 16px 20px;
  font-family: "SimSun", "宋体", serif;   /* 送货单是给客户的纸，用宋体更像单据 */
  font-size: 13px; line-height: 1.5;
}
.rc-title { text-align: center; font-size: 20px; font-weight: 700; letter-spacing: 2px;
            padding-bottom: 8px; }
.rc-meta { display: flex; gap: 18px; padding: 2px 0; }
.rc-meta .rc-date { margin-left: auto; }
/* 地址行高度写死一行：地址长短不一，不固定的话每张纸的表格起始位置都不一样，
   一叠单子摞起来看着就不齐。太长的截断，反正纸上印不下 */
.rc-addr {
  padding: 2px 0 6px; height: 26px; line-height: 20px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}

.rc-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.rc-table th, .rc-table td {
  border: 1px solid #000; padding: 4px 6px; word-break: break-all;
}
.rc-table th { text-align: center; font-weight: 700; }
.rc-table td.c { text-align: center; }
.rc-table td.n { text-align: right; font-variant-numeric: tabular-nums; }
.rc-table tr.blank td { height: 22px; }
/* 签字栏排两行：制单和配货并排，复核单独一行。
   原来靠全角空格挤在一行，制单人名字一长「复核」就被挤断成半截。 */
.rc-sign { line-height: 1.9; }
.rc-sign-row { display: flex; gap: 12px; }
.rc-sign-row span { flex: 1; white-space: nowrap; }
.rc-no { text-align: right; padding-top: 6px; font-size: 11px; color: #444; }

/* 打印：纸上只留送货单本身。
   把它固定到左上角铺满，是因为它原本躺在弹窗里 —— 不挪出来的话，
   打出来会跟着弹窗一起缩在页面中间一小块。 */
/* 打印：纸上只留送货单本身。
 *
 * 原来的写法是「全部 visibility:hidden，只放出送货单」，再把它绝对定位到左上角
 * 铺满。问题出在 width:100% —— 绝对定位元素的百分比是相对最近的定位祖先算的，
 * 那是宽 920px 的弹窗，比 A4 的可打印宽度还宽，右边的单价、金额、备注三列
 * 连同半个标题一起被裁掉了。
 *
 * 改成把弹窗以外的东西整个 display:none 拿出文档流，再把弹窗那串祖先的宽度、
 * 定位、内边距全部中和掉。送货单于是按纸的宽度自然排版，不存在裁切。 */
@media print {
  body > *:not(#modalMask) { display: none !important; }

  #modalMask {
    display: block !important; position: static !important;
    background: none !important; inset: auto !important;
  }
  #modal {
    position: static !important; width: auto !important; max-width: none !important;
    margin: 0 !important; padding: 0 !important;
    border-radius: 0 !important; box-shadow: none !important;
  }
  /* 弹窗自己的标题和按钮不该印上纸 */
  #modal > h3, #modal > .modal-btns, #modal > .hint { display: none !important; }

  .receipt-wrap {
    max-height: none !important; overflow: visible !important;
    background: none !important; padding: 0 !important;
  }
  .receipt { padding: 0 !important; font-size: 12px; }
  /* 「待交付」是给店里看的状态。客户手上那张纸不需要 —— 货就在他眼前，
     纸上写「待交付」只会让人以为还有什么没办完 */
  .rc-pending { display: none !important; }
  .rc-table tr { page-break-inside: avoid; }
  @page { margin: 12mm; }
}

/* 待出库：明细已经在了，库存还没动 */
.tag-pending { background:#fef3c7; color:#b45309; padding:1px 7px; border-radius:3px; font-size:12px; }
.rc-pending { border:1px solid #b45309; color:#b45309; padding:0 4px; }

/* 「确认出库」是真正动库存的那一步，做成实心的，和旁边只看看的按钮区分开 */
.btn.go { background: var(--green); border-color: var(--green); color: #fff; }
.btn.go:hover { background: #047857; border-color: #047857; }

/* 正在改某张单时顶上的提示条 —— 不摆出来的话，人分不清这是在开新单还是在改旧单 */
.edit-bar {
  background: #fffbeb; border: 1px solid #fde68a; color: #92400e;
  padding: 9px 14px; border-radius: 8px; margin-bottom: 12px;
  display: flex; align-items: center; gap: 12px; max-width: 1120px;
}
.edit-bar a { color: #2563eb; cursor: pointer; margin-left: auto; }
.edit-bar a:hover { text-decoration: underline; }

/* 概览上能点的卡片 */
.card.clickable { cursor: pointer; transition: transform .1s, box-shadow .1s; }
.card.clickable:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0,0,0,.10); }

/* 交付状态 */
.tag-done    { background:#dcfce7; color:#15803d; padding:1px 7px; border-radius:3px; font-size:12px; }
.tag-pending { background:#fef3c7; color:#b45309; padding:1px 7px; border-radius:3px; font-size:12px; }

/* 库存预警弹窗里的表格，多了会滚 */
.low-wrap { max-height: 60vh; overflow-y: auto; }

#view-orders #ordShipped { flex: 0 0 auto; }
