/* ============ 全局 ============ */
html, body, #app { height: 100%; margin: 0; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  color: var(--el-text-color-primary);
  background: var(--to-bg);
  --to-bg: #f3f5f9;
  --to-card: #ffffff;
  --to-border: #e7eaf0;
  --to-muted: #8a94a6;
  --to-code-bg: #f6f8fa;
}
html.dark body { --to-bg: #141414; --to-card: #1d1e1f; --to-border: #333; --to-muted: #8d9095; --to-code-bg: #262727; }
* { box-sizing: border-box; }
a { color: var(--el-color-primary); text-decoration: none; }
code, .mono { font-family: Consolas, "SFMono-Regular", Menlo, monospace; }
.boot-loading { display: flex; align-items: center; justify-content: center; height: 100%; color: #8a94a6; font-size: 16px; }

.mt8 { margin-top: 8px; } .mt16 { margin-top: 16px; } .mb8 { margin-bottom: 8px; } .mb16 { margin-bottom: 16px; }
.ml8 { margin-left: 8px; }
.muted { color: var(--to-muted); font-size: 13px; }
.flex { display: flex; align-items: center; gap: 8px; }
.flex-1 { flex: 1; min-width: 0; }
.between { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clickable, .el-table .clickable { cursor: pointer; }
.text-success { color: #67c23a; } .text-danger { color: #f56c6c; } .text-warning { color: #e6a23c; }

/* ============ 布局 ============ */
.layout { height: 100%; }
.layout-aside { background: #0f1b33; transition: width .2s; overflow: hidden; display: flex; flex-direction: column; }
.logo { height: 56px; display: flex; align-items: center; gap: 10px; padding: 0 18px; color: #fff; font-weight: 600; font-size: 15px; cursor: pointer; white-space: nowrap; border-bottom: 1px solid rgba(255,255,255,.06); }
.layout-menu { border-right: none !important; }
.layout-menu .el-menu-item.is-active { background: #2f6bff !important; }
.layout-menu:not(.el-menu--collapse) { width: 216px; }
.layout-header { height: 56px; background: var(--to-card); border-bottom: 1px solid var(--to-border); display: flex; align-items: center; gap: 14px; padding: 0 16px; }
.project-switch .project-name { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; padding: 6px 10px; border-radius: 6px; background: var(--el-fill-color-light); font-weight: 500; }
.header-title { color: var(--to-muted); font-size: 13px; }
.header-badge { margin-right: 6px; }
.header-badge .el-badge__content { top: 6px; }
.user-name { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.layout-main { padding: 16px; background: var(--to-bg); overflow-y: auto; }

/* ============ 卡片 / 统计 ============ */
.el-card { border-radius: 8px; border-color: var(--to-border); }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.toolbar .spacer { flex: 1; }
.stat-card { background: var(--to-card); border: 1px solid var(--to-border); border-radius: 8px; padding: 16px; display: flex; gap: 14px; align-items: center; margin-bottom: 0; height: 100%; }
.stat-icon { width: 46px; height: 46px; border-radius: 10px; display: flex; align-items: center; justify-content: center; color: #fff; flex-shrink: 0; }
.stat-title { color: var(--to-muted); font-size: 13px; }
.stat-value { font-size: 26px; font-weight: 600; line-height: 1.3; }
.stat-sub { color: var(--to-muted); font-size: 12px; }
.kv-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 16px; }
.kv-grid > div { display: flex; flex-direction: column; gap: 2px; }
.kv-grid span { color: var(--to-muted); font-size: 12px; }
.kv-grid b { font-size: 18px; font-weight: 600; }
.usage-bar { margin-bottom: 6px; }
.usage-head { display: flex; justify-content: space-between; font-size: 12px; color: var(--to-muted); margin-bottom: 2px; }
.top-server { padding: 6px 0; border-bottom: 1px dashed var(--to-border); cursor: pointer; }
.top-server:last-child { border-bottom: none; }
.top-server-name { font-weight: 500; margin-bottom: 4px; }
.dot-unread { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #f56c6c; }

/* ============ 登录 ============ */
.login-page { display: flex; height: 100%; background: linear-gradient(135deg, #0f1b33 0%, #1d3a7a 60%, #2f6bff 100%); }
.login-left { flex: 1; color: #fff; padding: 10vh 6vw; display: flex; flex-direction: column; justify-content: center; }
.login-brand { display: flex; gap: 16px; align-items: center; }
.login-brand h1 { margin: 0; font-size: 30px; }
.login-brand p { margin: 6px 0 0; opacity: .75; }
.login-features { list-style: none; padding: 0; margin: 48px 0 0; }
.login-features li { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; font-size: 15px; opacity: .9; }
.login-right { width: 460px; display: flex; align-items: center; justify-content: center; background: rgba(255,255,255,.04); }
.login-card { width: 360px; border-radius: 12px; padding: 12px 8px; }
.login-card h2 { margin: 0 0 24px; font-size: 22px; }
.login-tip { margin-top: 16px; font-size: 12px; color: #8a94a6; text-align: center; }
.login-field { margin-bottom: 22px; width: 100%; }
.login-field .el-input__password { cursor: pointer; }
@media (max-width: 900px) { .login-left { display: none; } .login-right { width: 100%; } }

/* ============ 通用组件 ============ */
.kv-editor .kv-row { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.kv-editor .kv-key { flex: 2; } .kv-editor .kv-value { flex: 3; } .kv-editor .kv-desc { flex: 2; }
.json-view { position: relative; }
.json-view pre { background: var(--to-code-bg); border: 1px solid var(--to-border); border-radius: 6px; padding: 10px 12px; margin: 0; overflow: auto; font-size: 12.5px; line-height: 1.55; white-space: pre-wrap; word-break: break-all; font-family: Consolas, Menlo, monospace; }
.json-view .json-copy { position: absolute; right: 8px; top: 6px; z-index: 1; }
.method-tag { min-width: 58px; text-align: center; font-weight: 600; }

/* Markdown 编辑器 */
.md-editor { display: flex; flex-direction: column; border: 1px solid var(--to-border); border-radius: 6px; overflow: hidden; background: var(--to-card); }
.md-toolbar { display: flex; align-items: center; gap: 2px; padding: 4px 8px; border-bottom: 1px solid var(--to-border); background: var(--el-fill-color-lighter); flex-wrap: wrap; }
.md-tool { border: none; background: transparent; min-width: 30px; height: 28px; border-radius: 4px; cursor: pointer; color: var(--el-text-color-regular); font-weight: 600; font-size: 13px; }
.md-tool:hover { background: var(--el-fill-color); }
.md-body { flex: 1; display: flex; min-height: 0; }
.md-textarea { flex: 1; border: none; outline: none; resize: none; padding: 14px 16px; font-family: Consolas, Menlo, "Microsoft YaHei", monospace; font-size: 14px; line-height: 1.7; background: transparent; color: var(--el-text-color-primary); border-right: 1px solid var(--to-border); }
.md-preview { flex: 1; overflow: auto; padding: 14px 20px; }

/* Markdown 渲染 */
.markdown-body { line-height: 1.75; font-size: 14.5px; word-wrap: break-word; }
.markdown-body h1, .markdown-body h2, .markdown-body h3 { margin: 1.2em 0 .6em; line-height: 1.35; }
.markdown-body h1 { font-size: 1.8em; border-bottom: 1px solid var(--to-border); padding-bottom: .3em; }
.markdown-body h2 { font-size: 1.45em; border-bottom: 1px solid var(--to-border); padding-bottom: .25em; }
.markdown-body h3 { font-size: 1.2em; }
.markdown-body p { margin: .6em 0; }
.markdown-body table { border-collapse: collapse; margin: .8em 0; display: block; overflow: auto; }
.markdown-body th, .markdown-body td { border: 1px solid var(--to-border); padding: 6px 12px; }
.markdown-body th { background: var(--el-fill-color-light); }
.markdown-body code { background: var(--to-code-bg); padding: 2px 5px; border-radius: 4px; font-size: .9em; }
.markdown-body pre { background: var(--to-code-bg); border: 1px solid var(--to-border); border-radius: 6px; padding: 12px; overflow: auto; }
.markdown-body pre code { background: transparent; padding: 0; }
.markdown-body blockquote { margin: .8em 0; padding: .4em 1em; color: var(--to-muted); border-left: 4px solid #c9d4ea; background: var(--el-fill-color-lighter); }
.markdown-body img { max-width: 100%; }
.markdown-body ul, .markdown-body ol { padding-left: 1.6em; }
.markdown-body hr { border: none; border-top: 1px solid var(--to-border); margin: 1.4em 0; }
.markdown-body input[type=checkbox] { margin-right: 6px; }
.embed-card { border: 1px solid #c9d8ff; background: #f3f7ff; border-left: 4px solid #2f6bff; border-radius: 6px; padding: 10px 14px; margin: .8em 0; font-size: 13.5px; }
html.dark .embed-card { background: #1a2338; border-color: #2c3e66; }
.embed-title { font-weight: 600; margin-bottom: 4px; }
.embed-sub { color: var(--to-muted); font-size: 12.5px; }
.embed-method { display: inline-block; padding: 0 6px; border-radius: 3px; color: #fff; font-size: 12px; font-weight: 600; background: #909399; }
.embed-method.m-GET { background: #67c23a; } .embed-method.m-POST { background: #e6a23c; } .embed-method.m-PUT { background: #409eff; } .embed-method.m-DELETE { background: #f56c6c; }
.embed-error { color: #f56c6c; } .embed-loading { color: var(--to-muted); }
.st-UP { color: #67c23a; } .st-DOWN { color: #f56c6c; } .st-PENDING { color: #e6a23c; } .st-PAUSED, .st-MAINTENANCE { color: #909399; }

/* 状态圆点 */
.status-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: #c0c4cc; flex-shrink: 0; }
.status-dot.up, .status-dot.online { background: #67c23a; box-shadow: 0 0 0 3px rgba(103,194,58,.18); }
.status-dot.down, .status-dot.offline { background: #f56c6c; box-shadow: 0 0 0 3px rgba(245,108,108,.18); }
.status-dot.pending { background: #e6a23c; }
.status-dot.paused, .status-dot.maintenance { background: #909399; }

/* 可用率条形图 */
.uptime-bars { display: flex; gap: 2px; align-items: flex-end; height: 26px; }
.uptime-bars i { flex: 1; height: 100%; border-radius: 2px; background: #e4e7ed; min-width: 2px; }
.uptime-bars i.good { background: #67c23a; } .uptime-bars i.warn { background: #e6a23c; } .uptime-bars i.bad { background: #f56c6c; }

/* 树形侧栏 + 内容 */
.split-page { display: flex; gap: 16px; align-items: stretch; min-height: calc(100vh - 120px); }
.split-side { width: 260px; flex-shrink: 0; background: var(--to-card); border: 1px solid var(--to-border); border-radius: 8px; padding: 12px; overflow: auto; }
.split-main { flex: 1; min-width: 0; }
.tree-node { display: flex; align-items: center; justify-content: space-between; width: 100%; padding-right: 4px; font-size: 13.5px; }
.tree-node .tree-ops { display: none; }
.el-tree-node__content:hover .tree-ops { display: inline-flex; }

/* 服务器卡片 */
.server-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.server-card { background: var(--to-card); border: 1px solid var(--to-border); border-radius: 8px; padding: 14px; cursor: pointer; transition: box-shadow .2s, transform .2s; }
.server-card:hover { box-shadow: 0 6px 18px rgba(31, 56, 108, .1); transform: translateY(-1px); }
.server-card.offline { opacity: .7; }

.el-table .cell { line-height: 1.5; }
.el-drawer__header { margin-bottom: 8px; }
.el-dialog__body { padding-top: 8px; }
