:root{
  --bg:#f3f5f9;--card:#ffffff;--line:#e5e9f2;--txt:#1c2333;--sub:#68738c;
  --pri:#2f6bff;--pri-d:#1f52d6;--ok:#18a058;--warn:#e08e0b;--err:#d64545;
  --r:12px;--shadow:0 1px 3px rgba(16,24,40,.08),0 1px 2px rgba(16,24,40,.04);
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:"Segoe UI","Microsoft YaHei",system-ui,sans-serif;background:var(--bg);color:var(--txt);min-height:100vh}
a{color:var(--pri);text-decoration:none}
/* top bar */
.topbar{display:flex;align-items:center;gap:16px;background:var(--card);border-bottom:1px solid var(--line);padding:0 24px;height:56px;position:sticky;top:0;z-index:10}
.topbar .brand{font-weight:700;font-size:16px;color:var(--txt)}
.topbar .brand span{color:var(--pri)}
.topbar .spacer{flex:1}
.topbar a.item{color:var(--sub);font-size:14px;padding:6px 10px;border-radius:8px}
.topbar a.item:hover{background:var(--bg);color:var(--txt)}
/* layout */
.wrap{max-width:1100px;margin:28px auto;padding:0 20px}
.wrap.full{max-width:1280px}
h1{font-size:22px;margin-bottom:6px}
.sub{color:var(--sub);font-size:13px;margin-bottom:20px}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow)}
.pad{padding:20px}
/* buttons */
.btn{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);background:var(--card);color:var(--txt);font-size:14px;padding:9px 16px;border-radius:10px;cursor:pointer;transition:.15s}
.btn:hover{border-color:var(--pri);color:var(--pri)}
.btn.primary{background:var(--pri);border-color:var(--pri);color:#fff}
.btn.primary:hover{background:var(--pri-d)}
.btn.danger{color:var(--err);border-color:#f1c8c8}
.btn.danger:hover{background:#fdf1f1}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn.block{width:100%;justify-content:center}
.btn.lg{font-size:15px;padding:12px 20px}
/* status dot */
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;background:#c3cad8;margin-right:7px;vertical-align:middle}
.dot.on{background:var(--ok);box-shadow:0 0 0 3px rgba(24,160,88,.15)}
/* terminal cards */
.term-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:16px}
.term{display:block;padding:20px;cursor:pointer;transition:.15s}
.term:hover{border-color:var(--pri);transform:translateY(-1px)}
.term .t-name{font-weight:600;font-size:16px;margin-bottom:4px}
.term .t-desc{color:var(--sub);font-size:13px;margin-bottom:14px}
.term .t-meta{display:flex;gap:14px;font-size:12.5px;color:var(--sub)}
.badge{display:inline-block;font-size:12px;padding:3px 10px;border-radius:20px;background:#eef2fb;color:var(--pri)}
.badge.gray{background:#f1f3f8;color:var(--sub)}
.badge.red{background:#fdeeee;color:var(--err)}
.badge.green{background:#e9f7ef;color:var(--ok)}
/* two-pane */
.split{display:grid;grid-template-columns:340px 1fr;gap:16px;align-items:stretch}
@media(max-width:900px){.split{grid-template-columns:1fr}}
.pane{display:flex;flex-direction:column;min-height:520px;max-height:calc(100vh - 170px)}
.pane .pane-head{padding:14px 16px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
.pane .pane-body{flex:1;overflow:auto}
/* file list */
.flist{list-style:none}
.flist li{display:flex;align-items:center;gap:8px;padding:11px 14px;border-bottom:1px solid var(--line);cursor:pointer;font-size:14px}
.flist li:hover{background:#f7f9fd}
.flist li.active{background:#eef4ff}
.flist li.active .fname{color:var(--pri);font-weight:600}
.flist .fname{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.flist .fsize{color:var(--sub);font-size:12px;flex-shrink:0}
.flist .fdel{border:none;background:none;color:#c3cad8;cursor:pointer;font-size:15px;padding:2px 6px;border-radius:6px}
.flist .fdel:hover{color:var(--err);background:#fdf1f1}
/* preview */
.preview{display:flex;flex-direction:column;align-items:center;padding:16px;gap:12px}
.preview canvas{max-width:100%;box-shadow:var(--shadow);border:1px solid var(--line);border-radius:6px;background:#fff}
.pager{display:flex;align-items:center;gap:12px;font-size:14px;color:var(--sub)}
.pager button{border:1px solid var(--line);background:var(--card);border-radius:8px;padding:5px 12px;cursor:pointer}
.pager button:disabled{opacity:.4;cursor:default}
.empty{color:var(--sub);text-align:center;padding:60px 20px;font-size:14px}
.meta{display:flex;flex-wrap:wrap;gap:18px;padding:12px 16px;border-top:1px solid var(--line);color:var(--sub);font-size:13px}
.meta b{color:var(--txt);font-weight:600}
/* bottom action bar */
.actionbar{display:flex;justify-content:flex-end;gap:10px;padding:14px 16px;border-top:1px solid var(--line)}
/* forms */
.field{margin-bottom:16px}
.field label{display:block;font-size:13px;color:var(--sub);margin-bottom:6px}
.field input[type=text],.field input[type=password]{width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:10px;font-size:14px;outline:none}
.field input:focus{border-color:var(--pri)}
.radio-row{display:flex;flex-direction:column;gap:10px}
.radio-row label{display:flex;align-items:center;gap:10px;padding:12px 14px;border:1px solid var(--line);border-radius:10px;cursor:pointer;font-size:14px}
.radio-row label:has(input:checked){border-color:var(--pri);background:#eef4ff}
.divider{height:1px;background:var(--line);margin:18px 0}
.hint{color:var(--sub);font-size:12.5px;line-height:1.7}
.msg{padding:10px 14px;border-radius:10px;font-size:13.5px;margin:12px 0}
.msg.err{background:#fdeeee;color:var(--err)}
.msg.ok{background:#e9f7ef;color:var(--ok)}
.msg.info{background:#eef2fb;color:var(--pri)}
/* switch */
.switch{position:relative;display:inline-block;width:44px;height:24px;flex-shrink:0}
.switch input{opacity:0;width:0;height:0}
.slider{position:absolute;inset:0;background:#cfd6e4;border-radius:20px;transition:.2s;cursor:pointer}
.slider:before{content:"";position:absolute;height:18px;width:18px;left:3px;top:3px;background:#fff;border-radius:50%;transition:.2s}
.switch input:checked+.slider{background:var(--ok)}
.switch input:checked+.slider:before{transform:translateX(20px)}
/* key list */
.krow{display:flex;align-items:center;gap:12px;padding:13px 4px;border-bottom:1px solid var(--line);font-size:14px}
.krow .kname{font-weight:600}
.krow .kdate{color:var(--sub);font-size:12.5px;flex:1}
/* steps */
.steps{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}
.step{font-size:12.5px;padding:5px 12px;border-radius:20px;background:#f1f3f8;color:var(--sub)}
.step.done{background:#e9f7ef;color:var(--ok)}
.step.now{background:#eef2fb;color:var(--pri);font-weight:600}
.step.bad{background:#fdeeee;color:var(--err)}
/* login page */
.login-box{max-width:400px;margin:8vh auto 0;padding:30px}
.login-box h1{font-size:20px;margin-bottom:2px}
.login-box .sub{margin-bottom:22px}
