Files
ui/_docs/ui_design/v2/plugin/annotations.html
T
Armen Rohalov 2a62415f0c ui_design v2: redesign of all 5 pages
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.
2026-05-16 20:09:16 +03:00

877 lines
46 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AZAION // Annotations</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; }
.mono { font-family: 'JetBrains Mono', ui-monospace, monospace; font-variant-numeric: tabular-nums; }
.num { font-variant-numeric: tabular-nums; }
.micro {
font: 500 10px/1.4 'JetBrains Mono', monospace;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--text-secondary);
}
.section-h {
font: 600 11px/1.4 'JetBrains Mono', monospace;
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); }
/* ── Canvas grid backdrop ─────────────────────────────────── */
.grid-bg {
background-color: #0E1216;
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);
background-size: 60px 60px;
}
/* faux terrain wash so the canvas reads as imagery */
.terrain {
background-color: #11181B;
background-image:
radial-gradient(900px 500px at 30% 40%, rgba(48,72,60,0.45), transparent 60%),
radial-gradient(700px 400px at 75% 65%, rgba(40,52,68,0.35), transparent 65%),
radial-gradient(400px 300px at 60% 30%, rgba(82,64,40,0.18), transparent 70%),
linear-gradient(rgba(255,255,255,0.025) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.025) 1px, transparent 1px);
background-size: auto, auto, auto, 48px 48px, 48px 48px;
}
/* ── Buttons ──────────────────────────────────────────────── */
.btn {
display: inline-flex; align-items: center; gap: 6px;
height: 28px; padding: 0 12px;
font: 600 11px/1 'JetBrains Mono', monospace;
letter-spacing: 0.08em; text-transform: uppercase;
border: 1px solid var(--border-hair); border-radius: 2px;
color: var(--text-secondary); background: transparent;
transition: background .12s, color .12s, border-color .12s;
cursor: pointer;
}
.btn:hover { background: var(--surface-2); color: var(--text-primary); }
.btn-amber {
background: var(--accent-amber); color: #0A0D10; border-color: var(--accent-amber);
}
.btn-amber:hover { filter: brightness(1.08); background: var(--accent-amber); color: #0A0D10; }
.btn-ghost-amber { color: var(--accent-amber); border-color: var(--accent-amber); }
.btn-ghost-amber:hover { background: rgba(255,157,61,0.12); color: var(--accent-amber); }
.btn-danger { color: var(--accent-red); border-color: rgba(255,71,86,0.4); }
.btn-danger:hover { background: rgba(255,71,86,0.12); color: var(--accent-red); border-color: var(--accent-red); }
.icobtn {
display: inline-flex; align-items: center; justify-content: center;
width: 28px; height: 28px;
border: 1px solid var(--border-hair); border-radius: 2px;
background: var(--surface-1); color: var(--text-secondary);
transition: background .12s, color .12s, border-color .12s;
cursor: pointer;
}
.icobtn:hover { background: var(--surface-2); color: var(--text-primary); border-color: var(--border-raised); }
.icobtn.active { color: var(--accent-amber); border-color: var(--accent-amber); background: rgba(255,157,61,0.08); }
/* ── Inputs ───────────────────────────────────────────────── */
.inp {
height: 28px; padding: 0 10px;
background: var(--surface-input); color: var(--text-primary);
border: 1px solid var(--border-hair); border-radius: 2px;
font: 12px 'IBM Plex Sans', sans-serif; outline: none;
transition: border-color .12s, box-shadow .12s;
}
.inp::placeholder { color: var(--text-muted); }
.inp:focus { border-color: var(--accent-amber); box-shadow: 0 0 0 1px var(--accent-amber); }
/* ── Pills ────────────────────────────────────────────────── */
.pill {
display: inline-flex; align-items: center; gap: 6px;
height: 20px; padding: 0 8px; border-radius: 2px;
font: 600 10px/1 'JetBrains Mono', monospace; letter-spacing: 0.1em;
text-transform: uppercase; border: 1px solid; background: transparent;
}
.pill .dot { width: 6px; height: 6px; border-radius: 999px; display: inline-block; }
.pill-green { color: var(--accent-green); border-color: rgba(61,220,132,0.5); }
.pill-green .dot { background: var(--accent-green); }
.pill-cyan { color: var(--accent-cyan); border-color: rgba(54,214,197,0.5); }
.pill-cyan .dot { background: var(--accent-cyan); }
.pill-amber { color: var(--accent-amber); border-color: rgba(255,157,61,0.5); }
.pill-amber .dot { background: var(--accent-amber); }
.pill-red { color: var(--accent-red); border-color: rgba(255,71,86,0.5); }
.pill-red .dot { background: var(--accent-red); }
.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: pulse 1.6s ease-in-out infinite;
display: inline-block;
}
@keyframes pulse {
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); }
}
/* ── Media row ────────────────────────────────────────────── */
.media-row {
position: relative;
display: grid; grid-template-columns: 44px 1fr auto; gap: 8px;
align-items: center;
height: 32px; padding: 0 12px 0 14px;
border-bottom: 1px solid var(--border-hair);
cursor: pointer; user-select: none;
}
.media-row:hover { background: var(--surface-2); }
.media-row.active {
background: var(--surface-2);
}
.media-row.active::before {
content: ''; position: absolute; left: 0; top: 0; bottom: 0;
width: 2px; background: var(--accent-amber);
}
.chip {
display: inline-flex; align-items: center; justify-content: center;
width: 40px; height: 16px; border-radius: 2px;
font: 600 9px/1 'JetBrains Mono', monospace; letter-spacing: 0.1em;
border: 1px solid;
}
.chip-photo { color: var(--accent-cyan); border-color: rgba(54,214,197,0.45); background: rgba(54,214,197,0.06); }
.chip-video { color: var(--accent-amber); border-color: rgba(255,157,61,0.45); background: rgba(255,157,61,0.06); }
/* ── Class row ────────────────────────────────────────────── */
.class-row {
display: grid; grid-template-columns: 16px 1fr auto; gap: 10px;
align-items: center; height: 28px; padding: 0 12px;
border-bottom: 1px solid var(--border-hair);
cursor: pointer;
}
.class-row:hover { background: var(--surface-2); }
.class-row.active { background: var(--surface-2); }
.class-row.active .kbd { color: var(--accent-amber); border-color: var(--accent-amber); }
.swatch { width: 12px; height: 12px; border-radius: 0; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.4); }
.kbd {
display: inline-flex; align-items: center; justify-content: center;
width: 18px; height: 16px; padding: 0;
font: 600 10px/1 'JetBrains Mono', monospace;
color: var(--text-muted); border: 1px solid var(--border-hair); border-radius: 2px;
background: var(--surface-0);
}
/* ── Segmented control (PhotoMode) ────────────────────────── */
.seg {
display: grid; grid-template-columns: 1fr 1fr 1fr;
border: 1px solid var(--border-hair); border-radius: 2px;
background: var(--surface-input); overflow: hidden;
}
.seg button {
height: 28px;
font: 600 10px/1 'JetBrains Mono', monospace; letter-spacing: 0.1em;
text-transform: uppercase; color: var(--text-secondary);
background: transparent; border-right: 1px solid var(--border-hair);
cursor: pointer; transition: background .12s, color .12s;
}
.seg button:last-child { border-right: 0; }
.seg button:hover { background: var(--surface-2); color: var(--text-primary); }
.seg button.active { background: var(--accent-amber); color: #0A0D10; }
/* ── Annotation list row (gradient stripe) ────────────────── */
.ann-row {
position: relative;
display: grid; grid-template-columns: 44px 1fr auto; gap: 8px;
align-items: center;
height: 36px; padding: 0 12px;
border-bottom: 1px solid var(--border-hair);
cursor: pointer;
background-color: var(--surface-1);
}
.ann-row::after {
content: ''; position: absolute; left: 0; right: 0; top: 0; bottom: 0;
background-image: var(--row-grad, none);
pointer-events: none;
}
.ann-row > * { position: relative; z-index: 1; }
.ann-row:hover { background-color: var(--surface-2); }
/* ── Bounding box label chip ──────────────────────────────── */
.bbox-label {
display: inline-flex; align-items: center; gap: 6px;
height: 22px; padding: 0 8px;
font: 600 10px/1 'JetBrains Mono', monospace; letter-spacing: 0.08em;
text-transform: uppercase;
border-radius: 2px;
background: rgba(10,13,16,0.92);
color: var(--text-primary);
border: 1px solid var(--border-hair);
}
.bbox-label .conf { color: var(--text-secondary); font-weight: 500; }
/* progress bar */
.scrub {
height: 4px; background: var(--surface-2); border: 1px solid var(--border-hair);
border-radius: 2px; position: relative; cursor: pointer;
}
.scrub .fill { position: absolute; left: 0; top: 0; bottom: 0; background: var(--accent-amber); }
.scrub .head {
position: absolute; top: 50%; width: 2px; height: 10px; background: var(--accent-amber);
transform: translate(-50%, -50%);
}
.scrub .head-knob {
position: absolute; top: 50%; width: 12px; height: 12px;
background: var(--accent-amber);
border: 2px solid var(--surface-1);
border-radius: 999px;
transform: translate(-50%, -50%);
box-shadow: 0 0 0 1px var(--accent-amber), 0 0 8px rgba(255,157,61,0.45);
z-index: 2;
cursor: grab;
}
.scrub .tick {
position: absolute; top: 50%; width: 1px; height: 6px; background: var(--text-muted);
transform: translateY(-50%);
}
.scrub .mark {
position: absolute; top: -3px; width: 2px; height: 10px;
}
/* volume */
.vol {
appearance: none; -webkit-appearance: none;
height: 2px; width: 72px; background: var(--border-hair); outline: none; border-radius: 2px;
}
.vol::-webkit-slider-thumb {
-webkit-appearance: none; appearance: none;
width: 10px; height: 10px; background: var(--accent-amber); border-radius: 0; cursor: pointer;
}
/* Top header tabs */
.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; }
/* Vertical hairline column separator */
.vhair { width: 1px; background: var(--border-hair); }
/* Splitter affordance */
.split {
width: 4px; cursor: col-resize; background: transparent;
position: relative;
}
.split::after {
content: ''; position: absolute; left: 1px; top: 0; bottom: 0; width: 1px;
background: var(--border-hair);
}
.split:hover::after { background: var(--accent-amber); }
/* AI banner */
.ai-banner {
backdrop-filter: blur(6px);
background: rgba(10,13,16,0.78);
border: 1px solid rgba(54,214,197,0.4);
}
/* Crosshair on canvas */
.crosshair {
position: absolute; pointer-events: none;
width: 100%; height: 100%; left: 0; top: 0;
background:
linear-gradient(rgba(255,157,61,0.10), rgba(255,157,61,0.10)) no-repeat,
linear-gradient(rgba(255,157,61,0.10), rgba(255,157,61,0.10)) no-repeat;
background-size: 100% 1px, 1px 100%;
background-position: 0 62%, 47% 0;
}
/* Selected handles */
.handle {
position: absolute; width: 6px; height: 6px;
background: var(--accent-amber); border: 1px solid #0A0D10;
}
/* 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); }
/* Scrollbars */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: var(--border-hair); border-radius: 2px; }
::-webkit-scrollbar-thumb:hover { background: var(--border-raised); }
::-webkit-scrollbar-track { background: transparent; }
</style>
</head>
<body class="h-screen 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">Flights</a>
<a href="annotations.html" class="tab active">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 GRID -->
<div class="flex" style="height: calc(100vh - 48px);">
<!-- ============ LEFT SIDEBAR ============ -->
<aside class="flex flex-col shrink-0" style="width: 264px; background: var(--surface-1);">
<!-- Media list -->
<div class="flex flex-col flex-1 min-h-0">
<div class="flex items-center justify-between px-3 h-9 border-b" style="border-color: var(--border-hair);">
<div class="flex items-center gap-2">
<span class="section-h">Media Files</span>
<span class="mono text-[10px]" style="color: var(--text-muted);">24</span>
</div>
<button class="icobtn" style="width:22px;height:22px;" title="Upload">
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 5v14M5 12h14"/></svg>
</button>
</div>
<div class="px-3 py-2 border-b" style="border-color: var(--border-hair);">
<div class="relative">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
class="absolute left-2 top-1/2 -translate-y-1/2" style="color: var(--text-muted);">
<circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/>
</svg>
<input class="inp w-full pl-7" placeholder="filter by name…" />
</div>
</div>
<div class="flex-1 overflow-y-auto min-h-0">
<div class="media-row">
<span class="chip chip-video">VIDEO</span>
<span class="truncate" style="color: var(--text-primary);">recon_north_03.mp4</span>
<span class="mono text-[11px]" style="color: var(--text-secondary);">04:12</span>
</div>
<div class="media-row active">
<span class="chip chip-video">VIDEO</span>
<span class="truncate" style="color: var(--text-primary); font-weight: 500;">strike_zone_07.mp4</span>
<span class="mono text-[11px]" style="color: var(--accent-amber);">02:47</span>
</div>
<div class="media-row">
<span class="chip chip-photo">PHOTO</span>
<span class="truncate" style="color: var(--text-primary);">orthoframe_0142.jpg</span>
<span class="mono text-[11px]" style="color: var(--text-muted);"></span>
</div>
<div class="media-row">
<span class="chip chip-photo">PHOTO</span>
<span class="truncate" style="color: var(--text-primary);">orthoframe_0143.jpg</span>
<span class="mono text-[11px]" style="color: var(--text-muted);"></span>
</div>
<div class="media-row">
<span class="chip chip-video">VIDEO</span>
<span class="truncate" style="color: var(--text-primary);">patrol_sector_b.mp4</span>
<span class="mono text-[11px]" style="color: var(--text-secondary);">11:08</span>
</div>
<div class="media-row">
<span class="chip chip-photo">PHOTO</span>
<span class="truncate" style="color: var(--text-primary);">orthoframe_0144.jpg</span>
<span class="mono text-[11px]" style="color: var(--text-muted);"></span>
</div>
<div class="media-row">
<span class="chip chip-video">VIDEO</span>
<span class="truncate" style="color: var(--text-primary);">night_ir_pass_02.mp4</span>
<span class="mono text-[11px]" style="color: var(--text-secondary);">07:33</span>
</div>
<div class="media-row">
<span class="chip chip-photo">PHOTO</span>
<span class="truncate" style="color: var(--text-primary);">orthoframe_0145.jpg</span>
<span class="mono text-[11px]" style="color: var(--text-muted);"></span>
</div>
<div class="media-row">
<span class="chip chip-video">VIDEO</span>
<span class="truncate" style="color: var(--text-primary);">corridor_east_01.mp4</span>
<span class="mono text-[11px]" style="color: var(--text-secondary);">03:51</span>
</div>
</div>
</div>
<!-- Detection classes -->
<div class="border-t" style="border-color: var(--border-hair);">
<div class="flex items-center justify-between px-3 h-9 border-b" style="border-color: var(--border-hair);">
<div class="flex items-center gap-2">
<span class="section-h">Detection Classes</span>
<span class="mono text-[10px]" style="color: var(--text-muted);">06</span>
</div>
</div>
<div class="grid grid-cols-[28px_1fr_auto] px-3 h-6 items-center border-b" style="border-color: var(--border-hair);">
<span class="micro">#</span>
<span class="micro">NAME</span>
<span class="micro">KEY</span>
</div>
<div>
<div class="class-row active">
<span class="swatch" style="background:#FF0000"></span>
<span style="color: var(--text-primary); font-weight: 500;">MilVeh</span>
<span class="kbd">1</span>
</div>
<div class="class-row">
<span class="swatch" style="background:#00FF00"></span>
<span style="color: var(--text-primary);">Truck</span>
<span class="kbd">2</span>
</div>
<div class="class-row">
<span class="swatch" style="background:#0000FF"></span>
<span style="color: var(--text-primary);">Vehicle</span>
<span class="kbd">3</span>
</div>
<div class="class-row">
<span class="swatch" style="background:#FFFF00"></span>
<span style="color: var(--text-primary);">Artillery</span>
<span class="kbd">4</span>
</div>
<div class="class-row">
<span class="swatch" style="background:#FF00FF"></span>
<span style="color: var(--text-primary);">Shadow</span>
<span class="kbd">5</span>
</div>
<div class="class-row">
<span class="swatch" style="background:#00FFFF"></span>
<span style="color: var(--text-primary);">Trenches</span>
<span class="kbd">6</span>
</div>
</div>
</div>
<!-- PhotoMode -->
<div class="p-3 border-t" style="border-color: var(--border-hair);">
<div class="flex items-center justify-between mb-2">
<span class="micro">PhotoMode</span>
</div>
<div class="seg">
<button class="active">Regular</button>
<button>Winter</button>
<button>Night</button>
</div>
</div>
</aside>
<div class="split"></div>
<!-- ============ MAIN VIEWER ============ -->
<main class="flex-1 flex flex-col min-w-0" style="background: var(--surface-0);">
<!-- Toolbar above canvas -->
<div class="h-9 flex items-center gap-3 px-4 border-b" style="border-color: var(--border-hair); background: var(--surface-1);">
<div class="flex items-center gap-2">
<span class="section-h">Canvas</span>
<span class="mono text-[11px]" style="color: var(--text-muted);">strike_zone_07.mp4</span>
<span class="mono text-[10px] px-1.5 py-0.5 border" style="color: var(--text-secondary); border-color: var(--border-hair);">1920×1080 · 30 FPS</span>
</div>
<div class="ml-auto flex items-center gap-2">
<span class="micro">ZOOM</span>
<span class="mono text-[11px]" style="color: var(--text-primary);">142%</span>
<span class="mx-2 h-4 w-px" style="background: var(--border-hair);"></span>
<span class="micro">CURSOR</span>
<span class="mono text-[11px]" style="color: var(--text-primary);">0.452, 0.318</span>
<span class="mx-2 h-4 w-px" style="background: var(--border-hair);"></span>
</div>
</div>
<!-- Canvas -->
<div class="flex-1 relative overflow-hidden">
<div class="absolute inset-0 terrain"></div>
<!-- AI Detection banner -->
<div class="absolute top-6 right-6 ai-banner rounded-[2px] px-3 py-2 w-72">
<div class="flex items-center gap-2 mb-1.5">
<span class="live-dot"></span>
<span class="micro" style="color: var(--accent-cyan);">AI DETECTION IN PROGRESS</span>
<span class="ml-auto mono text-[10px]" style="color: var(--text-muted);">3.2s</span>
</div>
<div class="mono text-[10px] space-y-0.5" style="color: var(--text-secondary);">
<div><span style="color: var(--text-muted);">[14:22:41]</span> tile 04/16 → 2 candidates</div>
<div><span style="color: var(--text-muted);">[14:22:42]</span> tile 05/16 → 1 candidate (conf 0.94)</div>
<div><span style="color: var(--accent-cyan);">[14:22:43]</span> filtering by min_conf=0.25…</div>
</div>
<div class="mt-2 h-[2px] bg-black/40 overflow-hidden">
<div style="height:100%; width: 38%; background: var(--accent-cyan);"></div>
</div>
</div>
<!-- ───────── Bounding Box 1: Friendly + Ready (cyan) ───────── -->
<div class="absolute" style="top: 28%; left: 18%; width: 22%; height: 28%;">
<div class="absolute inset-0 border-2" style="border-color: var(--accent-cyan); background: rgba(54,214,197,0.05);"></div>
<!-- corner brackets accent on the bbox -->
<div class="absolute -top-px -left-px w-2 h-2 border-t-2 border-l-2" style="border-color: var(--accent-cyan);"></div>
<div class="absolute -top-px -right-px w-2 h-2 border-t-2 border-r-2" style="border-color: var(--accent-cyan);"></div>
<div class="absolute -bottom-px -left-px w-2 h-2 border-b-2 border-l-2" style="border-color: var(--accent-cyan);"></div>
<div class="absolute -bottom-px -right-px w-2 h-2 border-b-2 border-r-2" style="border-color: var(--accent-cyan);"></div>
<!-- selection handles -->
<div class="handle" style="top: -3px; left: -3px;"></div>
<div class="handle" style="top: -3px; left: calc(50% - 3px);"></div>
<div class="handle" style="top: -3px; right: -3px;"></div>
<div class="handle" style="top: calc(50% - 3px); left: -3px;"></div>
<div class="handle" style="top: calc(50% - 3px); right: -3px;"></div>
<div class="handle" style="bottom: -3px; left: -3px;"></div>
<div class="handle" style="bottom: -3px; left: calc(50% - 3px);"></div>
<div class="handle" style="bottom: -3px; right: -3px;"></div>
<!-- Label -->
<div class="absolute" style="top: -26px; left: -2px;">
<div class="bbox-label" style="border-color: rgba(54,214,197,0.6);">
<!-- Friendly = rectangle (cyan) -->
<svg width="11" height="9" viewBox="0 0 11 9">
<rect x="0.5" y="0.5" width="10" height="8" fill="#87CEEB" stroke="#0A0D10" stroke-width="1"/>
</svg>
<!-- Ready = green dot -->
<span style="width:6px;height:6px;border-radius:999px;background:var(--accent-green);display:inline-block;"></span>
<span style="color: var(--accent-cyan);">VEHICLE</span>
<span class="conf">94.2%</span>
</div>
</div>
<!-- corner coords -->
<div class="absolute -bottom-4 right-0 mono text-[9px]" style="color: var(--text-muted);">0.40, 0.56</div>
</div>
<!-- ───────── Bounding Box 2: Hostile + Ready (red) ───────── -->
<div class="absolute" style="top: 44%; left: 56%; width: 18%; height: 24%;">
<div class="absolute inset-0 border-2" style="border-color: var(--accent-red); background: rgba(255,71,86,0.06);"></div>
<div class="absolute -top-px -left-px w-2 h-2 border-t-2 border-l-2" style="border-color: var(--accent-red);"></div>
<div class="absolute -top-px -right-px w-2 h-2 border-t-2 border-r-2" style="border-color: var(--accent-red);"></div>
<div class="absolute -bottom-px -left-px w-2 h-2 border-b-2 border-l-2" style="border-color: var(--accent-red);"></div>
<div class="absolute -bottom-px -right-px w-2 h-2 border-b-2 border-r-2" style="border-color: var(--accent-red);"></div>
<div class="absolute" style="top: -26px; left: -2px;">
<div class="bbox-label" style="border-color: rgba(255,71,86,0.6);">
<!-- Hostile = diamond (red, rotated square) -->
<svg width="11" height="11" viewBox="0 0 11 11">
<polygon points="5.5,0.7 10.3,5.5 5.5,10.3 0.7,5.5" fill="#FF0000" stroke="#0A0D10" stroke-width="1"/>
</svg>
<span style="width:6px;height:6px;border-radius:999px;background:var(--accent-green);display:inline-block;"></span>
<span style="color: var(--accent-red);">MILVEH</span>
<span class="conf">88.6%</span>
</div>
</div>
<div class="absolute -bottom-4 right-0 mono text-[9px]" style="color: var(--text-muted);">0.74, 0.68</div>
</div>
</div>
<!-- Scrubber + Controls -->
<div class="border-t" style="border-color: var(--border-hair); background: var(--surface-1);">
<!-- Scrubber -->
<div class="px-4 pt-3 pb-2">
<div class="scrub">
<div class="fill" style="width: 35%;"></div>
<!-- annotation marks -->
<div class="mark" style="left: 8%; background: #FF0000;"></div>
<div class="mark" style="left: 12%; background: #00FF00;"></div>
<div class="mark" style="left: 18%; background: #0000FF;"></div>
<div class="mark" style="left: 26%; background: #FFFF00;"></div>
<div class="mark" style="left: 35%; background: var(--accent-amber);"></div>
<div class="mark" style="left: 51%; background: #FF0000;"></div>
<div class="mark" style="left: 60%; background: #FFFF00;"></div>
<div class="mark" style="left: 73%; background: #00FFFF;"></div>
<div class="mark" style="left: 84%; background: #FF0000;"></div>
<div class="head" style="left: 35%;"></div>
<div class="head-knob" style="left: 35%;"></div>
<!-- tick marks -->
<div class="tick" style="left: 0%;"></div>
<div class="tick" style="left: 25%;"></div>
<div class="tick" style="left: 50%;"></div>
<div class="tick" style="left: 75%;"></div>
<div class="tick" style="left: 100%;"></div>
</div>
</div>
<!-- Controls row -->
<div class="px-4 pb-3 flex items-center gap-3">
<!-- Transport group -->
<div class="flex items-center gap-1 p-1 border rounded-[2px]" style="border-color: var(--border-hair);">
<button class="icobtn" title="Previous media" style="border: 0; background: transparent;">
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></svg>
</button>
<button class="icobtn" title="Back 5s" style="border: 0; background: transparent;">
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M11 18V6l-8.5 6zM22 18V6l-8.5 6z"/></svg>
</button>
<button class="icobtn active" title="Play" style="background: rgba(255,157,61,0.12);">
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
</button>
<button class="icobtn" title="Forward 5s" style="border: 0; background: transparent;">
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M13 6v12l8.5-6zM2 6v12l8.5-6z"/></svg>
</button>
<button class="icobtn" title="Next media" style="border: 0; background: transparent;">
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M16 6h2v12h-2zM6 18l8.5-6L6 6z"/></svg>
</button>
</div>
<span class="micro">FRAME STEP</span>
<div class="flex items-center gap-1 p-1 border rounded-[2px]" style="border-color: var(--border-hair);">
<button class="icobtn mono" style="width:30px; font-size:10px; border:0; background:transparent; letter-spacing:0;">1</button>
<button class="icobtn mono" style="width:30px; font-size:10px; border:0; background:transparent; letter-spacing:0;">5</button>
<button class="icobtn mono" style="width:30px; font-size:10px; border:0; background:transparent; letter-spacing:0;">10</button>
<button class="icobtn mono" style="width:30px; font-size:10px; border:0; background:transparent; letter-spacing:0;">30</button>
<button class="icobtn mono" style="width:30px; font-size:10px; border:0; background:transparent; letter-spacing:0;">60</button>
</div>
<span class="mx-1 h-5 w-px" style="background: var(--border-hair);"></span>
<button class="btn btn-ghost-amber">
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><path d="M17 21v-8H7v8M7 3v5h8"/></svg>
Save
</button>
<button class="btn btn-danger">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>
Delete
</button>
<button class="btn btn-danger" title="Delete all on frame">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11l4 6M14 11l-4 6"/></svg>
Delete All
</button>
<span class="mx-1 h-5 w-px" style="background: var(--border-hair);"></span>
<button class="btn btn-amber">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7V3h4"/><path d="M17 3h4v4"/><path d="M21 17v4h-4"/><path d="M7 21H3v-4"/><circle cx="12" cy="12" r="1.6" fill="currentColor" stroke="none"/></svg>
AI Detect
<span class="ml-1 mono opacity-70" style="font-size:9px;">[R]</span>
</button>
<span class="mx-1 h-5 w-px" style="background: var(--border-hair);"></span>
<div class="ml-auto flex items-center gap-2">
<button class="icobtn" title="Mute">
<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3a4.5 4.5 0 0 0-2.5-4v8a4.5 4.5 0 0 0 2.5-4z"/></svg>
</button>
<input type="range" class="vol" min="0" max="100" value="62" />
<span class="mono text-[10px]" style="color: var(--text-muted); width: 24px;">62</span>
</div>
</div>
<!-- Status bar -->
<div class="px-4 h-7 flex items-center border-t" style="border-color: var(--border-hair); background: var(--surface-0);">
<span class="mono text-[11px]" style="color: var(--text-primary);">00:58.412</span>
<span class="mono text-[11px] mx-1.5" style="color: var(--text-muted);">/</span>
<span class="mono text-[11px]" style="color: var(--text-secondary);">02:47.000</span>
<span class="mx-3 h-4 w-px" style="background: var(--border-hair);"></span>
<span class="micro">FRAME</span>
<span class="mono text-[11px] ml-1.5" style="color: var(--text-primary);">1284 / 5040</span>
</div>
</div>
</main>
<div class="split"></div>
<!-- ============ RIGHT SIDEBAR — Annotations List ============ -->
<aside class="flex flex-col shrink-0" style="width: 232px; background: var(--surface-1);">
<div class="flex items-center justify-between px-3 h-9 border-b" style="border-color: var(--border-hair);">
<div class="flex items-center gap-2">
<span class="section-h">Annotations</span>
<span class="mono text-[10px]" style="color: var(--text-muted);">14</span>
</div>
<div class="flex items-center gap-1">
<button class="icobtn" style="width:22px;height:22px;" title="Filter">
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="22 3 2 3 10 12.5 10 19 14 21 14 12.5"/></svg>
</button>
<button class="icobtn" style="width:22px;height:22px;" title="Sort">
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h13M3 12h9M3 18h5M17 8l4-4 4 4M21 4v16"/></svg>
</button>
</div>
</div>
<div class="grid grid-cols-[44px_1fr_auto] gap-2 px-3 h-6 items-center border-b" style="border-color: var(--border-hair);">
<span class="micro">TIME</span>
<span class="micro">CLASS</span>
<span class="micro">CONF</span>
</div>
<div class="flex-1 overflow-y-auto min-h-0">
<!-- 00:12 — single class red 95% -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(255,0,0,0.55) 0%, rgba(255,0,0,0.10) 60%, transparent 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">00:12</span>
<span style="color: var(--text-primary); font-weight: 500;">MilVeh</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">95%</span>
</div>
<!-- 00:18 — multi: green 88% + blue 71% -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(0,255,0,0.50) 0%, rgba(0,255,0,0.10) 48%, rgba(0,0,255,0.40) 52%, rgba(0,0,255,0.08) 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">00:18</span>
<span style="color: var(--text-primary);">Truck +1</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">88%</span>
</div>
<!-- 00:24 — single blue 76% -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(0,0,255,0.40) 0%, rgba(0,0,255,0.08) 60%, transparent 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">00:24</span>
<span style="color: var(--text-primary);">Vehicle</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">76%</span>
</div>
<!-- 00:31 — yellow 92% -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(255,255,0,0.50) 0%, rgba(255,255,0,0.10) 60%, transparent 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">00:31</span>
<span style="color: var(--text-primary);">Artillery</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">92%</span>
</div>
<!-- 00:45 — multi: red 94 + yellow 81 + cyan 64 -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(255,0,0,0.52) 0%, rgba(255,0,0,0.10) 30%, rgba(255,255,0,0.42) 34%, rgba(255,255,0,0.08) 64%, rgba(0,255,255,0.30) 68%, rgba(0,255,255,0.05) 100%);">
<span class="mono text-[11px]" style="color: var(--accent-amber);">00:45</span>
<span style="color: var(--text-primary); font-weight: 600;">MilVeh +2</span>
<span class="mono text-[10px]" style="color: var(--accent-amber);">94%</span>
</div>
<!-- 00:58 — current frame, selected look (cyan + red co-present) -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(54,214,197,0.55) 0%, rgba(54,214,197,0.10) 48%, rgba(255,71,86,0.50) 52%, rgba(255,71,86,0.10) 100%); background-color: var(--surface-2);">
<span class="mono text-[11px]" style="color: var(--accent-amber); font-weight: 600;">00:58</span>
<span style="color: var(--text-primary); font-weight: 600;">Vehicle, MilVeh</span>
<span class="mono text-[10px]" style="color: var(--text-primary);">94%</span>
</div>
<!-- 01:09 — magenta 70% -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(255,0,255,0.40) 0%, rgba(255,0,255,0.08) 60%, transparent 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">01:09</span>
<span style="color: var(--text-primary);">Shadow</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">70%</span>
</div>
<!-- 01:22 — cyan + green -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(0,255,255,0.45) 0%, rgba(0,255,255,0.10) 48%, rgba(0,255,0,0.40) 52%, rgba(0,255,0,0.08) 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">01:22</span>
<span style="color: var(--text-primary);">Trenches +1</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">83%</span>
</div>
<!-- 01:38 — red 97% -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(255,0,0,0.58) 0%, rgba(255,0,0,0.12) 60%, transparent 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">01:38</span>
<span style="color: var(--text-primary);">MilVeh</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">97%</span>
</div>
<!-- 01:51 — empty frame (no detections) -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(221,221,221,0.10), rgba(221,221,221,0.04));">
<span class="mono text-[11px]" style="color: var(--text-muted);">01:51</span>
<span style="color: var(--text-muted); font-style: italic;">empty frame</span>
<span class="mono text-[10px]" style="color: var(--text-muted);"></span>
</div>
<!-- 02:04 — green -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(0,255,0,0.45) 0%, rgba(0,255,0,0.10) 60%, transparent 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">02:04</span>
<span style="color: var(--text-primary);">Truck</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">85%</span>
</div>
<!-- 02:19 — yellow + red -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(255,255,0,0.45) 0%, rgba(255,255,0,0.10) 48%, rgba(255,0,0,0.50) 52%, rgba(255,0,0,0.10) 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">02:19</span>
<span style="color: var(--text-primary);">Artillery +1</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">79%</span>
</div>
<!-- 02:33 — blue 68% -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(0,0,255,0.35) 0%, rgba(0,0,255,0.06) 60%, transparent 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">02:33</span>
<span style="color: var(--text-primary);">Vehicle</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">68%</span>
</div>
<!-- 02:41 — red 91% -->
<div class="ann-row" style="--row-grad: linear-gradient(90deg, rgba(255,0,0,0.52) 0%, rgba(255,0,0,0.10) 60%, transparent 100%);">
<span class="mono text-[11px]" style="color: var(--text-secondary);">02:41</span>
<span style="color: var(--text-primary);">MilVeh</span>
<span class="mono text-[10px]" style="color: var(--text-secondary);">91%</span>
</div>
</div>
<!-- Footer summary -->
<div class="border-t px-3 py-2.5" style="border-color: var(--border-hair); background: var(--surface-0);">
<div class="flex items-center justify-between mb-2">
<span class="micro">SUMMARY</span>
<span class="mono text-[10px]" style="color: var(--text-muted);">14 ann · 3 empty</span>
</div>
<div class="flex items-center gap-1 h-2">
<span style="flex: 5; background: #FF0000; height: 100%;"></span>
<span style="flex: 3; background: #00FF00; height: 100%;"></span>
<span style="flex: 2; background: #0000FF; height: 100%;"></span>
<span style="flex: 2; background: #FFFF00; height: 100%;"></span>
<span style="flex: 1; background: #FF00FF; height: 100%;"></span>
<span style="flex: 1; background: #00FFFF; height: 100%;"></span>
</div>
<div class="flex items-center justify-between mt-2 mono text-[10px]" style="color: var(--text-muted);">
<span><span style="color:#FF0000;"></span> 5</span>
<span><span style="color:#00FF00;"></span> 3</span>
<span><span style="color:#0000FF;"></span> 2</span>
<span><span style="color:#FFFF00;"></span> 2</span>
<span><span style="color:#FF00FF;"></span> 1</span>
<span><span style="color:#00FFFF;"></span> 1</span>
</div>
</div>
</aside>
</div>
</body>
</html>