Graph node FPS hover tooltip, full names, no native SVG tooltips

Graph editor:
- Floating FPS tooltip on hover over running output_target nodes (300ms delay)
- Shows errors, uptime, and FPS sparkline seeded from server metrics history
- Tooltip positioned below node with fade-in/out animation
- Uses pointerover/pointerout with relatedTarget check to prevent flicker
- Fixed-width tooltip (200px) with monospace values to prevent layout shift
- Node titles show full names (removed truncate), no native SVG <title> tooltips

Documentation:
- Added duration/numeric formatting conventions to contexts/frontend.md
- Added node hover tooltip docs to contexts/graph-editor.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-17 15:45:59 +03:00
parent afd4a3bc05
commit 191c988cf9
8 changed files with 342 additions and 7 deletions
@@ -1172,3 +1172,62 @@ html:has(#tab-graph.active) {
background: var(--border-color);
margin: 4px 0;
}
/* ── Node hover FPS tooltip ── */
.graph-node-tooltip {
position: absolute;
z-index: 50;
background: var(--card-bg);
border: 1px solid var(--border-color);
border-radius: var(--radius-md, 6px);
box-shadow: 0 4px 14px var(--shadow-color, rgba(0,0,0,0.25));
padding: 8px 12px;
pointer-events: none;
font-size: 0.8rem;
width: 200px;
color: var(--text-color);
}
.graph-node-tooltip .gnt-row {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
line-height: 1.6;
}
.graph-node-tooltip .gnt-label {
color: var(--text-muted);
white-space: nowrap;
}
.graph-node-tooltip .gnt-value {
font-variant-numeric: tabular-nums;
font-weight: 500;
text-align: right;
min-width: 72px;
display: inline-block;
font-family: var(--font-mono, 'Consolas', 'Monaco', monospace);
}
.graph-node-tooltip .gnt-fps-row {
margin-top: 4px;
padding: 2px 0;
background: transparent;
}
.graph-node-tooltip.gnt-fade-in {
animation: gntFadeIn 0.15s ease-out forwards;
}
.graph-node-tooltip.gnt-fade-out {
animation: gntFadeOut 0.12s ease-in forwards;
}
@keyframes gntFadeIn {
from { opacity: 0; transform: translateY(-4px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes gntFadeOut {
from { opacity: 1; transform: translateY(0); }
to { opacity: 0; transform: translateY(4px); }
}