/* ============================================== CSS Variables - Design System ============================================== */ :root { /* Primary Colors */ --bg-primary: #0f172a; --bg-secondary: #1e293b; --bg-tertiary: #334155; --bg-quaternary: #475569; /* Text Colors */ --text-primary: #f1f5f9; --text-secondary: #94a3b8; --text-muted: #64748b; /* Accent Colors */ --accent-blue: #60a5fa; --accent-blue-hover: #3b82f6; --accent-blue-dark: #2563eb; /* Border Colors */ --border-color: #334155; --border-color-light: #475569; /* Status Colors */ --success-bg: #065f46; --success-text: #6ee7b7; --success-border: #10b981; --warning-bg: #78350f; --warning-text: #fcd34d; --warning-border: #f59e0b; --danger-bg: #7f1d1d; --danger-text: #fca5a5; --danger-border: #ef4444; --info-bg: #1e3a8a; --info-text: #93c5fd; --info-border: #3b82f6; /* Shadows */ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.2); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2); --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.3), 0 10px 10px -5px rgba(0, 0, 0, 0.2); /* Transitions */ --transition-fast: 150ms ease; --transition-base: 200ms ease; --transition-slow: 300ms ease; /* Border Radius */ --radius-sm: 6px; --radius-md: 8px; --radius-lg: 12px; --radius-xl: 16px; /* Bootstrap 5 Variable Overrides for Dark Theme */ --bs-body-bg: #0f172a; --bs-body-color: #f1f5f9; --bs-border-color: #334155; --bs-border-color-translucent: rgba(51, 65, 85, 0.5); /* Table Variables */ --bs-table-bg: #1e293b; --bs-table-color: #f1f5f9; --bs-table-border-color: #334155; --bs-table-striped-bg: #1e293b; --bs-table-striped-color: #f1f5f9; --bs-table-active-bg: #334155; --bs-table-active-color: #f1f5f9; --bs-table-hover-bg: #334155; --bs-table-hover-color: #f1f5f9; } /* ============================================== Global Styles ============================================== */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: var(--bg-primary); color: var(--text-primary); line-height: 1.6; min-height: 100vh; } /* Smooth scrolling */ html { scroll-behavior: smooth; } /* Better focus styles for accessibility */ :focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 2px; } /* ============================================== Typography ============================================== */ h1, h2, h3, h4, h5, h6 { color: var(--accent-blue); font-weight: 600; line-height: 1.3; } h1 { font-size: 2rem; } h2 { font-size: 1.75rem; } h3 { font-size: 1.5rem; } h4 { font-size: 1.25rem; } h5 { font-size: 1.125rem; } h6 { font-size: 1rem; } /* Page titles */ .page-title { color: var(--accent-blue); font-size: 2rem; font-weight: 600; margin-bottom: 0; } /* ============================================== Navbar ============================================== */ .navbar-custom { background: linear-gradient(135deg, var(--bg-secondary) 0%, var(--bg-tertiary) 100%); border-bottom: 1px solid var(--border-color-light); padding: 0.875rem 0; box-shadow: var(--shadow-md); } .navbar-brand { font-size: 1.5rem; font-weight: 700; color: var(--accent-blue) !important; letter-spacing: -0.5px; transition: color var(--transition-fast); } .navbar-brand:hover { color: var(--accent-blue-hover) !important; } .nav-link { color: var(--text-secondary) !important; font-weight: 500; padding: 0.5rem 1rem !important; border-radius: var(--radius-sm); transition: all var(--transition-fast); } .nav-link:hover { color: var(--text-primary) !important; background-color: rgba(255, 255, 255, 0.05); } .nav-link.active { color: var(--accent-blue) !important; background-color: rgba(96, 165, 250, 0.1); } /* Dropdown menus */ .dropdown-menu { background-color: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); padding: 0.5rem; } .dropdown-item { color: var(--text-secondary); padding: 0.5rem 1rem; border-radius: var(--radius-sm); transition: all var(--transition-fast); } .dropdown-item:hover, .dropdown-item:focus { color: var(--text-primary); background-color: var(--bg-tertiary); } .dropdown-divider { border-color: var(--border-color); } /* Navbar toggler for mobile */ .navbar-toggler { border-color: var(--border-color); padding: 0.5rem; } .navbar-toggler-icon { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28148, 163, 184, 1%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); } /* ============================================== Container ============================================== */ .container-fluid { max-width: 1400px; margin: 0 auto; padding: 1.5rem; } /* ============================================== Cards ============================================== */ .card { background-color: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: var(--radius-lg); margin-bottom: 1.5rem; box-shadow: var(--shadow-sm); transition: box-shadow var(--transition-base); } .card:hover { box-shadow: var(--shadow-md); } .card-header { background-color: var(--bg-tertiary); border-bottom: 1px solid var(--border-color); padding: 1rem 1.5rem; border-radius: var(--radius-lg) var(--radius-lg) 0 0 !important; } .card-header h5, .card-header .card-title { color: var(--accent-blue); margin-bottom: 0; font-weight: 600; } .card-body { padding: 1.5rem; } .card-title { color: var(--accent-blue); font-size: 1.25rem; font-weight: 600; margin-bottom: 1rem; } .card-footer { background-color: var(--bg-tertiary); border-top: 1px solid var(--border-color); padding: 1rem 1.5rem; } /* ============================================== Stat Cards ============================================== */ .stat-card { background-color: var(--bg-secondary); padding: 1.5rem; border-radius: var(--radius-lg); border: 1px solid var(--border-color); text-align: center; transition: all var(--transition-base); box-shadow: var(--shadow-sm); } .stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--accent-blue); } .stat-value { font-size: 2.5rem; font-weight: 700; color: var(--accent-blue); line-height: 1.2; } .stat-label { color: var(--text-secondary); font-size: 0.875rem; text-transform: uppercase; letter-spacing: 0.5px; margin-top: 0.5rem; font-weight: 500; } /* ============================================== Buttons ============================================== */ .btn { font-weight: 500; border-radius: var(--radius-md); padding: 0.5rem 1rem; transition: all var(--transition-fast); border: 1px solid transparent; } .btn:focus { box-shadow: 0 0 0 0.2rem rgba(96, 165, 250, 0.25); } /* Primary Button */ .btn-primary { background-color: var(--accent-blue-hover); border-color: var(--accent-blue-hover); color: #ffffff; } .btn-primary:hover, .btn-primary:focus { background-color: var(--accent-blue-dark); border-color: var(--accent-blue-dark); color: #ffffff; } .btn-primary:active { background-color: #1d4ed8; border-color: #1d4ed8; } /* Secondary Button */ .btn-secondary { background-color: var(--bg-tertiary); border-color: var(--border-color); color: var(--text-primary); } .btn-secondary:hover, .btn-secondary:focus { background-color: var(--bg-quaternary); border-color: var(--border-color-light); color: var(--text-primary); } /* Success Button */ .btn-success { background-color: #22c55e; border-color: #22c55e; color: #ffffff; } .btn-success:hover, .btn-success:focus { background-color: #16a34a; border-color: #16a34a; color: #ffffff; } /* Danger Button */ .btn-danger { background-color: #dc2626; border-color: #dc2626; color: #ffffff; } .btn-danger:hover, .btn-danger:focus { background-color: #b91c1c; border-color: #b91c1c; color: #ffffff; } /* Warning Button */ .btn-warning { background-color: #f59e0b; border-color: #f59e0b; color: #000000; } .btn-warning:hover, .btn-warning:focus { background-color: #d97706; border-color: #d97706; color: #000000; } /* Info Button */ .btn-info { background-color: #0ea5e9; border-color: #0ea5e9; color: #ffffff; } .btn-info:hover, .btn-info:focus { background-color: #0284c7; border-color: #0284c7; color: #ffffff; } /* Outline Buttons */ .btn-outline-primary { color: var(--accent-blue); border-color: var(--accent-blue-hover); } .btn-outline-primary:hover, .btn-outline-primary:focus { background-color: var(--accent-blue-hover); border-color: var(--accent-blue-hover); color: #ffffff; } .btn-outline-secondary { color: var(--text-secondary); border-color: var(--border-color); } .btn-outline-secondary:hover, .btn-outline-secondary:focus { background-color: var(--bg-tertiary); border-color: var(--border-color-light); color: var(--text-primary); } .btn-outline-success { color: var(--success-border); border-color: var(--success-border); } .btn-outline-success:hover, .btn-outline-success:focus { background-color: var(--success-border); border-color: var(--success-border); color: #ffffff; } .btn-outline-danger { color: var(--danger-border); border-color: var(--danger-border); } .btn-outline-danger:hover, .btn-outline-danger:focus { background-color: var(--danger-border); border-color: var(--danger-border); color: #ffffff; } /* Button Sizes */ .btn-lg { padding: 0.75rem 1.5rem; font-size: 1.125rem; } .btn-sm { padding: 0.25rem 0.5rem; font-size: 0.875rem; border-radius: var(--radius-sm); } /* Button Groups */ .btn-group .btn { border-radius: 0; } .btn-group .btn:first-child { border-top-left-radius: var(--radius-md); border-bottom-left-radius: var(--radius-md); } .btn-group .btn:last-child { border-top-right-radius: var(--radius-md); border-bottom-right-radius: var(--radius-md); } /* ============================================== Tables ============================================== */ .table { color: var(--text-primary); border-color: var(--border-color); margin-bottom: 0; } .table thead { background-color: var(--bg-tertiary); } .table thead th { color: var(--text-secondary); font-weight: 600; text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.5px; padding: 1rem; border-bottom: 2px solid var(--border-color); white-space: nowrap; } .table tbody tr, .table tbody tr.scan-row, .table tbody tr.schedule-row { background-color: var(--bg-secondary) !important; border-color: var(--border-color) !important; transition: background-color var(--transition-fast); } .table tbody tr:hover { background-color: var(--bg-tertiary) !important; } .table th, .table td { padding: 1rem; border-color: var(--border-color); vertical-align: middle; } .table-responsive { border-radius: var(--radius-md); overflow: hidden; } /* ============================================== Badges ============================================== */ .badge { padding: 0.35rem 0.75rem; border-radius: 50px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; } .badge-expected, .badge-good, .badge-success { background-color: var(--success-bg); color: var(--success-text); } .badge-unexpected, .badge-critical, .badge-danger { background-color: var(--danger-bg); color: var(--danger-text); } .badge-missing, .badge-warning { background-color: var(--warning-bg); color: var(--warning-text); } .badge-info { background-color: var(--info-bg); color: var(--info-text); } /* Bootstrap badge overrides */ .bg-success { background-color: var(--success-border) !important; } .bg-danger { background-color: var(--danger-border) !important; } .bg-warning { background-color: var(--warning-border) !important; color: #000 !important; } .bg-info { background-color: var(--info-border) !important; } .bg-secondary { background-color: var(--bg-quaternary) !important; } .bg-primary { background-color: var(--accent-blue-hover) !important; } /* ============================================== Alerts ============================================== */ .alert { border-radius: var(--radius-md); border: 1px solid; padding: 1rem 1.25rem; margin-bottom: 1rem; } .alert-success { background-color: var(--success-bg); border-color: var(--success-border); color: var(--success-text); } .alert-danger { background-color: var(--danger-bg); border-color: var(--danger-border); color: var(--danger-text); } .alert-warning { background-color: var(--warning-bg); border-color: var(--warning-border); color: var(--warning-text); } .alert-info { background-color: var(--info-bg); border-color: var(--info-border); color: var(--info-text); } .alert .btn-close { filter: invert(1) brightness(0.8); } .alert-link { color: inherit; text-decoration: underline; font-weight: 600; } /* ============================================== Form Controls ============================================== */ .form-control, .form-select { background-color: var(--bg-secondary); border: 1px solid var(--border-color); color: var(--text-primary); border-radius: var(--radius-md); padding: 0.625rem 0.875rem; transition: all var(--transition-fast); } .form-control:focus, .form-select:focus { background-color: var(--bg-primary); border-color: var(--accent-blue); color: var(--text-primary); box-shadow: 0 0 0 0.2rem rgba(96, 165, 250, 0.25); } .form-control::placeholder { color: var(--text-muted); } .form-control:disabled, .form-select:disabled { background-color: var(--bg-tertiary); opacity: 0.6; } .form-control-lg { padding: 0.75rem 1rem; font-size: 1.125rem; } .form-label { color: var(--text-secondary); font-weight: 500; margin-bottom: 0.5rem; } .form-text { color: var(--text-muted); font-size: 0.875rem; } .form-check-input { background-color: var(--bg-secondary); border-color: var(--border-color); } .form-check-input:checked { background-color: var(--accent-blue-hover); border-color: var(--accent-blue-hover); } .form-check-input:focus { box-shadow: 0 0 0 0.2rem rgba(96, 165, 250, 0.25); border-color: var(--accent-blue); } .form-check-label { color: var(--text-secondary); } /* Form switches */ .form-switch .form-check-input { width: 2.5rem; height: 1.25rem; margin-top: 0.125rem; } /* Required field indicator */ .text-danger { color: var(--danger-border) !important; } /* ============================================== Modals ============================================== */ .modal-content { background-color: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); } .modal-header { border-bottom: 1px solid var(--border-color); padding: 1.25rem 1.5rem; } .modal-title { color: var(--accent-blue); font-weight: 600; } .modal-body { padding: 1.5rem; } .modal-footer { border-top: 1px solid var(--border-color); padding: 1rem 1.5rem; gap: 0.5rem; } .btn-close { filter: invert(1) brightness(0.8); opacity: 0.5; transition: opacity var(--transition-fast); } .btn-close:hover { opacity: 1; } .modal-backdrop { background-color: rgba(0, 0, 0, 0.7); } /* ============================================== Pagination ============================================== */ .pagination { --bs-pagination-bg: var(--bg-secondary); --bs-pagination-border-color: var(--border-color); --bs-pagination-hover-bg: var(--bg-tertiary); --bs-pagination-hover-border-color: var(--border-color-light); --bs-pagination-focus-bg: var(--bg-tertiary); --bs-pagination-active-bg: var(--accent-blue-hover); --bs-pagination-active-border-color: var(--accent-blue-hover); --bs-pagination-disabled-bg: var(--bg-primary); --bs-pagination-disabled-border-color: var(--border-color); --bs-pagination-color: var(--text-secondary); --bs-pagination-hover-color: var(--text-primary); --bs-pagination-disabled-color: var(--text-muted); } .page-link { border-radius: var(--radius-sm); margin: 0 0.125rem; transition: all var(--transition-fast); } .page-item.active .page-link { color: #ffffff; } /* ============================================== Login Page ============================================== */ .login-card { max-width: 420px; margin: 5rem auto; padding: 2.5rem; background-color: var(--bg-secondary); border-radius: var(--radius-xl); border: 1px solid var(--border-color); box-shadow: var(--shadow-xl); } .brand-title { font-size: 2.5rem; font-weight: 700; color: var(--accent-blue); margin-bottom: 0.5rem; } .brand-subtitle { color: var(--text-muted); font-size: 1rem; margin-bottom: 0; } /* ============================================== Footer ============================================== */ .footer { margin-top: 3rem; padding: 1.5rem 0; border-top: 1px solid var(--border-color); text-align: center; color: var(--text-muted); font-size: 0.875rem; } .footer a { color: var(--accent-blue); text-decoration: none; transition: color var(--transition-fast); } .footer a:hover { color: var(--accent-blue-hover); } /* ============================================== Utility Classes ============================================== */ .text-muted { color: var(--text-secondary) !important; } .text-success { color: var(--success-border) !important; } .text-warning { color: var(--warning-border) !important; } .text-danger { color: var(--danger-border) !important; } .text-info { color: var(--accent-blue) !important; } .mono { font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Courier New', monospace; font-size: 0.9em; } code { background-color: var(--bg-primary); color: var(--accent-blue); padding: 0.125rem 0.375rem; border-radius: var(--radius-sm); font-size: 0.875em; } /* Border utilities */ .border-bottom { border-bottom: 1px solid var(--border-color) !important; } /* ============================================== Spinners / Loading States ============================================== */ .spinner-border { color: var(--accent-blue); } .spinner-border-sm { width: 1rem; height: 1rem; } /* ============================================== Charts ============================================== */ .chart-container { position: relative; height: 300px; margin: 1rem 0; } canvas { max-width: 100%; height: auto; } /* ============================================== Empty States ============================================== */ .empty-state { text-align: center; padding: 3rem 1rem; } .empty-state i { font-size: 3rem; color: var(--text-muted); opacity: 0.5; margin-bottom: 1rem; } .empty-state h5 { color: var(--text-secondary); } .empty-state p { color: var(--text-muted); } /* ============================================== Notifications (Toast-like) ============================================== */ .notification { position: fixed; top: 1.25rem; right: 1.25rem; z-index: 9999; min-width: 300px; animation: slideIn 0.3s ease; } @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } /* ============================================== Responsive Design ============================================== */ @media (max-width: 991.98px) { .navbar-collapse { background-color: var(--bg-secondary); padding: 1rem; border-radius: var(--radius-md); margin-top: 1rem; border: 1px solid var(--border-color); } .navbar-nav { gap: 0.25rem; } } @media (max-width: 767.98px) { .container-fluid { padding: 1rem; } h1 { font-size: 1.75rem; } .stat-value { font-size: 2rem; } .card-body { padding: 1rem; } .card-header { padding: 0.875rem 1rem; } .table th, .table td { padding: 0.75rem; } .btn-lg { padding: 0.625rem 1.25rem; font-size: 1rem; } .login-card { margin: 2rem 1rem; padding: 1.5rem; } .modal-dialog { margin: 0.5rem; } } @media (max-width: 575.98px) { .stat-card { padding: 1rem; } .stat-value { font-size: 1.75rem; } .stat-label { font-size: 0.75rem; } /* Stack action buttons on small screens */ .btn-group { flex-direction: column; } .btn-group .btn { border-radius: var(--radius-sm) !important; margin-bottom: 0.25rem; } } /* ============================================== Print Styles ============================================== */ @media print { .navbar-custom, .footer, .btn, .pagination { display: none !important; } body { background: white; color: black; } .card { border: 1px solid #ddd; break-inside: avoid; } } /* ============================================== Accessibility Improvements ============================================== */ /* Ensure sufficient contrast for links */ a { color: var(--accent-blue); text-decoration: none; transition: color var(--transition-fast); } a:hover { color: var(--accent-blue-hover); } /* Skip to main content link (hidden by default) */ .skip-link { position: absolute; top: -40px; left: 0; background: var(--accent-blue); color: white; padding: 0.5rem 1rem; z-index: 100; transition: top 0.3s; } .skip-link:focus { top: 0; } /* Reduced motion preference */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } }