diff --git a/frontend/src/pages/agents/index.vue b/frontend/src/pages/agents/index.vue index f0a3600..ea7ee79 100644 --- a/frontend/src/pages/agents/index.vue +++ b/frontend/src/pages/agents/index.vue @@ -1,22 +1,27 @@ @@ -643,46 +714,35 @@ onUnmounted(() => { height: 100%; display: flex; flex-direction: column; - overflow: auto; + overflow: hidden; position: relative; - background: - radial-gradient(circle at top, rgba(0, 245, 212, 0.07), transparent 34%), - linear-gradient(180deg, #03050a 0%, #07101a 35%, #03050a 100%); + background: var(--bg-void); } -.bg-grid, -.bg-glow, -.bg-circuit, +.bg-grid { + position: absolute; + inset: 0; + background-image: + linear-gradient(rgba(0,245,212,0.04) 1px, transparent 1px), + linear-gradient(90deg, rgba(0,245,212,0.04) 1px, transparent 1px); + background-size: 40px 40px; + pointer-events: none; + z-index: 0; +} +.bg-glow { + position: absolute; + inset: 0; + background: radial-gradient(ellipse 80% 60% at 50% 40%, rgba(0,245,212,0.05) 0%, transparent 70%); + pointer-events: none; + z-index: 0; +} .bg-particles { position: absolute; inset: 0; pointer-events: none; + z-index: 0; + overflow: hidden; } - -.bg-grid { - background-image: - linear-gradient(rgba(0, 245, 212, 0.04) 1px, transparent 1px), - linear-gradient(90deg, rgba(0, 245, 212, 0.04) 1px, transparent 1px); - background-size: 40px 40px; -} - -.bg-glow { - background: - radial-gradient(circle at 20% 20%, rgba(0, 245, 212, 0.08), transparent 26%), - radial-gradient(circle at 80% 14%, rgba(123, 44, 191, 0.08), transparent 22%), - radial-gradient(circle at 50% 70%, rgba(0, 245, 212, 0.05), transparent 30%); -} - -.bg-circuit { - opacity: 0.5; - background-image: - linear-gradient(90deg, transparent 12%, rgba(0, 245, 212, 0.08) 12%, rgba(0, 245, 212, 0.08) 12.4%, transparent 12.4%), - linear-gradient(transparent 20%, rgba(0, 245, 212, 0.06) 20%, rgba(0, 245, 212, 0.06) 20.5%, transparent 20.5%), - radial-gradient(circle at 12% 20%, rgba(0, 245, 212, 0.25) 0 2px, transparent 3px), - radial-gradient(circle at 88% 36%, rgba(0, 245, 212, 0.22) 0 2px, transparent 3px), - radial-gradient(circle at 58% 68%, rgba(0, 245, 212, 0.18) 0 2px, transparent 3px); -} - .bg-particle { position: absolute; border-radius: 50%; @@ -690,1168 +750,378 @@ onUnmounted(() => { box-shadow: 0 0 4px rgba(0,245,212,0.6), 0 0 8px rgba(0,245,212,0.2); animation: star-twinkle var(--d, 4s) ease-in-out infinite var(--delay, 0s); } - @keyframes star-twinkle { 0%, 100% { opacity: var(--o, 0.4); transform: scale(1); } - 50% { opacity: calc(var(--o, 0.4) * 0.3); transform: scale(0.45); } + 50% { opacity: calc(var(--o, 0.4) * 0.3); transform: scale(0.5); } } +/* Header */ .view-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 24px; border-bottom: 1px solid var(--border-dim); - position: sticky; - top: 0; + position: relative; z-index: 10; - background: rgba(5,8,16,0.72); + background: rgba(5,8,16,0.6); backdrop-filter: blur(8px); } - -.header-title { - font-family: var(--font-display); - font-size: 13px; - letter-spacing: 0.2em; - color: var(--text-primary); -} - -.title-bracket { - color: var(--accent-cyan); - opacity: 0.6; -} - -.header-actions { - display: flex; - align-items: center; - gap: 12px; -} +.header-title { font-family: var(--font-display); font-size: 13px; letter-spacing: 0.2em; color: var(--text-primary); } +.title-bracket { color: var(--accent-cyan); opacity: 0.6; } +.header-actions { display: flex; align-items: center; gap: 12px; } .btn-icon { - width: 32px; - height: 32px; - border-radius: 10px; - border: 1px solid var(--border-dim); - background: rgba(255,255,255,0.02); - color: var(--accent-cyan); - display: inline-flex; - align-items: center; - justify-content: center; + width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; + background: var(--bg-card); border: 1px solid var(--border-mid); border-radius: var(--radius-sm); + color: var(--text-secondary); cursor: pointer; transition: all var(--transition-fast); +} +.btn-icon:hover { border-color: var(--accent-cyan); color: var(--accent-cyan); box-shadow: var(--glow-cyan); } +.btn-icon.spinning svg { animation: spin 0.8s linear infinite; } +@keyframes spin { to { transform: rotate(360deg); } } + +.btn-add { + display: flex; align-items: center; gap: 6px; padding: 6px 14px; + background: rgba(0,245,212,0.08); border: 1px solid rgba(0,245,212,0.3); + border-radius: var(--radius-sm); color: var(--accent-cyan); font-family: var(--font-mono); + font-size: 11px; letter-spacing: 0.1em; cursor: pointer; transition: all var(--transition-fast); +} +.btn-add:hover { background: rgba(0,245,212,0.15); border-color: var(--accent-cyan); box-shadow: var(--glow-cyan); } + +.status-bar { display: flex; align-items: center; gap: 6px; font-size: 10px; color: var(--text-dim); letter-spacing: 0.1em; } +.status-dot { width: 6px; height: 6px; border-radius: 50%; } +.status-dot.connected { background: var(--accent-cyan); box-shadow: 0 0 6px var(--accent-cyan); animation: status-pulse-soft 2.6s ease-in-out infinite; } +.status-dot.disconnected { background: var(--text-dim); } +@keyframes status-pulse-soft { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.55; transform: scale(0.82); } } -.btn-icon.spinning svg { - animation: spin 1s linear infinite; +/* Canvas */ +.nodes-canvas { + flex: 1; + position: relative; + overflow: hidden; + isolation: isolate; + cursor: grab; } - -@keyframes spin { - to { transform: rotate(360deg); } +.nodes-canvas.panning { + cursor: grabbing; + user-select: none; } - -.status-bar { +.canvas-controls { + position: absolute; + right: 20px; + bottom: 18px; + z-index: 12; display: flex; align-items: center; gap: 8px; - padding: 8px 12px; - border: 1px solid var(--border-dim); - border-radius: 999px; - background: rgba(255,255,255,0.02); -} - -.status-dot { - width: 8px; - height: 8px; - border-radius: 999px; - box-shadow: 0 0 8px currentColor; -} - -.status-dot.connected { - background: var(--accent-green); - color: var(--accent-green); -} - -.status-dot.disconnected { - background: var(--accent-amber); - color: var(--accent-amber); -} - -.status-label { - font-size: 11px; - color: var(--text-secondary); - letter-spacing: 0.08em; -} - -.command-stage { - position: relative; - z-index: 1; - padding: 18px 20px 22px; -} - -.board-shell { - position: relative; - overflow: hidden; - padding: 18px 18px 20px; - border-radius: 24px; - border: 1px solid rgba(0, 245, 212, 0.12); - background: - linear-gradient(180deg, rgba(8, 14, 24, 0.95), rgba(3, 8, 16, 0.96)), - linear-gradient(135deg, rgba(0, 245, 212, 0.03), transparent 35%); - box-shadow: inset 0 1px 0 rgba(255,255,255,0.04), 0 24px 60px rgba(0,0,0,0.32), 0 0 24px rgba(0,245,212,0.05); -} - -.board-shell::before, -.board-shell::after { - content: ''; - position: absolute; - inset: 14px; - border: 1px solid rgba(0, 245, 212, 0.07); + padding: 8px; + border: 1px solid rgba(0,245,212,0.12); border-radius: 22px; - pointer-events: none; + background: linear-gradient(180deg, rgba(8, 13, 22, 0.92), rgba(5, 9, 18, 0.86)); + backdrop-filter: blur(14px); + box-shadow: 0 16px 36px rgba(0, 0, 0, 0.32), inset 0 1px 0 rgba(255,255,255,0.04); } - -.board-shell::after { - inset: auto 28px 28px auto; - width: 88px; - height: 88px; - border-radius: 50%; - filter: blur(12px); - background: radial-gradient(circle, rgba(0, 245, 212, 0.16), transparent 70%); - border: none; -} - -.board-trace { - position: absolute; - background: linear-gradient(90deg, transparent, rgba(0,245,212,0.12), transparent); - opacity: 0.6; -} - -.trace-1 { top: 96px; left: 10%; width: 22%; height: 1px; } -.trace-2 { top: 240px; right: 8%; width: 18%; height: 1px; } -.trace-3 { bottom: 120px; left: 6%; width: 16%; height: 1px; } - -.topology-stage { - display: flex; - flex-direction: column; - gap: 18px; -} - -.stage-caption { - display: inline-flex; - align-items: baseline; - gap: 10px; - margin: 0 auto 12px; - padding: 8px 14px; - border-radius: 999px; +.control-chip { + height: 36px; border: 1px solid rgba(0,245,212,0.12); - background: linear-gradient(90deg, rgba(3,8,16,0.78), rgba(7,14,24,0.9)); - box-shadow: 0 0 18px rgba(0,245,212,0.06); -} - -.stage-caption-kicker { - font-size: 10px; - letter-spacing: 0.22em; - text-transform: uppercase; - color: var(--accent-cyan); -} - -.stage-caption-title { - font-size: 12px; - letter-spacing: 0.12em; + background: rgba(9, 16, 28, 0.9); color: var(--text-secondary); -} - -.bus-caption { - margin-bottom: 18px; -} - -.topology-core-lane { - display: block; -} - -.master-chip-shell { - min-height: 0; - background: - linear-gradient(180deg, rgba(9,15,28,0.2), transparent 28%), - radial-gradient(circle at top center, rgba(0,245,212,0.08), transparent 40%); -} - -.topology-master { - justify-self: center; - width: min(720px, 100%); - margin: 0 auto; -} - -.topology-master::before, -.topology-master::after { - content: ''; - position: absolute; - pointer-events: none; -} - -.topology-master::before { - inset: -10px 6%; - border-radius: 32px; - border: 1px solid rgba(0,245,212,0.08); - opacity: 0.8; -} - -.topology-master::after { - inset: auto 12% -14px 12%; - height: 24px; - border-radius: 999px; - background: radial-gradient(circle, rgba(0,245,212,0.24), transparent 72%); - filter: blur(10px); -} - -.embedded-commander-skills { - position: relative; - margin-top: 8px; - padding: 12px; - border-radius: 16px; - border: 1px solid rgba(0,245,212,0.12); - background: - linear-gradient(180deg, rgba(8,14,24,0.68), rgba(4,8,16,0.88)), - repeating-linear-gradient(90deg, rgba(0,245,212,0.03) 0 1px, transparent 1px 18px); - box-shadow: inset 0 1px 0 rgba(255,255,255,0.03), 0 0 18px rgba(0,245,212,0.05); -} - -.embedded-commander-skills::before { - content: ''; - position: absolute; - left: 16px; - right: 16px; - top: 0; - height: 1px; - background: linear-gradient(90deg, transparent, rgba(0,245,212,0.55), transparent); -} - -.embedded-skills-header { - margin-bottom: 10px; -} - -.embedded-skills-grid { - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 8px; - margin-top: 0; -} - -.embedded-skill-chip { - min-height: 84px; - padding: 10px; - background: linear-gradient(180deg, rgba(10,16,28,0.92), rgba(6,10,18,0.98)); -} - -.embedded-skill-chip .skill-title { - font-size: 12px; -} - -.embedded-skill-chip .skill-description { - font-size: 10px; - line-height: 1.45; -} - -.topology-trunk { - position: relative; - width: 4px; - height: 70px; - margin: -4px auto 0; - border-radius: 999px; - background: linear-gradient(180deg, rgba(0,245,212,0.15), rgba(0,245,212,0.7), rgba(0,245,212,0.12)); - box-shadow: 0 0 16px rgba(0,245,212,0.12); -} - -.main-grid-shell { - position: relative; - padding: 20px 18px 10px; - border-radius: 24px; - border: 1px solid rgba(0,245,212,0.08); - background: - linear-gradient(180deg, rgba(4,9,18,0.84), rgba(3,7,14,0.95)), - radial-gradient(circle at top center, rgba(0,245,212,0.08), transparent 42%); - box-shadow: inset 0 1px 0 rgba(255,255,255,0.03), 0 20px 44px rgba(0,0,0,0.22); -} - -.main-grid-shell::before, -.main-grid-shell::after { - content: ''; - position: absolute; - pointer-events: none; -} - -.main-grid-shell::before { - inset: 12px; - border-radius: 20px; - border: 1px solid rgba(0,245,212,0.06); -} - -.main-grid-shell::after { - left: 24px; - right: 24px; - top: 62px; - height: 1px; - background: linear-gradient(90deg, transparent, rgba(0,245,212,0.3), transparent); -} - -.topology-trunk::before, -.topology-trunk::after, -.topology-drop::before, -.topology-drop::after, -.topology-sub-link .sub-link-line::before, -.topology-sub-link .sub-link-line::after { - content: ''; - position: absolute; - inset: 0; - pointer-events: none; -} - -.topology-trunk-joint { - position: absolute; - left: 50%; - bottom: -8px; - width: 14px; - height: 14px; - transform: translateX(-50%); - border-radius: 50%; - background: rgba(0,245,212,0.78); - box-shadow: 0 0 18px rgba(0,245,212,0.55), 0 0 34px rgba(0,245,212,0.22); -} - -.topology-trunk.energized::before, -.topology-drop.energized::before, -.topology-sub-link.energized .sub-link-line::before { - border-radius: inherit; - background: linear-gradient(180deg, transparent 0%, rgba(255,255,255,0.2) 20%, rgba(130,255,245,0.98) 42%, rgba(0,245,212,1) 50%, rgba(130,255,245,0.98) 58%, rgba(255,255,255,0.14) 78%, transparent 100%); - animation: current-vertical 1.15s linear infinite; -} - -.topology-trunk.energized::after, -.topology-drop.energized::after, -.topology-sub-link.energized .sub-link-line::after { - border-radius: inherit; - background: linear-gradient(180deg, transparent 0%, rgba(0,245,212,0.08) 20%, rgba(0,245,212,0.5) 50%, rgba(0,245,212,0.08) 80%, transparent 100%); - filter: blur(6px); - animation: current-trail-vertical 1.15s linear infinite; -} - -.topology-main-grid { - position: relative; - display: grid; - grid-template-columns: repeat(4, minmax(190px, 1fr)); - gap: 14px; - align-items: start; -} - -.topology-main-grid::after { - content: ''; - position: absolute; - left: 8%; - right: 8%; - top: 10px; - height: 44px; - border: 1px solid rgba(0,245,212,0.06); - border-bottom: none; - border-radius: 20px 20px 0 0; - pointer-events: none; -} - -.topology-main-grid::before { - content: ''; - position: absolute; - left: 12.5%; - right: 12.5%; - top: 10px; - height: 3px; - border-radius: 999px; - background: linear-gradient(90deg, rgba(0,245,212,0.18), rgba(0,245,212,0.68), rgba(0,245,212,0.18)); - box-shadow: 0 0 18px rgba(0,245,212,0.12); -} - -.topology-column { - position: relative; - display: flex; - flex-direction: column; - align-items: stretch; - gap: 10px; -} - -.topology-drop { - position: relative; - width: 3px; - height: 46px; - margin: 0 auto; - border-radius: 999px; - background: linear-gradient(180deg, rgba(0,245,212,0.6), rgba(0,245,212,0.08)); -} - -.topology-drop .link-joint { - position: absolute; - left: 50%; - top: -6px; - transform: translateX(-50%); -} - -.topology-main-chip { - width: 100%; -} - -.topology-link-label { + border-radius: 14px; + display: inline-flex; + align-items: center; justify-content: center; - min-height: 18px; + transition: all 0.18s ease; } - -.topology-link-label.energized .main-link-label { - color: var(--accent-cyan); - text-shadow: 0 0 10px rgba(0,245,212,0.35); -} - -.topology-sub-cluster { - display: grid; - gap: 12px; -} - -.topology-sub-node { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; -} - -.topology-sub-link { - position: relative; - display: flex; - flex-direction: column; - align-items: center; - gap: 6px; -} - -.topology-sub-link .link-joint { - width: 9px; - height: 9px; -} - -.topology-sub-link .sub-link-line { - width: 3px; - min-width: 3px; - min-height: 42px; - height: 42px; - border-radius: 999px; - background: linear-gradient(180deg, rgba(0,245,212,0.6), rgba(0,245,212,0.08)); -} - -.topology-sub-link .sub-link-label { - text-align: center; - white-space: normal; -} - -.topology-skills-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); -} - -.chip-card { - position: relative; - border-radius: 20px; - border: 1px solid rgba(0, 245, 212, 0.16); - background: - linear-gradient(180deg, rgba(9, 14, 26, 0.95), rgba(5, 9, 16, 0.98)), - linear-gradient(135deg, rgba(255,255,255,0.02), transparent 55%); - overflow: hidden; - transition: transform var(--transition-mid), border-color var(--transition-mid), box-shadow var(--transition-mid); -} - -.chip-card:hover { - transform: translateY(-2px); - border-color: rgba(0, 245, 212, 0.28); - box-shadow: 0 14px 34px rgba(0,0,0,0.24), 0 0 18px rgba(0,245,212,0.08); -} - -.chip-card.selected, -.chip-card.energized { - border-color: rgba(0, 245, 212, 0.46); - box-shadow: 0 0 0 1px rgba(0,245,212,0.18) inset, 0 0 24px rgba(0,245,212,0.15); -} - -.chip-card.energized { - box-shadow: - 0 0 0 1px rgba(0,245,212,0.22) inset, - 0 0 18px rgba(0,245,212,0.18), - 0 0 42px rgba(0,245,212,0.16), - 0 0 70px rgba(0,245,212,0.07); -} - -.chip-card.disabled { - opacity: 0.48; - filter: saturate(0.5); -} - -.chip-shell { - position: relative; - min-height: 212px; - padding: 18px; - display: flex; - flex-direction: column; - gap: 10px; -} - -.chip-shell.compact { - min-height: 168px; -} - -.topology-main-chip .chip-shell.compact { - min-height: 182px; - padding-top: 20px; -} - -.chip-pin { - position: absolute; - opacity: 0.45; -} - -.pin-top, -.pin-bottom { - left: 24px; - right: 24px; - height: 8px; - background: repeating-linear-gradient(90deg, rgba(0,245,212,0.2) 0 10px, transparent 10px 18px); -} - -.pin-top { top: 0; } -.pin-bottom { bottom: 0; } - -.pin-left, -.pin-right { - top: 24px; - bottom: 24px; - width: 8px; - background: repeating-linear-gradient(180deg, rgba(0,245,212,0.2) 0 10px, transparent 10px 18px); -} - -.pin-left { left: 0; } -.pin-right { right: 0; } - -.chip-overlay { - position: absolute; - inset: 12px; - border-radius: 18px; - border: 1px solid rgba(0, 245, 212, 0.08); - background: - linear-gradient(135deg, rgba(255,255,255,0.04), transparent 34%), - linear-gradient(180deg, transparent, rgba(0,245,212,0.04)); - pointer-events: none; -} - -.chip-overlay::after { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient(120deg, transparent 10%, rgba(0,245,212,0.15) 45%, transparent 70%); - transform: translateX(-120%); - animation: chip-scan 6s linear infinite; -} - -@keyframes chip-scan { - to { transform: translateX(120%); } -} - -@keyframes node-flicker { - 0%, 100% { - transform: scale(1); - opacity: 0.92; - } - 50% { - transform: scale(1.22); - opacity: 1; - } -} - -.chip-status-strip, -.chip-title-row, -.chip-footer, -.skills-header, -.skill-chip-top, -.sub-node-topline, -.sub-footer, -.drawer-header, -.toggle-row, -.drawer-actions { - display: flex; - align-items: center; - justify-content: space-between; - gap: 10px; -} - -.chip-state-dot, -.sub-status-dot { - width: 8px; - height: 8px; - border-radius: 50%; - background: currentColor; - box-shadow: 0 0 10px currentColor; -} - -.chip-state-dot.active, -.sub-node.active .sub-status-dot { color: var(--accent-green); } -.chip-state-dot.idle, -.sub-node.idle .sub-status-dot { color: var(--accent-cyan); } -.chip-state-dot.disabled, -.sub-node.disabled .sub-status-dot { color: var(--text-dim); } - -.chip-state-label, -.skills-eyebrow, -.skill-label, -.sub-name, -.drawer-title { - font-family: var(--font-display); - letter-spacing: 0.16em; -} - -.chip-state-label, -.skills-eyebrow, -.skill-label { - font-size: 11px; - color: var(--accent-cyan); -} - -.chip-code, -.runtime-tag, -.skills-badge, -.skill-state, -.main-link-label, -.sub-link-label, -.sub-badge, -.node-task-tag, -.node-idle, -.toggle-count { - font-size: 10px; - letter-spacing: 0.12em; - text-transform: uppercase; -} - -.chip-code { - color: var(--text-dim); -} - -.chip-name, -.skills-title, -.skill-title { - color: var(--text-primary); - font-weight: 700; -} - -.chip-name { - font-size: 22px; - letter-spacing: 0.08em; -} - -.skills-title { - font-size: 16px; -} - -.chip-role, -.skill-state, -.sub-role { - color: var(--accent-purple); -} - -.chip-desc, -.skill-description, -.sub-desc { - color: var(--text-secondary); - line-height: 1.65; -} - -.runtime-tag, -.skills-badge, -.skill-state, -.sub-badge, -.node-task-tag, -.node-idle, -.toggle-count { - padding: 4px 8px; - border-radius: 999px; -} - -.runtime-tag, -.skills-badge, -.node-task-tag { - background: rgba(0,245,212,0.1); - color: var(--accent-cyan); -} - -.node-idle { - background: rgba(255,255,255,0.04); - color: var(--text-dim); -} - -.node-stat { - display: inline-flex; - align-items: center; - gap: 6px; - padding: 4px 8px; - border-radius: 999px; - background: rgba(255,255,255,0.04); - color: var(--text-secondary); - font-size: 11px; -} - -.stat-label { color: var(--text-dim); } -.stat-val { color: var(--accent-cyan); } - -.route-telemetry { - position: relative; - padding: 12px 14px; - border-radius: 16px; - border: 1px solid rgba(0,245,212,0.14); - background: - linear-gradient(180deg, rgba(7,12,22,0.92), rgba(4,8,16,0.98)), - radial-gradient(circle at left center, rgba(0,245,212,0.08), transparent 45%); - box-shadow: inset 0 1px 0 rgba(255,255,255,0.03), 0 0 18px rgba(0,245,212,0.06); -} - -.route-telemetry::before { - content: ''; - position: absolute; - inset: 0; - border-radius: inherit; - background: linear-gradient(90deg, transparent 0%, rgba(0,245,212,0.08) 30%, transparent 70%); - transform: translateX(-100%); - animation: telemetry-scan 4s linear infinite; - pointer-events: none; -} - -.route-telemetry-header, -.route-telemetry-path { - display: flex; - align-items: center; - gap: 8px; - flex-wrap: wrap; -} - -.route-telemetry-header { - justify-content: space-between; - margin-bottom: 8px; -} - -.route-telemetry-label, -.route-telemetry-state { - font-size: 10px; - letter-spacing: 0.16em; - text-transform: uppercase; -} - -.route-telemetry-label { - color: var(--text-dim); -} - -.route-telemetry-state { - padding: 4px 8px; - border-radius: 999px; - color: var(--accent-cyan); - background: rgba(0,245,212,0.1); -} - -.route-segment { - position: relative; - display: inline-flex; - align-items: center; - gap: 8px; - padding: 4px 10px; - border-radius: 999px; - border: 1px solid rgba(0,245,212,0.12); - background: rgba(255,255,255,0.03); - color: var(--text-primary); - font-size: 11px; - letter-spacing: 0.12em; - text-transform: uppercase; -} - -.route-segment:not(:last-child)::after { - content: '→'; - position: relative; - right: -4px; - color: rgba(0,245,212,0.72); -} - -@keyframes telemetry-scan { - to { transform: translateX(100%); } -} - -.commander-skills { - padding: 18px; - border-radius: 24px; - border: 1px solid rgba(0, 245, 212, 0.12); - background: linear-gradient(180deg, rgba(8, 14, 24, 0.9), rgba(4, 8, 16, 0.96)); -} - -.skills-grid { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 12px; - margin-top: 16px; -} - -.skill-chip { - position: relative; - min-height: 118px; - border-radius: 18px; - border: 1px solid rgba(0,245,212,0.1); - background: linear-gradient(180deg, rgba(9,16,28,0.9), rgba(6,10,18,0.96)); - padding: 14px; - overflow: hidden; -} - -.skill-chip::before, -.main-link-line::before, -.sub-link-line::before, -.bus-spine::before { - content: ''; - position: absolute; - inset: 0; - pointer-events: none; -} - -.skill-chip::before { - background: linear-gradient(120deg, transparent 0%, rgba(0,245,212,0.08) 45%, transparent 65%); - transform: translateX(-140%); -} - -.skill-chip.active { - border-color: rgba(0,245,212,0.4); - box-shadow: 0 0 22px rgba(0,245,212,0.12), inset 0 0 0 1px rgba(0,245,212,0.12); -} - -.skill-chip.active::before { - animation: skill-sweep 2.8s linear infinite; -} - -@keyframes skill-sweep { - to { transform: translateX(140%); } -} - - -.link-joint { - width: 8px; - height: 8px; - min-width: 8px; - border-radius: 50%; - background: rgba(0,245,212,0.65); - box-shadow: 0 0 10px rgba(0,245,212,0.35); -} - -.pcb-link.energized .link-joint { - background: #9ffef4; - box-shadow: 0 0 12px rgba(159,254,244,0.9), 0 0 24px rgba(0,245,212,0.55), 0 0 40px rgba(0,245,212,0.28); - animation: node-flicker 0.9s ease-in-out infinite; -} - -.main-link-line, -.sub-link-line { - position: relative; - flex: 1; - overflow: hidden; -} - -.main-link-line { - height: 3px; - border-radius: 999px; - background: linear-gradient(90deg, rgba(0,245,212,0.6), rgba(0,245,212,0.08)); -} - -.sub-link-line { - width: 3px; - min-width: 3px; - min-height: 34px; - background: linear-gradient(180deg, rgba(0,245,212,0.6), rgba(0,245,212,0.08)); -} - -.main-link-label, -.sub-link-label { - color: var(--text-dim); - white-space: nowrap; -} - -.agent-chip .chip-name { - font-size: 22px; -} - -.compact-footer { - margin-top: auto; - align-items: flex-start; - flex-wrap: wrap; -} - -.cluster-toggle { - display: flex; - align-items: center; - justify-content: space-between; - gap: 10px; - width: 100%; - border: 1px solid rgba(0,245,212,0.12); - border-radius: 12px; - padding: 10px 12px; - background: rgba(5,10,18,0.72); - color: var(--text-secondary); - font-size: 11px; - letter-spacing: 0.08em; -} - -.toggle-count { - background: rgba(0,245,212,0.08); - color: var(--accent-cyan); -} - -.sub-cluster { - display: grid; - gap: 12px; -} - -.sub-node { - display: flex; - gap: 10px; - align-items: stretch; -} - -.sub-node-card { - flex: 1; - border-radius: 16px; - border: 1px solid rgba(0,245,212,0.1); - background: rgba(10,14,24,0.9); - padding: 12px; - display: flex; - flex-direction: column; - gap: 8px; -} - -.sub-node-card.energized, -.sub-node.active .sub-node-card { +.control-chip:hover { border-color: rgba(0,245,212,0.3); - box-shadow: 0 0 18px rgba(0,245,212,0.1); + color: var(--accent-cyan); + box-shadow: 0 0 18px rgba(0,245,212,0.08); } - -.sub-node.disabled .sub-node-card { +.zoom-chip { + width: 36px; + flex-shrink: 0; +} +.chip-symbol { + font-family: var(--font-display); + font-size: 18px; + line-height: 1; +} +.zoom-readout { + min-width: 72px; + padding: 0 14px; +} +.chip-value { + font-family: var(--font-display); + font-size: 11px; + letter-spacing: 0.08em; + color: var(--text-primary); +} +.nodes-viewport { + position: absolute; + inset: 0; + z-index: 1; + will-change: transform; +} +.nodes-stage { + position: absolute; + inset: 0; + will-change: auto; +} +.canvas-aura, +.canvas-scan { + position: absolute; + inset: 0; + pointer-events: none; + z-index: 0; +} +.canvas-aura { + background: + radial-gradient(circle at 50% 18%, rgba(0,245,212,0.1) 0%, rgba(0,245,212,0.05) 20%, transparent 46%), + radial-gradient(circle at 50% 62%, rgba(0,245,212,0.035) 0%, transparent 54%); + filter: blur(12px); + opacity: 0.72; +} +.canvas-scan { + inset: -20% 0; + background: linear-gradient(180deg, transparent 0%, rgba(0,245,212,0.018) 42%, rgba(0,245,212,0.045) 50%, rgba(0,245,212,0.018) 58%, transparent 100%); + animation: canvas-scan 11s linear infinite; opacity: 0.5; } - -.sub-name { color: var(--accent-cyan); font-size: 11px; } -.sub-badge { background: rgba(123, 44, 191, 0.14); color: var(--accent-purple); } -.sub-role { font-size: 12px; font-weight: 600; } -.sub-footer { font-size: 11px; color: var(--text-dim); margin-top: auto; justify-content: flex-start; } - -.cluster-fade-enter-active, -.cluster-fade-leave-active { - transition: opacity 0.22s ease, transform 0.22s ease; +@keyframes canvas-scan { + from { transform: translateY(-18%); } + to { transform: translateY(18%); } } - -.cluster-fade-enter-from, -.cluster-fade-leave-to { - opacity: 0; - transform: translateY(-8px); -} - -.config-drawer { - position: fixed; - top: 0; - right: 0; - width: min(420px, 100%); - height: 100%; - background: linear-gradient(180deg, rgba(9, 13, 23, 0.98), rgba(5, 8, 16, 0.98)); - border-left: 1px solid rgba(0,245,212,0.14); - z-index: 30; - display: flex; - flex-direction: column; -} - -.drawer-header { - padding: 18px 18px 14px; - border-bottom: 1px solid var(--border-dim); -} - -.drawer-title { - font-size: 12px; - color: var(--accent-cyan); -} - -.btn-close { - width: 32px; - height: 32px; - border-radius: 10px; - border: 1px solid var(--border-dim); - background: transparent; - color: var(--text-secondary); - display: inline-flex; - align-items: center; - justify-content: center; -} - -.drawer-body { - padding: 18px; - display: flex; - flex-direction: column; - gap: 14px; - min-height: 0; - flex: 1; -} - -.form-group { - display: flex; - flex-direction: column; - gap: 8px; -} - -.flex-1 { - flex: 1; -} - -.form-label { - font-size: 11px; - letter-spacing: 0.12em; - color: var(--text-dim); -} - -.form-input, -.form-textarea { - width: 100%; - border-radius: 12px; - border: 1px solid var(--border-dim); - background: rgba(255,255,255,0.03); - color: var(--text-primary); - padding: 10px 12px; -} - -.code-textarea { - font-family: var(--font-mono); -} - -.toggle-label { - font-size: 11px; - color: var(--text-secondary); -} - -.toggle-label.dim { - opacity: 0.45; -} - -.toggle-btn { - width: 50px; - height: 28px; - border-radius: 999px; - border: 1px solid var(--border-dim); - background: rgba(255,255,255,0.04); - position: relative; -} - -.toggle-btn.active { - background: rgba(0,245,212,0.12); - border-color: rgba(0,245,212,0.2); -} - -.toggle-knob { +.conn-svg { position: absolute; - top: 3px; - left: 3px; - width: 20px; - height: 20px; - border-radius: 999px; - background: var(--text-primary); - transition: transform 0.2s ease; -} - -.toggle-btn.active .toggle-knob { - transform: translateX(22px); - background: var(--accent-cyan); -} - -.btn-secondary, -.btn-primary { - border-radius: 12px; - padding: 10px 14px; - border: 1px solid var(--border-dim); -} - -.btn-secondary { - background: rgba(255,255,255,0.03); - color: var(--text-secondary); -} - -.btn-primary { - background: rgba(0,245,212,0.12); - border-color: rgba(0,245,212,0.24); - color: var(--accent-cyan); -} - -.btn-loader { - display: inline-block; - width: 10px; - height: 10px; - border-radius: 999px; - border: 2px solid currentColor; - border-right-color: transparent; - animation: spin 0.9s linear infinite; - margin-right: 6px; -} - -.drawer-backdrop { - position: fixed; inset: 0; - background: rgba(0,0,0,0.45); - z-index: 20; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; + overflow: visible; +} +.conn-path { + fill: none; + stroke: rgba(0,245,212,0.22); + stroke-width: 1.5; + stroke-dasharray: 5 7; + stroke-linecap: round; + filter: drop-shadow(0 0 6px rgba(0,245,212,0.06)); + animation: dash-flow 5.5s linear infinite; +} +@keyframes dash-flow { to { stroke-dashoffset: -48; } } +.conn-path.active { + stroke: color-mix(in srgb, var(--accent-cyan) 68%, var(--accent-amber) 32%); + stroke-opacity: 0.72; + stroke-width: 1.9; + stroke-dasharray: none; + filter: url(#lineGlow) drop-shadow(0 0 8px rgba(0,245,212,0.16)); + animation: line-flare 1.8s ease-in-out infinite alternate; +} +@keyframes line-flare { + from { stroke-opacity: 0.42; } + to { stroke-opacity: 0.78; } +} +.pulse-dot { fill: var(--accent-amber); filter: drop-shadow(0 0 8px var(--accent-amber)); } + +/* Node Cards */ +.node-card { + position: absolute; + z-index: 2; + cursor: pointer; + transition: transform 0.22s ease; +} +.node-sub.disabled { opacity: 0.35; cursor: not-allowed; } + +.node-inner { + width: 100%; + height: 100%; + background: rgba(13,21,37,0.92); + border: 1px solid rgba(0,245,212,0.2); + border-radius: var(--radius-md); + padding: var(--node-padding-y, 14px) var(--node-padding-x, 16px); + display: flex; + flex-direction: column; + gap: calc(3px * var(--node-scale, 1)); + position: relative; + overflow: hidden; + backdrop-filter: blur(12px); + transition: border-color 0.2s, box-shadow 0.2s, background 0.25s ease; +} +.node-inner::before { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient(115deg, transparent 20%, rgba(255,255,255,0.045) 32%, transparent 44%); + transform: translateX(-150%); + opacity: 0; + pointer-events: none; +} +.node-master .node-inner::after { + content: ''; + position: absolute; + inset: -18%; + background: radial-gradient(circle, rgba(0,245,212,0.1) 0%, rgba(0,245,212,0.045) 28%, transparent 62%); + opacity: 0.72; + animation: core-breathe 5.6s ease-in-out infinite; + pointer-events: none; +} +.node-master .node-inner { + background: linear-gradient(135deg, rgba(0,245,212,0.06) 0%, rgba(13,21,37,0.95) 100%); + border-color: rgba(0,245,212,0.3); +} +.node-card:hover .node-inner { + border-color: rgba(0,245,212,0.42); + box-shadow: 0 8px 28px rgba(0,245,212,0.11), 0 0 0 1px rgba(0,245,212,0.08); +} +.node-card:hover .node-inner::before { + opacity: 0.9; + animation: node-sheen 1.45s ease; +} +.node-card.selected .node-inner { + border-color: var(--accent-cyan); + box-shadow: 0 0 0 1px rgba(0,245,212,0.26), 0 0 18px rgba(0,245,212,0.14); +} +@keyframes node-sheen { + 0% { transform: translateX(-150%); } + 100% { transform: translateX(150%); } +} +@keyframes core-breathe { + 0%, 100% { opacity: 0.46; transform: scale(0.98); } + 50% { opacity: 0.8; transform: scale(1.01); } } -@media (max-width: 1400px) { - .command-stage { padding: 20px 18px 28px; } - .topology-main-grid { - grid-template-columns: repeat(2, minmax(240px, 1fr)); - } +.node-corner { position: absolute; width: var(--node-corner-size, 10px); height: var(--node-corner-size, 10px); opacity: 0.6; } +.node-corner.tl { top: calc(6px * var(--node-scale, 1)); left: calc(6px * var(--node-scale, 1)); border-top: calc(1.5px * var(--node-scale, 1)) solid var(--accent-cyan); border-left: calc(1.5px * var(--node-scale, 1)) solid var(--accent-cyan); } +.node-corner.tr { top: calc(6px * var(--node-scale, 1)); right: calc(6px * var(--node-scale, 1)); border-top: calc(1.5px * var(--node-scale, 1)) solid var(--accent-cyan); border-right: calc(1.5px * var(--node-scale, 1)) solid var(--accent-cyan); } +.node-corner.bl { bottom: calc(6px * var(--node-scale, 1)); left: calc(6px * var(--node-scale, 1)); border-bottom: calc(1.5px * var(--node-scale, 1)) solid var(--accent-cyan); border-left: calc(1.5px * var(--node-scale, 1)) solid var(--accent-cyan); } +.node-corner.br { bottom: calc(6px * var(--node-scale, 1)); right: calc(6px * var(--node-scale, 1)); border-bottom: calc(1.5px * var(--node-scale, 1)) solid var(--accent-cyan); border-right: calc(1.5px * var(--node-scale, 1)) solid var(--accent-cyan); } + +.node-status { position: absolute; top: calc(10px * var(--node-scale, 1)); right: calc(10px * var(--node-scale, 1)); width: var(--node-status-size, 10px); height: var(--node-status-size, 10px); border-radius: 50%; display: flex; align-items: center; justify-content: center; } +.status-ring { width: var(--node-status-ring-size, 8px); height: var(--node-status-ring-size, 8px); border-radius: 50%; } +.node-status.active::before { + content: ''; + position: absolute; + inset: -6px; + border: 1px solid rgba(0,245,212,0.22); + border-radius: 999px; + animation: status-orbit 2.3s ease-out infinite; +} +.node-status.active .status-ring { background: var(--accent-cyan); box-shadow: 0 0 8px var(--accent-cyan); animation: status-pulse 1.8s ease-in-out infinite; } +.node-status.idle .status-ring { background: var(--text-secondary); } +.node-status.disabled .status-ring { background: var(--text-dim); opacity: 0.4; } +@keyframes status-pulse { 0%,100%{opacity:1} 50%{opacity:0.4} } +@keyframes status-orbit { + 0% { transform: scale(0.5); opacity: 0.65; } + 100% { transform: scale(1.3); opacity: 0; } } -@media (max-width: 1100px) { - .embedded-skills-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } +.node-label { font-family: var(--font-display); font-size: calc(8px * var(--node-scale, 1)); letter-spacing: 0.2em; color: var(--text-dim); margin-bottom: 1px; } +.node-master .node-label { color: rgba(0,245,212,0.5); } +.node-name { font-family: var(--font-display); font-size: calc(15px * var(--node-scale, 1)); font-weight: 700; letter-spacing: 0.08em; color: var(--accent-cyan); line-height: 1.2; } +.node-master .node-name { font-size: calc(18px * var(--node-scale, 1)); } +.node-role { font-family: var(--font-mono); font-size: calc(10px * var(--node-scale, 1)); color: var(--accent-amber); letter-spacing: 0.05em; } +.node-desc { + font-family: var(--font-mono); font-size: calc(10px * var(--node-scale, 1)); color: var(--text-secondary); + line-height: 1.5; flex: 1; overflow: hidden; display: -webkit-box; + -webkit-line-clamp: 3; -webkit-box-orient: vertical; text-overflow: ellipsis; +} +.node-footer { display: flex; align-items: center; gap: calc(8px * var(--node-scale, 1)); flex-wrap: wrap; margin-top: 2px; } +.node-stat { display: flex; align-items: center; gap: calc(4px * var(--node-scale, 1)); font-family: var(--font-mono); font-size: calc(9px * var(--node-scale, 1)); } +.stat-label { color: var(--text-dim); } +.stat-val { color: var(--accent-cyan); font-weight: 600; } +.node-task-tag { + font-family: var(--font-mono); font-size: calc(9px * var(--node-scale, 1)); color: var(--accent-amber); + background: rgba(249,168,37,0.08); border: 1px solid rgba(249,168,37,0.18); + border-radius: 3px; padding: calc(1px * var(--node-scale, 1)) calc(6px * var(--node-scale, 1)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: calc(120px * var(--node-scale, 1)); + box-shadow: 0 0 10px rgba(249,168,37,0.05); + animation: task-tag-glow 3.4s ease-in-out infinite; +} +.node-idle { font-family: var(--font-mono); font-size: calc(9px * var(--node-scale, 1)); color: var(--text-dim); font-style: italic; } +.rel-label { + position: absolute; font-family: var(--font-mono); font-size: calc(8px * var(--node-scale, 1)); color: var(--text-dim); + letter-spacing: 0.05em; pointer-events: none; left: 50%; transform: translateX(-50%); + bottom: var(--node-rel-offset, -20px); white-space: nowrap; +} +.particle { position: absolute; border-radius: 50%; background: var(--accent-cyan); pointer-events: none; } + +@keyframes task-tag-glow { + 0%, 100% { box-shadow: 0 0 8px rgba(249,168,37,0.04); } + 50% { box-shadow: 0 0 14px rgba(249,168,37,0.1); } } -@media (max-width: 860px) { - .view-header { - flex-direction: column; - align-items: flex-start; - gap: 12px; - } - - .header-actions { - width: 100%; - justify-content: space-between; - } - - .command-stage { - padding: 16px 14px 26px; - } - - .board-shell { - padding: 16px; - } - - .topology-main-grid, - .embedded-skills-grid { - grid-template-columns: 1fr; - } - - .topology-main-grid::before { - left: 50%; - right: auto; - top: 0; - width: 3px; - height: calc(100% - 12px); - transform: translateX(-50%); - background: linear-gradient(180deg, rgba(0,245,212,0.18), rgba(0,245,212,0.68), rgba(0,245,212,0.18)); - } +/* Drawer */ +.config-drawer { + position: fixed; top: 0; right: 0; width: 420px; height: 100%; + background: rgba(5,8,16,0.97); border-left: 1px solid var(--border-mid); + backdrop-filter: blur(20px); z-index: 100; display: flex; flex-direction: column; + box-shadow: -10px 0 40px rgba(0,0,0,0.5); } - -@media (prefers-reduced-motion: reduce) { - .bg-particle, - .chip-overlay::after, - .skill-chip.active::before, - .bus-spine.energized::before, - .main-link.energized .main-link-line::before, - .sub-link.energized .sub-link-line::before { - animation: none !important; - } +.drawer-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 99; } +.drawer-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--border-dim); } +.drawer-title { font-family: var(--font-display); font-size: 11px; letter-spacing: 0.15em; color: var(--accent-cyan); } +.btn-close { + width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; + background: transparent; border: 1px solid var(--border-dim); border-radius: var(--radius-sm); + color: var(--text-dim); cursor: pointer; transition: all var(--transition-fast); } +.btn-close:hover { border-color: var(--accent-red); color: var(--accent-red); } +.drawer-body { flex: 1; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 16px; } +.drawer-body::-webkit-scrollbar { width: 4px; } +.drawer-body::-webkit-scrollbar-thumb { background: var(--border-mid); border-radius: 2px; } +.form-group { display: flex; flex-direction: column; gap: 6px; } +.form-group.flex-1 { flex: 1; display: flex; flex-direction: column; } +.form-label { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.15em; color: var(--text-dim); } +.form-input { + background: var(--bg-card); border: 1px solid var(--border-mid); border-radius: var(--radius-sm); + padding: 10px 12px; color: var(--text-primary); font-family: var(--font-mono); font-size: 12px; outline: none; + transition: border-color var(--transition-fast); +} +.form-input:focus { border-color: var(--accent-cyan); box-shadow: 0 0 0 1px rgba(0,245,212,.1); } +.form-textarea { + background: var(--bg-card); border: 1px solid var(--border-mid); border-radius: var(--radius-sm); + padding: 10px 12px; color: var(--text-primary); font-family: var(--font-mono); font-size: 11px; + outline: none; resize: none; line-height: 1.5; transition: border-color var(--transition-fast); +} +.form-textarea:focus { border-color: var(--accent-cyan); box-shadow: 0 0 0 1px rgba(0,245,212,.1); } +.code-textarea { font-size: 10px; flex: 1; } +.toggle-row { display: flex; align-items: center; gap: 12px; } +.toggle-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.1em; color: var(--accent-cyan); transition: color .2s; } +.toggle-label.dim { color: var(--text-dim); } +.toggle-btn { width: 44px; height: 22px; background: var(--bg-card); border: 1px solid var(--border-mid); border-radius: 11px; padding: 2px; cursor: pointer; transition: all .25s; } +.toggle-btn.active { background: rgba(0,245,212,.15); border-color: var(--accent-cyan); } +.toggle-knob { display: block; width: 16px; height: 16px; border-radius: 50%; background: var(--text-dim); transition: all .25s; } +.toggle-btn.active .toggle-knob { background: var(--accent-cyan); box-shadow: 0 0 8px var(--accent-cyan); transform: translateX(22px); } +.drawer-actions { display: flex; gap: 12px; padding-top: 8px; } +.btn-secondary,.btn-primary { + flex: 1; padding: 10px 16px; border-radius: var(--radius-sm); font-family: var(--font-mono); + font-size: 11px; letter-spacing: 0.1em; cursor: pointer; transition: all var(--transition-fast); + display: flex; align-items: center; justify-content: center; gap: 6px; +} +.btn-secondary { background: transparent; border: 1px solid var(--border-mid); color: var(--text-secondary); } +.btn-secondary:hover { border-color: var(--accent-cyan); color: var(--accent-cyan); } +.btn-primary { background: rgba(0,245,212,.1); border: 1px solid var(--accent-cyan); color: var(--accent-cyan); } +.btn-primary:hover { background: rgba(0,245,212,.2); box-shadow: var(--glow-cyan); } +.btn-primary:disabled { opacity: 0.4; cursor: not-allowed; } +.btn-loader { width: 12px; height: 12px; border: 1.5px solid transparent; border-top-color: var(--accent-cyan); border-radius: 50%; animation: spin .6s linear infinite; } + +/* Modal */ +.modal-overlay { + position: fixed; inset: 0; background: rgba(0,0,0,.7); backdrop-filter: blur(4px); + z-index: 200; display: flex; align-items: center; justify-content: center; +} +.modal-card { + width: 480px; max-height: 80vh; background: rgba(10,15,26,.98); border: 1px solid var(--border-mid); + border-radius: var(--radius-lg); display: flex; flex-direction: column; + box-shadow: 0 20px 60px rgba(0,0,0,.6), 0 0 0 1px rgba(0,245,212,.05); +} +.modal-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--border-dim); } +.modal-title { font-family: var(--font-display); font-size: 11px; letter-spacing: 0.15em; color: var(--accent-cyan); } +.modal-body { flex: 1; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 14px; } +.modal-body::-webkit-scrollbar { width: 4px; } +.modal-body::-webkit-scrollbar-thumb { background: var(--border-mid); border-radius: 2px; } +.modal-footer { display: flex; gap: 12px; padding: 16px 20px; border-top: 1px solid var(--border-dim); }