/* ============================================================================
   糖三丈客户管理系统 · 设计系统 v13
   ----------------------------------------------------------------------------
   方向：深化品牌红棕 + 舒适宽松；模式为 Redesign·Preserve ——
   只换视觉层，功能、DOM 结构、类名、JS 内联样式引用的变量一律不动。
   1. 令牌（颜色/间距/圆角/阴影）
   2. 基础与排版
   3. 布局（顶栏/导航/主区）
   4. 组件（面板/卡片/按钮/表单/表格/标签）
   5. 业务区块（跟进卡片/订单行/试吃/渠道条/警示条/产品/登录）
   6. 响应式与动效
   ========================================================================== */

/* ============ 1. 设计令牌 ============ */
:root{
  /* 品牌主色：沿用原有红棕，补齐深色阶与浅色阶 */
  --brand:#a8392c;
  --brand-600:#a8392c;
  --brand-700:#8f2c21;
  --brand-50:#fbeae7;
  --brand-100:#f5d8d3;

  /* 辅色：金（沿用；--gold-soft 为 app.js 内联样式在用的旧变量名，必须保留） */
  --gold:#c98a2b;
  --gold-50:#fbf3e2;
  --gold-100:#f4e6c8;
  --gold-soft:#fbf3e2;

  /* 中性：一套暖灰阶，统一此前并存的三种底色 */
  --bg:#f7f4ee;
  --surface:#ffffff;
  --surface-2:#fbf9f5;
  --surface-3:#f3efe6;
  --line:#e8e1d5;
  --line-2:#f0ebe1;
  --text:#2a2622;
  --text-2:#5c544a;
  /* 次要文字：表头、时间、地址、说明全靠它，是全站引用最多的一种颜色。
     原值 #8a8073 在白底上只有 3.88:1，不到 WCAG AA 的 4.5——白天仓库光线下、
     手机小字号、四十岁以上的人，都吃亏。改成 #6f665b = 5.63:1，
     色相不变（还是暖灰），只是压深，肉眼是「字清楚了一点」。 */
  --muted:#6f665b;
  /* 输入框占位符：原 #b3aa9c 只有 2.30:1，等于没有提示。3.69:1 是占位符的合理上限，
     再深就会和真实输入内容混淆。 */
  --placeholder:#8c8478;

  /* 状态色：语义与色值沿用，不做重新配色 */
  --red:#b3372e;     --red-soft:#fbeae8;
  /* 琥珀：12px 的到期标签用原色 #a86a12 只有 3.92:1，小字不达标，压深到 5.44:1 */
  --amber:#8a5608;   --amber-soft:#faf0dc;
  --blue:#2f6497;    --blue-soft:#e8f0f8;
  --green:#3f7a4a;   --green-soft:#eaf3ec;
  --purple:#6a4a8f;  --purple-soft:#f0ebf7;

  /* 间距：4px 基准栅格 */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px; --s-6:32px; --s-7:44px;

  /* 字号：8 档。此前并存 12.5 / 13.5 / 14.5 三个「半个像素」档，
     视觉上分不出差别，维护时也说不清该用哪个，一律就近取整。 */
  --fs-xs:12px;    /* 角标、序号、标签内的注 */
  --fs-sm:13px;    /* 表头、辅助说明 */
  --fs-base:14px;  /* 表格正文 */
  --fs-md:15px;    /* 表单、话术 */
  --fs-lg:17px;    /* 客户名、区块标题 */
  --fs-xl:20px;    /* 页面主标题 */

  /* 圆角：三档 + 胶囊 */
  --r-sm:6px; --r-md:10px; --r-lg:14px; --r-pill:999px;

  /* 阴影：暖调三层 */
  --sh-1:0 1px 2px rgba(58,48,36,.05), 0 1px 3px rgba(58,48,36,.04);
  --sh-2:0 2px 6px rgba(58,48,36,.07), 0 8px 20px rgba(58,48,36,.06);
  --sh-3:0 12px 32px rgba(58,48,36,.13), 0 28px 64px rgba(58,48,36,.10);

  /* 聚焦环 */
  --ring:0 0 0 3px rgba(168,57,44,.16);

  /* 动效 */
  --ease:cubic-bezier(.22,.61,.36,1);
}

/* ============ 2. 基础与排版 ============ */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:"PingFang SC","Microsoft YaHei","Hiragino Sans GB",system-ui,sans-serif;
  font-size:15px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3{margin:0;font-weight:600;letter-spacing:.2px;text-wrap:pretty}
p{text-wrap:pretty}
.hidden{display:none !important}

/* ============ 3. 布局 ============ */
.topbar{
  background:rgba(255,255,255,.92);
  backdrop-filter:saturate(140%) blur(10px);
  -webkit-backdrop-filter:saturate(140%) blur(10px);
  border-bottom:1px solid var(--line);
  padding:12px var(--s-5);
  display:flex;align-items:center;gap:var(--s-5);flex-wrap:wrap;
  position:sticky;top:0;z-index:20;
  box-shadow:var(--sh-1);
}
.brand{display:flex;align-items:center;gap:var(--s-3);min-width:0}
/* 品牌标记：沿用原有造型，加入金色高光与微弱阴影，不做成色块占位 */
.logo{
  width:36px;height:36px;border-radius:var(--r-md);
  background:linear-gradient(150deg,var(--brand-600),var(--brand-700));
  display:inline-block;position:relative;flex:none;
  box-shadow:var(--sh-1);
}
.logo::after{
  content:"";position:absolute;left:8px;top:10px;width:20px;height:15px;
  background:linear-gradient(160deg,var(--gold),#b87c1f);
  border-radius:3px;
}
.brand h1{font-size:18px;line-height:1.3}
.brand p{margin:2px 0 0;font-size:13px;color:var(--muted)}

.nav{display:flex;gap:var(--s-2);flex-wrap:wrap;margin-left:auto;align-items:center}
.nav button{
  border:1px solid transparent;background:transparent;color:var(--muted);
  padding:0 var(--s-4);border-radius:var(--r-md);font-size:15px;cursor:pointer;
  font-family:inherit;transition:background .16s var(--ease),color .16s var(--ease);
  white-space:nowrap;
}
.nav button:hover{background:var(--surface-3);color:var(--text)}
.nav button:active{transform:translateY(1px)}
.nav button.active{
  background:var(--brand-50);color:var(--brand);
  border-color:var(--brand-100);font-weight:600;
  box-shadow:inset 0 -2px 0 var(--brand);
}

main{max-width:1180px;margin:0 auto;padding:var(--s-5) var(--s-5) 64px}
.page{animation:fade .2s var(--ease)}
@keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ============ 4. 组件 ============ */
/* 面板 */
.panel{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:var(--s-5);box-shadow:var(--sh-1);
}
.toolbar{display:flex;gap:var(--s-3);align-items:center;margin-bottom:var(--s-4);flex-wrap:wrap}
.sec-title{
  font-size:15px;font-weight:600;margin:var(--s-5) 0 var(--s-3);
  display:flex;align-items:center;gap:var(--s-2);
}

/* 卡片 */
.cards{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(184px,1fr));
  gap:var(--s-4);margin-bottom:var(--s-5);
}
.card{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:var(--s-4) var(--s-4);
  box-shadow:var(--sh-1);
}
.card .n{
  font-size:30px;font-weight:600;line-height:1.15;letter-spacing:-.5px;
  font-variant-numeric:tabular-nums;
}
.card .l{font-size:13px;color:var(--muted);margin-top:2px}
.card.red .n{color:var(--red)}
.card.amber .n{color:var(--amber)}
.card.blue .n{color:var(--blue)}
.card.green .n{color:var(--green)}
.card.purple .n{color:var(--purple)}

