:root{
  --bg:#f5f6f8; --surface:#fff; --raised:#f0f2f5; --line:#e5e8ec;
  --text:#1a1d21; --muted:#6b7280; --dim:#9ca3af;
  --accent:#2563eb; --accent-bg:#eff4ff; --accent-hover:#1d4ed8;
  --ok:#16a34a; --ok-bg:#eafaf0; --warn:#eab308; --warn-bg:#fdf6e3;
  --down:#dc2626; --down-bg:#fdecec;
  --mono:'IBM Plex Mono',ui-monospace,monospace;
  --sans:'Noto Sans SC','IBM Plex Sans',system-ui,sans-serif;
  --radius:12px; --shadow:0 1px 3px rgba(0,0,0,.06),0 1px 2px rgba(0,0,0,.04);
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:var(--sans);background:var(--bg);color:var(--text);font-size:14px;line-height:1.5}
a{color:var(--accent);text-decoration:none}
button{font-family:inherit;cursor:pointer}
input,select,textarea{font-family:inherit;font-size:14px}

/* 布局 */
.layout{display:flex;min-height:100vh}
.side{width:210px;background:var(--surface);border-right:1px solid var(--line);display:flex;flex-direction:column;position:fixed;height:100vh}
.side-logo{padding:22px 20px;font-family:var(--mono);font-weight:700;font-size:17px;letter-spacing:-.5px}
.side-logo b{color:var(--accent)}
.side-tag{font-size:11px;color:var(--dim);font-weight:400;margin-top:2px;letter-spacing:0}
.side-nav{flex:1;padding:8px}
.side-nav button{display:block;width:100%;text-align:left;padding:11px 14px;border:none;background:none;color:var(--muted);border-radius:9px;font-size:14px;margin-bottom:2px;transition:.12s}
.side-nav button:hover{background:var(--raised);color:var(--text)}
.side-nav button.active{background:var(--accent-bg);color:var(--accent);font-weight:500}
.side-foot{padding:14px 20px;border-top:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;font-size:12px;color:var(--muted)}
.main{flex:1;margin-left:210px;padding:28px 32px;max-width:1200px}
.page-head{margin-bottom:22px}
.page-head h1{font-size:22px;font-weight:600}
.page-head .sub{color:var(--muted);font-size:13px;margin-top:4px}

/* 卡片 */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:20px;box-shadow:var(--shadow);margin-bottom:16px}
.grid{display:grid;gap:16px}
.grid.c4{grid-template-columns:repeat(4,1fr)}
.grid.c3{grid-template-columns:repeat(3,1fr)}
.grid.c2{grid-template-columns:repeat(2,1fr)}
@media(max-width:900px){.grid.c4,.grid.c3,.grid.c2{grid-template-columns:1fr 1fr}}

/* 统计块 */
.stat{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:18px 20px}
.stat .n{font-size:28px;font-weight:700;font-family:var(--mono)}
.stat .l{font-size:12px;color:var(--muted);margin-top:2px}
.stat .n.ok{color:var(--ok)} .stat .n.down{color:var(--down)} .stat .n.accent{color:var(--accent)}

/* 表格 */
table{width:100%;border-collapse:collapse}
th{text-align:left;font-size:12px;color:var(--muted);font-weight:500;padding:10px 12px;border-bottom:1px solid var(--line)}
td{padding:12px;border-bottom:1px solid var(--line);font-size:13px}
tr:last-child td{border-bottom:none}
tr:hover td{background:var(--raised)}
.mono{font-family:var(--mono)}

/* 徽章 */
.badge{display:inline-block;padding:3px 9px;border-radius:20px;font-size:11px;font-weight:600}
.badge.ok{background:var(--ok-bg);color:var(--ok)}
.badge.warn{background:var(--warn-bg);color:#96610C}
.badge.down{background:var(--down-bg);color:var(--down)}
.badge.gray{background:var(--raised);color:var(--muted)}
.badge.accent{background:var(--accent-bg);color:var(--accent)}

/* 按钮 */
.btn{padding:8px 15px;border:1px solid var(--line);background:var(--surface);border-radius:8px;font-size:13px;color:var(--text);transition:.12s}
.btn:hover{border-color:var(--dim)}
.btn.primary{background:var(--accent);color:#fff;border-color:var(--accent)}
.btn.primary:hover{background:var(--accent-hover)}
.btn.danger{color:var(--down);border-color:transparent}
.btn.danger:hover{background:var(--down-bg)}
.btn.sm{padding:5px 10px;font-size:12px}

/* 表单 */
.f{margin-bottom:14px}
.f label{display:block;font-size:13px;color:var(--muted);margin-bottom:6px}
.f input,.f select,.f textarea{width:100%;padding:9px 12px;border:1px solid var(--line);border-radius:8px;background:var(--surface);outline:none;transition:.12s}
.f input:focus,.f select:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-bg)}
.fgrid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.hint{font-size:12px;color:var(--dim);margin-top:4px;display:block}

/* 弹窗 */
.mask{position:fixed;inset:0;background:rgba(15,20,30,.4);display:flex;align-items:center;justify-content:center;z-index:50;padding:20px}
.modal{background:var(--surface);border-radius:16px;padding:26px;max-width:560px;width:100%;max-height:88vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}
.modal h2{font-size:18px;margin-bottom:4px}
.modal .sub{color:var(--muted);font-size:13px;margin-bottom:18px}
.modal-foot{display:flex;justify-content:flex-end;gap:10px;margin-top:20px}

/* 登录 */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#eef2f8,#f5f6f8)}
.login-box{background:var(--surface);border-radius:18px;padding:38px;width:100%;max-width:400px;box-shadow:0 12px 40px rgba(0,0,0,.1)}
.login-box .logo{font-family:var(--mono);font-weight:700;font-size:22px;text-align:center;margin-bottom:6px}
.login-box .logo b{color:var(--accent)}
.login-box .tip{text-align:center;color:var(--muted);font-size:13px;margin-bottom:26px}

/* toast */
.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:#1a1d21;color:#fff;padding:11px 20px;border-radius:9px;font-size:13px;z-index:100;box-shadow:0 6px 20px rgba(0,0,0,.25)}
.toast.err{background:var(--down)}

.row-actions{display:flex;gap:6px;justify-content:flex-end}
.empty{text-align:center;color:var(--dim);padding:40px;font-size:13px}
.flex{display:flex;align-items:center;gap:10px}
.flex-between{display:flex;align-items:center;justify-content:space-between}

/* 公告轮播条 */
.announce-bar{display:flex;align-items:center;gap:12px;background:linear-gradient(90deg,var(--accent-bg),#fff);border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:10px;padding:10px 16px;margin-bottom:18px}
.announce-ico{font-size:16px;flex-shrink:0}
.announce-text{flex:1;min-width:0;cursor:pointer;display:flex;align-items:center;gap:10px;overflow:hidden}
.announce-text b{font-size:13px;color:var(--text);flex-shrink:0}
.announce-body{font-size:13px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.announce-nav{display:flex;align-items:center;gap:8px;flex-shrink:0}
.announce-dots{display:flex;gap:5px}
.announce-dots i{width:6px;height:6px;border-radius:50%;background:var(--line);cursor:pointer;transition:.2s;display:block}
.announce-dots i.on{background:var(--accent);width:16px;border-radius:3px}
