Zhen Ye Claude Opus 4.6 (1M context) commited on
Commit
a2d3696
Β·
1 Parent(s): 745e94b

feat(demo): unified mission-status color scheme across all UI elements

Browse files

Redesigned colors around three mission states:
- Match (satisfies=true): #34d399 emerald green
- No Match (satisfies=false): #f87171 soft red
- Unassessed (no verdict): #64748b slate gray

Unified across:
- CSS variables (--mission-match/nomatch/unassessed)
- Track card dots (was type-based color, now mission status)
- SVG overlay strokes (was hardcoded rgba, now MISSION_COLORS)
- Status badges (now reference CSS vars)
- Timeline event markers (critical=match green, low=nomatch red)
- Event log entries (same mapping)
- Waveform density bars (green=high activity, gray=low)
- Inspect panel header label color
- Timeline legend dots

Added MISSION_COLORS constant + getMissionColor(track) helper in
helpers.js as single source of truth.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

demo/js/helpers.js CHANGED
@@ -19,6 +19,22 @@ function buildFeatures(gptRaw) {
19
  return features;
20
  }
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  // ── Status Badge Helper ──────────────────────────────────────────────
23
 
24
  function getStatusBadgeHTML(track) {
@@ -225,6 +241,8 @@ function matchAICommand(question) {
225
  // ── Export to namespace ─────────────────────────────────────────
226
 
227
  Object.assign(window.ISR, {
 
 
228
  buildFeatures,
229
  getStatusBadgeHTML,
230
  formatTime,
 
19
  return features;
20
  }
21
 
22
+ // ── Mission Status Color Helper ──────────────────────────────────────
23
+ // Single source of truth for mission-status-based colors.
24
+ // Used by track card dots, SVG overlays, timeline events, etc.
25
+
26
+ const MISSION_COLORS = {
27
+ match: { solid: '#34d399', bg: 'rgba(52, 211, 153, 0.15)', stroke: 'rgba(52, 211, 153, 0.8)' },
28
+ nomatch: { solid: '#f87171', bg: 'rgba(248, 113, 113, 0.12)', stroke: 'rgba(248, 113, 113, 0.8)' },
29
+ unassessed: { solid: '#64748b', bg: 'rgba(100, 116, 139, 0.12)', stroke: 'rgba(100, 116, 139, 0.5)' },
30
+ };
31
+
32
+ function getMissionColor(track) {
33
+ if (track.satisfies === true) return MISSION_COLORS.match;
34
+ if (track.satisfies === false) return MISSION_COLORS.nomatch;
35
+ return MISSION_COLORS.unassessed;
36
+ }
37
+
38
  // ── Status Badge Helper ──────────────────────────────────────────────
39
 
40
  function getStatusBadgeHTML(track) {
 
241
  // ── Export to namespace ─────────────────────────────────────────
242
 
243
  Object.assign(window.ISR, {
244
+ MISSION_COLORS,
245
+ getMissionColor,
246
  buildFeatures,
247
  getStatusBadgeHTML,
248
  formatTime,
demo/js/inspect.js CHANGED
@@ -39,7 +39,7 @@ function enterInspectState(trackId) {
39
 
40
  // Normalize track properties for display
41
  const trackLabel = realTrack ? (realTrack.label || 'object').toUpperCase() : mockTrack.label.toUpperCase();
42
- const trackColor = realTrack ? (realTrack.color || 'var(--accent)') : mockTrack.color;
43
  const trackConf = realTrack ? (realTrack.score || 0).toFixed(2) : mockTrack.confidence.toFixed(2);
44
 
45
  // Mission status badge for inspect header
 
39
 
40
  // Normalize track properties for display
41
  const trackLabel = realTrack ? (realTrack.label || 'object').toUpperCase() : mockTrack.label.toUpperCase();
42
+ const trackColor = realTrack ? ISR.getMissionColor(realTrack).solid : mockTrack.color;
43
  const trackConf = realTrack ? (realTrack.score || 0).toFixed(2) : mockTrack.confidence.toFixed(2);
44
 
45
  // Mission status badge for inspect header
demo/js/real-backend.js CHANGED
@@ -772,8 +772,9 @@ function renderTrackListFromData(tracks) {
772
  '</div>';
773
  }
774
 
 
775
  card.innerHTML = `
776
- <div class="track-dot" style="background: ${t.color}; box-shadow: 0 0 4px ${t.color};"></div>
777
  <div class="track-info">
778
  <div class="track-label" style="display:flex;align-items:center;gap:6px;">
779
  <span>${t.label}</span>
@@ -913,13 +914,9 @@ function renderSvgOverlay(tracks) {
913
  const nw = nx2 - nx1;
914
  const nh = ny2 - ny1;
915
 
916
- // Determine color by mission status (matches frontend overlays.js)
917
- let strokeColor = 'rgba(255, 255, 255, 0.3)';
918
- if (t.satisfies === true) {
919
- strokeColor = 'rgba(40, 167, 69, 0.8)';
920
- } else if (t.satisfies === false) {
921
- strokeColor = 'rgba(220, 53, 69, 0.8)';
922
- }
923
 
924
  const isSelected = ISR.STATE.selectedTrackId === t.track_id;
925
  const isHighlighted = ISR.STATE.highlightTrackId === t.track_id;
@@ -1086,7 +1083,8 @@ function renderWaveformFromDensity(canvas, densityData) {
1086
 
1087
  // Color gradient based on density value
1088
  const hue = 220 - val * 180; // blue(220) β†’ amber range
1089
- ctx.fillStyle = val > 0.7 ? '#f59e0b88' : val > 0.4 ? '#3b82f688' : '#22c55e88';
 
1090
  ctx.fillRect(x, y, Math.max(barW - 1, 1), barH);
1091
  }
1092
  }
@@ -1211,10 +1209,10 @@ function renderEventMarkersFromData(events) {
1211
  container.innerHTML = '';
1212
 
1213
  const PRIORITY_COLORS = {
1214
- critical: '#ef4444',
1215
- high: '#f59e0b',
1216
- normal: '#3b82f6',
1217
- low: '#22c55e',
1218
  };
1219
 
1220
  for (const evt of events) {
@@ -1261,10 +1259,10 @@ function renderEventLogFromData(events) {
1261
  if (!log) return;
1262
 
1263
  const PRIORITY_STYLES = {
1264
- critical: { bg: 'rgba(239,68,68,0.15)', color: '#ef4444' },
1265
  high: { bg: 'rgba(245,158,11,0.12)', color: '#f59e0b' },
1266
- normal: { bg: 'rgba(59,130,246,0.12)', color: '#3b82f6' },
1267
- low: { bg: 'rgba(34,197,94,0.12)', color: '#22c55e' },
1268
  };
1269
 
1270
  log.innerHTML = events.map(evt => {
@@ -1303,10 +1301,10 @@ function renderRealTimelineLegend(events) {
1303
  }
1304
 
1305
  const TYPE_COLORS = {
1306
- system: 'var(--text-tertiary)',
1307
- detection: 'var(--accent)',
1308
- tracking: 'var(--success)',
1309
- alert: 'var(--danger)',
1310
  };
1311
 
1312
  legend.innerHTML = Object.entries(typeCounts).map(([type, count]) =>
 
772
  '</div>';
773
  }
774
 
775
+ const mc = ISR.getMissionColor(t);
776
  card.innerHTML = `
777
+ <div class="track-dot" style="background: ${mc.solid}; box-shadow: 0 0 4px ${mc.solid};"></div>
778
  <div class="track-info">
779
  <div class="track-label" style="display:flex;align-items:center;gap:6px;">
780
  <span>${t.label}</span>
 
914
  const nw = nx2 - nx1;
915
  const nh = ny2 - ny1;
916
 
917
+ // Determine color by mission status β€” uses unified MISSION_COLORS
918
+ const _mc = ISR.getMissionColor(t);
919
+ const strokeColor = _mc.stroke;
 
 
 
 
920
 
921
  const isSelected = ISR.STATE.selectedTrackId === t.track_id;
922
  const isHighlighted = ISR.STATE.highlightTrackId === t.track_id;
 
1083
 
1084
  // Color gradient based on density value
1085
  const hue = 220 - val * 180; // blue(220) β†’ amber range
1086
+ // Waveform density: high activity = match green, medium = unassessed gray, low = dim
1087
+ ctx.fillStyle = val > 0.6 ? '#34d39988' : val > 0.3 ? '#64748b88' : '#64748b44';
1088
  ctx.fillRect(x, y, Math.max(barW - 1, 1), barH);
1089
  }
1090
  }
 
1209
  container.innerHTML = '';
1210
 
1211
  const PRIORITY_COLORS = {
1212
+ critical: ISR.MISSION_COLORS.match.solid, // mission match events
1213
+ high: '#f59e0b', // speed alerts
1214
+ normal: ISR.MISSION_COLORS.unassessed.solid, // detection/tracking events
1215
+ low: ISR.MISSION_COLORS.nomatch.solid, // no match / dismissed
1216
  };
1217
 
1218
  for (const evt of events) {
 
1259
  if (!log) return;
1260
 
1261
  const PRIORITY_STYLES = {
1262
+ critical: { bg: ISR.MISSION_COLORS.match.bg, color: ISR.MISSION_COLORS.match.solid },
1263
  high: { bg: 'rgba(245,158,11,0.12)', color: '#f59e0b' },
1264
+ normal: { bg: ISR.MISSION_COLORS.unassessed.bg, color: ISR.MISSION_COLORS.unassessed.solid },
1265
+ low: { bg: ISR.MISSION_COLORS.nomatch.bg, color: ISR.MISSION_COLORS.nomatch.solid },
1266
  };
1267
 
1268
  log.innerHTML = events.map(evt => {
 
1301
  }
1302
 
1303
  const TYPE_COLORS = {
1304
+ system: ISR.MISSION_COLORS.unassessed.solid,
1305
+ detection: ISR.MISSION_COLORS.unassessed.solid,
1306
+ tracking: ISR.MISSION_COLORS.unassessed.solid,
1307
+ alert: ISR.MISSION_COLORS.match.solid,
1308
  };
1309
 
1310
  legend.innerHTML = Object.entries(typeCounts).map(([type, count]) =>
demo/styles/components.css CHANGED
@@ -350,8 +350,8 @@
350
  font-size: 8px; padding: 2px 6px; border-radius: 3px; letter-spacing: 0.5px;
351
  font-weight: 600; text-transform: uppercase;
352
  }
353
- .status-badge.match { background: rgba(52,211,153,0.15); color: #34d399; }
354
- .status-badge.no-match { background: rgba(248,113,113,0.12); color: #f87171; }
355
- .status-badge.relevant { background: rgba(59,130,246,0.12); color: #60a5fa; }
356
- .status-badge.not-relevant { background: rgba(255,255,255,0.04); color: rgba(255,255,255,0.4); }
357
- .status-badge.pending { background: rgba(251,191,36,0.1); color: #fbbf24; }
 
350
  font-size: 8px; padding: 2px 6px; border-radius: 3px; letter-spacing: 0.5px;
351
  font-weight: 600; text-transform: uppercase;
352
  }
353
+ .status-badge.match { background: var(--mission-match-bg); color: var(--mission-match); }
354
+ .status-badge.no-match { background: var(--mission-nomatch-bg); color: var(--mission-nomatch); }
355
+ .status-badge.relevant { background: var(--mission-match-bg); color: var(--mission-match); }
356
+ .status-badge.not-relevant { background: var(--mission-nomatch-bg); color: var(--mission-nomatch); opacity: 0.6; }
357
+ .status-badge.pending { background: var(--mission-unassessed-bg); color: var(--mission-unassessed); }
demo/styles/variables.css CHANGED
@@ -12,6 +12,17 @@
12
  --text-tertiary: rgba(255, 255, 255, 0.35);
13
  --panel-bg: rgba(255, 255, 255, 0.02);
14
  --panel-border: rgba(255, 255, 255, 0.06);
 
 
 
 
 
 
 
 
 
 
 
15
  }
16
 
17
  /* ── Reset ──────────────────────────────────────────────────────── */
 
12
  --text-tertiary: rgba(255, 255, 255, 0.35);
13
  --panel-bg: rgba(255, 255, 255, 0.02);
14
  --panel-border: rgba(255, 255, 255, 0.06);
15
+
16
+ /* Mission status colors β€” single source of truth */
17
+ --mission-match: #34d399;
18
+ --mission-match-bg: rgba(52, 211, 153, 0.15);
19
+ --mission-match-stroke: rgba(52, 211, 153, 0.8);
20
+ --mission-nomatch: #f87171;
21
+ --mission-nomatch-bg: rgba(248, 113, 113, 0.12);
22
+ --mission-nomatch-stroke: rgba(248, 113, 113, 0.8);
23
+ --mission-unassessed: #64748b;
24
+ --mission-unassessed-bg: rgba(100, 116, 139, 0.12);
25
+ --mission-unassessed-stroke: rgba(100, 116, 139, 0.5);
26
  }
27
 
28
  /* ── Reset ──────────────────────────────────────────────────────── */