spaxel/dashboard/css/apdetection.css
jedarden d2e5b4d4a0 feat: implement passive radar auto-detection of router AP
Automatically detect the home router as a passive radar TX source,
eliminating need for a dedicated active TX node.

Firmware changes:
- During hello message, include ap_bssid and ap_channel from esp_wifi_sta_get_ap_info()

Mothership changes:
- On hello: extract ap_bssid; if >=80% of nodes report same BSSID create virtual node entry with virtual=1
- OUI lookup: embedded IEEE OUI registry as Go map compiled via go:embed; display router brand
- Detect AP BSSID change (router reboot/replacement) and emit system alert
- SQLite nodes table: add virtual BOOL, node_type TEXT, ap_bssid TEXT, ap_channel INT columns

Dashboard changes:
- Show "I detected your router (ASUS). Place it on the floor plan..." notification
- Render virtual AP nodes with distinct router icon in 3D view
- Drag-to-place virtual node (distinct router icon) in 3D editor

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 14:03:03 -04:00

211 lines
3.4 KiB
CSS

/**
* Spaxel Dashboard - AP Detection Panel Styles
*
* Styles for the router AP detection banner and placement UI.
*/
/* ============================================
AP Detection Banner
============================================ */
.ap-detection-banner {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
transform: translateY(-100%);
transition: transform 0.3s ease-out;
}
.ap-detection-banner-visible {
transform: translateY(0);
}
.ap-detection-content {
display: flex;
align-items: center;
padding: 16px 24px;
max-width: 800px;
margin: 0 auto;
color: white;
}
.ap-detection-icon {
font-size: 28px;
margin-right: 16px;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.1);
opacity: 0.8;
}
}
.ap-detection-message {
flex: 1;
}
.ap-detection-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 4px;
}
.ap-detection-subtitle {
font-size: 14px;
opacity: 0.9;
}
.ap-detection-actions {
display: flex;
gap: 12px;
margin-left: 16px;
}
/* ============================================
AP Placement Content
============================================ */
.ap-placement-content {
padding: 16px 0;
}
.ap-placement-list {
list-style: none;
padding: 0;
margin: 16px 0;
}
.ap-placement-list li {
padding: 8px 0;
padding-left: 24px;
position: relative;
}
.ap-placement-list li:before {
content: "•";
position: absolute;
left: 0;
color: #667eea;
font-weight: bold;
}
.ap-placement-tips {
margin-top: 20px;
}
.ap-placement-tip {
background: #f0f4ff;
border-left: 4px solid #667eea;
padding: 12px;
border-radius: 4px;
font-size: 14px;
color: #444;
}
/* ============================================
Responsive Design
============================================ */
@media (max-width: 768px) {
.ap-detection-content {
flex-direction: column;
text-align: center;
}
.ap-detection-icon {
margin-right: 0;
margin-bottom: 12px;
}
.ap-detection-actions {
margin-left: 0;
margin-top: 16px;
width: 100%;
}
.ap-detection-actions button {
flex: 1;
}
.ap-placement-list li {
padding-left: 0;
}
.ap-placement-list li:before {
display: none;
}
}
/* ============================================
Button Styles
============================================ */
.ap-btn {
padding: 10px 20px;
border: none;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.ap-btn-primary {
background: white;
color: #667eea;
}
.ap-btn-primary:hover {
background: #f0f0f0;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.ap-btn-secondary {
background: rgba(255, 255, 255, 0.2);
color: white;
border: 1px solid rgba(255, 255, 255, 0.3);
}
.ap-btn-secondary:hover {
background: rgba(255, 255, 255, 0.3);
}
.ap-btn:active {
transform: translateY(0);
}
/* ============================================
3D View Router Icon
============================================ */
/* Distinct router icon for virtual AP nodes in 3D view */
.virtual-node-router {
fill: #667eea;
stroke: #764ba2;
stroke-width: 1;
}
.virtual-node-router-glow {
opacity: 0.5;
animation: glow-pulse 2s ease-in-out infinite;
}
@keyframes glow-pulse {
0%, 100% {
opacity: 0.3;
}
50% {
opacity: 0.6;
}
}