:root{
  --bg:#f5f6f8; --card:#fff; --line:#e3e5e9; --line2:#d0d3d9;
  --tx:#1f2328; --tx2:#5b6270; --tx3:#8b929e;
  --brand:#1a56db; --brand-d:#1244b0; --brand-l:#eaf0fd;
  --ok:#1a7f37; --ok-l:#e8f5ec; --warn:#9a6700; --warn-l:#fff8e5;
  --err:#c62828; --err-l:#fdecec;
  --r:10px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg);color:var(--tx);
  font:15px/1.65 system-ui,-apple-system,"Segoe UI","Microsoft YaHei",sans-serif;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3{margin:0;font-weight:600;letter-spacing:-.01em}
h1{font-size:22px}h2{font-size:18px}h3{font-size:15px}
a{color:var(--brand);text-decoration:none}
button{font:inherit;cursor:pointer}
input,select,textarea{font:inherit;color:inherit}

.hidden{display:none!important}
.muted{color:var(--tx2)}
.small{font-size:13px}
.tiny{font-size:12px;color:var(--tx3)}
.mono{font-family:ui-monospace,Consolas,monospace;font-size:12.5px}
.row{display:flex;gap:10px;align-items:center}
.wrap{flex-wrap:wrap}
.spread{display:flex;justify-content:space-between;align-items:center;gap:12px}
.grow{flex:1;min-width:0}

/* 登录 */
.login-wrap{min-height:100vh;display:grid;place-items:center;padding:24px}
.login-card{width:100%;max-width:390px;background:var(--card);border:1px solid var(--line);
  border-radius:14px;padding:32px 28px}
