secubox-openwrt/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/crowdsec-dashboard/dashboard.css
CyberMind-FR f46e145927 feat(crowdsec): Add geo heatmap visualization for threat origins
- New heatmap.js component with SVG world map and country centroids
- Colored dots show threat distribution: orange (local), cyan (CAPI), red (WAF)
- Dot size scales logarithmically with threat count (4-20px)
- Hover tooltips show country code and count
- Added geo_local_raw and geo_capi_raw fields to RPCD backend
- CAPI geo extraction from decisions with GeoIP metadata
- CSS styling for heatmap container, dots, and legend

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-16 09:28:48 +01:00

170 lines
8.2 KiB
CSS

/* CrowdSec Dashboard - KISS CSS */
:root {
--cs-bg: var(--cyber-bg-primary, #1a1a2e);
--cs-surface: var(--cyber-bg-secondary, #16213e);
--cs-border: var(--cyber-border, #2d3748);
--cs-text: var(--cyber-text-primary, #e2e8f0);
--cs-muted: var(--cyber-text-muted, #718096);
--cs-accent: var(--cyber-accent-primary, #667eea);
--cs-success: var(--cyber-success, #10b981);
--cs-warning: var(--cyber-warning, #f59e0b);
--cs-danger: var(--cyber-danger, #ef4444);
}
.cs-view { max-width: 1200px; margin: 0 auto; padding: 1rem; }
/* Header */
.cs-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 1px solid var(--cs-border); }
.cs-title { font-size: 1.25rem; font-weight: 600; color: var(--cs-text); }
.cs-status { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; }
.cs-dot { width: 8px; height: 8px; border-radius: 50%; }
.cs-dot.online { background: var(--cs-success); }
.cs-dot.offline { background: var(--cs-danger); }
/* Nav */
.cs-nav { display: flex; gap: 0.25rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--cs-border); }
.cs-nav a { padding: 0.75rem 1rem; color: var(--cs-muted); text-decoration: none; border-bottom: 2px solid transparent; }
.cs-nav a:hover { color: var(--cs-text); }
.cs-nav a.active { color: var(--cs-accent); border-bottom-color: var(--cs-accent); }
/* Cards */
.cs-card { background: var(--cs-surface); border: 1px solid var(--cs-border); border-radius: 0.5rem; margin-bottom: 1rem; }
.cs-card-header { padding: 0.75rem 1rem; border-bottom: 1px solid var(--cs-border); font-weight: 600; display: flex; justify-content: space-between; align-items: center; }
.cs-card-body { padding: 1rem; }
/* Grid */
.cs-grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1rem; }
/* Stats */
.cs-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
.cs-stat { background: var(--cs-surface); border: 1px solid var(--cs-border); border-radius: 0.5rem; padding: 1rem; text-align: center; }
.cs-stat-value { font-size: 1.5rem; font-weight: 700; color: var(--cs-text); }
.cs-stat-label { font-size: 0.75rem; color: var(--cs-muted); margin-top: 0.25rem; }
.cs-stat.success .cs-stat-value { color: var(--cs-success); }
.cs-stat.warning .cs-stat-value { color: var(--cs-warning); }
.cs-stat.danger .cs-stat-value { color: var(--cs-danger); }
/* Tables */
.cs-table { width: 100%; border-collapse: collapse; }
.cs-table th, .cs-table td { padding: 0.75rem; text-align: left; border-bottom: 1px solid var(--cs-border); }
.cs-table th { color: var(--cs-muted); font-weight: 500; font-size: 0.75rem; text-transform: uppercase; }
.cs-table tr:hover { background: rgba(255,255,255,0.02); }
/* Badges */
.cs-badge { display: inline-block; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 0.75rem; font-weight: 500; }
.cs-badge.success { background: rgba(16,185,129,0.2); color: var(--cs-success); }
.cs-badge.warning { background: rgba(245,158,11,0.2); color: var(--cs-warning); }
.cs-badge.danger { background: rgba(239,68,68,0.2); color: var(--cs-danger); }
/* Buttons */
.cs-btn { padding: 0.5rem 1rem; border: 1px solid var(--cs-border); border-radius: 0.375rem; background: var(--cs-surface); color: var(--cs-text); cursor: pointer; font-size: 0.875rem; }
.cs-btn:hover { background: var(--cs-border); }
.cs-btn.primary { background: var(--cs-accent); border-color: var(--cs-accent); }
.cs-btn.danger { background: var(--cs-danger); border-color: var(--cs-danger); }
.cs-btn-sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; }
/* Forms */
.cs-input { width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--cs-border); border-radius: 0.375rem; background: var(--cs-bg); color: var(--cs-text); }
.cs-input:focus { outline: none; border-color: var(--cs-accent); }
.cs-label { display: block; margin-bottom: 0.25rem; color: var(--cs-muted); font-size: 0.875rem; }
.cs-field { margin-bottom: 1rem; }
/* Health checks */
.cs-health { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.5rem; }
.cs-health-item { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem; }
.cs-health-icon { width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.75rem; }
.cs-health-icon.ok { background: rgba(16,185,129,0.2); color: var(--cs-success); }
.cs-health-icon.error { background: rgba(239,68,68,0.2); color: var(--cs-danger); }
.cs-health-icon.warn { background: rgba(245,158,11,0.2); color: var(--cs-warning); }
.cs-health-label { font-size: 0.75rem; color: var(--cs-muted); }
.cs-health-value { font-size: 0.875rem; color: var(--cs-text); }
/* Status Grid (Setup page) */
.cs-status-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; }
.cs-status-item { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem; background: var(--cs-bg); border-radius: 0.375rem; }
.cs-status-icon { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1rem; flex-shrink: 0; }
.cs-status-icon.ok { background: rgba(16,185,129,0.2); color: var(--cs-success); }
.cs-status-icon.error { background: rgba(239,68,68,0.2); color: var(--cs-danger); }
.cs-status-info { flex: 1; min-width: 0; }
.cs-status-label { font-size: 0.875rem; font-weight: 500; color: var(--cs-text); }
.cs-status-detail { font-size: 0.75rem; color: var(--cs-muted); margin-top: 0.125rem; }
/* Toast info variant */
.cs-toast.info { border-color: var(--cs-accent); }
/* Empty/Loading */
.cs-empty { text-align: center; padding: 2rem; color: var(--cs-muted); }
.cs-loading { text-align: center; padding: 2rem; }
.cs-spinner { display: inline-block; width: 24px; height: 24px; border: 2px solid var(--cs-border); border-top-color: var(--cs-accent); border-radius: 50%; animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
/* Toast */
.cs-toast { position: fixed; bottom: 1rem; right: 1rem; padding: 0.75rem 1rem; border-radius: 0.375rem; background: var(--cs-surface); border: 1px solid var(--cs-border); z-index: 9999; }
.cs-toast.success { border-color: var(--cs-success); }
.cs-toast.error { border-color: var(--cs-danger); }
/* Misc */
.cs-ip { font-family: monospace; background: var(--cs-bg); padding: 0.125rem 0.375rem; border-radius: 0.25rem; }
.cs-scenario { font-family: monospace; font-size: 0.75rem; }
.cs-time { font-size: 0.75rem; color: var(--cs-muted); }
.cs-severity { padding: 0.125rem 0.375rem; border-radius: 0.25rem; font-size: 0.625rem; font-weight: 600; text-transform: uppercase; }
.cs-severity.low { background: rgba(16,185,129,0.2); color: var(--cs-success); }
.cs-severity.medium { background: rgba(245,158,11,0.2); color: var(--cs-warning); }
.cs-severity.high, .cs-severity.critical { background: rgba(239,68,68,0.2); color: var(--cs-danger); }
/* Geo */
.cs-geo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); gap: 0.5rem; }
.cs-geo-item { display: flex; flex-direction: column; align-items: center; padding: 0.5rem; }
.cs-flag { font-size: 1.25rem; }
.cs-geo-count { font-weight: 600; }
.cs-country { font-size: 0.625rem; color: var(--cs-muted); }
/* Heatmap */
.cs-heatmap-container {
position: relative;
width: 100%;
background: var(--kiss-bg2, #1a1d21);
border-radius: 8px;
overflow: hidden;
}
.cs-heatmap-svg {
display: block;
width: 100%;
height: auto;
}
.cs-heatmap-dot {
transition: transform 0.2s ease, opacity 0.2s ease;
cursor: pointer;
}
.cs-heatmap-dot:hover {
transform: scale(1.4);
opacity: 1 !important;
}
.cs-heatmap-legend {
display: flex;
justify-content: center;
gap: 24px;
padding: 12px 0;
background: rgba(0,0,0,0.2);
border-top: 1px solid var(--kiss-border, #2d3139);
}
.cs-heatmap-legend-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: var(--kiss-muted, #8b949e);
}
.cs-heatmap-legend-dot {
width: 10px;
height: 10px;
border-radius: 50%;
display: inline-block;
}
@media (max-width: 768px) {
.cs-stats { grid-template-columns: repeat(2, 1fr); }
.cs-grid-2 { grid-template-columns: 1fr; }
.cs-heatmap-legend { flex-direction: column; align-items: center; gap: 8px; }
}