/* ============================================================================
   仪表台账与校验管理系统 · 全站样式
   ----------------------------------------------------------------------------
   设计约定（改动前先读）：
   1. 本文件是唯一视觉来源，页面里只写结构，不写配色；页面内的内联 style 仅用于
      「按数据状态切换颜色」这一种场景（如 vl 在逾期时用 var(--danger)）。
   2. 变量名是全站契约：--bg --panel --ink --ink2 --ink3 --line --line2
      --accent --accent-soft --ok --warn --danger --purple --radius --radius-s
      视图里有内联 var(...) 引用（如逾期数值用 var(--danger) 上色），改名会断链。
   3. 沿用一套固定的类名（scan 过全部视图）：骨架 app/side/brand/navgroup/navitem/main
      topbar/view；卡片 card/grid/g4/g3/g2/g21/kpi；按钮 btn(.pri/.dgr/.sm/.lnk)/bar/ib；
      表格 tw/tag/pager；表单 filters/frm/fld/sec/cks；折叠 fold；提示 alert；
      弹窗 modal/modal-bg/modal-box/modal-hd/modal-bd/modal-ft/modal-x（开合脚本在 layout，
      用法见「弹窗」分节注释）；导出勾选 exp-grid；图表 bars；键值 kv/list；登录 login-*。
      新增样式请追加到对应分节末尾，不要另起一套。
   ============================================================================ */

