Files
claudetools/projects/msp-tools/guru-rmm/dashboard/src/index.css
azcomputerguru c332f4f48d feat(dashboard): UI refinements - density, flat agents table, history log
- Reduce layout density ~20% (tighter padding, margins, fonts)
- Flatten Agents table view with Client/Site columns (no grouping)
- Add version info to sidebar footer (UI v0.2.0, API v0.1.0)
- Replace Commands nav with sidebar History log
- Add /history page with full command list
- Add /history/:id detail view with output display
- Apply Mission Control styling to all new components

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 08:12:31 -07:00

1334 lines
30 KiB
CSS

/* Google Fonts Import - Must be first */
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Inter:wght@300;400;500;600;700&display=swap');
@import "tailwindcss";
/* ============================================================
GURU RMM - MISSION CONTROL DASHBOARD
A command center aesthetic with glassmorphism and glow effects
============================================================ */
/* ============================================================
CSS CUSTOM PROPERTIES (DESIGN TOKENS)
============================================================ */
:root {
/* Base Colors - Deep Navy/Slate Theme */
--bg-primary: #0a0e1a;
--bg-secondary: #111827;
--bg-tertiary: #1a2234;
--bg-elevated: #1e293b;
/* Card & Surface Colors - Glassmorphism */
--bg-card: rgba(15, 23, 42, 0.8);
--bg-card-hover: rgba(30, 41, 59, 0.9);
--bg-card-solid: #0f172a;
/* Accent Colors - Cyan/Teal Primary */
--accent-cyan: #06b6d4;
--accent-cyan-light: #22d3ee;
--accent-cyan-dark: #0891b2;
--accent-cyan-muted: rgba(6, 182, 212, 0.2);
/* Status Colors */
--accent-green: #10b981;
--accent-green-light: #34d399;
--accent-green-dark: #059669;
--accent-green-muted: rgba(16, 185, 129, 0.2);
--accent-amber: #f59e0b;
--accent-amber-light: #fbbf24;
--accent-amber-dark: #d97706;
--accent-amber-muted: rgba(245, 158, 11, 0.2);
--accent-rose: #f43f5e;
--accent-rose-light: #fb7185;
--accent-rose-dark: #e11d48;
--accent-rose-muted: rgba(244, 63, 94, 0.2);
/* Text Colors - Cool Gray Scale */
--text-primary: #f1f5f9;
--text-secondary: #94a3b8;
--text-muted: #64748b;
--text-disabled: #475569;
/* Border Colors */
--border-primary: rgba(255, 255, 255, 0.1);
--border-secondary: rgba(255, 255, 255, 0.05);
--border-accent: rgba(6, 182, 212, 0.3);
/* Glow Effects */
--glow-cyan: 0 0 20px rgba(6, 182, 212, 0.3);
--glow-cyan-intense: 0 0 30px rgba(6, 182, 212, 0.5), 0 0 60px rgba(6, 182, 212, 0.2);
--glow-green: 0 0 20px rgba(16, 185, 129, 0.3);
--glow-green-intense: 0 0 30px rgba(16, 185, 129, 0.5);
--glow-amber: 0 0 20px rgba(245, 158, 11, 0.3);
--glow-rose: 0 0 20px rgba(244, 63, 94, 0.3);
/* Glass Effect Properties */
--glass-bg: rgba(15, 23, 42, 0.8);
--glass-bg-light: rgba(30, 41, 59, 0.6);
--glass-border: rgba(255, 255, 255, 0.1);
--glass-blur: 12px;
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.3);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -4px rgba(0, 0, 0, 0.4);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.4);
/* Spacing & Sizing */
--radius-sm: 0.375rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--radius-xl: 1rem;
/* Transitions */
--transition-fast: 150ms ease;
--transition-base: 200ms ease;
--transition-slow: 300ms ease;
/* Typography */
--font-mono: 'JetBrains Mono', 'Fira Code', 'SF Mono', monospace;
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
/* Tailwind CSS Variable Overrides */
--background: 222.2 47% 5%;
--foreground: 210 40% 98%;
--card: 222.2 47% 8%;
--card-foreground: 210 40% 98%;
--popover: 222.2 47% 8%;
--popover-foreground: 210 40% 98%;
--primary: 187 82% 43%;
--primary-foreground: 222.2 47% 5%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 343 79% 60%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 187 82% 43%;
--radius: 0.5rem;
}
/* ============================================================
KEYFRAME ANIMATIONS
============================================================ */
/* Fade In Up - Card entrance animation */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Fade In - Simple fade */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* Pulse Glow - Status indicator pulse */
@keyframes pulse-glow {
0%, 100% {
opacity: 1;
box-shadow: 0 0 8px currentColor;
}
50% {
opacity: 0.7;
box-shadow: 0 0 16px currentColor, 0 0 24px currentColor;
}
}
/* Shimmer - Loading state effect */
@keyframes shimmer {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}
/* Scan Line - Horizontal scan effect */
@keyframes scan-line {
0% {
top: -5%;
opacity: 0;
}
10% {
opacity: 0.5;
}
90% {
opacity: 0.5;
}
100% {
top: 105%;
opacity: 0;
}
}
/* Rotate - For spinners and loading indicators */
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* Blink - For cursor and status indicators */
@keyframes blink {
0%, 50% {
opacity: 1;
}
51%, 100% {
opacity: 0;
}
}
/* Data Stream - Vertical scrolling effect */
@keyframes data-stream {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(100%);
}
}
/* Glow Pulse - Subtle glow pulsing */
@keyframes glow-pulse {
0%, 100% {
filter: drop-shadow(0 0 4px var(--accent-cyan));
}
50% {
filter: drop-shadow(0 0 12px var(--accent-cyan)) drop-shadow(0 0 20px var(--accent-cyan-muted));
}
}
/* Border Glow - Animated border glow */
@keyframes border-glow {
0%, 100% {
border-color: var(--border-accent);
box-shadow: inset 0 0 20px rgba(6, 182, 212, 0.05);
}
50% {
border-color: var(--accent-cyan);
box-shadow: inset 0 0 30px rgba(6, 182, 212, 0.1);
}
}
/* Float animation for particles */
@keyframes float {
0%, 100% {
transform: translateY(0) rotate(0deg);
opacity: 0.3;
}
50% {
transform: translateY(-20px) rotate(180deg);
opacity: 0.6;
}
}
/* Grid movement animation */
@keyframes grid-move {
0% {
transform: translateY(0);
}
100% {
transform: translateY(24px);
}
}
/* ============================================================
BASE STYLES
============================================================ */
*, *::before, *::after {
box-sizing: border-box;
border-color: var(--border-primary);
}
html {
font-size: 16px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
body {
margin: 0;
padding: 0;
font-family: var(--font-sans);
font-size: 1rem;
line-height: 1.6;
color: var(--text-primary);
background-color: var(--bg-primary);
min-height: 100vh;
overflow-x: hidden;
/* Background with subtle grid pattern */
background-image:
/* Radial gradient glow in corners */
radial-gradient(ellipse 80% 50% at 10% 10%, rgba(6, 182, 212, 0.08) 0%, transparent 50%),
radial-gradient(ellipse 60% 40% at 90% 90%, rgba(16, 185, 129, 0.06) 0%, transparent 50%),
radial-gradient(ellipse 50% 30% at 50% 0%, rgba(6, 182, 212, 0.04) 0%, transparent 50%),
/* Dot grid pattern */
radial-gradient(circle at center, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
background-size:
100% 100%,
100% 100%,
100% 100%,
24px 24px;
background-position:
0 0,
0 0,
0 0,
0 0;
background-attachment: fixed;
}
/* Optional: Subtle scan line overlay */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0, 0, 0, 0.03) 2px,
rgba(0, 0, 0, 0.03) 4px
);
pointer-events: none;
z-index: 9999;
opacity: 0.3;
}
/* ============================================================
TYPOGRAPHY
============================================================ */
h1, h2, h3, h4, h5, h6 {
font-family: var(--font-mono);
font-weight: 600;
color: var(--text-primary);
margin: 0;
letter-spacing: -0.02em;
}
h1 { font-size: 2.5rem; line-height: 1.2; }
h2 { font-size: 2rem; line-height: 1.25; }
h3 { font-size: 1.5rem; line-height: 1.3; }
h4 { font-size: 1.25rem; line-height: 1.35; }
h5 { font-size: 1.125rem; line-height: 1.4; }
h6 { font-size: 1rem; line-height: 1.5; }
p {
margin: 0;
color: var(--text-secondary);
}
code, pre, .mono {
font-family: var(--font-mono);
}
/* Data displays use mono font */
.data-value,
.metric-value,
.stat-number {
font-family: var(--font-mono);
font-weight: 600;
letter-spacing: 0.02em;
}
/* ============================================================
GLASSMORPHISM COMPONENTS
============================================================ */
.glass {
background: var(--glass-bg);
backdrop-filter: blur(var(--glass-blur));
-webkit-backdrop-filter: blur(var(--glass-blur));
border: 1px solid var(--glass-border);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-lg);
}
.glass-light {
background: var(--glass-bg-light);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
border: 1px solid var(--glass-border);
border-radius: var(--radius-md);
}
.glass-strong {
background: rgba(15, 23, 42, 0.9);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid var(--glass-border);
border-radius: var(--radius-lg);
}
.glass-card {
background: var(--glass-bg);
backdrop-filter: blur(var(--glass-blur));
-webkit-backdrop-filter: blur(var(--glass-blur));
border: 1px solid var(--glass-border);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-lg);
padding: 1rem;
transition: all var(--transition-base);
}
.glass-card:hover {
background: var(--bg-card-hover);
border-color: var(--border-accent);
box-shadow: var(--shadow-xl), var(--glow-cyan);
transform: translateY(-2px);
}
/* ============================================================
GLOW EFFECTS
============================================================ */
.glow-cyan {
box-shadow: var(--glow-cyan);
}
.glow-cyan-intense {
box-shadow: var(--glow-cyan-intense);
}
.glow-green {
box-shadow: var(--glow-green);
}
.glow-green-intense {
box-shadow: var(--glow-green-intense);
}
.glow-amber {
box-shadow: var(--glow-amber);
}
.glow-rose {
box-shadow: var(--glow-rose);
}
/* Text with glow */
.text-glow-cyan {
text-shadow: 0 0 10px var(--accent-cyan), 0 0 20px rgba(6, 182, 212, 0.5);
}
.text-glow-green {
text-shadow: 0 0 10px var(--accent-green), 0 0 20px rgba(16, 185, 129, 0.5);
}
/* ============================================================
GRADIENT TEXT
============================================================ */
.text-gradient {
background: linear-gradient(135deg, var(--accent-cyan-light), var(--accent-cyan), var(--accent-green));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.text-gradient-amber {
background: linear-gradient(135deg, var(--accent-amber-light), var(--accent-amber));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.text-gradient-rose {
background: linear-gradient(135deg, var(--accent-rose-light), var(--accent-rose));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.gradient-cyan-teal {
background: linear-gradient(135deg, var(--accent-cyan), var(--accent-green));
}
/* ============================================================
ANIMATION UTILITIES
============================================================ */
.animate-fade-in {
animation: fadeIn 0.3s ease-out forwards;
}
.animate-fade-in-up {
animation: fadeInUp 0.4s ease-out forwards;
}
.animate-fade-in-up-delay-1 {
animation: fadeInUp 0.4s ease-out 0.1s forwards;
opacity: 0;
}
.animate-fade-in-up-delay-2 {
animation: fadeInUp 0.4s ease-out 0.2s forwards;
opacity: 0;
}
.animate-fade-in-up-delay-3 {
animation: fadeInUp 0.4s ease-out 0.3s forwards;
opacity: 0;
}
.animate-pulse-glow {
animation: pulse-glow 2s ease-in-out infinite;
}
.animate-shimmer {
background: linear-gradient(
90deg,
var(--bg-tertiary) 0%,
var(--bg-elevated) 50%,
var(--bg-tertiary) 100%
);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
}
.animate-scan-line {
position: relative;
overflow: hidden;
}
.animate-scan-line::after {
content: '';
position: absolute;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(
90deg,
transparent 0%,
var(--accent-cyan) 50%,
transparent 100%
);
animation: scan-line 4s linear infinite;
pointer-events: none;
}
.animate-rotate {
animation: rotate 1s linear infinite;
}
.animate-glow-pulse {
animation: glow-pulse 3s ease-in-out infinite;
}
.animate-border-glow {
animation: border-glow 3s ease-in-out infinite;
}
.animate-float {
animation: float 6s ease-in-out infinite;
}
.animate-grid {
animation: grid-move 20s linear infinite;
}
/* ============================================================
STATUS INDICATORS
============================================================ */
.status-indicator {
display: inline-flex;
align-items: center;
gap: 0.5rem;
font-family: var(--font-mono);
font-size: 0.875rem;
font-weight: 500;
}
.status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
/* Online Status */
.status-online .status-dot,
.status-dot.online {
background-color: var(--accent-green);
box-shadow: 0 0 8px var(--accent-green);
animation: pulse-glow 2s ease-in-out infinite;
}
.status-online {
color: var(--accent-green);
}
/* Offline Status */
.status-offline .status-dot,
.status-dot.offline {
background-color: var(--text-muted);
box-shadow: none;
animation: none;
}
.status-offline {
color: var(--text-muted);
}
/* Warning Status */
.status-warning .status-dot,
.status-dot.warning {
background-color: var(--accent-amber);
box-shadow: 0 0 8px var(--accent-amber);
animation: pulse-glow 1.5s ease-in-out infinite;
}
.status-warning {
color: var(--accent-amber);
}
/* Error Status */
.status-error .status-dot,
.status-dot.error {
background-color: var(--accent-rose);
box-shadow: 0 0 8px var(--accent-rose);
animation: pulse-glow 1s ease-in-out infinite;
}
.status-error {
color: var(--accent-rose);
}
/* Status badges */
.status-badge {
display: inline-flex;
align-items: center;
gap: 0.375rem;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-family: var(--font-mono);
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-badge-online {
background-color: var(--accent-green-muted);
color: var(--accent-green-light);
border: 1px solid rgba(16, 185, 129, 0.3);
}
.status-badge-offline {
background-color: rgba(100, 116, 139, 0.2);
color: var(--text-muted);
border: 1px solid rgba(100, 116, 139, 0.3);
}
.status-badge-warning {
background-color: var(--accent-amber-muted);
color: var(--accent-amber-light);
border: 1px solid rgba(245, 158, 11, 0.3);
}
.status-badge-error {
background-color: var(--accent-rose-muted);
color: var(--accent-rose-light);
border: 1px solid rgba(244, 63, 94, 0.3);
}
/* ============================================================
CARD COMPONENTS
============================================================ */
.card {
background: var(--bg-card);
border: 1px solid var(--border-primary);
border-radius: var(--radius-lg);
padding: 1rem;
transition: all var(--transition-base);
}
.card-hover:hover {
border-color: var(--border-accent);
box-shadow: var(--shadow-lg), var(--glow-cyan);
transform: translateY(-2px);
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.75rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid var(--border-secondary);
}
.card-title {
font-family: var(--font-mono);
font-size: 0.875rem;
font-weight: 600;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.1em;
}
/* Metric Card */
.metric-card {
background: var(--glass-bg);
backdrop-filter: blur(var(--glass-blur));
border: 1px solid var(--glass-border);
border-radius: var(--radius-lg);
padding: 1rem;
display: flex;
flex-direction: column;
gap: 0.375rem;
}
.metric-label {
font-size: 0.75rem;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.1em;
font-weight: 500;
}
.metric-value {
font-family: var(--font-mono);
font-size: 1.75rem;
font-weight: 700;
color: var(--text-primary);
line-height: 1;
}
.metric-value.cyan { color: var(--accent-cyan); }
.metric-value.green { color: var(--accent-green); }
.metric-value.amber { color: var(--accent-amber); }
.metric-value.rose { color: var(--accent-rose); }
.metric-trend {
display: flex;
align-items: center;
gap: 0.25rem;
font-size: 0.75rem;
font-weight: 500;
}
.metric-trend.up { color: var(--accent-green); }
.metric-trend.down { color: var(--accent-rose); }
.metric-trend.neutral { color: var(--text-muted); }
/* ============================================================
DATA GRID / TABLE STYLES
============================================================ */
.data-grid {
width: 100%;
border-collapse: separate;
border-spacing: 0;
font-family: var(--font-mono);
font-size: 0.875rem;
}
.data-grid th {
background: var(--bg-tertiary);
color: var(--text-muted);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
font-size: 0.75rem;
padding: 0.5rem 0.75rem;
text-align: left;
border-bottom: 1px solid var(--border-primary);
}
.data-grid td {
padding: 0.5rem 0.75rem;
color: var(--text-secondary);
border-bottom: 1px solid var(--border-secondary);
transition: background var(--transition-fast);
}
.data-grid tr:hover td {
background: rgba(6, 182, 212, 0.05);
}
.data-grid tr:last-child td {
border-bottom: none;
}
/* ============================================================
BUTTONS
============================================================ */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
font-family: var(--font-mono);
font-size: 0.875rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
border-radius: var(--radius-md);
border: 1px solid transparent;
cursor: pointer;
transition: all var(--transition-base);
}
.btn-primary {
background: var(--accent-cyan);
color: var(--bg-primary);
border-color: var(--accent-cyan);
}
.btn-primary:hover {
background: var(--accent-cyan-light);
box-shadow: var(--glow-cyan);
}
.btn-secondary {
background: transparent;
color: var(--accent-cyan);
border-color: var(--accent-cyan);
}
.btn-secondary:hover {
background: var(--accent-cyan-muted);
box-shadow: var(--glow-cyan);
}
.btn-ghost {
background: transparent;
color: var(--text-secondary);
border-color: var(--border-primary);
}
.btn-ghost:hover {
background: var(--bg-tertiary);
color: var(--text-primary);
border-color: var(--border-accent);
}
.btn-danger {
background: var(--accent-rose);
color: white;
border-color: var(--accent-rose);
}
.btn-danger:hover {
background: var(--accent-rose-light);
box-shadow: var(--glow-rose);
}
.btn-mission-control {
background: linear-gradient(135deg, var(--accent-cyan), var(--accent-green));
color: var(--bg-primary);
font-weight: 600;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.btn-mission-control:hover:not(:disabled) {
box-shadow: var(--glow-cyan-intense);
transform: translateY(-1px);
}
.btn-mission-control:active:not(:disabled) {
transform: translateY(0);
}
.btn-mission-control:disabled {
opacity: 0.7;
cursor: not-allowed;
}
/* Loading shimmer overlay for button */
.btn-mission-control.loading::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.2) 50%,
transparent 100%
);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
/* ============================================================
FORM INPUTS
============================================================ */
.input {
width: 100%;
padding: 0.625rem 1rem;
font-family: var(--font-mono);
font-size: 0.875rem;
color: var(--text-primary);
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
border-radius: var(--radius-md);
transition: all var(--transition-base);
}
.input:focus {
outline: none;
border-color: var(--accent-cyan);
box-shadow: 0 0 0 3px var(--accent-cyan-muted);
}
.input::placeholder {
color: var(--text-muted);
}
.input-label {
display: block;
font-size: 0.75rem;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.1em;
margin-bottom: 0.5rem;
}
.input-mission-control {
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
color: var(--text-primary);
transition: all 0.2s ease;
}
.input-mission-control::placeholder {
color: var(--text-muted);
}
.input-mission-control:focus {
outline: none;
border-color: var(--accent-cyan);
box-shadow:
0 0 0 3px var(--accent-cyan-muted),
0 0 15px rgba(6, 182, 212, 0.2);
}
/* ============================================================
NAVIGATION
============================================================ */
.nav {
display: flex;
align-items: center;
gap: 0.25rem;
}
.nav-item {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.375rem 0.75rem;
font-family: var(--font-mono);
font-size: 0.8125rem;
font-weight: 500;
color: var(--text-muted);
background: transparent;
border: none;
border-radius: var(--radius-md);
cursor: pointer;
transition: all var(--transition-base);
text-decoration: none;
}
.nav-item:hover {
color: var(--text-primary);
background: var(--bg-tertiary);
}
.nav-item.active {
color: var(--accent-cyan);
background: var(--accent-cyan-muted);
}
/* ============================================================
SIDEBAR
============================================================ */
.sidebar {
background: var(--glass-bg);
backdrop-filter: blur(var(--glass-blur));
border-right: 1px solid var(--glass-border);
height: 100vh;
position: fixed;
width: 240px;
overflow-y: auto;
z-index: 100;
}
.sidebar-header {
padding: 1.5rem;
border-bottom: 1px solid var(--border-secondary);
}
.sidebar-logo {
font-family: var(--font-mono);
font-size: 1.25rem;
font-weight: 700;
color: var(--accent-cyan);
text-shadow: var(--glow-cyan);
}
.sidebar-nav {
padding: 1rem;
display: flex;
flex-direction: column;
gap: 0.25rem;
}
/* ============================================================
TERMINAL / CONSOLE STYLES
============================================================ */
.terminal {
background: var(--bg-primary);
border: 1px solid var(--border-primary);
border-radius: var(--radius-lg);
font-family: var(--font-mono);
font-size: 0.8125rem;
overflow: hidden;
}
.terminal-header {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem 1rem;
background: var(--bg-tertiary);
border-bottom: 1px solid var(--border-primary);
}
.terminal-dot {
width: 12px;
height: 12px;
border-radius: 50%;
}
.terminal-dot.red { background: var(--accent-rose); }
.terminal-dot.yellow { background: var(--accent-amber); }
.terminal-dot.green { background: var(--accent-green); }
.terminal-body {
padding: 1rem;
max-height: 400px;
overflow-y: auto;
}
.terminal-line {
display: flex;
gap: 0.5rem;
line-height: 1.6;
}
.terminal-prompt {
color: var(--accent-cyan);
user-select: none;
}
.terminal-output {
color: var(--text-secondary);
}
.terminal-cursor {
display: inline-block;
width: 8px;
height: 1em;
background: var(--accent-cyan);
animation: blink 1s step-end infinite;
vertical-align: text-bottom;
}
/* ============================================================
LOADING STATES
============================================================ */
.skeleton {
background: linear-gradient(
90deg,
var(--bg-tertiary) 0%,
var(--bg-elevated) 50%,
var(--bg-tertiary) 100%
);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
border-radius: var(--radius-md);
}
.skeleton-text {
height: 1em;
border-radius: var(--radius-sm);
}
.skeleton-title {
height: 1.5em;
width: 60%;
border-radius: var(--radius-sm);
}
.skeleton-card {
height: 120px;
border-radius: var(--radius-lg);
}
.loading-spinner {
width: 24px;
height: 24px;
border: 2px solid var(--border-primary);
border-top-color: var(--accent-cyan);
border-radius: 50%;
animation: rotate 0.8s linear infinite;
}
/* ============================================================
PROGRESS BARS
============================================================ */
.progress-bar {
height: 6px;
background: var(--bg-tertiary);
border-radius: 9999px;
overflow: hidden;
}
.progress-fill {
height: 100%;
border-radius: 9999px;
transition: width var(--transition-slow);
}
.progress-fill.cyan {
background: linear-gradient(90deg, var(--accent-cyan-dark), var(--accent-cyan-light));
box-shadow: var(--glow-cyan);
}
.progress-fill.green {
background: linear-gradient(90deg, var(--accent-green-dark), var(--accent-green-light));
box-shadow: var(--glow-green);
}
.progress-fill.amber {
background: linear-gradient(90deg, var(--accent-amber-dark), var(--accent-amber-light));
box-shadow: var(--glow-amber);
}
.progress-fill.rose {
background: linear-gradient(90deg, var(--accent-rose-dark), var(--accent-rose-light));
box-shadow: var(--glow-rose);
}
/* ============================================================
TOOLTIPS
============================================================ */
.tooltip {
position: relative;
}
.tooltip::after {
content: attr(data-tooltip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%) translateY(-8px);
padding: 0.5rem 0.75rem;
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--text-primary);
background: var(--bg-elevated);
border: 1px solid var(--border-primary);
border-radius: var(--radius-md);
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: all var(--transition-fast);
z-index: 1000;
}
.tooltip:hover::after {
opacity: 1;
visibility: visible;
transform: translateX(-50%) translateY(-4px);
}
/* ============================================================
BACKGROUND PATTERNS
============================================================ */
.bg-grid-pattern {
background-image:
linear-gradient(var(--border-primary) 1px, transparent 1px),
linear-gradient(90deg, var(--border-primary) 1px, transparent 1px);
background-size: 50px 50px;
}
.bg-dot-pattern {
background-image: radial-gradient(var(--border-primary) 1px, transparent 1px);
background-size: 30px 30px;
}
/* ============================================================
UTILITY CLASSES
============================================================ */
/* Colors */
.text-cyan { color: var(--accent-cyan); }
.text-green { color: var(--accent-green); }
.text-amber { color: var(--accent-amber); }
.text-rose { color: var(--accent-rose); }
.text-primary { color: var(--text-primary); }
.text-secondary { color: var(--text-secondary); }
.text-muted { color: var(--text-muted); }
.bg-cyan { background-color: var(--accent-cyan); }
.bg-green { background-color: var(--accent-green); }
.bg-amber { background-color: var(--accent-amber); }
.bg-rose { background-color: var(--accent-rose); }
/* Borders */
.border-cyan { border-color: var(--accent-cyan); }
.border-green { border-color: var(--accent-green); }
.border-amber { border-color: var(--accent-amber); }
.border-rose { border-color: var(--accent-rose); }
/* Font families */
.font-mono { font-family: var(--font-mono); }
.font-sans { font-family: var(--font-sans); }
.font-mono-display {
font-family: 'JetBrains Mono', 'Space Mono', 'Fira Code', monospace;
}
/* Letter spacing */
.tracking-widest-custom {
letter-spacing: 0.2em;
}
/* Compact spacing utilities */
.space-y-compact > * + * {
margin-top: 0.75rem;
}
.gap-compact {
gap: 0.75rem;
}
/* ============================================================
SCROLLBAR STYLING
============================================================ */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: var(--bg-secondary);
}
::-webkit-scrollbar-thumb {
background: var(--bg-elevated);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--text-disabled);
}
/* Selection */
::selection {
background: var(--accent-cyan-muted);
color: var(--text-primary);
}
/* Focus visible for accessibility */
:focus-visible {
outline: 2px solid var(--accent-cyan);
outline-offset: 2px;
}
/* ============================================================
RESPONSIVE UTILITIES
============================================================ */
@media (max-width: 768px) {
.sidebar {
transform: translateX(-100%);
transition: transform var(--transition-base);
}
.sidebar.open {
transform: translateX(0);
}
h1 { font-size: 2rem; }
h2 { font-size: 1.5rem; }
h3 { font-size: 1.25rem; }
.metric-value {
font-size: 1.5rem;
}
}
/* ============================================================
PRINT STYLES
============================================================ */
@media print {
body {
background: white;
color: black;
}
.glass,
.glass-card {
background: white;
backdrop-filter: none;
border: 1px solid #ccc;
box-shadow: none;
}
.animate-pulse-glow,
.animate-scan-line::after {
animation: none;
}
body::before {
display: none;
}
}