:root{
  --bg:#f4f6f8; --card:#fff; --ink:#101828; --ink2:#475467; --ink3:#98a2b3;
  --line:#e4e7ec; --brand:#0f766e; --brand-2:#115e59; --brand-soft:#e6f4f1;
  --ok:#067647; --warn:#b54708; --bad:#b42318; --info:#175cd3;
  --radius:14px; --shadow:0 1px 2px rgba(16,24,40,.06),0 8px 24px -12px rgba(16,24,40,.18);
  --safe-b: env(safe-area-inset-bottom, 0px);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;height:100%}
body{
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei","Noto Sans CJK SC",system-ui,sans-serif;
  background:var(--bg); color:var(--ink); font-size:14px; line-height:1.55;
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
a{color:var(--brand);text-decoration:none}
button{font-family:inherit}
input,select,textarea{font-family:inherit;font-size:16px}
.boot{display:flex;align-items:center;justify-content:center;min-height:100vh}
.boot-box{text-align:center;color:var(--ink2)}
.logo{width:56px;height:56px;border-radius:16px;background:var(--brand);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:19px;margin:0 auto 12px}

/* ---------- layout ---------- */
.shell{display:flex;min-height:100vh}
.side{width:248px;flex:0 0 248px;background:#0b3a37;color:#cfeee9;display:flex;flex-direction:column;position:sticky;top:0;height:100vh}
.side .brand{display:grid;grid-template-columns:38px 1fr;column-gap:11px;align-items:center;padding:20px 15px 16px}
.side .brand .logo{width:38px;height:38px;font-size:14px;border-radius:11px;margin:0;background:#14b8a6;color:#04302d;letter-spacing:0}
.side .brand b{display:block;font-size:14px;color:#fff;letter-spacing:.4px;line-height:1.35;font-weight:600}
.side .brand span{display:block;font-size:11px;color:#7fbfb7;letter-spacing:.3px;margin-top:1px}
.nav{padding:8px 10px 14px;overflow-y:auto;flex:1}
/* 网格布局：图标列固定 20px，文字列左对齐 —— 所有条目文字严格对齐 */
.nav a{display:grid;grid-template-columns:20px 1fr;align-items:center;column-gap:11px;
  padding:9px 11px;border-radius:9px;color:#b6ded8;font-size:13.5px;line-height:20px;min-height:38px;
  letter-spacing:.2px;margin-bottom:1px;position:relative;transition:background .14s,color .14s}
.nav a .ico{display:flex;align-items:center;justify-content:center;width:20px;height:20px;flex:0 0 20px}
.nav a .lbl{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}
.nav a svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round;opacity:.82;display:block}
.nav a.on,.nav a:hover{background:rgba(255,255,255,.1);color:#fff}
.nav a.on svg,.nav a:hover svg{opacity:1}
.nav a.on:before{content:"";position:absolute;left:-10px;top:50%;transform:translateY(-50%);
  width:3px;height:18px;border-radius:0 3px 3px 0;background:#2dd4bf}
.nav .grp{font-size:11px;color:#5f9b94;padding:14px 11px 6px;letter-spacing:1.2px;font-weight:600}
.side .me{border-top:1px solid rgba(255,255,255,.1);padding:13px 15px 15px}
.side .me b{color:#fff;font-size:13px;display:block;line-height:1.4}
.side .me span{font-size:11px;color:#7fbfb7;display:block;margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.main{flex:1;min-width:0;display:flex;flex-direction:column}
.top{height:58px;background:#fff;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:12px;padding:0 18px;position:sticky;top:0;z-index:20}
.top h1{font-size:16px;margin:0;font-weight:600;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.top .bell{position:relative;cursor:pointer;border:none;background:none;padding:7px;border-radius:9px;
  display:flex;align-items:center;justify-content:center;color:var(--ink2);transition:background .14s,color .14s}
.top .bell:hover{background:#f2f4f7;color:var(--brand)}
.top .bell svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;display:block}
.top .bell i{position:absolute;top:2px;right:0;background:var(--bad);color:#fff;font-size:10px;font-style:normal;padding:0 4px;border-radius:8px;line-height:14px}
.content{padding:18px;max-width:1280px;width:100%;margin:0 auto;flex:1}
.tabbar{display:none;position:fixed}

/* ---------- cards / typography ---------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:16px;margin-bottom:14px}
.card h3{margin:0 0 12px;font-size:14.5px;font-weight:600;display:flex;align-items:center;gap:8px}
.card h3 .sub{font-weight:400;color:var(--ink3);font-size:12px}
.grid{display:grid;gap:12px}
.g4{grid-template-columns:repeat(4,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g2{grid-template-columns:repeat(2,1fr)}
.stat{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow)}
.stat .k{font-size:12px;color:var(--ink2)}
.stat .v{font-size:26px;font-weight:650;letter-spacing:-.5px;margin-top:2px}
.stat.brand .v{color:var(--brand)}
.stat.warn .v{color:var(--warn)}
.stat.bad .v{color:var(--bad)}
.stat.ok .v{color:var(--ok)}
.muted{color:var(--ink2)}
.tiny{font-size:12px;color:var(--ink3)}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.spread{display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap}
.empty{text-align:center;padding:38px 16px;color:var(--ink3)}
.empty .big{margin:0 auto 10px;opacity:.3;width:34px;height:34px;display:flex;align-items:center;justify-content:center}
.empty .big svg{width:34px;height:34px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;border:1px solid var(--line);background:#fff;color:var(--ink);
  padding:9px 14px;border-radius:10px;font-size:13.5px;font-weight:500;cursor:pointer;transition:.15s;white-space:nowrap}
.btn:hover{border-color:#c8cdd6;background:#fafbfc}
.btn:disabled{opacity:.55;cursor:not-allowed}
.btn.primary{background:var(--brand);border-color:var(--brand);color:#fff}
.btn.primary:hover{background:var(--brand-2);border-color:var(--brand-2)}
.btn.danger{background:#fff;border-color:#fca5a5;color:var(--bad)}
.btn.danger:hover{background:#fef3f2}
.btn.ghost{background:transparent;border-color:transparent;color:var(--ink2);padding:6px 8px}
.btn.sm{padding:6px 10px;font-size:12.5px;border-radius:8px}
.btn.block{width:100%}
.btn-ico{display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;margin-right:5px}
.btn-ico svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* ---------- forms ---------- */
label.f{display:block;margin-bottom:12px}
label.f > span{display:block;font-size:12.5px;color:var(--ink2);margin-bottom:6px}
label.f > span b{color:var(--bad);font-weight:400}
.inp,select.inp,textarea.inp{width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:10px;background:#fff;color:var(--ink);outline:none;transition:.15s}
.inp:focus{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft)}
textarea.inp{min-height:84px;resize:vertical}
.hint{font-size:11.5px;color:var(--ink3);margin-top:4px}
.err{background:#fef3f2;color:var(--bad);border:1px solid #fecdca;padding:9px 12px;border-radius:10px;font-size:12.5px;margin-bottom:12px}
.okbox{background:#ecfdf3;color:var(--ok);border:1px solid #abefc6;padding:9px 12px;border-radius:10px;font-size:12.5px;margin-bottom:12px}
.notice{background:#fffaeb;border:1px solid #fedf89;color:#93370d;padding:10px 12px;border-radius:10px;font-size:12.5px}
.drop{border:1.5px dashed #cbd5e1;border-radius:12px;padding:22px;text-align:center;color:var(--ink2);cursor:pointer;background:#fcfdfe}
.drop.over{border-color:var(--brand);background:var(--brand-soft)}
.drop b{display:block;color:var(--ink);margin-bottom:2px}

/* ---------- table ---------- */
table{width:100%;border-collapse:collapse;font-size:13px}
th{text-align:left;font-weight:500;color:var(--ink2);font-size:12px;padding:9px 10px;border-bottom:1px solid var(--line);white-space:nowrap;background:#fbfcfd}
td{padding:10px;border-bottom:1px solid #f1f3f6;vertical-align:middle}
tr:hover td{background:#fbfcfd}
.tbl-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.tbl-wrap table{min-width:640px}

/* ---------- badges ---------- */
.bdg{display:inline-flex;align-items:center;gap:4px;font-size:11.5px;padding:2px 8px;border-radius:20px;background:#f2f4f7;color:var(--ink2);white-space:nowrap;font-weight:500}
.bdg.ok{background:#ecfdf3;color:var(--ok)}
.bdg.warn{background:#fffaeb;color:var(--warn)}
.bdg.bad{background:#fef3f2;color:var(--bad)}
.bdg.info{background:#eff8ff;color:var(--info)}
.bdg.brand{background:var(--brand-soft);color:var(--brand-2)}

/* ---------- login ---------- */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px;
  background:radial-gradient(1200px 600px at 20% 0%,#14807a 0%,#0b3a37 55%,#072825 100%)}
.login{width:100%;max-width:392px;background:#fff;border-radius:18px;padding:26px 24px;box-shadow:0 24px 60px -20px rgba(0,0,0,.5)}
.login .logo{margin:0 0 14px}
.login h2{margin:0 0 4px;font-size:19px}
.login p.sub{margin:0 0 20px;color:var(--ink2);font-size:12.5px}
.login .foot{margin-top:14px;text-align:center;font-size:11.5px;color:var(--ink3)}

/* ---------- steps ---------- */
.steps{display:flex;align-items:flex-start;gap:0;margin:4px 0 16px;overflow-x:auto;padding-bottom:4px}
.step{flex:1;min-width:96px;text-align:center;position:relative;font-size:11.5px;color:var(--ink3)}
.step .dot{width:26px;height:26px;border-radius:50%;background:#f2f4f7;color:var(--ink3);display:flex;align-items:center;justify-content:center;
  margin:0 auto 5px;font-size:12px;font-weight:600;position:relative;z-index:2}
.step:before{content:"";position:absolute;top:13px;left:-50%;width:100%;height:2px;background:#eef1f4;z-index:1}
.step:first-child:before{display:none}
.step.done .dot{background:var(--ok);color:#fff}
.step.cur .dot{background:var(--brand);color:#fff;box-shadow:0 0 0 4px var(--brand-soft)}
.step.cur{color:var(--brand-2);font-weight:600}
.step.rej .dot{background:var(--bad);color:#fff}

/* ---------- timeline ---------- */
.tl{position:relative;padding-left:22px}
.tl:before{content:"";position:absolute;left:6px;top:6px;bottom:6px;width:2px;background:#eef1f4}
.tl-item{position:relative;padding-bottom:16px}
.tl-item:before{content:"";position:absolute;left:-22px;top:4px;width:12px;height:12px;border-radius:50%;background:#fff;border:2.5px solid #cfd6df}
.tl-item.ok:before{border-color:var(--ok);background:var(--ok)}
.tl-item.rej:before{border-color:var(--bad);background:var(--bad)}
.tl-item .t{font-size:13px;font-weight:600}
.tl-item .m{font-size:12px;color:var(--ink2)}
.tl-item .c{font-size:12.5px;background:#f8fafb;border-left:3px solid var(--line);padding:6px 9px;border-radius:0 8px 8px 0;margin-top:5px}

/* ---------- drawer / modal ---------- */
.mask{position:fixed;inset:0;background:rgba(16,24,40,.45);z-index:100;display:flex;align-items:center;justify-content:center;padding:16px;backdrop-filter:blur(2px)}
.modal{background:#fff;border-radius:16px;max-width:640px;width:100%;max-height:88vh;overflow:auto;box-shadow:0 24px 60px -12px rgba(0,0,0,.35)}
.modal .hd{padding:16px 18px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;position:sticky;top:0;background:#fff;z-index:2;border-radius:16px 16px 0 0}
.modal .hd h3{margin:0;font-size:15px}
.modal .bd{padding:16px 18px}
.modal .ft{padding:12px 18px;border-top:1px solid var(--line);display:flex;gap:10px;justify-content:flex-end;position:sticky;bottom:0;background:#fff}
.x{border:none;background:#f2f4f7;width:30px;height:30px;border-radius:9px;cursor:pointer;font-size:16px;color:var(--ink2);line-height:1}

/* ---------- toast ---------- */
#toasts{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(20px + var(--safe-b));z-index:300;display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none;width:100%;padding:0 16px}
.toast{background:#101828;color:#fff;padding:10px 16px;border-radius:10px;font-size:13px;box-shadow:0 8px 24px -8px rgba(0,0,0,.4);animation:ti .22s ease;max-width:420px}
.toast.ok{background:#067647}.toast.bad{background:#b42318}.toast.warn{background:#b54708}
@keyframes ti{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ---------- misc ---------- */
.kv{display:grid;grid-template-columns:96px 1fr;gap:6px 10px;font-size:13px}
.kv .k{color:var(--ink3);font-size:12.5px}
.chip{display:inline-block;background:#f2f4f7;border-radius:8px;padding:3px 8px;font-size:11.5px;color:var(--ink2);margin:0 4px 4px 0}
.pre{background:#0b1220;color:#d6e2f0;padding:12px;border-radius:10px;font-family:ui-monospace,Menlo,monospace;font-size:11.5px;overflow:auto;max-height:340px;white-space:pre-wrap;word-break:break-all}
.skeleton{background:linear-gradient(90deg,#f2f4f7 25%,#e9edf2 37%,#f2f4f7 63%);background-size:400% 100%;animation:sk 1.3s infinite;border-radius:8px;height:60px}
@keyframes sk{0%{background-position:100% 50%}100%{background-position:0 50%}}
.hide{display:none!important}

/* ---------- responsive: tablet ---------- */
@media (max-width:1100px){ .g4{grid-template-columns:repeat(2,1fr)} .g3{grid-template-columns:repeat(2,1fr)} }
/* ---------- responsive: mobile ---------- */
@media (max-width:780px){
  .side{display:none}
  .top{padding:0 14px;height:54px}
  .content{padding:12px 12px calc(74px + var(--safe-b))}
  .g4,.g3,.g2{grid-template-columns:1fr 1fr}
  .g2.force1,.g4.force1{grid-template-columns:1fr}
  .card{padding:13px;border-radius:12px}
  .stat{padding:12px}
  .stat .v{font-size:22px}
  .tabbar{display:flex;position:fixed;left:0;right:0;bottom:0;background:#fff;border-top:1px solid var(--line);
    z-index:80;padding-bottom:var(--safe-b);box-shadow:0 -2px 10px -4px rgba(16,24,40,.16)}
  .tabbar a{flex:1;text-align:center;padding:7px 2px 5px;font-size:10.5px;color:var(--ink3);
    display:flex;flex-direction:column;align-items:center;gap:3px;letter-spacing:.2px}
  .tabbar a .ico{display:flex;align-items:center;justify-content:center;width:22px;height:22px}
  .tabbar a svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.7;
    stroke-linecap:round;stroke-linejoin:round;display:block}
  .tabbar a.on{color:var(--brand);font-weight:600}
  .tabbar a.on svg{stroke-width:2}
  .m-hide{display:none!important}
  .modal{max-height:92vh;border-radius:14px}
  .steps .step{min-width:78px}
  .login{padding:22px 18px}
  .kv{grid-template-columns:84px 1fr}
}
@media (max-width:520px){
  .g4,.g3,.g2{grid-template-columns:1fr 1fr}
  .g2.force1,.g4.force1,.g3.force1{grid-template-columns:1fr}
  .stat .v{font-size:21px}
  .stat .k{font-size:11.5px}
  .top h1{font-size:15.5px}
  .top .btn.sm{padding:7px 10px;font-size:12.5px}
}
@media (max-width:380px){ .g4,.g3{grid-template-columns:1fr 1fr} }

/* ---------- 移动端表格 → 卡片式（避免横向截断） ---------- */
@media (max-width:780px){
  .tbl-wrap{overflow:visible}
  .tbl-wrap table{min-width:0;display:block}
  .tbl-wrap thead{display:none}
  .tbl-wrap tbody,.tbl-wrap tr,.tbl-wrap td{display:block;width:auto}
  .tbl-wrap tr{border:1px solid var(--line);border-radius:11px;padding:10px 12px;margin-bottom:9px;background:#fff}
  .tbl-wrap tr:hover td{background:transparent}
  .tbl-wrap td{border:none;padding:2px 0;font-size:13px;display:flex;gap:10px;align-items:baseline}
  .tbl-wrap td:before{
    content:attr(data-th);flex:0 0 62px;color:var(--ink3);font-size:11.5px;line-height:1.7;
  }
  .tbl-wrap td:empty{display:none}
  .tbl-wrap td[data-th=""]:before{display:none}
  .dash-recent .tbl-wrap td:nth-child(1){font-weight:600}
}


/* toast 在移动端需抬升到标签栏之上，避免遮挡图标 */
@media (max-width:780px){
  #toasts{bottom:calc(76px + var(--safe-b))}
}


/* 卡片标题在窄屏不换行、副标题独立成行 */
@media (max-width:780px){
  .card h3{flex-wrap:wrap;row-gap:2px;line-height:1.4}
  .card h3 .sub{flex-basis:100%;font-size:11.5px;line-height:1.5}
}


/* ---------- 趋势柱状图 ---------- */
.trend{display:flex;align-items:flex-end;gap:4px;height:140px;padding-top:6px}
.trend-col{flex:1;min-width:0;display:flex;flex-direction:column;height:100%}
.trend-bar-wrap{flex:1;display:flex;align-items:flex-end}
.trend-bar{width:100%;background:linear-gradient(180deg,#2dd4bf,#0f766e);border-radius:4px 4px 0 0;transition:height .2s}
.trend-col:hover .trend-bar{background:linear-gradient(180deg,#14b8a6,#115e59)}
.trend-lbl{font-size:9.5px;color:var(--ink3);text-align:center;margin-top:5px;height:13px;line-height:13px;white-space:nowrap;overflow:hidden}