:root{
  /* 中性 */
  --bg:#f5f7fb;
  --panel:#ffffff;
  --ink:#0f172a;
  --ink2:#475569;
  --ink3:#8a94a6;
  --line:#e6ebf3;
  --line2:#eff3f9;

  /* 主色 */
  --accent:#2563eb;
  --accent-2:#3b82f6;
  --accent-ink:#1d4ed8;
  --accent-soft:#eaf1fe;
  --accent-line:#cddffb;

  /* 语义色 */
  --ok:#0e9f6e;     --ok-soft:#e8f8f1;     --ok-line:#bfe9d7;
  --warn:#c2750c;   --warn-soft:#fdf5e7;   --warn-line:#f2ddb3;
  --danger:#dc2626; --danger-soft:#fdecec; --danger-line:#f6c9c9;
  --purple:#7c3aed; --purple-soft:#f3eefe; --purple-line:#ded0fb;

  /* 侧栏（深色，与浅色内容区形成层次） */
  --side-bg:#0f1a2e;
  --side-bg2:#16233c;
  --side-ink:#c3cddf;
  --side-dim:#7f8da6;

  /* 尺寸与投影 */
  --radius:14px;
  --radius-s:9px;
  --radius-xs:7px;
  --sh-1:0 1px 2px rgba(16,24,40,.05), 0 1px 3px rgba(16,24,40,.06);
  --sh-2:0 4px 14px rgba(16,24,40,.08), 0 1px 3px rgba(16,24,40,.05);
  --sh-3:0 14px 36px rgba(15,23,42,.12);
  --ring:0 0 0 3px rgba(37,99,235,.16);
  --t:.16s cubic-bezier(.4,0,.2,1);
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei","Hiragino Sans GB",sans-serif;
  font-size:13.5px; line-height:1.6; -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
button,input,select,textarea{font-family:inherit;font-size:13px;color:inherit}
a{color:var(--accent);text-decoration:none;transition:color var(--t)}
a:hover{color:var(--accent-ink)}
.ico{vertical-align:-2px;flex:0 0 auto}
.mono{font-family:ui-monospace,SFMono-Regular,Consolas,"Courier New",monospace;font-size:12px;letter-spacing:-.01em}
.muted{color:var(--ink3)}
.nowrap{white-space:nowrap}
.ib{display:inline}
.sp{flex:1}

/* 滚动条 */
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:#cbd5e5;border-radius:20px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:#aab8cf;background-clip:content-box}

/* ---------- 骨架 ---------- */
.app{display:grid;grid-template-columns:232px 1fr;min-height:100vh}

.side{
  position:sticky; top:0; height:100vh; overflow:auto;
  background:linear-gradient(180deg,var(--side-bg) 0%,var(--side-bg2) 100%);
  color:var(--side-ink);
  padding:18px 12px 14px;
  display:flex; flex-direction:column;
  border-right:1px solid rgba(255,255,255,.05);
}
.side::before{
  content:''; position:absolute; left:0; right:0; top:0; height:240px; pointer-events:none;
  background:radial-gradient(420px 200px at 18% 0%, rgba(59,130,246,.22), transparent 70%);
}
.side::-webkit-scrollbar-thumb{background:#2c3c58;background-clip:content-box}

.brand{
  position:relative; display:flex; align-items:center; gap:11px;
  padding:2px 8px 16px; margin-bottom:10px; border-bottom:1px solid rgba(255,255,255,.08);
}
.brand .logo{
  width:34px; height:34px; border-radius:10px; flex:0 0 auto;
  background:linear-gradient(135deg,#3b82f6,#6366f1); color:#fff;
  display:grid; place-items:center; font-size:15px; font-weight:600;
  box-shadow:0 4px 14px rgba(59,130,246,.42);
}
.brand b{font-size:13.5px; font-weight:600; display:block; line-height:1.35; color:#fff}
.brand span{font-size:11px; color:var(--side-dim)}

nav{position:relative; flex:1; overflow:auto; margin:0 -4px; padding:0 4px}
.navgroup{margin-bottom:14px}
.navgt{
  font-size:10.5px; color:var(--side-dim); font-weight:600; letter-spacing:.09em;
  padding:8px 10px 6px;
}
.navitem{
  display:flex; align-items:center; gap:10px;
  padding:8px 10px; border-radius:var(--radius-xs);
  color:var(--side-ink); margin-bottom:2px; position:relative;
  transition:background var(--t), color var(--t);
}
.navitem:hover{background:rgba(255,255,255,.07); color:#fff}
.navitem.on{
  background:linear-gradient(90deg,rgba(59,130,246,.26),rgba(59,130,246,.06));
  color:#fff; font-weight:500;
}
.navitem.on::before{
  content:''; position:absolute; left:-12px; top:50%; transform:translateY(-50%);
  width:3px; height:18px; border-radius:0 3px 3px 0; background:#60a5fa;
}
.side .foot{
  margin-top:auto; padding:12px 10px 2px; border-top:1px solid rgba(255,255,255,.08);
  font-size:11px; color:var(--side-dim); line-height:1.7;
}

.main{
  min-width:0; display:flex; flex-direction:column;
  background:var(--bg);
  background-image:
    radial-gradient(1100px 520px at 100% -8%, #e9f1ff 0%, rgba(233,241,255,0) 62%),
    radial-gradient(820px 460px at -8% 108%, #eef2ff 0%, rgba(238,242,255,0) 58%);
  background-attachment:fixed;
}
.topbar{
  position:sticky; top:0; z-index:20;
  background:rgba(255,255,255,.88);
  backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  border-bottom:1px solid var(--line);
  padding:13px 26px; display:flex; align-items:center; gap:12px; flex-wrap:wrap;
}
.topbar h1{margin:0; font-size:16px; font-weight:600; letter-spacing:-.01em}
.topbar .sub{
  font-size:11.5px; color:var(--ink3); background:#f1f5fb;
  border:1px solid var(--line); border-radius:20px; padding:2px 10px;
}
.topbar .who{
  display:flex; align-items:center; gap:9px; font-size:12.5px; color:var(--ink2);
  background:#fff; border:1px solid var(--line); border-radius:30px; padding:4px 12px 4px 5px;
  transition:border-color var(--t), box-shadow var(--t);
}
.topbar .who:hover{border-color:var(--accent-line); box-shadow:var(--sh-1)}
.topbar .who b{font-weight:600; color:var(--ink)}
.topbar form{display:inline}
.view{padding:22px 26px 56px; min-width:0; flex:1}

/* ---------- 卡片 / 网格 / KPI ---------- */
.card{
  background:var(--panel); border:1px solid var(--line); border-radius:var(--radius);
  padding:18px; box-shadow:var(--sh-1);
}
.card+.card{margin-top:16px}
.card h2{
  margin:0 0 14px; font-size:13.5px; font-weight:600; color:var(--ink);
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
}
.card h2::before{
  content:''; width:3px; height:14px; border-radius:3px; flex:0 0 auto;
  background:linear-gradient(180deg,#60a5fa,#2563eb);
}
.card h2 .sp{flex:1}
.grid{display:grid; gap:16px}
.g4{grid-template-columns:repeat(4,minmax(0,1fr))}
.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.g21{grid-template-columns:340px minmax(0,1fr)}
@media(max-width:1200px){.g4{grid-template-columns:repeat(2,minmax(0,1fr))}.g21{grid-template-columns:1fr}.g2{grid-template-columns:1fr}}

.kpi{
  position:relative; background:#fff; border:1px solid var(--line);
  border-radius:var(--radius); padding:16px 18px 15px; overflow:hidden;
  box-shadow:var(--sh-1); transition:box-shadow var(--t), transform var(--t);
}
.kpi::before{
  content:''; position:absolute; left:0; right:0; top:0; height:3px;
  background:linear-gradient(90deg,#7cb0fb,#2563eb); opacity:.9;
}
.kpi:hover{box-shadow:var(--sh-2); transform:translateY(-1px)}
.kpi .lb{font-size:12px; color:var(--ink3); font-weight:500}
.kpi .vl{
  font-size:28px; font-weight:600; letter-spacing:-.02em; line-height:1.15;
  margin-top:6px; font-variant-numeric:tabular-nums;
}
.kpi .vl small{font-size:12px; font-weight:500; color:var(--ink3); margin-left:4px}
.kpi .ex{font-size:11.5px; color:var(--ink3); margin-top:6px}
.kpi a{color:inherit; font-weight:500}
.kpi a:hover{color:var(--accent)}
.kpi.warn{border-color:var(--warn-line); background:linear-gradient(180deg,#fffdf7,#fff)}
.kpi.warn::before{background:linear-gradient(90deg,#fbbf24,#d97706)}
.kpi.danger{border-color:var(--danger-line); background:linear-gradient(180deg,#fff8f8,#fff)}
.kpi.danger::before{background:linear-gradient(90deg,#f87171,#dc2626)}
.kpi.ok{border-color:var(--ok-line); background:linear-gradient(180deg,#f8fdfb,#fff)}
.kpi.ok::before{background:linear-gradient(90deg,#34d399,#0e9f6e)}

/* ---------- 按钮 ---------- */
.btn{
  display:inline-flex; align-items:center; gap:6px; white-space:nowrap;
  border:1px solid var(--line); background:#fff; border-radius:var(--radius-xs);
  padding:6px 12px; cursor:pointer; color:var(--ink2); font-weight:500; line-height:1.45;
  transition:background var(--t), border-color var(--t), color var(--t), box-shadow var(--t), transform var(--t);
}
.btn:hover{border-color:#cbd5e6; color:var(--ink); background:#f8fafc; box-shadow:var(--sh-1)}
.btn:active{transform:translateY(1px)}
.btn.pri{
  background:linear-gradient(180deg,#3b82f6,#2563eb); border-color:#2563eb; color:#fff;
  box-shadow:0 1px 2px rgba(37,99,235,.3);
}
.btn.pri:hover{
  background:linear-gradient(180deg,#4a8cf8,#2b6ce6); border-color:#2b6ce6; color:#fff;
  box-shadow:0 3px 12px rgba(37,99,235,.34);
}
.btn.dgr:hover{border-color:var(--danger-line); color:var(--danger); background:var(--danger-soft)}
.btn.sm{padding:4px 9px; font-size:12px}
.btn.lnk{border:0; background:transparent; color:var(--accent); padding:3px 6px; box-shadow:none}
.btn.lnk:hover{background:var(--accent-soft); color:var(--accent-ink); box-shadow:none}
.btn.lnk.dgr{color:var(--danger)}
.btn.lnk.dgr:hover{background:var(--danger-soft)}
.btn[disabled]{opacity:.5; cursor:not-allowed}
.bar{display:flex; gap:8px; align-items:center; flex-wrap:wrap}

/* ---------- 表格 ---------- */
table{width:100%; border-collapse:separate; border-spacing:0; font-size:12.5px}
th,td{text-align:left; padding:10px 12px; border-bottom:1px solid var(--line2); vertical-align:middle}
thead th{
  font-size:11.5px; font-weight:600; color:var(--ink3); background:#f8fafc;
  white-space:nowrap; letter-spacing:.02em;
}
tbody tr{transition:background var(--t)}
tbody tr:hover{background:#f7faff}
tbody tr:last-child td{border-bottom:0}
td.num,th.num{text-align:right; font-variant-numeric:tabular-nums}
/* 表头点击排序 */
th a.th-sort{color:inherit; text-decoration:none; display:inline-flex; align-items:center; gap:4px}
th a.th-sort:hover{color:var(--accent)}
th a.th-sort .sort-arr{font-size:10px; line-height:1; opacity:.4}
th a.th-sort.on{color:var(--accent)}
th a.th-sort.on .sort-arr{opacity:1}
.tw{overflow:auto; border:1px solid var(--line); border-radius:var(--radius-s); background:#fff}
.tw.sh{max-height:none}
.hint{font-size:11.5px; color:var(--ink3); line-height:1.65}

/* ---------- 分页 ---------- */
.pager{display:flex; gap:5px; align-items:center; flex-wrap:wrap; padding:14px 2px 0; font-size:12.5px}
.pager .pg-info{color:var(--ink3); margin-right:8px}
.pager .pg{
  border:1px solid var(--line); border-radius:var(--radius-xs); padding:4px 11px;
  color:var(--ink2); background:#fff; transition:all var(--t);
}
.pager .pg:hover{border-color:var(--accent-line); color:var(--accent); box-shadow:var(--sh-1)}
.pager .pg.on{
  background:linear-gradient(180deg,#3b82f6,#2563eb); border-color:#2563eb; color:#fff;
  box-shadow:0 1px 2px rgba(37,99,235,.3);
}
.pager .pg.dis{opacity:.45; padding:4px 11px; border:1px solid var(--line2); border-radius:var(--radius-xs)}

/* ---------- 标签 ---------- */
.tag{
  display:inline-flex; align-items:center; padding:2px 9px; border-radius:20px;
  font-size:11px; font-weight:500; line-height:1.65; border:1px solid transparent; white-space:nowrap;
}
.t-ok{background:var(--ok-soft); color:var(--ok); border-color:var(--ok-line)}
.t-warn{background:var(--warn-soft); color:var(--warn); border-color:var(--warn-line)}
.t-dgr{background:var(--danger-soft); color:var(--danger); border-color:var(--danger-line)}
.t-gray{background:#f4f6fa; color:var(--ink2); border-color:#e5eaf2}
.t-blue{background:var(--accent-soft); color:var(--accent-ink); border-color:var(--accent-line)}
.t-purple{background:var(--purple-soft); color:var(--purple); border-color:var(--purple-line)}
/* 一台仪表可能同时按多个类别管理，多枚徽标要留出间距 */
.tagset{display:inline-flex; gap:4px; align-items:center; flex-wrap:wrap}

/* ---------- 表单 ---------- */
.filters{
  display:flex; gap:8px; flex-wrap:wrap; align-items:center;
  margin-bottom:14px; padding:14px; border:1px solid var(--line);
  border-radius:var(--radius-s); background:#fafbfe;
}
input[type=text],input[type=number],input[type=date],input[type=month],input[type=password],input[type=file],select,textarea{
  border:1px solid var(--line); border-radius:var(--radius-xs); padding:6px 10px;
  background:#fff; min-width:0; width:100%; transition:border-color var(--t), box-shadow var(--t);
}
input[type=file]{padding:5px}
input:hover,select:hover,textarea:hover{border-color:#d3dbe8}
input:focus,select:focus,textarea:focus{outline:none; border-color:var(--accent-2); box-shadow:var(--ring)}
select{cursor:pointer; appearance:none; background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.6L6 7.6l3-3' fill='none' stroke='%238a94a6' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 9px center; padding-right:26px}
.filters input[type=text]{width:230px}
.filters select{width:auto; min-width:124px}
.frm{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:13px 16px}
.frm-1{grid-template-columns:1fr}
.frm-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.frm-3{grid-template-columns:repeat(3,minmax(0,1fr))}
@media(max-width:900px){.frm,.frm-2,.frm-3{grid-template-columns:1fr}}
.fld{display:flex; flex-direction:column; gap:5px}
.fld>span{font-size:11.5px; color:var(--ink2); font-weight:500}
.fld>span b{color:var(--danger); font-weight:400}
.fld.span2{grid-column:1/-1}
.sec{
  grid-column:1/-1; font-size:12px; font-weight:600; color:var(--ink2);
  border-bottom:1px solid var(--line2); padding-bottom:6px; margin-top:6px;
  display:flex; align-items:center; gap:8px;
}
.sec::before{content:''; width:3px; height:12px; border-radius:3px; background:var(--accent-line)}
.frm-actions{
  grid-column:1/-1; display:flex; gap:8px; padding-top:10px;
  border-top:1px solid var(--line2); margin-top:8px;
}
.static-val{padding:6px 0; font-size:13px}
.cks{display:flex; flex-wrap:wrap; gap:6px 16px; padding:4px 0}
.cks label{display:flex; align-items:center; gap:6px; font-size:12.5px; cursor:pointer}
.cks input[type=checkbox],.cks input[type=radio]{width:auto; margin:0}
label.inline{display:inline-flex; align-items:center; gap:6px; font-size:12.5px}
label.inline input[type=checkbox]{width:auto}
input[type=checkbox],input[type=radio]{accent-color:var(--accent); width:14px; height:14px; cursor:pointer}

/* ---------- 折叠面板 ---------- */
details.fold{
  border:1px solid var(--line); border-radius:var(--radius); background:#fff;
  margin-bottom:16px; box-shadow:var(--sh-1); overflow:hidden;
}
details.fold>summary{
  cursor:pointer; padding:13px 18px; font-size:13.5px; font-weight:600;
  list-style:none; display:flex; align-items:center; gap:9px;
  transition:background var(--t), color var(--t);
}
details.fold>summary::-webkit-details-marker{display:none}
details.fold>summary:before{
  content:""; width:6px; height:6px; flex:0 0 auto;
  border-right:1.7px solid var(--ink3); border-bottom:1.7px solid var(--ink3);
  transform:rotate(-45deg); margin-left:2px; transition:transform .18s;
}
details.fold[open]>summary:before{transform:rotate(45deg)}
details.fold>summary:hover{color:var(--accent); background:#fafbfe}
details.fold .fold-body{padding:2px 18px 18px}
details.fold.sm>summary{padding:10px 14px; font-size:12.5px}
details.fold.sm .fold-body{padding:0 14px 14px}

/* ---------- 提示 ---------- */
.alert{
  border-radius:var(--radius-s); border:1px solid; padding:11px 14px;
  margin-bottom:14px; font-size:12.5px; line-height:1.7;
  display:flex; align-items:flex-start; gap:8px;
}
.alert b{font-weight:600}
.alert.info{background:var(--accent-soft); border-color:var(--accent-line); color:#1c4d92}
.alert.warn{background:var(--warn-soft); border-color:var(--warn-line); color:#7d4e06}
.alert.success{background:var(--ok-soft); border-color:var(--ok-line); color:#0b5f49}
.alert.danger{background:var(--danger-soft); border-color:var(--danger-line); color:#95271c}

/* ---------- 弹窗 ----------
   通用模态框：结构固定为
     .modal > .modal-bg + .modal-box( > .modal-hd + [form.]modal-form( > .modal-bd + .modal-ft ) )
   开合只由 .modal 上的 .open 类控制（布局脚本 AppModal 负责），不依赖 [hidden]。
   触发：任意元素带 data-modal="弹窗id"；关闭：任意元素带 data-modal-close（含遮罩与 Esc）。 */
.modal{position:fixed; inset:0; z-index:80; display:none}
.modal.open{display:block}
.modal-bg{position:absolute; inset:0; background:rgba(15,23,42,.44); animation:modalFade .16s ease-out}
.modal-box{
  position:relative; margin:5.5vh auto 0; width:min(780px, calc(100vw - 28px));
  max-height:88vh; display:flex; flex-direction:column;
  background:var(--panel); border-radius:var(--radius); box-shadow:var(--sh-3);
  animation:modalPop .18s cubic-bezier(.4,0,.2,1);
}
@keyframes modalFade{from{opacity:0} to{opacity:1}}
@keyframes modalPop{from{opacity:0; transform:translateY(-10px) scale(.985)} to{opacity:1; transform:none}}
.modal-hd{
  display:flex; align-items:center; gap:9px; padding:14px 18px;
  border-bottom:1px solid var(--line); flex:0 0 auto;
}
.modal-hd h3{margin:0; font-size:14px; font-weight:600}
.modal-hd .sub{font-size:12px; color:var(--ink3)}
.modal-x{
  display:grid; place-items:center; width:28px; height:28px; padding:0; flex:0 0 auto;
  border:1px solid transparent; border-radius:var(--radius-xs);
  background:transparent; color:var(--ink3); cursor:pointer;
  transition:background var(--t), color var(--t);
}
.modal-x:hover{background:var(--line2); color:var(--ink)}
.modal-form{display:flex; flex-direction:column; min-height:0}
.modal-bd{padding:16px 18px; overflow:auto; flex:1 1 auto}
.modal-ft{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap; flex:0 0 auto;
  padding:12px 18px; border-top:1px solid var(--line); background:#fafbfe;
  border-radius:0 0 var(--radius) var(--radius);
}

/* 导出字段勾选网格（弹窗内） */
.exp-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(126px,1fr)); gap:2px 10px}
.exp-grid label{
  display:flex; align-items:center; gap:7px; font-size:12.5px; white-space:nowrap;
  padding:5px 8px; border-radius:var(--radius-xs); cursor:pointer;
  transition:background var(--t);
}
.exp-grid label:hover{background:#f2f6fd}

/* ---------- 条形图 ---------- */
.bars{display:flex; flex-direction:column; gap:10px}
.bars .row{display:grid; grid-template-columns:100px 1fr 78px; gap:10px; align-items:center; font-size:12px}
.bars .tr{height:10px; border-radius:20px; background:#eef2f8; overflow:hidden}
.bars .fl{display:block; height:100%; border-radius:20px; transition:width .4s cubic-bezier(.4,0,.2,1)}
.bars .num{color:var(--ink2); font-variant-numeric:tabular-nums; text-align:right}

/* ---------- 键值 / 列表 ---------- */
.kv{display:grid; grid-template-columns:104px 1fr; gap:7px 14px; font-size:12.5px}
.kv .k{color:var(--ink3)}
.list{display:flex; flex-direction:column}
.list .li{display:flex; align-items:center; gap:10px; padding:9px 0; border-bottom:1px solid var(--line2); font-size:12.5px}
.list .li:last-child{border-bottom:0}
.list .li .sp{flex:1; min-width:0}

/* ---------- 登录页 ---------- */
.login-wrap{
  min-height:100vh; display:grid; place-items:center; padding:24px;
  position:relative; overflow:hidden;
  background:linear-gradient(135deg,#0d1728 0%,#14223a 48%,#1b2c4a 100%);
}
.login-wrap::before{
  content:''; position:absolute; width:640px; height:640px; border-radius:50%;
  top:-240px; right:-160px; pointer-events:none;
  background:radial-gradient(circle, rgba(59,130,246,.34), transparent 66%);
}
.login-wrap::after{
  content:''; position:absolute; width:540px; height:540px; border-radius:50%;
  bottom:-210px; left:-140px; pointer-events:none;
  background:radial-gradient(circle, rgba(124,58,237,.26), transparent 66%);
}
.login-box{
  position:relative; z-index:1; width:min(412px,100%);
  background:#fff; border-radius:20px; padding:32px 30px 28px;
  box-shadow:0 26px 64px rgba(2,8,23,.45), 0 2px 8px rgba(2,8,23,.2);
  animation:loginIn .34s cubic-bezier(.2,.8,.3,1) both;
}
@keyframes loginIn{from{opacity:0; transform:translateY(14px) scale(.99)}to{opacity:1; transform:none}}
.login-box .lg{
  width:46px; height:46px; border-radius:13px; margin-bottom:16px;
  background:linear-gradient(135deg,#3b82f6,#6366f1); color:#fff;
  display:grid; place-items:center; font-size:18px; font-weight:600;
  box-shadow:0 8px 22px rgba(59,130,246,.42);
}
.login-box h1{font-size:19px; font-weight:600; margin:0 0 6px; letter-spacing:-.01em}
.login-box .sub{font-size:12.5px; color:var(--ink3); margin-bottom:22px}
.login-box .fld{margin-bottom:14px}
.login-box .btn{width:100%; justify-content:center; padding:9px; font-size:13.5px}
.login-box .other{margin-top:18px; padding-top:16px; border-top:1px solid var(--line2); text-align:center}
.login-box .foot{margin-top:18px; font-size:11.5px; color:var(--ink3); text-align:center; line-height:1.8}
.login-box .demo{
  margin-top:16px; padding:11px 13px; border-radius:var(--radius-s);
  border:1px dashed var(--accent-line); background:var(--accent-soft);
  font-size:11.5px; color:var(--ink2); line-height:1.9;
}
.login-box .demo b{color:var(--accent-ink); font-weight:600}
.login-box .demo code{
  font-family:ui-monospace,SFMono-Regular,Consolas,monospace; font-size:11px;
  background:#fff; border:1px solid var(--accent-line); border-radius:5px;
  padding:1px 6px; color:var(--accent-ink);
}
.login-box .demo .dtitle{
  display:flex; align-items:center; gap:6px; font-weight:600; color:var(--accent-ink);
  margin-bottom:5px; font-size:11.5px;
}

/* ---------- 打印 ---------- */
@media print{
  .side,.topbar,.no-print,.pager,details.fold{display:none!important}
  .app{display:block}
  .view{padding:0}
  .card{border:0; padding:0; margin:0 0 10px; box-shadow:none}
  .tw{border:0; overflow:visible}
  th{position:static; background:#fff}
  tbody tr:hover{background:transparent}
  body{background:#fff; font-size:11.5px; background-image:none}
  .main{background:#fff; background-image:none}
}
.print-title{display:none; font-size:15px; font-weight:600; margin-bottom:10px}

/* ---------- 小屏 ---------- */
@media(max-width:860px){
  .app{grid-template-columns:1fr}
  .side{position:relative; height:auto; padding:12px}
  .side::before{height:160px}
  nav{display:flex; flex-wrap:wrap; gap:4px}
  .navgroup{margin-bottom:6px; flex:1 1 100%}
  .navitem{display:inline-flex; margin-right:4px}
  .navitem.on::before{display:none}
  .side .foot{display:none}
  .topbar{padding:12px 16px}
  .view{padding:16px 16px 44px}
  .kpi .vl{font-size:24px}
  .modal-box{margin:14px auto 0; max-height:calc(100vh - 28px)}
  .exp-grid{grid-template-columns:repeat(auto-fill,minmax(110px,1fr))}
}
