Spaces:
Running
Running
| /* Custom scrollbar */ | |
| ::-webkit-scrollbar { | |
| width: 6px; | |
| height: 6px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: #0f172a; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: #334155; | |
| border-radius: 3px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: #475569; | |
| } | |
| /* Camera Feed Styles */ | |
| .camera-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); | |
| gap: 1rem; | |
| padding: 1rem; | |
| } | |
| .camera-feed-wrapper { | |
| background: #1e293b; | |
| border: 1px solid #334155; | |
| border-radius: 8px; | |
| overflow: hidden; | |
| position: relative; | |
| } | |
| .camera-feed-wrapper.single-view { | |
| grid-column: 1 / -1; | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| } | |
| /* CRM Styles */ | |
| .client-form input, | |
| .client-form select { | |
| transition: border-color 0.2s; | |
| } | |
| .client-form input:focus, | |
| .client-form select:focus { | |
| outline: none; | |
| border-color: #06b6d4; | |
| box-shadow: 0 0 0 3px rgba(6, 182, 212, 0.1); | |
| } | |
| /* ONVIF Scanner Animation */ | |
| @keyframes scanPulse { | |
| 0%, 100% { opacity: 0.4; } | |
| 50% { opacity: 1; } | |
| } | |
| .scanning-active { | |
| animation: scanPulse 1.5s ease-in-out infinite; | |
| } | |
| /* Fullscreen camera override */ | |
| camera-feed:fullscreen { | |
| width: 100vw; | |
| height: 100vh; | |
| background: black; | |
| } | |
| camera-feed:fullscreen .camera-container { | |
| height: 100%; | |
| } | |
| /* Animations */ | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(-5px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| @keyframes fadeOut { | |
| from { opacity: 1; transform: translateY(0); } | |
| to { opacity: 0; transform: translateY(-5px); } | |
| } | |
| @keyframes pulse-red { | |
| 0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); } | |
| 70% { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); } | |
| } | |
| @keyframes scan-line { | |
| 0% { transform: translateX(-100%); } | |
| 100% { transform: translateX(200%); } | |
| } | |
| .animate-fade-in { | |
| animation: fadeIn 0.3s ease-out forwards; | |
| } | |
| .alert-pulse { | |
| animation: pulse-red 2s infinite; | |
| } | |
| /* Map Dots */ | |
| .map-dot { | |
| width: 24px; | |
| height: 24px; | |
| border-radius: 50%; | |
| background-color: #06b6d4; | |
| box-shadow: 0 0 8px #06b6d4; | |
| transition: all 0.5s ease-in-out; | |
| opacity: 0; | |
| transform: scale(0); | |
| position: absolute; | |
| z-index: 20; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 10px; | |
| font-weight: bold; | |
| color: white; | |
| border: 2px solid rgba(255, 255, 255, 0.3); | |
| } | |
| .map-dot.active { | |
| opacity: 1; | |
| transform: scale(1); | |
| animation: dotPulse 1.5s ease-in-out infinite; | |
| } | |
| .map-dot.latent { | |
| background-color: #f59e0b; | |
| box-shadow: 0 0 10px #f59e0b, 0 0 20px rgba(245, 158, 11, 0.5); | |
| animation: dotWarning 1s ease-in-out infinite; | |
| border-color: rgba(255, 255, 255, 0.5); | |
| } | |
| .map-dot.confirmed { | |
| background-color: #ef4444; | |
| box-shadow: 0 0 15px #ef4444, 0 0 30px rgba(239, 68, 68, 0.5); | |
| animation: dotAlert 0.5s ease-in-out infinite; | |
| border-color: rgba(255, 255, 255, 0.8); | |
| } | |
| /* Zone hover effects enhancement */ | |
| [id^="zone-"] { | |
| transition: all 0.3s ease; | |
| position: relative; | |
| overflow: visible; | |
| } | |
| [id^="zone-"]:hover { | |
| transform: scale(1.02); | |
| z-index: 10; | |
| box-shadow: 0 0 20px rgba(6, 182, 212, 0.2); | |
| } | |
| @keyframes dotPulse { | |
| 0%, 100% { box-shadow: 0 0 8px #06b6d4; } | |
| 50% { box-shadow: 0 0 16px #06b6d4, 0 0 24px rgba(6, 182, 212, 0.5); } | |
| } | |
| @keyframes dotWarning { | |
| 0%, 100% { transform: scale(1); } | |
| 50% { transform: scale(1.2); } | |
| } | |
| @keyframes dotAlert { | |
| 0%, 100% { transform: scale(1); opacity: 1; } | |
| 50% { transform: scale(1.3); opacity: 0.8; } | |
| } | |
| /* Scan Beam Effect */ | |
| #scan-beam { | |
| background: linear-gradient(90deg, transparent, rgba(34, 197, 94, 0.8), #22c55e, rgba(34, 197, 94, 0.8), transparent); | |
| width: 150px; | |
| height: 100%; | |
| position: absolute; | |
| animation: scan-line 2s linear infinite; | |
| filter: blur(2px); | |
| } | |
| /* Custom Styles for Web Component Shadow DOM to allow global theme leaking if needed, | |
| but usually we encapsulate. Here we just fix base styling. */ | |
| sentinel-navbar { | |
| display: block; | |
| width: 100%; | |
| } | |
| /* Hover effects for map zones */ | |
| [id^="zone-"] { | |
| transition: all 0.3s ease; | |
| } | |
| [id^="zone-"]:hover { | |
| transform: scale(1.02); | |
| z-index: 5; | |
| } | |
| /* Simulation button active state */ | |
| .sim-btn:active { | |
| transform: scale(0.95); | |
| } | |
| /* Modal animations */ | |
| .modal-enter { | |
| animation: modalFadeIn 0.3s ease-out; | |
| } | |
| @keyframes modalFadeIn { | |
| from { opacity: 0; transform: scale(0.95); } | |
| to { opacity: 1; transform: scale(1); } | |
| } | |
| /* Camera status indicators */ | |
| .status-online { color: #22c55e; } | |
| .status-offline { color: #ef4444; } | |
| .status-warning { color: #f59e0b; } | |
| /* PTZ Controls overlay */ | |
| .ptz-overlay { | |
| position: absolute; | |
| inset: 0; | |
| background: rgba(0,0,0,0.3); | |
| opacity: 0; | |
| transition: opacity 0.3s; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .camera-container:hover .ptz-overlay { | |
| opacity: 1; | |
| } | |
| /* NVR Status Panel Animations */ | |
| @keyframes dataPulse { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0.5; } | |
| } | |
| .animate-data-flow { | |
| animation: dataPulse 2s ease-in-out infinite; | |
| } | |
| /* Uptime counter styling */ | |
| #uptime { | |
| font-variant-numeric: tabular-nums; | |
| letter-spacing: 0.05em; | |
| } | |