.login-card h1{font-size:20px;margin-bottom:4px}
.login-card .sub{color:var(--tx2);font-size:13px;margin-bottom:24px}
.login-hint{margin-top:18px;padding:12px 14px;background:var(--brand-l);border-radius:8px;
  font-size:12.5px;color:#1244b0;line-height:1.9}

/* 顶栏 */
.top{position:sticky;top:0;z-index:20;background:var(--card);border-bottom:1px solid var(--line)}
.top-in{max-width:1080px;margin:0 auto;padding:0 20px;height:56px;display:flex;align-items:center;gap:16px}
.brand{font-weight:600;font-size:15px;display:flex;align-items:center;gap:8px}
.brand .dot{width:9px;height:9px;border-radius:50%;background:var(--brand)}
.nav{display:flex;gap:4px;margin-left:8px;flex:0 1 auto;min-width:0;overflow-x:auto;
  scrollbar-width:none;-ms-overflow-style:none}
.nav::-webkit-scrollbar{display:none}
.nav a{white-space:nowrap;flex:0 0 auto}
.nav a{padding:7px 12px;border-radius:7px;color:var(--tx2);font-size:14px}
.nav a:hover{background:#f0f1f3;color:var(--tx)}
.nav a.on{background:var(--brand-l);color:var(--brand-d);font-weight:500}
.who{margin-left:auto;display:flex;align-items:center;gap:10px;font-size:13px;flex:0 0 auto}
.badge{display:inline-block;padding:2px 8px;border-radius:20px;font-size:11.5px;
  background:#eef0f3;color:var(--tx2);white-space:nowrap}
.badge.b{background:var(--brand-l);color:var(--brand-d)}
.badge.g{background:var(--ok-l);color:var(--ok)}
.badge.o{background:var(--warn-l);color:var(--warn)}
.badge.r{background:var(--err-l);color:var(--err)}
/* 侧边栏待审红点。只在「一张单都没人打过电话」时亮——
   把「已联系待定」也算进去，红点就永远灭不掉，人两天就看不见它了 */
.nav .pill{display:inline-block;min-width:17px;padding:0 5px;margin-left:6px;
  border-radius:9px;background:var(--err);color:#fff;font-size:11px;
  line-height:17px;text-align:center;vertical-align:1px;font-weight:600}
.nav .pill[hidden]{display:none}

/* 当前页名：摆在品牌右边，灰字 + 一条竖线。
   不是为了好看，是为了能指着屏幕说「改这一页」还不认错。 */
.pagetag{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--tx2);
  white-space:nowrap;flex:0 0 auto}
.pagetag::before{content:"";width:1px;height:13px;background:var(--line);flex:0 0 auto}

/* 主体 */
.main{max-width:1080px;margin:0 auto;padding:24px 20px 80px}
.page-head{margin-bottom:20px}
.page-head .sub{color:var(--tx2);font-size:13.5px;margin-top:6px}

/* 卡片 */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:20px}
.card+.card{margin-top:16px}
.grid{display:grid;gap:12px}
/* grid 里的间距交给 gap。`.card+.card` 的 margin-top 是给竖排卡片准备的，
   在 grid 里会把第二张及之后的卡整体往下推 16px——2026-10-28 应用中心
   截图里两张卡一高一低、顶部对不齐，根因就是它。 */
.grid>.card+.card{margin-top:0}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
@media(max-width:720px){.g2,.g3,.g4{grid-template-columns:1fr 1fr}}

/* 应用卡 */
.app{cursor:pointer;transition:.12s;display:flex;gap:12px;align-items:flex-start}
.app:hover{border-color:var(--line2);box-shadow:0 2px 10px rgba(20,30,60,.06);transform:translateY(-1px)}
.app .ico{width:36px;height:36px;border-radius:9px;background:var(--brand-l);color:var(--brand-d);
  display:grid;place-items:center;font-weight:600;font-size:15px;flex:0 0 auto}
.app .nm{font-weight:500;font-size:14.5px}
.app .ds{font-size:12.5px;color:var(--tx2);margin-top:2px;line-height:1.55}
.cat-title{font-size:13px;font-weight:500;color:var(--tx3);margin:22px 0 10px;
  text-transform:none;letter-spacing:.02em}

/* 客户货架 —— 「我买了什么」，不是「我有什么权限」。
   三行结构，从上到下回答客户三个问题：
     第一行：这是什么、开通了没有
     第二行：它能帮我干什么（一句话，人话）
     第三行：什么时候到期、从哪进去
   第三行用 margin-top:auto 顶到底，几张卡并排时「打开」按钮永远在同一条水平线上，
   客户不用拿眼睛找。 */
/* auto-fit 不是 auto-fill：fill 会保留空轨道，只有两张卡时右边会空出一整列，
   看着像"页面没铺满"。fit 会把空轨道折叠掉，卡片自己撑开。 */
.shelf{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:16px}
.shelf-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  padding:18px 20px 16px;display:flex;flex-direction:column;min-height:168px;transition:.12s}
.shelf-card.on{cursor:pointer}
.shelf-card.on:hover{border-color:var(--line2);box-shadow:0 2px 10px rgba(20,30,60,.06)}
.shelf-head{display:flex;align-items:center;gap:11px}
.shelf-ico{width:40px;height:40px;border-radius:11px;flex:0 0 auto;display:grid;place-items:center;
  font-weight:600;font-size:16px;background:var(--brand-l);color:var(--brand-d)}
