* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #0a0a0a; color: #fff; min-height: 100vh; } .header { background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); padding: 15px 30px; border-bottom: 2px solid #0f3460; display: flex; justify-content: space-between; align-items: center; } .header h1 { font-size: 20px; color: #e94560; } .status-bar { display: flex; gap: 20px; font-size: 13px; } .status-item { display: flex; align-items: center; gap: 8px; } .status-dot { width: 8px; height: 8px; border-radius: 50%; background: #28a745; animation: pulse 2s infinite; } .status-dot.warning { background: #ffc107; } .status-dot.error { background: #dc3545; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .container { padding: 20px; display: grid; grid-template-columns: repeat(auto-fill, minmax(480px, 1fr)); gap: 20px; } .video-card { background: #1a1a2e; border-radius: 12px; overflow: hidden; border: 1px solid #0f3460; } .video-header { padding: 12px 15px; background: #16213e; display: flex; justify-content: space-between; align-items: center; } .video-title { font-size: 14px; font-weight: 600; } .video-status { display: flex; align-items: center; gap: 8px; font-size: 12px; } .detection-badge { padding: 3px 10px; border-radius: 20px; font-size: 11px; font-weight: 600; } .detection-badge.idle { background: #28a745; } .detection-badge.detected { background: #e94560; animation: blink 1s infinite; } @keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } } .video-container { position: relative; background: #000; aspect-ratio: 16/9; } .video-container video, .video-container canvas, .video-container img { width: 100%; height: 100%; object-fit: contain; } .roi-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } .video-info { padding: 12px 15px; background: #16213e; font-size: 12px; } .info-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; } .info-item { display: flex; justify-content: space-between; padding: 4px 0; border-bottom: 1px solid #0f3460; } .info-label { color: #888; } .info-value { color: #fff; font-family: monospace; } .info-value.detected { color: #e94560; font-weight: bold; } .log-panel { position: fixed; right: 20px; bottom: 20px; width: 400px; max-height: 300px; background: rgba(26, 26, 46, 0.95); border: 1px solid #0f3460; border-radius: 8px; overflow: hidden; } .log-header { padding: 10px 15px; background: #16213e; font-size: 13px; font-weight: 600; display: flex; justify-content: space-between; align-items: center; } .log-content { padding: 10px; font-size: 11px; font-family: 'Consolas', monospace; max-height: 250px; overflow-y: auto; } .log-entry { padding: 3px 0; border-bottom: 1px solid #0f3460; } .log-time { color: #888; } .log-event { color: #e94560; } .log-info { color: #28a745; } .empty-state { text-align: center; padding: 60px; color: #666; } .nav-links { display: flex; gap: 15px; } .nav-links a { color: #fff; text-decoration: none; padding: 8px 16px; border-radius: 6px; background: #0f3460; font-size: 13px; transition: all 0.3s; } .nav-links a:hover, .nav-links a.active { background: #e94560; } /* 处理切换按钮 */ .process-toggle { display: flex; gap: 5px; margin-left: 10px; } .toggle-btn { padding: 4px 12px; border: 1px solid #0f3460; background: #1a1a2e; color: #888; border-radius: 4px; cursor: pointer; font-size: 11px; transition: all 0.3s; } .toggle-btn:hover { background: #0f3460; color: #fff; } .toggle-btn.active { background: #e94560; border-color: #e94560; color: #fff; } /* 视频画面切换 */ .video-frame { width: 100%; height: 100%; object-fit: contain; } .video-frame.hidden { display: none; }