/* ========================================================================= Loading Overlay ========================================================================= */ #loading-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 9999; align-items: center; justify-content: center; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); opacity: 0; transition: opacity 0.4s ease; } #loading-overlay.show { display: flex; opacity: 1; } /* ========================================================================= Auth Page ========================================================================= */ #loginPage { min-height: 100vh; display: flex; align-items: center; justify-content: center; background-color: #f3f4f6; padding: 3rem 1rem; position: relative; z-index: 1; } #loginPage.hidden { display: none !important; } #mainContent.hidden { display: none !important; } nav.hidden { display: none !important; } #footer.hidden { display: none !important; } body[data-oidc-enabled="false"] #loginPage { display: none !important; visibility: hidden !important; } body[data-skip-login-page="true"] #loginPage { display: none !important; visibility: hidden !important; } body:has(#loginPage:not(.hidden)) { background-color: #f3f4f6; overflow: hidden; } /* ========================================================================= Layout ========================================================================= */ #restartBanner { display: none; } #serverManagerList { min-height: 480px; } ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: #f1f1f1; } ::-webkit-scrollbar-thumb { background: #888; border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: #555; } /* ========================================================================= Select2 Overrides ========================================================================= */ .select2-container--default .select2-selection--multiple { border: 1px solid #d1d5db; border-radius: 0.375rem; padding: 0.25rem 0.5rem; min-height: 42px; } .select2-container--default .select2-selection--multiple .select2-selection__choice { background-color: #3b82f6; border: 1px solid #3b82f6; color: white; border-radius: 0.25rem; padding: 0 0.5rem; } .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { color: white; margin-right: 0.25rem; } /* ========================================================================= Modals ========================================================================= */ .modal-content { box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); } body.modal-open { overflow: hidden !important; } /* ========================================================================= Tooltips ========================================================================= */ .tooltip { position: relative; display: inline-block; } .tooltip .tooltip-text { visibility: hidden; width: 200px; background-color: #333; color: #fff; text-align: center; border-radius: 6px; padding: 5px; position: absolute; z-index: 1; bottom: 125%; left: 50%; margin-left: -100px; opacity: 0; transition: opacity 0.3s; } .tooltip:hover .tooltip-text { visibility: visible; opacity: 1; } /* ========================================================================= Search Highlights ========================================================================= */ mark { background-color: #fef08a; padding: 0.1em 0em 0.1em 0.2em; border-radius: 0.25em; } /* ========================================================================= Toast Notifications ========================================================================= */ #toast-container { position: fixed; top: 1.5rem; right: 1.5rem; display: flex; flex-direction: column; gap: 0.5rem; z-index: 10000; pointer-events: none; } .toast { min-width: 240px; max-width: 360px; padding: 0.75rem 1rem; border-radius: 0.5rem; color: #fff; pointer-events: auto; font-weight: 500; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); opacity: 0; transform: translateY(-6px); transition: opacity 0.25s ease, transform 0.25s ease; } .toast.show { opacity: 1; transform: translateY(0); } .toast-success { background-color: #047857; } .toast-error { background-color: #b91c1c; } .toast-info { background-color: #1d4ed8; } .toast-warning { background-color: #d97706; } .toast-ban-event { background-color: #7f1d1d; pointer-events: auto; cursor: pointer; } .toast-ban-event:hover { background-color: #991b1b; transform: translateY(-2px); box-shadow: 0 15px 20px -3px rgba(0, 0, 0, 0.15); } .toast-unban-event { background-color: #14532d; pointer-events: auto; cursor: pointer; } .toast-unban-event:hover { background-color: #166534; transform: translateY(-2px); box-shadow: 0 15px 20px -3px rgba(0, 0, 0, 0.15); } /* ========================================================================= Status Indicator ========================================================================= */ #backendStatus { display: flex; align-items: center; gap: 0.5rem; padding: 0.25rem 0.5rem; margin-left: 5px; border-radius: 0.25rem; transition: background-color 0.2s ease; } #statusDot { width: 0.5rem; height: 0.5rem; border-radius: 50%; display: inline-block; transition: background-color 0.3s ease, box-shadow 0.3s ease; box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7); animation: pulse 2s infinite; } #statusDot.bg-green-500 { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7); animation: pulseGreen 2s infinite; } #statusDot.bg-yellow-500 { box-shadow: 0 0 0 0 rgba(234, 179, 8, 0.7); animation: pulseYellow 2s infinite; } #statusDot.bg-red-500 { box-shadow: 0 0 0 0 rgb(163 44 44); animation: pulseRed 2s infinite; } #statusDot.bg-gray-400 { animation: none; } #statusText { font-size: 0.75rem; font-weight: 500; color: rgba(255, 255, 255, 0.9); white-space: nowrap; } @keyframes pulseGreen { 0% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7); } 70% { box-shadow: 0 0 0 4px rgba(34, 197, 94, 0); } 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); } } @keyframes pulseYellow { 0% { box-shadow: 0 0 0 0 rgba(234, 179, 8, 0.7); } 70% { box-shadow: 0 0 0 4px rgba(234, 179, 8, 0); } 100% { box-shadow: 0 0 0 0 rgba(234, 179, 8, 0); } } @keyframes pulseRed { 0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); } 70% { box-shadow: 0 0 0 4px rgba(239, 68, 68, 0); } 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); } } /* ========================================================================= Clock ========================================================================= */ #clockDisplay { display: flex; align-items: center; padding: 0.25rem 0.75rem; border-radius: 0.25rem; background-color: rgba(255, 255, 255, 0.1); transition: background-color 0.2s ease; } #clockDisplay:hover { background-color: rgba(255, 255, 255, 0.15); } #clockTime { font-family: 'Courier New', Courier, monospace; font-size: 0.875rem; font-weight: 600; color: rgba(255, 255, 255, 0.95); letter-spacing: 0.05em; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } /* ========================================================================= Responsive Overrides ========================================================================= */ /* Override Tailwind md: (768px) to collapse menu at 830px */ @media (max-width: 830px) { nav .hidden.md\:block { display: none !important; } nav > div > div > div.md\:hidden:not(#mobileMenu) { display: block !important; } nav #mobileMenu:not(.hidden) { display: block !important; } nav #mobileMenu.hidden { display: none !important; } } @media (max-width: 768px) { #backendStatus { padding: 0.125rem 0.375rem; } #statusText { font-size: 0.625rem; } #clockDisplay { padding: 0.125rem 0.5rem; } #clockTime { font-size: 0.75rem; } } /* ========================================================================= Integration Fields ========================================================================= */ #advancedMikrotikFields, #advancedPfSenseFields, #advancedOPNsenseFields { padding: 10px; } /* ========================================================================= Font Awesome Fallback ========================================================================= */ /* Ensure icons render when FA is loaded async or partially */ .fas, .far, .fab, .fal, .fad { font-family: "Font Awesome 6 Free", "Font Awesome 6 Brands", "Font Awesome 6 Pro"; font-weight: 900; display: inline-block; font-style: normal; font-variant: normal; text-rendering: auto; line-height: 1; } .fas::before { font-weight: 900; } button .fas, button .far, button .fab { display: inline-block; width: 1em; text-align: center; margin-right: 0.25rem; } button .fas:only-child, button .far:only-child, button .fab:only-child { margin-right: 0; } /* ========================================================================= WebSocket Tooltip ========================================================================= */ #wsTooltip { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; line-height: 1.5; } /* ========================================================================= Ignore IPs ========================================================================= */ /* Prevent horizontal overflow on long IP lists */ #ignoreIPsContainer { overflow-x: hidden; word-wrap: break-word; overflow-wrap: break-word; } #ignoreIPsTags { max-width: 100%; overflow-wrap: anywhere; word-break: break-word; } .ignore-ip-tag { max-width: 100%; word-break: break-all; overflow-wrap: anywhere; }