Files
ai-worker-platform/static/style.css
T
hz4th_coder dfdcd78f1a DAG画布:节点拖不动根因修复 + 缩放比例显示/一键100%
- 根因:dagLayout 画布宽(1100-1360px)超出视口可用宽度(约1060px),加上保存的偏移视图可能把节点推到视口外 → 节点不可见/不可点,表现为'拖不动'
- 修复:打开画布时若无保存视图、或节点全部在视口外,自动适配缩放(≤100%)并居中,全部节点始终可见可拖
- 新增右上角缩放控件:实时显示缩放百分比(滚轮/适配/拖动联动) + ⤢适配按钮 + 100%一键回原始视图
- 实测:真实鼠标拖动在 0.82x 缩放下精确跟随;滚轮 112%→100% 显示联动
2026-08-12 23:55:57 +08:00

181 lines
13 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
:root{
--bg:#0f1420; --panel:#171e2e; --panel2:#1d2638; --border:#2a3550;
--text:#e6ebf5; --muted:#8b97ad; --accent:#4f8cff; --accent2:#38d39f;
--warn:#ffb454; --danger:#ff6b6b; --purple:#a78bfa;
}
*{margin:0;padding:0;box-sizing:border-box}
body{background:var(--bg);color:var(--text);font-family:"PingFang SC","Microsoft YaHei",system-ui,sans-serif;font-size:14px}
#app{display:flex;min-height:100vh}
#sidebar{width:220px;background:var(--panel);border-right:1px solid var(--border);display:flex;flex-direction:column;position:fixed;top:0;bottom:0}
.logo{padding:20px 18px;font-size:18px;font-weight:700;border-bottom:1px solid var(--border)}
.logo span{color:var(--accent)}
.logo small{display:block;font-size:11px;color:var(--muted);font-weight:400;margin-top:2px}
nav{padding:12px 0;flex:1}
nav a{display:block;padding:11px 20px;color:var(--muted);text-decoration:none;border-left:3px solid transparent}
nav a:hover{color:var(--text);background:var(--panel2)}
nav a.active{color:var(--accent);border-left-color:var(--accent);background:var(--panel2)}
.sidebar-foot{padding:14px 18px;border-top:1px solid var(--border);font-size:12px}
.conn.ok{color:var(--accent2)} .conn.err{color:var(--danger)}
.logout{color:var(--muted);text-decoration:none;display:block;margin-top:6px}
.logout:hover{color:var(--danger)}
#main{flex:1;margin-left:220px;padding:24px 28px;max-width:1400px}
h1.page-title{font-size:20px;margin-bottom:18px}
h1.page-title small{color:var(--muted);font-weight:400;font-size:13px;margin-left:8px}
.toolbar{display:flex;gap:10px;margin-bottom:16px;flex-wrap:wrap}
.btn{background:var(--panel2);border:1px solid var(--border);color:var(--text);padding:8px 14px;border-radius:8px;cursor:pointer;font-size:13px}
.btn:hover{border-color:var(--accent)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn.primary:hover{filter:brightness(1.15)}
.btn.success{background:var(--accent2);border-color:var(--accent2);color:#06281c}
.btn.danger{background:transparent;border-color:var(--danger);color:var(--danger)}
.btn.warn{background:transparent;border-color:var(--warn);color:var(--warn)}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn.sm{padding:4px 10px;font-size:12px;border-radius:6px}
input,select,textarea{background:var(--panel2);border:1px solid var(--border);color:var(--text);padding:8px 10px;border-radius:8px;font-size:13px;outline:none;width:100%}
input:focus,select:focus,textarea:focus{border-color:var(--accent)}
textarea{min-height:90px;resize:vertical;font-family:inherit}
label{display:block;font-size:12px;color:var(--muted);margin:12px 0 5px}
.row{display:flex;gap:10px}.row>*{flex:1}
.card{background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:16px}
.grid{display:grid;gap:14px}
.g4{grid-template-columns:repeat(4,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g2{grid-template-columns:repeat(2,1fr)}
@media(max-width:1100px){.g4{grid-template-columns:repeat(2,1fr)}.g3,.g2{grid-template-columns:1fr}}
.stat{background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:16px 18px}
.stat .num{font-size:26px;font-weight:700;margin-top:6px}
.stat .lbl{color:var(--muted);font-size:12px}
.stat .sub{color:var(--muted);font-size:11px;margin-top:4px}
table{width:100%;border-collapse:collapse;font-size:13px}
th{color:var(--muted);text-align:left;font-weight:500;padding:10px 12px;border-bottom:1px solid var(--border);white-space:nowrap}
td{padding:10px 12px;border-bottom:1px solid var(--border);vertical-align:middle}
tr:hover td{background:var(--panel2)}
.mono{font-family:ui-monospace,Consolas,monospace}
.badge{display:inline-block;padding:2px 9px;border-radius:20px;font-size:12px;white-space:nowrap}
.st-todo{background:#2a3550;color:#aeb9d4}
.st-running{background:#173b6b;color:#6db3ff}
.st-review{background:#4a3a10;color:#ffd166}
.st-done{background:#0f3d2e;color:#38d39f}
.st-rejected{background:#4a1c1c;color:#ff8f8f}
.st-failed{background:#3d1c2e;color:#ff7ac2}
.st-cancelled{background:#333;color:#999}
.pri-high{color:#ff6b6b}.pri-medium{color:#ffb454}.pri-low{color:#8b97ad}
.kanban{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;align-items:start;min-width:1200px}
.kb-col{background:var(--panel);border:1px solid var(--border);border-radius:12px;min-height:200px}
.kb-head{padding:10px 12px;font-weight:600;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid var(--border)}
.kb-head .cnt{color:var(--muted);font-size:12px}
.kb-body{padding:10px;display:flex;flex-direction:column;gap:8px;min-height:120px}
.kb-card{background:var(--panel2);border:1px solid var(--border);border-radius:10px;padding:10px 12px;cursor:grab;transition:border .15s}
.kb-card:hover{border-color:var(--accent)}
.kb-card.dragging{opacity:.4}
.kb-col.drag-over{border-color:var(--accent);background:var(--panel2)}
.kb-card .t{font-size:13px;font-weight:500;margin-bottom:6px}
.kb-card .m{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.kb-card .cost{color:var(--muted);font-size:11px;margin-top:6px}
.kb-card .out{font-size:11px;color:var(--accent2);margin-top:4px;display:none}
.list-item{display:flex;justify-content:space-between;align-items:center;padding:12px 0;border-bottom:1px solid var(--border)}
.list-item:last-child{border-bottom:none}
.list-item .title{font-weight:600}
.list-item .meta{color:var(--muted);font-size:12px;margin-top:3px}
.modal{width:640px;max-width:94vw;max-height:86vh;overflow-y:auto;background:var(--panel);border:1px solid var(--border);border-radius:14px;padding:22px;position:relative}
.modal h3{font-size:16px;margin-bottom:14px}
.modal .close{position:absolute;top:14px;right:16px;background:none;border:none;color:var(--muted);font-size:20px;cursor:pointer}
.modal .close:hover{color:var(--text)}
#modal-mask{position:fixed;inset:0;background:rgba(0,0,0,.55);display:flex;align-items:center;justify-content:center;z-index:100}
.modal-actions{display:flex;gap:10px;margin-top:18px;justify-content:flex-end;flex-wrap:wrap}
#login-mask{position:fixed;inset:0;background:var(--bg);z-index:200;display:flex;align-items:center;justify-content:center}
.login-box{width:340px;background:var(--panel);border:1px solid var(--border);border-radius:14px;padding:30px;text-align:center}
.login-box h2{font-size:17px;margin-bottom:6px}
.login-box p{color:var(--muted);font-size:13px;margin-bottom:16px}
.login-box .btn{width:100%;margin-top:12px;padding:10px}
.err{color:var(--danger);font-size:12px;margin-top:10px;min-height:16px}
#toast-wrap{position:fixed;top:20px;right:20px;z-index:300;display:flex;flex-direction:column;gap:8px}
.toast{background:var(--panel2);border:1px solid var(--border);border-left:3px solid var(--accent);padding:10px 16px;border-radius:8px;font-size:13px;animation:slidein .25s}
.toast.ok{border-left-color:var(--accent2)}
.toast.err{border-left-color:var(--danger)}
@keyframes slidein{from{transform:translateX(30px);opacity:0}to{transform:none;opacity:1}}
.log-line{font-size:12px;padding:7px 10px;border-left:2px solid var(--border);margin-bottom:6px;background:var(--panel2);border-radius:0 8px 8px 0;font-family:ui-monospace,Consolas,monospace;word-break:break-all}
.log-line.info{border-left-color:var(--accent)}
.log-line.success{border-left-color:var(--accent2)}
.log-line.warn{border-left-color:var(--warn)}
.log-line.error{border-left-color:var(--danger)}
.log-line .ts{color:var(--muted);margin-right:8px}
.output-box{background:#0b0f18;border:1px solid var(--border);border-radius:10px;padding:14px;white-space:pre-wrap;word-break:break-word;font-family:ui-monospace,Consolas,monospace;font-size:13px;max-height:300px;overflow-y:auto}
.kv{display:grid;grid-template-columns:90px 1fr;gap:6px 12px;font-size:13px}
.kv dt{color:var(--muted)}
.kv dd{margin:0}
.sec-title{font-size:14px;font-weight:600;margin:20px 0 10px;color:var(--accent)}
.bar{height:8px;background:var(--panel2);border-radius:6px;overflow:hidden;margin-top:6px}
.bar>div{height:100%;background:var(--accent);border-radius:6px}
.empty{color:var(--muted);text-align:center;padding:40px 0}
.spin{display:inline-block;width:14px;height:14px;border:2px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:rot .8s linear infinite;vertical-align:-2px;margin-right:6px}
@keyframes rot{to{transform:rotate(360deg)}}
.proj-card{cursor:pointer;transition:border .15s}
.proj-card:hover{border-color:var(--accent)}
.pager-tip{color:var(--muted);font-size:12px}
.pill{display:inline-block;background:var(--panel2);border:1px solid var(--border);border-radius:6px;padding:2px 8px;font-size:12px;margin:2px}
/* V1tabs / DAG / 告警 / 开关 */
.tabs{display:flex;gap:4px;margin-bottom:16px;border-bottom:1px solid var(--border)}
.tabs a{padding:9px 16px;color:var(--muted);text-decoration:none;border-bottom:2px solid transparent;font-size:13px}
.tabs a.active{color:var(--accent);border-bottom-color:var(--accent)}
.dag-box{background:var(--panel);border:1px solid var(--border);border-radius:12px;overflow:hidden;height:520px;position:relative;touch-action:none;user-select:none;cursor:grab}
.dag-box svg{display:block;transition:transform .05s linear;overflow:visible}
.dag-node{stroke:var(--border);stroke-width:1.5;rx:10;cursor:grab}
.dag-node:hover{stroke:var(--accent)}
.dag-node rect{stroke-width:1.5;rx:10}
.dag-label{font-size:13px;font-weight:600;fill:#ffffff;stroke:none;text-anchor:middle;pointer-events:none}
.dag-sub{font-size:11px;fill:rgba(255,255,255,.82);stroke:none;text-anchor:middle;pointer-events:none}
.dag-edge{stroke:var(--border);stroke-width:1.5;fill:none;marker-end:url(#arrow)}
.dag-edge.act{stroke:var(--accent)}
.dag-trash{position:absolute;left:14px;bottom:14px;background:rgba(255,107,107,.1);border:1.5px dashed var(--danger);color:var(--danger);border-radius:10px;padding:8px 14px;font-size:12px;cursor:pointer;z-index:5;display:flex;align-items:center;gap:6px;backdrop-filter:blur(2px)}
.dag-trash:hover,.dag-trash.hover{background:rgba(255,107,107,.25);border-style:solid}
.dag-trash .cnt{background:var(--danger);color:#fff;border-radius:8px;padding:0 6px;font-size:11px}
.dag-zoom{position:absolute;right:14px;top:14px;background:rgba(23,30,46,.88);border:1px solid var(--border);border-radius:8px;padding:4px 10px;font-size:12px;color:var(--muted);display:flex;align-items:center;gap:6px;z-index:6}
.dag-zoom b{color:var(--text);font-weight:600;min-width:42px;text-align:center}
.dag-zoom button{background:var(--panel2);border:1px solid var(--border);color:var(--text);border-radius:5px;padding:2px 8px;font-size:11px;cursor:pointer}
.dag-zoom button:hover{border-color:var(--accent);color:var(--accent)}
.alert-row{border-left:3px solid var(--border);padding:12px 14px;margin-bottom:8px;background:var(--panel2);border-radius:0 10px 10px 0;cursor:pointer}
.alert-row.unread{border-left-color:var(--warn)}
.alert-row.critical{border-left-color:var(--danger)}
.alert-row .t{font-weight:600;font-size:13px}
.alert-row .d{color:var(--muted);font-size:12px;margin-top:4px}
.alert-row .tm{color:var(--muted);font-size:11px;margin-top:4px}
.alert-row .badge{margin-right:8px}
.check-group{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}
.check-group label{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--text);margin:0;padding:5px 10px;background:var(--panel2);border:1px solid var(--border);border-radius:20px;cursor:pointer}
.check-group input{width:auto}
.switch{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:13px}
.switch input{width:auto}
code{background:var(--panel2);border:1px solid var(--border);border-radius:6px;padding:2px 7px;font-size:12px;color:var(--accent2);font-family:ui-monospace,Consolas,monospace}
.doc-item{display:flex;justify-content:space-between;align-items:center;padding:12px 0;border-bottom:1px solid var(--border)}
.wbs-row{border:1px solid var(--border);border-radius:10px;padding:12px;margin-bottom:10px;background:var(--panel2)}
.wbs-row .idx{display:inline-block;width:26px;height:26px;line-height:26px;text-align:center;background:var(--accent);color:#fff;border-radius:50%;font-size:13px;margin-right:8px}
.copy-btn{cursor:pointer;color:var(--accent)}
.tab-note{color:var(--muted);font-size:12px;margin-bottom:12px}
/* ---------- V2 新增样式 ---------- */
.mode-card{border-left:3px solid var(--accent);transition:transform .15s}
.mode-card:hover{transform:translateY(-2px);box-shadow:0 4px 14px rgba(0,0,0,.08)}
.agent-step{border:1px solid var(--line);border-radius:8px;padding:8px;margin-bottom:6px;font-size:12px}
.agent-step pre{margin:6px 0 0;font-size:12px;color:#444}
.empty-td{text-align:center;color:var(--muted);padding:16px}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.form-grid label{display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--muted)}
.form-grid input,.form-grid select,.form-grid textarea{font-size:13px}
.form-grid textarea{resize:vertical}
#main .tabs a{cursor:pointer}
.tag{display:inline-block;background:var(--accent-soft,#eef2ff);color:#4f5bd5;border-radius:4px;padding:0 6px;font-size:11px;margin-right:4px}