/* 按钮 */
.btn{
  border:1px solid var(--line);background:var(--surface);color:var(--text);
  padding:8px var(--s-4);border-radius:var(--r-md);cursor:pointer;font-size:14px;
  font-family:inherit;text-decoration:none;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-height:36px;line-height:1.2;
  transition:background .16s var(--ease),border-color .16s var(--ease),
             box-shadow .16s var(--ease),transform .08s var(--ease);
}
.btn:hover{border-color:#d8cfc0;background:var(--surface-2);box-shadow:var(--sh-1)}
.btn:active{transform:translateY(1px);box-shadow:none}
.btn:focus-visible{outline:none;box-shadow:var(--ring)}
.btn.primary{
  background:var(--brand);color:#fff;border-color:var(--brand);
  box-shadow:0 1px 2px rgba(143,44,33,.28);
}
.btn.primary:hover{background:var(--brand-700);border-color:var(--brand-700)}
.btn.big{padding:12px 28px;font-size:16px;min-height:44px}
.btn.ghost{background:transparent}
.btn.tiny{padding:5px var(--s-3);font-size:13px;min-height:30px}
.btn.danger{color:var(--red);border-color:#eccec9}
.btn.danger:hover{background:var(--red-soft);border-color:#e3b6b1}
/* 描边主操作：用于「一张卡、一行里各有一个」的重复动作（标记已联系、填快递）。
   实心红只留给整页唯一的那个主按钮（保存订单、下载 Excel）。
   跟进页原来有 31 个实心红按钮、待回填 35 个，红一多就不代表紧急了——
   现在逾期靠左边框和 chip 表达，按钮退回描边，主次才分得开。 */
.btn.mark{color:var(--brand);border-color:#e4c6c1;background:var(--surface)}
.btn.mark:hover{background:var(--brand);border-color:var(--brand);color:#fff}
.btn:disabled{opacity:.5;cursor:not-allowed;box-shadow:none}
/* 主按钮禁用时改中性灰。半透明的红看起来像「按钮坏了」，
   而且和「不能点」这件事没有对应关系——灰才是「现在不用管它」。 */
.btn.primary:disabled{background:var(--surface-3);color:var(--muted);border-color:var(--line);opacity:1}

/* 表单控件 */
input,select,textarea{
  font-family:inherit;font-size:15px;color:var(--text);
  border:1px solid var(--line);border-radius:var(--r-md);
  padding:9px var(--s-3);background:var(--surface);outline:none;
  transition:border-color .16s var(--ease),box-shadow .16s var(--ease);
}
input:focus,select:focus,textarea:focus{
  border-color:var(--brand);box-shadow:var(--ring);
}
input::placeholder,textarea::placeholder{color:var(--placeholder)}
input[type=search]{min-width:280px}
textarea{width:100%;min-height:76px;resize:vertical}

/* 表格 */
table{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
th{
  text-align:left;color:var(--muted);font-weight:500;font-size:var(--fs-sm);
  border-bottom:1px solid var(--line);padding:var(--s-3) var(--s-3);white-space:nowrap;
}
td{
  border-bottom:1px solid var(--line-2);padding:var(--s-3) var(--s-3);
  vertical-align:middle;
}
tr:last-child td{border-bottom:none}
tbody tr:hover{background:var(--surface-2)}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}
/* 合计行（按月订单明细等）：和上面的明细分开，一眼能看到总额 */
tfoot td{
  border-top:2px solid var(--line);border-bottom:none;font-weight:600;
  color:var(--text);background:var(--surface-2);
}
/* 客户序号：录入先后编号，窄列、弱化不抢眼，鼠标悬停显示录入时间 */
td.seq,th.seq{
  width:3.2rem;min-width:3.2rem;text-align:right;
  color:var(--muted);font-variant-numeric:tabular-nums;font-size:12px;
}

/* 标签 */
.tag{
  font-size:12px;padding:3px 10px;border-radius:var(--r-pill);
  border:1px solid;line-height:1.7;white-space:nowrap;
}
.tag.due{color:var(--amber);border-color:#e6cd9c;background:var(--amber-soft)}
.tag.risk{color:var(--red);border-color:#e9c3be;background:var(--red-soft)}
.tag.soon{color:var(--blue);border-color:#c3d7ea;background:var(--blue-soft)}
.tag.lost{color:#8a5a2b;border-color:#dfc8ab;background:#faf4ea}
.tag.unknown_overdue{color:var(--purple);border-color:#d0c3e4;background:var(--purple-soft)}
.tag.normal,.tag.unknown{color:var(--muted);border-color:var(--line);background:var(--surface-3)}

/* 条形图 */
.bar-wrap{display:flex;align-items:center;gap:var(--s-3);margin:var(--s-2) 0}
.bar-name{width:130px;flex:none;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bar{flex:1;height:22px;background:var(--surface-3);border-radius:var(--r-sm);overflow:hidden}
.bar i{
  display:block;height:100%;border-radius:var(--r-sm);
  background:linear-gradient(90deg,var(--gold),#b87c1f);
}
.bar-val{width:110px;flex:none;text-align:right;font-size:13px;color:var(--muted);
  font-variant-numeric:tabular-nums}

/* 柱状图（经营盘点「近 6 个月走势」与业绩看板「月度业绩比较」共用）
   三处结构修正：
   1) 柱高改由 JS 按 px 算并写进内联样式（原来写的是百分比 + Math.max(2|3, …)，
      3% 落在 110px 里只有 3.3px，「零」和「一点点」几乎不可分）；
   2) 柱区底部补 1px 基线 —— 柱子以前悬空，「没有成交」缺少参照物；
   3) 标签独立成一行，不再和柱子挤在同一块空间里。
   基线画在 .col-chart 上而不是每根柱子上，否则列与列之间的空隙会把线断成十几段。 */
.col-chart{
  display:flex;gap:10px;align-items:flex-end;
  height:120px;border-bottom:1px solid var(--line);
}
.col-chart.sm{height:110px}
.col-chart .col-col{
  flex:1;min-width:0;height:100%;
  display:flex;align-items:flex-end;justify-content:center;gap:3px;
}
.col-chart .col-col > i{display:block;min-width:7px;border-radius:3px 3px 0 0}
/* 零成交：留一根 4px 淡柱。不给高度就看不出「有这个人 / 这个月存在但没单」，
   给实色又会让人误读成有成交，所以只降透明度。 */
.col-chart .col-col > i.zero{opacity:.25}
.col-axis{display:flex;gap:10px}
.col-axis .col-col{
  flex:1;min-width:0;text-align:center;margin-top:5px;
  font-size:var(--fs-xs);color:var(--muted);line-height:1.5;
}
.col-axis .col-val{color:var(--text-2);font-size:var(--fs-sm)}
.pb-legend{display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:8px}
.pb-legend > span{
  display:inline-flex;align-items:center;gap:5px;
  font-size:var(--fs-xs);color:var(--text-2);
}
.pb-legend > span > i{width:10px;height:10px;border-radius:2px;display:inline-block;flex:none}

/* 表单布局
   标签列 88px（原来 78px，四个字加粗就顶到字段边上），字段列等宽。
   行内不再出现「标签 + 长字段 + 说明文字」三件套：说明一律落到字段下方，
   否则字段被挤成一条缝，说明还压在按钮上。 */
.form-panel .row{
  display:flex;align-items:center;gap:var(--s-3);
  margin-bottom:var(--s-4);flex-wrap:wrap;
}
.form-panel label{width:88px;flex:none;color:var(--muted);font-size:var(--fs-base)}
/* 带说明的字段所在行改成顶对齐：标签和输入框第一行文字对齐，
   否则两行高的字段会让标签浮在中间（聚水潭单号那行就是这样）。 */
.form-panel .row:has(.field){align-items:flex-start}
.form-panel .row:has(.field) > label{padding-top:9px}
/* 带说明的字段：输入框 + 下方说明，作为一个整体参与行布局 */
.form-panel .field{flex:1;min-width:200px;display:flex;flex-direction:column;gap:5px}
.form-panel .field > .hint{font-size:var(--fs-sm)}
.grow{flex:1;min-width:180px}
/* 包在 .grow 里的输入框必须撑满：input 默认宽度只有二十来个字符，
   「记一单」最关键的客户搜索框以前就是这样，宽 200 多，旁边的聚水潭单号反倒占整行。 */
.form-panel .grow > input:not([type=checkbox]):not([type=radio]),
.form-panel .grow > select{width:100%}
.sep{height:1px;background:var(--line);margin:var(--s-5) 0}
.align-right{justify-content:flex-end}
.total{font-size:17px}
.total b{color:var(--brand);font-size:24px;font-variant-numeric:tabular-nums}
.hint{font-size:13px;color:var(--muted);line-height:1.6}
.msg{margin-top:var(--s-3);font-size:14px;color:var(--green)}
.msg.err{color:var(--red)}
.map-row{display:grid;grid-template-columns:120px 1fr;gap:var(--s-3);align-items:center;margin-bottom:var(--s-3)}
.map-row label{color:var(--muted);font-size:14px}
.mrglab{display:block;margin:var(--s-2) 0;font-size:14px;cursor:pointer}
.mrglab input{margin-right:var(--s-2)}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-5)}
.form-panel.sub2 label{width:64px}
/* 同一行并排的第二个标签（日期 | 备注），桌面上和前一字段拉开距离 */
.form-panel .lb-inline{margin-left:var(--s-4)}

/* 导入页的目录行：输入框和「扫描」按钮排在同一行，按钮不再压在路径尾巴上。
   这个 .row 在 .panel 里、不在 .form-panel 里，所以以前没有任何 flex 规则，
   输入框、按钮按内联流排，按钮正好盖住长路径的最后几个字。 */
.dir-row{display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;margin-bottom:var(--s-4)}
.dir-row > label{width:88px;flex:none;color:var(--muted);font-size:var(--fs-base)}
.dir-field{flex:1;min-width:230px;display:flex;gap:var(--s-2)}
.dir-field input{flex:1;min-width:0}
.dir-field input[type=file]{flex:0 1 auto;min-width:0;max-width:100%}
.dir-field .btn{flex:none}

/* 空态 / 小标题 / 分组 */
.empty{
  color:var(--muted);text-align:center;padding:var(--s-7) 0;
  font-size:var(--fs-md);
}
/* 统一的空态组件：图标 → 一句「这是什么」→ 一句「为什么空 / 下一步做什么」→ 可选按钮。
   以前全站三套写法：有的只有一句话、有的两行 <br> 硬折、有的还指着已经改名前的入口。 */
.empty-state{text-align:center;padding:var(--s-6) var(--s-4) var(--s-6)}
.empty-state .es-icon{display:block;font-size:26px;line-height:1;opacity:.45;margin-bottom:var(--s-2)}
.empty-state .es-title{font-size:var(--fs-md);font-weight:600;color:var(--text);margin:0 0 4px}
.empty-state .es-hint{
  font-size:var(--fs-sm);color:var(--muted);line-height:1.7;
  max-width:430px;margin:0 auto;
}
.empty-state .btn{margin-top:var(--s-3)}
/* 紧凑版：同一屏里已经用一个完整空态说明过原因时，第二处只留一行文字 */
.empty-state.mini{padding:var(--s-4) 2px;text-align:left}
.empty-state.mini .es-title{font-weight:400;color:var(--muted);font-size:var(--fs-base);margin:0}
/* 行内版：图标 + 一句话 + 按钮挤在同一行，外面套一层虚线框。
   用在「两块相邻的空图本该合并成一条」的地方——业绩看板的「月度业绩比较」和
   「销售额排序」同时为空时，以前各占约 120px、各放一句灰字，翻两屏才看明白是同一件事。 */
.empty-state.inline{
  display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;
  padding:var(--s-4);background:var(--surface-2);
  border:1px dashed var(--line);border-radius:var(--r-md);
  text-align:left;
}
.empty-state.inline .es-icon{margin:0;font-size:20px;opacity:.4;flex:none}
.empty-state.inline .es-title{margin:0;font-weight:400;font-size:var(--fs-base);color:var(--muted)}
.empty-state.inline .es-hint{margin:0;max-width:none;font-size:var(--fs-sm)}
.empty-state.inline .btn{margin:0 0 0 auto;flex:none}
.group{margin-bottom:var(--s-6)}
.group h2{font-size:16px;margin-bottom:var(--s-3);display:flex;align-items:center;gap:var(--s-2)}
.dot{width:10px;height:10px;border-radius:50%;display:inline-block;flex:none}
.count{font-size:13px;color:var(--muted);font-weight:400}

/* 客户搜索建议 */
.suggest{position:relative;z-index:5}
.suggest .s-item{
  position:absolute;left:0;right:0;background:var(--surface);
  border:1px solid var(--line);border-top:none;padding:var(--s-3) var(--s-4);
  cursor:pointer;font-size:14px;
}
.suggest .s-item:hover{background:var(--brand-50)}
.suggest .s-item:first-child{border-top:1px solid var(--line);border-radius:var(--r-md) var(--r-md) 0 0}
.picked{
  background:var(--green-soft);border:1px solid #c9e0ce;border-radius:var(--r-md);
  padding:var(--s-3) var(--s-4);font-size:15px;
  display:inline-flex;align-items:center;gap:var(--s-3);
}

/* 订单行 */
.order-row{
  display:flex;gap:var(--s-2);align-items:center;
  margin-bottom:var(--s-3);flex-wrap:wrap;
}
.order-row select,.order-row input{flex:1;min-width:110px}
.order-row .q{flex:none;width:88px}
.order-row .p{flex:none;width:108px}
.order-row .rm{flex:none}

/* 弹窗 */
.modal{
  position:fixed;inset:0;background:rgba(42,38,34,.44);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  display:flex;align-items:flex-start;justify-content:center;
  padding:var(--s-7) var(--s-4);overflow:auto;z-index:50;
}
.modal-box{
  background:var(--surface);border-radius:var(--r-lg);
  padding:var(--s-5);width:100%;max-width:840px;box-shadow:var(--sh-3);
  animation:pop .18s var(--ease);
}
@keyframes pop{from{opacity:0;transform:translateY(10px) scale(.99)}to{opacity:1;transform:none}}
.modal-box h2{font-size:18px;margin-bottom:var(--s-4)}
.modal-box .actions-row{
  display:flex;gap:var(--s-3);justify-content:flex-end;margin-top:var(--s-5);
}

/* 轻提示 */
.toast{
  position:fixed;bottom:var(--s-6);left:50%;transform:translateX(-50%);
  background:#2a2622;color:#fff;padding:var(--s-3) var(--s-5);
  border-radius:var(--r-md);font-size:15px;z-index:99;box-shadow:var(--sh-3);
  animation:pop .18s var(--ease);
}

/* 时间线 */
.timeline{margin-top:var(--s-2)}
.tl-item{display:flex;gap:var(--s-4);padding:var(--s-3) 0;border-bottom:1px solid var(--line-2)}
.tl-date{
  width:96px;flex:none;color:var(--muted);font-size:var(--fs-sm);
  font-variant-numeric:tabular-nums;
}
.tl-body{flex:1}
.tl-body .ps{font-size:var(--fs-xs);color:var(--muted);margin-top:2px}

/* ============ 5. 业务区块 ============ */
/* 今日跟进：客户卡片（左边框＝状态语义，非装饰）
   ---------------------------------------------------------------
   卡片分三段：头部（谁 / 多急 / 多少）→ 商品与话术（说什么）→ 底部（做什么）。
   底色一律白，状态只靠 3px 左边框 + 头部 chip：
   原来整卡铺 --amber-soft，18 张叠在一起时满屏米黄，反而看不出哪张最急——
   颜色的作用是让人一眼找到「今天必须打的那个」，不是给页面上色。 */
.follow{
  background:var(--surface);border:1px solid var(--line);
  border-left:3px solid var(--line);
  border-radius:var(--r-md);padding:8px var(--s-4) 8px 14px;
  margin-bottom:var(--s-2);box-shadow:var(--sh-1);
  transition:box-shadow .18s var(--ease);
}
.follow:hover{box-shadow:var(--sh-2)}
.follow.due{border-left-color:var(--amber)}
.follow.risk{border-left-color:var(--red)}
.follow.soon{border-left-color:var(--blue)}
.follow.lost{border-left-color:#8a5a2b}
.follow.unknown_overdue{border-left-color:var(--purple)}
.follow.done{opacity:.6}
.follow-head{display:flex;align-items:baseline;gap:var(--s-3);flex-wrap:wrap;line-height:1.35}
.follow-head .name{font-size:var(--fs-lg);font-weight:600;cursor:pointer}
.follow-head .name:hover{color:var(--brand);text-decoration:underline}
.follow-head .phone{color:var(--muted);font-size:var(--fs-base);font-variant-numeric:tabular-nums}
/* 累计金额靠右：一眼看金额，不用横着扫到行尾 */
.follow-head .amt{
  margin-left:auto;font-size:var(--fs-base);font-weight:600;color:var(--text-2);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
.follow-head .amt i{font-style:normal;font-weight:400;color:var(--muted);font-size:var(--fs-xs);margin-left:3px}

/* 商品行：不再一个个套虚线框。框只用来分隔「不同的东西」，
   同一张卡里的规格本来就是一组，套框反而把卡片撑高、视线打碎。 */
.items{margin-top:var(--s-1);display:flex;flex-direction:column;gap:2px}
.item{font-size:var(--fs-base);color:var(--text-2);line-height:1.45}
.item b{font-weight:600;color:var(--text)}
.item .meta{color:var(--muted);font-size:var(--fs-xs);margin-left:6px}
/* 元信息按「段」排：分隔点由 CSS 生成，某一段被隐藏时它的点一起消失，
   不会在行首留下一个孤零零的「·」。窄屏靠这个属性决定藏哪几段。
   「上次 2026-07-18（109 天前）」的括号也由 CSS 生成：
   手机上藏掉绝对日期、括号跟着一起消失，只剩「上次 109 天前」——
   一行放得下，不会把「通常 30 包」挤到第二行、拆成「通 / 常 30 包」。 */
.item .meta .seg + .seg::before{content:'·';margin:0 5px;opacity:.65}
.item .m-last .ago::before{content:'（'}
.item .m-last .ago::after{content:'）'}

/* 话术：左侧 2px 品牌引线 + 无底色。整段是要被念出来/复制走的话，
   用引线表示「这是一句原话」，比虚线框更像引用、也更省高度。 */
.msg-wrap{position:relative}
.message{
  margin-top:4px;padding:0 0 0 10px;
  border-left:2px solid var(--brand-100);
  font-size:var(--fs-base);line-height:1.55;color:#3b3733;
  text-wrap:pretty;
}

/* 底部动作：地址占剩余宽度（单行省略，全文在 title），按钮靠右。
   地址原来单独占一行，一屏就少看 1/4 家店。 */
.follow-foot{display:flex;align-items:center;gap:var(--s-2);margin-top:6px;flex-wrap:wrap}
.follow-foot .btn.tiny{min-height:28px;padding:4px 10px}
.follow-foot .addr{
  flex:1 1 200px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--muted);font-size:var(--fs-xs);
}
.follow-foot .acts{display:flex;align-items:center;gap:var(--s-2);margin-left:auto;flex-wrap:wrap}
.follow-foot input[data-note]{width:170px;min-height:30px;padding:4px 8px;font-size:var(--fs-sm)}
/* 备注框默认收起：31 张卡各带一个空输入框，页面上就是 31 个空槽，
   真正常填的是少数。点「加备注」才展开并聚焦。 */
.follow:not(.note-on) .follow-foot input[data-note]{display:none}

/* 今日跟进：可点击筛选卡片
   ---------------------------------------------------------------
   5 张卡原来走 .cards 的 auto-fit(184px)，一屏铺成一大块 ~104px 高；
   名单要往下滚过 460px 才出现第一张客户卡。这里单独收紧：
   一行 5 个等宽、数字 24px、标签 12px，整块高度压到 ~76px。
   选中不再追加第三行「✓ 筛选中」（那会让选中的卡比邻居高 22px，
   一行卡底边参差），改成右上角一个小勾，卡高完全一致。 */
#todayCards{
  grid-template-columns:repeat(5,minmax(0,1fr));
  gap:10px;margin-bottom:var(--s-3);
}
#todayCards .card{padding:10px 12px;position:relative}
#todayCards .card .n{font-size:24px;letter-spacing:-.3px}
#todayCards .card .l{font-size:var(--fs-xs);margin-top:1px;line-height:1.4}
/* 桌面用长标签，手机用两三个字的短名（见 app.js CARD_FILTERS） */
#todayCards .card .l .sm{display:none}
@media (max-width:560px){
  #todayCards{gap:8px}
  #todayCards .card{padding:8px 8px}
  #todayCards .card .n{font-size:22px}
  #todayCards .card .l .lg{display:none}
  #todayCards .card .l .sm{display:inline}
}
button.filter-card{
  font-family:inherit;text-align:left;cursor:pointer;
  transition:box-shadow .18s var(--ease),border-color .18s var(--ease),
             transform .18s var(--ease);
}
button.filter-card:hover{box-shadow:var(--sh-2);transform:translateY(-1px)}
button.filter-card.active{
  border-width:2px;padding:9px 11px;box-shadow:var(--sh-2);
  border-color:currentColor;
}
button.filter-card.active::after{
  content:'✓';position:absolute;top:7px;right:8px;
  font-size:12px;font-weight:700;line-height:1;color:inherit;opacity:.45;
}
#todayCards .filter-hint{
  grid-column:1/-1;font-size:11px;color:var(--muted);
  margin:-2px 0 0;text-align:right;line-height:1.4;
}

/* 渠道切换条：统一到暖灰中性，去掉原来的冷灰蓝 */
.channel-bar{
  display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap;
  background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-md);padding:6px var(--s-3);
  margin-bottom:var(--s-3);font-size:13px;
}
.channel-bar .btn{margin-left:auto}
.chanbar{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap}

/* 数据过期提示：并入令牌体系 */
.warn-banner{
  background:var(--amber-soft);border:1px solid #ecd4a6;
  border-left:4px solid var(--amber);border-radius:var(--r-md);
  padding:var(--s-3) var(--s-4);margin-bottom:var(--s-4);
  line-height:1.7;font-size:14px;color:#7a5410;text-wrap:pretty;
}
.warn-banner b{color:var(--red);font-size:15px}
.row-warn td{background:var(--red-soft);color:var(--red);font-weight:600}

/* 客户列表：可点击排序表头 */
th.sortable{cursor:pointer;user-select:none;white-space:nowrap;
  transition:color .16s var(--ease)}
th.sortable:hover{color:var(--brand);background:var(--surface-3)}
th.sortable.on{color:var(--brand);font-weight:600}
/* 排序箭头：不排序的列不画箭头。
   之前每个可排序列头都常驻一个 opacity:.4 的「↕」，14 个列头就是 14 个灰点，
   远看像表头脏了，也把真正「现在按这一列排」的注意力抢走。
   现在只有当前列显示实心三角（品牌色），其余列移到表头上才淡入一个提示。 */
th .sc{font-size:10px;opacity:0;margin-left:var(--s-1);color:var(--brand);
  transition:opacity .16s var(--ease)}
th.sortable:hover .sc{opacity:.45}
th.sortable:hover .sc:empty::before{content:'↕'}
th.sortable.on .sc{opacity:1}

/* 客户表：列宽定死，行高回到 44px。
   此前「最近下单」没定宽也没 nowrap，2026-10-25 被折成两行；
   地址自适应宽度，长地址折 2–3 行，把整行撑到 60–150px，
   一屏只剩 10 家、50 家一页要翻五次。 */
.cust-table{table-layout:fixed;min-width:900px}
.cust-table th,.cust-table td{padding:8px var(--s-3);white-space:nowrap}
.cust-table .c-name{width:190px}
.cust-table .c-seq{width:56px;text-align:right}
.cust-table .c-phone{width:124px}
.cust-table .c-owner{width:66px}
.cust-table .c-last{width:98px}
.cust-table .c-orders{width:66px}
.cust-table .c-amount{width:104px}
/* 操作列要按「最小内距 + 按钮宽度」算：78px 时 24px 内距只剩 54，按钮 62 宽，
   定宽表格不会撑开列，按钮直接溢出到单元格外面、戳出面板边框。 */
.cust-table .c-act{width:92px;text-align:right}
.cust-table th.c-act,.cust-table td.c-act{padding-left:var(--s-2);padding-right:var(--s-2)}
/* 地址是唯一允许伸缩的列：单行截断，全文在 title 里，鼠标停一下就能看 */
.cust-table td.c-addr{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 行内「记一单」压到 26px，(26 + 上下各 8px 内距) ≈ 43px 一行。
   按钮原来 30px 高，把整行顶到 53px，一屏就少看三行。 */
.cust-table .btn.tiny{min-height:26px;padding:2px 10px}

/* 顶栏：8 个页面入口 + 身份 + 退出登录 + 退出系统，全部平铺一行
   ------------------------------------------------------------------
   不做折叠：每个页面点一下就到，不用先展开菜单再点第二下。
   手机上装不下就横滑（见 ≤760 段），这是有意的取舍——
   少点一次比少滑一次更重要。
   「退出系统」会停掉整个后台服务，所以右端两个退出按钮用颜色区分：
   退出登录是中性灰，退出系统是红字红边。 */
.nav{position:relative;align-items:center}
.nav > button,
.nav > .whoami{
  height:38px;display:inline-flex;align-items:center;justify-content:center;
  line-height:1;padding:0 var(--s-4);box-sizing:border-box;
}
.nav > button{font-size:15px}

.whoami{
  font-size:14px;font-weight:600;cursor:pointer;border-radius:var(--r-pill);
  white-space:nowrap;gap:7px;margin-left:var(--s-3);
  color:var(--brand);background:var(--brand-50);border:1px solid var(--brand-100);
  transition:filter .16s var(--ease),box-shadow .16s var(--ease);
}
.whoami::before{
  content:"";width:7px;height:7px;border-radius:50%;
  background:var(--brand);flex:none;
}
.whoami.sales{color:var(--blue);background:var(--blue-soft);border-color:#d5e2ef}
.whoami.sales::before{background:var(--blue)}
.whoami:hover{filter:brightness(.96);box-shadow:var(--sh-1)}

/* 退出类按钮：比导航按钮矮一档、字号小一号，视觉上退到次要层。
   必须用 .nav > .exit-btn 这种高特异性写法——上面 .nav > button 定的
   padding/font-size 特异性更高，不加会被吃回去。 */
.nav > .exit-btn{
  margin-left:var(--s-2);border:1px solid var(--line);background:transparent;
  color:var(--muted);border-radius:var(--r-md);padding:0 var(--s-3);
  font-size:13px;cursor:pointer;white-space:nowrap;height:38px;
  display:inline-flex;align-items:center;
  transition:background .16s var(--ease),color .16s var(--ease),border-color .16s var(--ease);
}
.ghost-btn:hover{background:var(--surface-3);color:var(--text);border-color:var(--line)}
/* 退出系统会关掉整个后台服务（所有人掉线，要重启才能恢复）。
   红字红边，和紧挨着的「退出登录」一眼分得开。 */
.nav > .exit-btn.danger{color:var(--red);border-color:#e4c3be}
.nav > .exit-btn.danger:hover{background:var(--red-soft);color:var(--red);border-color:#d9b0a9}

/* 产品页：拖拽排序
   每个品种是「品种名分组头 + 一张规格表」，表头只出现一次。
   原来每行都印一遍「默认单价」，79 个品种 × 4 个规格 ≈ 300 次重复，
   既占掉 150px 宽度，又让「单价」这个列名永远跟在输入框旁边没法对齐。 */
.prod-card{border-bottom:1px solid var(--line-2);padding:var(--s-3) 0}
.prod-head{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap}
.prod-head b{font-size:16px}
.prod-head .cnt{
  font-size:var(--fs-xs);color:var(--muted);font-weight:400;
  background:var(--surface-3);border-radius:var(--r-pill);padding:1px 8px;
}
.prod-head .ops{margin-left:auto;display:flex;gap:6px;flex-wrap:wrap}
/* 「删除品种」常显红框：一屏五六个品种就有五六个红按钮，
   和逾期、危险提示抢同一套视觉信号。默认中性，hover 才转红。 */
.prod-head .ops [data-del-prod]{color:var(--muted);border-color:transparent;background:transparent}
.prod-head .ops [data-del-prod]:hover{color:var(--red);border-color:#eccec9;background:var(--red-soft)}
.drag-h{
  cursor:grab;color:#b9b0a1;user-select:none;padding:0 var(--s-1);
  font-size:15px;line-height:1;
}
.drag-h:hover{color:var(--brand)}
.drag-src{opacity:.35}
/* 规格表按内容收紧，不铺满整行。
   100% 宽度 + 定宽布局时，剩余的 300 多像素会全部塞给没设宽度的「规格」列，
   结果「1斤」和「桶」之间空出半屏——眼睛要在空白里找下一列。
   收紧之后五列挨着，79 个品种从上往下扫的时候不用横跳。 */
/* 定宽列 + 末尾一个吃掉剩余宽度的空列：
   列都挤在左边好扫，而分隔线又铺满整行（否则表格右边会露出一截毛边）。
   若直接给整表 100%，剩下的 300 多像素会全塞进「规格」列，
   「1斤」和「桶」之间空出半屏——眼睛得在空白里找下一列。 */
.spec-table{margin-top:4px;width:100%;table-layout:fixed}
.spec-table th:nth-child(1),.spec-table td:nth-child(1){width:160px}
.spec-table th:nth-child(2),.spec-table td:nth-child(2){width:88px}
.spec-table th:nth-child(3),.spec-table td:nth-child(3){width:150px}
.spec-table th:nth-child(4),.spec-table td:nth-child(4){width:120px}
.spec-table th:nth-child(5),.spec-table td:nth-child(5){width:80px}
.spec-table .sp{padding:0}
/* 「单位」并进规格单元格里显示（只在小屏生效，见 ≤560 段） */
.spec-table .u{display:none}
.spec-table th{
  font-size:var(--fs-xs);font-weight:500;color:var(--muted);
  padding:4px var(--s-2);border-bottom:1px solid var(--line-2);white-space:nowrap;
}
.spec-table td,.spec-table th{padding:5px var(--s-2);font-size:var(--fs-base)}
.spec-table td:first-child{white-space:nowrap}
.spec-table input.spec-in{width:86px;padding:4px 7px;font-size:var(--fs-base)}
.spec-table tr[data-sort-id]{cursor:default}
.spec-table tr[data-sort-id]:hover{background:var(--surface-2)}
/* 规格删除：默认隐藏，鼠标移到这一行 / 键盘 Tab 到时才出现。
   规格一旦删掉，历史订单里的这条明细就没了名字，属于不可逆操作，
   不该在一屏 300 行里始终亮着红字等着被误点。触屏没有 hover，保持常显。 */
.spec-table [data-del-spec]{opacity:0;transition:opacity .14s var(--ease)}
.spec-table tr:hover [data-del-spec],
.spec-table [data-del-spec]:focus-visible{opacity:1}
@media (hover:none){
  .spec-table [data-del-spec]{opacity:1}
}

/* 试吃跟进 */
.trial-group{
  border-radius:var(--r-md);padding:var(--s-3) var(--s-4) var(--s-4);
  margin-bottom:var(--s-3);border:1px solid var(--line);background:var(--surface);
}
.trial-group-t{font-weight:600;font-size:var(--fs-sm);margin-bottom:var(--s-1)}
.trial-row{
  display:flex;align-items:center;gap:var(--s-3);padding:var(--s-2) 0;
  border-bottom:1px dashed var(--line);font-size:var(--fs-sm);
}
.trial-row:last-child{border-bottom:none}
.trial-row b{min-width:60px}
.trial-phone{color:var(--brand);white-space:nowrap;font-variant-numeric:tabular-nums}
.trial-meta{
  color:var(--muted);font-size:var(--fs-xs);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;
}
.trial-gap{flex:1}

/* 产品页：把品种标成试吃小包装 */
.trial-flag{
  display:inline-flex;align-items:center;gap:5px;
  font-size:var(--fs-xs);color:var(--muted);white-space:nowrap;cursor:pointer;
}
.trial-flag input{width:15px;height:15px;margin:0;cursor:pointer}
.trial-flag:hover{color:var(--brand)}

/* 登录界面 */
.login-view{
  position:fixed;inset:0;z-index:200;
  display:flex;align-items:center;justify-content:center;
  background:
    radial-gradient(1100px 520px at 50% -10%, var(--brand-50), transparent 70%),
    linear-gradient(180deg,#f9f6f0,#f4efe5);
}
.login-box{
  width:372px;max-width:92vw;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-lg);
  padding:var(--s-6) var(--s-5) var(--s-5);box-shadow:var(--sh-3);
  animation:pop .22s var(--ease);
}
.login-brand{text-align:center;margin-bottom:var(--s-5)}
.login-brand h1{font-size:20px;margin:var(--s-3) 0 0;letter-spacing:.5px}
.login-brand .logo{margin:0 auto}
.login-box .row{margin-bottom:var(--s-3);display:flex;align-items:center;gap:var(--s-3)}
.login-box label{width:52px;flex:none;color:var(--muted);font-size:14px}
.login-box input{flex:1}
.login-box .btn.big{width:100%;margin-top:var(--s-2)}

/* ---- 补齐历史遗留的未定义类（旧样式缺失，非本次改动丢失）---- */
/* 可点击的客户名：给出明确的可点击暗示 */
.lk{cursor:pointer;transition:color .16s var(--ease)}
.lk:hover{color:var(--brand);text-decoration:underline}
/* 跟进备注输入框 */
.note-in{flex:1;min-width:200px}
/* 订单行里的产品 / 规格下拉 */
.p-sel,.sp-sel{flex:1;min-width:120px}
/* 产品页分类标签条 */
.tabs{display:flex;gap:var(--s-2);flex-wrap:wrap;align-items:center}
/* 简易表格（导入结果等） */
.tbl{margin-top:var(--s-2)}
.tbl th,.tbl td{padding:var(--s-2) var(--s-3)}

/* ============ 6. 响应式与动效 ============ */
@media (max-width:820px){
  .grid2{grid-template-columns:1fr}
  main{padding:var(--s-4) var(--s-4) 56px}
}
@media (max-width:760px){
  /* 顶栏压缩，导航改为可横滑的胶囊条 */
  .topbar{padding:var(--s-3) var(--s-4);gap:var(--s-3)}
  .brand h1{font-size:16px}
  .brand p{display:none}
  .nav{
    flex-wrap:nowrap;overflow-x:auto;margin-left:0;width:100%;
    gap:var(--s-2);padding-bottom:2px;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;
  }
  .nav::-webkit-scrollbar{display:none}
  .nav > button,.nav > .whoami{height:44px;flex:none;padding:0 var(--s-3);font-size:14px}
  /* 控件多，导航按原样横滑。身份胶囊限宽，名字长也不会把右端两个退出按钮推太远；
     它必须留在条里——改密码只有这一个入口。 */
  .nav > .whoami{max-width:104px;overflow:hidden}
  .nav > .exit-btn{height:40px;font-size:13px}
  /* 触控目标 ≥44px，字号 16px 防 iOS 自动缩放 */
  .btn{min-height:44px;padding:10px var(--s-4);font-size:15px}
  .btn.tiny{min-height:36px}
  input,select,textarea{font-size:16px}
  input[type=search]{min-width:0;width:100%}
  .toolbar{gap:var(--s-2)}
  .toolbar > input[type=search]{flex:1 1 100%}
  .cards{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:var(--s-3)}
  .card{padding:var(--s-3)}
  .card .n{font-size:26px}
  /* 表格自己横向滚，页面不再被撑宽。
     实测客户页在 476 宽的手机上被撑到 665px、记一单被撑到 516px，
     整页左右拖的时候连顶栏工具栏都跟着跑。
     只挂在这几个「纯表格」容器上，不给 .panel 统一加 overflow——
     「记一单」里客户搜索的下拉是绝对定位子元素，会被父级 overflow 裁掉。 */
  #custList,#prodList,#trialLedger,#orderMonthList,#pendingShipList,
  #usersHost,#perfHost,#auditHost{overflow-x:auto}
  /* 表格里的行内动作不换行：手机上曾经被挤成「改名/划拨/重置/停用」四行竖排，
     一行账号占掉 110px 高，还顶出屏幕 110px 宽。宁可表格横向滚。 */
  td.acts{white-space:nowrap}
  td.acts .btn{margin-right:var(--s-1)}
  /* 客户表：手机上先砍信息量最小、屏幕最缺的三列（序号/归属/地址），
     地址仍可通过搜索命中，详情里也看得到。点数细节在第 3 批改成卡片。
     另外把表格退回 auto 布局：定宽布局在窄屏上如果「各列宽度之和 > 可用宽度」，
     列与列会直接压在一起（实测名字和电话叠成一团），auto 是宁可整体超宽也不重叠。 */
  .cust-table{table-layout:auto;min-width:0}
  .cust-table .c-seq,.cust-table .c-owner,.cust-table .c-addr{display:none}
  .cust-table .c-name{width:auto;max-width:200px;overflow:hidden;text-overflow:ellipsis}
  .cust-table .btn.tiny{min-height:30px;padding:3px var(--s-2)}
  /* 订单行：一行 4 个控件挤不下（实测溢出 40px），改成两列栅格 */
  .order-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-2)}
  .order-row select,.order-row input,
  .order-row .q,.order-row .p{width:100%;min-width:0;flex:none}
  .order-row .rm{grid-column:1/-1;justify-self:end}
  .panel{padding:var(--s-4);border-radius:var(--r-md)}
  table{font-size:var(--fs-sm)}
  th,td{padding:10px var(--s-2)}
  .modal{padding:var(--s-4) var(--s-3)}
  .modal-box{padding:var(--s-4);border-radius:var(--r-md)}
  .modal-box .actions-row .btn{flex:1}
  .follow{padding:var(--s-3)}
  .bar-name{width:92px}
  .bar-val{width:84px}
  .form-panel label{width:100%}
  .form-panel .lb-inline{margin-left:0}
  /* 导入页的目录行：手机上标签独占一行，输入框吃满剩余宽度，
     否则 428px 的内容区里路径只能看到「E://每日发货记录//202」 */
  /* 窄屏：规格表退回 auto 并给一个最小宽度，表格在容器里横向滚，
     不把五列硬压进 400px（压了以后输入框和文字会互相盖住）。 */
  .spec-table{table-layout:auto;min-width:520px}
  .spec-table .sp{display:none}
  .dir-row > label{width:100%}
  .dir-field{min-width:0}
  .dir-field .btn{flex:0 0 auto}
}

/* 中等宽度（≤1100）：先收「地址」。
   客户表 9 列全部展开需要约 900px；1100 视口下面板内宽只有 900 出头，
   地址列会被压到 100px 以内，只能显示「XX省XX市…」——不如让位给名字和金额，
   地址还能靠搜索命中、点客户进详情也看得到。 */
@media (max-width:1100px){
  .cust-table .c-addr{display:none}
}

/* 平板（≤960）：再收序号和归属，并退回 auto 布局。
   定宽布局的前提是「各列宽度之和 ≤ 可用宽度」，否则列会互相压住；
   这一段可用宽度不足 900，必须让位。 */
@media (max-width:960px){
  .cust-table{table-layout:auto;min-width:0}
  .cust-table .c-seq,.cust-table .c-owner{display:none}
  .cust-table .c-name{width:auto;max-width:210px;overflow:hidden;text-overflow:ellipsis}
}

/* 手机竖屏（≤560）：客户表整张变成卡片。
   ------------------------------------------------------------------
   表格在 476 宽下只有两条路：横滑（找不到人）、或者砍到 4 列小字
   （看得见名字，看不见「多少钱、上次什么时候买」）。
   卡片按三行排：谁 + 多少钱 / 电话 · 最近下单 · 几单 / 地址 + 两个动作。
   一份 DOM 两种形态，不用维护第二套渲染；整卡可点进详情（tr 上的 data-cust），
   行内「记一单」「拨号」在点击委托里排在它前面判断。 */
.m-only{display:none}

@media (max-width:560px){
  .m-only{display:inline-block}
  .d-only{display:none}

  /* 行内空态在手机上换两行：图标+标题一行、按钮一行。
     四个 flex 项挤不进 395px，原来会折成三行 139px，比合并之前省不了多少。
     那句解释（es-hint）在手机上隐去——标题已经说明「还没有成交」，按钮就是下一步。 */
  .empty-state.inline{
    display:grid;grid-template-columns:auto minmax(0,1fr);
    gap:var(--s-2) var(--s-2);align-items:center;
  }
  .empty-state.inline .es-icon{grid-area:1/1}
  .empty-state.inline .es-title{grid-area:1/2}
  .empty-state.inline .es-hint{display:none}
  .empty-state.inline .btn{grid-area:2/2;justify-self:start;margin:0}

  /* ---------- 跟进卡在手机上压高度（230 → 约 160） ----------
     一屏最多放 3.5 张，打完一轮 30 家要滑十几屏。高度从三处让出来，
     全是「内容不变、只是不并排」的让法，不砍任何一条信息：
     ① 商品元信息折两行 → 藏掉推算出来的「周期」「预计用完日」两段，回到一行；
     ② 话术 3–4 行 → 折两行，点一下展开（复制仍取全文，不受影响）；
     ③ 地址和按钮挤成两行 → 地址让出宽度，和按钮同一行。 */
  .follow{padding:10px 12px}
  .item .m-cycle,.item .m-pred{display:none}
  .item .m-last .dt{display:none}
  .item .m-last .ago::before,.item .m-last .ago::after{content:none}
  /* clamp 只作用在视觉上，textContent 仍是完整话术，
     所以「复制话术」拿到的还是全文（见 app.js data-copy-msg）。
     右侧留 34px 空槽放「全文」——不放渐隐带压在字上：
     试过渐变遮罩，最后两个字会被牌子盖掉一半，看着像话术被截坏了。 */
  .msg-wrap .message{
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
    overflow:hidden;cursor:pointer;padding-right:34px;
  }
  .msg-wrap::after{
    content:'全文';position:absolute;right:0;bottom:0;
    width:34px;text-align:right;font-size:11px;line-height:20px;color:var(--brand);
    pointer-events:none;
  }
  .follow.msg-on .msg-wrap .message{display:block;overflow:visible;padding-right:0}
  .follow.msg-on .msg-wrap::after{display:none}
  /* 本来就只有一两行的短话术，不挂「全文」（渲染后由 app.js 量出 .no-cut） */
  .follow.no-cut .msg-wrap::after{display:none}
  /* 地址不再占一整行：flex-basis 归零后它会一直缩，
     实在放不下才换行，而不是一上来就催着换行。 */
  .follow-foot .addr{flex:1 1 0;min-width:0}
  .follow.note-on .follow-foot input[data-note]{flex:1 1 100%;order:99;width:100%}

  /* ---------- 产品页规格表：手机上压进一屏，不再横滑 ----------
     原来 ≤760 段给了 min-width:520px，让表格在容器里横向滚。
     可一屏只有 442：滚到最右才能看见「删除」，等于手机上根本没法删规格。
     四招把 520 压到 300 出头，剩下的宽度留给末尾 .sp 空列：
     ① 「单位」不单独占列，并进规格里写成「1斤 / 桶」；
     ② 单价输入框吃满列宽，不再固定 86px；
     ③ 「试吃装」三个字去掉，只留勾选框（表头就写着「试吃装」）；
     ④ 「删除」收成 40px 方钮，文字留在 DOM 里给读屏。 */
  #prodList .spec-table{table-layout:fixed;min-width:0;width:100%}
  #prodList .spec-table th,
  #prodList .spec-table td{padding:5px 6px}
  #prodList .spec-table th:nth-child(2),
  #prodList .spec-table td:nth-child(2){display:none}
  #prodList .spec-table th:nth-child(1),#prodList .spec-table td:nth-child(1){width:110px}
  #prodList .spec-table th:nth-child(3),#prodList .spec-table td:nth-child(3){width:94px}
  #prodList .spec-table th:nth-child(4),#prodList .spec-table td:nth-child(4){width:58px}
  #prodList .spec-table th:nth-child(5),#prodList .spec-table td:nth-child(5){width:44px}
  #prodList .spec-table td:first-child{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #prodList .spec-table .u{display:inline;color:var(--muted)}
  /* ≤760 段把 .sp 藏了（表格在横滑，末尾空列没意义）；
     这里表格不横滑了，得把空列还回来，剩余宽度才落在右边，
     而不是被摊给「规格/单价」四列、把内容拉散。 */
  #prodList .spec-table .sp{display:table-cell}
  #prodList .spec-table input.spec-in{width:100%;min-width:0}
  #prodList .spec-table .trial-flag{
    width:100%;justify-content:center;font-size:0;gap:0;
  }
  #prodList .spec-table [data-del-spec]{
    width:38px;min-width:38px;padding:0;font-size:0;opacity:1;
    color:var(--muted);border-color:transparent;background:transparent;
  }
  #prodList .spec-table [data-del-spec]::before{content:'×';font-size:18px;line-height:1}
  #prodList .spec-table [data-del-spec]:active{
    color:var(--red);border-color:#eccec9;background:var(--red-soft);
  }

  /* 卡片自己撑开，不需要横向滚动容器 */
  #custList{overflow:visible}
  .cust-table,.cust-table tbody{display:block;min-width:0}
  .cust-table thead{display:none}
  .cust-table tr{
    display:grid;
    grid-template-columns:minmax(0,1fr) auto auto 96px;
    align-items:center;
    column-gap:6px;row-gap:1px;
    padding:10px 12px;margin:0 0 8px;
    background:var(--surface);
    border:1px solid var(--line);border-radius:var(--r-md);
    box-shadow:var(--sh-1);cursor:pointer;
  }
  .cust-table tr:last-child{margin-bottom:0}
  .cust-table tr:active{background:var(--surface-2)}
  .cust-table td{
    display:block;padding:0;border:none;min-width:0;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  /* 第一行：名字跨前三列，金额钉在右端 */
  .cust-table td.c-name{grid-row:1;grid-column:1/4;font-size:var(--fs-lg)}
  .cust-table td.c-amount{grid-row:1;grid-column:4;font-size:15px;font-weight:600}
  /* 第二行：电话在左，最近下单与单数靠右，中间自然留白 */
  .cust-table td.c-phone{grid-row:2;grid-column:1;font-size:var(--fs-sm);color:var(--text-2)}
  .cust-table td.c-last{grid-row:2;grid-column:2;font-size:var(--fs-xs);color:var(--muted)}
  .cust-table td.c-orders{grid-row:2;grid-column:3;font-size:var(--fs-xs);color:var(--muted)}
  .cust-table td.c-last::before,
  .cust-table td.c-orders::before{content:'·';margin-right:5px;color:var(--line)}
  .cust-table td.c-orders::after{content:' 单'}
  /* 第三行：地址单行省略，右侧两个 40px 圆钮 */
  /* ≤760 段把地址列藏了（表格放不下），卡片形态要再打开 */
  .cust-table td.c-addr{
    display:block;grid-row:3;grid-column:1/4;
    font-size:var(--fs-xs);padding-top:3px;
  }
  .cust-table td.c-act{
    grid-row:3;grid-column:4;
    display:flex;align-items:center;justify-content:flex-end;gap:8px;
    overflow:visible;
  }
  /* 「记一单」收成圆形图标：文字留在 DOM 里给读屏，视觉上只显示 ＋ */
  .cust-table .c-act .btn{
    width:40px;height:40px;min-height:40px;padding:0;border-radius:50%;
    font-size:0;flex:none;
  }
  .cust-table .c-act .btn::before{content:'＋';font-size:19px;line-height:1;font-weight:400}
  .icon-act{
    width:40px;height:40px;flex:none;border-radius:50%;
    display:inline-flex;align-items:center;justify-content:center;
    border:1px solid var(--line);background:var(--surface);color:var(--text-2);
    text-decoration:none;
  }
  .icon-act:active{background:var(--surface-3);color:var(--brand)}
}

/* 拨号按钮只在手机出现：桌面 92px 的操作列放不下两个按钮，
   而且电脑上拨号也没意义（微信销售不走电话外呼）。 */
.icon-act{display:none}
@media (max-width:560px){ .icon-act{display:inline-flex} }

/* 尊重系统「减弱动效」设置 */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important}
}

/* 打印：隐藏交互元素，保持可读 */
@media print{
  .topbar,.nav,.toast,.modal{display:none !important}
  body{background:#fff}
  .panel,.card,.follow{box-shadow:none}
}

/* ---------- 分页：客户页页码条 / 队列「加载更多」 ----------
   客户页 50 家一页，只有一页时 JS 直接给空串，所以这里只管多页的样子。
   页码条固定在列表下方居中，翻页时不用来回找按钮。 */
.pager{
  display:flex;align-items:center;justify-content:center;gap:var(--s-3);
  flex-wrap:wrap;padding:var(--s-3) var(--s-2);
}
.pager .pg{font-size:14px;color:var(--muted)}
.pager .pg b{color:var(--text)}
.pager .btn[disabled]{opacity:.45;cursor:not-allowed}
/* 待回填 / 按月翻单的「加载更多」：居中一行，不抢表格的视线 */
.more-row{display:flex;justify-content:center;padding:var(--s-3) 0}
/* 记一单搜客户：命中超过 8 家时在列表末尾提示收窄关键词 */
.suggest .s-more{
  position:relative;background:var(--surface);border:1px solid var(--line);
  border-top:none;padding:var(--s-2) var(--s-4);
  font-size:13px;color:var(--muted);border-radius:0 0 var(--r-md) var(--r-md);
}
