style(admin): compact dashboard layout

This commit is contained in:
caoqianming 2026-08-28 15:11:18 +08:00
parent 7f439a91d5
commit 510033d06f
2 changed files with 56 additions and 50 deletions

View File

@ -7,46 +7,46 @@
<style> <style>
:root { :root {
color-scheme: light; color-scheme: light;
--bg: #f4f6f8; --panel: #ffffff; --panel-soft: #f8fafb; --bg: #f5f6f7; --panel: #ffffff; --panel-soft: #f7f8f9;
--border: #dfe3e7; --border-soft: #edf0f2; --border: #dfe3e6; --border-soft: #eceff1;
--text: #202428; --text-strong: #121619; --muted: #70777f; --text: #202428; --text-strong: #121619; --muted: #70777f;
--accent: #b83a31; --accent-hover: #a9322a; --accent-soft: #fbecea; --accent: #b83a31; --accent-hover: #a9322a; --accent-soft: #fbecea;
--accent-ring: rgba(184,58,49,.16); --accent-ring: rgba(184,58,49,.16);
--ok: #238653; --warn: #b66a16; --danger: #b83a31; --ok: #238653; --warn: #b66a16; --danger: #b83a31;
--r-md: 6px; --r-lg: 12px; --r-md: 5px; --r-lg: 8px;
--shadow-soft: 0 1px 2px rgba(18,24,30,.04), 0 8px 24px rgba(18,24,30,.035); --shadow-soft: 0 1px 2px rgba(18,24,30,.035);
--mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, monospace; --mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, monospace;
} }
* { box-sizing: border-box; } * { box-sizing: border-box; }
body { body {
margin: 0; font-family: system-ui, -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif; margin: 0; font-family: system-ui, -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif;
color: var(--text); background: var(--bg); font-size: 13px; line-height: 1.55; color: var(--text); background: var(--bg); font-size: 13px; line-height: 1.45;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
} }
header { header {
position: sticky; top: 0; z-index: 10; min-height: 64px; position: sticky; top: 0; z-index: 10; min-height: 54px;
background: rgba(255,255,255,.94); backdrop-filter: blur(12px); background: rgba(255,255,255,.94); backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border); box-shadow: 0 1px 0 rgba(18,24,30,.02); border-bottom: 1px solid var(--border); box-shadow: 0 1px 0 rgba(18,24,30,.02);
display: flex; align-items: center; gap: 16px; padding: 10px max(20px, calc((100vw - 1480px) / 2)); display: flex; align-items: center; gap: 12px; padding: 8px max(18px, calc((100vw - 1480px) / 2));
} }
header .brand { display: flex; align-items: center; gap: 11px; min-width: 0; } header .brand { display: flex; align-items: center; gap: 9px; min-width: 0; }
header .logo { header .logo {
width: 34px; height: 34px; flex: 0 0 auto; border-radius: 9px; width: 30px; height: 30px; flex: 0 0 auto; border-radius: 7px;
background: linear-gradient(135deg, var(--accent), #8e2a20); background: linear-gradient(135deg, var(--accent), #8e2a20);
box-shadow: 0 5px 14px rgba(184,58,49,.22); box-shadow: 0 3px 9px rgba(184,58,49,.18);
color: #fff; font-weight: 750; font-size: 15px; color: #fff; font-weight: 750; font-size: 14px;
display: flex; align-items: center; justify-content: center; display: flex; align-items: center; justify-content: center;
} }
header .brand-copy { min-width: 0; } header .brand-copy { min-width: 0; }
header .title { color: var(--text-strong); font-weight: 650; font-size: 15px; line-height: 1.25; } header .title { color: var(--text-strong); font-weight: 650; font-size: 14px; line-height: 1.2; }
header .eyebrow { margin-top: 1px; color: var(--muted); font-size: 10px; letter-spacing: .7px; text-transform: uppercase; } header .eyebrow { margin-top: 1px; color: var(--muted); font-size: 10px; letter-spacing: .7px; text-transform: uppercase; }
header .spacer { flex: 1; } header .spacer { flex: 1; }
header .meta { color: var(--muted); font-size: 12px; font-family: var(--mono); } header .meta { color: var(--muted); font-size: 12px; font-family: var(--mono); }
header .actions { display: flex; align-items: center; gap: 7px; } header .actions { display: flex; align-items: center; gap: 6px; }
header a, header button { header a, header button {
min-height: 32px; display: inline-flex; align-items: center; justify-content: center; min-height: 30px; display: inline-flex; align-items: center; justify-content: center;
font-size: 12px; font-weight: 550; color: var(--text); text-decoration: none; font-size: 12px; font-weight: 550; color: var(--text); text-decoration: none;
padding: 5px 11px; border: 1px solid var(--border); border-radius: var(--r-md); padding: 4px 10px; border: 1px solid var(--border); border-radius: var(--r-md);
background: #fff; cursor: pointer; transition: .15s ease; background: #fff; cursor: pointer; transition: .15s ease;
} }
header a:hover, header button:hover { border-color: #c8cdd2; background: var(--panel-soft); color: var(--accent); } header a:hover, header button:hover { border-color: #c8cdd2; background: var(--panel-soft); color: var(--accent); }
@ -54,22 +54,22 @@
header label.auto { color: var(--muted); display: flex; align-items: center; gap: 6px; padding: 0 4px; cursor: pointer; white-space: nowrap; } header label.auto { color: var(--muted); display: flex; align-items: center; gap: 6px; padding: 0 4px; cursor: pointer; white-space: nowrap; }
input[type="checkbox"] { accent-color: var(--accent); } input[type="checkbox"] { accent-color: var(--accent); }
main { padding: 28px 24px 48px; max-width: 1480px; margin: 0 auto; } main { padding: 16px 18px 30px; max-width: 1480px; margin: 0 auto; }
.msg { padding: 40px 16px; text-align: center; color: var(--muted); } .msg { padding: 28px 14px; text-align: center; color: var(--muted); }
.msg a { color: var(--accent); } .msg a { color: var(--accent); }
/* 目录 + 内容两栏;目录 sticky 跟随滚动 */ /* 目录 + 内容两栏;目录 sticky 跟随滚动 */
#layout { display: grid; grid-template-columns: 196px minmax(0, 1fr); gap: 24px; align-items: start; } #layout { display: grid; grid-template-columns: 172px minmax(0, 1fr); gap: 16px; align-items: start; }
#toc { #toc {
position: sticky; top: 88px; display: flex; flex-direction: column; gap: 3px; position: sticky; top: 70px; display: flex; flex-direction: column; gap: 2px;
padding: 10px; background: rgba(255,255,255,.76); border: 1px solid var(--border); padding: 7px; background: rgba(255,255,255,.82); border: 1px solid var(--border);
border-radius: var(--r-lg); box-shadow: var(--shadow-soft); border-radius: var(--r-lg); box-shadow: var(--shadow-soft);
} }
#toc .toc-label { padding: 5px 10px 8px; color: #959ba1; font-size: 10px; font-weight: 700; letter-spacing: 1px; } #toc .toc-label { padding: 4px 8px 6px; color: #959ba1; font-size: 10px; font-weight: 700; letter-spacing: .8px; }
#toc a { #toc a {
display: flex; align-items: center; gap: 9px; min-height: 36px; display: flex; align-items: center; gap: 7px; min-height: 31px;
color: var(--muted); text-decoration: none; font-size: 12px; padding: 7px 10px; color: var(--muted); text-decoration: none; font-size: 12px; padding: 5px 8px;
border-radius: 7px; border: 1px solid transparent; transition: .15s ease; border-radius: 5px; border: 1px solid transparent; transition: .15s ease;
} }
#toc .nav-index { width: 20px; color: #a0a6ac; font: 10px/1 var(--mono); } #toc .nav-index { width: 20px; color: #a0a6ac; font: 10px/1 var(--mono); }
#toc a:hover { background: var(--panel-soft); color: var(--text-strong); } #toc a:hover { background: var(--panel-soft); color: var(--text-strong); }
@ -77,39 +77,39 @@
#toc a.active .nav-index { color: var(--accent); } #toc a.active .nav-index { color: var(--accent); }
#content { min-width: 0; } #content { min-width: 0; }
.page-intro { .page-intro {
position: relative; overflow: hidden; margin-bottom: 18px; padding: 22px 24px; position: relative; overflow: hidden; margin-bottom: 10px; padding: 13px 16px;
border: 1px solid #e6d9d7; border-radius: var(--r-lg); border: 1px solid #e6d9d7; border-radius: var(--r-lg);
background: linear-gradient(120deg, #fff 0%, #fff 54%, #fdf4f2 100%); box-shadow: var(--shadow-soft); background: linear-gradient(120deg, #fff 0%, #fff 54%, #fdf4f2 100%); box-shadow: var(--shadow-soft);
} }
.page-intro::after { .page-intro::after {
content: ""; position: absolute; right: -70px; top: -90px; width: 220px; height: 220px; content: ""; position: absolute; right: -55px; top: -75px; width: 170px; height: 170px;
border: 42px solid rgba(184,58,49,.055); border-radius: 50%; pointer-events: none; border: 32px solid rgba(184,58,49,.045); border-radius: 50%; pointer-events: none;
} }
.page-intro h1 { position: relative; margin: 0; color: var(--text-strong); font-size: 20px; line-height: 1.35; } .page-intro h1 { position: relative; margin: 0; color: var(--text-strong); font-size: 17px; line-height: 1.3; }
.page-intro p { position: relative; margin: 6px 0 0; color: var(--muted); font-size: 12px; } .page-intro p { position: relative; margin: 3px 0 0; color: var(--muted); font-size: 11px; }
.anchor { scroll-margin-top: 82px; } .anchor { scroll-margin-top: 68px; }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; } .card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 7px; }
.card-head h2 { margin: 0; } .card-head h2 { margin: 0; }
.ctrl { display: flex; gap: 6px; } .ctrl { display: flex; gap: 6px; }
.ctrl select { .ctrl select {
min-height: 32px; font-size: 12px; padding: 4px 28px 4px 9px; border: 1px solid var(--border); min-height: 30px; font-size: 12px; padding: 3px 26px 3px 8px; border: 1px solid var(--border);
border-radius: var(--r-md); background: #fff; color: var(--text); border-radius: var(--r-md); background: #fff; color: var(--text);
} }
.sublabel { color: var(--muted); font-size: 11px; margin-bottom: 4px; } .sublabel { color: var(--muted); font-size: 10px; margin-bottom: 3px; font-weight: 600; letter-spacing: .2px; }
.grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); } .grid { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
.card { .card {
background: var(--panel); border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--panel); border: 1px solid var(--border); border-radius: var(--r-lg);
padding: 18px 20px; margin-bottom: 16px; box-shadow: var(--shadow-soft); padding: 12px 14px; margin-bottom: 10px; box-shadow: var(--shadow-soft);
} }
.card h2 { margin: 0 0 13px; font-size: 13px; color: var(--text-strong); font-weight: 650; letter-spacing: .15px; } .card h2 { margin: 0 0 8px; font-size: 13px; color: var(--text-strong); font-weight: 650; letter-spacing: .1px; }
/* 大数字 stat 块 */ /* 大数字 stat 块 */
.stat { position: relative; overflow: hidden; min-height: 102px; background: linear-gradient(145deg,#fff,var(--panel-soft)); border: 1px solid var(--border-soft); border-radius: 10px; padding: 14px 16px; } .stat { position: relative; overflow: hidden; min-height: 78px; background: linear-gradient(145deg,#fff,var(--panel-soft)); border: 1px solid var(--border-soft); border-radius: 7px; padding: 10px 12px; }
.stat::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: #d9dde1; } .stat::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: #d9dde1; }
.stat .k { color: var(--muted); font-size: 12px; } .stat .k { color: var(--muted); font-size: 11px; }
.stat .v { color: var(--text-strong); font-size: 23px; font-weight: 650; font-family: var(--mono); margin-top: 7px; letter-spacing: -.5px; } .stat .v { color: var(--text-strong); font-size: 20px; font-weight: 650; font-family: var(--mono); margin-top: 3px; letter-spacing: -.4px; line-height: 1.25; }
.stat .sub { color: var(--muted); font-size: 11px; margin-top: 2px; } .stat .sub { color: var(--muted); font-size: 11px; margin-top: 2px; }
.stat.warn { border-color: #efd8b7; background: #fffaf2; } .stat.warn { border-color: #efd8b7; background: #fffaf2; }
.stat.warn::before { background: var(--warn); } .stat.warn::before { background: var(--warn); }
@ -119,9 +119,9 @@
.stat.danger .v { color: var(--danger); } .stat.danger .v { color: var(--danger); }
/* chips(状态分布) */ /* chips(状态分布) */
.chips { display: flex; flex-wrap: wrap; gap: 6px; } .chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip { .chip {
font-size: 12px; padding: 3px 9px; border-radius: 999px; font-size: 11px; padding: 2px 8px; border-radius: 999px;
background: #f1f1f1; color: var(--text); font-family: var(--mono); background: #f1f1f1; color: var(--text); font-family: var(--mono);
} }
.chip b { font-weight: 700; } .chip b { font-weight: 700; }
@ -130,13 +130,14 @@
.chip.ok { background: #e8f5e9; color: var(--ok); } .chip.ok { background: #e8f5e9; color: var(--ok); }
table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12px; } table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12px; }
th, td { padding: 9px 10px; text-align: right; border-bottom: 1px solid var(--border-soft); white-space: nowrap; } th, td { padding: 7px 9px; text-align: right; border-bottom: 1px solid var(--border-soft); white-space: nowrap; }
th:first-child, td:first-child { text-align: left; } th:first-child, td:first-child { text-align: left; }
th { color: var(--muted); background: var(--panel-soft); font-weight: 600; } th { color: #626a72; background: var(--panel-soft); font-size: 11px; font-weight: 650; letter-spacing: .1px; }
thead th:first-child { border-radius: 7px 0 0 7px; } thead th:first-child { border-radius: 7px 0 0 7px; }
thead th:last-child { border-radius: 0 7px 7px 0; } thead th:last-child { border-radius: 0 7px 7px 0; }
tbody tr { transition: background-color .12s ease; } tbody tr { transition: background-color .12s ease; }
tbody tr:hover { background: #fafbfc; } tbody tr:hover { background: #fafbfc; }
tbody tr:last-child td { border-bottom-color: transparent; }
td.num { font-family: var(--mono); } td.num { font-family: var(--mono); }
td.num.hot { color: var(--danger); font-weight: 700; } td.num.hot { color: var(--danger); font-weight: 700; }
td.trend { font-family: var(--mono); letter-spacing: 1px; color: var(--accent); } td.trend { font-family: var(--mono); letter-spacing: 1px; color: var(--accent); }
@ -283,9 +284,9 @@
.app-msg.success { border-color: #b8ddb9; background: #f1faf1; color: var(--ok); } .app-msg.success { border-color: #b8ddb9; background: #f1faf1; color: var(--ok); }
.app-msg.error { border-color: #edc1bd; background: var(--accent-soft); color: var(--danger); } .app-msg.error { border-color: #edc1bd; background: var(--accent-soft); color: var(--danger); }
.pager { display: flex; align-items: center; gap: 12px; justify-content: flex-end; margin-top: 10px; } .pager { display: flex; align-items: center; gap: 8px; justify-content: flex-end; margin-top: 7px; }
.pager button { .pager button {
min-height: 32px; font-size: 12px; padding: 4px 12px; border: 1px solid var(--border); border-radius: var(--r-md); min-height: 30px; font-size: 12px; padding: 3px 10px; border: 1px solid var(--border); border-radius: var(--r-md);
background: #fff; cursor: pointer; color: var(--text); background: #fff; cursor: pointer; color: var(--text);
} }
.pager button:hover:not(:disabled) { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); } .pager button:hover:not(:disabled) { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
@ -298,6 +299,11 @@
} }
select:focus, input:focus, textarea:focus { border-color: var(--accent) !important; box-shadow: 0 0 0 3px var(--accent-ring); outline: none; } select:focus, input:focus, textarea:focus { border-color: var(--accent) !important; box-shadow: 0 0 0 3px var(--accent-ring); outline: none; }
@media (min-width: 821px) and (max-width: 1080px) {
#layout { grid-template-columns: 148px minmax(0, 1fr); gap: 12px; }
#toc .nav-index { display: none; }
}
@media (max-width: 820px) { @media (max-width: 820px) {
main { padding: 10px; } main { padding: 10px; }
.grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); } .grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
@ -327,10 +333,10 @@
#toc .toc-label, #toc .nav-index { display: none; } #toc .toc-label, #toc .nav-index { display: none; }
#toc a { min-height: 32px; white-space: nowrap; border: 1px solid var(--border); background: #fff; } #toc a { min-height: 32px; white-space: nowrap; border: 1px solid var(--border); background: #fff; }
#toc a.active { border-color: var(--accent); } #toc a.active { border-color: var(--accent); }
.page-intro { padding: 18px; } .page-intro { padding: 12px 14px; }
.page-intro h1 { font-size: 18px; } .page-intro h1 { font-size: 17px; }
.anchor { scroll-margin-top: 150px; } .anchor { scroll-margin-top: 150px; }
.card { padding: 15px; } .card { padding: 12px; }
} }
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {

View File

@ -118,7 +118,7 @@ function renderTasks(t) {
return `<span class="chip ${c}">${escapeHtml(k)} <b>${n}</b></span>`; return `<span class="chip ${c}">${escapeHtml(k)} <b>${n}</b></span>`;
}).join("") || `<span class="empty">无</span>`; }).join("") || `<span class="empty">无</span>`;
return `<div class="card"><h2>任务(共 ${t.total || 0}</h2>` return `<div class="card"><h2>任务(共 ${t.total || 0}</h2>`
+ `<div style="margin-bottom:10px;"><div class="sublabel">status</div><div class="chips">${statusChips}</div></div>` + `<div style="margin-bottom:7px;"><div class="sublabel">status</div><div class="chips">${statusChips}</div></div>`
+ `<div><div class="sublabel">run_status</div><div class="chips">${runChips}</div></div>` + `<div><div class="sublabel">run_status</div><div class="chips">${runChips}</div></div>`
+ `</div>`; + `</div>`;
} }
@ -746,7 +746,7 @@ function tierLegendHTML() {
return `<div style="margin:2px 0;"><b>${escapeHtml(name)}${name === def ? "(默认)" : ""}</b>` return `<div style="margin:2px 0;"><b>${escapeHtml(name)}${name === def ? "(默认)" : ""}</b>`
+ `<span style="color:var(--muted);">${members.map(escapeHtml).join("、") || "(空)"}</span></div>`; + `<span style="color:var(--muted);">${members.map(escapeHtml).join("、") || "(空)"}</span></div>`;
}).join(""); }).join("");
return `<div class="tier-legend" style="font-size:.85em;margin:0 0 10px;padding:8px 10px;` return `<div class="tier-legend" style="font-size:.85em;margin:0 0 7px;padding:6px 8px;`
+ `background:var(--bg-soft,#f6f6f6);border-radius:6px;">` + `background:var(--bg-soft,#f6f6f6);border-radius:6px;">`
+ `<div style="color:var(--muted);margin-bottom:4px;">档位说明(改 config/agent.yaml model_tiersadmin 始终全开)</div>` + `<div style="color:var(--muted);margin-bottom:4px;">档位说明(改 config/agent.yaml model_tiersadmin 始终全开)</div>`
+ rows + `</div>`; + rows + `</div>`;