mirror of
https://github.com/azaion/ui.git
synced 2026-06-21 13:31:10 +00:00
2a62415f0c
ui_design v2: tactical-ops redesign of all 5 pages Two parallel takes on visual polish for flights, annotations, dataset explorer, admin, and settings. - v2/plugin/ — self-contained HTML produced via the frontend-design plugin, adheres to v2/plugin/_design_system.md.. - v2/stitch/ — Google Stitch MCP exports against the same design system. IA from the original wireframes in _docs/ui_design/ is preserved verbatim — this pass is visual only.
896 lines
45 KiB
HTML
896 lines
45 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>AZAION // FLIGHTS — Tactical Ops</title>
|
||
<script src="https://cdn.tailwindcss.com"></script>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root {
|
||
--surface-0: #0A0D10;
|
||
--surface-1: #13171C;
|
||
--surface-2: #1A1F26;
|
||
--surface-input: #0A0D10;
|
||
--border-hair: #252B34;
|
||
--border-raised: #3B4451;
|
||
--text-primary: #E8ECF1;
|
||
--text-secondary:#9AA4B2;
|
||
--text-muted: #5B6573;
|
||
--accent-amber: #FF9D3D;
|
||
--accent-cyan: #36D6C5;
|
||
--accent-red: #FF4756;
|
||
--accent-green: #3DDC84;
|
||
--accent-blue: #4E9EFF;
|
||
}
|
||
html, body {
|
||
background: var(--surface-0);
|
||
color: var(--text-primary);
|
||
}
|
||
body {
|
||
font-family: 'IBM Plex Sans', system-ui, sans-serif;
|
||
font-size: 13px;
|
||
line-height: 1.5;
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
.mono { font-family: 'JetBrains Mono', ui-monospace, monospace; font-variant-numeric: tabular-nums; }
|
||
.num { font-variant-numeric: tabular-nums; font-family: 'JetBrains Mono', ui-monospace, monospace; }
|
||
|
||
.micro {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 10px;
|
||
line-height: 1.4;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
color: var(--text-secondary);
|
||
}
|
||
.section-head {
|
||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||
font-size: 11px;
|
||
line-height: 1.2;
|
||
letter-spacing: 0.14em;
|
||
text-transform: uppercase;
|
||
color: var(--accent-amber);
|
||
}
|
||
|
||
/* Corner brackets */
|
||
.bracket { position: relative; }
|
||
.bracket::before, .bracket::after,
|
||
.bracket > .br::before, .bracket > .br::after {
|
||
content: ''; position: absolute; width: 8px; height: 8px;
|
||
border-color: var(--accent-amber); border-style: solid; border-width: 0;
|
||
pointer-events: none;
|
||
}
|
||
.bracket::before { top: -1px; left: -1px; border-top-width: 1px; border-left-width: 1px; }
|
||
.bracket::after { top: -1px; right: -1px; border-top-width: 1px; border-right-width: 1px; }
|
||
.bracket > .br::before { bottom: -1px; left: -1px; border-bottom-width: 1px; border-left-width: 1px; }
|
||
.bracket > .br::after { bottom: -1px; right: -1px; border-bottom-width: 1px; border-right-width: 1px; }
|
||
|
||
.bracket-cyan::before, .bracket-cyan::after,
|
||
.bracket-cyan > .br::before, .bracket-cyan > .br::after { border-color: var(--accent-cyan); }
|
||
.bracket-red::before, .bracket-red::after,
|
||
.bracket-red > .br::before, .bracket-red > .br::after { border-color: var(--accent-red); }
|
||
|
||
.hair { border-color: var(--border-hair); }
|
||
.panel { background: var(--surface-1); border: 1px solid var(--border-hair); }
|
||
|
||
/* Buttons */
|
||
.btn-primary {
|
||
background: var(--accent-amber); color: #0A0D10; border: 1px solid var(--accent-amber);
|
||
padding: 6px 14px; font-family: 'JetBrains Mono', monospace; font-size: 11px;
|
||
letter-spacing: 0.08em; text-transform: uppercase; font-weight: 600;
|
||
transition: filter .12s;
|
||
}
|
||
.btn-primary:hover { filter: brightness(1.08); }
|
||
.btn-secondary {
|
||
background: transparent; color: var(--accent-amber); border: 1px solid var(--accent-amber);
|
||
padding: 6px 14px; font-family: 'JetBrains Mono', monospace; font-size: 11px;
|
||
letter-spacing: 0.08em; text-transform: uppercase;
|
||
}
|
||
.btn-secondary:hover { background: rgba(255,157,61,0.12); }
|
||
.btn-ghost {
|
||
background: transparent; color: var(--text-secondary); border: 1px solid var(--border-hair);
|
||
padding: 6px 14px; font-family: 'JetBrains Mono', monospace; font-size: 11px;
|
||
letter-spacing: 0.08em; text-transform: uppercase;
|
||
}
|
||
.btn-ghost:hover { color: var(--text-primary); border-color: var(--border-raised); }
|
||
.btn-danger {
|
||
background: var(--accent-red); color: #0A0D10; border: 1px solid var(--accent-red);
|
||
padding: 6px 14px; font-family: 'JetBrains Mono', monospace; font-size: 11px;
|
||
letter-spacing: 0.08em; text-transform: uppercase; font-weight: 600;
|
||
}
|
||
.btn-cyan {
|
||
background: transparent; color: var(--accent-cyan); border: 1px solid var(--accent-cyan);
|
||
padding: 6px 14px; font-family: 'JetBrains Mono', monospace; font-size: 11px;
|
||
letter-spacing: 0.08em; text-transform: uppercase;
|
||
}
|
||
.btn-cyan:hover { background: rgba(54,214,197,0.10); }
|
||
|
||
/* Inputs */
|
||
.ipt {
|
||
background: var(--surface-input); border: 1px solid var(--border-hair);
|
||
border-radius: 2px; padding: 6px 10px; height: 32px;
|
||
font-family: 'IBM Plex Sans', sans-serif; font-size: 12px;
|
||
color: var(--text-primary); width: 100%;
|
||
}
|
||
.ipt:focus { outline: none; border-color: var(--accent-amber); box-shadow: 0 0 0 1px var(--accent-amber); }
|
||
.ipt::placeholder { color: var(--text-muted); }
|
||
.ipt-num { font-variant-numeric: tabular-nums; font-family: 'JetBrains Mono', monospace; }
|
||
select.ipt { appearance: none; background-image:
|
||
linear-gradient(45deg, transparent 50%, var(--text-secondary) 50%),
|
||
linear-gradient(135deg, var(--text-secondary) 50%, transparent 50%);
|
||
background-position: calc(100% - 14px) 14px, calc(100% - 9px) 14px;
|
||
background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 26px; }
|
||
input[type="date"].ipt { color-scheme: dark; }
|
||
|
||
/* Pill / status */
|
||
.pill {
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
padding: 2px 8px; border-radius: 2px; border: 1px solid currentColor;
|
||
font-family: 'JetBrains Mono', monospace; font-size: 10px;
|
||
letter-spacing: 0.12em; text-transform: uppercase;
|
||
background: transparent;
|
||
}
|
||
.pill .dot { width: 6px; height: 6px; border-radius: 9999px; background: currentColor; flex-shrink: 0; }
|
||
.pill-green { color: var(--accent-green); }
|
||
.pill-cyan { color: var(--accent-cyan); }
|
||
.pill-red { color: var(--accent-red); }
|
||
.pill-amber { color: var(--accent-amber); }
|
||
.pill-muted { color: var(--text-secondary); border-color: var(--border-hair); }
|
||
|
||
@keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: .35 } }
|
||
.pulse { animation: pulse 1.6s ease-in-out infinite; }
|
||
|
||
/* Header live-dot — glow-ring animation, matches other plugin pages */
|
||
.live-dot {
|
||
width: 6px; height: 6px; border-radius: 999px;
|
||
background: var(--accent-cyan);
|
||
box-shadow: 0 0 0 0 rgba(54,214,197,0.5);
|
||
animation: liveDotPulse 1.6s ease-in-out infinite;
|
||
display: inline-block;
|
||
flex: none;
|
||
}
|
||
@keyframes liveDotPulse {
|
||
0%,100% { box-shadow: 0 0 0 0 rgba(54,214,197,0.5); }
|
||
50% { box-shadow: 0 0 0 6px rgba(54,214,197,0); }
|
||
}
|
||
|
||
/* Draw-mode selector buttons */
|
||
.dmode {
|
||
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
||
height: 32px; padding: 0 8px;
|
||
font-family: 'JetBrains Mono', monospace;
|
||
font-size: 10px; font-weight: 600;
|
||
letter-spacing: 0.10em; text-transform: uppercase;
|
||
border: 1px solid; border-radius: 2px;
|
||
background: transparent;
|
||
cursor: pointer;
|
||
transition: background-color .12s, color .12s, box-shadow .12s;
|
||
white-space: nowrap;
|
||
}
|
||
.dmode:hover { background-color: rgba(255,255,255,0.04); }
|
||
.dmode-sq { width: 32px; height: 32px; padding: 0; }
|
||
.dmode-amber { color: var(--accent-amber); border-color: var(--accent-amber); }
|
||
.dmode-amber.active { background-color: rgba(255,157,61,0.20); box-shadow: inset 0 0 0 1px var(--accent-amber); }
|
||
.dmode-green { color: var(--accent-green); border-color: var(--accent-green); }
|
||
.dmode-green.active { background-color: rgba(61,220,132,0.18); box-shadow: inset 0 0 0 1px var(--accent-green); }
|
||
.dmode-red { color: var(--accent-red); border-color: var(--accent-red); }
|
||
.dmode-red.active { background-color: rgba(255,71,86,0.18); box-shadow: inset 0 0 0 1px var(--accent-red); }
|
||
|
||
/* Params panel collapse */
|
||
.params-panel { width: 290px; transition: width .18s ease; }
|
||
.params-panel.collapsed { width: 44px; }
|
||
.params-panel.collapsed .panel-body { display: none; }
|
||
.params-panel:not(.collapsed) .collapsed-rail { display: none; }
|
||
.collapsed-rail {
|
||
display: flex; flex-direction: column; align-items: center; gap: 8px;
|
||
padding: 10px 6px;
|
||
}
|
||
.rail-btn {
|
||
width: 32px; height: 32px;
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
border: 1px solid var(--border-hair); border-radius: 2px;
|
||
background: var(--surface-0); color: var(--text-secondary);
|
||
cursor: pointer; transition: color .12s, border-color .12s, background-color .12s;
|
||
font-family: 'JetBrains Mono', monospace; font-size: 12px;
|
||
}
|
||
.rail-btn:hover { color: var(--text-primary); border-color: var(--border-raised); background: var(--surface-2); }
|
||
.collapse-btn {
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
width: 26px; height: 26px;
|
||
border: 1px solid var(--border-hair); border-radius: 2px;
|
||
background: var(--surface-1); color: var(--text-secondary);
|
||
cursor: pointer; transition: color .12s, border-color .12s;
|
||
font-family: 'JetBrains Mono', monospace; font-size: 12px;
|
||
}
|
||
.collapse-btn:hover { color: var(--accent-amber); border-color: var(--accent-amber); }
|
||
|
||
/* Tab nav */
|
||
.tab {
|
||
display: inline-flex; align-items: center;
|
||
height: 48px; padding: 0 14px;
|
||
font: 500 12px/1 'JetBrains Mono', monospace;
|
||
letter-spacing: 0.10em; text-transform: uppercase;
|
||
color: var(--text-secondary);
|
||
border-bottom: 2px solid transparent;
|
||
cursor: pointer;
|
||
}
|
||
.tab:hover { color: var(--text-primary); }
|
||
.tab.active { color: var(--text-primary); border-bottom-color: var(--accent-amber); font-weight: 500; }
|
||
|
||
/* Icon buttons in header */
|
||
.ibtn {
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
width: 28px; height: 28px;
|
||
border: 1px solid var(--border-hair); border-radius: 2px;
|
||
color: var(--text-secondary); background: transparent;
|
||
transition: color .12s, border-color .12s, background-color .12s;
|
||
cursor: pointer;
|
||
}
|
||
.ibtn:hover { color: var(--text-primary); border-color: var(--border-raised); background: var(--surface-2); }
|
||
.ibtn.active { color: var(--accent-amber); border-color: var(--accent-amber); background: rgba(255,157,61,0.08); }
|
||
.ibtn.danger:hover { color: var(--accent-red); border-color: var(--accent-red); background: rgba(255,71,86,0.08); }
|
||
|
||
/* Flight list row */
|
||
.fl-row {
|
||
display: flex; align-items: center; gap: 8px;
|
||
height: 28px; padding: 0 12px;
|
||
border-bottom: 1px solid var(--border-hair);
|
||
cursor: pointer;
|
||
font-family: 'JetBrains Mono', monospace; font-size: 12px;
|
||
color: var(--text-primary);
|
||
}
|
||
.fl-row:hover { background: var(--surface-2); }
|
||
.fl-row.active { background: var(--surface-2); position: relative; }
|
||
.fl-row.active::before {
|
||
content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
|
||
background: var(--accent-amber);
|
||
}
|
||
.fl-row .fid { color: var(--accent-amber); }
|
||
.fl-row .meta { margin-left: auto; font-size: 10px; color: var(--text-muted); letter-spacing: 0.08em; }
|
||
|
||
/* Waypoint row */
|
||
.wp-row {
|
||
display: flex; align-items: center; gap: 10px;
|
||
height: 30px; padding: 0 4px;
|
||
border-bottom: 1px solid var(--border-hair);
|
||
font-size: 12px; color: var(--text-primary);
|
||
}
|
||
.wp-row:last-child { border-bottom: none; }
|
||
.wp-row .wp-id {
|
||
font-family: 'JetBrains Mono', monospace; font-size: 11px;
|
||
color: var(--text-secondary); width: 28px;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.wp-row .wp-marker { width: 10px; height: 10px; flex-shrink: 0; }
|
||
.wp-row .wp-tag {
|
||
margin-left: auto; font-family: 'JetBrains Mono', monospace;
|
||
font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase;
|
||
color: var(--text-muted); border: 1px solid var(--border-hair);
|
||
padding: 1px 5px; border-radius: 2px;
|
||
}
|
||
|
||
/* Map background grid */
|
||
.map-grid {
|
||
background-color: #0F1318;
|
||
background-image:
|
||
linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
|
||
linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px),
|
||
radial-gradient(ellipse at 30% 40%, rgba(54,214,197,0.04), transparent 60%),
|
||
radial-gradient(ellipse at 80% 70%, rgba(255,157,61,0.03), transparent 65%);
|
||
background-size: 60px 60px, 60px 60px, 100% 100%, 100% 100%;
|
||
}
|
||
|
||
/* GPS-Denied accent state */
|
||
.gps-active-frame {
|
||
border: 2px solid var(--accent-red) !important;
|
||
box-shadow: inset 0 0 0 1px rgba(255,71,86,0.12);
|
||
}
|
||
.gps-active-frame.bracket::before, .gps-active-frame.bracket::after,
|
||
.gps-active-frame.bracket > .br::before, .gps-active-frame.bracket > .br::after {
|
||
border-color: var(--accent-red);
|
||
}
|
||
|
||
/* Scrollbar */
|
||
::-webkit-scrollbar { width: 8px; height: 8px; }
|
||
::-webkit-scrollbar-track { background: var(--surface-0); }
|
||
::-webkit-scrollbar-thumb { background: var(--border-hair); border-radius: 0; }
|
||
::-webkit-scrollbar-thumb:hover { background: var(--border-raised); }
|
||
|
||
/* Map waypoint markers (svg-styled overlays) */
|
||
.wp-marker-map {
|
||
position: absolute; transform: translate(-50%, -50%);
|
||
pointer-events: auto;
|
||
}
|
||
.wp-square { width: 12px; height: 12px; background: #0A0D10; border: 1.5px solid var(--accent-cyan); }
|
||
.wp-square.corrected { border-color: var(--accent-cyan); background: rgba(54,214,197,0.15); }
|
||
.wp-diamond { width: 14px; height: 14px; background: var(--accent-green); border: 1.5px solid #0A0D10; transform: translate(-50%,-50%) rotate(45deg); box-shadow: 0 0 0 1px var(--accent-green); }
|
||
.wp-octagon {
|
||
width: 16px; height: 16px; background: var(--accent-red);
|
||
clip-path: polygon(30% 0, 70% 0, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0 70%, 0 30%);
|
||
}
|
||
|
||
.crosshair-x, .crosshair-y {
|
||
position: absolute; background: rgba(255,255,255,0.06); pointer-events: none;
|
||
}
|
||
.crosshair-x { left: 0; right: 0; height: 1px; top: 50%; }
|
||
.crosshair-y { top: 0; bottom: 0; width: 1px; left: 50%; }
|
||
|
||
.map-axis-label {
|
||
position: absolute; font-family: 'JetBrains Mono', monospace; font-size: 9px;
|
||
color: var(--text-muted); letter-spacing: 0.1em; text-transform: uppercase;
|
||
}
|
||
|
||
details > summary { list-style: none; cursor: pointer; }
|
||
details > summary::-webkit-details-marker { display: none; }
|
||
</style>
|
||
</head>
|
||
<body class="h-screen flex flex-col overflow-hidden">
|
||
|
||
<!-- ========================= GLOBAL HEADER ========================= -->
|
||
<header class="h-12 flex items-center px-4 gap-3 border-b" style="border-color: var(--border-hair); background: var(--surface-1);">
|
||
<span class="mono font-bold" style="color: var(--accent-amber); letter-spacing: 0.2em; font-size: 14px;">AZAION</span>
|
||
|
||
<span class="micro" style="color: var(--text-muted);">//</span>
|
||
|
||
<button class="inline-flex items-center gap-2 mono" style="height: 28px; padding: 0 10px; background: var(--surface-1); border: 1px solid var(--accent-amber); border-radius: 2px; font-size: 11px; letter-spacing: 0.10em;">
|
||
<span class="live-dot"></span>
|
||
<span style="color: var(--text-primary);">FL-03</span>
|
||
<span style="color: var(--text-secondary); font-size: 10px;">▾</span>
|
||
</button>
|
||
|
||
<nav class="flex items-center self-stretch ml-3">
|
||
<a href="flights.html" class="tab active">Flights</a>
|
||
<a href="annotations.html" class="tab">Annotations</a>
|
||
<a href="dataset_explorer.html" class="tab">Dataset</a>
|
||
<a href="admin.html" class="tab">Admin</a>
|
||
</nav>
|
||
|
||
<div class="ml-auto flex items-center gap-2" style="font: 500 10px/1.4 'JetBrains Mono', monospace; letter-spacing: 0.12em; text-transform: uppercase;">
|
||
<span class="live-dot"></span>
|
||
<span style="color: var(--accent-cyan);">LINK</span>
|
||
<span style="color: var(--border-raised);">|</span>
|
||
<span style="color: var(--text-secondary); text-transform: none; letter-spacing: 0;">user@azaion.com</span>
|
||
<span style="color: var(--border-raised); margin: 0 4px;">|</span>
|
||
<a href="settings.html" class="ibtn" title="Settings">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M12 15a3 3 0 100-6 3 3 0 000 6z"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 11-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 11-4 0v-.09a1.65 1.65 0 00-1-1.51 1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 11-2.83-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 110-4h.09a1.65 1.65 0 001.51-1 1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 112.83-2.83l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 114 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 112.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 110 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
|
||
</a>
|
||
<a href="#" class="ibtn danger" title="Sign out">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
|
||
</a>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- ========================= MAIN ROW ========================= -->
|
||
<div class="flex flex-1 overflow-hidden">
|
||
|
||
<!-- =========================================================== -->
|
||
<!-- FLIGHT LIST SIDEBAR (~200px) -->
|
||
<!-- =========================================================== -->
|
||
<aside class="w-[210px] shrink-0 flex flex-col border-r hair" style="background: var(--surface-1);">
|
||
<div class="px-3 py-2.5 flex items-center justify-between border-b hair">
|
||
<span class="section-head">Flight Roster</span>
|
||
<span class="micro num" style="color: var(--text-muted);">04</span>
|
||
</div>
|
||
|
||
<!-- Filter -->
|
||
<div class="px-3 py-2 border-b hair">
|
||
<div class="relative">
|
||
<input class="ipt h-7 text-[11px] pl-7 mono" placeholder="SEARCH FLIGHTS" style="letter-spacing:0.08em;">
|
||
<svg class="absolute left-2 top-1/2 -translate-y-1/2" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="color: var(--text-muted);"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Flight list -->
|
||
<div class="flex-1 overflow-y-auto">
|
||
<div class="fl-row active">
|
||
<span class="fid">FL02</span>
|
||
<span style="color: var(--accent-amber);" title="Pinned">★</span>
|
||
<span class="meta num">05/12</span>
|
||
</div>
|
||
<div class="fl-row">
|
||
<span class="fid">FL01</span>
|
||
<span class="meta num">05/09</span>
|
||
</div>
|
||
<div class="fl-row">
|
||
<span class="fid">FL03</span>
|
||
<span class="meta num">05/08</span>
|
||
</div>
|
||
<div class="fl-row">
|
||
<span class="fid">FL04</span>
|
||
<span class="meta num">05/03</span>
|
||
</div>
|
||
<div class="fl-row">
|
||
<span class="fid" style="color: var(--text-muted);">FL05</span>
|
||
<span class="micro" style="color: var(--text-muted);">DRAFT</span>
|
||
<span class="meta num">04/28</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Create -->
|
||
<div class="p-3 border-t hair">
|
||
<button class="btn-primary w-full flex items-center justify-center gap-2">
|
||
<svg width="10" height="10" viewBox="0 0 10 10"><path d="M5 1 V9 M1 5 H9" stroke="currentColor" stroke-width="1.5"/></svg>
|
||
Create New
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Telemetry card -->
|
||
<div class="m-3 mt-0 bracket panel p-3" style="padding:12px;">
|
||
<div class="flex items-center justify-between mb-2">
|
||
<span class="micro" style="color: var(--accent-amber);">// Telemetry</span>
|
||
</div>
|
||
<label class="micro block mb-1">Date</label>
|
||
<input type="date" value="2025-03-01" class="ipt ipt-num text-[12px]">
|
||
<span class="br"></span>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- =========================================================== -->
|
||
<!-- PARAMS / GPS-DENIED PANEL (~280px) — both modes visible -->
|
||
<!-- =========================================================== -->
|
||
<aside id="paramsPanel" class="params-panel shrink-0 overflow-y-auto border-r hair" style="background: var(--surface-1);">
|
||
|
||
<!-- Collapsed rail (visible only when .collapsed) -->
|
||
<div class="collapsed-rail">
|
||
<button class="rail-btn" onclick="toggleParams()" title="Expand parameters">»</button>
|
||
<span class="block w-6 h-px" style="background: var(--border-hair);"></span>
|
||
<button class="dmode dmode-sq dmode-amber active" title="Points">
|
||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="1.6" fill="currentColor"/><circle cx="18" cy="6" r="1.6" fill="currentColor"/><circle cx="12" cy="14" r="1.6" fill="currentColor"/><circle cx="6" cy="20" r="1.6" fill="currentColor"/><circle cx="18" cy="20" r="1.6" fill="currentColor"/></svg>
|
||
</button>
|
||
<button class="dmode dmode-sq dmode-green" title="Work Area">
|
||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="4 7 12 3 20 7 20 17 12 21 4 17"/></svg>
|
||
</button>
|
||
<button class="dmode dmode-sq dmode-red" title="No-Go Zone">
|
||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><line x1="5.6" y1="5.6" x2="18.4" y2="18.4"/></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Expanded body -->
|
||
<div class="panel-body">
|
||
|
||
<!-- Mode toggle bar -->
|
||
<div class="flex items-stretch border-b hair" style="background: var(--surface-0);">
|
||
<button id="tabFP" onclick="setMode('fp')" class="flex-1 py-2.5 mono text-[10px] uppercase tracking-[0.14em] border-b-2 transition"
|
||
style="color: var(--text-primary); border-color: var(--accent-amber); background: var(--surface-1);">
|
||
Flight Params
|
||
</button>
|
||
<button id="tabGPS" onclick="setMode('gps')" class="flex-1 py-2.5 mono text-[10px] uppercase tracking-[0.14em] border-b-2 transition"
|
||
style="color: var(--text-secondary); border-color: transparent;">
|
||
GPS-Denied
|
||
</button>
|
||
<button class="collapse-btn shrink-0 mx-1 self-center" onclick="toggleParams()" title="Collapse">«</button>
|
||
</div>
|
||
|
||
<!-- ============== FLIGHT PARAMETERS ============== -->
|
||
<section id="flightParams" class="p-4 space-y-5">
|
||
|
||
<!-- Draw-mode selector -->
|
||
<div>
|
||
<div class="flex items-center justify-between mb-1.5">
|
||
<span class="micro" style="color: var(--accent-amber);">// Draw Mode</span>
|
||
<span class="micro num" style="color: var(--text-muted);">click map to plot</span>
|
||
</div>
|
||
<div class="grid grid-cols-3 gap-2">
|
||
<button class="dmode dmode-amber active" data-mode="points">
|
||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="1.6" fill="currentColor"/><circle cx="18" cy="6" r="1.6" fill="currentColor"/><circle cx="12" cy="14" r="1.6" fill="currentColor"/><circle cx="6" cy="20" r="1.6" fill="currentColor"/><circle cx="18" cy="20" r="1.6" fill="currentColor"/><path d="M6 6l6 8 6-8M6 20l6-6 6 6" opacity="0.45"/></svg>
|
||
<span>Points</span>
|
||
</button>
|
||
<button class="dmode dmode-green" data-mode="work">
|
||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="4 7 12 3 20 7 20 17 12 21 4 17"/></svg>
|
||
<span>Work Area</span>
|
||
</button>
|
||
<button class="dmode dmode-red" data-mode="nogo">
|
||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><line x1="5.6" y1="5.6" x2="18.4" y2="18.4"/></svg>
|
||
<span>No-Go Zone</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<header class="flex items-center justify-between">
|
||
<h2 class="section-head">Mission Config</h2>
|
||
<span class="pill pill-amber"><span class="dot"></span>FL02</span>
|
||
</header>
|
||
|
||
<div class="bracket panel p-3 space-y-3">
|
||
<div>
|
||
<label class="micro block mb-1.5">Aircraft</label>
|
||
<select class="ipt">
|
||
<option>DJI Mavic 3 Enterprise</option>
|
||
<option>DJI Matrice 350 RTK</option>
|
||
<option>Autel EVO Max 4T</option>
|
||
</select>
|
||
</div>
|
||
<div class="grid grid-cols-2 gap-2">
|
||
<div>
|
||
<label class="micro block mb-1.5">Default Height</label>
|
||
<div class="relative">
|
||
<input type="number" value="100" class="ipt ipt-num pr-9">
|
||
<span class="absolute right-2.5 top-1/2 -translate-y-1/2 micro" style="color: var(--text-muted);">M</span>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<label class="micro block mb-1.5">Focal Length</label>
|
||
<div class="relative">
|
||
<input type="number" value="24" class="ipt ipt-num pr-10">
|
||
<span class="absolute right-2.5 top-1/2 -translate-y-1/2 micro" style="color: var(--text-muted);">MM</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<label class="micro block mb-1.5">Comm Address / Port</label>
|
||
<input type="text" value="192.168.1.42:8080" class="ipt ipt-num">
|
||
</div>
|
||
<span class="br"></span>
|
||
</div>
|
||
|
||
<!-- Waypoints -->
|
||
<div class="bracket panel p-3">
|
||
<header class="flex items-center justify-between mb-2.5">
|
||
<span class="section-head">Waypoints</span>
|
||
<span class="micro num" style="color: var(--text-muted);">06 PTS</span>
|
||
</header>
|
||
|
||
<div class="space-y-0">
|
||
<div class="wp-row">
|
||
<span class="wp-id">00</span>
|
||
<span class="wp-marker" style="background: var(--accent-green); transform: rotate(45deg);"></span>
|
||
<span class="mono text-[11px]">START</span>
|
||
<span class="wp-tag" style="color: var(--accent-green); border-color: var(--accent-green);">ORIGIN</span>
|
||
</div>
|
||
<div class="wp-row">
|
||
<span class="wp-id">01</span>
|
||
<span class="wp-marker" style="background: transparent; border: 1.5px solid var(--accent-cyan);"></span>
|
||
<span class="mono text-[11px]">Point 1</span>
|
||
<span class="wp-tag">TRACK</span>
|
||
</div>
|
||
<div class="wp-row">
|
||
<span class="wp-id">02</span>
|
||
<span class="wp-marker" style="background: transparent; border: 1.5px solid var(--accent-cyan);"></span>
|
||
<span class="mono text-[11px]">Point 2</span>
|
||
<span class="wp-tag" style="color: var(--accent-red); border-color: var(--accent-red);">MIL-VEH</span>
|
||
</div>
|
||
<div class="wp-row">
|
||
<span class="wp-id">03</span>
|
||
<span class="wp-marker" style="background: transparent; border: 1.5px solid var(--accent-cyan);"></span>
|
||
<span class="mono text-[11px]">Point 3</span>
|
||
</div>
|
||
<div class="wp-row">
|
||
<span class="wp-id">04</span>
|
||
<span class="wp-marker" style="background: transparent; border: 1.5px solid var(--accent-cyan);"></span>
|
||
<span class="mono text-[11px]">Point 4</span>
|
||
<span class="wp-tag">CONFIRM</span>
|
||
</div>
|
||
<div class="wp-row">
|
||
<span class="wp-id">FN</span>
|
||
<span class="wp-marker" style="background: var(--accent-red); clip-path: polygon(30% 0, 70% 0, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0 70%, 0 30%);"></span>
|
||
<span class="mono text-[11px]">FINISH</span>
|
||
<span class="wp-tag" style="color: var(--accent-red); border-color: var(--accent-red);">TARGET</span>
|
||
</div>
|
||
</div>
|
||
<span class="br"></span>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-2 gap-2">
|
||
<button onclick="setMode('gps')" class="btn-secondary" style="color: var(--accent-red); border-color: var(--accent-red);">GPS-Denied</button>
|
||
<button class="btn-cyan">Upload</button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ============== GPS-DENIED MODE ============== -->
|
||
<section id="gpsDenied" class="p-4 space-y-5 hidden">
|
||
<header class="flex items-center justify-between">
|
||
<h2 class="section-head" style="color: var(--accent-red);">GPS-Denied // Active</h2>
|
||
<span class="pill pill-red"><span class="dot pulse"></span>GPS-DENIED ACTIVE</span>
|
||
</header>
|
||
|
||
<!-- Frame with red accent -->
|
||
<div id="gpsFrame" class="bracket bracket-red panel gps-active-frame p-3">
|
||
<header class="flex items-center justify-between mb-3">
|
||
<span class="section-head" style="color: var(--accent-red);">// Orthophoto Upload</span>
|
||
<span class="micro num" style="color: var(--text-muted);">03 / 12</span>
|
||
</header>
|
||
|
||
<div class="space-y-1.5">
|
||
<div class="flex items-center gap-2.5 border hair px-2.5 py-2" style="background: var(--surface-0);">
|
||
<span class="w-6 h-6 flex items-center justify-center shrink-0 mono text-[10px]" style="background: var(--accent-cyan); color: #0A0D10; font-weight: 700;">P1</span>
|
||
<span class="mono text-[11px] flex-1 truncate">ortho_001.jpg</span>
|
||
<span class="num text-[10px]" style="color: var(--text-secondary);">48.8566, 2.3522</span>
|
||
</div>
|
||
<div class="flex items-center gap-2.5 border hair px-2.5 py-2" style="background: var(--surface-0);">
|
||
<span class="w-6 h-6 flex items-center justify-center shrink-0 mono text-[10px]" style="background: var(--accent-cyan); color: #0A0D10; font-weight: 700;">P2</span>
|
||
<span class="mono text-[11px] flex-1 truncate">ortho_002.jpg</span>
|
||
<span class="num text-[10px]" style="color: var(--text-secondary);">48.8612, 2.3601</span>
|
||
</div>
|
||
<div class="flex items-center gap-2.5 border hair px-2.5 py-2" style="background: var(--surface-0);">
|
||
<span class="w-6 h-6 flex items-center justify-center shrink-0 mono text-[10px]" style="background: var(--accent-cyan); color: #0A0D10; font-weight: 700;">P3</span>
|
||
<span class="mono text-[11px] flex-1 truncate">ortho_003.jpg</span>
|
||
<span class="num text-[10px]" style="color: var(--text-secondary);">48.8703, 2.3754</span>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="w-full mt-2.5 py-2 mono text-[10px] uppercase tracking-[0.12em] border border-dashed flex items-center justify-center gap-2"
|
||
style="border-color: var(--border-raised); color: var(--text-secondary); background: transparent;">
|
||
<svg width="10" height="10" viewBox="0 0 10 10"><path d="M5 1 V9 M1 5 H9" stroke="currentColor" stroke-width="1.4"/></svg>
|
||
Upload Photos
|
||
</button>
|
||
<span class="br"></span>
|
||
</div>
|
||
|
||
<!-- Live GPS readout -->
|
||
<div class="bracket panel p-3">
|
||
<header class="flex items-center justify-between mb-2.5">
|
||
<span class="section-head">// Live GPS</span>
|
||
<span class="pill pill-green"><span class="dot pulse"></span>CONNECTED</span>
|
||
</header>
|
||
<div class="space-y-1.5 text-[12px]">
|
||
<div class="flex items-center justify-between py-1 border-b hair">
|
||
<span class="micro">Status</span>
|
||
<span class="mono" style="color: var(--accent-green);">CONNECTED · STREAMING</span>
|
||
</div>
|
||
<div class="flex items-center justify-between py-1 border-b hair">
|
||
<span class="micro">Latitude</span>
|
||
<span class="num">48.85660° N</span>
|
||
</div>
|
||
<div class="flex items-center justify-between py-1 border-b hair">
|
||
<span class="micro">Longitude</span>
|
||
<span class="num">02.35220° E</span>
|
||
</div>
|
||
<div class="flex items-center justify-between py-1 border-b hair">
|
||
<span class="micro">Satellites</span>
|
||
<span class="num" style="color: var(--accent-cyan);">12 / 14</span>
|
||
</div>
|
||
<div class="flex items-center justify-between py-1">
|
||
<span class="micro">Drift</span>
|
||
<span class="num" style="color: var(--accent-amber);">±2.4 M</span>
|
||
</div>
|
||
</div>
|
||
<span class="br"></span>
|
||
</div>
|
||
|
||
<!-- GPS Correction -->
|
||
<div class="bracket panel p-3">
|
||
<header class="flex items-center justify-between mb-2.5">
|
||
<span class="section-head">// GPS Correction</span>
|
||
</header>
|
||
<div class="space-y-2.5">
|
||
<div>
|
||
<label class="micro block mb-1.5">Waypoint #</label>
|
||
<input type="number" value="03" class="ipt ipt-num">
|
||
</div>
|
||
<div>
|
||
<label class="micro block mb-1.5">Corrected GPS</label>
|
||
<input type="text" value="48.86120, 2.36011" class="ipt ipt-num">
|
||
</div>
|
||
<button class="btn-primary w-full">Apply Correction</button>
|
||
</div>
|
||
<span class="br"></span>
|
||
</div>
|
||
|
||
<button onclick="setMode('fp')" class="btn-ghost w-full">‹ Back to Flight Params</button>
|
||
</section>
|
||
|
||
</div><!-- /.panel-body -->
|
||
</aside>
|
||
|
||
<!-- =========================================================== -->
|
||
<!-- MAP VIEW -->
|
||
<!-- =========================================================== -->
|
||
<main class="flex-1 relative overflow-hidden map-grid">
|
||
|
||
<!-- crosshairs -->
|
||
<div class="crosshair-x"></div>
|
||
<div class="crosshair-y"></div>
|
||
|
||
<!-- axis labels -->
|
||
<div class="map-axis-label" style="top: 8px; left: 12px;">SECTOR 04-K // ZOOM 17</div>
|
||
<div class="map-axis-label" style="top: 8px; left: 50%; transform: translateX(-50%);">— TARGET CORRIDOR —</div>
|
||
<div class="map-axis-label" style="bottom: 8px; left: 12px;">N 48.8566 // E 02.3522</div>
|
||
<div class="map-axis-label" style="bottom: 8px; right: 12px;">GRID 60M · WGS-84</div>
|
||
|
||
<!-- Compass rosette top-left -->
|
||
<div class="absolute top-12 left-4 w-20 h-20 flex items-center justify-center border hair bracket panel"
|
||
style="background: rgba(19,23,28,0.6); backdrop-filter: blur(2px);">
|
||
<svg width="60" height="60" viewBox="-30 -30 60 60" style="color: var(--accent-amber);">
|
||
<circle r="24" fill="none" stroke="currentColor" stroke-opacity="0.3" stroke-width="0.7"/>
|
||
<circle r="20" fill="none" stroke="currentColor" stroke-opacity="0.2" stroke-width="0.5"/>
|
||
<line x1="0" y1="-26" x2="0" y2="-20" stroke="currentColor" stroke-width="1.5"/>
|
||
<line x1="0" y1="20" x2="0" y2="26" stroke="currentColor" stroke-opacity="0.4" stroke-width="0.8"/>
|
||
<line x1="-26" y1="0" x2="-20" y2="0" stroke="currentColor" stroke-opacity="0.4" stroke-width="0.8"/>
|
||
<line x1="20" y1="0" x2="26" y2="0" stroke="currentColor" stroke-opacity="0.4" stroke-width="0.8"/>
|
||
<text x="0" y="-12" text-anchor="middle" font-family="JetBrains Mono" font-size="7" fill="currentColor" font-weight="700">N</text>
|
||
<polygon points="0,-16 -3,-8 0,-10 3,-8" fill="currentColor"/>
|
||
</svg>
|
||
<span class="br"></span>
|
||
</div>
|
||
|
||
<!-- SVG paths overlay -->
|
||
<svg class="absolute inset-0 w-full h-full" viewBox="0 0 800 600" preserveAspectRatio="none">
|
||
<defs>
|
||
<marker id="arrowCyan" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
|
||
<path d="M0,0 L10,5 L0,10 z" fill="#36D6C5"/>
|
||
</marker>
|
||
</defs>
|
||
<!-- Original (planned) path — red dashed -->
|
||
<polyline points="150,450 250,350 350,280 450,320 550,250 650,200"
|
||
fill="none" stroke="#FF4756" stroke-width="1.5"
|
||
stroke-dasharray="5 4" opacity="0.85"/>
|
||
<!-- Corrected (live) path — cyan solid -->
|
||
<polyline points="150,460 255,358 360,290 455,328 555,260 650,210"
|
||
fill="none" stroke="#36D6C5" stroke-width="2"
|
||
marker-end="url(#arrowCyan)"/>
|
||
<!-- Correction ties (thin perpendicular linkers between original/corrected) -->
|
||
<g stroke="#36D6C5" stroke-width="0.6" stroke-dasharray="2 2" opacity="0.4">
|
||
<line x1="250" y1="350" x2="255" y2="358"/>
|
||
<line x1="350" y1="280" x2="360" y2="290"/>
|
||
<line x1="450" y1="320" x2="455" y2="328"/>
|
||
<line x1="550" y1="250" x2="555" y2="260"/>
|
||
</g>
|
||
</svg>
|
||
|
||
<!-- Waypoint markers on map -->
|
||
<!-- Start: diamond (green) -->
|
||
<div class="wp-marker-map" style="left:18.75%; top:75%;">
|
||
<div class="wp-diamond"></div>
|
||
<span class="absolute top-3 left-3 mono text-[9px] num" style="color: var(--accent-green); letter-spacing: 0.1em;">WP-00 · START</span>
|
||
</div>
|
||
<!-- Intermediate: square handles -->
|
||
<div class="wp-marker-map" style="left:31.25%; top:58.3%;">
|
||
<div class="wp-square"></div>
|
||
<span class="absolute top-3 left-3 mono text-[9px] num" style="color: var(--accent-cyan);">WP-01</span>
|
||
</div>
|
||
<div class="wp-marker-map" style="left:43.75%; top:46.7%;">
|
||
<div class="wp-square"></div>
|
||
<span class="absolute top-3 left-3 mono text-[9px] num" style="color: var(--accent-cyan);">WP-02</span>
|
||
</div>
|
||
<div class="wp-marker-map" style="left:56.25%; top:53.3%;">
|
||
<div class="wp-square"></div>
|
||
<span class="absolute top-3 left-3 mono text-[9px] num" style="color: var(--accent-cyan);">WP-03</span>
|
||
<span class="absolute -top-4 -left-1 mono text-[8px]" style="color: var(--accent-amber); letter-spacing: 0.1em;">CORRECTED</span>
|
||
</div>
|
||
<div class="wp-marker-map" style="left:68.75%; top:41.7%;">
|
||
<div class="wp-square"></div>
|
||
<span class="absolute top-3 left-3 mono text-[9px] num" style="color: var(--accent-cyan);">WP-04</span>
|
||
</div>
|
||
<!-- Finish: octagon (red) -->
|
||
<div class="wp-marker-map" style="left:81.25%; top:33.3%;">
|
||
<div class="wp-octagon"></div>
|
||
<span class="absolute top-3.5 left-3.5 mono text-[9px] num" style="color: var(--accent-red); letter-spacing: 0.1em;">WP-FN · TARGET</span>
|
||
</div>
|
||
|
||
<!-- ============ MAP HUD: TOP-RIGHT STATUS ============ -->
|
||
<div class="absolute top-4 right-4 w-[240px] bracket panel p-3" style="background: rgba(19,23,28,0.92); backdrop-filter: blur(4px);">
|
||
<header class="flex items-center justify-between mb-2.5 pb-2 border-b hair">
|
||
<span class="flex items-center gap-2 mono text-[10px]" style="color: var(--accent-cyan); letter-spacing: 0.14em;">
|
||
<span class="w-1.5 h-1.5 rounded-full pulse" style="background: var(--accent-cyan);"></span>
|
||
LIVE · CONNECTED
|
||
</span>
|
||
<span class="micro num" style="color: var(--text-muted);">FL02</span>
|
||
</header>
|
||
<div class="space-y-1">
|
||
<div class="flex items-center justify-between">
|
||
<span class="micro">Sat</span>
|
||
<span class="num text-[12px]" style="color: var(--accent-green);">12 / 14</span>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<span class="micro">Lat</span>
|
||
<span class="num text-[12px]">48.85660° N</span>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<span class="micro">Lon</span>
|
||
<span class="num text-[12px]">02.35220° E</span>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<span class="micro">Alt</span>
|
||
<span class="num text-[12px]">320 M / AGL</span>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<span class="micro">Hdg</span>
|
||
<span class="num text-[12px]" style="color: var(--accent-amber);">047° NE</span>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<span class="micro">Spd</span>
|
||
<span class="num text-[12px]">11.4 M/S</span>
|
||
</div>
|
||
<div class="flex items-center justify-between pt-1.5 mt-1.5 border-t hair">
|
||
<span class="micro">Link</span>
|
||
<span class="num text-[11px]" style="color: var(--accent-green);">RSSI -52 DBM</span>
|
||
</div>
|
||
</div>
|
||
<span class="br"></span>
|
||
</div>
|
||
|
||
<!-- ============ MAP HUD: LEGEND BOTTOM-LEFT ============ -->
|
||
<div class="absolute bottom-12 left-4 w-[200px] bracket panel p-3" style="background: rgba(19,23,28,0.92);">
|
||
<header class="mb-2 pb-1.5 border-b hair">
|
||
<span class="section-head">// Map Legend</span>
|
||
</header>
|
||
<div class="space-y-1.5 text-[11px]">
|
||
<div class="flex items-center gap-2.5">
|
||
<svg width="22" height="6"><line x1="0" y1="3" x2="22" y2="3" stroke="#FF4756" stroke-width="1.5" stroke-dasharray="3 3"/></svg>
|
||
<span class="mono uppercase text-[10px]" style="letter-spacing: 0.1em;">Planned · Original</span>
|
||
</div>
|
||
<div class="flex items-center gap-2.5">
|
||
<svg width="22" height="6"><line x1="0" y1="3" x2="22" y2="3" stroke="#36D6C5" stroke-width="2"/></svg>
|
||
<span class="mono uppercase text-[10px]" style="letter-spacing: 0.1em;">Corrected · Live</span>
|
||
</div>
|
||
<div class="flex items-center gap-2.5 pt-1.5 border-t hair">
|
||
<div style="width:10px; height:10px; background: var(--accent-green); transform: rotate(45deg);"></div>
|
||
<span class="mono uppercase text-[10px]" style="letter-spacing: 0.1em;">Origin / Start</span>
|
||
</div>
|
||
<div class="flex items-center gap-2.5">
|
||
<div style="width:10px; height:10px; background: transparent; border: 1.5px solid var(--accent-cyan);"></div>
|
||
<span class="mono uppercase text-[10px]" style="letter-spacing: 0.1em;">Waypoint</span>
|
||
</div>
|
||
<div class="flex items-center gap-2.5">
|
||
<div style="width:11px; height:11px; background: var(--accent-red); clip-path: polygon(30% 0, 70% 0, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0 70%, 0 30%);"></div>
|
||
<span class="mono uppercase text-[10px]" style="letter-spacing: 0.1em;">Target / Finish</span>
|
||
</div>
|
||
</div>
|
||
<span class="br"></span>
|
||
</div>
|
||
|
||
<!-- ============ MAP TOOLBAR: RIGHT EDGE ============ -->
|
||
<div class="absolute top-1/2 right-4 -translate-y-1/2 flex flex-col gap-1.5">
|
||
<button class="w-8 h-8 flex items-center justify-center border hair panel mono text-[11px]" title="Zoom in" style="color: var(--text-primary);">+</button>
|
||
<button class="w-8 h-8 flex items-center justify-center border hair panel mono text-[11px]" title="Zoom out" style="color: var(--text-primary);">−</button>
|
||
<div class="w-8 h-px" style="background: var(--border-hair);"></div>
|
||
<button class="w-8 h-8 flex items-center justify-center border hair panel" title="Recenter" style="color: var(--accent-amber);">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="12" cy="12" r="3"/><circle cx="12" cy="12" r="8"/><line x1="12" y1="2" x2="12" y2="4"/><line x1="12" y1="20" x2="12" y2="22"/><line x1="2" y1="12" x2="4" y2="12"/><line x1="20" y1="12" x2="22" y2="12"/></svg>
|
||
</button>
|
||
<button class="w-8 h-8 flex items-center justify-center border hair panel" title="Layers" style="color: var(--text-secondary);">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- ============ BOTTOM STATUS STRIP ============ -->
|
||
<div class="absolute bottom-0 left-0 right-0 h-7 flex items-center px-3 gap-4 border-t hair"
|
||
style="background: var(--surface-1);">
|
||
<span class="pill pill-green"><span class="dot pulse"></span>TELEMETRY · LIVE</span>
|
||
<span class="micro" style="color: var(--text-muted);">SSE</span>
|
||
<span class="micro num" style="color: var(--text-secondary);">FRAME 12,847 / 18,400</span>
|
||
<span class="micro" style="color: var(--text-muted);">·</span>
|
||
<span class="micro num" style="color: var(--text-secondary);">LAT 48.85660 N · LON 02.35220 E</span>
|
||
<span class="ml-auto micro num" style="color: var(--text-muted);">LAST PING +0.42S</span>
|
||
</div>
|
||
</main>
|
||
|
||
</div>
|
||
|
||
<script>
|
||
function setMode(mode) {
|
||
const fp = document.getElementById('flightParams');
|
||
const gps = document.getElementById('gpsDenied');
|
||
const tabFP = document.getElementById('tabFP');
|
||
const tabGPS = document.getElementById('tabGPS');
|
||
if (mode === 'gps') {
|
||
fp.classList.add('hidden');
|
||
gps.classList.remove('hidden');
|
||
tabFP.style.color = 'var(--text-secondary)';
|
||
tabFP.style.borderColor = 'transparent';
|
||
tabFP.style.background = 'transparent';
|
||
tabGPS.style.color = 'var(--text-primary)';
|
||
tabGPS.style.borderColor = 'var(--accent-red)';
|
||
tabGPS.style.background = 'var(--surface-1)';
|
||
} else {
|
||
gps.classList.add('hidden');
|
||
fp.classList.remove('hidden');
|
||
tabGPS.style.color = 'var(--text-secondary)';
|
||
tabGPS.style.borderColor = 'transparent';
|
||
tabGPS.style.background = 'transparent';
|
||
tabFP.style.color = 'var(--text-primary)';
|
||
tabFP.style.borderColor = 'var(--accent-amber)';
|
||
tabFP.style.background = 'var(--surface-1)';
|
||
}
|
||
}
|
||
|
||
function toggleParams() {
|
||
document.getElementById('paramsPanel').classList.toggle('collapsed');
|
||
}
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|