- Extended AI context selection to host rows in HostsOverview - Added resourceId prop to StackedMemoryBar for sparkline support - Relocated guest URL editing from GuestRow name click - Added GuestNotes component with URL field in AI sidebar - Refined host routing in AI service backend - Minor animation and styling improvements
262 lines
5.3 KiB
CSS
262 lines
5.3 KiB
CSS
/* Animated Metric Container */
|
|
.metric-container {
|
|
position: relative;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
overflow: visible;
|
|
min-height: 1em;
|
|
}
|
|
|
|
.metric-value {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
position: relative;
|
|
z-index: 2;
|
|
}
|
|
|
|
.metric-ghost {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
z-index: 1;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Ghost sliding UP and fading out (old value when increasing) */
|
|
@keyframes ghostSlideUp {
|
|
0% {
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
filter: blur(0);
|
|
}
|
|
100% {
|
|
transform: translateY(-20px);
|
|
opacity: 0;
|
|
filter: blur(2px);
|
|
}
|
|
}
|
|
|
|
/* Ghost sliding DOWN and fading out (old value when decreasing) */
|
|
@keyframes ghostSlideDown {
|
|
0% {
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
filter: blur(0);
|
|
}
|
|
100% {
|
|
transform: translateY(20px);
|
|
opacity: 0;
|
|
filter: blur(2px);
|
|
}
|
|
}
|
|
|
|
/* New value entering from below (when increasing) */
|
|
@keyframes enterFromBelow {
|
|
0% {
|
|
transform: translateY(15px);
|
|
opacity: 0;
|
|
filter: blur(1px);
|
|
color: rgb(34, 197, 94); /* green-500 */
|
|
}
|
|
50% {
|
|
color: rgb(34, 197, 94);
|
|
}
|
|
100% {
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
filter: blur(0);
|
|
color: inherit;
|
|
}
|
|
}
|
|
|
|
/* New value entering from above (when decreasing) */
|
|
@keyframes enterFromAbove {
|
|
0% {
|
|
transform: translateY(-15px);
|
|
opacity: 0;
|
|
filter: blur(1px);
|
|
color: rgb(239, 68, 68); /* red-500 */
|
|
}
|
|
50% {
|
|
color: rgb(239, 68, 68);
|
|
}
|
|
100% {
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
filter: blur(0);
|
|
color: inherit;
|
|
}
|
|
}
|
|
|
|
/* Apply animations */
|
|
.metric-ghost-up {
|
|
animation: ghostSlideUp 0.4s ease-out forwards;
|
|
color: rgb(156, 163, 175); /* gray-400 */
|
|
}
|
|
|
|
.metric-ghost-down {
|
|
animation: ghostSlideDown 0.4s ease-out forwards;
|
|
color: rgb(156, 163, 175); /* gray-400 */
|
|
}
|
|
|
|
.metric-entering-up {
|
|
animation: enterFromBelow 0.4s ease-out;
|
|
}
|
|
|
|
.metric-entering-down {
|
|
animation: enterFromAbove 0.4s ease-out;
|
|
}
|
|
|
|
/* Dark mode adjustments */
|
|
.dark .metric-ghost-up,
|
|
.dark .metric-ghost-down {
|
|
color: rgb(107, 114, 128); /* gray-500 */
|
|
}
|
|
|
|
.dark .metric-entering-up {
|
|
animation: enterFromBelowDark 0.4s ease-out;
|
|
}
|
|
|
|
.dark .metric-entering-down {
|
|
animation: enterFromAboveDark 0.4s ease-out;
|
|
}
|
|
|
|
@keyframes enterFromBelowDark {
|
|
0% {
|
|
transform: translateY(15px);
|
|
opacity: 0;
|
|
filter: blur(1px);
|
|
color: rgb(74, 222, 128); /* green-400 */
|
|
}
|
|
50% {
|
|
color: rgb(74, 222, 128);
|
|
}
|
|
100% {
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
filter: blur(0);
|
|
color: inherit;
|
|
}
|
|
}
|
|
|
|
@keyframes enterFromAboveDark {
|
|
0% {
|
|
transform: translateY(-15px);
|
|
opacity: 0;
|
|
filter: blur(1px);
|
|
color: rgb(248, 113, 113); /* red-400 */
|
|
}
|
|
50% {
|
|
color: rgb(248, 113, 113);
|
|
}
|
|
100% {
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
filter: blur(0);
|
|
color: inherit;
|
|
}
|
|
}
|
|
|
|
/* Optional: Add a subtle glow during animation */
|
|
.metric-entering-up::before,
|
|
.metric-entering-down::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
width: 150%;
|
|
height: 150%;
|
|
pointer-events: none;
|
|
border-radius: 50%;
|
|
animation: pulseGlow 0.4s ease-out;
|
|
}
|
|
|
|
.metric-entering-up::before {
|
|
background: radial-gradient(circle, rgba(34, 197, 94, 0.3) 0%, transparent 60%);
|
|
}
|
|
|
|
.metric-entering-down::before {
|
|
background: radial-gradient(circle, rgba(239, 68, 68, 0.3) 0%, transparent 60%);
|
|
}
|
|
|
|
@keyframes pulseGlow {
|
|
0% {
|
|
opacity: 0;
|
|
transform: translate(-50%, -50%) scale(0.5);
|
|
}
|
|
50% {
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
opacity: 0;
|
|
transform: translate(-50%, -50%) scale(1.5);
|
|
}
|
|
}
|
|
/* Node row click animation */
|
|
@keyframes nodeClick {
|
|
0% {
|
|
transform: scale(1);
|
|
}
|
|
50% {
|
|
transform: scale(0.98);
|
|
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
.node-click {
|
|
animation: nodeClick 0.15s ease-out;
|
|
}
|
|
|
|
/* AI Context row highlight - subtle left accent bar */
|
|
/* Using purple-500 for a clean, modern look */
|
|
|
|
.ai-context-row {
|
|
background-color: rgba(147, 51, 234, 0.04);
|
|
box-shadow: inset 3px 0 0 0 rgba(147, 51, 234, 0.6);
|
|
}
|
|
|
|
.ai-context-row:hover {
|
|
background-color: rgba(147, 51, 234, 0.08);
|
|
}
|
|
|
|
/* Adjacent rows - keep the left border consistent */
|
|
.ai-context-row.ai-context-no-top,
|
|
.ai-context-row.ai-context-no-bottom,
|
|
.ai-context-row.ai-context-no-top.ai-context-no-bottom {
|
|
background-color: rgba(147, 51, 234, 0.04);
|
|
box-shadow: inset 3px 0 0 0 rgba(147, 51, 234, 0.6);
|
|
}
|
|
|
|
.ai-context-row.ai-context-no-top:hover,
|
|
.ai-context-row.ai-context-no-bottom:hover,
|
|
.ai-context-row.ai-context-no-top.ai-context-no-bottom:hover {
|
|
background-color: rgba(147, 51, 234, 0.08);
|
|
}
|
|
|
|
/* Dark mode - using purple-400 for better visibility */
|
|
.dark .ai-context-row {
|
|
background-color: rgba(167, 139, 250, 0.06);
|
|
box-shadow: inset 3px 0 0 0 rgba(167, 139, 250, 0.5);
|
|
}
|
|
|
|
.dark .ai-context-row:hover {
|
|
background-color: rgba(167, 139, 250, 0.12);
|
|
}
|
|
|
|
.dark .ai-context-row.ai-context-no-top,
|
|
.dark .ai-context-row.ai-context-no-bottom,
|
|
.dark .ai-context-row.ai-context-no-top.ai-context-no-bottom {
|
|
background-color: rgba(167, 139, 250, 0.06);
|
|
box-shadow: inset 3px 0 0 0 rgba(167, 139, 250, 0.5);
|
|
}
|
|
|
|
.dark .ai-context-row.ai-context-no-top:hover,
|
|
.dark .ai-context-row.ai-context-no-bottom:hover,
|
|
.dark .ai-context-row.ai-context-no-top.ai-context-no-bottom:hover {
|
|
background-color: rgba(167, 139, 250, 0.12);
|
|
}
|
|
|