diff --git a/src/world_intel_mcp/dashboard/index.html b/src/world_intel_mcp/dashboard/index.html
index eefcfc3..c3f696a 100644
--- a/src/world_intel_mcp/dashboard/index.html
+++ b/src/world_intel_mcp/dashboard/index.html
@@ -410,8 +410,8 @@ a { color: var(--accent); text-decoration: none; }
.mk-plane:hover { transform: scale(3); }
.mk-traffic {
border-radius: 50%;
- border: 2px solid rgba(255,160,0,0.5);
- background: radial-gradient(circle, rgba(255,160,0,0.5) 30%, rgba(255,160,0,0) 70%);
+ border: 2px solid rgba(224,224,224,0.5);
+ background: radial-gradient(circle, rgba(224,224,224,0.5) 30%, rgba(224,224,224,0) 70%);
cursor: pointer; transition: transform 0.15s;
}
.mk-traffic:hover { transform: scale(1.3); }
@@ -426,8 +426,8 @@ a { color: var(--accent); text-decoration: none; }
.mk-navwarn:hover { transform: rotate(45deg) scale(1.8); }
.mk-cam {
width: 7px; height: 7px; border-radius: 50%;
- background: rgba(120,220,255,0.6);
- border: 1px solid rgba(120,220,255,0.4);
+ background: rgba(144,144,144,0.7);
+ border: 1px solid rgba(144,144,144,0.5);
cursor: pointer; transition: transform 0.15s;
}
.mk-cam:hover { transform: scale(1.8); }
@@ -556,7 +556,7 @@ a { color: var(--accent); text-decoration: none; }
-
+
Webcams
0
@@ -604,7 +604,7 @@ a { color: var(--accent); text-decoration: none; }
var $ = function(s) { return document.querySelector(s); };
var $$ = function(s) { return document.querySelectorAll(s); };
-var safe = function(h) { return DOMPurify.sanitize(h, {ALLOWED_TAGS: ['tr','td','th','table','thead','tbody','a','span','div','br'], ALLOWED_ATTR: ['class','style','href','data-click','data-external']}); };
+var safe = function(h) { return DOMPurify.sanitize(h, {ALLOWED_TAGS: ['tr','td','th','table','thead','tbody','a','span','div','br','img'], ALLOWED_ATTR: ['class','style','href','data-click','data-external','src','alt']}); };
function fmtNum(n, d) { d = d != null ? d : 2; return n == null ? '\u2014' : Number(n).toLocaleString(undefined, {minimumFractionDigits: d, maximumFractionDigits: d}); }
function fmtPct(n) { return n == null ? '\u2014' : (n >= 0 ? '+' : '') + fmtNum(n); }
@@ -663,7 +663,7 @@ $('#drawerToggle').addEventListener('click', function() {
});
// ════════════ DETAIL MODAL ════════════
-var COLORS = { earthquake: 'var(--red)', military: 'var(--blue)', conflict: 'var(--amber)', fire: 'var(--gold)', convergence: 'var(--purple)', nuclear: 'var(--green)', military_base: 'var(--teal)', port: 'var(--blue)', nuclear_facility: 'var(--gold)', pipeline: 'var(--purple)', exposure: '#e040fb', waterway: 'var(--accent)', cable: 'var(--blue)', airtraffic: '#00c8ff', traffic_city: '#ffa000', navwarn: '#ffc832', webcam: '#78dcff' };
+var COLORS = { earthquake: 'var(--red)', military: 'var(--blue)', conflict: 'var(--amber)', fire: 'var(--gold)', convergence: 'var(--purple)', nuclear: 'var(--green)', military_base: 'var(--teal)', port: 'var(--blue)', nuclear_facility: 'var(--gold)', pipeline: 'var(--purple)', exposure: '#e040fb', waterway: 'var(--accent)', cable: 'var(--blue)', airtraffic: '#00c8ff', traffic_city: '#e0e0e0', navwarn: '#ffc832', webcam: '#909090' };
var LABELS = { earthquake: 'EARTHQUAKE', military: 'MILITARY AIRCRAFT', conflict: 'CONFLICT EVENT', fire: 'WILDFIRE CLUSTER', convergence: 'SIGNAL CONVERGENCE', nuclear: 'NUCLEAR MONITOR', military_base: 'MILITARY BASE', port: 'STRATEGIC PORT', nuclear_facility: 'NUCLEAR FACILITY', pipeline: 'PIPELINE', exposure: 'POPULATION EXPOSURE', waterway: 'STRATEGIC WATERWAY', cable: 'CABLE CORRIDOR', airtraffic: 'AIRCRAFT', traffic_city: 'TRAFFIC CONGESTION', navwarn: 'NAVIGATION WARNING', webcam: 'WEBCAM' };
function showDetail(type, d) {
@@ -825,7 +825,6 @@ function showDetail(type, d) {
title = d.title || 'Camera';
subtitle = (d.city || '') + (d.country ? ', ' + d.country : '');
fields = [
- ['Title', d.title || '\u2014'],
['City', d.city || '\u2014'],
['Country', d.country || '\u2014'],
['Status', d.status || '\u2014'],
@@ -850,7 +849,12 @@ function showDetail(type, d) {
'
' + esc(title) + '
' +
(subtitle ? '
' + esc(subtitle) + '
' : '');
- var body = fields.map(function(f) {
+ var body = '';
+ // Webcam: show preview image at top of detail panel
+ if (type === 'webcam' && d.preview_url) {
+ body += '
 + ')
';
+ }
+ body += fields.map(function(f) {
return '
' + esc(f[0]) + '' + esc(String(f[1])) + '
';
}).join('');
@@ -1044,7 +1048,6 @@ function showDrawerDetail(id) {
title = d.title || 'Camera';
subtitle = (d.city || '') + (d.country ? ', ' + d.country : '');
fields = [
- ['Title', d.title || '\u2014'],
['City', d.city || '\u2014'],
['Country', d.country || '\u2014'],
['Status', d.status || '\u2014'],
@@ -1072,7 +1075,11 @@ function showDrawerDetail(id) {
'
' + esc(title) + '
' +
(subtitle ? '
' + esc(subtitle) + '
' : '');
- var body = fields.map(function(f) {
+ var body = '';
+ if (type === 'webcam' && d.preview_url) {
+ body += '
 + ')
';
+ }
+ body += fields.map(function(f) {
return '
' + esc(f[0]) + '' + esc(String(f[1])) + '
';
}).join('');