Files
intercept/static/css/index.css
Smittix dc4434db84 Add mobile responsive design overhaul
- Add responsive.css with shared utilities (hamburger menu, touch targets, responsive typography)
- Add hamburger menu and mobile drawer navigation to main app
- Add horizontal scrolling mobile nav bar for mode switching
- Refactor index.css with mobile-first breakpoints
- Update adsb_dashboard.css for mobile layouts
- Update satellite_dashboard.css for mobile layouts
- Add mobile nav controller to app.js with drawer toggle
- Hide stats/taglines on small screens
- Unified breakpoints: 480px (phone), 768px (tablet), 1024px (desktop)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 18:30:15 +00:00

5055 lines
97 KiB
CSS
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.
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
/* Tactical dark palette */
--bg-primary: #0a0c10;
--bg-secondary: #0f1218;
--bg-tertiary: #151a23;
--bg-card: #121620;
--bg-elevated: #1a202c;
/* Accent colors - sophisticated blue/amber */
--accent-cyan: #4a9eff;
--accent-cyan-dim: rgba(74, 158, 255, 0.15);
--accent-green: #22c55e;
--accent-green-dim: rgba(34, 197, 94, 0.15);
--accent-red: #ef4444;
--accent-red-dim: rgba(239, 68, 68, 0.15);
--accent-orange: #f59e0b;
--accent-amber: #d4a853;
--accent-amber-dim: rgba(212, 168, 83, 0.15);
/* Text hierarchy */
--text-primary: #e8eaed;
--text-secondary: #9ca3af;
--text-dim: #4b5563;
--text-muted: #374151;
/* Borders */
--border-color: #1f2937;
--border-light: #374151;
--border-glow: rgba(74, 158, 255, 0.2);
/* Status colors */
--status-online: #22c55e;
--status-warning: #f59e0b;
--status-error: #ef4444;
--status-offline: #6b7280;
}
[data-theme="light"] {
--bg-primary: #f8fafc;
--bg-secondary: #f1f5f9;
--bg-tertiary: #e2e8f0;
--bg-card: #ffffff;
--bg-elevated: #f8fafc;
--accent-cyan: #2563eb;
--accent-cyan-dim: rgba(37, 99, 235, 0.1);
--accent-green: #16a34a;
--accent-red: #dc2626;
--accent-orange: #d97706;
--accent-amber: #b45309;
--text-primary: #0f172a;
--text-secondary: #475569;
--text-dim: #94a3b8;
--text-muted: #cbd5e1;
--border-color: #e2e8f0;
--border-light: #cbd5e1;
--border-glow: rgba(37, 99, 235, 0.15);
}
[data-theme="light"] body {
background: var(--bg-primary);
}
[data-theme="light"] .leaflet-tile-pane {
filter: none;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
min-height: 100vh;
font-size: 14px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
/* ============================================
WELCOME PAGE
============================================ */
.welcome-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--bg-primary);
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.welcome-overlay::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background:
radial-gradient(circle at 50% 50%, rgba(74, 158, 255, 0.03) 0%, transparent 50%),
linear-gradient(180deg, transparent 0%, rgba(0, 212, 255, 0.02) 100%);
pointer-events: none;
}
.welcome-container {
width: 90%;
max-width: 900px;
z-index: 1;
animation: welcomeFadeIn 0.8s ease-out;
}
@keyframes welcomeFadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Welcome Header */
.welcome-header {
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 1px solid var(--border-color);
}
.welcome-logo {
animation: logoPulse 3s ease-in-out infinite;
}
@keyframes logoPulse {
0%, 100% {
filter: drop-shadow(0 0 15px rgba(0, 212, 255, 0.3));
}
50% {
filter: drop-shadow(0 0 30px rgba(0, 212, 255, 0.6));
}
}
.welcome-logo .signal-wave {
animation: signalPulse 2s ease-in-out infinite;
}
.welcome-logo .signal-wave-1 { animation-delay: 0s; }
.welcome-logo .signal-wave-2 { animation-delay: 0.2s; }
.welcome-logo .signal-wave-3 { animation-delay: 0.4s; }
@keyframes signalPulse {
0%, 100% { opacity: 0.3; }
50% { opacity: 1; }
}
.welcome-logo .logo-dot {
animation: dotPulse 1.5s ease-in-out infinite;
}
@keyframes dotPulse {
0%, 100% {
fill: #00ff88;
filter: drop-shadow(0 0 5px rgba(0, 255, 136, 0.5));
}
50% {
fill: #00ffaa;
filter: drop-shadow(0 0 15px rgba(0, 255, 136, 0.9));
}
}
.welcome-title-block {
text-align: left;
}
.welcome-title {
font-family: 'JetBrains Mono', monospace;
font-size: 2.5rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: 0.2em;
margin: 0;
text-shadow: 0 0 20px rgba(0, 212, 255, 0.3);
}
.welcome-tagline {
font-family: 'JetBrains Mono', monospace;
font-size: 0.9rem;
color: var(--accent-cyan);
letter-spacing: 0.15em;
margin: 4px 0 0 0;
}
.welcome-version {
display: inline-block;
font-family: 'JetBrains Mono', monospace;
font-size: 0.65rem;
color: var(--bg-primary);
background: var(--accent-cyan);
padding: 2px 8px;
border-radius: 3px;
letter-spacing: 0.05em;
margin-top: 8px;
}
/* Welcome Content Grid */
.welcome-content {
display: grid;
grid-template-columns: 1fr 1.5fr;
gap: 30px;
margin-bottom: 20px;
}
.welcome-content h2 {
font-family: 'JetBrains Mono', monospace;
font-size: 0.75rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.15em;
margin: 0 0 15px 0;
padding-bottom: 8px;
border-bottom: 1px solid var(--border-color);
}
/* Changelog Section */
.welcome-changelog {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 20px;
max-height: 320px;
overflow-y: auto;
}
.changelog-release {
margin-bottom: 20px;
}
.changelog-release:last-child {
margin-bottom: 0;
}
.changelog-version-header {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
.changelog-version {
font-family: 'JetBrains Mono', monospace;
font-size: 0.8rem;
color: var(--accent-cyan);
font-weight: 600;
}
.changelog-date {
font-family: 'Inter', sans-serif;
font-size: 0.7rem;
color: var(--text-dim);
}
.changelog-list {
margin: 0;
padding-left: 18px;
list-style: none;
}
.changelog-list li {
font-family: 'Inter', sans-serif;
font-size: 0.75rem;
color: var(--text-secondary);
margin-bottom: 6px;
position: relative;
}
.changelog-list li::before {
content: '>';
position: absolute;
left: -15px;
color: var(--accent-green);
font-family: 'JetBrains Mono', monospace;
}
/* Mode Selection Grid */
.welcome-modes {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 20px;
}
.mode-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
.mode-card {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 10px;
background: var(--bg-tertiary);
border: 1px solid var(--border-color);
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
text-align: center;
}
.mode-card:hover {
background: var(--bg-elevated);
border-color: var(--accent-cyan);
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0, 212, 255, 0.15);
}
.mode-card:active {
transform: translateY(0);
}
.mode-card .mode-icon {
font-size: 1.5rem;
margin-bottom: 6px;
}
.mode-card .mode-name {
font-family: 'JetBrains Mono', monospace;
font-size: 0.75rem;
font-weight: 600;
color: var(--text-primary);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.mode-card .mode-desc {
font-family: 'Inter', sans-serif;
font-size: 0.65rem;
color: var(--text-dim);
margin-top: 4px;
}
/* Welcome Footer */
.welcome-footer {
text-align: center;
padding-top: 15px;
border-top: 1px solid var(--border-color);
}
.welcome-footer p {
font-family: 'Inter', sans-serif;
font-size: 0.7rem;
color: var(--text-dim);
letter-spacing: 0.1em;
text-transform: uppercase;
margin: 0;
}
/* Welcome Scanline */
.welcome-scanline {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 2px;
background: linear-gradient(90deg, transparent, var(--accent-cyan), transparent);
animation: scanlineMove 5s linear infinite;
opacity: 0.4;
}
@keyframes scanlineMove {
0% { top: 0; }
100% { top: 100%; }
}
/* Welcome Fade Out */
.welcome-overlay.fade-out {
animation: welcomeFadeOut 0.4s ease-in forwards;
}
@keyframes welcomeFadeOut {
from { opacity: 1; }
to { opacity: 0; visibility: hidden; }
}
/* Responsive - Mobile First */
/* Base: Mobile styles */
.welcome-content {
grid-template-columns: 1fr;
}
.welcome-header {
flex-direction: column;
text-align: center;
}
.welcome-title-block {
text-align: center;
}
.mode-grid {
grid-template-columns: repeat(2, 1fr);
}
/* Larger phones: 3 columns for mode grid */
@media (min-width: 480px) {
.mode-grid {
grid-template-columns: repeat(3, 1fr);
}
}
/* Tablet and up: Side-by-side layout */
@media (min-width: 768px) {
.welcome-content {
grid-template-columns: 1fr 1.5fr;
}
.welcome-header {
flex-direction: row;
text-align: left;
}
.welcome-title-block {
text-align: left;
}
}
/* ============================================
END LANDING PAGE
============================================ */
.container {
max-width: 100%;
margin: 0;
padding: 0;
}
header {
background: var(--bg-secondary);
padding: 10px 12px;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 10px;
border-bottom: 1px solid var(--border-color);
position: relative;
min-height: 52px;
}
@media (min-width: 768px) {
header {
justify-content: center;
padding: 12px 20px;
}
}
@media (min-width: 1024px) {
header {
text-align: center;
display: block;
}
}
header::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(90deg, var(--accent-cyan) 0%, var(--accent-amber) 50%, var(--accent-cyan) 100%);
opacity: 0.8;
}
header::after {
display: none;
}
header h1 {
color: var(--text-primary);
font-size: 1.1rem;
font-weight: 600;
letter-spacing: 0.15em;
margin: 0;
display: inline;
vertical-align: middle;
}
.logo {
display: inline-block;
vertical-align: middle;
margin-right: 8px;
}
.logo svg {
width: 36px;
height: 36px;
filter: drop-shadow(0 0 8px var(--accent-cyan-dim));
transition: filter 0.3s ease;
}
.logo:hover svg {
filter: drop-shadow(0 0 12px var(--accent-cyan));
}
/* Mode Navigation Bar */
.mode-nav {
display: none;
background: var(--bg-tertiary);
border-bottom: 1px solid var(--border-color);
padding: 0 20px;
}
@media (min-width: 1024px) {
.mode-nav {
display: flex;
align-items: center;
gap: 8px;
height: 44px;
}
}
.mode-nav-group {
display: flex;
align-items: center;
gap: 4px;
}
.mode-nav-label {
font-size: 9px;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 1px;
margin-right: 8px;
font-weight: 500;
}
.mode-nav-divider {
width: 1px;
height: 24px;
background: var(--border-color);
margin: 0 12px;
}
.mode-nav-btn {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 14px;
background: transparent;
border: 1px solid transparent;
border-radius: 4px;
color: var(--text-secondary);
font-family: 'Inter', sans-serif;
font-size: 11px;
font-weight: 500;
cursor: pointer;
transition: all 0.15s ease;
}
.mode-nav-btn .nav-icon {
font-size: 14px;
}
.mode-nav-btn .nav-label {
text-transform: uppercase;
letter-spacing: 0.5px;
}
.mode-nav-btn:hover {
background: var(--bg-elevated);
color: var(--text-primary);
border-color: var(--border-color);
}
.mode-nav-btn.active {
background: var(--accent-cyan);
color: var(--bg-primary);
border-color: var(--accent-cyan);
}
.mode-nav-btn.active .nav-icon {
filter: brightness(0);
}
.mode-nav-actions {
margin-left: auto;
}
.nav-action-btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 14px;
background: var(--bg-elevated);
border: 1px solid var(--accent-cyan);
border-radius: 4px;
color: var(--accent-cyan);
font-family: 'Inter', sans-serif;
font-size: 11px;
font-weight: 500;
text-decoration: none;
cursor: pointer;
transition: all 0.15s ease;
}
.nav-action-btn .nav-icon {
font-size: 12px;
}
.nav-action-btn .nav-label {
text-transform: uppercase;
letter-spacing: 0.5px;
}
.nav-action-btn:hover {
background: var(--accent-cyan);
color: var(--bg-primary);
}
/* Dropdown Navigation */
.mode-nav-dropdown {
position: relative;
}
.mode-nav-dropdown-btn {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 14px;
background: transparent;
border: 1px solid transparent;
border-radius: 4px;
color: var(--text-secondary);
font-family: 'Inter', sans-serif;
font-size: 11px;
font-weight: 500;
cursor: pointer;
transition: all 0.15s ease;
}
.mode-nav-dropdown-btn:hover {
background: var(--bg-elevated);
color: var(--text-primary);
border-color: var(--border-color);
}
.mode-nav-dropdown-btn .nav-icon {
font-size: 14px;
}
.mode-nav-dropdown-btn .nav-label {
text-transform: uppercase;
letter-spacing: 0.5px;
}
.mode-nav-dropdown-btn .dropdown-arrow {
font-size: 8px;
margin-left: 4px;
transition: transform 0.2s ease;
}
.mode-nav-dropdown.open .mode-nav-dropdown-btn {
background: var(--bg-elevated);
color: var(--text-primary);
border-color: var(--border-color);
}
.mode-nav-dropdown.open .dropdown-arrow {
transform: rotate(180deg);
}
.mode-nav-dropdown.has-active .mode-nav-dropdown-btn {
background: var(--accent-cyan);
color: var(--bg-primary);
border-color: var(--accent-cyan);
}
.mode-nav-dropdown.has-active .mode-nav-dropdown-btn .nav-icon {
filter: brightness(0);
}
.mode-nav-dropdown-menu {
position: absolute;
top: 100%;
left: 0;
margin-top: 4px;
min-width: 180px;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 6px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
opacity: 0;
visibility: hidden;
transform: translateY(-8px);
transition: all 0.15s ease;
z-index: 1000;
padding: 6px;
}
.mode-nav-dropdown.open .mode-nav-dropdown-menu {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.mode-nav-dropdown-menu .mode-nav-btn {
width: 100%;
justify-content: flex-start;
padding: 10px 12px;
border-radius: 4px;
margin: 0;
}
.mode-nav-dropdown-menu .mode-nav-btn:hover {
background: var(--bg-elevated);
}
.mode-nav-dropdown-menu .mode-nav-btn.active {
background: var(--accent-cyan);
color: var(--bg-primary);
}
.version-badge {
font-size: 0.6rem;
font-weight: 500;
font-family: 'JetBrains Mono', monospace;
letter-spacing: 0.05em;
color: var(--text-secondary);
background: var(--bg-tertiary);
padding: 2px 8px;
border-radius: 4px;
border: 1px solid var(--border-color);
}
header p {
color: var(--text-secondary);
font-size: 11px;
letter-spacing: 0.1em;
text-transform: uppercase;
margin: 4px 0 8px 0;
}
header p.subtitle {
font-size: 10px;
color: var(--text-secondary);
margin: 0 0 8px 0;
}
header h1 .tagline {
font-weight: 400;
color: var(--accent-cyan, #00d4ff);
font-size: 0.6em;
opacity: 0.9;
display: none;
}
@media (min-width: 768px) {
header h1 .tagline {
display: inline;
}
}
/* Header stat badges */
.header-stats {
display: none;
justify-content: center;
gap: 8px;
flex-wrap: wrap;
}
@media (min-width: 768px) {
.header-stats {
display: flex;
}
}
.stat-badge {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
background: var(--bg-tertiary);
border: 1px solid var(--border-color);
border-radius: 6px;
font-family: 'JetBrains Mono', monospace;
transition: all 0.2s ease;
}
.stat-badge:hover {
border-color: var(--border-light);
background: var(--bg-elevated);
}
.stat-badge .badge-icon {
font-size: 14px;
opacity: 0.7;
}
.stat-badge .badge-value {
font-size: 14px;
font-weight: 600;
color: var(--accent-cyan);
}
.stat-badge .badge-label {
font-size: 10px;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.stat-badge .badge-value.highlight {
color: var(--accent-green);
}
.stat-badge .badge-value.warning {
color: var(--accent-orange);
}
.stat-badge .badge-value.alert {
color: var(--accent-red);
}
.stat-badge .badge-label {
font-size: 10px;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 1px;
}
.stat-badge .badge-icon {
font-size: 16px;
}
.header-stats-group {
display: none;
}
.header-stats-group.active {
display: flex;
gap: 12px;
flex-wrap: wrap;
justify-content: center;
}
/* UTC Clock in header */
.header-clock {
position: static;
transform: none;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
color: var(--text-secondary);
display: flex;
align-items: center;
gap: 6px;
margin-left: auto;
}
@media (min-width: 1024px) {
.header-clock {
position: absolute;
top: 50%;
left: 20px;
transform: translateY(-50%);
font-size: 12px;
gap: 8px;
margin-left: 0;
}
}
.header-clock .utc-time {
color: var(--accent-cyan);
font-weight: 600;
}
.header-clock .utc-label {
font-size: 9px;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 1px;
}
/* Active mode indicator */
.active-mode-indicator {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 12px;
background: var(--accent-cyan);
color: var(--bg-primary);
border-radius: 4px;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
margin-left: 10px;
}
.active-mode-indicator .pulse-dot {
width: 6px;
height: 6px;
background: var(--bg-primary);
border-radius: 50%;
animation: pulse-glow 2s infinite;
}
.help-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 20px;
width: 32px;
height: 32px;
border-radius: 50%;
background: var(--bg-primary);
border: 1px solid var(--border-color);
color: var(--text-secondary);
font-size: 16px;
font-weight: bold;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
}
.help-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
background: var(--bg-secondary);
}
#depsBtn {
right: 60px;
}
.theme-toggle {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 100px;
width: 32px;
height: 32px;
border-radius: 50%;
background: var(--bg-primary);
border: 1px solid var(--border-color);
color: var(--text-secondary);
font-size: 16px;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
}
.theme-toggle:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
background: var(--bg-secondary);
}
.theme-toggle .icon-sun,
.theme-toggle .icon-moon {
position: absolute;
transition: opacity 0.2s, transform 0.2s;
}
.theme-toggle .icon-sun {
opacity: 0;
transform: rotate(-90deg);
}
.theme-toggle .icon-moon {
opacity: 1;
transform: rotate(0deg);
}
[data-theme="light"] .theme-toggle .icon-sun {
opacity: 1;
transform: rotate(0deg);
}
[data-theme="light"] .theme-toggle .icon-moon {
opacity: 0;
transform: rotate(90deg);
}
.help-modal {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.85);
z-index: 10000;
overflow-y: auto;
padding: 40px 20px;
}
.help-modal.active {
display: block;
}
.help-content {
max-width: 800px;
margin: 0 auto;
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 30px;
position: relative;
}
.help-content h2 {
color: var(--accent-cyan);
margin-bottom: 20px;
font-size: 24px;
letter-spacing: 2px;
}
.help-content h3 {
color: var(--text-primary);
margin: 25px 0 15px 0;
font-size: 14px;
text-transform: uppercase;
letter-spacing: 1px;
border-bottom: 1px solid var(--border-color);
padding-bottom: 8px;
}
.help-close {
position: absolute;
top: 15px;
right: 15px;
background: none;
border: none;
color: var(--text-dim);
font-size: 24px;
cursor: pointer;
transition: color 0.2s;
}
.help-close:hover {
color: var(--accent-red);
}
.icon-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 12px;
margin: 15px 0;
}
.icon-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 4px;
font-size: 12px;
}
.icon-item .icon {
font-size: 18px;
width: 30px;
text-align: center;
}
.icon-item .desc {
color: var(--text-secondary);
}
.tip-list {
list-style: none;
padding: 0;
margin: 15px 0;
}
.tip-list li {
padding: 8px 0;
padding-left: 20px;
position: relative;
color: var(--text-secondary);
font-size: 13px;
border-bottom: 1px solid var(--border-color);
}
.tip-list li:last-child {
border-bottom: none;
}
.tip-list li::before {
content: '';
position: absolute;
left: 0;
color: var(--accent-cyan);
font-weight: bold;
}
.help-tabs {
display: flex;
gap: 0;
margin-bottom: 20px;
border: 1px solid var(--border-color);
border-radius: 4px;
overflow: hidden;
}
.help-tab {
flex: 1;
padding: 10px;
background: var(--bg-primary);
border: none;
color: var(--text-secondary);
cursor: pointer;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 1px;
transition: all 0.15s ease;
position: relative;
}
.help-tab:not(:last-child) {
border-right: 1px solid var(--border-color);
}
.help-tab:hover {
background: var(--bg-tertiary);
color: var(--text-primary);
}
.help-tab.active {
background: var(--bg-tertiary);
color: var(--accent-cyan);
}
.help-tab.active::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2px;
background: var(--accent-cyan);
}
.help-section {
display: none;
}
.help-section.active {
display: block;
}
.main-content {
display: flex;
flex-direction: column;
gap: 0;
height: calc(100dvh - 96px);
height: calc(100vh - 96px); /* Fallback */
overflow: hidden;
}
@media (min-width: 1024px) {
.main-content {
display: grid;
grid-template-columns: 320px 1fr;
height: calc(100dvh - 96px);
height: calc(100vh - 96px); /* Fallback */
}
}
.sidebar {
background: var(--bg-secondary);
border-right: 1px solid var(--border-color);
padding: 12px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 8px;
}
/* Mobile: Sidebar is controlled by mobile-drawer class from responsive.css */
@media (max-width: 1023px) {
.sidebar:not(.open) {
/* Hidden by mobile-drawer transform, but ensure no layout impact */
}
}
.sidebar::before {
display: none;
}
.section {
background: var(--bg-tertiary);
border: 1px solid var(--border-color);
border-radius: 6px;
overflow: hidden;
padding: 12px;
position: relative;
}
.section h3 {
color: var(--text-primary);
margin: -12px -12px 12px -12px;
padding: 10px 12px;
background: var(--bg-secondary);
border-bottom: 1px solid var(--border-color);
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
user-select: none;
}
.section h3::before {
content: '';
width: 3px;
height: 12px;
background: var(--accent-cyan);
border-radius: 2px;
flex-shrink: 0;
}
.section h3::after {
content: '▾';
font-size: 10px;
color: var(--text-secondary);
transition: transform 0.2s ease, color 0.2s ease;
margin-left: auto;
padding: 2px 6px;
background: var(--bg-primary);
border-radius: 3px;
}
.section.collapsed h3 {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 10px;
}
.section.collapsed h3::after {
content: '▸';
color: var(--accent-cyan);
}
.section.collapsed {
padding-bottom: 0;
}
.section.collapsed>*:not(h3) {
display: none !important;
}
.section h3:hover {
background: var(--bg-elevated);
}
.section h3:hover::before {
background: var(--accent-amber);
}
.form-group {
margin-bottom: 10px;
}
.form-group:last-child {
margin-bottom: 0;
}
.form-group label {
display: block;
margin-bottom: 4px;
color: var(--text-secondary);
font-size: 10px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.form-group label.inline-checkbox {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
margin-bottom: 0;
text-transform: none;
font-size: 11px;
}
.form-group label.inline-checkbox input[type="checkbox"] {
width: auto;
margin: 0;
accent-color: var(--accent-cyan);
}
.form-group input,
.form-group select {
width: 100%;
padding: 8px 10px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 4px;
color: var(--text-primary);
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
transition: all 0.15s ease;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: var(--accent-cyan);
box-shadow: 0 0 0 2px var(--accent-cyan-dim);
}
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.checkbox-group label {
display: flex;
align-items: center;
gap: 6px;
color: var(--text-secondary);
font-size: 11px;
cursor: pointer;
padding: 6px 10px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 4px;
transition: all 0.15s ease;
}
.checkbox-group label:hover {
border-color: var(--border-light);
background: var(--bg-secondary);
}
.checkbox-group input[type="checkbox"] {
width: auto;
accent-color: var(--accent-cyan);
}
.preset-buttons {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.preset-btn {
padding: 6px 12px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
color: var(--text-secondary);
cursor: pointer;
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.05em;
transition: all 0.15s ease;
border-radius: 4px;
}
.preset-btn:hover {
background: var(--bg-secondary);
color: var(--accent-cyan);
border-color: var(--accent-cyan);
}
.run-btn {
width: 100%;
padding: 12px;
background: var(--accent-green);
border: none;
color: #fff;
font-family: 'Inter', sans-serif;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
cursor: pointer;
transition: all 0.2s ease;
margin-top: 8px;
border-radius: 4px;
}
.run-btn::before {
display: none;
}
.run-btn:hover {
background: #1db954;
box-shadow: 0 4px 12px rgba(34, 197, 94, 0.3);
transform: translateY(-1px);
}
.run-btn:active {
transform: translateY(0);
}
.run-btn.active,
.stop-btn {
background: var(--accent-red);
color: #fff;
}
.stop-btn {
width: 100%;
padding: 12px;
background: var(--accent-red);
border: none;
color: #fff;
font-family: 'Inter', sans-serif;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
cursor: pointer;
transition: all 0.2s ease;
margin-top: 8px;
border-radius: 4px;
}
.stop-btn:hover {
background: #dc2626;
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
}
.output-panel {
background: var(--bg-primary);
display: flex;
flex-direction: column;
position: relative;
overflow-y: auto;
overflow-x: hidden;
min-height: 0; /* Allow shrinking in grid context for proper scrolling */
}
.output-panel::before {
display: none;
}
.output-header {
padding: 10px 16px;
background: var(--bg-secondary);
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--border-color);
}
.output-header h3 {
color: var(--text-primary);
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
display: flex;
align-items: center;
gap: 8px;
}
.output-header h3::before {
content: '';
width: 6px;
height: 6px;
background: var(--accent-cyan);
border-radius: 50%;
}
.stats {
display: flex;
gap: 8px;
font-size: 10px;
color: var(--text-secondary);
font-family: 'JetBrains Mono', monospace;
}
.stats>div {
display: flex;
align-items: center;
gap: 4px;
padding: 4px 8px;
background: var(--bg-tertiary);
border: 1px solid var(--border-color);
border-radius: 4px;
}
.stats>div:hover {
border-color: var(--border-light);
}
.stats span {
color: var(--accent-cyan);
font-weight: 600;
}
.output-content {
flex: 1;
padding: 10px;
overflow-y: auto;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
background: var(--bg-primary);
min-height: 400px;
max-height: 600px;
}
.output-content::-webkit-scrollbar {
width: 8px;
}
.output-content::-webkit-scrollbar-track {
background: var(--bg-secondary);
}
.output-content::-webkit-scrollbar-thumb {
background: var(--border-light);
border-radius: 4px;
}
.output-content::-webkit-scrollbar-thumb:hover {
background: var(--text-dim);
}
.message {
padding: 12px;
margin-bottom: 8px;
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-cyan);
background: var(--bg-secondary);
border-radius: 4px;
position: relative;
transition: all 0.15s ease;
}
.message:hover {
background: var(--bg-tertiary);
border-color: var(--border-light);
}
.message.pocsag {
border-left-color: var(--accent-cyan);
}
.message.flex {
border-left-color: var(--accent-amber);
}
.message .header {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
font-size: 10px;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 1px;
}
.message .protocol {
color: var(--accent-cyan);
font-weight: 600;
}
.message.pocsag .protocol {
color: var(--accent-cyan);
}
.message.flex .protocol {
color: var(--accent-orange);
}
.message .address {
color: var(--accent-green);
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
margin-bottom: 8px;
}
.message .content {
color: var(--text-primary);
word-wrap: break-word;
font-size: 13px;
line-height: 1.5;
}
.message .content.numeric {
font-family: 'JetBrains Mono', monospace;
font-size: 15px;
letter-spacing: 2px;
color: var(--accent-cyan);
}
.status-bar {
padding: 12px 20px;
background: linear-gradient(180deg, var(--bg-secondary) 0%, var(--bg-primary) 100%);
border-top: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
align-items: center;
font-size: 11px;
gap: 15px;
flex-wrap: wrap;
}
.status-indicator {
display: flex;
align-items: center;
gap: 10px;
text-transform: uppercase;
letter-spacing: 2px;
padding: 6px 12px;
background: rgba(0, 0, 0, 0.3);
border-radius: 4px;
border: 1px solid var(--border-color);
}
.status-controls {
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.control-group {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
background: rgba(0, 0, 0, 0.2);
border-radius: 4px;
border: 1px solid var(--border-color);
}
.control-group-label {
font-size: 9px;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 1px;
margin-right: 4px;
}
.status-dot {
width: 8px;
height: 8px;
background: var(--text-dim);
position: relative;
}
.status-dot.running {
background: var(--accent-green);
box-shadow: 0 0 10px var(--accent-green);
animation: pulse-glow 2s infinite;
}
@keyframes pulse-glow {
0%,
100% {
opacity: 1;
box-shadow: 0 0 10px var(--accent-green);
}
50% {
opacity: 0.7;
box-shadow: 0 0 20px var(--accent-green), 0 0 30px var(--accent-green);
}
}
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.3;
}
}
.clear-btn {
padding: 8px 16px;
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-secondary);
cursor: pointer;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 2px;
transition: all 0.2s ease;
}
.clear-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
.tool-status {
font-size: 10px;
padding: 4px 10px;
margin-left: 8px;
text-transform: uppercase;
letter-spacing: 1px;
font-weight: 600;
}
.tool-status.ok {
background: transparent;
border: 1px solid var(--accent-green);
color: var(--accent-green);
}
.tool-status.missing {
background: transparent;
border: 1px solid var(--accent-red);
color: var(--accent-red);
}
.info-text {
font-size: 10px;
color: var(--text-dim);
margin-top: 8px;
text-transform: uppercase;
letter-spacing: 1px;
}
.header-controls {
display: flex;
align-items: center;
gap: 20px;
}
.signal-meter {
display: flex;
align-items: flex-end;
gap: 2px;
height: 20px;
padding: 0 10px;
}
.signal-bar {
width: 4px;
background: var(--border-color);
transition: all 0.1s ease;
}
.signal-bar:nth-child(1) {
height: 4px;
}
.signal-bar:nth-child(2) {
height: 8px;
}
.signal-bar:nth-child(3) {
height: 12px;
}
.signal-bar:nth-child(4) {
height: 16px;
}
.signal-bar:nth-child(5) {
height: 20px;
}
.signal-bar.active {
background: var(--accent-cyan);
}
/* Waterfall canvases (inside collapsible panels) */
#waterfallCanvas,
#sensorWaterfallCanvas {
width: 100%;
height: 30px;
background: var(--bg-primary);
border: none;
display: block;
}
#waterfallCanvas.active,
#sensorWaterfallCanvas.active {
border-color: var(--accent-cyan);
}
.status-controls {
display: flex;
gap: 8px;
align-items: center;
}
.control-btn {
padding: 6px 12px;
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-secondary);
cursor: pointer;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 1px;
transition: all 0.2s ease;
font-family: 'Inter', sans-serif;
}
.control-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
.control-btn.active {
border-color: var(--accent-green);
color: var(--accent-green);
}
.control-btn.muted {
border-color: var(--accent-red);
color: var(--accent-red);
}
#adsbStatsChart {
width: 100%;
height: 80px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 3px;
}
/* Network Relationship Graph */
.network-graph-container {
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 12px;
margin-top: 10px;
}
.network-graph-container h4 {
color: var(--accent-cyan);
font-size: 11px;
text-transform: uppercase;
letter-spacing: 1px;
margin: 0 0 10px 0;
}
#networkGraph {
width: 100%;
height: 200px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 3px;
}
.network-graph-legend {
display: flex;
gap: 15px;
margin-top: 8px;
font-size: 10px;
}
.legend-item {
display: flex;
align-items: center;
gap: 5px;
color: var(--text-secondary);
}
.legend-dot {
width: 10px;
height: 10px;
border-radius: 50%;
}
.legend-dot.ap {
background: var(--accent-cyan);
}
.legend-dot.client {
background: var(--accent-green);
}
.legend-dot.drone {
background: var(--accent-orange);
}
/* Spectrum Waterfall */
.spectrum-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.spectrum-header h5 {
margin: 0;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1px;
}
.spectrum-info {
display: flex;
gap: 15px;
font-size: 11px;
}
.spectrum-info span:last-child {
font-weight: bold;
}
/* Removed - now using sensor-waterfall-panel structure for waterfalls */
/* Waterfall Panel (used for both pager and 433MHz modes) */
.sensor-waterfall-panel {
margin: 0 15px 10px 15px;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 4px;
overflow: hidden;
}
.sensor-waterfall-header {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
background: var(--bg-tertiary);
border-bottom: 1px solid var(--border-color);
font-size: 11px;
font-weight: 600;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
user-select: none;
}
.sensor-waterfall-header:hover {
background: var(--bg-hover);
}
.sensor-waterfall-content {
background: #000;
transition: max-height 0.3s ease, padding 0.3s ease;
max-height: 50px;
overflow: hidden;
}
.sensor-waterfall-panel.collapsed .sensor-waterfall-content {
max-height: 0;
padding: 0;
}
.sensor-waterfall-panel.collapsed .sensor-waterfall-header {
border-bottom: none;
}
/* Removed duplicate - consolidated above */
.waterfall-scale {
display: flex;
justify-content: space-between;
padding: 4px 8px;
font-size: 9px;
color: var(--text-dim);
background: rgba(0, 0, 0, 0.5);
}
.spectrum-legend {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
margin-top: 8px;
font-size: 10px;
color: var(--text-dim);
}
.spectrum-gradient {
width: 150px;
height: 12px;
background: linear-gradient(to right,
#000080, #0000ff, #00ffff, #00ff00, #ffff00, #ff0000, #ffffff);
border-radius: 2px;
}
#spectrumLineChart {
width: 100%;
height: 100px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 3px;
}
/* Audio Receiver Controls */
.status-line {
display: flex;
justify-content: space-between;
font-size: 12px;
padding: 4px 0;
border-bottom: 1px solid var(--border-color);
}
.status-line:last-of-type {
border-bottom: none;
}
#audioStartBtn.active {
background: var(--accent-green);
border-color: var(--accent-green);
color: var(--bg-primary);
}
#waterfallCanvas {
cursor: crosshair;
}
/* Channel Recommendation */
.channel-recommendation {
background: var(--bg-card);
border: 1px solid var(--accent-green);
border-radius: 4px;
padding: 10px;
margin-top: 10px;
}
.channel-recommendation h4 {
color: var(--accent-green);
font-size: 11px;
text-transform: uppercase;
letter-spacing: 1px;
margin: 0 0 8px 0;
}
.channel-recommendation .rec-text {
font-size: 12px;
color: var(--text-secondary);
}
.channel-recommendation .rec-channel {
font-size: 18px;
font-weight: bold;
color: var(--accent-green);
}
/* Device Correlation */
.correlation-badge {
display: inline-block;
padding: 2px 6px;
background: var(--accent-orange);
color: var(--bg-primary);
font-size: 9px;
border-radius: 3px;
margin-left: 5px;
font-weight: bold;
}
/* Hidden SSID reveal */
.hidden-ssid-revealed {
color: var(--accent-orange);
font-style: italic;
}
.mode-content {
display: none;
}
.mode-content.active {
display: block;
}
/* Aircraft (ADS-B) Styles */
.aircraft-card {
padding: 12px;
margin-bottom: 8px;
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-cyan);
background: var(--bg-secondary);
display: grid;
grid-template-columns: auto 1fr auto;
gap: 12px;
align-items: center;
}
.aircraft-icon {
font-size: 28px;
transform: rotate(var(--heading, 0deg));
transition: transform 0.3s ease;
}
.aircraft-info {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 8px;
}
.aircraft-callsign {
color: var(--accent-cyan);
font-weight: 600;
font-size: 14px;
}
.aircraft-data {
font-size: 11px;
color: var(--text-secondary);
}
.aircraft-data span {
color: var(--text-primary);
}
/* Aircraft Map Display - Leaflet */
.aircraft-map-container {
position: relative;
width: 100%;
height: 400px;
background: #0a0a0a;
border: 1px solid var(--accent-cyan);
border-radius: 4px;
overflow: hidden;
box-shadow: 0 0 20px rgba(0, 212, 255, 0.2);
}
#aircraftMap {
width: 100%;
height: 100%;
background: #0a0a0a;
}
/* Dark theme for Leaflet */
.leaflet-container {
background: #0a0a0a;
font-family: 'JetBrains Mono', monospace;
}
.leaflet-tile-pane,
.leaflet-container .leaflet-tile-pane {
filter: invert(1) hue-rotate(180deg) brightness(0.8) contrast(1.2) !important;
}
.leaflet-control-zoom {
margin-top: 45px !important;
}
.leaflet-control-zoom a {
background: var(--bg-card) !important;
color: var(--accent-cyan) !important;
border-color: var(--border-color) !important;
}
.leaflet-control-zoom a:hover {
background: var(--bg-tertiary) !important;
}
.leaflet-control-attribution {
background: rgba(0, 0, 0, 0.7) !important;
color: #666 !important;
font-size: 9px !important;
}
.leaflet-control-attribution a {
color: #888 !important;
}
.map-header {
position: absolute;
top: 8px;
left: 10px;
right: 10px;
display: flex;
justify-content: space-between;
z-index: 1000;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
color: var(--accent-cyan);
text-shadow: 0 0 5px var(--accent-cyan);
background: rgba(0, 0, 0, 0.6);
padding: 4px 8px;
border-radius: 3px;
}
.map-footer {
position: absolute;
bottom: 8px;
left: 10px;
right: 10px;
display: flex;
justify-content: space-between;
z-index: 1000;
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
color: var(--accent-cyan);
text-shadow: 0 0 5px var(--accent-cyan);
background: rgba(0, 0, 0, 0.6);
padding: 4px 8px;
border-radius: 3px;
}
/* Aircraft marker styles */
.aircraft-marker {
display: flex;
align-items: center;
justify-content: center;
}
.aircraft-marker svg {
filter: drop-shadow(0 0 4px currentColor);
}
.aircraft-popup {
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
}
.aircraft-popup .callsign {
color: var(--accent-cyan);
font-weight: bold;
font-size: 13px;
}
.aircraft-popup .data-row {
display: flex;
justify-content: space-between;
margin: 3px 0;
}
.aircraft-popup .label {
color: #888;
}
.aircraft-popup .value {
color: #fff;
}
.leaflet-popup-content-wrapper {
background: var(--bg-card) !important;
border: 1px solid var(--border-color) !important;
border-radius: 4px !important;
}
.leaflet-popup-tip {
background: var(--bg-card) !important;
border: 1px solid var(--border-color) !important;
}
.leaflet-popup-content {
color: var(--text-primary) !important;
margin: 10px !important;
}
.leaflet-tooltip.aircraft-tooltip {
background: rgba(0, 0, 0, 0.8) !important;
border: 1px solid var(--accent-cyan) !important;
color: var(--accent-cyan) !important;
font-family: 'JetBrains Mono', monospace !important;
font-size: 10px !important;
padding: 2px 6px !important;
border-radius: 2px !important;
}
.leaflet-tooltip.aircraft-tooltip::before {
border-right-color: var(--accent-cyan) !important;
}
/* Satellite Mode Styles */
.satellite-section {
margin-bottom: 20px;
}
.satellite-tabs {
display: flex;
gap: 4px;
margin-bottom: 15px;
}
.satellite-tab {
padding: 8px 16px;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 4px;
color: var(--text-secondary);
cursor: pointer;
font-family: 'Inter', sans-serif;
font-size: 11px;
text-transform: uppercase;
transition: all 0.2s ease;
}
.satellite-tab:hover {
border-color: var(--accent-cyan);
color: var(--text-primary);
}
.satellite-tab.active {
background: var(--accent-cyan);
border-color: var(--accent-cyan);
color: var(--bg-primary);
}
.satellite-content {
display: none;
}
.satellite-content.active {
display: block;
}
/* Satellite Dashboard Embed */
.satellite-dashboard-embed {
width: 100%;
height: calc(100vh - 200px);
min-height: 700px;
max-height: 900px;
background: var(--bg-primary);
border-radius: 8px;
overflow: hidden;
border: 1px solid var(--border-color);
}
.satellite-dashboard-embed iframe {
width: 100%;
height: 100%;
border: none;
background: var(--bg-primary);
}
/* Satellite Pass Predictor - Cool UI */
.pass-predictor {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto auto;
gap: 15px;
}
@media (max-width: 1100px) {
.pass-predictor {
grid-template-columns: 1fr;
}
}
.polar-plot-container {
position: relative;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 15px;
min-height: 320px;
}
.ground-track-cell {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 15px;
min-height: 320px;
display: flex;
flex-direction: column;
}
.ground-track-cell #groundTrackMap {
flex: 1;
min-height: 200px;
}
.countdown-cell {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 15px;
}
.countdown-cell .satellite-countdown {
margin: 0;
padding: 0;
border: none;
background: none;
}
.pass-list-cell {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 15px;
max-height: 350px;
overflow-y: auto;
}
.polar-plot-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.polar-plot-title {
color: var(--accent-cyan);
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1px;
}
.popout-btn {
padding: 4px 10px;
background: transparent;
border: 1px solid var(--accent-cyan);
border-radius: 3px;
color: var(--accent-cyan);
font-size: 10px;
cursor: pointer;
transition: all 0.2s ease;
}
.popout-btn:hover {
background: var(--accent-cyan);
color: var(--bg-primary);
}
.polar-plot {
position: relative;
width: 100%;
padding-bottom: 100%;
}
.polar-plot canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.pass-list-container {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 15px;
max-height: 450px;
overflow-y: auto;
}
.pass-list-header {
color: var(--accent-cyan);
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
/* Satellite Countdown Block */
.satellite-countdown {
background: linear-gradient(135deg, var(--bg-tertiary) 0%, var(--bg-secondary) 100%);
border: 1px solid var(--accent-cyan);
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
box-shadow: 0 0 20px rgba(0, 212, 255, 0.1);
}
.countdown-satellite-name {
color: var(--accent-cyan);
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 2px;
text-align: center;
margin-bottom: 12px;
text-shadow: 0 0 10px var(--accent-cyan-dim);
}
.countdown-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-bottom: 10px;
}
.countdown-block {
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 6px;
padding: 10px;
text-align: center;
}
.countdown-label {
color: var(--text-dim);
font-size: 9px;
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 5px;
}
.countdown-value {
color: var(--accent-cyan);
font-size: 22px;
font-weight: 700;
font-family: 'JetBrains Mono', monospace;
text-shadow: 0 0 15px var(--accent-cyan-dim);
line-height: 1.2;
}
.countdown-value.active {
color: var(--accent-green);
text-shadow: 0 0 15px rgba(0, 255, 136, 0.4);
animation: countdown-pulse 1s ease-in-out infinite;
}
@keyframes countdown-pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.7;
}
}
.countdown-sublabel {
color: var(--text-secondary);
font-size: 9px;
margin-top: 4px;
}
.countdown-status {
text-align: center;
font-size: 10px;
color: var(--text-dim);
padding-top: 8px;
border-top: 1px solid var(--border-color);
}
.countdown-status.visible {
color: var(--accent-green);
}
.countdown-status.upcoming {
color: var(--accent-orange);
}
.location-input {
display: flex;
gap: 8px;
margin-bottom: 15px;
}
.location-input input {
flex: 1;
padding: 8px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 3px;
color: var(--text-primary);
font-size: 12px;
}
.pass-card {
padding: 12px;
margin-bottom: 8px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 4px;
cursor: pointer;
transition: all 0.2s ease;
}
.pass-card:hover {
border-color: var(--accent-cyan);
}
.pass-card.active {
border-color: var(--accent-cyan);
box-shadow: 0 0 10px rgba(0, 255, 255, 0.2);
}
.pass-satellite {
color: var(--accent-cyan);
font-weight: 600;
margin-bottom: 4px;
}
.pass-time {
color: var(--text-primary);
font-size: 13px;
margin-bottom: 4px;
}
.pass-details {
display: flex;
gap: 15px;
font-size: 11px;
color: var(--text-secondary);
}
.pass-details span {
color: var(--text-primary);
}
.pass-quality {
display: inline-block;
padding: 2px 8px;
border-radius: 10px;
font-size: 10px;
font-weight: 600;
}
.pass-quality.excellent {
background: rgba(0, 255, 0, 0.2);
color: var(--accent-green);
}
.pass-quality.good {
background: rgba(0, 255, 255, 0.2);
color: var(--accent-cyan);
}
.pass-quality.fair {
background: rgba(255, 102, 0, 0.2);
color: var(--accent-orange);
}
/* Satellite List Styles */
.satellite-list {
max-height: 200px;
overflow-y: auto;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 8px;
}
.sat-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 8px;
margin-bottom: 4px;
background: var(--bg-secondary);
border-radius: 3px;
font-size: 12px;
}
.sat-item:last-child {
margin-bottom: 0;
}
.sat-item label {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
flex: 1;
}
.sat-item input[type="checkbox"] {
margin: 0;
}
.sat-item .sat-name {
color: var(--text-primary);
}
.sat-item .sat-norad {
color: var(--text-secondary);
font-size: 10px;
}
.sat-item .sat-remove {
background: none;
border: none;
color: var(--accent-red);
cursor: pointer;
font-size: 14px;
padding: 2px 6px;
opacity: 0.6;
}
.sat-item .sat-remove:hover {
opacity: 1;
}
.sat-item.builtin .sat-remove {
display: none;
}
/* Satellite Add Modal */
.sat-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
display: none;
justify-content: center;
align-items: center;
z-index: 10000;
}
.sat-modal.active {
display: flex;
}
.sat-modal-content {
background: var(--bg-secondary);
border: 1px solid var(--accent-cyan);
border-radius: 8px;
padding: 20px;
width: 90%;
max-width: 500px;
max-height: 80vh;
overflow-y: auto;
}
.sat-modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid var(--border-color);
}
.sat-modal-header h3 {
color: var(--accent-cyan);
margin: 0;
}
.sat-modal-close {
background: none;
border: none;
color: var(--text-secondary);
font-size: 24px;
cursor: pointer;
}
.sat-modal-close:hover {
color: var(--text-primary);
}
.sat-modal-tabs {
display: flex;
gap: 10px;
margin-bottom: 15px;
}
.sat-modal-tab {
flex: 1;
padding: 8px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 4px;
color: var(--text-secondary);
cursor: pointer;
font-size: 12px;
}
.sat-modal-tab.active {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
.sat-modal-section {
display: none;
}
.sat-modal-section.active {
display: block;
}
.tle-textarea {
width: 100%;
height: 120px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 4px;
color: var(--text-primary);
font-family: monospace;
font-size: 11px;
padding: 10px;
resize: vertical;
}
.celestrak-categories {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
max-height: 200px;
overflow-y: auto;
}
.celestrak-cat {
padding: 8px 12px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 4px;
color: var(--text-secondary);
cursor: pointer;
font-size: 11px;
text-align: center;
}
.celestrak-cat:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
/* Popout window styles */
.popout-container {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: var(--bg-primary);
z-index: 10000;
display: none;
}
.popout-container.active {
display: block;
}
.popout-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
background: var(--bg-secondary);
border-bottom: 1px solid var(--border-color);
}
.popout-title {
color: var(--accent-cyan);
font-size: 18px;
font-weight: 600;
}
.popout-close {
padding: 8px 16px;
background: transparent;
border: 1px solid var(--accent-red);
border-radius: 3px;
color: var(--accent-red);
cursor: pointer;
}
.popout-body {
padding: 20px;
height: calc(100vh - 70px);
overflow: auto;
}
/* Sensor card styling */
.sensor-card {
padding: 15px;
margin-bottom: 10px;
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-green);
background: var(--bg-secondary);
}
.sensor-card .device-name {
color: var(--accent-green);
font-weight: 600;
font-size: 13px;
margin-bottom: 8px;
}
.sensor-card .sensor-data {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 8px;
}
.sensor-card .data-item {
background: var(--bg-primary);
padding: 8px 10px;
border: 1px solid var(--border-color);
}
.sensor-card .data-label {
font-size: 9px;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 1px;
}
.sensor-card .data-value {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
color: var(--accent-cyan);
}
/* Recon Dashboard - Prominent Device Intelligence */
.recon-panel {
background: var(--bg-card);
border: 1px solid var(--border-color);
margin: 15px;
margin-bottom: 10px;
position: relative;
}
.recon-panel::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(90deg, var(--accent-orange), var(--accent-cyan), transparent);
}
.recon-panel.collapsed .recon-content {
display: none;
}
.recon-header {
padding: 12px 15px;
background: var(--bg-secondary);
border-bottom: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
align-items: center;
}
.recon-header h4 {
color: var(--accent-orange);
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 2px;
margin: 0;
}
.recon-stats {
display: flex;
gap: 15px;
font-size: 10px;
font-family: 'JetBrains Mono', monospace;
}
.recon-stats span {
color: var(--accent-cyan);
}
.recon-content {
max-height: 300px;
overflow-y: auto;
}
.device-row {
display: grid;
grid-template-columns: 1fr auto auto auto;
gap: 10px;
padding: 10px 15px;
border-bottom: 1px solid var(--border-color);
font-size: 11px;
align-items: center;
transition: background 0.2s ease;
}
.device-row:hover {
background: var(--bg-secondary);
}
.device-row.anomaly {
border-left: 3px solid var(--accent-red);
background: rgba(255, 51, 102, 0.05);
}
.device-row.new-device {
border-left: 3px solid var(--accent-green);
background: rgba(0, 255, 136, 0.05);
}
.device-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.device-name-row {
color: var(--text-primary);
font-weight: 500;
}
.device-id {
color: var(--text-dim);
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
}
.device-meta {
text-align: right;
color: var(--text-secondary);
font-family: 'JetBrains Mono', monospace;
}
.device-meta.encrypted {
color: var(--accent-green);
}
.device-meta.plaintext {
color: var(--accent-red);
}
.transmission-bar {
width: 60px;
height: 4px;
background: var(--border-color);
position: relative;
}
.transmission-bar-fill {
height: 100%;
background: var(--accent-cyan);
transition: width 0.3s ease;
}
.badge {
display: inline-block;
padding: 2px 6px;
font-size: 9px;
text-transform: uppercase;
letter-spacing: 1px;
border: 1px solid;
}
.badge.proto-pocsag {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
.badge.proto-flex {
border-color: var(--accent-orange);
color: var(--accent-orange);
}
.badge.proto-433 {
border-color: var(--accent-green);
color: var(--accent-green);
}
.badge.proto-unknown {
border-color: var(--text-dim);
color: var(--text-dim);
}
.recon-toggle {
padding: 4px 8px;
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-secondary);
cursor: pointer;
font-size: 9px;
text-transform: uppercase;
letter-spacing: 1px;
}
.recon-toggle:hover {
border-color: var(--accent-orange);
color: var(--accent-orange);
}
.recon-toggle.active {
border-color: var(--accent-orange);
color: var(--accent-orange);
background: rgba(255, 136, 0, 0.1);
}
.hex-dump {
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
color: var(--text-dim);
background: var(--bg-primary);
padding: 8px;
margin-top: 8px;
border: 1px solid var(--border-color);
word-break: break-all;
}
.timeline-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--accent-cyan);
display: inline-block;
margin-right: 5px;
}
.timeline-dot.recent {
background: var(--accent-green);
}
.timeline-dot.stale {
background: var(--accent-orange);
}
.timeline-dot.old {
background: var(--text-dim);
}
/* WiFi Layout Container - side by side layout */
.wifi-layout-container {
display: flex;
gap: 15px;
padding: 15px;
background: var(--bg-secondary);
margin: 0 15px 10px 15px;
border: 1px solid var(--border-color);
height: calc(100vh - 200px); /* Take most of the available height */
min-height: 400px;
}
/* WiFi Visualizations */
.wifi-visuals {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
flex: 1;
overflow-y: auto;
padding-right: 10px;
}
/* WiFi Device List (right column) */
.wifi-device-list {
width: 350px;
min-width: 300px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 4px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.wifi-device-list-header {
padding: 10px 12px;
background: var(--bg-tertiary);
border-bottom: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
align-items: center;
}
.wifi-device-list-header h5 {
margin: 0;
color: var(--accent-cyan);
font-size: 12px;
}
.wifi-device-list-header .device-count {
color: var(--text-dim);
font-size: 11px;
}
.wifi-device-list-content {
flex: 1;
overflow-y: auto;
padding: 10px;
}
/* WiFi network cards in device list - more compact */
.wifi-network-card {
margin-bottom: 8px;
padding: 10px !important;
}
.wifi-network-card .header {
font-size: 12px;
}
/* WiFi client cards in device list */
.wifi-client-card {
margin-bottom: 8px;
padding: 10px !important;
border-left-color: var(--accent-purple) !important;
background: rgba(153, 51, 255, 0.05);
}
.wifi-client-card .header {
font-size: 12px;
}
.wifi-client-card .sensor-data {
font-size: 10px;
}
.wifi-network-card .sensor-data {
font-size: 10px;
}
.wifi-network-card .preset-btn {
font-size: 9px !important;
padding: 3px 6px !important;
}
@media (max-width: 1200px) {
.wifi-layout-container {
flex-direction: column;
height: auto;
max-height: calc(100vh - 200px);
}
.wifi-visuals {
grid-template-columns: 1fr;
max-height: 50vh;
}
.wifi-device-list {
width: 100%;
min-width: auto;
max-height: 300px;
}
}
/* Bluetooth Layout Container */
.bt-layout-container {
display: flex;
gap: 15px;
padding: 15px;
background: var(--bg-secondary);
margin: 0 15px 10px 15px;
border: 1px solid var(--border-color);
height: calc(100vh - 200px);
min-height: 400px;
}
.bt-layout-container .wifi-visuals {
flex: 1;
}
.bt-device-list {
border-left-color: var(--accent-purple) !important;
}
.bt-device-list .wifi-device-list-header h5 {
color: var(--accent-purple);
}
/* Bluetooth Device Type Overview */
.bt-type-overview {
display: flex;
flex-direction: column;
gap: 6px;
font-size: 11px;
}
.bt-type-item {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 8px;
background: rgba(0,0,0,0.2);
border-radius: 3px;
}
.bt-type-icon {
font-size: 14px;
}
/* Bluetooth Signal Distribution */
.bt-signal-dist {
display: flex;
flex-direction: column;
gap: 8px;
font-size: 10px;
}
.signal-range {
display: flex;
align-items: center;
gap: 8px;
}
.signal-range span:first-child {
width: 70px;
color: var(--text-dim);
}
.signal-range span:last-child {
width: 20px;
text-align: right;
}
.signal-bar-bg {
flex: 1;
height: 8px;
background: var(--bg-tertiary);
border-radius: 4px;
overflow: hidden;
}
.signal-bar {
height: 100%;
border-radius: 4px;
transition: width 0.3s ease;
}
.signal-bar.strong {
background: var(--accent-green);
}
.signal-bar.medium {
background: var(--accent-orange);
}
.signal-bar.weak {
background: var(--accent-red);
}
/* Bluetooth Device Cards */
.bt-device-card {
margin-bottom: 8px;
padding: 10px !important;
border-left-color: var(--accent-purple) !important;
}
.bt-device-card .header {
font-size: 12px;
}
.bt-device-card .sensor-data {
font-size: 10px;
}
.bt-device-card.tracker {
border-left-color: var(--accent-orange) !important;
background: rgba(255, 165, 0, 0.05);
}
.bt-device-card.findmy {
border-left-color: #007aff !important;
background: rgba(0, 122, 255, 0.05);
}
@media (max-width: 1200px) {
.bt-layout-container {
flex-direction: column;
height: auto;
max-height: calc(100vh - 200px);
}
.bt-layout-container .wifi-visuals {
max-height: 50vh;
}
.bt-device-list {
width: 100%;
min-width: auto;
max-height: 300px;
}
}
.wifi-visual-panel {
background: var(--bg-primary);
border: 1px solid var(--border-color);
padding: 10px;
position: relative;
}
.wifi-visual-panel h5 {
color: var(--accent-cyan);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid var(--border-color);
}
/* Radar Display */
.radar-container {
position: relative;
width: 150px;
height: 150px;
margin: 0 auto;
}
#radarCanvas,
#btRadarCanvas {
width: 100%;
height: 100%;
border-radius: 50%;
background: radial-gradient(circle, #001515 0%, #000a0a 100%);
border: 1px solid var(--accent-cyan-dim);
}
#btRadarCanvas {
background: radial-gradient(circle, #150015 0%, #0a000a 100%);
border: 1px solid rgba(138, 43, 226, 0.3);
}
/* Channel Graph */
.channel-graph {
display: flex;
align-items: flex-end;
justify-content: space-around;
height: 60px;
padding: 5px 0;
border-bottom: 1px solid var(--border-color);
}
.channel-bar-wrapper {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.channel-bar {
width: 80%;
background: var(--border-color);
min-height: 2px;
transition: height 0.3s ease, background 0.3s ease;
}
.channel-bar.active {
background: var(--accent-cyan);
box-shadow: 0 0 5px var(--accent-cyan);
}
.channel-bar.congested {
background: var(--accent-orange);
}
.channel-bar.very-congested {
background: var(--accent-red);
}
.channel-label {
font-size: 8px;
color: #fff;
margin-top: 3px;
}
/* Security Donut */
.security-container {
display: flex;
align-items: center;
gap: 15px;
}
.security-donut {
width: 80px;
height: 80px;
flex-shrink: 0;
}
#securityCanvas {
width: 100%;
height: 100%;
}
.security-legend {
display: flex;
flex-direction: column;
gap: 4px;
font-size: 10px;
font-family: 'JetBrains Mono', monospace;
}
.security-legend-item {
display: flex;
align-items: center;
gap: 6px;
}
.security-legend-dot {
width: 10px;
height: 10px;
border-radius: 2px;
}
.security-legend-dot.wpa3 {
background: var(--accent-green);
}
.security-legend-dot.wpa2 {
background: var(--accent-orange);
}
.security-legend-dot.wep {
background: var(--accent-red);
}
.security-legend-dot.open {
background: var(--accent-cyan);
}
/* Signal Strength Meter */
.signal-strength-display {
text-align: center;
padding: 5px;
}
.target-ssid {
font-size: 11px;
color: var(--text-secondary);
margin-bottom: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.signal-value {
font-family: 'JetBrains Mono', monospace;
font-size: 28px;
color: var(--accent-cyan);
text-shadow: 0 0 10px var(--accent-cyan-dim);
}
.signal-value.weak {
color: var(--accent-red);
text-shadow: 0 0 10px rgba(255, 51, 102, 0.4);
}
.signal-value.medium {
color: var(--accent-orange);
text-shadow: 0 0 10px rgba(255, 136, 0, 0.4);
}
.signal-value.strong {
color: var(--accent-green);
text-shadow: 0 0 10px rgba(0, 255, 136, 0.4);
}
.signal-bars-large {
display: flex;
justify-content: center;
align-items: flex-end;
gap: 3px;
height: 30px;
margin-top: 8px;
}
.signal-bar-large {
width: 8px;
background: var(--border-color);
transition: all 0.2s ease;
}
.signal-bar-large.active {
box-shadow: 0 0 5px currentColor;
}
.signal-bar-large.weak {
background: var(--accent-red);
}
.signal-bar-large.medium {
background: var(--accent-orange);
}
.signal-bar-large.strong {
background: var(--accent-green);
}
.signal-bar-large:nth-child(1) {
height: 20%;
}
.signal-bar-large:nth-child(2) {
height: 40%;
}
.signal-bar-large:nth-child(3) {
height: 60%;
}
.signal-bar-large:nth-child(4) {
height: 80%;
}
.signal-bar-large:nth-child(5) {
height: 100%;
}
/* Scanline effect overlay */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
background: repeating-linear-gradient(0deg,
rgba(0, 0, 0, 0.03),
rgba(0, 0, 0, 0.03) 1px,
transparent 1px,
transparent 2px);
z-index: 1000;
}
/* Disclaimer Modal */
.disclaimer-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.95);
z-index: 99999;
display: flex;
align-items: center;
justify-content: center;
pointer-events: auto;
}
.disclaimer-modal {
background: var(--bg-card);
border: 1px solid var(--accent-cyan);
max-width: 550px;
padding: 30px;
text-align: center;
box-shadow: 0 0 50px rgba(0, 212, 255, 0.3);
pointer-events: auto;
position: relative;
z-index: 100000;
}
.disclaimer-modal h2 {
color: var(--accent-red);
font-size: 1.5em;
margin-bottom: 20px;
letter-spacing: 3px;
}
.disclaimer-modal .warning-icon {
font-size: 48px;
margin-bottom: 15px;
}
.disclaimer-modal p {
color: var(--text-secondary);
font-size: 13px;
line-height: 1.8;
margin-bottom: 15px;
text-align: left;
}
.disclaimer-modal ul {
text-align: left;
color: var(--text-secondary);
font-size: 12px;
margin: 15px 0;
padding-left: 20px;
}
.disclaimer-modal ul li {
margin-bottom: 8px;
}
.disclaimer-modal .accept-btn {
background: var(--accent-cyan);
color: #000;
border: none;
padding: 12px 40px;
font-family: 'Inter', sans-serif;
font-size: 14px;
font-weight: 600;
letter-spacing: 2px;
cursor: pointer;
margin-top: 20px;
transition: all 0.3s ease;
pointer-events: auto;
position: relative;
z-index: 100001;
}
.disclaimer-modal .accept-btn:hover {
background: #fff;
box-shadow: 0 0 20px rgba(0, 212, 255, 0.5);
}
.disclaimer-hidden {
display: none !important;
}
/* Ground Track Map */
#groundTrackMap {
height: 240px;
border-radius: 6px;
margin-top: 10px;
}
.ground-track-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 5px;
}
.ground-track-title {
font-size: 14px;
font-weight: 600;
color: var(--accent-cyan);
}
.sat-position-indicator {
position: absolute;
width: 12px;
height: 12px;
background: #ff0;
border: 2px solid #000;
border-radius: 50%;
transform: translate(-50%, -50%);
z-index: 100;
animation: pulse-sat 1s infinite;
}
@keyframes pulse-sat {
0%,
100% {
box-shadow: 0 0 0 0 rgba(255, 255, 0, 0.7);
}
50% {
box-shadow: 0 0 0 8px rgba(255, 255, 0, 0);
}
}
/* Beacon Flood Alert */
.beacon-flood-alert {
background: linear-gradient(135deg, rgba(255, 0, 0, 0.2), rgba(255, 100, 0, 0.2));
border: 1px solid #ff4444;
border-radius: 6px;
padding: 10px;
margin: 10px 0;
animation: beacon-flash 0.5s infinite alternate;
}
@keyframes beacon-flash {
from {
opacity: 0.8;
}
to {
opacity: 1;
}
}
/* WPS Indicator */
.wps-enabled {
background: #ff6600;
color: #000;
padding: 2px 6px;
border-radius: 3px;
font-size: 9px;
}
/* Rogue AP Indicator */
.rogue-indicator {
background: linear-gradient(90deg, #ff0000, #cc0000);
color: #fff;
padding: 4px 8px;
margin: -10px -10px 8px -10px;
font-size: 10px;
font-weight: bold;
text-align: center;
text-transform: uppercase;
letter-spacing: 1px;
animation: rogue-pulse 1.5s infinite;
}
@keyframes rogue-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
/* PMKID Capture */
.pmkid-btn {
background: linear-gradient(135deg, #9933ff, #6600cc);
color: #fff;
}
.pmkid-btn:hover {
background: linear-gradient(135deg, #aa44ff, #7700dd);
}
/* Find My Detection */
.findmy-device {
border-left: 3px solid #007aff;
background: rgba(0, 122, 255, 0.1);
}
.findmy-badge {
background: linear-gradient(135deg, #007aff, #5856d6);
color: #fff;
padding: 2px 8px;
border-radius: 10px;
font-size: 10px;
font-weight: bold;
}
/* Tracker Following Alert */
.tracker-following-alert {
background: linear-gradient(135deg, rgba(255, 0, 0, 0.3), rgba(255, 50, 50, 0.2));
border: 2px solid #ff0000;
border-radius: 8px;
padding: 15px;
margin: 10px 0;
animation: tracker-pulse 1s infinite;
}
@keyframes tracker-pulse {
0%,
100% {
border-color: #ff0000;
}
50% {
border-color: #ff6666;
}
}
.tracker-following-alert h4 {
color: #ff4444;
margin: 0 0 10px 0;
display: flex;
align-items: center;
gap: 8px;
}
/* Flight Path Trails */
.flight-trail {
stroke-dasharray: 5, 5;
fill: none;
}
/* Squawk Alerts */
.squawk-emergency {
background: #ff0000 !important;
animation: squawk-flash 0.3s infinite alternate;
}
.squawk-hijack {
background: #ff0000 !important;
}
.squawk-radio-fail {
background: #ff6600 !important;
}
.squawk-mayday {
background: #ff0000 !important;
}
@keyframes squawk-flash {
from {
opacity: 0.7;
}
to {
opacity: 1;
}
}
.squawk-alert-banner {
position: fixed;
top: 60px;
left: 50%;
transform: translateX(-50%);
background: #ff0000;
color: #fff;
padding: 15px 30px;
border-radius: 8px;
font-weight: bold;
z-index: 9999;
animation: squawk-banner-flash 0.5s infinite alternate;
}
@keyframes squawk-banner-flash {
from {
background: #ff0000;
}
to {
background: #cc0000;
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateX(-50%) translateY(-20px);
}
to {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
/* Military Aircraft */
.military-aircraft {
border-left: 3px solid #556b2f;
background: rgba(85, 107, 47, 0.2);
}
.military-badge {
background: #556b2f;
color: #fff;
padding: 2px 6px;
border-radius: 3px;
font-size: 9px;
font-weight: bold;
}
/* Map Clustering */
.marker-cluster {
background: rgba(0, 212, 255, 0.6);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
color: #000;
border: 2px solid var(--accent-cyan);
}
.marker-cluster-small {
width: 30px;
height: 30px;
font-size: 12px;
}
.marker-cluster-medium {
width: 40px;
height: 40px;
font-size: 14px;
}
.marker-cluster-large {
width: 50px;
height: 50px;
font-size: 16px;
}
/* Audio Visualizer */
.audio-visualizer {
background: rgba(0, 0, 0, 0.3);
border: 1px solid var(--border-color);
border-radius: 6px;
padding: 10px;
}
.signal-meter {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 10px;
}
.signal-meter label {
font-size: 10px;
color: var(--text-secondary);
width: 40px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.meter-bar {
flex: 1;
height: 12px;
background: linear-gradient(90deg,
var(--accent-green) 0%,
var(--accent-green) 60%,
var(--accent-orange) 60%,
var(--accent-orange) 80%,
var(--accent-red) 80%,
var(--accent-red) 100%
);
border-radius: 3px;
position: relative;
overflow: hidden;
opacity: 0.3;
}
.meter-fill {
position: absolute;
top: 0;
left: 0;
height: 100%;
background: linear-gradient(90deg,
var(--accent-green) 0%,
var(--accent-green) 60%,
var(--accent-orange) 60%,
var(--accent-orange) 80%,
var(--accent-red) 80%,
var(--accent-red) 100%
);
border-radius: 3px;
width: 0%;
transition: width 0.05s ease-out;
}
.meter-peak {
position: absolute;
top: 0;
height: 100%;
width: 2px;
background: #fff;
opacity: 0.8;
transition: left 0.05s ease-out;
left: 0%;
}
.meter-value {
font-size: 10px;
font-family: 'JetBrains Mono', monospace;
color: var(--text-secondary);
width: 50px;
text-align: right;
}
#audioSpectrumCanvas {
width: 100%;
height: 60px;
border-radius: 4px;
background: rgba(0, 0, 0, 0.4);
}
/* Airband visualizer in ADS-B dashboard */
.airband-visualizer {
background: rgba(0, 0, 0, 0.3);
border: 1px solid var(--border-color);
border-radius: 6px;
padding: 8px;
margin-top: 10px;
}
.airband-visualizer .signal-meter {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
}
.airband-visualizer .signal-meter label {
font-size: 9px;
color: var(--text-secondary);
width: 35px;
}
.airband-visualizer .meter-bar {
flex: 1;
height: 10px;
}
.airband-visualizer .meter-value {
font-size: 9px;
width: 45px;
}
.airband-visualizer canvas {
width: 100%;
height: 50px;
border-radius: 3px;
background: rgba(0, 0, 0, 0.4);
}
/* GPS Indicator */
.gps-indicator {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 8px;
background: var(--accent-green-dim);
border: 1px solid var(--accent-green);
border-radius: 12px;
font-size: 10px;
font-weight: 600;
color: var(--accent-green);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.gps-indicator .gps-dot {
width: 6px;
height: 6px;
background: var(--accent-green);
border-radius: 50%;
animation: gps-pulse 2s ease-in-out infinite;
}
@keyframes gps-pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(0.8); }
}
/* ============================================
RADIO CONTROL INTERFACE - Listening Post
Modern tactical radio-inspired UI
============================================ */
/* Radio Panel Container */
.radio-panel {
display: flex;
flex-direction: column;
gap: 20px;
padding: 20px;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 12px;
}
/* Frequency Display Section */
.radio-display-section {
display: flex;
justify-content: center;
padding: 15px 0;
}
.freq-display {
background: rgba(0, 0, 0, 0.8);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 25px 40px;
text-align: center;
box-shadow:
inset 0 0 40px rgba(0, 0, 0, 0.6),
0 0 30px var(--accent-cyan-dim);
position: relative;
overflow: hidden;
}
.freq-display::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg,
transparent 0%,
var(--accent-cyan) 50%,
transparent 100%
);
opacity: 0.5;
}
.freq-status {
font-family: 'Orbitron', monospace;
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 3px;
margin-bottom: 8px;
}
.freq-status.active {
color: var(--accent-cyan);
animation: freq-status-pulse 1.5s ease-in-out infinite;
}
.freq-status.signal {
color: var(--accent-green);
}
@keyframes freq-status-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
.freq-digits {
font-family: 'JetBrains Mono', monospace;
font-size: 56px;
font-weight: 700;
color: var(--accent-cyan);
text-shadow:
0 0 10px var(--accent-cyan),
0 0 25px var(--accent-cyan),
0 0 50px rgba(74, 158, 255, 0.4);
letter-spacing: 2px;
line-height: 1;
}
.freq-digits.signal {
color: var(--accent-green);
text-shadow:
0 0 10px var(--accent-green),
0 0 25px var(--accent-green),
0 0 50px rgba(34, 197, 94, 0.4);
}
.freq-unit {
font-family: 'JetBrains Mono', monospace;
font-size: 20px;
color: var(--text-secondary);
margin-left: 8px;
vertical-align: baseline;
}
.freq-mode-badge {
display: inline-block;
padding: 6px 16px;
background: var(--accent-cyan-dim);
border: 1px solid var(--accent-cyan);
border-radius: 4px;
font-family: 'Orbitron', monospace;
font-size: 12px;
font-weight: 600;
color: var(--accent-cyan);
margin-top: 12px;
letter-spacing: 1px;
}
/* Radio Controls Section */
.radio-controls-section {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 30px;
padding: 20px;
background: var(--bg-primary);
border-radius: 8px;
border: 1px solid var(--border-color);
}
.radio-control-group {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.radio-control-label {
font-family: 'Orbitron', monospace;
font-size: 10px;
font-weight: 600;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 2px;
}
/* Rotary Knob */
.radio-knob {
width: 70px;
height: 70px;
background: linear-gradient(145deg, var(--bg-elevated), var(--bg-primary));
border-radius: 50%;
border: 2px solid var(--border-light);
position: relative;
cursor: grab;
box-shadow:
inset 0 2px 6px rgba(0, 0, 0, 0.4),
0 4px 12px rgba(0, 0, 0, 0.3),
0 0 20px var(--accent-cyan-dim);
transition: box-shadow 0.2s ease;
}
.radio-knob:hover {
box-shadow:
inset 0 2px 6px rgba(0, 0, 0, 0.4),
0 4px 12px rgba(0, 0, 0, 0.3),
0 0 30px var(--accent-cyan-dim);
}
.radio-knob:active {
cursor: grabbing;
}
.radio-knob::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 20px;
height: 20px;
background: radial-gradient(circle, var(--bg-tertiary) 0%, var(--bg-primary) 100%);
border-radius: 50%;
transform: translate(-50%, -50%);
border: 1px solid var(--border-color);
}
.radio-knob::after {
content: '';
position: absolute;
width: 3px;
height: 22px;
background: var(--accent-cyan);
top: 6px;
left: 50%;
transform: translateX(-50%);
border-radius: 2px;
box-shadow: 0 0 8px var(--accent-cyan);
}
.radio-knob.active::after {
background: var(--accent-green);
box-shadow: 0 0 8px var(--accent-green);
}
/* Knob tick marks ring */
.knob-ticks {
position: absolute;
width: 90px;
height: 90px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
pointer-events: none;
}
.knob-tick {
position: absolute;
width: 2px;
height: 6px;
background: var(--border-light);
top: 0;
left: 50%;
transform-origin: center 45px;
}
.knob-tick.major {
height: 8px;
background: var(--text-muted);
}
.knob-label {
font-family: 'Orbitron', monospace;
font-size: 9px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 4px;
}
.knob-value {
font-family: 'JetBrains Mono', monospace;
font-size: 16px;
font-weight: 600;
color: var(--accent-cyan);
text-shadow: 0 0 10px var(--accent-cyan-dim);
}
/* Knobs Row Container */
.knobs-row {
display: flex;
gap: 30px;
justify-content: center;
}
.knob-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
}
/* Button Bank */
.radio-button-bank {
display: flex;
gap: 2px;
background: var(--bg-primary);
padding: 4px;
border-radius: 6px;
border: 1px solid var(--border-color);
}
.radio-btn {
padding: 10px 14px;
background: var(--bg-secondary);
border: 1px solid transparent;
color: var(--text-secondary);
font-family: 'Orbitron', monospace;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
transition: all 0.15s ease;
min-width: 50px;
text-align: center;
}
.radio-btn:first-child {
border-radius: 4px 0 0 4px;
}
.radio-btn:last-child {
border-radius: 0 4px 4px 0;
}
.radio-btn:only-child {
border-radius: 4px;
}
.radio-btn.active {
background: var(--accent-cyan);
color: var(--bg-primary);
box-shadow: 0 0 15px var(--accent-cyan-dim);
}
.radio-btn:hover:not(.active) {
background: var(--bg-elevated);
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
/* Tuning Dial */
.tuning-dial {
width: 100px;
height: 100px;
background: conic-gradient(
from 0deg,
var(--bg-secondary) 0deg,
var(--bg-elevated) 45deg,
var(--bg-secondary) 90deg,
var(--bg-elevated) 135deg,
var(--bg-secondary) 180deg,
var(--bg-elevated) 225deg,
var(--bg-secondary) 270deg,
var(--bg-elevated) 315deg,
var(--bg-secondary) 360deg
);
border-radius: 50%;
border: 3px solid var(--border-light);
position: relative;
cursor: grab;
box-shadow:
0 4px 20px rgba(0, 0, 0, 0.4),
inset 0 0 30px rgba(0, 0, 0, 0.4);
}
.tuning-dial:active {
cursor: grabbing;
}
.tuning-dial::after {
content: '';
position: absolute;
top: 4px;
left: 50%;
width: 4px;
height: 12px;
background: var(--accent-cyan);
transform: translateX(-50%);
border-radius: 2px;
box-shadow: 0 0 10px var(--accent-cyan);
}
/* Fine Tune Buttons */
.fine-tune-btns {
display: flex;
gap: 4px;
margin-top: 8px;
}
.tune-btn {
padding: 6px 10px;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
color: var(--text-secondary);
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
font-weight: 600;
border-radius: 4px;
cursor: pointer;
transition: all 0.15s ease;
}
.tune-btn:hover {
background: var(--bg-elevated);
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
.tune-btn:active {
background: var(--accent-cyan);
color: var(--bg-primary);
}
/* Arc Signal Meter */
.signal-arc-meter {
width: 180px;
height: 100px;
position: relative;
}
.signal-arc-meter svg {
width: 100%;
height: 100%;
}
.signal-arc-bg {
fill: none;
stroke: var(--bg-primary);
stroke-width: 12;
stroke-linecap: round;
}
.signal-arc-fill {
fill: none;
stroke: url(#signal-gradient);
stroke-width: 12;
stroke-linecap: round;
stroke-dasharray: 188.5;
stroke-dashoffset: 188.5;
transition: stroke-dashoffset 0.1s ease-out;
}
.signal-arc-needle {
fill: var(--accent-cyan);
filter: drop-shadow(0 0 4px var(--accent-cyan));
transform-origin: 90px 90px;
transition: transform 0.1s ease-out;
}
.signal-arc-center {
fill: var(--bg-secondary);
stroke: var(--border-color);
stroke-width: 1;
}
.signal-arc-label {
font-family: 'JetBrains Mono', monospace;
font-size: 8px;
fill: var(--text-muted);
}
.signal-arc-value {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
font-weight: 600;
fill: var(--accent-cyan);
text-anchor: middle;
}
/* Scanner Section */
.radio-scanner-section {
display: flex;
flex-direction: column;
gap: 12px;
padding: 15px;
background: var(--bg-primary);
border-radius: 8px;
border: 1px solid var(--border-color);
}
.scanner-range {
display: flex;
align-items: center;
gap: 10px;
justify-content: center;
}
.scanner-range input {
width: 100px;
padding: 8px 12px;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 4px;
color: var(--accent-cyan);
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
font-weight: 600;
text-align: center;
}
.scanner-range input:focus {
outline: none;
border-color: var(--accent-cyan);
box-shadow: 0 0 0 2px var(--accent-cyan-dim);
}
.scanner-range span {
font-family: 'Orbitron', monospace;
font-size: 12px;
color: var(--text-muted);
}
.scanner-buttons {
display: flex;
gap: 8px;
justify-content: center;
}
.radio-action-btn {
padding: 12px 24px;
border: 1px solid var(--border-color);
background: var(--bg-secondary);
color: var(--text-secondary);
font-family: 'Orbitron', monospace;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 2px;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s ease;
}
.radio-action-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
.radio-action-btn.scan {
background: var(--accent-green);
border-color: var(--accent-green);
color: #fff;
}
.radio-action-btn.scan:hover {
background: #1db954;
box-shadow: 0 0 20px rgba(34, 197, 94, 0.4);
}
.radio-action-btn.scan.active {
background: var(--accent-red);
border-color: var(--accent-red);
}
.radio-action-btn.scan.active:hover {
box-shadow: 0 0 20px var(--accent-red-dim);
}
.radio-action-btn.pause {
background: var(--accent-orange);
border-color: var(--accent-orange);
color: #000;
}
.radio-action-btn.pause:disabled {
opacity: 0.4;
cursor: not-allowed;
}
/* Scan Progress Bar */
.scan-progress {
height: 6px;
background: var(--bg-secondary);
border-radius: 3px;
overflow: hidden;
margin-top: 8px;
}
.scan-bar {
height: 100%;
width: 0%;
background: linear-gradient(90deg, var(--accent-cyan), var(--accent-green));
border-radius: 3px;
transition: width 0.2s ease-out;
box-shadow: 0 0 10px var(--accent-cyan);
}
/* Activity Log Section */
.radio-log-section {
background: var(--bg-primary);
border-radius: 8px;
border: 1px solid var(--border-color);
overflow: hidden;
}
.log-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 15px;
background: var(--bg-secondary);
border-bottom: 1px solid var(--border-color);
}
.log-header span {
font-family: 'Orbitron', monospace;
font-size: 10px;
font-weight: 600;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 2px;
}
.log-toggle {
background: none;
border: none;
color: var(--text-muted);
cursor: pointer;
font-size: 14px;
padding: 4px 8px;
}
.log-toggle:hover {
color: var(--accent-cyan);
}
.log-content {
max-height: 200px;
overflow-y: auto;
padding: 10px 15px;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
}
/* Radio Meters Section */
.radio-meters-section {
display: flex;
justify-content: center;
align-items: center;
gap: 30px;
padding: 15px;
}
.spectrum-display {
flex: 1;
max-width: 400px;
}
.spectrum-display canvas {
width: 100%;
height: 80px;
background: rgba(0, 0, 0, 0.4);
border-radius: 6px;
border: 1px solid var(--border-color);
}
/* Responsive adjustments for radio panel */
@media (max-width: 768px) {
.radio-controls-section {
flex-direction: column;
align-items: center;
gap: 20px;
}
.knobs-row {
flex-wrap: wrap;
}
.freq-digits {
font-size: 40px;
}
.radio-button-bank {
flex-wrap: wrap;
justify-content: center;
}
}
/* ============================================
RADIO MODULE BOX SYSTEM
Compact modular layout for Listening Post
============================================ */
.radio-module-box {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
position: relative;
}
.radio-module-box::before {
content: '';
position: absolute;
top: 0;
left: 10px;
right: 10px;
height: 1px;
background: linear-gradient(90deg, transparent, var(--accent-cyan-dim), transparent);
}
/* Main Scanner Module - Primary Feature */
.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);
}
.radio-module-box.scanner-main::before {
height: 2px;
background: linear-gradient(90deg, transparent, var(--accent-cyan), transparent);
}
.radio-module-box.scanner-main .module-header {
color: var(--accent-cyan);
font-size: 13px;
letter-spacing: 3px;
}
.module-header {
font-family: 'Orbitron', 'JetBrains Mono', monospace;
font-size: 10px;
font-weight: 600;
color: var(--accent-cyan);
text-transform: uppercase;
letter-spacing: 2px;
margin-bottom: 8px;
}
/* Compact Radio Button Bank */
.radio-button-bank.compact {
gap: 2px;
}
.radio-button-bank.compact .radio-btn {
padding: 5px 10px;
font-size: 10px;
}
/* Radio Input Fields */
.radio-input {
background: rgba(0, 0, 0, 0.4);
border: 1px solid var(--border-color);
border-radius: 4px;
color: var(--text-primary);
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
padding: 6px 8px;
text-align: center;
}
.radio-input:focus {
outline: none;
border-color: var(--accent-cyan);
box-shadow: 0 0 5px var(--accent-cyan-dim);
}
/* Smaller Action Buttons for Compact Layout */
.radio-action-btn {
padding: 6px 12px;
font-size: 10px;
font-family: 'Orbitron', monospace;
font-weight: 600;
text-transform: uppercase;
background: var(--bg-elevated);
border: 1px solid var(--accent-cyan);
color: var(--accent-cyan);
border-radius: 4px;
cursor: pointer;
transition: all 0.15s;
flex: 1;
}
.radio-action-btn:hover:not(:disabled) {
background: var(--accent-cyan);
color: var(--bg-primary);
box-shadow: 0 0 10px var(--accent-cyan-dim);
}
.radio-action-btn:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.radio-action-btn.scan {
background: var(--accent-green);
border-color: var(--accent-green);
color: #000;
}
.radio-action-btn.scan:hover:not(:disabled) {
box-shadow: 0 0 15px rgba(0, 255, 136, 0.4);
}
/* Statistics Box */
.stat-box {
background: rgba(0, 0, 0, 0.3);
border-radius: 6px;
padding: 10px;
text-align: center;
}
.stat-value {
font-family: 'JetBrains Mono', monospace;
font-size: 22px;
font-weight: bold;
}
.stat-label {
font-size: 9px;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
/* Smaller Knobs for Compact Layout */
.radio-module-box .radio-knob {
width: 55px;
height: 55px;
}
.radio-module-box .knob-container {
text-align: center;
}
.radio-module-box .knob-label {
font-size: 9px;
margin-top: 5px;
}
.radio-module-box .knob-value {
font-size: 11px;
}
/* Smaller Tuning Dial for Compact Layout */
.radio-module-box .tuning-dial {
width: 90px;
height: 90px;
}
/* Fine Tune Buttons - Compact */
.fine-tune-btns {
display: flex;
gap: 4px;
justify-content: center;
}
.tune-btn {
padding: 4px 8px;
font-size: 10px;
font-family: 'JetBrains Mono', monospace;
background: var(--bg-elevated);
border: 1px solid var(--border-color);
color: var(--text-secondary);
border-radius: 3px;
cursor: pointer;
transition: all 0.15s;
}
.tune-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
}
/* Signal Hits Table Compact */
.radio-module-box table th,
.radio-module-box table td {
padding: 4px 6px;
border-bottom: 1px solid var(--border-color);
}
.radio-module-box table tbody tr:hover {
background: rgba(0, 212, 255, 0.05);
}
/* Log Content Compact */
.radio-module-box .log-content {
background: rgba(0, 0, 0, 0.2);
border-radius: 4px;
padding: 8px;
font-family: 'JetBrains Mono', monospace;
}
/* Listening Mode Selector Buttons */
.radio-mode-btn {
padding: 12px 24px;
font-family: 'Orbitron', 'JetBrains Mono', monospace;
font-size: 13px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 2px;
background: var(--bg-elevated);
border: 2px solid var(--border-color);
color: var(--text-secondary);
border-radius: 6px;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
gap: 10px;
}
.radio-mode-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
background: rgba(0, 212, 255, 0.05);
}
.radio-mode-btn.active {
background: linear-gradient(135deg, rgba(0, 212, 255, 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);
}
/* Listening Mode Panels */
.listening-mode-panel {
display: contents;
}
.listening-mode-panel[style*="display: none"] {
display: none !important;
}
/* Frequency Preset Buttons */
.preset-freq-btn {
padding: 8px 14px;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
background: var(--bg-elevated);
border: 1px solid var(--border-color);
color: var(--text-secondary);
border-radius: 4px;
cursor: pointer;
transition: all 0.15s;
}
.preset-freq-btn:hover {
border-color: var(--accent-cyan);
color: var(--accent-cyan);
background: rgba(0, 212, 255, 0.1);
}
.preset-freq-btn:active {
transform: scale(0.98);
}