.shelf-ico.off{background:#f0f1f3;color:var(--tx3)}
.shelf-nm{flex:1;min-width:0;font-weight:600;font-size:15.5px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.shelf-blurb{margin:13px 0 0;font-size:13.5px;line-height:1.75;color:var(--tx2)}
.shelf-foot{margin-top:auto;padding-top:14px;border-top:1px solid var(--line);
  display:flex;align-items:center;justify-content:space-between;gap:12px}
.shelf-meta{font-size:12.5px;color:var(--tx3);min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* 「我们来看过这家几次」的明细。不做表格：手机 390 下三列会把字挤成竖排。 */
.visit-line{display:flex;flex-wrap:wrap;gap:2px 14px;padding:7px 0;font-size:13px;
  border-top:1px solid var(--line)}
.visit-line:first-child{border-top:0;padding-top:2px}
@media(max-width:460px){
  .shelf{grid-template-columns:1fr}
  .shelf-card{min-height:0}
}

/* 表单 */
.field{margin-bottom:14px}
.field label{display:block;font-size:13px;color:var(--tx2);margin-bottom:6px}
.field .hint{font-size:12px;color:var(--tx3);margin-top:5px;line-height:1.6}
input[type=text],input[type=password],input[type=number],input[type=date],
input[type=datetime-local],select,textarea{
  width:100%;padding:9px 11px;border:1px solid var(--line2);border-radius:8px;
  background:#fff;outline:none;transition:.12s}
input:focus,select:focus,textarea:focus{border-color:var(--brand);box-shadow:0 0 0 3px rgba(26,86,219,.12)}
textarea{min-height:66px;resize:vertical}

.btn{padding:9px 16px;border-radius:8px;border:1px solid var(--line2);background:#fff;font-size:14px;
  white-space:nowrap}
.btn:hover{background:#f4f5f7}
.btn.p{background:var(--brand);border-color:var(--brand);color:#fff}
.btn.p:hover{background:var(--brand-d)}
.btn.d{background:#fff;border-color:#e8b4b4;color:var(--err)}
.btn.sm{padding:5px 11px;font-size:13px;border-radius:6px}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn-row{display:flex;gap:10px;justify-content:flex-end;margin-top:20px}

/* 表 */
table{width:100%;border-collapse:collapse;font-size:13.5px}
th{text-align:left;font-weight:500;color:var(--tx3);font-size:12.5px;
  padding:9px 10px;border-bottom:1px solid var(--line)}
td{padding:11px 10px;border-bottom:1px solid #f0f1f3;vertical-align:middle}
tbody tr:hover{background:#fafbfc}
tbody tr:last-child td{border-bottom:none}

/* 提示条 */
.alert{padding:11px 14px;border-radius:8px;font-size:13px;line-height:1.65;margin-bottom:14px}
.alert.err{background:var(--err-l);color:#8e1f1f;border:1px solid #f3cccc}
.alert.warn{background:var(--warn-l);color:#7a5200;border:1px solid #f0e0b8}
.alert.ok{background:var(--ok-l);color:#14652c;border:1px solid #cbe7d3}
.alert.info{background:var(--brand-l);color:#1244b0;border:1px solid #cddcfb}

/* 模态 */
.mask{position:fixed;inset:0;background:rgba(20,25,40,.35);display:grid;place-items:center;
  z-index:50;padding:20px;overflow:auto}
.modal{background:#fff;border-radius:14px;width:100%;max-width:560px;padding:26px;
  max-height:88vh;overflow:auto;box-shadow:0 20px 60px rgba(10,20,50,.2)}
.modal.wide{max-width:720px}
.modal h2{margin-bottom:4px}
.modal .sub{color:var(--tx2);font-size:13px;margin-bottom:20px}

/* 查重结果 */
.hit{border:1px solid var(--line);border-radius:9px;padding:13px 14px;margin-bottom:9px;background:#fcfcfd}
.hit.is-sure{border-color:#f0c9c9;background:#fefafa}
.hit .nm{font-weight:500;font-size:14px}
.hit .rs{font-size:12px;color:var(--err);margin-top:4px}
.hit .meta{font-size:12px;color:var(--tx3);margin-top:3px}
.hit .acts{display:flex;gap:8px;margin-top:9px}

/* 步骤条 */
.steps{display:flex;gap:6px;margin-bottom:20px}
.steps .s{flex:1;height:3px;border-radius:2px;background:#e9ebee}
.steps .s.on{background:var(--brand)}

.empty{text-align:center;padding:44px 20px;color:var(--tx3);font-size:13.5px}
.kv{display:grid;grid-template-columns:100px 1fr;gap:8px 12px;font-size:13.5px}
.kv .k{color:var(--tx3)}
.tag{display:inline-block;padding:1px 7px;border-radius:5px;background:#f0f1f3;
  font-size:12px;color:var(--tx2);margin:2px 4px 2px 0}

@media(max-width:760px){
  .top-in{padding:0 12px;gap:8px}
  /* 品牌文字别在这个宽度就收掉：390 的手机上只剩一个蓝点，像页面没加载完。
     真正放不下是 460 以下的事，那一条在下面单独写。 */
  .nav{margin-left:0}
}

/* ---------------- 手机（真实使用场景：站在车间里拿手机看） ---------------- */

/* 卡片在窄屏必须塌成一列。原来 720 以下只降到两列，390 宽的手机上
   两列会把页面撑到 490 宽 —— 右侧按钮被顶出屏幕、正文被切掉半个字，
   看着像"网页坏了"，实际是宽度溢出了。 */
@media(max-width:460px){
  .g2,.g3,.g4{grid-template-columns:1fr}
}

/* 顶栏：手机上原来的排法放不下（品牌+页名+导航+账号挤成一团），
   改成两行 —— 第一行品牌/页名/账号，第二行导航自己横向滚。 */
@media(max-width:640px){
  .top-in{flex-wrap:wrap;height:auto;padding:9px 14px;gap:8px 10px}
  .pagetag{font-size:12px}
  .nav{order:3;flex:1 0 100%;margin-left:0;padding-bottom:2px}
  .who{gap:8px}
  .who .tiny{display:none}   /* 手机号在手机上不显示，占地方又不常看 */
  .main{padding:18px 14px 60px}
  .card{padding:16px}
}

/* 真的挤不下了：名字太长的徽章截断，但不清空——
   手机上「我是谁」比「我叫什么全名」重要。退出按钮永远留着。 */
@media(max-width:460px){
  .who .badge{max-width:84px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
}

/* 密码框：右边留出「显示」的位置；下面那行提示只在输错字符/开中文输入法时冒出来。
   网页换不了你的输入法，但至少让你一眼看见打进去的是中文还是英文。 */
.pwd-wrap{position:relative}
.pwd-wrap input{padding-right:56px}
.pwd-eye{position:absolute;right:4px;top:50%;transform:translateY(-50%);
  border:0;background:transparent;color:var(--tx3);font-size:12.5px;
  padding:4px 8px;cursor:pointer;border-radius:6px}
.pwd-eye:hover{color:var(--brand);background:var(--brand-l)}
.pwd-tip{display:none;margin-top:6px;font-size:12.5px;line-height:1.6;color:var(--warn)}
.pwd-tip.on{display:block}

/* 「手机号 + 获取验证码」一行。按钮不许换行——390px 上挤成两行
   会让整个表单看起来塌了一截，而这是客户第一次见我们的页面。 */
.otp-row{display:flex;gap:8px}
.otp-row input{flex:1;min-width:0}
.otp-row .btn{white-space:nowrap;padding:9px 12px;font-size:13px;flex:none}

/* 「客户」详情里的「最近改动」清单。默认的项目符号太大，挤得看不清时间。 */
.trail{margin:0;padding-left:18px}
.trail li{margin:7px 0;font-size:13px;line-height:1.6}
.trail li .tiny{margin-left:6px}

/* 临时密码：整屏只在这一处出现，要的就是"一眼看得清、手抄不会错"。
   所以字大、字距拉开、底下一行灰字交代"只显示这一次"。 */
.pwdbox{margin:16px 0 4px;padding:18px;border:1px dashed var(--line2);border-radius:10px;
  background:#fbfbfc;text-align:center;user-select:all}
.pwdbox .mono{font-size:30px;letter-spacing:4px;font-weight:600}
