spaxel/dashboard/setup.html
jedarden 6bf1e0394a feat(explainability): detection explainability overlay with per-link contributions, Fresnel zones, and BLE identity
Implements the full explainability overlay for understanding why a blob was detected:
- ExplainabilitySnapshot generation with per-link contribution tracking and zone decay
- Fresnel zone ellipsoid geometry computation and 3D wireframe rendering
- WebSocket request_explain / blob_explain flow for on-demand snapshots
- Right-click, long-press, click, and hover tooltip activation paths
- X-ray overlay dims non-contributing elements, highlights contributing links
- Sidebar panel with confidence gauge, links table, sparklines, BLE match card
- Escape key and backdrop click to exit, restoring scene state

Also includes: simple mode removal, CSS cleanup, fleet page enhancements, sidebar timeline fixes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 19:23:55 -04:00

77 lines
2.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>Spaxel — Setup</title>
<link rel="stylesheet" href="css/tokens.css">
<link rel="stylesheet" href="css/layout.css">
<link rel="stylesheet" href="css/panels.css">
<link rel="stylesheet" href="css/floorplan.css">
<style>
.app-shell--live .setup-header {
height: 44px;
gap: var(--space-4);
font-size: var(--text-sm);
}
.setup-header__link {
color: var(--text-secondary);
text-decoration: none;
font-size: var(--text-sm);
}
.setup-header__link:hover {
color: var(--text-primary);
}
#status-text {
color: var(--text-secondary);
flex: 1;
}
</style>
</head>
<body class="has-mobile-nav">
<div class="app-shell app-shell--live">
<nav class="app-header setup-header">
<a href="/" class="setup-header__link">&larr; Home</a>
<span style="color:var(--text-primary);font-weight:600;">Spaxel Setup</span>
<span id="status-text"></span>
<a href="/live" class="setup-header__link">Live View</a>
</nav>
<main class="app-main">
<div id="scene-container"></div>
</main>
</div><!-- /.app-shell -->
<div class="setup-toolbar">
<button id="btn-floorplan">Floor Plan</button>
<button id="btn-nodes">Nodes</button>
<button id="btn-zones">Zones</button>
<button id="btn-coverage">Coverage</button>
<button id="btn-calibrate">Calibrate</button>
</div>
<script src="js/viz3d.js"></script>
<script src="js/websocket.js"></script>
<script src="js/app.js"></script>
<script src="js/placement.js"></script>
<script src="js/floorplan-setup.js"></script>
<script src="js/zone-editor.js"></script>
<script src="js/portal.js"></script>
<script>
// Auto-activate setup mode
document.addEventListener('DOMContentLoaded', function () {
// Open the placement/setup panels on load
if (typeof Placement !== 'undefined' && Placement.init) {
Placement.init();
}
if (typeof FloorPlanSetup !== 'undefined' && FloorPlanSetup.init) {
FloorPlanSetup.init();
}
});
</script>
</body>
</html>