fix: resolve two-window hang and sweep UI/theming updates

Fix app becoming unresponsive when two browser windows are open: the
root cause was HTTP/1.1 connection pool exhaustion (6-connection limit
per origin). VoiceAlerts was opening 3 SSE streams per window by
default, so two windows produced 8 connections and permanently starved
all regular HTTP requests.

- voice-alerts.js: default all streams to false (opt-in) to stay within
  the browser connection limit; existing user preferences in localStorage
  are preserved
- routes/alerts.py: replace direct AlertManager.stream_events() with
  sse_stream_fanout so both windows receive every alert instead of
  competing for the same queue
- routes/bluetooth_v2.py: same fanout fix via subscribe_fanout_queue,
  preserving named SSE events (device_update, scan_started, etc.)

Also includes accumulated UI/theming changes: accent-cyan CSS variable
sweep across mode CSS/JS files, standalone dashboard pages, template
updates, satellite TLE data refresh, and tile provider default rename.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
James Smith
2026-05-20 22:01:10 +01:00
parent 5100f55586
commit a3f2fa7b88
48 changed files with 1524 additions and 943 deletions
+15 -12
View File
@@ -1031,7 +1031,7 @@ body {
width: 100%;
object-fit: cover;
border-radius: 6px;
border: 1px solid rgba(0, 212, 255, 0.3);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.3);
}
.selected-callsign {
@@ -2227,6 +2227,10 @@ body {
color: var(--text-inverse);
}
html[data-ui-tier="enhanced"] .strip-btn.primary {
background: linear-gradient(135deg, rgba(46, 125, 138, 0.85) 0%, rgba(20, 88, 100, 0.80) 100%);
}
.strip-btn.primary:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(var(--accent-cyan-rgb), 0.3);
@@ -2462,19 +2466,18 @@ body {
}
/* ============================================
ENHANCED TIER — amber military console
ENHANCED TIER — signals teal console
============================================ */
html[data-ui-tier="enhanced"] {
--bg-dark: #080600;
--bg-panel: #0c0a04;
--bg-card: #0e0b05;
--radar-bg: #0c0a04;
--radar-cyan: #c89628;
--border-glow: rgba(200, 150, 40, 0.25);
--border-color: rgba(200, 150, 40, 0.2);
--grid-line: rgba(200, 150, 40, 0.07);
--accent-cyan: #c89628;
--accent-green: #c89628;
--bg-dark: #000000;
--bg-panel: #020404;
--bg-card: #020404;
--radar-bg: #020404;
--radar-cyan: #2e7d8a;
--border-glow: rgba(46, 125, 138, 0.20);
--border-color: rgba(46, 125, 138, 0.18);
--grid-line: rgba(46, 125, 138, 0.07);
--accent-cyan: #2e7d8a;
}
/* ============================================
+25
View File
@@ -721,3 +721,28 @@ body {
grid-template-columns: 1fr;
}
}
html[data-ui-tier="enhanced"] {
--accent-cyan: #2e7d8a;
--accent-cyan-rgb: 46, 125, 138;
--border-color: rgba(46, 125, 138, 0.18);
--border-glow: rgba(46, 125, 138, 0.20);
--grid-line: rgba(46, 125, 138, 0.07);
--bg-dark: #000000;
--bg-panel: #020404;
--bg-card: #020404;
}
html[data-ui-tier="enhanced"] body {
background: #000000;
}
html[data-ui-tier="enhanced"] .session-strip {
background: linear-gradient(120deg, rgba(4, 8, 8, 0.95), rgba(6, 10, 10, 0.95));
}
html[data-ui-tier="lean"] {
--border-color: #2a2a2a;
--border-glow: transparent;
--grid-line: transparent;
}
+8 -8
View File
@@ -10,15 +10,15 @@
align-items: center;
gap: 8px;
padding: 6px 12px;
background: rgba(0, 212, 255, 0.1);
border: 1px solid rgba(0, 212, 255, 0.3);
background: rgba(var(--accent-cyan-rgb), 0.1);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.3);
border-radius: 20px;
cursor: pointer;
transition: all 0.2s;
}
.agent-indicator:hover {
background: rgba(0, 212, 255, 0.2);
background: rgba(var(--accent-cyan-rgb), 0.2);
border-color: var(--accent-cyan);
}
@@ -49,7 +49,7 @@
.agent-indicator-count {
font-size: 10px;
padding: 2px 6px;
background: rgba(0, 212, 255, 0.2);
background: rgba(var(--accent-cyan-rgb), 0.2);
border-radius: 10px;
color: var(--accent-cyan);
}
@@ -123,11 +123,11 @@
}
.agent-selector-item:hover {
background: rgba(0, 212, 255, 0.1);
background: rgba(var(--accent-cyan-rgb), 0.1);
}
.agent-selector-item.selected {
background: rgba(0, 212, 255, 0.15);
background: rgba(var(--accent-cyan-rgb), 0.15);
border-left: 3px solid var(--accent-cyan);
}
@@ -188,7 +188,7 @@
gap: 4px;
padding: 2px 8px;
font-size: 10px;
background: rgba(0, 212, 255, 0.1);
background: rgba(var(--accent-cyan-rgb), 0.1);
color: var(--accent-cyan);
border-radius: 10px;
font-family: var(--font-mono);
@@ -201,7 +201,7 @@
}
.agent-badge.agent-remote {
background: rgba(0, 212, 255, 0.1);
background: rgba(var(--accent-cyan-rgb), 0.1);
color: var(--accent-cyan);
}
+10 -11
View File
@@ -1375,19 +1375,18 @@ body {
}
/* ============================================
ENHANCED TIER — amber military console
ENHANCED TIER — signals teal console
============================================ */
html[data-ui-tier="enhanced"] {
--bg-dark: #080600;
--bg-panel: #0c0a04;
--bg-card: #0e0b05;
--radar-bg: #0c0a04;
--radar-cyan: #c89628;
--border-glow: rgba(200, 150, 40, 0.25);
--border-color: rgba(200, 150, 40, 0.2);
--grid-line: rgba(200, 150, 40, 0.07);
--accent-cyan: #c89628;
--accent-green: #c89628;
--bg-dark: #000000;
--bg-panel: #020404;
--bg-card: #020404;
--radar-bg: #020404;
--radar-cyan: #2e7d8a;
--border-glow: rgba(46, 125, 138, 0.20);
--border-color: rgba(46, 125, 138, 0.18);
--grid-line: rgba(46, 125, 138, 0.07);
--accent-cyan: #2e7d8a;
}
/* ============================================
+1 -1
View File
@@ -38,7 +38,7 @@
.device-card:hover {
border-color: var(--accent-cyan, #00d4ff);
box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.2);
box-shadow: 0 0 0 1px rgba(var(--accent-cyan-rgb), 0.2);
}
.device-card:active {
+2 -2
View File
@@ -162,8 +162,8 @@
}
.heatmap-row.selected {
background: rgba(0, 212, 255, 0.1);
outline: 1px solid rgba(0, 212, 255, 0.3);
background: rgba(var(--accent-cyan-rgb), 0.1);
outline: 1px solid rgba(var(--accent-cyan-rgb), 0.3);
}
.heatmap-header {
+1 -1
View File
@@ -1645,7 +1645,7 @@
.signal-card.signal-card-clickable:hover {
border-color: var(--accent-cyan, #00d4ff);
box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.2);
box-shadow: 0 0 0 1px rgba(var(--accent-cyan-rgb), 0.2);
}
.signal-card.signal-card-clickable:active {
+36
View File
@@ -406,6 +406,42 @@
color: var(--text-primary, #e6edf5);
}
/* ---- Enhanced tier overrides ---- */
html[data-ui-tier="enhanced"] .run-state-strip {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.96), rgba(2, 4, 4, 0.97));
border-color: rgba(46, 125, 138, 0.28);
}
html[data-ui-tier="enhanced"] .run-state-chip {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.82), rgba(2, 4, 4, 0.84));
border-color: rgba(46, 125, 138, 0.22);
}
html[data-ui-tier="enhanced"] .run-state-chip.active {
border-color: rgba(46, 125, 138, 0.60);
box-shadow: inset 0 0 0 1px rgba(46, 125, 138, 0.16);
}
html[data-ui-tier="enhanced"] .run-state-chip .dot {
background: rgba(46, 125, 138, 0.40);
box-shadow: none;
}
html[data-ui-tier="enhanced"] .run-state-chip.running .dot {
background: var(--accent-green, #38c180);
box-shadow: 0 0 0 4px rgba(56, 193, 128, 0.16), 0 0 12px rgba(56, 193, 128, 0.35);
}
html[data-ui-tier="enhanced"] .run-state-btn {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.9), rgba(2, 4, 4, 0.92));
border-color: rgba(46, 125, 138, 0.40);
}
html[data-ui-tier="enhanced"] .run-state-btn:hover {
background: rgba(46, 125, 138, 0.12);
border-color: rgba(46, 125, 138, 0.65);
}
/* ---- Light theme overrides ---- */
[data-theme="light"] .run-state-chip {
background: linear-gradient(180deg, rgba(233, 238, 245, 0.9), rgba(225, 232, 242, 0.92));
+8 -3
View File
@@ -1206,12 +1206,12 @@ textarea:focus {
}
/* ============================================
ENHANCED TIER — amber left-border card accents
ENHANCED TIER — signals teal card accents
============================================ */
[data-ui-tier="enhanced"] .stat-card,
[data-ui-tier="enhanced"] .data-card {
border-left: 2px solid var(--accent-cyan);
background: rgba(200, 150, 40, 0.03);
background: rgba(46, 125, 138, 0.03);
}
[data-ui-tier="enhanced"] .stat-value,
@@ -1226,5 +1226,10 @@ textarea:focus {
letter-spacing: 2px;
text-transform: uppercase;
font-size: var(--text-xs);
color: rgba(200, 150, 40, 0.5);
color: rgba(46, 125, 138, 0.55);
}
html[data-ui-tier="enhanced"] .card-header,
html[data-ui-tier="enhanced"] .panel-header {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.88) 0%, rgba(2, 4, 4, 0.9) 100%);
}
+12 -12
View File
@@ -1188,10 +1188,10 @@ a.nav-dashboard-btn:hover {
}
/* ============================================
ENHANCED TIER amber console nav framing
ENHANCED TIER signals teal console nav framing
============================================ */
[data-ui-tier="enhanced"] .mode-nav {
background: linear-gradient(180deg, rgba(14, 11, 3, 0.95), rgba(8, 6, 0, 0.92));
background: linear-gradient(180deg, rgba(4, 8, 8, 0.95), rgba(2, 4, 4, 0.92));
}
[data-ui-tier="enhanced"] .mode-nav::after,
@@ -1201,16 +1201,16 @@ a.nav-dashboard-btn:hover {
}
[data-ui-tier="enhanced"] .mode-nav-btn.active {
background: rgba(200, 150, 40, 0.08);
background: rgba(46, 125, 138, 0.08);
color: var(--accent-cyan);
border-left: 2px solid var(--accent-cyan);
box-shadow: -2px 0 8px rgba(200, 150, 40, 0.15);
box-shadow: -2px 0 8px rgba(46, 125, 138, 0.15);
padding-left: 12px;
}
[data-ui-tier="enhanced"] .nav-clock .utc-time {
color: var(--accent-cyan);
text-shadow: 0 0 8px rgba(200, 150, 40, 0.3);
text-shadow: 0 0 8px rgba(46, 125, 138, 0.28);
font-weight: 700;
}
@@ -1236,14 +1236,14 @@ a.nav-dashboard-btn:hover {
/* Enhanced tier toggle button styling */
[data-ui-tier="enhanced"] .nav-tier-btn {
background: rgba(200, 150, 40, 0.10);
border-color: rgba(200, 150, 40, 0.4);
color: #c89628;
box-shadow: 0 0 8px rgba(200, 150, 40, 0.08);
text-shadow: 0 0 6px rgba(200, 150, 40, 0.3);
background: rgba(46, 125, 138, 0.10);
border-color: rgba(46, 125, 138, 0.38);
color: #2e7d8a;
box-shadow: 0 0 8px rgba(46, 125, 138, 0.07);
text-shadow: 0 0 6px rgba(46, 125, 138, 0.25);
}
[data-ui-tier="enhanced"] .nav-tier-btn:hover {
background: rgba(200, 150, 40, 0.16);
border-color: rgba(200, 150, 40, 0.6);
background: rgba(46, 125, 138, 0.16);
border-color: rgba(46, 125, 138, 0.55);
}
+156 -108
View File
@@ -29,6 +29,7 @@
/* Accent colors */
--accent-cyan: #4aa3ff;
--accent-cyan-rgb: 74, 163, 255;
--primary-color: var(--accent-cyan);
--accent-cyan-dim: rgba(var(--accent-cyan-rgb), 0.16);
--accent-cyan-hover: #6bb3ff;
--accent-cyan-glow: rgba(var(--accent-cyan-rgb), 0.12);
@@ -108,7 +109,7 @@
/* ============================================
TYPOGRAPHY
============================================ */
--font-sans: 'Roboto Condensed', 'Arial Narrow', Roboto, 'Helvetica Neue', Arial, sans-serif;
--font-sans: 'Inter', 'Roboto Condensed', 'Helvetica Neue', Arial, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', 'Source Code Pro', Consolas, monospace;
/* Font sizes */
@@ -178,85 +179,6 @@
--content-max-width: 1400px;
}
/* ============================================
LIGHT THEME OVERRIDES
============================================ */
[data-theme="light"] {
--bg-primary: #f4f7fb;
--bg-secondary: #e9eef5;
--bg-tertiary: #dde5f0;
--bg-card: #ffffff;
--bg-elevated: #f1f4f9;
--bg-overlay: rgba(244, 247, 251, 0.92);
--surface-glass: rgba(255, 255, 255, 0.84);
--surface-panel-gradient: linear-gradient(160deg, rgba(255, 255, 255, 0.96) 0%, rgba(241, 245, 251, 0.97) 100%);
--ambient-top-left: rgba(31, 95, 168, 0.1);
--ambient-top-right: rgba(31, 138, 87, 0.06);
--ambient-bottom: rgba(181, 134, 58, 0.05);
/* Background aliases for components */
--bg-dark: var(--bg-primary);
--bg-panel: var(--bg-secondary);
--accent-cyan: #1f5fa8;
--accent-cyan-rgb: 31, 95, 168;
--accent-cyan-dim: rgba(31, 95, 168, 0.12);
--accent-cyan-hover: #2c73bf;
--accent-green: #1f8a57;
--accent-green-hover: #167a4a;
--accent-green-dim: rgba(31, 138, 87, 0.12);
--accent-red: #c74444;
--accent-red-hover: #b33a3a;
--accent-red-dim: rgba(199, 68, 68, 0.12);
--accent-orange: #b5863a;
--accent-orange-dim: rgba(181, 134, 58, 0.12);
--accent-amber: #b5863a;
--accent-amber-dim: rgba(181, 134, 58, 0.12);
--accent-yellow: #9a8420;
--accent-purple: #6b5ba8;
/* Status colors - light theme */
--status-online: #1f8a57;
--status-warning: #b5863a;
--status-error: #c74444;
--status-offline: #6b7c93;
--status-info: #1f5fa8;
/* Severity colors */
--severity-critical: #c74444;
--severity-high: #b5863a;
--severity-medium: #9a8420;
--severity-low: #1f8a57;
/* Data visualization neon replacements */
--neon-green: #1a8a50;
--neon-yellow: #9a8420;
--neon-orange: #b5863a;
--neon-red: #c74444;
--text-primary: #122034;
--text-secondary: #3a4a5f;
--text-dim: #566a7f;
--text-muted: #7a8a9e;
--text-inverse: #f4f7fb;
--border-color: #d1d9e6;
--border-light: #c1ccdb;
--border-glow: rgba(31, 95, 168, 0.12);
--grid-line: rgba(31, 95, 168, 0.14);
--grid-dot: rgba(12, 18, 24, 0.06);
--noise-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='40'%20height='40'%20viewBox='0%200%2040%2040'%3E%3Cg%20fill='%23000000'%20fill-opacity='0.05'%3E%3Ccircle%20cx='3'%20cy='5'%20r='1'/%3E%3Ccircle%20cx='11'%20cy='9'%20r='1'/%3E%3Ccircle%20cx='18'%20cy='3'%20r='1'/%3E%3Ccircle%20cx='26'%20cy='12'%20r='1'/%3E%3Ccircle%20cx='34'%20cy='6'%20r='1'/%3E%3Ccircle%20cx='7'%20cy='19'%20r='1'/%3E%3Ccircle%20cx='15'%20cy='24'%20r='1'/%3E%3Ccircle%20cx='28'%20cy='22'%20r='1'/%3E%3Ccircle%20cx='36'%20cy='18'%20r='1'/%3E%3Ccircle%20cx='5'%20cy='33'%20r='1'/%3E%3Ccircle%20cx='19'%20cy='32'%20r='1'/%3E%3Ccircle%20cx='31'%20cy='34'%20r='1'/%3E%3C/g%3E%3C/svg%3E");
--accent-cyan-glow: rgba(31, 95, 168, 0.08);
--scanline: none;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.15);
--shadow-glow: 0 0 18px rgba(31, 95, 168, 0.1);
}
/* ============================================
REDUCED MOTION
============================================ */
@@ -304,40 +226,166 @@ html[data-ui-tier="lean"] {
}
/* ============================================
ENHANCED TIER amber military console
ENHANCED TIER signals teal console
============================================ */
html[data-ui-tier="enhanced"] {
--bg-primary: #080600;
--bg-secondary: #0c0a04;
--bg-tertiary: #100d06;
--bg-card: #0e0b05;
--bg-elevated: #141008;
--bg-overlay: rgba(8, 6, 0, 0.82);
--surface-glass: rgba(14, 11, 5, 0.82);
--surface-panel-gradient: linear-gradient(160deg, rgba(20, 16, 8, 0.94) 0%, rgba(12, 10, 4, 0.96) 100%);
--bg-primary: #000000;
--bg-secondary: #020404;
--bg-tertiary: #040808;
--bg-card: #020404;
--bg-elevated: #060a0a;
--bg-overlay: rgba(0, 0, 0, 0.88);
--surface-glass: rgba(2, 4, 4, 0.90);
--surface-panel-gradient: linear-gradient(160deg, rgba(6, 10, 10, 0.96) 0%, rgba(2, 4, 4, 0.98) 100%);
--accent-cyan: #c89628;
--accent-cyan-rgb: 200, 150, 40;
--accent-cyan-dim: rgba(200, 150, 40, 0.14);
--accent-cyan-hover: #e0aa30;
--accent-cyan-glow: rgba(200, 150, 40, 0.10);
--accent-cyan: #2e7d8a;
--accent-cyan-rgb: 46, 125, 138;
--accent-cyan-dim: rgba(46, 125, 138, 0.14);
--accent-cyan-hover: #3a9aaa;
--accent-cyan-glow: rgba(46, 125, 138, 0.09);
--accent-green: #c89628;
--accent-green-hover: #e0aa30;
--accent-green-dim: rgba(200, 150, 40, 0.14);
/* red/green intentionally unchanged — semantic status only */
/* red is intentionally unchanged — critical alerts only */
--ambient-top-left: rgba(46, 125, 138, 0.07);
--ambient-top-right: rgba(46, 125, 138, 0.04);
--ambient-bottom: rgba(46, 125, 138, 0.03);
--ambient-top-left: rgba(200, 150, 40, 0.08);
--ambient-top-right: rgba(200, 150, 40, 0.05);
--ambient-bottom: rgba(200, 150, 40, 0.04);
--grid-line: rgba(46, 125, 138, 0.07);
--border-color: rgba(46, 125, 138, 0.18);
--border-light: rgba(46, 125, 138, 0.28);
--border-glow: rgba(46, 125, 138, 0.20);
--border-focus: #2e7d8a;
--grid-line: rgba(200, 150, 40, 0.07);
--border-color: rgba(200, 150, 40, 0.2);
--border-light: rgba(200, 150, 40, 0.3);
--border-glow: rgba(200, 150, 40, 0.25);
--border-focus: #c89628;
--status-info: #2e7d8a;
--status-online: #c89628;
--status-info: #c89628;
--font-sans: 'Inter', 'Roboto Condensed', 'Helvetica Neue', Arial, sans-serif;
}
/* ============================================
LIGHT THEME OVERRIDES
Placed after tier blocks so html[data-theme="light"]
(specificity 0,1,1) beats both tier selectors when active.
============================================ */
html[data-theme="light"] {
--bg-primary: #f4f7fb;
--bg-secondary: #e9eef5;
--bg-tertiary: #dde5f0;
--bg-card: #ffffff;
--bg-elevated: #f1f4f9;
--bg-overlay: rgba(244, 247, 251, 0.92);
--surface-glass: rgba(255, 255, 255, 0.84);
--surface-panel-gradient: linear-gradient(160deg, rgba(255, 255, 255, 0.96) 0%, rgba(241, 245, 251, 0.97) 100%);
--ambient-top-left: rgba(31, 95, 168, 0.1);
--ambient-top-right: rgba(31, 138, 87, 0.06);
--ambient-bottom: rgba(181, 134, 58, 0.05);
--bg-dark: var(--bg-primary);
--bg-panel: var(--bg-secondary);
--accent-cyan: #1f5fa8;
--accent-cyan-rgb: 31, 95, 168;
--accent-cyan-dim: rgba(31, 95, 168, 0.12);
--accent-cyan-hover: #2c73bf;
--accent-green: #1f8a57;
--accent-green-hover: #167a4a;
--accent-green-dim: rgba(31, 138, 87, 0.12);
--accent-red: #c74444;
--accent-red-hover: #b33a3a;
--accent-red-dim: rgba(199, 68, 68, 0.12);
--accent-orange: #b5863a;
--accent-orange-dim: rgba(181, 134, 58, 0.12);
--accent-amber: #b5863a;
--accent-amber-dim: rgba(181, 134, 58, 0.12);
--accent-yellow: #9a8420;
--accent-purple: #6b5ba8;
--status-online: #1f8a57;
--status-warning: #b5863a;
--status-error: #c74444;
--status-offline: #6b7c93;
--status-info: #1f5fa8;
--severity-critical: #c74444;
--severity-high: #b5863a;
--severity-medium: #9a8420;
--severity-low: #1f8a57;
--neon-green: #1a8a50;
--neon-yellow: #9a8420;
--neon-orange: #b5863a;
--neon-red: #c74444;
--text-primary: #122034;
--text-secondary: #3a4a5f;
--text-dim: #566a7f;
--text-muted: #7a8a9e;
--text-inverse: #f4f7fb;
--border-color: #d1d9e6;
--border-light: #c1ccdb;
--border-glow: rgba(31, 95, 168, 0.12);
--grid-line: rgba(31, 95, 168, 0.14);
--grid-dot: rgba(12, 18, 24, 0.06);
--noise-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='40'%20height='40'%20viewBox='0%200%2040%2040'%3E%3Cg%20fill='%23000000'%20fill-opacity='0.05'%3E%3Ccircle%20cx='3'%20cy='5'%20r='1'/%3E%3Ccircle%20cx='11'%20cy='9'%20r='1'/%3E%3Ccircle%20cx='18'%20cy='3'%20r='1'/%3E%3Ccircle%20cx='26'%20cy='12'%20r='1'/%3E%3Ccircle%20cx='34'%20cy='6'%20r='1'/%3E%3Ccircle%20cx='7'%20cy='19'%20r='1'/%3E%3Ccircle%20cx='15'%20cy='24'%20r='1'/%3E%3Ccircle%20cx='28'%20cy='22'%20r='1'/%3E%3Ccircle%20cx='36'%20cy='18'%20r='1'/%3E%3Ccircle%20cx='5'%20cy='33'%20r='1'/%3E%3Ccircle%20cx='19'%20cy='32'%20r='1'/%3E%3Ccircle%20cx='31'%20cy='34'%20r='1'/%3E%3C/g%3E%3C/svg%3E");
--accent-cyan-glow: rgba(31, 95, 168, 0.08);
--scanline: none;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.15);
--shadow-glow: 0 0 18px rgba(31, 95, 168, 0.1);
}
/* Lean tier + light: specificity (0,2,1) beats lean-only (0,1,1) */
html[data-ui-tier="lean"][data-theme="light"] {
--bg-primary: #f4f7fb;
--bg-secondary: #e9eef5;
--bg-tertiary: #dde5f0;
--bg-card: #ffffff;
--bg-elevated: #f1f4f9;
--bg-dark: #f4f7fb;
--bg-panel: #e9eef5;
--bg-overlay: rgba(244, 247, 251, 0.92);
--surface-glass: rgba(255, 255, 255, 0.84);
--surface-panel-gradient: linear-gradient(160deg, rgba(255, 255, 255, 0.96) 0%, rgba(241, 245, 251, 0.97) 100%);
--accent-cyan: #1f5fa8;
--accent-cyan-rgb: 31, 95, 168;
--accent-cyan-dim: rgba(31, 95, 168, 0.12);
--accent-green: #1f8a57;
--text-primary: #122034;
--text-secondary: #3a4a5f;
--text-dim: #566a7f;
--text-muted: #7a8a9e;
--border-color: #d1d9e6;
--border-light: #c1ccdb;
--border-glow: rgba(31, 95, 168, 0.12);
--grid-line: rgba(31, 95, 168, 0.14);
--ambient-top-left: rgba(31, 95, 168, 0.1);
--ambient-top-right: rgba(31, 138, 87, 0.06);
--ambient-bottom: rgba(181, 134, 58, 0.05);
}
/* Enhanced tier + light: cool whites with signals teal accents */
html[data-ui-tier="enhanced"][data-theme="light"] {
--bg-primary: #f4f7fb;
--bg-secondary: #e9eef5;
--bg-tertiary: #dde5f0;
--bg-card: #ffffff;
--bg-elevated: #f1f4f9;
--bg-dark: #f4f7fb;
--bg-panel: #e9eef5;
--bg-overlay: rgba(244, 247, 251, 0.92);
--surface-glass: rgba(255, 255, 255, 0.84);
--text-primary: #0a1a1e;
--text-secondary: #1c3a42;
--text-dim: #3a5a62;
--border-color: rgba(30, 100, 112, 0.28);
--grid-line: rgba(30, 100, 112, 0.12);
--accent-cyan: #1e6470;
--accent-cyan-rgb: 30, 100, 112;
--accent-cyan-dim: rgba(30, 100, 112, 0.12);
--accent-cyan-hover: #25808e;
--accent-cyan-glow: rgba(30, 100, 112, 0.08);
}
+67 -1
View File
@@ -1,6 +1,6 @@
/* Local font declarations for offline mode */
/* Roboto Condensed - variable font, one file covers all weights */
/* Roboto Condensed - variable font, one file covers all weights */
@font-face {
font-family: 'Roboto Condensed';
font-style: normal;
@@ -18,3 +18,69 @@
src: url('/static/vendor/fonts/RobotoCondensed-LatinExt.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Inter - used by enhanced tier */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/static/vendor/fonts/Inter-Regular.woff2') format('woff2');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('/static/vendor/fonts/Inter-Medium.woff2') format('woff2');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('/static/vendor/fonts/Inter-SemiBold.woff2') format('woff2');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('/static/vendor/fonts/Inter-Bold.woff2') format('woff2');
}
/* JetBrains Mono - used by enhanced tier and all --font-mono elements */
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/static/vendor/fonts/JetBrainsMono-Regular.woff2') format('woff2');
}
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('/static/vendor/fonts/JetBrainsMono-Medium.woff2') format('woff2');
}
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('/static/vendor/fonts/JetBrainsMono-SemiBold.woff2') format('woff2');
}
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('/static/vendor/fonts/JetBrainsMono-Bold.woff2') format('woff2');
}
+89 -18
View File
@@ -262,10 +262,10 @@ body {
@keyframes logoPulse {
0%, 100% {
filter: drop-shadow(0 0 15px rgba(0, 212, 255, 0.3));
filter: drop-shadow(0 0 15px rgba(var(--accent-cyan-rgb), 0.3));
}
50% {
filter: drop-shadow(0 0 30px rgba(0, 212, 255, 0.6));
filter: drop-shadow(0 0 30px rgba(var(--accent-cyan-rgb), 0.6));
}
}
@@ -304,7 +304,7 @@ body {
color: var(--text-primary);
letter-spacing: 0.2em;
margin: 0;
text-shadow: 0 0 20px rgba(0, 212, 255, 0.3);
text-shadow: 0 0 20px rgba(var(--accent-cyan-rgb), 0.3);
white-space: nowrap;
}
@@ -453,7 +453,7 @@ body {
background: var(--bg-elevated);
border-color: var(--accent-cyan);
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0, 212, 255, 0.15);
box-shadow: 0 4px 20px rgba(var(--accent-cyan-rgb), 0.15);
}
.mode-card:hover .mode-icon {
@@ -2529,7 +2529,7 @@ header h1 .tagline {
border: 1px solid var(--accent-cyan);
border-radius: 4px;
overflow: hidden;
box-shadow: 0 0 20px rgba(0, 212, 255, 0.2);
box-shadow: 0 0 20px rgba(var(--accent-cyan-rgb), 0.2);
}
#aircraftMap {
@@ -2863,7 +2863,7 @@ header h1 .tagline {
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
box-shadow: 0 0 20px rgba(0, 212, 255, 0.1);
box-shadow: 0 0 20px rgba(var(--accent-cyan-rgb), 0.1);
}
.countdown-satellite-name {
@@ -5879,7 +5879,7 @@ body::before {
max-width: 550px;
padding: 30px;
text-align: center;
box-shadow: 0 0 50px rgba(0, 212, 255, 0.3);
box-shadow: 0 0 50px rgba(var(--accent-cyan-rgb), 0.3);
pointer-events: auto;
position: relative;
z-index: 100000;
@@ -5939,7 +5939,7 @@ body::before {
.disclaimer-modal .accept-btn:hover {
background: #fff;
box-shadow: 0 0 20px rgba(0, 212, 255, 0.5);
box-shadow: 0 0 20px rgba(var(--accent-cyan-rgb), 0.5);
}
.disclaimer-hidden {
@@ -6190,7 +6190,7 @@ body::before {
/* Map Clustering */
.marker-cluster {
background: rgba(0, 212, 255, 0.6);
background: rgba(var(--accent-cyan-rgb), 0.6);
border-radius: 50%;
display: flex;
align-items: center;
@@ -7045,7 +7045,7 @@ body::before {
.radio-module-box.scanner-main {
background: linear-gradient(180deg, var(--bg-secondary) 0%, rgba(0,20,30,0.95) 100%);
border: 1px solid var(--accent-cyan-dim);
box-shadow: 0 0 20px rgba(0, 212, 255, 0.1), inset 0 0 40px rgba(0, 0, 0, 0.3);
box-shadow: 0 0 20px rgba(var(--accent-cyan-rgb), 0.1), inset 0 0 40px rgba(0, 0, 0, 0.3);
}
.radio-module-box.scanner-main::before {
@@ -7224,7 +7224,7 @@ body::before {
}
.radio-module-box table tbody tr:hover {
background: rgba(0, 212, 255, 0.05);
background: rgba(var(--accent-cyan-rgb), 0.05);
}
/* Log Content Compact */
@@ -7257,14 +7257,14 @@ body::before {
.radio-mode-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
background: rgba(0, 212, 255, 0.05);
background: rgba(var(--accent-cyan-rgb), 0.05);
}
.radio-mode-btn.active {
background: linear-gradient(135deg, rgba(0, 212, 255, 0.2), rgba(0, 255, 136, 0.1));
background: linear-gradient(135deg, rgba(var(--accent-cyan-rgb), 0.2), rgba(0, 255, 136, 0.1));
border-color: var(--accent-cyan);
color: var(--accent-cyan);
box-shadow: 0 0 20px rgba(0, 212, 255, 0.2), inset 0 0 20px rgba(0, 212, 255, 0.05);
box-shadow: 0 0 20px rgba(var(--accent-cyan-rgb), 0.2), inset 0 0 20px rgba(var(--accent-cyan-rgb), 0.05);
}
/* Listening Mode Panels */
@@ -7292,7 +7292,7 @@ body::before {
.preset-freq-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
background: rgba(0, 212, 255, 0.1);
background: rgba(var(--accent-cyan-rgb), 0.1);
}
.preset-freq-btn:active {
@@ -7652,6 +7652,11 @@ body[data-mode="tscm"] {
background-size: unset;
}
html[data-ui-tier="lean"][data-theme="light"] body {
background-color: var(--bg-primary);
background-image: none;
}
[data-ui-tier="lean"] *,
[data-ui-tier="lean"] *::before,
[data-ui-tier="lean"] *::after {
@@ -7677,9 +7682,75 @@ body[data-mode="tscm"] {
/* ============================================
ENHANCED TIER visual edge/glow overrides
ENHANCED TIER panel surface overrides
Replaces hardcoded cool-dark navy gradients
with warm near-black amber equivalents.
============================================ */
html[data-ui-tier="enhanced"] {
--visual-edge-cyan: rgba(200, 150, 40, 0.34);
--visual-glow-cyan: 0 0 24px rgba(200, 150, 40, 0.16);
--visual-edge-cyan: rgba(46, 125, 138, 0.30);
--visual-glow-cyan: 0 0 24px rgba(46, 125, 138, 0.12);
--visual-surface-soft: linear-gradient(180deg, rgba(6, 10, 10, 0.9) 0%, rgba(3, 5, 5, 0.95) 100%);
--visual-surface-panel: linear-gradient(160deg, rgba(6, 10, 10, 0.95) 0%, rgba(2, 4, 4, 0.96) 100%);
}
html[data-ui-tier="enhanced"] .mode-nav {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.96) 0%, rgba(2, 4, 4, 0.98) 100%);
}
html[data-ui-tier="enhanced"] .mode-nav-dropdown-menu {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.98) 0%, rgba(2, 4, 4, 0.99) 100%);
border-color: rgba(46, 125, 138, 0.20);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(46, 125, 138, 0.09);
}
html[data-ui-tier="enhanced"] .run-state-strip {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.96) 0%, rgba(2, 4, 4, 0.97) 100%);
}
html[data-ui-tier="enhanced"] .section h3 {
background: linear-gradient(180deg, rgba(6, 10, 10, 1) 0%, rgba(4, 8, 8, 1) 100%);
}
html[data-ui-tier="enhanced"] .section h3::after {
background: rgba(2, 4, 4, 0.9);
}
html[data-ui-tier="enhanced"] .form-group input,
html[data-ui-tier="enhanced"] .form-group select {
background: rgba(2, 4, 4, 0.72);
}
html[data-ui-tier="enhanced"] .preset-btn,
html[data-ui-tier="enhanced"] .control-btn,
html[data-ui-tier="enhanced"] .clear-btn {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.88) 0%, rgba(2, 4, 4, 0.9) 100%);
}
html[data-ui-tier="enhanced"] .output-panel {
background: linear-gradient(180deg, rgba(2, 4, 4, 0.98) 0%, rgba(1, 2, 2, 0.99) 100%);
}
html[data-ui-tier="enhanced"] .output-header {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.95) 0%, rgba(2, 4, 4, 0.98) 100%);
}
html[data-ui-tier="enhanced"] .output-content {
background: linear-gradient(180deg, rgba(2, 4, 4, 0.6) 0%, rgba(2, 4, 4, 0.9) 100%);
}
html[data-ui-tier="enhanced"] .stats > div {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.8) 0%, rgba(2, 4, 4, 0.82) 100%);
}
html[data-ui-tier="enhanced"] .message {
background: linear-gradient(180deg, rgba(4, 8, 8, 0.8) 0%, rgba(2, 4, 4, 0.82) 100%);
}
html[data-ui-tier="enhanced"] .status-bar {
background: linear-gradient(180deg, rgba(3, 6, 6, 0.96) 0%, rgba(2, 4, 4, 0.97) 100%);
}
html[data-ui-tier="enhanced"] .status-indicator,
html[data-ui-tier="enhanced"] .control-group {
background: linear-gradient(180deg, rgba(3, 6, 6, 0.78) 0%, rgba(2, 4, 4, 0.8) 100%);
}
+4 -4
View File
@@ -284,7 +284,7 @@
#btLocateMap {
position: absolute;
inset: 0;
background: #1a1a2e;
background: var(--bg-primary, #07090e);
}
.btl-map-overlay-controls {
@@ -442,8 +442,8 @@
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--accent-cyan, #00d4ff);
background: rgba(0, 212, 255, 0.1);
border: 1px solid rgba(0, 212, 255, 0.3);
background: rgba(var(--accent-cyan-rgb), 0.1);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.3);
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
@@ -452,7 +452,7 @@
}
.btl-detect-irk-btn:hover {
background: rgba(0, 212, 255, 0.2);
background: rgba(var(--accent-cyan-rgb), 0.2);
border-color: var(--accent-cyan, #00d4ff);
}
+23
View File
@@ -471,3 +471,26 @@
height: 40px;
}
}
html[data-ui-tier="enhanced"] .meteor-visuals-container {
--ms-border: rgba(46, 125, 138, 0.22);
--ms-surface: linear-gradient(180deg, rgba(2, 6, 6, 0.97) 0%, rgba(1, 3, 3, 0.98) 100%);
--ms-accent: #2e7d8a;
--ms-accent-dim: rgba(46, 125, 138, 0.12);
background: radial-gradient(circle at 14% -18%, rgba(46, 125, 138, 0.10) 0%, rgba(46, 125, 138, 0) 38%),
radial-gradient(circle at 86% -26%, rgba(46, 125, 138, 0.07) 0%, rgba(46, 125, 138, 0) 36%),
#000202;
}
html[data-ui-tier="enhanced"] .ms-headline,
html[data-ui-tier="enhanced"] .ms-events-panel {
background: rgba(2, 6, 6, 0.9);
}
html[data-ui-tier="enhanced"] .ms-events-table th {
background: rgba(2, 6, 6, 0.95);
}
html[data-ui-tier="enhanced"] .ms-events-table tr:hover td {
background: rgba(46, 125, 138, 0.04);
}
+14
View File
@@ -199,3 +199,17 @@
align-items: stretch;
}
}
html[data-ui-tier="enhanced"] .morse-raw-panel {
border-color: rgba(46, 125, 138, 0.18);
background: rgba(1, 4, 4, 0.9);
}
html[data-ui-tier="enhanced"] .morse-raw-text {
color: rgba(70, 180, 200, 0.90);
}
html[data-ui-tier="enhanced"] .morse-metrics-panel span {
border-color: rgba(46, 125, 138, 0.18);
background: rgba(1, 4, 4, 0.88);
}
+4 -4
View File
@@ -160,14 +160,14 @@
flex-direction: column;
align-items: center;
padding: 4px 10px;
background: rgba(0, 229, 255, 0.05);
border: 1px solid rgba(0, 229, 255, 0.15);
background: rgba(var(--accent-cyan-rgb), 0.05);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.15);
border-radius: 4px;
min-width: 55px;
}
.radiosonde-strip .strip-stat:hover {
background: rgba(0, 229, 255, 0.1);
border-color: rgba(0, 229, 255, 0.3);
background: rgba(var(--accent-cyan-rgb), 0.1);
border-color: rgba(var(--accent-cyan-rgb), 0.3);
}
.radiosonde-strip .strip-value {
font-family: var(--font-mono);
+1 -1
View File
@@ -342,7 +342,7 @@
.sstv-general-image-card:hover {
border-color: var(--accent-cyan);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 212, 255, 0.2);
box-shadow: 0 4px 12px rgba(var(--accent-cyan-rgb), 0.2);
}
.sstv-general-image-card-inner {
+2 -2
View File
@@ -401,7 +401,7 @@
.sstv-image-card:hover {
border-color: var(--accent-cyan);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 212, 255, 0.2);
box-shadow: 0 4px 12px rgba(var(--accent-cyan-rgb), 0.2);
}
.sstv-image-card-inner {
@@ -688,7 +688,7 @@
font-weight: 700;
color: var(--accent-cyan);
letter-spacing: 2px;
text-shadow: 0 0 20px rgba(0, 212, 255, 0.3);
text-shadow: 0 0 20px rgba(var(--accent-cyan-rgb), 0.3);
}
.sstv-countdown-value.imminent {
+29 -29
View File
@@ -300,7 +300,7 @@
}
.subghz-btn.active {
background: rgba(0, 212, 255, 0.1);
background: rgba(var(--accent-cyan-rgb), 0.1);
border-color: var(--accent-cyan, var(--accent-cyan));
color: var(--accent-cyan, var(--accent-cyan));
}
@@ -384,9 +384,9 @@
}
.subghz-capture-card.selected {
border-color: rgba(0, 212, 255, 0.85);
box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.3);
background: rgba(0, 212, 255, 0.06);
border-color: rgba(var(--accent-cyan-rgb), 0.85);
box-shadow: 0 0 0 1px rgba(var(--accent-cyan-rgb), 0.3);
background: rgba(var(--accent-cyan-rgb), 0.06);
}
.subghz-capture-header {
@@ -455,9 +455,9 @@
}
.subghz-capture-tag.auto {
border-color: rgba(0, 212, 255, 0.55);
border-color: rgba(var(--accent-cyan-rgb), 0.55);
color: var(--accent-cyan);
background: rgba(0, 212, 255, 0.12);
background: rgba(var(--accent-cyan-rgb), 0.12);
}
.subghz-capture-tag.hint {
@@ -536,13 +536,13 @@
}
.subghz-capture-actions button.select-btn {
border-color: rgba(0, 212, 255, 0.5);
border-color: rgba(var(--accent-cyan-rgb), 0.5);
color: var(--accent-cyan);
}
.subghz-capture-actions button.select-btn.selected {
border-color: rgba(0, 212, 255, 0.9);
background: rgba(0, 212, 255, 0.18);
border-color: rgba(var(--accent-cyan-rgb), 0.9);
background: rgba(var(--accent-cyan-rgb), 0.18);
color: #7beeff;
}
@@ -781,14 +781,14 @@
height: 26px;
border: 1px solid var(--border-color, #2a3040);
border-radius: 4px;
background: linear-gradient(90deg, rgba(0, 212, 255, 0.07), rgba(255, 170, 0, 0.07));
background: linear-gradient(90deg, rgba(var(--accent-cyan-rgb), 0.07), rgba(255, 170, 0, 0.07));
margin-bottom: 8px;
overflow: hidden;
}
.subghz-tx-burst-timeline.dragging {
border-color: rgba(0, 212, 255, 0.65);
box-shadow: 0 0 0 1px rgba(0, 212, 255, 0.25) inset;
border-color: rgba(var(--accent-cyan-rgb), 0.65);
box-shadow: 0 0 0 1px rgba(var(--accent-cyan-rgb), 0.25) inset;
}
.subghz-tx-burst-selection {
@@ -796,8 +796,8 @@
top: 3px;
bottom: 3px;
border-radius: 3px;
border: 1px solid rgba(0, 212, 255, 0.95);
background: rgba(0, 212, 255, 0.22);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.95);
background: rgba(var(--accent-cyan-rgb), 0.22);
pointer-events: none;
display: none;
z-index: 2;
@@ -823,8 +823,8 @@
}
.subghz-tx-burst-marker:hover {
background: rgba(0, 212, 255, 0.85);
border-color: rgba(0, 212, 255, 1);
background: rgba(var(--accent-cyan-rgb), 0.85);
border-color: rgba(var(--accent-cyan-rgb), 1);
}
.subghz-tx-burst-list {
@@ -861,7 +861,7 @@
.subghz-tx-burst-item button {
padding: 2px 8px;
border: 1px solid rgba(0, 212, 255, 0.5);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.5);
border-radius: 3px;
background: transparent;
color: var(--accent-cyan);
@@ -871,7 +871,7 @@
}
.subghz-tx-burst-item button:hover {
background: rgba(0, 212, 255, 0.12);
background: rgba(var(--accent-cyan-rgb), 0.12);
}
.subghz-tx-modal-actions {
@@ -901,13 +901,13 @@
}
.subghz-tx-trim-btn {
background: rgba(0, 212, 255, 0.14);
background: rgba(var(--accent-cyan-rgb), 0.14);
color: var(--accent-cyan);
border-color: rgba(0, 212, 255, 0.55) !important;
border-color: rgba(var(--accent-cyan-rgb), 0.55) !important;
}
.subghz-tx-trim-btn:hover {
background: rgba(0, 212, 255, 0.26);
background: rgba(var(--accent-cyan-rgb), 0.26);
}
.subghz-tx-cancel-btn {
@@ -1043,7 +1043,7 @@
}
.subghz-action-btn.decode:hover {
background: rgba(0, 212, 255, 0.12);
background: rgba(var(--accent-cyan-rgb), 0.12);
border-color: var(--accent-cyan, var(--accent-cyan));
color: var(--accent-cyan, var(--accent-cyan));
}
@@ -1275,7 +1275,7 @@
.subghz-phase-step.active {
color: var(--accent-cyan, var(--accent-cyan));
text-shadow: 0 0 6px rgba(0, 212, 255, 0.3);
text-shadow: 0 0 6px rgba(var(--accent-cyan-rgb), 0.3);
}
.subghz-phase-step.completed {
@@ -1328,9 +1328,9 @@
}
.subghz-burst-indicator.recent {
border-color: rgba(0, 212, 255, 0.45);
border-color: rgba(var(--accent-cyan-rgb), 0.45);
color: var(--accent-cyan);
background: rgba(0, 212, 255, 0.1);
background: rgba(var(--accent-cyan-rgb), 0.1);
}
.subghz-burst-indicator.recent .subghz-burst-dot {
@@ -1445,8 +1445,8 @@
transform: translateY(0);
}
.subghz-hub-card--cyan { border-color: rgba(0, 212, 255, 0.2); }
.subghz-hub-card--cyan:hover { border-color: var(--accent-cyan, var(--accent-cyan)); background: rgba(0, 212, 255, 0.05); }
.subghz-hub-card--cyan { border-color: rgba(var(--accent-cyan-rgb), 0.2); }
.subghz-hub-card--cyan:hover { border-color: var(--accent-cyan, var(--accent-cyan)); background: rgba(var(--accent-cyan-rgb), 0.05); }
.subghz-hub-card--cyan .subghz-hub-icon { color: var(--accent-cyan, var(--accent-cyan)); }
.subghz-hub-card--green { border-color: rgba(0, 255, 136, 0.2); }
@@ -1736,8 +1736,8 @@
.subghz-rx-burst-pill.recent {
color: var(--accent-cyan);
border-color: rgba(0, 212, 255, 0.65);
background: rgba(0, 212, 255, 0.12);
border-color: rgba(var(--accent-cyan-rgb), 0.65);
background: rgba(var(--accent-cyan-rgb), 0.12);
}
.subghz-rx-level-label {
+2 -2
View File
@@ -17,7 +17,7 @@
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--accent-cyan, #00d4ff);
border-bottom: 1px solid rgba(0, 212, 255, 0.2);
border-bottom: 1px solid rgba(var(--accent-cyan-rgb), 0.2);
padding-bottom: 6px;
margin-top: 8px;
}
@@ -221,7 +221,7 @@
fill: none;
stroke: var(--accent-cyan, #00d4ff);
stroke-width: 1.5;
filter: drop-shadow(0 0 2px rgba(0, 212, 255, 0.4));
filter: drop-shadow(0 0 2px rgba(var(--accent-cyan-rgb), 0.4));
}
.sys-sparkline-area {
+136
View File
@@ -1180,3 +1180,139 @@
font-family: var(--font-mono, monospace);
font-size: 9px;
}
/* ---- Enhanced tier: replace blue palette with signals teal ---- */
html[data-ui-tier="enhanced"] .wf-container {
--wf-border: rgba(46, 125, 138, 0.22);
--wf-surface: linear-gradient(180deg, rgba(2, 6, 6, 0.97) 0%, rgba(1, 3, 3, 0.98) 100%);
background: radial-gradient(circle at 14% -18%, rgba(46, 125, 138, 0.08) 0%, rgba(46, 125, 138, 0) 38%),
radial-gradient(circle at 86% -26%, rgba(46, 125, 138, 0.05) 0%, rgba(46, 125, 138, 0) 36%),
#000202;
}
html[data-ui-tier="enhanced"] .wf-headline {
background: rgba(2, 6, 6, 0.86);
}
html[data-ui-tier="enhanced"] .wf-headline-tag {
color: rgba(70, 185, 200, 0.90);
}
html[data-ui-tier="enhanced"] .wf-rx-vfo {
border-color: rgba(46, 125, 138, 0.25);
background: linear-gradient(180deg, rgba(3, 8, 8, 0.92) 0%, rgba(1, 4, 4, 0.95) 100%);
}
html[data-ui-tier="enhanced"] .wf-rx-vfo-status {
color: rgba(65, 175, 192, 0.88);
}
html[data-ui-tier="enhanced"] .wf-rx-vfo-readout {
color: rgba(80, 190, 205, 0.92);
}
html[data-ui-tier="enhanced"] #wfRxFreqReadout {
text-shadow: 0 0 16px rgba(46, 125, 138, 0.25);
}
html[data-ui-tier="enhanced"] .wf-rx-modebank {
border-color: rgba(46, 125, 138, 0.22);
background: rgba(1, 4, 4, 0.86);
}
html[data-ui-tier="enhanced"] .wf-mode-btn {
border-color: rgba(46, 125, 138, 0.24);
background: linear-gradient(180deg, rgba(4, 8, 8, 0.95) 0%, rgba(2, 5, 5, 0.95) 100%);
color: rgba(65, 175, 192, 0.90);
}
html[data-ui-tier="enhanced"] .wf-mode-btn:hover {
border-color: rgba(46, 125, 138, 0.48);
}
html[data-ui-tier="enhanced"] .wf-mode-btn.is-active,
html[data-ui-tier="enhanced"] .wf-mode-btn.active {
border-color: rgba(46, 125, 138, 0.62);
background: linear-gradient(180deg, rgba(6, 16, 18, 0.92) 0%, rgba(4, 12, 14, 0.95) 100%);
color: rgba(100, 210, 222, 0.96);
box-shadow: 0 0 14px rgba(46, 125, 138, 0.22);
}
html[data-ui-tier="enhanced"] .wf-rx-levels,
html[data-ui-tier="enhanced"] .wf-rx-meter-wrap,
html[data-ui-tier="enhanced"] .wf-rx-actions {
border-color: rgba(46, 125, 138, 0.20);
background: rgba(1, 4, 4, 0.85);
}
html[data-ui-tier="enhanced"] .wf-monitor-select {
border-color: rgba(46, 125, 138, 0.25);
background: rgba(1, 3, 3, 0.8);
}
html[data-ui-tier="enhanced"] .wf-rx-smeter-fill {
box-shadow: 0 0 10px rgba(46, 125, 138, 0.22);
}
html[data-ui-tier="enhanced"] .wf-monitor-btn-secondary {
border-color: rgba(46, 125, 138, 0.45);
background: linear-gradient(180deg, rgba(4, 12, 14, 0.95) 0%, rgba(2, 8, 10, 0.95) 100%);
color: rgba(80, 190, 205, 0.90);
}
html[data-ui-tier="enhanced"] .wf-freq-bar {
background: rgba(2, 6, 6, 0.78);
}
html[data-ui-tier="enhanced"] .wf-spectrum-canvas-wrap {
background: radial-gradient(circle at 50% -120%, rgba(46, 125, 138, 0.06) 0%, rgba(46, 125, 138, 0) 65%);
}
html[data-ui-tier="enhanced"] .wf-band-strip {
background: linear-gradient(180deg, rgba(2, 6, 6, 0.96) 0%, rgba(1, 3, 3, 0.98) 100%);
}
html[data-ui-tier="enhanced"] .wf-band-block {
border-color: rgba(46, 125, 138, 0.42);
color: rgba(80, 190, 205, 0.92);
}
html[data-ui-tier="enhanced"] .wf-band-edge {
color: rgba(65, 175, 192, 0.88);
}
html[data-ui-tier="enhanced"] .wf-band-marker::before {
background: rgba(46, 125, 138, 0.58);
box-shadow: 0 0 5px rgba(46, 125, 138, 0.30);
}
html[data-ui-tier="enhanced"] .wf-band-marker-label {
border-color: rgba(46, 125, 138, 0.48);
background: rgba(2, 5, 5, 0.95);
color: rgba(80, 190, 205, 0.90);
}
html[data-ui-tier="enhanced"] .wf-tune-line {
background: rgba(46, 125, 138, 0.72);
}
html[data-ui-tier="enhanced"] .wf-freq-axis {
background: rgba(2, 6, 6, 0.86);
}
html[data-ui-tier="enhanced"] .wf-side .section.wf-side-hero {
background: linear-gradient(180deg, rgba(3, 8, 8, 0.95) 0%, rgba(1, 4, 4, 0.97) 100%);
border-color: rgba(46, 125, 138, 0.30);
box-shadow: 0 8px 24px rgba(0, 8, 10, 0.30), inset 0 0 0 1px rgba(255, 255, 255, 0.03);
}
html[data-ui-tier="enhanced"] .wf-side-chip {
color: rgba(65, 175, 192, 0.88);
border-color: rgba(46, 125, 138, 0.32);
background: rgba(6, 16, 18, 0.30);
}
html[data-ui-tier="enhanced"] .wf-side-stat {
border-color: rgba(46, 125, 138, 0.20);
}
+9 -9
View File
@@ -308,7 +308,7 @@
opacity: 1;
}
.wxsat-timeline-pass.apt { background: rgba(0, 212, 255, 0.6); }
.wxsat-timeline-pass.apt { background: rgba(var(--accent-cyan-rgb), 0.6); }
.wxsat-timeline-pass.lrpt { background: rgba(0, 255, 136, 0.6); }
.wxsat-timeline-pass.scheduled { border: 1px solid var(--accent-yellow); }
@@ -585,7 +585,7 @@
}
.wxsat-pass-mode.apt {
background: rgba(0, 212, 255, 0.15);
background: rgba(var(--accent-cyan-rgb), 0.15);
color: var(--accent-cyan);
}
@@ -626,7 +626,7 @@
}
.wxsat-pass-quality.good {
background: rgba(0, 212, 255, 0.15);
background: rgba(var(--accent-cyan-rgb), 0.15);
color: var(--accent-cyan);
}
@@ -759,16 +759,16 @@
.wxsat-map-tooltip {
background: rgba(5, 15, 32, 0.92);
border: 1px solid rgba(102, 229, 255, 0.65);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.65);
border-radius: 4px;
color: #8fe8ff;
color: var(--accent-cyan);
box-shadow: 0 0 12px rgba(0, 210, 255, 0.24);
font-size: 10px;
letter-spacing: 0.25px;
}
.wxsat-map-tooltip.leaflet-tooltip-top:before {
border-top-color: rgba(102, 229, 255, 0.65);
border-top-color: rgba(var(--accent-cyan-rgb), 0.65);
}
/* ===== Image Gallery Panel ===== */
@@ -1221,8 +1221,8 @@
.wxsat-phase-step.completed {
color: var(--accent-cyan, #00d4ff);
border-color: rgba(0, 212, 255, 0.3);
background: rgba(0, 212, 255, 0.05);
border-color: rgba(var(--accent-cyan-rgb), 0.3);
background: rgba(var(--accent-cyan-rgb), 0.05);
opacity: 0.7;
}
@@ -1267,7 +1267,7 @@
.wxsat-console-filter.active {
border-color: var(--accent-cyan, #00d4ff);
color: var(--accent-cyan, #00d4ff);
background: rgba(0, 212, 255, 0.08);
background: rgba(var(--accent-cyan-rgb), 0.08);
}
.wxsat-console-actions {
+30 -31
View File
@@ -157,7 +157,7 @@ body {
.stat-badge {
background: var(--bg-card);
border: 1px solid rgba(0, 212, 255, 0.3);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.3);
border-radius: 4px;
padding: 4px 10px;
font-family: var(--font-mono);
@@ -309,7 +309,7 @@ body {
/* Panels */
.panel {
background: var(--bg-panel);
border: 1px solid rgba(0, 212, 255, 0.2);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.2);
overflow: hidden;
position: relative;
}
@@ -326,8 +326,8 @@ body {
.panel-header {
padding: 10px 15px;
background: rgba(0, 212, 255, 0.05);
border-bottom: 1px solid rgba(0, 212, 255, 0.1);
background: rgba(var(--accent-cyan-rgb), 0.05);
border-bottom: 1px solid rgba(var(--accent-cyan-rgb), 0.1);
font-family: 'Orbitron', monospace;
font-size: 11px;
font-weight: 500;
@@ -955,7 +955,7 @@ body {
.packet-entry {
padding: 7px 10px;
border-bottom: 1px solid rgba(0, 212, 255, 0.08);
border-bottom: 1px solid rgba(var(--accent-cyan-rgb), 0.08);
font-size: 10px;
font-family: var(--font-mono);
word-break: break-word;
@@ -1010,7 +1010,7 @@ body {
.packet-modal {
position: fixed;
inset: 0;
z-index: 2000;
z-index: 5000;
display: flex;
align-items: center;
justify-content: center;
@@ -1140,7 +1140,7 @@ body {
gap: 10px;
padding: 10px;
background: var(--bg-panel);
border-bottom: 1px solid rgba(0, 212, 255, 0.2);
border-bottom: 1px solid rgba(var(--accent-cyan-rgb), 0.2);
}
.satellite-selector label {
@@ -1153,7 +1153,7 @@ body {
.satellite-selector select {
flex: 1;
background: rgba(0, 212, 255, 0.1);
background: rgba(var(--accent-cyan-rgb), 0.1);
border: 1px solid var(--accent-cyan);
border-radius: 4px;
padding: 8px 12px;
@@ -1166,12 +1166,12 @@ body {
.satellite-selector select:focus {
outline: none;
box-shadow: 0 0 15px rgba(0, 212, 255, 0.3);
box-shadow: 0 0 15px rgba(var(--accent-cyan-rgb), 0.3);
}
#satRefreshBtn {
background: transparent;
border: 1px solid rgba(0, 212, 255, 0.4);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.4);
border-radius: 4px;
color: var(--text-secondary);
cursor: pointer;
@@ -1199,7 +1199,7 @@ body {
/* Countdown panel */
.countdown-panel {
flex-shrink: 0;
background: linear-gradient(135deg, rgba(0, 212, 255, 0.1) 0%, rgba(0, 255, 136, 0.05) 100%);
background: linear-gradient(135deg, rgba(var(--accent-cyan-rgb), 0.1) 0%, rgba(0, 255, 136, 0.05) 100%);
}
.countdown-display {
@@ -1232,7 +1232,7 @@ body {
.countdown-block {
background: rgba(0, 0, 0, 0.3);
border: 1px solid rgba(0, 212, 255, 0.2);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.2);
border-radius: 4px;
padding: 8px 4px;
text-align: center;
@@ -1359,7 +1359,7 @@ body {
.pass-item {
background: rgba(0, 0, 0, 0.3);
border: 1px solid rgba(0, 212, 255, 0.15);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.15);
border-radius: 4px;
padding: 8px 10px;
margin-bottom: 6px;
@@ -1369,13 +1369,13 @@ body {
.pass-item:hover {
border-color: var(--accent-cyan);
background: rgba(0, 212, 255, 0.05);
background: rgba(var(--accent-cyan-rgb), 0.05);
}
.pass-item.active {
border-color: var(--accent-cyan);
box-shadow: 0 0 15px rgba(0, 212, 255, 0.2);
background: rgba(0, 212, 255, 0.1);
box-shadow: 0 0 15px rgba(var(--accent-cyan-rgb), 0.2);
background: rgba(var(--accent-cyan-rgb), 0.1);
}
.pass-item-header {
@@ -1407,7 +1407,7 @@ body {
}
.pass-quality.good {
background: rgba(0, 212, 255, 0.2);
background: rgba(var(--accent-cyan-rgb), 0.2);
color: var(--accent-cyan);
}
@@ -1434,7 +1434,7 @@ body {
gap: 20px;
padding: 10px 20px;
background: var(--bg-panel);
border-top: 1px solid rgba(0, 212, 255, 0.3);
border-top: 1px solid rgba(var(--accent-cyan-rgb), 0.3);
}
.control-group {
@@ -1455,7 +1455,7 @@ body {
width: 90px;
padding: 6px 8px;
background: rgba(0, 0, 0, 0.3);
border: 1px solid rgba(0, 212, 255, 0.3);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.3);
border-radius: 4px;
color: var(--accent-cyan);
font-family: var(--font-mono);
@@ -1465,13 +1465,13 @@ body {
.control-group input:focus {
outline: none;
border-color: var(--accent-cyan);
box-shadow: 0 0 10px rgba(0, 212, 255, 0.2);
box-shadow: 0 0 10px rgba(var(--accent-cyan-rgb), 0.2);
}
.btn {
padding: 8px 16px;
border: 1px solid var(--accent-cyan);
background: rgba(0, 212, 255, 0.1);
background: rgba(var(--accent-cyan-rgb), 0.1);
color: var(--accent-cyan);
font-family: 'Orbitron', monospace;
font-size: 11px;
@@ -1486,7 +1486,7 @@ body {
.btn:hover {
background: var(--accent-cyan);
color: var(--bg-dark);
box-shadow: 0 0 20px rgba(0, 212, 255, 0.3);
box-shadow: 0 0 20px rgba(var(--accent-cyan-rgb), 0.3);
}
.btn.primary {
@@ -1780,17 +1780,16 @@ body.embedded .controls-bar {
}
/* ============================================
ENHANCED TIER amber military console
ENHANCED TIER signals teal console
============================================ */
html[data-ui-tier="enhanced"] {
--bg-dark: #080600;
--bg-panel: #0c0a04;
--bg-card: #0e0b05;
--border-glow: rgba(200, 150, 40, 0.25);
--border-color: rgba(200, 150, 40, 0.2);
--grid-line: rgba(200, 150, 40, 0.07);
--accent-cyan: #c89628;
--accent-green: #c89628;
--bg-dark: #000000;
--bg-panel: #020404;
--bg-card: #020404;
--border-glow: rgba(46, 125, 138, 0.20);
--border-color: rgba(46, 125, 138, 0.18);
--grid-line: rgba(46, 125, 138, 0.07);
--accent-cyan: #2e7d8a;
}
/* ============================================
+68 -9
View File
@@ -266,7 +266,7 @@
}
.toggle-switch input:focus + .toggle-slider {
box-shadow: 0 0 0 2px rgba(0, 212, 255, 0.3);
box-shadow: 0 0 0 2px rgba(var(--accent-cyan-rgb), 0.3);
}
/* Select Dropdown */
@@ -461,8 +461,8 @@
/* Info Callout */
.settings-info {
background: rgba(0, 212, 255, 0.1);
border: 1px solid rgba(0, 212, 255, 0.2);
background: rgba(var(--accent-cyan-rgb), 0.1);
border: 1px solid rgba(var(--accent-cyan-rgb), 0.2);
border-radius: 6px;
padding: 12px;
margin-top: 16px;
@@ -474,25 +474,32 @@
color: var(--accent-cyan, #00d4ff);
}
/* Map tile variants */
.tile-layer-cyan {
/* Map tile variants — teal tint, skipped in lean mode */
html:not([data-ui-tier="lean"]) .tile-layer-cyan {
filter: sepia(0.35) hue-rotate(185deg) saturate(1.75) brightness(1.06) contrast(1.05);
}
/* Global Leaflet map theme: cyber overlay */
/* Lean mode: suppress every map filter unconditionally */
html[data-ui-tier="lean"] .leaflet-tile-pane,
html[data-ui-tier="lean"] .leaflet-tile,
html[data-ui-tier="lean"] .tile-layer-cyan {
filter: none !important;
}
/* Global Leaflet map theme: cyber overlay — default and enhanced only, not lean */
.leaflet-container.map-theme-cyber {
position: relative;
background: #020813;
isolation: isolate;
}
.leaflet-container.map-theme-cyber .leaflet-tile-pane {
html:not([data-ui-tier="lean"]) .leaflet-container.map-theme-cyber .leaflet-tile-pane {
filter: sepia(0.74) hue-rotate(176deg) saturate(1.72) brightness(1.05) contrast(1.08);
opacity: 1;
}
/* Hard global fallback: enforce cyber tint on all Leaflet tile images */
html.map-cyber-enabled .leaflet-container .leaflet-tile {
/* Hard global fallback: enforce cyber tint on all Leaflet tile images — not lean */
html:not([data-ui-tier="lean"]).map-cyber-enabled .leaflet-container .leaflet-tile {
filter: sepia(0.74) hue-rotate(176deg) saturate(1.72) brightness(1.05) contrast(1.08) !important;
}
@@ -527,6 +534,58 @@ html.map-cyber-enabled .leaflet-container::after {
background-size: 52px 52px, 52px 52px;
}
/* Lean tier: no overlays, no filters — original tile colors */
html[data-ui-tier="lean"] .leaflet-container::before,
html[data-ui-tier="lean"] .leaflet-container::after {
background: none !important;
background-image: none !important;
}
/* Enhanced tier: signals teal map tint overrides — global (all Leaflet maps) */
html[data-ui-tier="enhanced"] .leaflet-container {
background: #000000;
}
html[data-ui-tier="enhanced"] .leaflet-container::before {
background: none !important;
}
html[data-ui-tier="enhanced"] .leaflet-tile-pane {
filter: sepia(0.85) hue-rotate(150deg) saturate(1.35) brightness(0.78) contrast(1.08);
}
/* Narrower overrides for cyber-specific classes (same filter, kept for !important precedence) */
html[data-ui-tier="enhanced"] .leaflet-container.map-theme-cyber {
background: #000000;
}
html[data-ui-tier="enhanced"] .tile-layer-cyan {
filter: sepia(0.85) hue-rotate(150deg) saturate(1.35) brightness(0.78) contrast(1.08);
}
html[data-ui-tier="enhanced"] .leaflet-container.map-theme-cyber .leaflet-tile-pane {
filter: sepia(0.85) hue-rotate(150deg) saturate(1.35) brightness(0.78) contrast(1.08);
}
html[data-ui-tier="enhanced"].map-cyber-enabled .leaflet-container {
background: #000000;
}
html[data-ui-tier="enhanced"].map-cyber-enabled .leaflet-container .leaflet-tile {
filter: sepia(0.85) hue-rotate(150deg) saturate(1.35) brightness(0.78) contrast(1.08) !important;
}
html[data-ui-tier="enhanced"].map-cyber-enabled .leaflet-container::before {
background: none;
}
html[data-ui-tier="enhanced"].map-cyber-enabled .leaflet-container::after {
background-image:
linear-gradient(rgba(46, 125, 138, 0.1) 1px, transparent 1px),
linear-gradient(90deg, rgba(46, 125, 138, 0.1) 1px, transparent 1px);
background-size: 52px 52px, 52px 52px;
}
/* Responsive */
@media (max-width: 1023px) {
.settings-tabs {