diff --git a/frontend/src/App.css b/frontend/src/App.css index 9fbc320..be6df2b 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -1,9 +1,22 @@ /* Tactical Intelligence Dashboard Styles */ +/* IMPORTANT: This file MUST be imported in App.js */ * { font-family: 'Outfit', system-ui, sans-serif; } +/* Pulse animation for glowing dots - used by inline styles */ +@keyframes pulse { + 0%, 100% { + opacity: 1; + transform: scale(1); + } + 50% { + opacity: 0.7; + transform: scale(1.2); + } +} + :root { /* Base Colors */ --intel-darkest: #0A0E27; diff --git a/frontend/src/App.js b/frontend/src/App.js index 92a498a..e57fb04 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -6,8 +6,150 @@ import UserMenu from './components/UserMenu'; import UserManagement from './components/UserManagement'; import AuditLog from './components/AuditLog'; import NvdSyncModal from './components/NvdSyncModal'; +import './App.css'; const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api'; + +// ============================================ +// INLINE STYLES - NUCLEAR OPTION FOR VISIBILITY +// ============================================ +const STYLES = { + // Main container with visible background + mainContainer: { + minHeight: '100vh', + background: 'linear-gradient(135deg, #0A0E27 0%, #131937 50%, #0A0E27 100%)', + padding: '1.5rem', + position: 'relative', + overflow: 'hidden', + }, + // Stat cards with BRIGHT CYAN borders + statCard: { + background: 'linear-gradient(135deg, rgba(19, 25, 55, 1) 0%, rgba(30, 39, 73, 0.95) 100%)', + border: '3px solid #00D9FF', + borderRadius: '0.5rem', + padding: '1rem', + boxShadow: '0 8px 24px rgba(0, 0, 0, 0.6), 0 0 30px rgba(0, 217, 255, 0.3), inset 0 2px 0 rgba(0, 217, 255, 0.2)', + position: 'relative', + overflow: 'hidden', + }, + // Intel card with thick glowing border + intelCard: { + background: 'linear-gradient(135deg, rgba(19, 25, 55, 1) 0%, rgba(30, 39, 73, 0.95) 50%, rgba(19, 25, 55, 1) 100%)', + border: '3px solid rgba(0, 217, 255, 0.6)', + borderRadius: '0.5rem', + boxShadow: '0 12px 32px rgba(0, 0, 0, 0.7), 0 0 40px rgba(0, 217, 255, 0.25), inset 0 2px 0 rgba(0, 217, 255, 0.15)', + position: 'relative', + overflow: 'hidden', + }, + // Vendor card with depth + vendorCard: { + background: 'linear-gradient(135deg, rgba(10, 14, 39, 0.95) 0%, rgba(19, 25, 55, 0.9) 100%)', + border: '2px solid rgba(0, 217, 255, 0.4)', + borderRadius: '0.5rem', + padding: '1rem', + boxShadow: '0 6px 16px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(0, 217, 255, 0.1)', + marginBottom: '0.75rem', + }, + // CRITICAL severity badge - BRIGHT RED with WHITE text + badgeCritical: { + display: 'inline-flex', + alignItems: 'center', + gap: '0.5rem', + background: 'linear-gradient(135deg, rgba(255, 51, 102, 0.4) 0%, rgba(255, 51, 102, 0.3) 100%)', + border: '2px solid #FF3366', + borderRadius: '0.375rem', + padding: '0.375rem 0.875rem', + color: '#FFFFFF', + fontWeight: '700', + fontSize: '0.75rem', + textTransform: 'uppercase', + letterSpacing: '0.5px', + textShadow: '0 0 10px rgba(255, 51, 102, 0.9)', + boxShadow: '0 0 20px rgba(255, 51, 102, 0.5), 0 4px 8px rgba(0, 0, 0, 0.4)', + }, + // HIGH severity badge - BRIGHT ORANGE/YELLOW with WHITE text + badgeHigh: { + display: 'inline-flex', + alignItems: 'center', + gap: '0.5rem', + background: 'linear-gradient(135deg, rgba(255, 184, 0, 0.4) 0%, rgba(255, 184, 0, 0.3) 100%)', + border: '2px solid #FFB800', + borderRadius: '0.375rem', + padding: '0.375rem 0.875rem', + color: '#FFFFFF', + fontWeight: '700', + fontSize: '0.75rem', + textTransform: 'uppercase', + letterSpacing: '0.5px', + textShadow: '0 0 10px rgba(255, 184, 0, 0.9)', + boxShadow: '0 0 20px rgba(255, 184, 0, 0.5), 0 4px 8px rgba(0, 0, 0, 0.4)', + }, + // MEDIUM severity badge - BRIGHT CYAN with WHITE text + badgeMedium: { + display: 'inline-flex', + alignItems: 'center', + gap: '0.5rem', + background: 'linear-gradient(135deg, rgba(0, 217, 255, 0.4) 0%, rgba(0, 217, 255, 0.3) 100%)', + border: '2px solid #00D9FF', + borderRadius: '0.375rem', + padding: '0.375rem 0.875rem', + color: '#FFFFFF', + fontWeight: '700', + fontSize: '0.75rem', + textTransform: 'uppercase', + letterSpacing: '0.5px', + textShadow: '0 0 10px rgba(0, 217, 255, 0.9)', + boxShadow: '0 0 20px rgba(0, 217, 255, 0.5), 0 4px 8px rgba(0, 0, 0, 0.4)', + }, + // LOW severity badge - BRIGHT GREEN with WHITE text + badgeLow: { + display: 'inline-flex', + alignItems: 'center', + gap: '0.5rem', + background: 'linear-gradient(135deg, rgba(0, 255, 136, 0.4) 0%, rgba(0, 255, 136, 0.3) 100%)', + border: '2px solid #00FF88', + borderRadius: '0.375rem', + padding: '0.375rem 0.875rem', + color: '#FFFFFF', + fontWeight: '700', + fontSize: '0.75rem', + textTransform: 'uppercase', + letterSpacing: '0.5px', + textShadow: '0 0 10px rgba(0, 255, 136, 0.9)', + boxShadow: '0 0 20px rgba(0, 255, 136, 0.5), 0 4px 8px rgba(0, 0, 0, 0.4)', + }, + // Glowing dot for badges + glowDot: (color) => ({ + width: '8px', + height: '8px', + borderRadius: '50%', + background: color, + boxShadow: `0 0 12px ${color}, 0 0 6px ${color}`, + animation: 'pulse 2s ease-in-out infinite', + }), +}; + +// Helper function to get severity badge style +const getSeverityBadgeStyle = (severity) => { + switch (severity?.toLowerCase()) { + case 'critical': return STYLES.badgeCritical; + case 'high': return STYLES.badgeHigh; + case 'medium': return STYLES.badgeMedium; + case 'low': return STYLES.badgeLow; + default: return STYLES.badgeMedium; + } +}; + +// Helper function to get severity dot color +const getSeverityDotColor = (severity) => { + switch (severity?.toLowerCase()) { + case 'critical': return '#FF3366'; + case 'high': return '#FFB800'; + case 'medium': return '#00D9FF'; + case 'low': return '#00FF88'; + default: return '#00D9FF'; + } +}; const API_HOST = process.env.REACT_APP_API_HOST || 'http://localhost:3001'; const severityLevels = ['All Severities', 'Critical', 'High', 'Medium', 'Low']; @@ -628,23 +770,27 @@ export default function App() { - {/* Stats Bar */} + {/* Stats Bar - INLINE STYLES FOR GUARANTEED VISIBILITY */}