/* ═══ 최신 CSS 리빌드 — 디자인 토큰 + 현대 색상 공간 ═══ */ @layer reset, tokens, layout, components, utilities; @layer tokens { :root { /* ── 강조색: #00ff87 민트 그린 ── */ --accent: #00ff87; --accent-strong: #00d46f; --accent-soft: rgba(0,255,135,.14); --accent-glow: rgba(0,255,135,.35); /* ── 다크 / 화이트 교차 팔레트 ── */ --dark: #0a0d10; --dark-2: #12161b; --dark-3: #1a2027; --dark-border: #232a33; --light: #f7f8fa; --light-2: #ffffff; --light-border: #e2e5ea; /* 전면 다크: 모든 패널 + 캔버스 통일 */ --panel-bg: var(--dark); --panel-bg-2: var(--dark-2); --panel-border: var(--dark-border); --panel-text: #e8eaed; --panel-text-dim: #9aa3ad; --panel-text-faint: #7f8a97; /* 대비 4.68:1 — 이전 #6b7681 은 3.54:1 로 WCAG AA(4.5) 미달이었다 */ --canvas-bg: var(--dark); --canvas-grid: color-mix(in srgb, var(--accent) 7%, transparent); --dot: rgba(255,255,255,.035); /* 도트 그리드 — 매우 낮은 대비 */ /* 노드 (다크 캔버스 위 = 다크 카드) */ --node-bg: var(--dark-2); --node-border: var(--dark-border); --node-text: #e8eaed; /* 공용 */ --danger: #ff5d5d; --danger-soft: rgba(255,93,93,.12); --radius-sm: 8px; --radius-md: 12px; --radius-lg: 16px; --shadow-sm: 0 1px 3px rgba(0,0,0,.1); --shadow-md: 0 6px 24px rgba(0,0,0,.28); --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --topbar-h: 52px; --sidebar-w: 240px; --inspector-w: 280px; --font: 'Pretendard', 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR', system-ui, -apple-system, sans-serif; } } @layer reset { *,*::before,*::after{box-sizing:border-box;margin:0;padding:0} button,input,textarea{font:inherit;color:inherit} } @layer layout { body{ font-family:var(--font); background:var(--dark); color:var(--panel-text); height:100dvh; display:flex;flex-direction:column;overflow:hidden; scrollbar-gutter:stable; overscroll-behavior:none; } #canvas-wrap,#canvas{touch-action:none} #canvas .node{touch-action:none} #edges{width:100%;height:100%;position:absolute;left:0;top:0;overflow:visible;pointer-events:none} #edges path, #edges text{pointer-events:auto} #zoom-controls{position:fixed;left:16px;bottom:16px;z-index:85;display:flex;flex-direction:row;align-items:center;gap:4px;background:var(--dark-2);border:1px solid var(--dark-border);border-radius:12px;padding:6px} #zoom-controls button{width:32px;height:32px;font-size:16px;border-radius:8px} #zoom-level{min-width:44px;text-align:center;font-size:12px;font-weight:700;color:var(--accent)} #canvas .node .nport{touch-action:none} #topbar{ height:var(--topbar-h); background:var(--panel-bg); border-block-end:1px solid var(--panel-border); display:flex;align-items:center; padding-inline:10px; gap:4px;flex-shrink:0; position:relative;z-index:20; backdrop-filter:blur(12px); background:color-mix(in srgb, var(--panel-bg) 88%, transparent); overflow-x:auto;overflow-y:hidden; } #topbar::-webkit-scrollbar{height:3px} #topbar .spacer{flex:1} #app{flex:1;display:flex;min-height:0} #sidebar{ width:280px; background:var(--panel-bg-2); border-inline-end:1px solid var(--panel-border); /* 노드 팔레트 마지막 항목이 뷰포트 하단을 넘어가는데 스크롤이 없어 화면이 짧은 기기에서는 아예 닿을 수 없었다 */ overflow-y:auto; flex-shrink:0;display:flex;flex-direction:column; } #canvas-wrap{ flex:1;position:relative;overflow:hidden; background: radial-gradient(circle at 20% 30%, var(--canvas-grid), transparent 45%), radial-gradient(var(--dot) 1px, transparent 1px), var(--canvas-bg); background-size:auto, 32px 32px, auto; container-type:inline-size; } #canvas{position:absolute;inset:0} #inspector{ width:var(--inspector-w); background:var(--panel-bg-2); border-inline-start:1px solid var(--panel-border); flex-shrink:0;overflow-y:auto; } #inspector-body{min-height:200px} } @layer components { /* 사이드바 */ #wf-list{list-style:none;padding:var(--space-2);overflow-y:auto;flex:1} #wf-list li{ display:flex;justify-content:space-between;align-items:center; padding:9px 12px; border-radius:8px; cursor:pointer;font-size:13px;margin-block-end:4px; color:var(--panel-text-dim); transition:background .15s ease, color .15s ease; min-height:36px; ;margin-bottom:4px} #wf-list li .wf-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0} #wf-list li:hover{background:var(--dark-3);color:var(--panel-text)} #wf-list li.active{background:var(--accent-soft);color:var(--accent);font-weight:600} #wf-list .wf-del{border:none;background:none;font-size:16px;color:var(--panel-text-faint);cursor:pointer;padding:6px 8px;margin:-4px 0;border-radius:6px;min-width:28px;text-align:center} #wf-list .wf-del:hover{color:var(--danger);background:rgba(255,93,93,.1)} #wf-list .wf-del:hover{color:var(--danger)} #add-wf{ margin:var(--space-2) var(--space-3); padding:var(--space-3); border:1px dashed var(--dark-border); border-radius:var(--radius-md); background:none;cursor:pointer;font-size:14px; color:var(--panel-text-dim); transition:border-color .15s, background .15s, color .15s; } #add-wf:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)} /* 노드 — 라이트 표면 (다크 캔버스 대비 아님, 라이트 캔버스 위) */ #canvas .node{ position:absolute;min-width:180px;padding:10px 14px; background:linear-gradient(180deg, var(--dark-3) 0%, var(--node-bg) 30%); border:1px solid var(--node-border); border-radius:var(--radius-md); cursor:grab;user-select:none; display:flex;align-items:center;gap:var(--space-2); box-shadow:var(--shadow-sm); z-index:1; color:var(--node-text); transition:transform .15s ease, border-color .15s ease, box-shadow .15s ease, background .15s; } #canvas .node::before{ content:'';position:absolute;top:0;left:0;right:0;height:3px; border-radius:var(--radius-md) var(--radius-md) 0 0; background:var(--node-accent, var(--border-strong)); } #canvas .node:hover{ background:var(--dark-3); transform:translateY(-2px); /* 호버 리프트 */ box-shadow:0 6px 16px rgba(0,0,0,.25); border-color:color-mix(in srgb, var(--node-accent, var(--border-strong)) 50%, var(--node-border)); } /* 타입별 상단 바 색 */ #canvas .node.type-start{--node-accent:#2ea043} #canvas .node.type-process{--node-accent:#1f6feb} #canvas .node.type-decision{--node-accent:#d29922} #canvas .node.type-approval{--node-accent:#b45f06} #canvas .node.type-supervisor{--node-accent:#8957e5} #canvas .node.type-reviewer{--node-accent:#0d9488} #canvas .node.type-connector{--node-accent:#f78166} #canvas .node.type-vote{--node-accent:#e26dd4} #canvas .node.type-end{--node-accent:#d1242f} #canvas .node:hover{border-color:color-mix(in srgb, var(--accent) 60%, var(--node-border))} #canvas .node.sel{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft), 0 0 18px var(--accent-glow);transform:translateY(-2px)} #canvas .node:has(.nport:active){border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft), 0 0 18px var(--accent-glow)} #canvas .node .nicon{ width:26px;height:26px;border-radius:var(--radius-sm); color:#fff;display:flex;align-items:center;justify-content:center; font-size:14px;flex-shrink:0;aspect-ratio:1; } #canvas .node .nlabel{ font-size:14px;font-weight:700;color:#f1f3f5; white-space:normal;overflow:hidden;text-overflow:ellipsis;word-break:keep-all;line-height:1.3;max-height:2.6em;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical; text-wrap:balance; } #canvas .node .nindex{ font-size:10px;font-weight:700;color:var(--panel-text-faint); background:var(--dark);border-radius:4px;padding:1px 5px; font-family:ui-monospace,monospace; } #canvas .node .nport{ position:absolute;inset-inline-end:-4px;top:50%;translate:0 -50%; width:18px;height:18px;border-radius:50%; background:var(--accent); border:3px solid var(--node-bg); cursor:crosshair;opacity:.7;transition:opacity .15s, scale .15s; z-index:5;pointer-events:auto; box-shadow:0 0 10px var(--accent-glow); } #canvas .node .nport:hover{scale:1.3;background:var(--accent-strong)} #canvas .node:hover .nport{opacity:1} #canvas .node:has(.nport):not(:hover) .nport{opacity:.45} #canvas .node .nport:hover{scale:1.3} /* 엣지 — 다크 캔버스에서 가시성 개선 */ #edges{position:absolute;inset:0;pointer-events:none;z-index:0} #edges line{pointer-events:stroke;stroke:#8fa3b5 !important;stroke-width:3} #edges text{fill:var(--accent) !important} /* 인스펙터 */ #inspector h3{font-size:14px;padding:14px var(--space-4) var(--space-2);border-block-end:1px solid var(--panel-border);color:var(--panel-text)} #inspector-body{padding:var(--space-4);display:flex;flex-direction:column;gap:var(--space-2)} #inspector label{font-size:12px;color:var(--panel-text-dim);margin-block-start:var(--space-2)} #inspector input,#inspector textarea{ width:100%;padding:var(--space-2); background:var(--dark-3); border:1px solid var(--dark-border); border-radius:var(--radius-sm); font-size:13px;font-family:inherit; color:var(--panel-text); transition:border-color .15s, box-shadow .15s; } #inspector input:focus-visible,#inspector textarea:focus-visible{ outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft); } #inspector button{margin-block-start:var(--space-3);padding:9px;border:none;border-radius:var(--radius-sm);cursor:pointer;font-size:13px} #f-del-node,#f-del-edge{background:var(--danger-soft);color:var(--danger)} /* 컨텍스트 메뉴 */ #ctx-menu{ position:fixed;display:none;z-index:50; background:var(--dark-2); border:1px solid var(--dark-border); border-radius:var(--radius-md); box-shadow:var(--shadow-md); padding:var(--space-1); backdrop-filter:blur(8px); background:color-mix(in srgb, var(--dark-2) 92%, transparent); } #ctx-menu button{ display:block;width:100%;text-align:left; padding:var(--space-2) var(--space-3); border:none;background:none;cursor:pointer;font-size:13px;border-radius:var(--radius-sm); color:var(--panel-text); transition:background .12s, color .12s; } #ctx-menu button:hover{background:var(--dark-3);color:var(--accent)} } @layer utilities { #topbar .tb-action{flex-shrink:0} /* 전역 .tb-action — 모든 패널 버튼을 다크 테마로 통일 (흰색 기본 버튼 방지) */ .tb-action{ background:var(--dark-3); color:var(--panel-text); border:1px solid var(--dark-border); border-radius:8px; padding:5px 11px; font-size:12px; font-family:inherit; cursor:pointer; transition:background .15s ease, border-color .15s ease, color .15s ease; } .tb-action:hover{background:var(--dark-2);border-color:var(--accent);color:var(--accent)} .tb-action:active{transform:scale(.97)} #topbar .tb-sep{width:1px;height:22px;background:var(--dark-border);margin:0 4px;flex-shrink:0} #topbar button{ padding:5px 11px; background:transparent; border:1px solid var(--dark-border); border-radius:8px; color:var(--panel-text); cursor:pointer;font-size:12px;font-weight:500; white-space:nowrap;height:30px;line-height:1; transition:border-color .15s, background .15s, color .15s, translate .15s, transform .1s; } #topbar button:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)} /* 우상단 내보내기/가져오기 — #00ff87 강조 버튼 */ #topbar button.tb-action{ background:var(--accent); border:1px solid var(--accent); color:#04100a; font-weight:700; box-shadow:0 0 12px var(--accent-glow); } #topbar button.tb-action:hover{ background:var(--accent-strong); border-color:var(--accent-strong); color:#04100a; box-shadow:0 0 18px var(--accent-glow); } #topbar button:active{translate:0 1px;transform:scale(.97)} #topbar button{transition:border-color .15s, background .15s, color .15s, translate .15s, transform .1s} #topbar button:focus-visible{outline:2px solid var(--accent);outline-offset:2px;box-shadow:0 0 0 4px rgba(0,255,135,.15)} #topbar input#wf-name{ background:var(--dark-2); border:1px solid var(--dark-border); border-radius:var(--radius-sm); color:var(--panel-text); padding:7px 12px;font-size:13px; } #topbar input#wf-name:focus-visible{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)} @container (max-width: 480px){ #canvas .node{min-width:130px;padding:8px 10px} #canvas .node .nlabel{font-size:12px} } @media(max-width:900px){ #sidebar{position:absolute;z-index:10;height:100%;translate:-100% 0;transition:translate .2s ease} #sidebar.open{translate:0 0} #inspector{position:absolute;inset-inline-end:0;z-index:10;height:100%;translate:100% 0;transition:translate .2s ease} #inspector.open{translate:0 0} } @media (prefers-reduced-motion: reduce){ *,*::before,*::after{transition-duration:.01ms !important;animation-duration:.01ms !important} } /* ═══ 모바일 최적화 ═══ */ #mobile-actions{display:none} .mm-item{display:block;width:100%;text-align:left;padding:12px 14px;border:none;background:none;color:var(--panel-text);cursor:pointer;font-size:14px;border-radius:10px} .mm-item:hover{background:var(--dark-3);color:var(--accent)} @media (max-width: 768px){ /* 상단바 축소: wf-name/검색은 숨기고 나머지 버튼은 하단으로 */ #topbar{height:48px;padding-inline:10px;gap:8px} #topbar input#wf-name{display:none} #topbar input#wf-search{display:none} #topbar button:not(#sidebar-toggle){display:none} #sidebar-toggle{font-size:18px;padding:8px 10px} /* 하단 고정 액션 바 */ #mobile-actions{ display:flex;position:fixed;bottom:0;left:0;right:0;z-index:55; background:color-mix(in srgb, var(--dark-2) 92%, transparent); backdrop-filter:blur(10px); border-top:1px solid var(--dark-border); padding:8px 10px calc(8px + env(safe-area-inset-bottom)); gap:8px;justify-content:space-between; } #mobile-actions button{ flex:1;padding:12px 6px;font-size:12px;white-space:nowrap; background:var(--dark-3);border:1px solid var(--dark-border); color:var(--panel-text);border-radius:10px;cursor:pointer; min-height:44px; /* 터치 최적 크기 */ } #mobile-actions button:active{background:var(--accent-soft);color:var(--accent)} #mobile-actions #m-btn-run{background:var(--accent);color:#04100a;font-weight:700;border-color:var(--accent)} /* 캔버스 하단 여백 — 하단바에 가려지지 않게 */ #canvas-wrap{margin-bottom:0} #app{min-height:0} /* 인스펙터 — 하단 시트 스타일 */ #inspector{ width:100%;height:60vh;top:auto;bottom:0; border-radius:16px 16px 0 0; border-left:none;border-top:1px solid var(--dark-border); } #inspector{translate:0 100%} #inspector.open{translate:0 0} /* 사이드바 — 전체 높이 */ #sidebar{width:240px;top:0;height:100%} /* 미니맵 — 하단바 위로 */ #minimap{bottom:70px;right:12px;width:130px;height:90px} /* 토스트 — 하단바 위 */ #toast-container{bottom:70px} /* 실행 상태 바 — 하단바 위 */ #run-status-bar{bottom:64px} } /* 다크 스크롤바 */ ::-webkit-scrollbar{width:10px;height:10px} ::-webkit-scrollbar-track{background:transparent} ::-webkit-scrollbar-thumb{background:var(--dark-border);border-radius:5px} ::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb, var(--accent) 40%, var(--dark-border))} /* 실행 미리보기 모드 */ #run-overlay{ position:fixed;inset:0;z-index:60; background:rgba(0,0,0,.55); display:flex;align-items:center;justify-content:center; backdrop-filter:blur(3px); } #run-panel{ background:var(--dark-2);border:1px solid var(--dark-border); border-radius:var(--radius-lg);padding:20px 24px; min-width:340px;box-shadow:var(--shadow-md); color:var(--panel-text); } #run-panel h4{color:var(--accent);margin-bottom:12px} #run-panel button{margin-top:8px} .node.run-current{ border-color:var(--accent) !important; box-shadow:0 0 0 3px var(--accent-soft), 0 0 24px var(--accent-glow) !important; background:color-mix(in srgb, var(--accent) 12%, var(--dark-2)) !important; } .node.run-visited{border-color:color-mix(in srgb, var(--accent) 50%, var(--dark-border)) !important} /* 다중 선택 */ #canvas .node.multi{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)} /* 줌 컨트롤 */ #zoom-controls{ position:fixed;left:16px;bottom:16px;z-index:40; display:flex;flex-direction:row;gap:6px;align-items:center; background:color-mix(in srgb, var(--dark-2) 90%, transparent); border:1px solid var(--dark-border);border-radius:12px; padding:8px;backdrop-filter:blur(8px); } #zoom-controls button{ width:32px;height:32px;border-radius:8px;font-size:16px; background:var(--dark-3);border:1px solid var(--dark-border); color:var(--panel-text);cursor:pointer; transition:background .15s, color .15s, transform .1s; } #zoom-controls button:hover{background:var(--accent-soft);color:var(--accent)} #zoom-controls button:active{transform:scale(.9)} #zoom-level{font-size:10px;color:var(--panel-text-faint);font-family:ui-monospace,monospace} /* 미니맵 */ #minimap{ position:fixed;right:16px;bottom:16px;z-index:40; width:180px;height:120px; background:color-mix(in srgb, var(--dark-2) 92%, transparent); border:1px solid var(--dark-border);border-radius:var(--radius-md); overflow:hidden;pointer-events:none; backdrop-filter:blur(6px); } #minimap .mm-node{position:absolute;border-radius:50%;opacity:.9} #minimap .mm-node.type-start{background:var(--n-start)} #minimap .mm-node.type-process{background:var(--n-process)} #minimap .mm-node.type-decision{background:var(--n-decision)} #minimap .mm-node.type-end{background:var(--n-end)} /* 토스트 */ #toast-container{ position:fixed;top:14px;right:14px; z-index:100;display:flex;flex-direction:column;gap:8px;align-items:flex-end;pointer-events:none; } #toast-container .toast{pointer-events:auto} .toast{ background:var(--dark-2);border:1px solid var(--dark-border); color:var(--panel-text);border-radius:var(--radius-md); padding:12px 18px;font-size:13px;box-shadow:var(--shadow-md); opacity:0;translate:0 8px;transition:opacity .25s, translate .25s; max-width:520px; } .toast.show{opacity:1;translate:0 0} /* 템플릿 버튼 */ .tpl-btn{ display:block;width:100%;text-align:left; padding:8px 10px;margin-top:6px; background:var(--dark-3);border:1px solid var(--dark-border); border-radius:var(--radius-sm);color:var(--panel-text); cursor:pointer;font-size:12px; transition:border-color .15s, color .15s; } .tpl-btn:hover{border-color:var(--accent);color:var(--accent)} /* 그룹 노드 */ .group-box{ position:absolute;z-index:0; background:color-mix(in srgb, var(--accent) 4%, transparent); border:1px dashed color-mix(in srgb, var(--accent) 40%, transparent); border-radius:16px;pointer-events:none; } .group-box .g-label{ position:absolute;top:-10px;left:12px; font-size:11px;color:var(--accent); background:var(--dark);padding:0 8px;border-radius:4px; } .group-box.collapsed{border-style:solid} /* 인라인 편집 */ .inline-edit{ background:var(--dark-3);border:1px solid var(--accent); border-radius:6px;color:var(--panel-text); font-size:14px;font-weight:600;padding:2px 6px; width:100%;font-family:inherit;outline:none; } /* AI 패널 */ #ai-panel h4{color:var(--accent);margin-bottom:12px;font-size:15px} #ai-panel textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)} /* 실행 로그 패널 */ #runlog-panel::-webkit-scrollbar{width:6px} #runlog-panel::-webkit-scrollbar-thumb{background:var(--dark-border);border-radius:3px} /* 엣지 path hover */ #edges path{pointer-events:stroke;transition:stroke .15s} #edges path:hover{stroke:var(--accent) !important} /* 실행 상태 배지 */ .exec-badge{ position:absolute;top:-8px;right:-8px; width:20px;height:20px;border-radius:50%; display:flex;align-items:center;justify-content:center; font-size:11px;border:2px solid var(--dark); background:var(--dark-3); } .exec-badge.running{background:#d29922;color:#fff;animation:pulse 1s infinite} .exec-badge.completed{ background:#2ea043;color:#fff; animation:pop .3s ease; } @keyframes pop{ 0%{transform:scale(0);opacity:0} 70%{transform:scale(1.3)} 100%{transform:scale(1);opacity:1} } .exec-badge.failed{background:#d1242f;color:#fff} @keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}} /* 노드 잠금 배지 */ .lock-badge{ position:absolute;top:-8px;left:-8px;font-size:11px; background:var(--dark-3);border:1px solid var(--dark-border); border-radius:50%;width:18px;height:18px; display:flex;align-items:center;justify-content:center; } /* 통계 패널 */ #stats-panel h4{color:var(--accent);margin-bottom:8px} #stats-body{line-height:1.7} /* 실행 상태 바 */ #run-status-bar{ cursor:pointer;left:16px;transform:none;bottom:16px; display:none;position:fixed; } #run-status-bar span{white-space:nowrap} #rs-status{color:var(--accent);font-weight:700} #rs-time{color:var(--panel-text-faint)} /* 에이전트 배지 */ .agent-badge{ position:absolute;bottom:-9px;left:10px; font-size:9px;font-weight:700;color:#04100a; padding:1px 6px;border-radius:6px;white-space:nowrap; max-width:110px;overflow:hidden;text-overflow:ellipsis; } .agent-badge.unassigned{ background:transparent;color:var(--panel-text-faint); border:1px dashed var(--dark-border);font-weight:400; } /* 미할당 노드 — 점선 강조 */ #canvas .node:has(.agent-badge.unassigned){border-style:dashed} /* 선택된 에이전트 담당 노드 강조 */ #canvas .node.agent-highlight{ border-color:var(--accent) !important; box-shadow:0 0 0 2px var(--accent-soft), 0 0 14px var(--accent-glow) !important; } /* 에이전트 패널 */ #agents-panel h4{color:var(--accent);margin-bottom:8px} .agent-item:hover{border-color:var(--accent-strong) !important} /* 드래그 고스트 — 원본 반투명 */ #canvas .node.drag-ghost{opacity:.4;border-style:dashed} /* 착지 바운스 */ #canvas .node.drop-bounce{animation:dropBounce .3s ease} @keyframes dropBounce{0%{transform:translateY(-4px) scale(1.03)}60%{transform:translateY(1px)}100%{transform:translateY(0)}} /* 엣지 연결 상태 */ #edges path.edge-flash, #edges line.edge-flash{stroke:var(--accent) !important;stroke-width:5px !important;filter:drop-shadow(0 0 6px var(--accent-glow));transition:stroke .3s} #edges path.edge-flash[marker-end]{animation:arrowPulse .8s ease 2} #edges path.edge-flow{stroke-dasharray:10 8;animation:edgeFlow .6s linear infinite} @keyframes edgeFlow{to{stroke-dashoffset:-18}} @keyframes arrowPulse{0%,100%{filter:drop-shadow(0 0 2px var(--accent))}50%{filter:drop-shadow(0 0 10px var(--accent))}} #canvas .node .edge-ok{position:absolute;bottom:-9px;left:50%;transform:translateX(-50%);font-size:9px;font-weight:700;color:var(--accent);background:rgba(0,255,135,.12);border:1px solid rgba(0,255,135,.3);border-radius:10px;padding:1px 6px;white-space:nowrap;z-index:6} #canvas .node .edge-warn{position:absolute;bottom:-9px;left:50%;transform:translateX(-50%);font-size:9px;font-weight:700;color:var(--yellow);background:rgba(210,153,34,.12);border:1px solid rgba(210,153,34,.3);border-radius:10px;padding:1px 6px;white-space:nowrap;z-index:6} /* 신뢰도 배지 */ .conf-badge{ position:absolute;top:-9px;right:10px; font-size:9px;font-weight:700; background:var(--dark-3);border:1px solid var(--dark-border); padding:1px 6px;border-radius:6px; } /* 파이프라인 상태 배지 */ .pipe-badge{ display:inline-block;margin-left:4px;font-size:10px; } .pipe-badge.done{color:var(--accent)} .pipe-badge.blocked{color:#ff5d5d} .pipe-badge.running{color:#d29922;animation:pulse 1s infinite} .pipe-badge.idle{color:var(--panel-text-faint)} @keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}} /* 작업 상태 배지 */ .node-status-pill{display:inline-block;padding:2px 8px;border-radius:10px;font-size:10px;font-weight:700;cursor:pointer;margin-left:4px;border:1px solid;user-select:none} .node-status-pill.s-waiting{color:#9aa7b5;border-color:#5a6470;background:rgba(90,100,112,.15)} .node-status-pill.s-working{color:#4da3ff;border-color:#4da3ff;background:rgba(77,163,255,.12)} .node-status-pill.s-review{color:#ffc24d;border-color:#ffc24d;background:rgba(255,194,77,.12)} .node-status-pill.s-done{color:#00ff87;border-color:#00ff87;background:rgba(0,255,135,.12)} .node-status-pill.s-blocked{color:#ff5d5d;border-color:#ff5d5d;background:rgba(255,93,93,.12)} .fb-btn:hover{background:var(--dark-3);color:var(--accent)} .status-badge{ position:absolute;bottom:-9px;right:10px; font-size:9px;font-weight:600; background:var(--dark-3);border:1px solid var(--dark-border); padding:1px 6px;border-radius:6px; } /* 인계 메시지 */ .handoff-msg{ display:block;font-size:9px;color:var(--panel-text-dim); margin-top:2px;max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; } /* 블로커 배지 */ .blocker-badge{ display:block;font-size:9px;color:#ff5d5d;font-weight:700; margin-top:2px; } /* 블로커 노드 강조 */ #canvas .node:has(.blocker-badge){border-color:#ff5d5d !important} }
에이전트 - 에 대한 새 API 키를 발급합니다.