:root{--bg: #0b0d10;--surface-1: #111317;--surface-2: #16191e;--surface-3: #1d2129;--overlay: rgba(5, 6, 8, .72);--border: #23272f;--border-strong: #323845;--text: #e7eaef;--text-secondary: #a3aab6;--text-muted: #6d7480;--accent: #5c8dff;--accent-strong: #3d6fe8;--accent-surface: rgba(92, 141, 255, .12);--ok: #34c17e;--ok-surface: rgba(52, 193, 126, .13);--warn: #d99f37;--warn-surface: rgba(217, 159, 55, .13);--danger: #e5544b;--danger-strong: #d34238;--danger-surface: rgba(229, 84, 75, .13);--font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--mono: "JetBrains Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;--radius-sm: 6px;--radius: 8px;--radius-lg: 10px;--control-h: 32px;--side-w: 232px;--side-w-collapsed: 60px;--dur: .14s;--ease: cubic-bezier(.3, .7, .4, 1);color-scheme:dark}*{box-sizing:border-box}html,body,#root{height:100%}body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font);font-size:13px;line-height:1.5;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}h1,h2,h3,p,ul{margin:0}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}code,pre{font-family:var(--mono)}::selection{background:var(--accent-surface);color:var(--text)}:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--radius-sm)}input:focus-visible,select:focus-visible,textarea:focus-visible,button:focus-visible{outline-offset:0}*{scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}*::-webkit-scrollbar{width:10px;height:10px}*::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:8px;border:3px solid transparent;background-clip:padding-box}*::-webkit-scrollbar-track{background:transparent}.app{display:grid;grid-template-columns:var(--side-w) minmax(0,1fr);height:100vh}.app.collapsed{grid-template-columns:var(--side-w-collapsed) minmax(0,1fr)}.main{overflow-y:auto;min-width:0}.page{max-width:1080px;margin:0 auto;padding:28px 32px 48px}.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:20px}.page-head h1{font-size:17px;font-weight:600;letter-spacing:-.01em;line-height:1.3}.page-head .desc{margin-top:2px;color:var(--text-secondary);font-size:13px}.breadcrumb{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--text-muted);margin-bottom:6px}.breadcrumb a{color:var(--text-muted)}.breadcrumb a:hover{color:var(--text);text-decoration:none}.muted{color:var(--text-muted)}.dim{color:var(--text-secondary)}.mono{font-family:var(--mono);font-size:12px}.side{background:var(--surface-1);border-right:1px solid var(--border);display:flex;flex-direction:column;padding:12px 10px;gap:2px;overflow-y:auto;overflow-x:hidden}.side-head{display:flex;align-items:center;gap:9px;padding:4px 8px 14px;color:var(--text)}.side-head .brand-name{font-size:13px;font-weight:600;letter-spacing:-.01em;white-space:nowrap;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis}.collapse-btn{margin-left:auto}.nav-label{font-size:10.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--text-muted);padding:14px 10px 5px;white-space:nowrap}.nav-item{display:flex;align-items:center;gap:10px;width:100%;height:34px;padding:0 12px;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--text-secondary);font:inherit;font-size:13px;cursor:pointer;white-space:nowrap;transition:background var(--dur) var(--ease),color var(--dur) var(--ease)}.nav-item:hover{background:var(--surface-2);color:var(--text);text-decoration:none}.nav-item.active{background:var(--surface-3);color:var(--text)}.nav-item.active .nav-ico{color:var(--accent)}.nav-ico{display:inline-flex;color:var(--text-muted);transition:color var(--dur) var(--ease)}.nav-item:hover .nav-ico,.nav-item:focus-visible .nav-ico{color:var(--text-secondary)}.side-foot{margin-top:auto;padding-top:12px;border-top:1px solid var(--border);display:flex;align-items:center;gap:8px}.user-chip{display:flex;align-items:center;gap:8px;min-width:0;flex:1;padding:4px 6px}.avatar{width:26px;height:26px;flex:none;border-radius:50%;background:var(--surface-3);border:1px solid var(--border-strong);display:grid;place-items:center;font-size:10.5px;font-weight:600;color:var(--text-secondary)}.user-chip .who{min-width:0;line-height:1.25;display:flex;flex-direction:column}.user-chip .who .name{font-size:12.5px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.user-chip .who .role{font-size:11px;color:var(--text-muted);text-transform:capitalize}.app.collapsed .side{align-items:stretch}.app.collapsed .side-head{justify-content:center;padding:4px 0 14px}.app.collapsed .side-head .brand-name{display:none}.app.collapsed .side-head .collapse-btn{margin-left:0}.app.collapsed .nav-label,.app.collapsed .user-chip .who{display:none}.app.collapsed .side-head .collapse-btn-center{display:inline-flex}.app.collapsed .nav-item{justify-content:center;padding:0;width:100%}.app.collapsed .nav-item .nav-txt{display:none}.app.collapsed .side-foot{flex-direction:column;padding-top:12px}.app.collapsed .user-chip{padding:4px;justify-content:center}[data-tip]{position:relative}[data-tip]:hover:after,[data-tip]:focus-visible:after{content:attr(data-tip);position:absolute;left:calc(100% + 8px);top:50%;transform:translateY(-50%);background:var(--surface-3);border:1px solid var(--border-strong);color:var(--text);font-size:12px;line-height:1.3;padding:5px 8px;border-radius:var(--radius-sm);white-space:nowrap;z-index:60;pointer-events:none;box-shadow:0 4px 16px #0006}.panel{background:var(--surface-1);border:1px solid var(--border);border-radius:var(--radius-lg)}.panel-pad{padding:16px}.section-title{font-size:13px;font-weight:600;color:var(--text);margin-bottom:12px}.toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.toolbar .grow{flex:1;min-width:120px}.btn,.icon-btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:var(--control-h);padding:0 12px;border:1px solid var(--border-strong);border-radius:var(--radius);background:var(--surface-2);color:var(--text);font:inherit;font-size:13px;font-weight:500;cursor:pointer;white-space:nowrap;transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease),color var(--dur) var(--ease)}.btn:hover:not(:disabled),.icon-btn:hover:not(:disabled){background:var(--surface-3);border-color:var(--border-strong)}.btn:active:not(:disabled),.icon-btn:active:not(:disabled){background:#22262e}.btn:disabled,.icon-btn:disabled{opacity:.45;cursor:not-allowed}.btn .ico,.icon-btn .ico{color:var(--text-secondary);transition:color var(--dur) var(--ease)}.btn:hover:not(:disabled) .ico{color:var(--text)}.btn-primary{background:var(--accent-strong);border-color:var(--accent-strong);color:#fff}.btn-primary .ico,.btn-primary:hover:not(:disabled) .ico{color:#fff}.btn-primary:hover:not(:disabled){background:var(--accent);border-color:var(--accent)}.btn-danger{background:transparent;border-color:var(--border-strong);color:var(--danger)}.btn-danger .ico,.btn-danger:hover:not(:disabled) .ico{color:var(--danger)}.btn-danger:hover:not(:disabled){background:var(--danger-surface);border-color:var(--danger)}.btn-danger-solid{background:var(--danger-strong);border-color:var(--danger-strong);color:#fff}.btn-danger-solid .ico,.btn-danger-solid:hover:not(:disabled) .ico{color:#fff}.btn-danger-solid:hover:not(:disabled){background:var(--danger);border-color:var(--danger)}.btn-ghost{background:transparent;border-color:transparent;color:var(--text-secondary)}.btn-ghost .ico{color:var(--text-muted)}.btn-ghost:hover:not(:disabled){background:var(--surface-2);border-color:transparent;color:var(--text)}.btn-sm{height:26px;padding:0 8px;font-size:12px;gap:5px;border-radius:var(--radius-sm)}.icon-btn{width:var(--control-h);padding:0;color:var(--text-secondary)}.icon-btn .ico{color:var(--text-muted)}.icon-btn:hover:not(:disabled) .ico{color:var(--text)}.icon-btn-sm{width:26px;height:26px}.spin{animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.input,.select,.textarea{height:var(--control-h);padding:0 10px;border:1px solid var(--border-strong);border-radius:var(--radius);background:var(--bg);color:var(--text);font:inherit;font-size:13px;width:100%;transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease)}.input::placeholder,.textarea::placeholder{color:var(--text-muted)}.input:hover:not(:disabled),.select:hover:not(:disabled),.textarea:hover:not(:disabled){border-color:#3d4450}.input:focus,.select:focus,.textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-surface)}.input:disabled,.select:disabled,.textarea:disabled{opacity:.5;cursor:not-allowed}.select{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding-right:28px;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236d7480' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;cursor:pointer}.textarea{height:auto;padding:10px;line-height:1.55;resize:vertical}.textarea.code{font-family:var(--mono);font-size:12px;line-height:1.6}.field{display:flex;flex-direction:column;gap:6px}.field>.label{font-size:12px;font-weight:500;color:var(--text-secondary)}.field .hint{font-size:11.5px;color:var(--text-muted)}.form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}.check{display:inline-flex;align-items:center;gap:8px;height:var(--control-h);font-size:13px;color:var(--text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none}.check input{width:15px;height:15px;margin:0;accent-color:var(--accent);cursor:pointer}.search{position:relative}.search .input{padding-left:30px}.search .ico{position:absolute;left:9px;top:50%;transform:translateY(-50%);color:var(--text-muted);pointer-events:none;display:inline-flex}.tabs{display:inline-flex;align-items:center;gap:2px;padding:3px;background:var(--surface-1);border:1px solid var(--border);border-radius:var(--radius)}.tab{display:inline-flex;align-items:center;gap:7px;height:30px;padding:0 13px;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--text-secondary);font:inherit;font-size:12.5px;font-weight:500;cursor:pointer;white-space:nowrap;transition:background var(--dur) var(--ease),color var(--dur) var(--ease)}.tab:hover{color:var(--text)}.tab.on{background:var(--surface-3);color:var(--text)}.tab.on .ico{color:var(--accent)}.tab .ico{color:var(--text-muted)}.table-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface-1)}table{width:100%;border-collapse:collapse;font-size:13px}th{text-align:left;font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--text-muted);padding:9px 14px;border-bottom:1px solid var(--border);white-space:nowrap;background:var(--surface-1);position:sticky;top:0}td{padding:9px 14px;border-bottom:1px solid var(--border);vertical-align:middle;color:var(--text-secondary)}tbody tr:last-child td{border-bottom:0}tbody tr{transition:background var(--dur) var(--ease)}tbody tr:hover{background:var(--surface-2)}td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}td .primary-link{color:var(--text);font-weight:500}td .primary-link:hover{color:var(--accent)}.pill{display:inline-flex;align-items:center;gap:6px;height:20px;padding:0 8px;border-radius:999px;font-size:11.5px;font-weight:500;border:1px solid transparent;white-space:nowrap}.pill .dot{width:6px;height:6px;border-radius:50%;flex:none}.pill-ok{color:var(--ok);background:var(--ok-surface)}.pill-ok .dot{background:var(--ok)}.pill-warn{color:var(--warn);background:var(--warn-surface)}.pill-warn .dot{background:var(--warn)}.pill-danger{color:var(--danger);background:var(--danger-surface)}.pill-danger .dot{background:var(--danger)}.pill-info{color:var(--accent);background:var(--accent-surface)}.pill-info .dot{background:var(--accent)}.pill-off{color:var(--text-muted);background:var(--surface-2);border-color:var(--border)}.pill-off .dot{background:var(--text-muted)}.pill .dot.pulse{animation:pulse 2s var(--ease) infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.45}}.badge{display:inline-flex;align-items:center;gap:5px;height:19px;padding:0 7px;border-radius:5px;background:var(--surface-2);border:1px solid var(--border);color:var(--text-secondary);font-size:11px;font-weight:500;font-family:var(--mono);white-space:nowrap}.svc-row{display:flex;align-items:center;gap:7px;min-width:0}.svc-dot{width:7px;height:7px;border-radius:50%;flex:none}.svc-dot.ok{background:var(--ok)}.svc-dot.warn{background:var(--warn)}.svc-dot.danger{background:var(--danger)}.svc-dot.off{background:var(--text-muted)}.notice{display:flex;align-items:flex-start;gap:8px;padding:9px 12px;border-radius:var(--radius);border:1px solid var(--border);background:var(--surface-2);color:var(--text-secondary);font-size:12.5px;margin:10px 0;min-width:0}.notice>span:last-child{min-width:0;overflow-wrap:anywhere}.notice>span:last-child{max-height:260px;overflow-y:auto}.notice .ico{flex:none;margin-top:1px;display:inline-flex}.notice-ok{border-color:#34c17e59;background:var(--ok-surface);color:var(--text)}.notice-ok .ico{color:var(--ok)}.notice-err{border-color:#e5544b59;background:var(--danger-surface);color:var(--text)}.notice-err .ico{color:var(--danger)}.notice-warn{border-color:#d99f3759;background:var(--warn-surface);color:var(--text)}.notice-warn .ico{color:var(--warn)}.notice-info .ico{color:var(--accent)}.log-panel{border:1px solid var(--border);border-radius:var(--radius-lg);background:#0a0c0f;overflow:hidden}.log-head{display:flex;align-items:center;gap:8px;padding:7px 12px;border-bottom:1px solid var(--border);background:var(--surface-1)}.log-head .title{font-size:12px;font-weight:500;font-family:var(--mono);color:var(--text-secondary)}.log{margin:0;padding:12px 14px;font-family:var(--mono);font-size:12px;line-height:1.6;color:#c4cad4;white-space:pre-wrap;word-break:break-word;overflow-y:auto;min-height:320px;max-height:480px}.log:empty:before{content:""}.empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:48px 24px;text-align:center;color:var(--text-muted)}.empty .ico{color:var(--text-muted);opacity:.7;margin-bottom:4px;display:inline-flex}.empty .title{font-size:13.5px;font-weight:500;color:var(--text-secondary)}.empty .hint{font-size:12.5px;max-width:360px}.empty .action{margin-top:8px}.skeleton{border-radius:var(--radius-sm);background:linear-gradient(90deg,var(--surface-2) 25%,var(--surface-3) 50%,var(--surface-2) 75%);background-size:200% 100%;animation:shimmer 1.4s ease infinite;height:14px}@keyframes shimmer{to{background-position:-200% 0}}.overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--overlay);display:grid;place-items:center;z-index:100;padding:16px}.dialog{width:100%;max-width:400px;background:var(--surface-2);border:1px solid var(--border-strong);border-radius:12px;box-shadow:0 16px 48px #00000080;padding:20px}.dialog .dlg-ico{display:grid;place-items:center;width:36px;height:36px;border-radius:var(--radius);margin-bottom:12px}.dialog .dlg-ico.danger{background:var(--danger-surface);color:var(--danger)}.dialog h2{font-size:14.5px;font-weight:600;margin-bottom:6px}.dialog .dlg-body{color:var(--text-secondary);font-size:13px;margin-bottom:16px}.dialog .dlg-actions{display:flex;justify-content:flex-end;gap:8px}.row{display:flex;align-items:center;gap:8px}.wrap{flex-wrap:wrap}.spacer{flex:1}.stack-list{display:flex;flex-direction:column}.divider{height:1px;background:var(--border);border:0;margin:20px 0}.kbd{display:inline-block;padding:1px 5px;border:1px solid var(--border-strong);border-bottom-width:2px;border-radius:4px;background:var(--surface-2);font-family:var(--mono);font-size:11px;color:var(--text-secondary)}.login{min-height:100vh;display:grid;place-items:center;padding:24px;background:var(--bg)}.login .card{width:100%;max-width:340px;background:var(--surface-1);border:1px solid var(--border);border-radius:14px;padding:28px;display:flex;flex-direction:column;gap:14px}.login .brand{display:flex;flex-direction:column;align-items:center;gap:10px;margin-bottom:4px}.login .brand .name{font-size:15px;font-weight:600;letter-spacing:-.01em}.login .brand .sub{font-size:12px;color:var(--text-muted)}.console-grid{display:grid;grid-template-columns:200px minmax(0,1fr);gap:14px;align-items:start}.svc-list{display:flex;flex-direction:column;gap:2px;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface-1);padding:6px}.svc-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 9px;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--text-secondary);font:inherit;font-size:12.5px;cursor:pointer;text-align:left;transition:background var(--dur) var(--ease),color var(--dur) var(--ease)}.svc-item:hover{background:var(--surface-2);color:var(--text)}.svc-item.on{background:var(--surface-3);color:var(--text)}.svc-item .port{margin-left:auto}.tpl-grid{display:grid;grid-template-columns:300px minmax(0,1fr);gap:16px;align-items:start}.tpl-item{display:block;width:100%;text-align:left;padding:11px 12px;border:0;border-bottom:1px solid var(--border);border-radius:0;background:transparent;color:inherit;font:inherit;cursor:pointer;transition:background var(--dur) var(--ease)}.tpl-item:last-child{border-bottom:0}.tpl-item:hover{background:var(--surface-2)}.tpl-item.on{background:var(--surface-3)}.tpl-item .tpl-name{font-size:13px;font-weight:500;color:var(--text)}.tpl-item .tpl-desc{font-size:12px;color:var(--text-muted);margin-top:1px;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}.file-editor{margin-top:14px}.file-editor .ed-head{display:flex;align-items:center;gap:8px;padding:8px 12px;border-bottom:1px solid var(--border)}@media(max-width:1100px){.console-grid{grid-template-columns:1fr}.svc-list{flex-direction:row;flex-wrap:wrap}.svc-item{width:auto}.tpl-grid{grid-template-columns:1fr}.page-head{flex-direction:column;align-items:stretch}.page-head .actions{flex-wrap:wrap}}@media(max-width:860px){.page{padding:20px 16px 40px}.page-head{flex-direction:column;align-items:stretch}.page-head .actions{flex-wrap:wrap}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}
