:root{
  --brand:#4C1D95; --brand-800:#3B0F7A; --brand-700:#5B21B6; --brand-600:#6D28D9;
  --brand-500:#7C3AED; --brand-400:#8B5CF6; --brand-300:#A78BFA; --brand-50:#F3EEFB;
  --accent:#00BFA5; --accent-soft:#E0F7F1; --gold:#F59E0B; --gold-soft:#FEF3E2;
  --danger:#E5484D; --danger-soft:#FDECEC;
  --ink:#1F2333; --ink-2:#5A6072; --ink-3:#9098A8;
  --line:#ECEDF3; --bg:#F6F5FA; --card:#fff;
  --shadow-sm:0 2px 10px rgba(46,16,101,.06);
  --shadow-md:0 10px 30px rgba(46,16,101,.10);
  --radius:14px;
}
*{margin:0;padding:0;box-sizing:border-box;font-family:"PingFang SC","Microsoft YaHei",system-ui,sans-serif;}
body{background:var(--bg);color:var(--ink);font-size:14px;}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{background:#d9d5e6;border-radius:8px}

/* ============ 登录页 ============ */
.login-page{display:flex;min-height:100vh;}
.login-aside{width:440px;flex:none;background:linear-gradient(160deg,#2E1065 0%,#1E0A45 60%,#160734 100%);color:#fff;
  display:flex;flex-direction:column;justify-content:space-between;padding:48px 42px;position:relative;overflow:hidden;}
.login-aside::after{content:"";position:absolute;right:-120px;bottom:-120px;width:360px;height:360px;border-radius:50%;
  background:radial-gradient(circle,rgba(139,92,246,.35),transparent 65%);}
.login-aside .brand{display:flex;align-items:center;gap:14px;z-index:1;}
.login-aside .lg{width:52px;height:52px;border-radius:15px;background:linear-gradient(135deg,var(--brand-500),var(--brand));
  display:flex;align-items:center;justify-content:center;box-shadow:0 8px 22px rgba(124,58,237,.45);flex:none;}
.login-aside .tt{font-size:19px;font-weight:800;line-height:1.3;}
.login-aside .sub{font-size:12px;color:rgba(255,255,255,.55);margin-top:3px;}
.login-aside .hero{font-size:30px;font-weight:900;line-height:1.45;z-index:1;}
.login-aside .hero small{display:block;font-size:14px;font-weight:500;color:rgba(255,255,255,.6);margin-top:14px;line-height:1.9;}
.login-aside .foot{font-size:11.5px;color:rgba(255,255,255,.4);z-index:1;}
.login-main{flex:1;display:flex;align-items:center;justify-content:center;padding:24px;}
.login-box{width:380px;max-width:100%;}
.login-box h1{font-size:24px;font-weight:900;margin-bottom:6px;}
.login-box .desc{color:var(--ink-3);font-size:13px;margin-bottom:26px;}
.login-box .fm{margin-bottom:16px;}
.login-box label{display:block;font-size:12.5px;font-weight:700;color:var(--ink-2);margin-bottom:7px;}
.login-box input{width:100%;border:1px solid var(--line);border-radius:11px;padding:12px 14px;font-size:14px;outline:0;transition:.18s;background:#FBFAFD;}
.login-box input:focus{border-color:var(--brand-300);box-shadow:0 0 0 3px rgba(139,92,246,.12);background:#fff;}
.login-box .btn{width:100%;margin-top:6px;border:0;cursor:pointer;font-weight:700;font-size:15px;border-radius:11px;padding:13px;
  background:linear-gradient(135deg,var(--brand-500),var(--brand));color:#fff;box-shadow:0 8px 20px rgba(124,58,237,.32);transition:.18s;}
.login-box .btn:hover{transform:translateY(-1px);box-shadow:0 11px 26px rgba(124,58,237,.4);}
.login-box .btn:disabled{opacity:.6;cursor:not-allowed;transform:none;}
.login-err{background:var(--danger-soft);color:#C0392B;font-size:12.5px;font-weight:600;padding:10px 14px;border-radius:10px;margin-bottom:14px;display:none;}
.login-err.show{display:block;}
.login-demo{margin-top:20px;background:var(--brand-50);border:1px dashed var(--brand-300);border-radius:12px;padding:13px 15px;font-size:12px;color:var(--brand-700);line-height:1.9;}
.login-demo b{color:var(--brand-800);}

/* ============ 侧栏 ============ */
.side{width:236px;flex:none;background:linear-gradient(180deg,#2E1065 0%,#1E0A45 100%);color:#fff;
  display:flex;flex-direction:column;position:sticky;top:0;height:100vh;overflow-y:auto;}
.logo{display:flex;align-items:center;gap:10px;padding:20px 18px 16px;}
.logo .lg{width:38px;height:38px;border-radius:11px;background:linear-gradient(135deg,var(--brand-500),var(--brand));
  display:flex;align-items:center;justify-content:center;box-shadow:0 6px 16px rgba(124,58,237,.45);flex:none;}
.logo .tt{font-size:14.5px;font-weight:800;line-height:1.25;}
.logo .sub{font-size:10.5px;color:rgba(255,255,255,.55);font-weight:500;margin-top:2px;}
.nav{padding:4px 12px 18px;flex:1;}
.nav .grp{font-size:10.5px;color:rgba(255,255,255,.38);font-weight:700;letter-spacing:1.5px;margin:16px 8px 6px;}
.ni{display:flex;align-items:center;gap:11px;padding:9.5px 12px;border-radius:10px;cursor:pointer;
  color:rgba(255,255,255,.66);font-weight:600;font-size:13.5px;margin-bottom:2px;position:relative;transition:.18s;}
.ni:hover{background:rgba(255,255,255,.07);color:#fff;}
.ni.on{background:linear-gradient(90deg,rgba(139,92,246,.28),rgba(139,92,246,.10));color:#fff;}
.ni.on::before{content:"";position:absolute;left:-12px;top:8px;bottom:8px;width:3.5px;border-radius:0 4px 4px 0;background:var(--brand-300);}
.ni svg{flex:none;opacity:.9;}
.ni .bdg{margin-left:auto;font-size:10px;font-weight:800;background:var(--danger);color:#fff;border-radius:999px;padding:2px 7px;}
.side-foot{padding:14px 18px;border-top:1px solid rgba(255,255,255,.08);font-size:10.5px;color:rgba(255,255,255,.4);line-height:1.7;}

/* ============ 主区 ============ */
.main{flex:1;min-width:0;display:flex;flex-direction:column;}
.topbar{position:sticky;top:0;z-index:50;background:rgba(255,255,255,.86);backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);display:flex;align-items:center;gap:16px;padding:0 26px;height:60px;}
.crumb{font-size:16px;font-weight:800;}
.crumb small{color:var(--ink-3);font-weight:500;font-size:11.5px;margin-left:10px;}
.search{margin-left:auto;display:flex;align-items:center;gap:8px;background:#F2F1F7;border:1px solid transparent;
  border-radius:10px;padding:8px 14px;width:260px;color:var(--ink-3);transition:.2s;}
.search:focus-within{background:#fff;border-color:var(--brand-300);box-shadow:0 0 0 3px rgba(139,92,246,.12);}
.search input{border:0;outline:0;background:transparent;font-size:13px;width:100%;color:var(--ink);}
.icon-btn{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;
  cursor:pointer;color:var(--ink-2);position:relative;transition:.18s;}
.icon-btn:hover{background:var(--brand-50);color:var(--brand-700);}
.icon-btn .red-dot{position:absolute;top:7px;right:8px;width:8px;height:8px;border-radius:50%;background:var(--danger);border:1.5px solid #fff;}
.me{display:flex;align-items:center;gap:10px;cursor:pointer;padding:5px 6px;border-radius:10px;transition:.18s;position:relative;}
.me:hover{background:var(--brand-50);}
.ava{width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,var(--brand-500),var(--brand));
  color:#fff;font-size:13px;font-weight:800;display:flex;align-items:center;justify-content:center;flex:none;}
.me .nm{font-size:13px;font-weight:700;}
.me .rl{font-size:10.5px;color:var(--ink-3);}
.me-menu{position:absolute;top:48px;right:0;background:#fff;border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-md);
  padding:6px;min-width:150px;display:none;z-index:60;}
.me-menu.show{display:block;}
.me-menu .mi{padding:9px 12px;border-radius:8px;font-size:13px;font-weight:600;color:var(--ink-2);cursor:pointer;}
.me-menu .mi:hover{background:var(--brand-50);color:var(--brand-700);}
.content{padding:24px 26px 40px;flex:1;}

/* ============ 通用 ============ */
.page{display:none;animation:fadein .25s ease;}
.page.on{display:block;}
@keyframes fadein{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.pg-head{display:flex;align-items:center;gap:12px;margin-bottom:18px;}
.pg-head h2{font-size:19px;font-weight:900;}
.pg-head .tip{color:var(--ink-3);font-size:12.5px;}
.pg-head .sp{flex:1;}
.btn{border:0;cursor:pointer;font-weight:700;font-size:13px;border-radius:10px;padding:9px 18px;
  background:linear-gradient(135deg,var(--brand-500),var(--brand));color:#fff;box-shadow:0 6px 16px rgba(124,58,237,.30);transition:.18s;}
.btn:hover{transform:translateY(-1px);box-shadow:0 9px 20px rgba(124,58,237,.38);}
.btn:disabled{opacity:.55;cursor:not-allowed;transform:none;}
.btn.ghost{background:#fff;color:var(--brand-700);border:1px solid var(--brand-300);box-shadow:none;}
.btn.ghost:hover{background:var(--brand-50);}
.btn.sm{padding:5.5px 12px;font-size:12px;border-radius:8px;}
.card{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow-sm);padding:18px;}
.grid{display:grid;gap:14px;}
.pill{font-size:11px;font-weight:800;border-radius:999px;padding:3.5px 10px;white-space:nowrap;}
.p-ok{background:var(--accent-soft);color:#00806C;}
.p-warn{background:var(--gold-soft);color:#B45309;}
.p-err{background:var(--danger-soft);color:#C0392B;}
.p-info{background:var(--brand-50);color:var(--brand-700);}
.p-gray{background:#F0F1F5;color:var(--ink-2);}

/* KPI 卡 */
.kpis{grid-template-columns:repeat(4,1fr);margin-bottom:16px;}
.kpi{background:#fff;border-radius:var(--radius);box-shadow:var(--shadow-sm);padding:18px;position:relative;overflow:hidden;transition:.2s;}
.kpi:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);}
.kpi .ic{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;margin-bottom:12px;color:#fff;}
.kpi .k{font-size:12.5px;color:var(--ink-2);font-weight:600;}
.kpi .v{font-size:26px;font-weight:900;letter-spacing:.3px;margin-top:3px;}
.kpi .v small{font-size:14px;font-weight:700;color:var(--ink-2);}
.kpi .d{margin-top:8px;font-size:11.5px;font-weight:700;display:flex;align-items:center;gap:5px;}
.d.up{color:#00806C;} .d.down{color:#C0392B;} .d.dim{color:var(--ink-3);font-weight:500;}
.kpi::after{content:"";position:absolute;right:-26px;top:-26px;width:96px;height:96px;border-radius:50%;
  background:radial-gradient(circle,rgba(139,92,246,.10),transparent 70%);}

/* 图表区 */
.charts{grid-template-columns:1.9fr 1fr;margin-bottom:16px;}
.card .hd{display:flex;align-items:center;margin-bottom:14px;}
.card .hd h3{font-size:15px;font-weight:800;}
.card .hd .r{margin-left:auto;font-size:12px;color:var(--ink-3);cursor:default;}
.legend{display:flex;gap:14px;font-size:12px;color:var(--ink-2);font-weight:600;}
.legend i{display:inline-block;width:9px;height:9px;border-radius:3px;margin-right:5px;}
.donut-wrap{display:flex;align-items:center;gap:20px;}
.donut-side{flex:1;display:flex;flex-direction:column;gap:10px;}
.donut-side .li{display:flex;align-items:center;gap:8px;font-size:12.5px;}
.donut-side .li b{margin-left:auto;font-size:13px;}
.donut-side .li .bar{height:5px;border-radius:4px;background:#F0EEF8;flex:1;margin:0 2px;overflow:hidden;}
.donut-side .li .bar i{display:block;height:100%;border-radius:4px;}

/* 表格 */
.tbl{width:100%;border-collapse:collapse;}
.tbl th{font-size:11.5px;color:var(--ink-3);font-weight:700;text-align:left;padding:10px 12px;
  border-bottom:1px solid var(--line);letter-spacing:.4px;white-space:nowrap;}
.tbl td{padding:12px;border-bottom:1px solid #F3F3F8;font-size:13px;vertical-align:middle;}
.tbl tr:last-child td{border-bottom:0;}
.tbl tbody tr{transition:.15s;}
.tbl tbody tr:hover{background:#FAF9FE;}
.tbl .strong{font-weight:700;}
.tbl .dim{color:var(--ink-3);font-size:12px;}
.ops{display:flex;gap:6px;white-space:nowrap;flex-wrap:wrap;}
.op{font-size:12px;font-weight:700;color:var(--brand-600);background:var(--brand-50);border:0;border-radius:7px;padding:5px 11px;cursor:pointer;transition:.15s;}
.op:hover{background:var(--brand-300);color:#fff;}
.op.warn{color:#B45309;background:var(--gold-soft);} .op.warn:hover{background:var(--gold);color:#fff;}
.op.err{color:#C0392B;background:var(--danger-soft);} .op.err:hover{background:var(--danger);color:#fff;}
.ch-tag{font-size:11px;font-weight:800;border-radius:7px;padding:3px 8px;}
.ch-wx{background:#E8F8F2;color:#07A269;} .ch-ali{background:#EAF1FE;color:#2F6FE4;} .ch-yl{background:#FDF1E7;color:#D96A1E;}
.pager{display:flex;align-items:center;gap:6px;margin-top:14px;justify-content:flex-end;font-size:12.5px;color:var(--ink-2);flex-wrap:wrap;}
.pager .pg{min-width:29px;height:29px;border-radius:8px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-weight:700;transition:.15s;}
.pager .pg:hover{background:var(--brand-50);}
.pager .pg.on{background:var(--brand-500);color:#fff;}
.pager .dim{color:var(--ink-3);margin-right:auto;}

/* 筛选条 */
.filters{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:14px;}
.filters .f{display:flex;align-items:center;gap:7px;background:#fff;border:1px solid var(--line);border-radius:10px;padding:8px 12px;font-size:12.5px;color:var(--ink-2);transition:.18s;}
.filters .f:focus-within{border-color:var(--brand-300);box-shadow:0 0 0 3px rgba(139,92,246,.10);}
.filters input,.filters select{border:0;outline:0;background:transparent;font-size:12.5px;color:var(--ink);width:130px;}
.filters .f input{width:160px;}
.filters select{width:auto;cursor:pointer;appearance:none;padding-right:4px;}
.seg{display:flex;background:#fff;border:1px solid var(--line);border-radius:10px;padding:3px;gap:2px;}
.seg .s{font-size:12px;font-weight:700;color:var(--ink-2);padding:5.5px 13px;border-radius:8px;cursor:pointer;transition:.15s;}
.seg .s.on{background:linear-gradient(135deg,var(--brand-500),var(--brand));color:#fff;box-shadow:0 4px 10px rgba(124,58,237,.25);}

/* 市场/码牌 */
.mkt-grid{grid-template-columns:repeat(3,1fr);margin-bottom:16px;}
.mkt{background:#fff;border-radius:var(--radius);box-shadow:var(--shadow-sm);padding:18px;transition:.2s;position:relative;overflow:hidden;cursor:pointer;}
.mkt:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);}
.mkt .nm{font-weight:900;font-size:15px;display:flex;align-items:center;gap:8px;}
.mkt .loc{font-size:11.5px;color:var(--ink-3);margin-top:3px;}
.mkt .nums{display:flex;margin-top:14px;border-top:1px dashed var(--line);padding-top:12px;}
.mkt .nums .c{flex:1;} .mkt .nums .c+.c{border-left:1px solid var(--line);padding-left:12px;}
.mkt .nums .v{font-size:17px;font-weight:900;} .mkt .nums .k{font-size:10.5px;color:var(--ink-3);margin-top:2px;}
.occ{margin-top:12px;} .occ .lb{display:flex;justify-content:space-between;font-size:11px;color:var(--ink-2);font-weight:700;margin-bottom:5px;}
.occ .bar{height:7px;border-radius:6px;background:#F0EEF8;overflow:hidden;}
.occ .bar i{display:block;height:100%;border-radius:6px;background:linear-gradient(90deg,var(--brand-400),var(--brand));}

.code-hero{display:flex;align-items:center;gap:14px;background:linear-gradient(135deg,var(--brand-700),var(--brand) 55%,var(--brand-800));
  border-radius:var(--radius);color:#fff;padding:16px 20px;margin-bottom:16px;position:relative;overflow:hidden;}
.code-hero::after{content:"";position:absolute;inset:0;background-image:radial-gradient(rgba(255,255,255,.10) 1px,transparent 1px);background-size:16px 16px;opacity:.4;mask-image:linear-gradient(to bottom,black,transparent);}
.code-hero .ic{width:44px;height:44px;border-radius:12px;background:rgba(255,255,255,.16);display:flex;align-items:center;justify-content:center;flex:none;}
.code-hero .t{font-weight:900;font-size:15px;} .code-hero .s{font-size:12px;opacity:.8;margin-top:3px;}
.code-hero .sp{flex:1;}

/* 纳统月份 */
.nat-grid{grid-template-columns:repeat(3,1fr);margin-bottom:16px;}
.nat{background:#fff;border-radius:var(--radius);box-shadow:var(--shadow-sm);padding:18px;}
.nat .m{font-size:22px;font-weight:900;} .nat .m small{font-size:12px;color:var(--ink-3);font-weight:600;}
.nat .row{display:flex;justify-content:space-between;font-size:12px;margin-top:10px;color:var(--ink-2);}
.nat .row b{color:var(--ink);}
.nat .ops-row{margin-top:12px;display:flex;gap:8px;align-items:center;flex-wrap:wrap;}

/* 角色 */
.role-grid{grid-template-columns:repeat(4,1fr);}
.role{background:#fff;border-radius:var(--radius);box-shadow:var(--shadow-sm);padding:18px;transition:.2s;}
.role:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);}
.role .ic{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;color:#fff;margin-bottom:12px;}
.role h4{font-size:14.5px;font-weight:800;} .role .d{font-size:12px;color:var(--ink-2);margin:6px 0 12px;line-height:1.7;}
.role .n{font-size:11.5px;color:var(--ink-3);} .role .n b{color:var(--brand-700);font-size:14px;}

/* 集成配置 */
.intg{background:#fff;border-radius:var(--radius);box-shadow:var(--shadow-sm);padding:18px;margin-bottom:14px;}
.intg .hd{display:flex;align-items:center;gap:10px;margin-bottom:6px;}
.intg .hd h3{font-size:15px;font-weight:800;}
.intg .kv{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:8px 18px;margin-top:10px;}
.intg .kv .row{font-size:12.5px;display:flex;gap:8px;padding:5px 0;border-bottom:1px dashed var(--line);}
.intg .kv .row .k{color:var(--ink-3);width:140px;flex:none;}
.intg .kv .row .v{font-family:monospace;word-break:break-all;}

/* 模态 */
.overlay{position:fixed;inset:0;background:rgba(23,10,54,.45);backdrop-filter:blur(3px);z-index:100;
  display:none;align-items:center;justify-content:center;}
.overlay.show{display:flex;animation:fadein .2s;}
.modal{width:480px;max-width:92vw;max-height:88vh;overflow-y:auto;background:#fff;border-radius:18px;box-shadow:0 30px 80px rgba(23,10,54,.35);animation:pop .22s cubic-bezier(.2,.9,.3,1.3);}
@keyframes pop{from{transform:scale(.92);opacity:0}to{transform:scale(1);opacity:1}}
.modal .m-hd{display:flex;align-items:center;padding:18px 22px 0;}
.modal .m-hd h3{font-size:16.5px;font-weight:900;} .modal .m-hd .x{margin-left:auto;cursor:pointer;color:var(--ink-3);font-size:20px;line-height:1;padding:4px;}
.modal .m-bd{padding:16px 22px;}
.modal .m-ft{padding:14px 22px 20px;display:flex;gap:10px;justify-content:flex-end;}
.fm{margin-bottom:14px;} .fm label{display:block;font-size:12px;font-weight:700;color:var(--ink-2);margin-bottom:6px;}
.fm input,.fm select{width:100%;border:1px solid var(--line);border-radius:10px;padding:9.5px 13px;font-size:13px;outline:0;transition:.18s;background:#FBFAFD;}
.fm input:focus,.fm select:focus{border-color:var(--brand-300);box-shadow:0 0 0 3px rgba(139,92,246,.10);background:#fff;}
.fm .hint{font-size:11px;color:var(--ink-3);margin-top:5px;}
.fm-2{display:grid;grid-template-columns:1fr 1fr;gap:12px;}

/* Toast */
.toast{position:fixed;left:50%;bottom:34px;transform:translateX(-50%) translateY(20px);background:#241046;color:#fff;
  font-size:13px;font-weight:600;padding:11px 22px;border-radius:12px;box-shadow:0 14px 34px rgba(23,10,54,.35);
  opacity:0;pointer-events:none;transition:.25s;z-index:200;max-width:80vw;text-align:center;}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
.empty{text-align:center;color:var(--ink-3);font-size:13px;padding:40px 0;}
.loading{text-align:center;color:var(--ink-3);font-size:13px;padding:30px 0;}

@media (max-width:1100px){ .kpis,.charts,.mkt-grid,.nat-grid,.role-grid{grid-template-columns:repeat(2,1fr);} }
@media (max-width:860px){
  .login-aside{display:none;}
  .side{width:64px;}
  .logo .tt,.logo .sub,.nav .grp,.ni span.txt,.side-foot{display:none;}
  .ni{justify-content:center;}
  .content{padding:16px;}
  .topbar{padding:0 14px;gap:8px;}
  .search{display:none;}
}

/* ---- 桌面端登录页「服务器设置」（仅 Electron 环境显示） ---- */
.login-box .srv-toggle{display:inline-block;margin-top:12px;font-size:12px;color:var(--brand-700);text-decoration:none;opacity:.75;}
.login-box .srv-toggle:hover{opacity:1;text-decoration:underline;}
.login-box .srv-set{margin-top:12px;padding:14px;border:1px dashed var(--brand-300);border-radius:11px;background:var(--brand-50);}
.login-box .srv-set .fm label{font-size:12px;}
.login-box .srv-set .fm input{width:100%;margin-top:4px;}
.srv-hint{font-size:12px;margin-top:6px;min-height:16px;color:#6B7280;}
.srv-hint.ok{color:#15803D;}
.srv-hint.bad{color:#B91C1C;}
.srv-ops{display:flex;gap:8px;margin-top:10px;}
.btn2{flex:1;border:1px solid var(--brand-300);background:#fff;color:var(--brand-700);font-weight:600;font-size:12px;border-radius:9px;padding:8px 0;cursor:pointer;}
.btn2:hover{background:var(--brand-50);}

/* ---- App 布局修正：侧栏与主区横向 flex，主区独立滚动（修复主区被挤到视口下方、盖住侧栏） ---- */
body.app{display:flex;height:100vh;overflow:hidden;}
body.app .main{overflow-y:auto;}
