/* ===== 贸易业务台 · 产品库 / 销售管理 ===== */
:root{
  --bg:#f5f6f8; --panel:#ffffff; --panel-2:#fafbfc; --panel-3:#f2f4f7;
  --text:#1f2329; --muted:#6b7280; --faint:#9aa3af;
  --border:#e5e7eb; --border-strong:#d5d9e0;
  --accent:#3c6ef2; --accent-soft:#e8f0fe;
  --green:#16a34a; --green-soft:#ecfdf3;
  --amber:#d97706; --amber-soft:#fffaeb;
  --red:#dc2626; --red-soft:#fef3f2;
  --violet:#7c3aed; --violet-soft:#f5f3ff;
  --teal:#0d9488; --teal-soft:#f0fdfa;
  --shadow:0 1px 2px rgba(16,24,40,.05), 0 4px 14px rgba(16,24,40,.06);
  --radius:10px;
}
*{box-sizing:border-box}
[hidden]{display:none !important}
html,body{margin:0;height:100%}
body{
  background:var(--bg); color:var(--text); font-size:13.5px; line-height:1.55;
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei","Hiragino Sans GB",sans-serif;
}
button,input,textarea,select{font-family:inherit;font-size:inherit;color:inherit}
h1{font-size:16px;margin:0;font-weight:650}
code{background:#eef1f5;padding:1px 5px;border-radius:4px;font-size:12px}
a{color:var(--accent);text-decoration:none}

/* ---------- 顶栏 ----------
   0.75.51：跟下面那条 .appnav 连成一块深蓝 #33475f —— 这一身原本只给企业邮箱页
   （见本文件末尾的 ML:SKIN 段），这版起全站统一。
   ★ padding:12px 20px / .appnav 的 top:57px 一个数都别动，动了全站吸顶错位。 */
.topbar{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:12px 20px;background:#33475f;border-bottom:0;
  position:sticky;top:0;z-index:20;
}
.topbar h1{color:#fff}
.brand{display:flex;align-items:center;gap:10px}
.logo{
  width:32px;height:32px;border-radius:9px;background:linear-gradient(135deg,#3c6ef2,#7ea4ff);
  color:#fff;display:grid;place-items:center;font-size:16px;
}
/* 深蓝底上提一档亮度。★ .logo.teal / .logo.violet 是**有意的页面识别色**
   （操作日志 / 研发那两页），权重跟 .topbar .logo 同级，所以必须排在它后面。 */
.topbar .logo{background:linear-gradient(135deg,#4d7dfd,#7ea4ff)}
.logo.teal{background:linear-gradient(135deg,#0d9488,#5eead4)}
.logo.violet{background:linear-gradient(135deg,#7c3aed,#c4b5fd)}
.sub{color:var(--faint);font-size:12px}
.topbar .sub{color:rgba(255,255,255,.62)}
.top-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}

/* ---------- 应用导航 ----------
   0.75.51 起跟上面的 .topbar 连成一块深蓝（原来只染企业邮箱页）。 */
.appnav{
  display:flex;gap:4px;padding:0 20px;background:#33475f;border-bottom:0;
  box-shadow:inset 0 -1px 0 rgba(255,255,255,.09);position:sticky;top:57px;z-index:19;
}
.appnav a{
  padding:9px 14px;font-size:13px;color:rgba(255,255,255,.72);border-bottom:2px solid transparent;
  display:flex;align-items:center;gap:6px;transition:.15s;
}
.appnav a:hover{color:#fff;background:rgba(255,255,255,.08)}
.appnav a.on{color:#fff;border-bottom-color:#fff;font-weight:600}
.appnav a .n{
  font-size:11px;background:rgba(255,255,255,.10);border-radius:999px;padding:0 6px;
  color:rgba(255,255,255,.72);
}
.appnav a.on .n{background:rgba(255,255,255,.16);color:#fff}
/* 行尾一句说明：深蓝底上要把 .hint 的浅底浅框剥掉（跟 style.css 里 .modnav .hint
   一个写法），不然是一块白底浅灰字压在 navy 上，看着像贴错位的标签。 */
.appnav .hint{align-self:center;font-size:12px;color:rgba(255,255,255,.42);padding-left:12px;
  background:transparent;border:0;border-radius:0;margin:0}
/* 待办红点：业绩评估入口上「轮到你打分」的份数（0.75.16 系统内推送）。
   红而不是灰：这是要人动手的事，不是「有多少条记录」那种背景信息。 */
.appnav a .todo{
  font-size:11px;line-height:16px;min-width:16px;text-align:center;font-weight:600;
  background:#dc2626;color:#fff;border-radius:999px;padding:0 5px;
}

/* ---------- 按钮 ---------- */
.btn{
  border:1px solid var(--border-strong);background:var(--panel);border-radius:8px;
  padding:6px 12px;cursor:pointer;transition:.15s;white-space:nowrap;
}
.btn:hover{background:var(--panel-2);border-color:#c3c9d4}
.btn-primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn-primary:hover{background:#2f55c9}
.btn-ghost{border-color:transparent;background:transparent}
.btn-ghost:hover{background:#eef1f5}
.btn-sm{padding:3px 9px;font-size:12px;border-radius:6px}
.btn-danger{color:var(--red);border-color:#fca5a5}
.btn-danger:hover{background:var(--red-soft)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn-ok{color:#067647;border-color:#abefc6}
.btn-ok:hover{background:var(--green-soft)}
/* 下载 PDF 专用：Adobe 官方 PDF 红 #EC1C24，跟蓝色的「下载（原文件）」分开 ——
   同一屏上两个下载按钮，颜色不一样才不会点错发给客户。
   hover 必须自己写一条：.btn:hover 的权重比 .btn-pdf 高，不写会被顶成灰色。 */
.btn-pdf{background:#EC1C24;border-color:#EC1C24;color:#fff}
.btn-pdf:hover{background:#C4120F;border-color:#C4120F}
.src-pill{
  font-size:12px;padding:3px 10px;border-radius:999px;background:#eef1f5;color:var(--muted);
  border:1px solid var(--border);
}
.src-pill.live{background:var(--green-soft);color:#067647;border-color:#abefc6}
.src-pill.demo{background:var(--amber-soft);color:#b54708;border-color:#fedf89}
/* 顶栏深蓝上，浅灰底 / 绿底 / 黄底的 pill 都太跳 —— 进到顶栏里一律翻成半透明白
   （出顶栏的实时状态仍然保原色） */
.topbar .src-pill,
.topbar .src-pill.live,
.topbar .src-pill.demo{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.25);color:rgba(255,255,255,.85)}

/* ---------- KPI ---------- */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px;padding:14px 20px 4px}
.kpi{
  background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);
  padding:10px 14px;box-shadow:var(--shadow);transition:.15s;
}
.kpi .n{font-size:22px;font-weight:680;line-height:1.25}
.kpi .l{font-size:12px;color:var(--muted);margin-top:2px}
.kpi.clickable{cursor:pointer}
.kpi.clickable:hover{border-color:#b9c2d0;transform:translateY(-1px)}
.kpi.warn .n{color:var(--amber)}
.kpi.danger .n{color:var(--red)}
.kpi.ok .n{color:var(--green)}
.kpi.accent .n{color:var(--accent)}
.kpi .n small{font-size:12px;font-weight:500;color:var(--faint)}
/* 可下钻的 KPI（已收款 / 待收款）：右下角给一个「明细 ›」的入口提示 */
.kpi .l .drill{
  display:inline-block;margin-left:5px;font-size:11px;color:var(--faint);
  border:1px solid var(--border);border-radius:999px;padding:0 6px;
}
.kpi.clickable:hover .l .drill{color:var(--accent);border-color:var(--accent)}

/* ---------- 收款明细下钻表 ---------- */
#recvTb .rvrow{cursor:pointer}
#recvTb .rvrow:hover{background:var(--panel-2)}
#recvTb .rvrow .lnk{color:var(--accent);border-bottom:1px dashed currentColor}
#recvTb .payln td{background:var(--panel-2);padding-top:2px;padding-bottom:2px;font-size:12px}
#recvTb .payln:hover{background:var(--panel-2)}

/* ---------- 产品销量看板 ---------- */
#prodTb .prk{cursor:pointer}
#prodTb .prk-det td{background:var(--panel-2);font-size:12px;padding:6px 9px}

/* ---------- 排行看板（客户 / 业务员） ---------- */
.rank-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));
  gap:12px;padding:14px 16px 24px;
}
.rcard{
  border:1px solid var(--border);border-radius:var(--radius);background:var(--panel);
  padding:11px 13px;cursor:pointer;transition:.15s;box-shadow:var(--shadow);
}
.rcard:hover{border-color:var(--accent);transform:translateY(-2px)}
.rcard .rk-h{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.rcard .rk-no{
  flex:0 0 auto;min-width:20px;height:20px;border-radius:6px;background:var(--panel-3);
  color:var(--muted);font-size:11px;text-align:center;line-height:20px;font-weight:700;
}
.rcard .rk-nm{font-size:13.5px;font-weight:660;word-break:break-word}
.rcard .rk-line{display:flex;gap:4px}
.rcard .rk-amt{font-size:19px;font-weight:700;margin-top:7px}
.rcard .rk-sub{font-size:11.5px;color:var(--muted);margin-top:1px}
.rcard .rk-meta{display:flex;gap:5px;flex-wrap:wrap;margin-top:8px}
.rcard .rk-foot{
  display:flex;justify-content:space-between;align-items:center;
  margin-top:8px;padding-top:7px;border-top:1px solid var(--border);font-size:11.5px;
}
/* 工具栏上的「只看 XX」标记 */
#focusChip{display:inline-flex;align-items:center;gap:6px}
.chip-x{
  border:0;background:transparent;cursor:pointer;color:inherit;
  font-size:14px;line-height:1;padding:0 2px;opacity:.7;
}
.chip-x:hover{opacity:1}

/* ---------- 工具栏 ---------- */
.toolbar{
  display:flex;align-items:center;gap:10px;padding:10px 20px;flex-wrap:wrap;
  background:var(--panel);border-top:1px solid var(--border);border-bottom:1px solid var(--border);
  position:sticky;top:96px;z-index:18;
}
.search{
  flex:1;min-width:200px;max-width:380px;border:1px solid var(--border-strong);border-radius:8px;
  padding:6px 12px;background:var(--panel);
}
.search:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.seg{display:flex;border:1px solid var(--border-strong);border-radius:8px;overflow:hidden}
.seg button{
  border:0;background:var(--panel);padding:6px 12px;cursor:pointer;border-right:1px solid var(--border);
}
.seg button:last-child{border-right:0}
.seg button.on{background:var(--accent-soft);color:var(--accent);font-weight:600}
.sel{
  border:1px solid var(--border-strong);border-radius:8px;padding:6px 8px;background:var(--panel);
}
.grow{flex:1}
.hint{color:var(--faint);font-size:12px}
/* 顶栏里那句说明（深蓝底上原色看不见，见 style.css 同名的那条） */
.topbar .hint{color:rgba(255,255,255,.55)}
/* 区块里整段的说明文字（采购明细下面「箱数与托盘号不用填…」、
   报关计量下面「第一数量 = …」）：跟上面的表格同宽，一屏写不下就分行显示。
   行距放宽一点 —— 这种一整段夹着 <b> 的说明，挤在一起扫一眼找不到重点。 */
.sechint{line-height:1.75}

/* ---------- 布局 ---------- */
.wrap{display:grid;grid-template-columns:minmax(320px,400px) 1fr;gap:14px;padding:14px 20px 40px;align-items:start}
.wrap.single{grid-template-columns:1fr}
.pane{
  background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);
  box-shadow:var(--shadow);overflow:hidden;
}
.pane-head{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:10px 14px;border-bottom:1px solid var(--border);background:var(--panel-2);
}
.pane-head h2{margin:0;font-size:14px;font-weight:640}
/* 订单序号（0.74.4）：0.75.64 起挪到单号**左边**（跟客户对账的号排前面）。
   小一号、灰底描边，别跟订单号抢眼 —— 扫一眼知道这家第几单就行；
   值在「订单信息」里改。 */
.oseq{font-size:11.5px;font-weight:500;color:var(--muted);background:var(--panel-3);
  border:1px solid var(--border);border-radius:999px;padding:2px 10px;margin-right:8px;
  vertical-align:1px;white-space:nowrap}
/* 订单详情头上的客户名链接（0.74.7）：平时跟普通文字一个样（虚线下划提示可点），
   悬停变蓝 —— 点开在新窗口看客户档案、顺手就能改。 */
.cust-link{color:inherit;text-decoration:none;border-bottom:1px dashed var(--border-strong)}
.cust-link:hover{color:var(--accent);border-bottom-color:var(--accent)}
.pane-body{padding:12px 14px}
.scroll{max-height:calc(100vh - 240px);overflow:auto}

/* ---------- 表格 ---------- */
table.tb{width:100%;border-collapse:collapse}
table.tb th,table.tb td{
  padding:7px 9px;border-bottom:1px solid var(--border);text-align:left;vertical-align:middle;
}
table.tb th{
  font-size:12px;color:var(--muted);font-weight:600;background:var(--panel-2);
  position:sticky;top:0;z-index:2;
}
table.tb tr:hover td{background:var(--panel-2)}
table.tb td.num,table.tb th.num{text-align:right;font-variant-numeric:tabular-nums}
table.tb td.ctr,table.tb th.ctr{text-align:center}
table.tb tfoot td{font-weight:650;background:var(--panel-2);border-top:2px solid var(--border-strong)}
.tb-wrap{overflow:auto;max-height:calc(100vh - 300px)}

/* 明细行的上下移动：拼托只认上下相邻，行序是能改的最后一个自由度。
   做成两个小箭头而不是拖拽 —— 拖放在表格里容易误触，也测不了；
   箭头点一下动一位，动完立刻能看见托号重排。默认半透明，悬停整行才显出来，
   免得 20 行密密麻麻全是箭头。 */
.mv{display:inline-flex;gap:2px;margin-left:4px;vertical-align:middle;opacity:.35}
table.tb tr:hover .mv{opacity:1}
.mvbtn{
  width:17px;height:17px;line-height:1;padding:0;border:1px solid var(--border);
  border-radius:3px;background:var(--panel-2);color:var(--muted);
  font-size:11px;cursor:pointer;
}
.mvbtn:hover{background:var(--accent, var(--border-strong));color:#fff;border-color:transparent}

/* 列宽可拖（T.bindColResize）：固定布局，拖出来的宽度才作数，
   不然表格会按内容自己重新分配，拖了也白拖 */
table.tb.resizable{table-layout:fixed}
/* 订单明细：按内容量身（sales.js 的 fitTblCols 先量再写 width）。
   同样得用固定布局 —— auto 布局会把量身得出的宽度当成参考值挥发掉，
   表格还是按自己的算法重排。配合 fitTblCols 写死的表格总宽，
   多出来的部分走 .tb-wrap 横向滚，不去挤那几列正文。 */
table.tb.fitcols{table-layout:fixed}
/* 这里**不加** td{overflow:hidden}：万一量身失手（比如浏览器不给 canvas），
   overflow:hidden 会把文字裁掉，正正踩中这次要治的「截断」。
   宁可让内容溢出到下一格被人看见，再回来修宽度。 */
.tb th{position:relative}
.colrz{
  position:absolute;top:0;right:0;width:7px;height:100%;
  cursor:col-resize;user-select:none;touch-action:none;
}
.colrz:hover,.colrz:active{background:var(--accent-soft)}
body.rz-ing{cursor:col-resize;user-select:none}
/* 食品线不显示 TDS：整列收起（.c-tds 打在 th 与 td 上） */
table.tb.no-tds .c-tds{display:none}
/* MSDS 整列收起，跟 TDS 一个套路（白名单在 products.js 的 MSDS_LINES）。
   只在「只看食品 / 美妆」这类用不上 MSDS 的筛选下加这个类，
   看全部或看塑业时列子照旧在。
   用 CSS 收而不是不输出这一格：th / td 数量始终对得上，
   白名单一改立刻复原，不用改渲染那一段。 */
table.tb.no-msds .c-msds{display:none}
/* 操作列里那几个按钮别被压扁：字一挤就看不出是「编辑」还是「复制」 */
.tb td.ctr .btn-sm{white-space:nowrap}
/* 品名那一列按内容自适应：品名有长有短，写死宽度的话长的会被截断、
   短的又空一大片。让它自己撑开，表格其余列保持定宽 */
table.tb td.pname, table.tb th.pname{white-space:normal;min-width:150px}
/* 自动算出来的格子（箱数、每箱重量…）：给个浅底，一眼看出这格不用填 */
.tb .ro{display:block;padding:2px 6px;border-radius:4px;background:var(--bg-faint,#f6f6f4);
  color:var(--fg-dim,#666);text-align:right;font-variant-numeric:tabular-nums}
/* 尾箱提示：最后一箱没装满时喊一声，跟别的提示一个字号但要能看见 */
.tb .hint.tail{color:var(--warn,#b7791f);white-space:normal}
/* 每箱重量 / 体积「一眼判死刑」的红格子（sales.js 的 packBad 打上来的）。
   跟 .ro 一样是自动算的格子，只是换成了红底红字 ——
   这里不做事后纠正，只把「这行多半把每箱值当成单件值填了」摆到人眼前，
   改哪个数由人定（产品库那一格和明细那一格都可能错，系统猜不了）。
   淡红底而不是纯红字：数字本身还要看得清，抄到别处去时不能看花眼。 */
.tb .ro.wbad{background:var(--red-soft,#fef3f2);color:#b42318;font-weight:640}
/* 表里的迷你下拉（单位、币种、计价单位）：跟旁边的数字输入框一样高，别把行撑高 */
.tb select.sel-mini{padding:2px 4px;font-size:12px;max-width:100%}
/* 采购明细「币种 / 计价单位 / 采购单价」那一格：三个控件横排不换行。
   以前它们直接躺在 td 里，列宽一紧就折行（单价掉到第二行，看着像没填）。
   套一层 .pk3 并给它写死需要的宽度，fitTblCols 量到这个宽度就会把列撑开，
   三样永远在同一行 —— 列宽是按内容给的，不是拍一个数写死。 */
.tb .ppcell{white-space:nowrap}
.tb .pk3{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.tb .pk3 select,.tb .pk3 input{flex:none}
/* 采购明细底部的合计行（总箱数 / 托盘数 / 总个数 / 总金额）：加粗 + 顶部
   细分隔线 + 浅灰底，跟数据行一眼分得开。class 名够特异，全站共用不撞。 */
.tb .pk-sum td{font-weight:700;border-top:2px solid var(--bd,#ddd);background:var(--bg-faint,#f6f6f4)}
/* 次级标签：挂在某个字段下面的小标题（比如客户名称下面的「订单序号」），
   比正式 label 轻一号，别让人以为这是又一个同级的必填项 */
.fld label.sub{display:block;font-size:11.5px;color:var(--fg-dim,#888);margin-bottom:2px}
/* 回收站的行给点区分：整行降透明度，跟「已停用」的手感一致 */
.tr-trash{background:repeating-linear-gradient(45deg,transparent,transparent 8px,rgba(127,127,127,.05) 8px,rgba(127,127,127,.05) 16px)}

/* ---------- 徽章 / 标签 ---------- */
.tag{
  display:inline-flex;align-items:center;gap:4px;font-size:11.5px;padding:1px 8px;
  border-radius:999px;border:1px solid var(--border);background:var(--panel-2);color:var(--muted);
  white-space:nowrap;
}
.tag.moke{background:#e8f0fe;color:#2f55c9;border-color:#bfdbfe}
.tag.delm{background:var(--violet-soft);color:#6d28d9;border-color:#ddd6fe}
.tag.beauty{background:#fdf2f8;color:#be185d;border-color:#fbcfe8}
.tag.violet{background:var(--violet-soft);color:#6d28d9;border-color:#ddd6fe}
.tag.green{background:var(--green-soft);color:#067647;border-color:#abefc6}
.tag.amber{background:var(--amber-soft);color:#b54708;border-color:#fedf89}
.tag.red{background:var(--red-soft);color:#b42318;border-color:#fecdca}
.tag.blue{background:var(--accent-soft);color:var(--accent);border-color:#bfdbfe}
.tag.grey{background:var(--panel-3);color:var(--muted)}
.tag.teal{background:var(--teal-soft);color:#0f766e;border-color:#99f6e4}
.tag.sm{font-size:11px;padding:0 6px}

/* 客户标签那一列：几个小标签横排，装不下的直接裁掉（不撑宽表格）。
   悬停看全部 —— 列宽就这么点，全摆出来会把旁边的列一起顶变形。 */
.tagrow{display:inline-flex;gap:3px;max-width:100%;overflow:hidden;
  white-space:nowrap;vertical-align:middle}

/* ---------- 订单列表 ---------- */
.olist{display:flex;flex-direction:column}
.ocard{
  padding:10px 14px;border-bottom:1px solid var(--border);cursor:pointer;transition:.13s;
  display:flex;flex-direction:column;gap:5px;
}
.ocard:hover{background:var(--panel-2)}
.ocard.on{background:var(--accent-soft);box-shadow:inset 3px 0 0 var(--accent)}
.ocard .r1{display:flex;align-items:center;gap:8px}
.ocard .no{font-weight:640;font-size:13px}
.ocard .co{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--muted)}
.ocard .meta{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--faint);flex-wrap:wrap}
.ocard .amt{margin-left:auto;font-weight:640;font-variant-numeric:tabular-nums}
.empty{padding:34px 16px;text-align:center;color:var(--faint)}

/* 卡片 meta 行右下角的「删除」。默认几乎看不见，鼠标移到这张单上才浮出来——
   删除是不可恢复的，摆在明面上容易被手滑点到，贴上去又显得每张单都在催人删它。
   就算误触，下一步还有一次把订单号、客户、金额都列出来的确认。 */
.ocard .meta .odel{
  margin-left:auto;padding:1px 7px;border:1px solid transparent;border-radius:5px;
  background:transparent;color:var(--faint);font-size:11px;line-height:1.6;
  cursor:pointer;opacity:0;transition:.13s;
}
.ocard:hover .odel,.ocard.on .odel{opacity:1}
.ocard .odel:hover{background:rgba(220,38,38,.09);border-color:var(--red);color:var(--red)}
.ocard .odel:focus-visible{opacity:1;outline:2px solid var(--accent);outline-offset:1px}
/* 回收站里的「恢复」跟「删除」同一个位置、同一套尺寸，
   只换个颜色：同形状不同色，比换个名字更不容易按错。 */
.ocard .odel.restore{color:var(--accent);border-color:rgba(60,110,242,.45)}
.ocard .odel.restore:hover{background:rgba(60,110,242,.10);border-color:var(--accent);color:var(--accent)}
@media (hover:none){.ocard .odel{opacity:.55}}   /* 触摸屏没有 hover，给个淡淡的存在感 */

/* ---------- 单据 / 阶段 ---------- */
.stepper{display:flex;gap:0;overflow-x:auto;padding:4px 0 10px}
.step{
  flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:3px;
  min-width:74px;position:relative;padding:0 2px;cursor:pointer;
}
.step:not(:last-child)::after{
  content:"";position:absolute;top:13px;left:calc(50% + 14px);right:calc(-50% + 14px);
  height:2px;background:var(--border-strong);
}
.step.done:not(:last-child)::after{background:var(--green)}
.step .dot{
  width:26px;height:26px;border-radius:50%;display:grid;place-items:center;font-size:11px;
  border:2px solid var(--border-strong);background:var(--panel);color:var(--muted);
  font-weight:600;z-index:1;
}
.step.done .dot{background:var(--green);border-color:var(--green);color:#fff}
.step.cur .dot{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:0 0 0 4px var(--accent-soft)}
.step.blocked .dot{border-color:var(--amber);color:var(--amber);background:var(--amber-soft)}
.step .nm{font-size:11px;color:var(--muted);text-align:center;line-height:1.3}
.step.cur .nm{color:var(--accent);font-weight:600}
.step:hover .nm{color:var(--text)}

.docrow{
  display:flex;align-items:center;gap:10px;padding:9px 12px;border:1px solid var(--border);
  border-radius:8px;margin-bottom:7px;background:var(--panel);transition:.13s;
  /* 窄屏时按钮整块换行，而不是把行撑出横向滚动条 */
  flex-wrap:wrap;min-width:0;
}
.docrow:hover{border-color:#c3c9d4}
.docrow.done{background:var(--green-soft);border-color:#abefc6}
/* 单据图标：老的一整行（.docrow，阶段卡片和研发页还在用）和新的九宫格卡片
   （.doccard）共用一套，别写两遍 —— 写两遍迟早改一处忘一处。 */
.docrow .ic,.doccard .ic{
  width:30px;height:30px;border-radius:7px;display:grid;place-items:center;font-size:11px;
  font-weight:700;background:var(--panel-3);color:var(--muted);flex:0 0 auto;
}
.docrow.done .ic,.doccard.done .ic{background:#abefc6;color:#067647}
.docrow .ic.w,.doccard .ic.w{background:#dbeafe;color:#2f55c9}
.docrow .ic.x,.doccard .ic.x{background:#d1fae5;color:#067647}
.docrow .ic.u,.doccard .ic.u{background:#ede9fe;color:#6d28d9}
/* 单据九宫格（2026-09-30 用户指名）：以前一张单据占整整一行，十来种单据要滚
   好几屏，出单时找哪张还没做很费劲。改成一行三个卡片、卡片加高，一屏看完。
   窗口窄了自动降成两列 / 一列 —— 卡片里按钮本来就换行，不会挤成一条。 */
.docgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
@media (max-width:1180px){.docgrid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:820px){.docgrid{grid-template-columns:minmax(0,1fr)}}
.doccard{
  display:flex;flex-direction:column;min-height:118px;padding:9px 10px;
  border:1px solid var(--border);border-radius:9px;background:var(--panel);
  transition:.13s;min-width:0;
}
.doccard:hover{border-color:#c3c9d4}
.doccard.done{background:var(--green-soft);border-color:#abefc6}
/* 抬头：图标 + 单据名 + 标签（人工上传 / 可上传）。名字再长也不换行，
   说明在悬浮提示里看（data-tip）。 */
.doccard .dc-h{display:flex;align-items:center;gap:7px;min-width:0}
.doccard .dc-h .dname{
  font-weight:640;font-size:13px;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.doccard .dc-h .tag{margin-left:auto;flex:0 0 auto}
/* 中间：单号 / 文件名 / 缺字段提示，纵向排，各自单行省略号 */
.doccard .dc-body{margin-top:6px;min-width:0}
.doccard .dc-body div{font-size:11.5px;color:var(--faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 底部按钮：贴着卡片底边（margin-top:auto），卡片高度不一时也齐平 */
.doccard .dc-act{margin-top:auto;padding-top:8px;display:flex;gap:6px;flex-wrap:wrap}
.doccard .dc-act .hint{font-size:11.5px}

/* 项目概览：左边档案字段、右边「剖面图（美工上传）+ AI 结构图」（2026-10-03）。
   窄屏自动折行 —— 卡片里全是文字，折了照样读。 */
.ov-row{display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap}
.ov-left{flex:1 1 300px;min-width:0}
.ov-right{flex:1 1 320px;min-width:280px;max-width:480px}
/* 美工上传的剖面图（2026-10-08）：图本身按比例缩放、不裁不拉伸，点一下放大看。
   下面那张 AI 结构图是另一块（.xsec），两张图各占各的位置，谁也不顶谁。 */
.ximg{border:1px solid var(--border);border-radius:9px;background:var(--panel);
  padding:10px;margin-bottom:10px}
.ximg .xh{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.ximg .xh b{font-size:13px;font-weight:640}
.ximg .xh .hint{font-size:11.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ximg .xh .xact{margin-left:auto;display:flex;gap:6px;flex:0 0 auto}
.ximg img{display:block;width:100%;max-height:300px;object-fit:contain;
  background:#fff;border:1px solid var(--border);border-radius:7px;cursor:zoom-in}

/* AI 结构图：AI 把产品自上而下拆成几层，每层一条色带（层名 + 英文 + 占比），
   说明折行放在色带里。色带颜色是浅色系、字一律深色，跟主题走不刺眼。 */
.xsec{border:1px solid var(--border);border-radius:9px;background:var(--panel);padding:10px}
.xsec .xh{display:flex;align-items:center;gap:8px}
.xsec .xh b{font-size:13px;font-weight:640}
.xsec .xh .btn{margin-left:auto}
.xsec .xsum{font-size:12.5px;margin:8px 0;color:var(--text)}
.xsec .xlayers{display:flex;flex-direction:column;gap:4px}
.xsec .xl{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 10px;
  padding:7px 10px;border-radius:7px;border:1px solid rgba(0,0,0,.06);min-width:0;
}
.xsec .xl b{font-size:12.5px;font-weight:640;color:#1f2329}
.xsec .xl .en{font-size:11.5px;color:rgba(0,0,0,.55)}
.xsec .xl .xr{margin-left:auto;font-size:11.5px;color:rgba(0,0,0,.55);white-space:nowrap}
.xsec .xl div{flex-basis:100%;font-size:12px;line-height:1.55;color:rgba(0,0,0,.75)}
.xsec .hintbox{margin-top:8px}

.docrow .txt{flex:1 1 240px;min-width:0}
.docrow .txt b{font-weight:640;font-size:13px}
/* 单据名：单行省略号，再长也不许换行、不许把行撑宽（说明移到悬浮提示里了） */
.docrow .txt b.dname{display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.docrow .txt div{font-size:11.5px;color:var(--faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.docrow .act{display:flex;gap:6px;flex:0 0 auto;flex-wrap:wrap;justify-content:flex-end;max-width:100%}

/* 悬浮说明：挂在 body 上的固定定位气泡（.pane 有 overflow:hidden，
   用 CSS ::after 做气泡会被裁掉）。pointer-events:none —— 不挡点击与划选复制。 */
.floattip{
  position:fixed;z-index:1200;pointer-events:none;max-width:420px;
  background:var(--panel);color:var(--text);border:1px solid var(--border-strong);
  border-radius:8px;padding:7px 10px;font-size:12px;line-height:1.6;
  box-shadow:0 6px 20px rgba(16,24,40,.18);white-space:pre-wrap;word-break:break-word;
}
.floattip[hidden]{display:none}
.warnlist{font-size:12px;color:#b54708;background:var(--amber-soft);border:1px solid #fedf89;
  border-radius:7px;padding:6px 10px;margin-top:5px}
.errlist{font-size:12px;color:#b42318;background:var(--red-soft);border:1px solid #fecdca;
  border-radius:7px;padding:6px 10px;margin-top:5px}
.okbox{font-size:12px;color:#027a48;background:var(--green-soft);border:1px solid #a6f4c5;
  border-radius:7px;padding:6px 10px;margin-top:5px}
.hintbox{font-size:12px;color:var(--muted);background:var(--panel-3);border:1px solid var(--border);
  border-radius:7px;padding:6px 10px;margin-top:5px}
.gatelist{list-style:none;margin:5px 0 0;padding:0;display:flex;flex-direction:column;gap:2px}
.gatelist li{font-size:12px}
.gatelist li.ok{color:#027a48}
.gatelist li.no{color:#b42318;font-weight:600}
.chkline{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted);cursor:pointer}
.chkline input{width:14px;height:14px;margin:0}

/* ---------- 表单 ---------- */
.grid2{display:grid;grid-template-columns:repeat(2,1fr);gap:10px 14px}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:10px 14px}
.grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:10px 14px}
.fld{display:flex;flex-direction:column;gap:3px}
.fld label{font-size:11.5px;color:var(--muted);font-weight:600}
.fld input,.fld select,.fld textarea{
  border:1px solid var(--border-strong);border-radius:7px;padding:5px 9px;background:var(--panel);width:100%;
}
.fld input:focus,.fld select:focus,.fld textarea:focus{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);
}
.fld input[readonly]{background:var(--panel-3);color:var(--muted)}
textarea{resize:vertical;min-height:52px}
.sec{margin-bottom:16px}
/* 收款 / 付款两列（2026-10-05 用户指名）：左边收款（客户付我们的）、
   右边付款（我们付供应商的）。窄屏退成一列 —— 两张表并排放不下时
   硬挤会把备注列挤没。 */
.paygrid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;align-items:start}
@media (max-width:1180px){.paygrid{grid-template-columns:minmax(0,1fr)}}
/* 收付款记录空态收窄（0.75.68 用户指名）：全局 .empty 的 34px 上下留白是给
   整页「没有匹配订单」那种大空屏用的，收款/付款表里只放一句「暂无收款」，
   上下各留 34px 就把两块表格撑得又高又空。改成只贴文字高度（上下 0、留左右），
   单元格高度 = 一行「暂无收款」的行高，不再多占。 */
.paygrid table .empty{padding:0 16px}
.sec>h3{
  font-size:12.5px;margin:0 0 8px;color:var(--muted);font-weight:650;
  text-transform:none;letter-spacing:.02em;
}
.row-inline{display:flex;gap:8px;align-items:center;flex-wrap:wrap}

/* ---------- 弹层 ---------- */
.modal{
  position:fixed;inset:0;background:rgba(16,24,40,.42);display:grid;place-items:center;z-index:80;
  padding:20px;
}
.modal-card{
  background:var(--panel);border-radius:12px;box-shadow:0 12px 40px rgba(16,24,40,.24);
  width:min(940px,100%);max-height:92vh;display:flex;flex-direction:column;overflow:hidden;
}
.modal-card.narrow{width:min(560px,100%)}
.modal-head{
  display:flex;align-items:center;justify-content:space-between;padding:12px 18px;
  border-bottom:1px solid var(--border);
}
.modal-head h2{margin:0;font-size:15px}
.modal-body{padding:16px 18px;overflow:auto}
.modal-foot{
  display:flex;justify-content:flex-end;gap:8px;padding:12px 18px;border-top:1px solid var(--border);
  background:var(--panel-2);
}
/* 保存按钮左边那句「已保存 3 次 · 最近 10:24」：小字、等宽数字，别抢按钮的注意力 */
.save-meta{font-size:11.5px;color:var(--fg-dim,#888);margin-right:8px;font-variant-numeric:tabular-nums}
/* 存过之后的按钮置灰 —— 但**不禁用**：改完还得能接着点第二第三次。
   置灰只是「这次已经存了」的记号，不是把人拦住。 */
.btn.is-saved{opacity:.5;box-shadow:none}
.btn.is-saved:hover{opacity:1}
/* 弹窗底部左边要放按钮（比如产品库弹窗的「＋ 新建产品」）时，
   把右边那组按钮包进 .right，中间自动留白 */
.modal-foot .right{display:flex;gap:8px;margin-left:auto}
/* 列宽自适应：表头不写宽度，让浏览器按内容分配（产品库弹窗用） */
table.tb.autofit{table-layout:auto}
table.tb.autofit th,table.tb.autofit td{white-space:normal}
.x{border:0;background:transparent;font-size:18px;cursor:pointer;color:var(--muted);line-height:1}
.x:hover{color:var(--text)}

/* ---------- 看板 ---------- */
.board{display:flex;gap:12px;overflow-x:auto;padding:14px 20px 40px;align-items:flex-start}
.bcol{
  flex:0 0 250px;background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);
  box-shadow:var(--shadow);max-height:calc(100vh - 250px);display:flex;flex-direction:column;
}
.bcol-h{
  padding:9px 12px;border-bottom:1px solid var(--border);font-size:12.5px;font-weight:640;
  display:flex;align-items:center;justify-content:space-between;gap:6px;background:var(--panel-2);
  border-radius:var(--radius) var(--radius) 0 0;
}
.bcol-h .n{font-size:11px;background:var(--panel-3);border-radius:999px;padding:0 7px;color:var(--muted)}
.bcol-b{padding:8px;overflow:auto;display:flex;flex-direction:column;gap:7px}
.bcard{
  border:1px solid var(--border);border-radius:8px;padding:8px 10px;background:var(--panel);
  cursor:grab;font-size:12.5px;
}
.bcard:hover{border-color:#b9c2d0;box-shadow:var(--shadow)}
.bcard.drag{opacity:.4}
.bcard .no{font-weight:640}
.bcard .co{color:var(--muted);font-size:11.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bcard .amt{font-variant-numeric:tabular-nums;font-weight:600;margin-top:3px}
.bcol.over{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.bcol.deny{border-color:var(--red);background:var(--red-soft)}

/* ---------- 时间线 ---------- */
.tl{position:relative;padding-left:18px}
.tl::before{content:"";position:absolute;left:5px;top:4px;bottom:4px;width:2px;background:var(--border)}
.tl-item{position:relative;padding:0 0 12px}
.tl-item .dot{
  position:absolute;left:-17px;top:4px;width:10px;height:10px;border-radius:50%;
  background:var(--panel);border:2px solid var(--border-strong);
}
.tl-item.now .dot{background:var(--accent);border-color:var(--accent)}
.tl-item.done .dot{background:var(--green);border-color:var(--green)}
.tl-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:12.5px}
.tl-h strong{font-weight:640}
.tl-h span{color:var(--faint);font-size:11.5px}
.tl-body{font-size:12px;color:var(--muted);margin-top:1px}

/* ---------- 杂项 ---------- */
.kv{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;font-size:12.5px}
.kv dt{color:var(--muted);white-space:nowrap}
.kv dd{margin:0}
.toast{
  position:fixed;bottom:22px;left:50%;transform:translateX(-50%);background:#1f2329;color:#fff;
  padding:9px 18px;border-radius:9px;z-index:99;box-shadow:0 8px 24px rgba(16,24,40,.28);
  font-size:13px;max-width:70vw;
}
.toast.err{background:#b42318}
.toast.ok{background:#067647}
.footer{padding:14px 20px 30px;color:var(--faint);font-size:12px}
.spin{display:inline-block;width:12px;height:12px;border:2px solid rgba(255,255,255,.4);
  border-top-color:#fff;border-radius:50%;animation:sp .7s linear infinite;vertical-align:-1px}
@keyframes sp{to{transform:rotate(360deg)}}
.copy{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px}
.mono{font-variant-numeric:tabular-nums}
.right{text-align:right}
.center{text-align:center}
.mt8{margin-top:8px}.mt12{margin-top:12px}.mb8{margin-bottom:8px}
.flex{display:flex;align-items:center;gap:8px}
.wrapflex{display:flex;flex-wrap:wrap;gap:6px}
.pill-num{
  display:inline-block;min-width:18px;text-align:center;font-size:11px;background:var(--panel-3);
  border-radius:999px;padding:0 6px;color:var(--muted);
}
.bar{height:6px;border-radius:999px;background:var(--panel-3);overflow:hidden;min-width:70px}
.bar>i{display:block;height:100%;background:var(--accent);border-radius:999px}
.bar.g>i{background:var(--green)}
.bar.a>i{background:var(--amber)}
.bar.r>i{background:var(--red)}

/* ---------- 客户列表 / 供应商列表 ---------- */
.muted{color:var(--faint)}
.mon{font-variant-numeric:tabular-nums}
.clip2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* 单行截断：公司名称这种一定要看得见整列的老长串名字，
   鼠标悬停给全文。表格用 auto 布局，宽度靠列定义里的 w 约束。 */
.clip1{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
td.hasclip{max-width:200px}
/* 客户/供应商名称：看着就要像链接，人才会去点。
   clip1 的 display:block 对 <a> 一样有效，长公司名照旧单行截断。 */
.pf-link{color:var(--accent);font-weight:600;cursor:pointer;text-decoration:none}
.pf-link:hover{text-decoration:underline}
/* 名称格：健康度圆点 + 名字。圆点 8px 固定不动，名字吃掉剩下的宽度再截断。
   少了 min-width:0，flex 子项不会收缩，长公司名会把整列撑出屏幕。 */
.namecell{display:flex;align-items:center;gap:7px;min-width:0}
.namecell .clip1{flex:1 1 auto;min-width:0}
/* 产品库品名那一格：缩略图 + 品名并排。
   图片不许被压扁（flex:0 0 auto），品名吃掉剩下的宽度。
   品名用 .pf-name 而不是 .clip1 —— 不截断，长名字换行显示全。 */
.namecell .pthumb{flex:0 0 auto}
.namecell .pf-name{flex:1 1 auto;min-width:0;white-space:normal;word-break:break-word}
/* 市场调查：每个维度结论下面那行「来源 · 可信度」。
   它比结论小一号、缩进一点，一眼能看出是附属信息而不是又一个结论；
   可信度那枚 tag 跟列表里其它 tag 一个样式，不另造一套颜色。 */
.mk-src{font-size:12px;color:var(--faint,#888);margin:0 0 10px 10px;
  display:flex;align-items:center;gap:6px;flex-wrap:wrap}
/* 关键词调查的结果列表：一行一条，标题可点开来源网址，网址单独一行小字。
   「来源网址」是这一块的主角——后面要导进背调资料的凭据就是它，
   所以给它独立一行，不跟摘要挤在一起。 */
.kw-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding-bottom:8px;margin-bottom:8px;border-bottom:1px solid var(--border)}
.kw-hit{display:flex;align-items:flex-start;gap:8px;padding:7px 0;
  border-bottom:1px dashed var(--border)}
.kw-hit:last-child{border-bottom:0}
.kw-hit .kwpick{margin-top:3px;flex:none}
.kw-main{flex:1;min-width:0}
.kw-t{font-size:12.8px;font-weight:600;color:var(--accent);text-decoration:none;
  display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kw-t:hover{text-decoration:underline}
.kw-u{font-size:11px;color:var(--faint,#888);margin-top:1px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kw-x{font-size:11.5px;color:var(--muted);margin-top:3px;line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* 品名 / 规格这类"长短差得多"的列：不写死成某个数字，按内容自适应。
   踩过的坑（v0.67.1）：这里原本写的是 min-width:120px，看着有下限，
   其实一点用没有 —— 这张表是 table-layout:fixed（列宽可拖的前提），
   fixed 布局下 **列宽只认 th 的 width，min-width 对列宽不起作用**，
   没写 width 的列只能去分「表格总宽 − 其余列固定宽」剩下的空间。
   产品库其余列加起来约 1458px，窗口 1500px 时两列只分到几十像素，
   DELM 十几个字的品名被压成一竖条，看着就是「截断 / 错位」。
   所以这里给一个够用的 width 作兜底（JS 没跑也看得清），
   真正的「按最长那条品名量身」由 products.js 的 fitNameCols() 渲染后实测再调。
   overflow-wrap:anywhere 保证再长也不溢出、不出省略号，换行显示全。 */
table.tb th.fit{width:240px}
table.tb th.fit,table.tb td.fit{white-space:normal;overflow-wrap:anywhere;word-break:break-word}
/* fitcols 只是「固定布局 + 列宽由 JS 量身」，**不带总宽兜底**。
   订单页那几张表（订单明细 / 采购明细 / 报关计量）要跟容器同宽 ——
   2026-10-01 用户指名：订单页九块左右两边要齐，表格不能自己定宽。
   总宽由 sales.js 的 fitTblCols 写成 width:100% + min-width:各列之和，
   容器不够宽时先压「按内容量身」的那几列（品名 / 编码 / 备注折行），
   压到下限才肯横滚。 */
table.tb.fitcols{table-layout:fixed}
/* 1800px 那条兜底是**产品库**那张表的（列多，JS 没跑成时不至于糊成一团），
   所以单独挂 fitwide —— 以前它挂在 fitcols 上，订单页三张表跟着一起被撑到
   1800，比旁边的表单区 / 单据区宽出一截，就是用户说的「宽度不协调」。 */
table.tb.fitcols.fitwide{min-width:1800px}
/* 收款记录的「备注」列按内容量身（2026-09-30 用户指名）：跟明细表一样是
   fixed 布局 + JS 量完写死。用 fitnote 而不是 fitcols 只是为了让「订单页的表」
   和「产品库的表」在读代码时能分清 —— 两边样式现在完全一样。 */
table.tb.fitnote{table-layout:fixed}
/* 邮件那头已经查不到往来了，分数是上次同步留下的旧值：画淡一点，
   跟"现在就这样"区分开，悬停里有说明。 */
.health.h-stale{opacity:.4}

/* 客户 360：点客户名打开的那一屏 */
.modal-card.wide{width:min(1080px,100%)}
.pf-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px 14px}
.pf-kv{display:flex;flex-direction:column;gap:2px}
.pf-kv label{font-size:11px;color:var(--faint);font-weight:600}
.pf-kv span{font-size:13px}
.pf-sec{margin-bottom:16px}
.pf-sec>h3{font-size:12.5px;margin:0 0 8px;color:var(--muted);font-weight:650}
.pf-box{border:1px solid var(--border);border-radius:8px;padding:10px 12px;background:var(--panel-2)}
.pf-empty{color:var(--faint);font-size:12.5px;padding:6px 0}
.pf-note{white-space:pre-wrap;font-size:13px;line-height:1.6}
.tl{display:flex;flex-direction:column;gap:0}
.tl-row{display:grid;grid-template-columns:112px 62px 1fr;gap:10px;padding:8px 0;
  border-bottom:1px solid var(--border);font-size:12.8px}
.tl-row:last-child{border-bottom:0}
.tl-d{color:var(--faint);font-variant-numeric:tabular-nums}
.tl-k{align-self:start}
.tl-t b{font-weight:640}
.tl-t em{color:var(--faint);font-style:normal;display:block;margin-top:2px}
.pf-tabs{display:flex;gap:6px;margin-bottom:12px;flex-wrap:wrap}

/* 联系人子表 */
.ctb{width:100%;border-collapse:collapse}
.ctb th{text-align:left;font-size:11.5px;color:var(--muted);font-weight:600;padding:4px 6px}
.ctb td{padding:3px 6px}
.ctb input{width:100%;padding:5px 7px;border:1px solid var(--border);border-radius:6px;
  background:var(--panel);font:inherit;font-size:12.5px}
.ct-add{margin-top:6px}

/* 产品图片：列表缩略图 + 弹层里的图片格 */
.pf-sub{font-size:12px;color:var(--faint);font-weight:600;margin:10px 0 6px}
.pthumb{width:26px;height:26px;object-fit:cover;border-radius:5px;margin-right:6px;
  border:1px solid var(--border);vertical-align:middle}
.imglist{display:flex;flex-wrap:wrap;gap:10px}
.imgcell{width:132px;border:1px solid var(--border);border-radius:8px;padding:6px;background:var(--panel-2)}
.imgcell img{width:100%;height:88px;object-fit:cover;border-radius:6px;background:#f3f4f6;display:block}
.imgops{display:flex;gap:6px;justify-content:center;margin-top:6px}

.kpi.green .n{color:var(--green)}
.kpi.blue .n{color:var(--accent)}
.kpi.amber .n{color:var(--amber)}
.kpi.violet .n{color:var(--violet)}
.kpi.teal .n{color:var(--teal)}

.bulkbar{
  display:flex;align-items:center;gap:8px;padding:8px 12px;
  border-bottom:1px solid var(--border);background:var(--panel-2);font-size:12px;
}
.statgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:12px;padding:14px}
.statcard{background:var(--panel-2);border:1px solid var(--border);border-radius:var(--radius);padding:12px 14px}
.statcard.wide{grid-column:1/-1}
.statcard h3{margin:0 0 8px;font-size:12.5px;color:var(--muted);font-weight:650}
.bar-row{display:grid;grid-template-columns:118px 1fr 84px;align-items:center;gap:9px;padding:2.5px 0;font-size:12px}
.bar-k{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bar-t{position:relative;height:8px;background:var(--panel-3);border-radius:999px;overflow:hidden;min-width:40px}
.bar-t>i{position:absolute;left:0;top:0;bottom:0;background:var(--accent);border-radius:999px}
.bar-v{text-align:right;color:var(--muted);font-variant-numeric:tabular-nums}
.bar-v em{font-style:normal;color:var(--faint);font-size:11px}
table.tb.mini{font-size:12px}
table.tb.mini td,table.tb.mini th{padding:5px 8px}

/* 订单明细里可点的品名（打开产品库 360 详情）。沿用全局链接色，
   hover 才出下划线 —— 平时不打扰，悬停时一眼知道能点。 */
a.pmlink{color:var(--accent)}
a.pmlink:hover{text-decoration:underline}

/* 单据预览（2026-10-01 加，2026-10-02 加大）：单据卡片上「预览」按钮点开的那层。

   单据是**横向**铺开的表格 —— 抬头 / 收货人 / 品名规格 / 金额 / 备注一列列排开，
   通用抽屉那 680 连半张发票都放不下，第一版加到 1080 还是得横向滚着看，
   一行行核对数字时被截掉半截，等于没核。

   所以尺寸按「能整张看」给，不再是「看着像个弹层」：
     · 宽度顶到 1480（再宽普通笔记本也放不下了，左右各留 12px 当边框）；
     · 高度按视口算满，外层那 24px 的留白在这层收成 12px；
     · 还嫌不够就点右上角「⤢ 全屏」连圆角和留白一起去掉，整块屏都给单据。 */
.drawer.pvwrap{padding:12px}
.drawer-box.pvdrawer{width:min(1480px,calc(100vw - 24px));max-height:calc(100vh - 24px);
  padding:14px 16px}
/* 全屏：连圆角一起收掉，屏幕边上不留白 —— 差这几十像素，装箱单最右那列
   「总箱数」就从「差一点」变成「看得见」。 */
.drawer-box.pvdrawer.full{width:100vw;max-width:100vw;height:100vh;max-height:none;
  border-radius:0;padding:10px 12px}
.drawer.pvwrap.full{padding:0}
.pvframe{flex:1;width:100%;min-height:0;border:1px solid var(--border);
  border-radius:8px;background:#fff}
.pvfoot{display:flex;gap:10px;justify-content:flex-end;align-items:center;
  padding-top:12px;margin-top:2px}
/* 预览点「返回」滚回那张卡片时闪一下：九宫格里一屏七八张单据，
   只滚动不停留的话，眼睛还得自己找是哪一张。 */
.doccard.flash{animation:dcflash 1.2s ease-out}
@keyframes dcflash{
  0%,100%{box-shadow:none;border-color:var(--border)}
  15%,55%{box-shadow:0 0 0 3px rgba(59,130,246,.35);border-color:var(--accent)}
}

/* ---------- 从文件新建订单（确认页） ---------- */
/* 拖放区：整块可点，虚线边框说明"这里能放东西进来" */
.fm-drop{
  border:1.5px dashed var(--border);border-radius:10px;background:var(--panel-2);
  padding:22px 16px;text-align:center;cursor:pointer;transition:border-color .15s,background .15s;
}
.fm-drop:hover,.fm-drop:focus{border-color:var(--accent);background:var(--accent-soft);outline:none}
.fm-drop.on{border-color:var(--accent);background:var(--accent-soft)}
.fm-drop-t{font-size:13.5px;font-weight:600;margin-bottom:4px}
.fm-work{display:flex;align-items:center;gap:10px;font-size:13.5px;padding:14px 0}
.fm-spin{
  width:16px;height:16px;border:2px solid var(--border);border-top-color:var(--accent);
  border-radius:50%;animation:fmspin .8s linear infinite;flex:none;
}
@keyframes fmspin{to{transform:rotate(360deg)}}
.fm-sec{margin-top:14px}
.fm-sec>h3{font-size:12.5px;margin:0 0 8px;color:var(--muted);font-weight:650}
.fm-sec>h3 .hint{font-weight:400;margin-left:6px}
.fm-head{display:flex;flex-wrap:wrap;align-items:center;gap:8px;font-size:12.5px;color:var(--muted)}
.fm-warn{
  margin-top:10px;border:1px solid var(--amber-soft);background:var(--amber-soft);
  border-radius:8px;padding:8px 10px;font-size:12.5px;color:#b54708;white-space:pre-wrap;
}
/* 明细行：勾选 + 状态徽标 + 内容 + 候选下拉。
   用 grid 而不是 table，是因为每行的「候选」是整行宽的说明，塞进单元格会挤成一团 */
.fm-row{
  display:grid;grid-template-columns:26px 1fr 260px;gap:10px;align-items:start;
  padding:10px;border:1px solid var(--border);border-radius:8px;margin-bottom:8px;
  background:var(--panel);
}
.fm-row.off{opacity:.5}
.fm-row.is-conflict{border-color:var(--red-soft);background:var(--red-soft)}
.fm-row.is-new{border-color:var(--accent-soft)}
.fm-row-main{min-width:0}
.fm-row-name{font-size:13px;font-weight:620;word-break:break-all}
.fm-row-sub{font-size:12px;color:var(--muted);margin-top:2px;word-break:break-all}
.fm-row-why{font-size:11.8px;color:var(--faint);margin-top:4px;line-height:1.5}
.fm-row-side{display:flex;flex-direction:column;gap:6px}
.fm-row-side select,.fm-row-side input{width:100%}
.fm-grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.fm-cust-line{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.fm-cust-line .hint{flex:1;min-width:180px}

/* 公司资料里的「收款银行」卡片：一家一张，可以加可以删。
   为什么不用表格：银行要能整块加、整块删，而且每家的字段自己成一屏才看得清，
   表格里加一行 = 六列同时对不上人。卡片着的时候第一眼看到的是「这家叫什么、
   是不是默认」，账号那些细项收在里面。 */
.bank-card{border:1px solid var(--border);border-radius:10px;padding:10px 12px;margin-bottom:10px;background:var(--panel-2)}
.bank-head{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.bank-head input[data-bk="label"]{flex:1;min-width:0;font-weight:600}
.bank-head .bk-def{display:flex;align-items:center;gap:5px;font-size:12.5px;color:var(--muted);white-space:nowrap}
.bank-head .btn-sm{margin-left:auto}

/* 收款币种那片下拉勾选：<details> 原生收起/展开，不引第三方组件。
   收起来那一行写成 select 的样式，一眼知道点得开；展开就是一排可以勾的币种。 */
.curpick{position:relative}
.curpick>summary{list-style:none;cursor:pointer;border:1px solid var(--border);border-radius:8px;
  padding:7px 10px;background:var(--panel);font-size:13px;min-height:32px}
.curpick>summary::-webkit-details-marker{display:none}
.curpick>summary::after{content:"▼";float:right;font-size:9px;color:var(--faint);margin-top:4px}
.curpick[open]>summary::after{content:"▲"}
.curpick .cur-box{border:1px solid var(--border);border-top:0;border-radius:0 0 8px 8px;
  background:var(--panel);padding:8px 10px;display:flex;flex-wrap:wrap;gap:6px 14px}
.cur-opt{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;color:var(--muted);white-space:nowrap}


/* 回收站里的一行（客户 / 供应商档案，0.73.97）
   每行自带勾选框：恢复和彻底删除都可能是好几家一起做。
   第二行写清「谁在什么时候删的、还有几个联系人 / 有没有背调」——
   人对着公司名想不起是哪一次误删的，得靠这些细节认出来。 */
.tr-row{display:flex;align-items:flex-start;gap:10px;padding:9px 10px;border:1px solid var(--border);
  border-radius:9px;margin-bottom:8px;background:var(--panel-2);cursor:pointer}
.tr-row:hover{border-color:var(--muted)}
.tr-row input{margin-top:2px}
.tr-main{flex:1;min-width:0;display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px}
.tr-sub{flex:0 0 auto;font-size:12px;color:var(--faint);white-space:nowrap;margin-top:2px}


/* 客户详情里的展会名片原图（0.73.98）
   缩略图给一个能认出「是哪张」的高度就够（名片上的字要放大才看得清，
   所以点一下弹整页）；一排排不下就自动换行，一叠名片扫出好几张是常事。 */
.cardimgs{display:flex;flex-wrap:wrap;gap:12px}
.cardimg{margin:0;width:200px;cursor:zoom-in;border:1px solid var(--border);
  border-radius:9px;padding:6px;background:var(--panel-2);text-align:center}
.cardimg:hover{border-color:var(--accent)}
.cardimg-thumb{display:block;width:100%;height:118px;object-fit:cover;object-position:top center;
  border-radius:6px;background:var(--panel)}
.cardimg figcaption{font-size:12px;color:var(--faint);margin-top:5px}

/* ---------- 企业邮箱（/mail，2026-10 新增的页签） ----------
   ★ 只补这几条：三栏骨架、目录、邮件行、未读三件套、引用块、附件、写信框。
   其余一律复用上面现成的 .pane / .pane-head / .btn / .tag / .empty /
   .hint / .search。类名全带 ml- 前缀，别的页面不会撞。
   0.75.44：照网易网页版那一套排 —— 左目录（写邮件 / 搜索 / 文件夹）、
   中列表、右原文。以前是「上面一排目录小圆钮 + 下面两栏」。 */

/* ★ 三栏：目录 196px、列表 320~400px、正文吃掉剩下的。
   窄屏（≤1100px）退回竖排 —— 硬挤成一团的话，正文那一栏只剩两三个字宽。 */
.ml-shell{display:grid;grid-template-columns:196px minmax(320px,400px) 1fr;
  gap:12px;padding:12px 14px 16px;align-items:start}
.ml-side{display:flex;flex-direction:column;gap:8px;padding:12px}
.ml-compose{width:100%;justify-content:center;padding:8px 10px}
.ml-q{width:100%}
.ml-folders{display:flex;flex-direction:column;gap:2px}
/* 目录改成竖排的一条条（不是小圆钮）：一排扫过去找的是「名字」，
   竖排才对得上人脑子里那个文件夹的样子 */
.ml-folder{display:flex;align-items:center;gap:8px;width:100%;border:0;
  background:transparent;border-radius:7px;padding:6px 10px;font-size:12.5px;
  color:var(--muted);cursor:pointer;font-family:inherit;text-align:left}
.ml-folder:hover{background:var(--panel-2);color:var(--accent)}
.ml-folder.on{background:var(--accent-soft);color:var(--accent);font-weight:600}
.ml-folder .ml-un{margin-left:auto}
.ml-sidefoot{margin-top:auto;padding-top:10px;border-top:1px solid var(--border);
  display:flex;flex-direction:column;gap:6px;align-items:stretch}
@media (max-width:1100px){
  .ml-shell{grid-template-columns:1fr}
  .ml-side{flex-direction:row;flex-wrap:wrap;align-items:center}
  .ml-compose{width:auto}
  .ml-q{width:auto;flex:1;min-width:160px}
  .ml-folders{flex-direction:row;flex-wrap:wrap;flex:1;min-width:200px}
  .ml-sidefoot{margin-top:0;border-top:0;padding-top:0;flex-direction:row;align-items:center}
}
/* 未读小标：目录名后面那枚蓝点数字 */
.ml-un{background:var(--accent);color:#fff;border-radius:999px;font-size:10.5px;
  line-height:1.6;padding:0 6px;font-weight:600}

/* 列表：一个目录几十封，行要矮一点才扫得完 */
.ml-list{max-height:calc(100vh - 230px);overflow:auto}
.ml-listcol,.ml-readcol{display:flex;flex-direction:column;min-height:0}
.ml-readcol .pane-body{max-height:calc(100vh - 230px);overflow:auto}
.ml-empty{padding:28px 14px;text-align:center;color:var(--faint);font-size:12.5px}
/* 行：头像圈固定在左，右边那坨（名字/主题/预览/尾巴）吃满剩下的宽度 ——
   ★ .ml-body 必须 min-width:0，不然主题长了会整行被撑宽，省略号永远不出来 */
.ml-row{position:relative;display:flex;gap:9px;padding:9px 12px 9px 22px;
  border-bottom:1px solid #f1f3f5;cursor:pointer}
.ml-body{flex:1;min-width:0}
.ml-ava{flex:0 0 30px;height:30px;margin-top:2px;border-radius:50%;
  background:#e8f0fe;color:#2f55c9;font-weight:700;font-size:13px;
  display:flex;align-items:center;justify-content:center;user-select:none}
.ml-row:hover{background:var(--panel-2)}
.ml-row.on{background:var(--accent-soft);box-shadow:inset 3px 0 0 var(--accent)}
/* ★ 未读三件套：左侧圆点 + 浅底色 + 加粗。只加粗是不够的 ——
   窄栏里扫过去，加粗跟已读的差别很小，圆点才是第一眼看到的那个信号。 */
.ml-row .ml-dot{display:none}
.ml-row.unseen{background:#f4f8ff}
.ml-row.unseen .ml-dot{display:block;position:absolute;left:8px;top:16px;
  width:6px;height:6px;border-radius:50%;background:var(--accent)}
.ml-row.unseen .ml-who,.ml-row.unseen .ml-sub{font-weight:650;color:#111827}
.ml-top{display:flex;align-items:baseline;gap:8px}
.ml-who{flex:1;min-width:0;font-size:12.5px;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ml-when{font-size:11px;color:var(--faint);white-space:nowrap}
.ml-sub{font-size:13px;color:var(--text);margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ml-prev{font-size:11.5px;color:var(--faint);margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ml-tail{display:flex;gap:8px;font-size:11px;color:var(--faint);margin-top:2px;min-height:14px}
.ml-pager{display:flex;align-items:center;gap:10px;justify-content:center;
  padding:8px 12px;border-top:1px solid var(--border)}

/* ==ML:SKIN== 0.75.45 照网易灵犀办公网页版换肤（0.75.44 只摆了三栏，
   外壳还是 CRM 白底观感，用户比着截图说「还是不一样」）。
   0.75.51：顶栏 / 导航行的深蓝 #33475f 与主色 #3c6ef2 **已全站生效**
   —— 那几条已从本段搬走：去掉了 body.mlpage 前缀，
   搬进本文件开头 .topbar / .appnav 的**全局**规则里，
   ★ 本段现在只剩企业邮箱页特有的样式（写信用 / 同步钮 / 搜索条）。
   ★ 下游测试 test_mail_page.js ⑫ 组钉的是全局那条，别再搬回来。 */
/* 邮箱页底子比全站稍灰一点（三栏外的留白），跟别处一眼能分开 */
body.mlpage{background:#eef1f5}
/* 左栏：蓝色大钮 + 圆形同步钮并排（网易那个「写邮件 ↻」的样子） */
body.mlpage .ml-newrow{display:flex;gap:8px}
body.mlpage .ml-newrow .ml-compose{flex:1;border-radius:8px;font-weight:600;
  box-shadow:0 2px 6px rgba(60,110,242,.32)}
body.mlpage .ml-sync{flex:0 0 38px;width:38px;height:38px;border-radius:50%;
  padding:0;font-size:17px;line-height:1;display:grid;place-items:center}
body.mlpage .ml-sync:hover{border-color:var(--accent);color:var(--accent)}
/* 搜索框：网易是灰底无边框的圆角条，聚焦才亮蓝 */
body.mlpage .ml-q{background:#f2f4f7;border-color:transparent}
body.mlpage .ml-q:focus{background:#fff;border-color:var(--accent)}
/* 工作区三栏底色统一浅灰，栏内是白面板（现有 .pane 自带） */
/* ==ML:SKIN:END== */

/* 右栏正文 */
.ml-acts{display:inline-flex;gap:6px;flex-wrap:wrap}
.ml-meta{display:grid;grid-template-columns:auto 1fr;gap:2px 10px;font-size:12px;
  color:var(--muted);padding-bottom:10px;border-bottom:1px solid var(--border);margin-bottom:10px}
.ml-meta b{color:var(--faint);font-weight:600;white-space:nowrap}
.ml-p{white-space:pre-wrap;word-break:break-word;font-size:13px;line-height:1.75;margin-bottom:9px}
/* HTML 原文：一律关进 sandbox iframe（没有 allow-scripts / allow-same-origin），
   邮件里的远程图片和脚本在这个页面里一步都跑不起来 */
.ml-frame{width:100%;height:min(60vh,520px);border:1px solid var(--border);
  border-radius:8px;background:#fff}
.ml-atts{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px;
  padding-top:10px;border-top:1px solid var(--border)}
.ml-att{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--accent);
  background:var(--panel-2);border:1px solid var(--border);border-radius:8px;
  padding:5px 10px;text-decoration:none}
.ml-att:hover{border-color:var(--accent);background:var(--accent-soft)}
.ml-size{color:var(--faint);font-size:11px}

/* 写信框 */
.ml-mask{position:fixed;inset:0;background:rgba(17,24,39,.45);z-index:70;
  display:flex;align-items:center;justify-content:center;padding:24px}
.ml-modal{background:var(--panel);border-radius:12px;box-shadow:0 12px 40px rgba(16,24,40,.22);
  width:min(680px,100%);max-height:88vh;overflow:auto;padding:18px 20px}
.ml-modal h3{margin:0 0 12px;font-size:15px}
.ml-field{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.ml-field label{flex:0 0 56px;font-size:12px;color:var(--muted)}
.ml-field input,.ml-field textarea{flex:1;min-width:0;border:1px solid var(--border);
  border-radius:7px;padding:6px 9px;font-size:13px;font-family:inherit;background:var(--panel)}
.ml-field textarea{resize:vertical;line-height:1.7}
.ml-note{font-size:11.5px;color:var(--faint);margin:6px 0 8px}
.ml-ack{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--muted);
  margin:10px 0 4px}
.ml-btnrow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:6px}
