:root{--brand: #3b5bdb;--brand-soft: #eef1fd;--ink: #1b2431;--ink-2: #4a5568;--ink-3: #8a94a6;--line: #e6e9f0;--line-2: #f0f2f7;--bg: #f6f7f9;--panel: #ffffff;--ok: #12805c;--ok-soft: #e6f6ef;--warn: #b45309;--warn-soft: #fef3e2;--danger: #c0392b;--danger-soft: #fdeceb;--info-soft: #eaf1fe;--radius: 10px;--shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 4px 16px rgba(16, 24, 40, .04)}*{box-sizing:border-box}html,body,#app{height:100%}body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.55 -apple-system,BlinkMacSystemFont,PingFang SC,Microsoft YaHei,Segoe UI,sans-serif;-webkit-font-smoothing:antialiased}a{color:var(--brand);text-decoration:none}h1,h2,h3,h4{margin:0;font-weight:600;letter-spacing:-.01em}input,select,textarea,button{font:inherit;color:inherit}.layout{display:flex;height:100%}.side{width:218px;flex:0 0 218px;background:var(--panel);border-right:1px solid var(--line);display:flex;flex-direction:column}.side-brand{height:56px;display:flex;align-items:center;gap:9px;padding:0 16px;border-bottom:1px solid var(--line-2)}.side-brand .logo{width:26px;height:26px;border-radius:7px;background:var(--brand);color:#fff;display:grid;place-items:center;font-size:13px;font-weight:700}.side-brand .name{font-weight:600;font-size:14px}.side-brand .sub{font-size:11px;color:var(--ink-3)}.side-nav{flex:1;overflow-y:auto;padding:10px 8px 20px}.nav-group-title{font-size:11px;color:var(--ink-3);padding:12px 10px 6px;letter-spacing:.06em}.nav-item{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:8px;color:var(--ink-2);cursor:pointer;position:relative;margin-bottom:1px}.nav-item:hover{background:var(--line-2)}.nav-item.active{background:var(--brand-soft);color:var(--brand);font-weight:500}.nav-item .ico{width:16px;height:16px;flex:0 0 16px;opacity:.85}.nav-badge{margin-left:auto;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:#fde8e6;color:var(--danger);font-size:11px;line-height:18px;text-align:center}.main{flex:1;min-width:0;display:flex;flex-direction:column}.topbar{height:56px;background:var(--panel);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:14px;padding:0 20px}.topbar .crumb{font-size:13px;color:var(--ink-3)}.topbar .crumb b{color:var(--ink);font-weight:500}.topbar .spacer{flex:1}.content{flex:1;overflow-y:auto;padding:20px}.p-head{display:flex;align-items:flex-end;gap:12px;margin-bottom:16px}.p-head h2{font-size:19px}.p-head .desc{color:var(--ink-3);font-size:12px;padding-bottom:2px}.p-head .actions{margin-left:auto;display:flex;gap:8px}.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);margin-bottom:16px;overflow:hidden}.card-hd{display:flex;align-items:center;gap:10px;padding:13px 16px;border-bottom:1px solid var(--line-2)}.card-hd h3{font-size:14px}.card-hd .actions{margin-left:auto;display:flex;gap:8px;align-items:center}.card-bd{padding:16px}.card-bd.flush{padding:0}.banner{display:flex;gap:10px;align-items:flex-start;padding:10px 14px;border-radius:9px;font-size:13px;margin-bottom:14px;border:1px solid transparent}.banner.warn{background:var(--warn-soft);color:#8a4b06;border-color:#f5deb8}.banner.danger{background:var(--danger-soft);color:#8f2b1f;border-color:#f6cdc8}.banner.info{background:var(--info-soft);color:#24417e;border-color:#d3e0fb}.banner b{font-weight:600}.t-wrap{overflow-x:auto}table.t{width:100%;border-collapse:collapse;font-size:13px}.t th{text-align:left;font-weight:500;color:var(--ink-3);font-size:12px;padding:10px 14px;background:#fbfcfd;border-bottom:1px solid var(--line);white-space:nowrap}.t td{padding:11px 14px;border-bottom:1px solid var(--line-2);vertical-align:middle}.t tbody tr:hover td{background:#fcfdff}.t tbody tr:last-child td{border-bottom:none}.t .num{font-variant-numeric:tabular-nums}.t .mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:var(--ink-2)}.t .muted{color:var(--ink-3)}.t .strong{font-weight:500}.t-empty{padding:40px 0;text-align:center;color:var(--ink-3);font-size:13px}.tag{display:inline-flex;align-items:center;height:21px;padding:0 8px;border-radius:5px;font-size:12px;white-space:nowrap;background:var(--line-2);color:var(--ink-2)}.tag.ok{background:var(--ok-soft);color:var(--ok)}.tag.warn{background:var(--warn-soft);color:var(--warn)}.tag.danger{background:var(--danger-soft);color:var(--danger)}.tag.info{background:var(--info-soft);color:#24417e}.tag.brand{background:var(--brand-soft);color:var(--brand)}.b{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 12px;border-radius:7px;border:1px solid var(--line);background:var(--panel);color:var(--ink);cursor:pointer;font-size:13px;transition:background .12s,border-color .12s}.b:hover:not(:disabled){background:#fafbfd;border-color:#d9dee9}.b:disabled{opacity:.5;cursor:not-allowed}.b.primary{background:var(--brand);border-color:var(--brand);color:#fff}.b.primary:hover:not(:disabled){background:#3150c8;border-color:#3150c8}.b.danger{color:var(--danger);border-color:#f0cdc8;background:#fff}.b.danger:hover:not(:disabled){background:var(--danger-soft)}.b.text{border-color:transparent;background:transparent;color:var(--brand);padding:0 6px;height:26px}.b.sm{height:27px;padding:0 9px;font-size:12px}.f-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:12px}.f-field{display:flex;flex-direction:column;gap:5px}.f-field label{font-size:12px;color:var(--ink-3)}.f-in,select.f-in{height:32px;padding:0 10px;border:1px solid var(--line);border-radius:7px;background:#fff;min-width:120px;outline:none}.f-in:focus{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft)}.f-in.lg{height:38px;font-size:14px}.f-in.code{font-family:ui-monospace,Menlo,monospace;letter-spacing:.18em;font-size:17px;text-align:center}.f-hint{font-size:12px;color:var(--ink-3)}.f-err{font-size:12px;color:var(--danger)}.s-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:16px}@media(max-width:1100px){.s-grid{grid-template-columns:repeat(2,1fr)}}.s-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:15px 16px;box-shadow:var(--shadow)}.s-card .label{font-size:12px;color:var(--ink-3);margin-bottom:6px}.s-card .value{font-size:24px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:-.02em}.s-card .value small{font-size:13px;font-weight:400;color:var(--ink-3);margin-left:3px}.s-card .foot{margin-top:6px;font-size:12px;color:var(--ink-3)}.m-mask{position:fixed;top:0;right:0;bottom:0;left:0;background:#1219266b;display:grid;place-items:center;z-index:50;padding:24px}.m-box{background:var(--panel);border-radius:12px;width:480px;max-width:100%;box-shadow:0 20px 48px #1018282e;overflow:hidden}.m-hd{padding:15px 18px;border-bottom:1px solid var(--line-2);font-weight:600}.m-bd{padding:18px}.m-ft{padding:13px 18px;border-top:1px solid var(--line-2);display:flex;justify-content:flex-end;gap:8px}.login-page{height:100%;display:grid;grid-template-columns:1fr 420px;background:var(--panel)}@media(max-width:900px){.login-page{grid-template-columns:1fr}}.login-side{background:linear-gradient(160deg,#22305a,#3b5bdb 62%,#5b7bf0);color:#fff;padding:56px;display:flex;flex-direction:column;justify-content:space-between}.login-side h1{font-size:30px;line-height:1.35;letter-spacing:-.02em}.login-side p{color:#ffffffc7;font-size:13px;max-width:420px}.login-side ol{color:#ffffffd1;font-size:13px;padding-left:18px;line-height:2}.login-form{padding:56px 44px;display:flex;flex-direction:column;justify-content:center}.login-form h2{font-size:22px;margin-bottom:6px}.login-form .lead{color:var(--ink-3);font-size:13px;margin-bottom:24px}.role-chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}.chip{padding:5px 10px;border:1px solid var(--line);border-radius:999px;font-size:12px;cursor:pointer;color:var(--ink-2);background:#fff}.chip.on{border-color:var(--brand);color:var(--brand);background:var(--brand-soft)}.empty{text-align:center;padding:56px 20px;color:var(--ink-3)}.empty .big{font-size:15px;color:var(--ink-2);margin-bottom:6px}.skel-line{height:12px;border-radius:6px;background:linear-gradient(90deg,#eef1f6,#f7f8fa,#eef1f6);background-size:200% 100%;animation:skel 1.4s infinite}@keyframes skel{0%{background-position:200% 0}to{background-position:-200% 0}}.kv{display:grid;grid-template-columns:96px 1fr;gap:8px 12px;font-size:13px}.kv dt{color:var(--ink-3)}.kv dd{margin:0}
