diff --git a/static/css/adsb_dashboard.css b/static/css/adsb_dashboard.css index 8ef6822..1b8e9ab 100644 --- a/static/css/adsb_dashboard.css +++ b/static/css/adsb_dashboard.css @@ -25,7 +25,7 @@ } body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + font-family: var(--font-sans); background: var(--bg-dark); color: var(--text-primary); min-height: 100vh; @@ -94,7 +94,7 @@ body { } .logo { - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 16px; font-weight: 700; letter-spacing: 2px; diff --git a/static/css/adsb_history.css b/static/css/adsb_history.css index f24740b..1261599 100644 --- a/static/css/adsb_history.css +++ b/static/css/adsb_history.css @@ -20,7 +20,7 @@ } body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + font-family: var(--font-sans); background: var(--bg-dark); color: var(--text-primary); min-height: 100vh; diff --git a/static/css/ais_dashboard.css b/static/css/ais_dashboard.css index 8a8b7c0..38985fc 100644 --- a/static/css/ais_dashboard.css +++ b/static/css/ais_dashboard.css @@ -28,7 +28,7 @@ } body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + font-family: var(--font-sans); background: var(--bg-dark); color: var(--text-primary); min-height: 100vh; @@ -97,7 +97,7 @@ body { } .logo { - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 16px; font-weight: 700; letter-spacing: 2px; @@ -438,7 +438,7 @@ body { padding: 10px 15px; background: rgba(74, 158, 255, 0.05); border-bottom: 1px solid rgba(74, 158, 255, 0.1); - font-family: 'Orbitron', 'Terminus', monospace; + font-family: 'Orbitron', 'JetBrains Mono', monospace; font-size: 11px; font-weight: 500; letter-spacing: 2px; @@ -510,7 +510,7 @@ body { } .vessel-name { - font-family: 'Orbitron', 'Terminus', monospace; + font-family: 'Orbitron', 'JetBrains Mono', monospace; font-size: 16px; font-weight: 700; color: var(--accent-cyan); @@ -604,7 +604,7 @@ body { } .vessel-item-name { - font-family: 'Orbitron', 'Terminus', monospace; + font-family: 'Orbitron', 'JetBrains Mono', monospace; font-size: 12px; font-weight: 600; color: var(--accent-cyan); @@ -1148,7 +1148,7 @@ body { } .dsc-distress-alert .dsc-alert-header { - font-family: 'Orbitron', 'Terminus', monospace; + font-family: 'Orbitron', 'JetBrains Mono', monospace; font-size: 24px; font-weight: 700; color: var(--accent-red); diff --git a/static/css/components/device-cards.css b/static/css/components/device-cards.css index 645d258..af6f39b 100644 --- a/static/css/components/device-cards.css +++ b/static/css/components/device-cards.css @@ -53,7 +53,7 @@ } .device-name { - font-family: 'Inter', -apple-system, sans-serif; + font-family: var(--font-sans); font-size: 14px; font-weight: 600; color: var(--text-primary, #e0e0e0); @@ -221,7 +221,7 @@ } .device-range-band .range-label { - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 11px; font-weight: 600; color: var(--range-color); @@ -262,7 +262,7 @@ } .device-manufacturer .mfr-name { - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); } /* ============================================ @@ -426,7 +426,7 @@ } .message-card-title { - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 13px; font-weight: 600; color: var(--text-primary, #e0e0e0); diff --git a/static/css/components/signal-cards.css b/static/css/components/signal-cards.css index 19e5e73..87e65c4 100644 --- a/static/css/components/signal-cards.css +++ b/static/css/components/signal-cards.css @@ -107,7 +107,7 @@ display: inline-flex; align-items: center; gap: 5px; - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 11px; font-weight: 500; padding: 5px 10px; @@ -864,7 +864,7 @@ .signal-search-input { width: 100%; padding: 6px 10px; - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 11px; color: var(--text-primary); background: var(--bg-card); diff --git a/static/css/core/variables.css b/static/css/core/variables.css index 318717e..0c1d969 100644 --- a/static/css/core/variables.css +++ b/static/css/core/variables.css @@ -1,198 +1,198 @@ -/** - * INTERCEPT Design Tokens - * Single source of truth for colors, spacing, typography, and effects - * Import this file FIRST in any stylesheet that needs design tokens - */ - -:root { - /* ============================================ - COLOR PALETTE - Dark Theme (Default) - ============================================ */ - - /* Backgrounds - layered depth system */ - --bg-primary: #0a0c10; - --bg-secondary: #0f1218; - --bg-tertiary: #151a23; - --bg-card: #121620; - --bg-elevated: #1a202c; - --bg-overlay: rgba(0, 0, 0, 0.7); - - /* Background aliases for components */ - --bg-dark: var(--bg-primary); - --bg-panel: var(--bg-secondary); - - /* Accent colors */ - --accent-cyan: #4a9eff; - --accent-cyan-dim: rgba(74, 158, 255, 0.15); - --accent-cyan-hover: #6bb3ff; - --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-orange-dim: rgba(245, 158, 11, 0.15); - --accent-amber: #d4a853; - --accent-amber-dim: rgba(212, 168, 83, 0.15); - --accent-yellow: #eab308; - --accent-purple: #a855f7; - - /* Text hierarchy */ - --text-primary: #e8eaed; - --text-secondary: #9ca3af; - --text-dim: #4b5563; - --text-muted: #374151; - --text-inverse: #0a0c10; - - /* Borders */ - --border-color: #1f2937; - --border-light: #374151; - --border-glow: rgba(74, 158, 255, 0.2); - --border-focus: var(--accent-cyan); - - /* Status colors */ - --status-online: #22c55e; - --status-warning: #f59e0b; - --status-error: #ef4444; - --status-offline: #6b7280; - --status-info: #3b82f6; - - /* ============================================ - SPACING SCALE - ============================================ */ - --space-1: 4px; - --space-2: 8px; - --space-3: 12px; - --space-4: 16px; - --space-5: 20px; - --space-6: 24px; - --space-8: 32px; - --space-10: 40px; - --space-12: 48px; - --space-16: 64px; - - /* ============================================ - TYPOGRAPHY - ============================================ */ - --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; - --font-mono: 'Terminus', 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; - - /* Font sizes */ - --text-xs: 10px; - --text-sm: 12px; - --text-base: 14px; - --text-lg: 16px; - --text-xl: 18px; - --text-2xl: 20px; - --text-3xl: 24px; - --text-4xl: 30px; - - /* Font weights */ - --font-normal: 400; - --font-medium: 500; - --font-semibold: 600; - --font-bold: 700; - - /* Line heights */ - --leading-tight: 1.25; - --leading-normal: 1.5; - --leading-relaxed: 1.75; - - /* ============================================ - BORDERS & RADIUS - ============================================ */ - --radius-sm: 4px; - --radius-md: 6px; - --radius-lg: 8px; - --radius-xl: 12px; - --radius-full: 9999px; - - /* ============================================ - SHADOWS - ============================================ */ - --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3); - --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4); - --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.5); - --shadow-glow: 0 0 20px rgba(74, 158, 255, 0.15); - - /* ============================================ - TRANSITIONS - ============================================ */ - --transition-fast: 150ms ease; - --transition-base: 200ms ease; - --transition-slow: 300ms ease; - - /* ============================================ - Z-INDEX SCALE - ============================================ */ - --z-base: 0; - --z-dropdown: 100; - --z-sticky: 200; - --z-fixed: 300; - --z-modal-backdrop: 400; - --z-modal: 500; - --z-toast: 600; - --z-tooltip: 700; - - /* ============================================ - LAYOUT - ============================================ */ - --header-height: 60px; - --nav-height: 44px; - --sidebar-width: 280px; - --stats-strip-height: 36px; - --content-max-width: 1400px; -} - -/* ============================================ - LIGHT THEME OVERRIDES - ============================================ */ -[data-theme="light"] { - --bg-primary: #f8fafc; - --bg-secondary: #f1f5f9; - --bg-tertiary: #e2e8f0; - --bg-card: #ffffff; - --bg-elevated: #f8fafc; - --bg-overlay: rgba(255, 255, 255, 0.9); - - /* Background aliases for components */ - --bg-dark: var(--bg-primary); - --bg-panel: var(--bg-secondary); - - --accent-cyan: #2563eb; - --accent-cyan-dim: rgba(37, 99, 235, 0.1); - --accent-cyan-hover: #1d4ed8; - --accent-green: #16a34a; - --accent-green-dim: rgba(22, 163, 74, 0.1); - --accent-red: #dc2626; - --accent-red-dim: rgba(220, 38, 38, 0.1); - --accent-orange: #d97706; - --accent-orange-dim: rgba(217, 119, 6, 0.1); - --accent-amber: #b45309; - --accent-amber-dim: rgba(180, 83, 9, 0.1); - - --text-primary: #0f172a; - --text-secondary: #475569; - --text-dim: #94a3b8; - --text-muted: #cbd5e1; - --text-inverse: #f8fafc; - - --border-color: #e2e8f0; - --border-light: #cbd5e1; - --border-glow: rgba(37, 99, 235, 0.15); - - --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 20px rgba(37, 99, 235, 0.1); -} - -/* ============================================ - REDUCED MOTION - ============================================ */ -@media (prefers-reduced-motion: reduce) { - :root { - --transition-fast: 0ms; - --transition-base: 0ms; - --transition-slow: 0ms; - } -} +/** + * INTERCEPT Design Tokens + * Single source of truth for colors, spacing, typography, and effects + * Import this file FIRST in any stylesheet that needs design tokens + */ + +:root { + /* ============================================ + COLOR PALETTE - Dark Theme (Default) + ============================================ */ + + /* Backgrounds - layered depth system */ + --bg-primary: #0a0c10; + --bg-secondary: #0f1218; + --bg-tertiary: #151a23; + --bg-card: #121620; + --bg-elevated: #1a202c; + --bg-overlay: rgba(0, 0, 0, 0.7); + + /* Background aliases for components */ + --bg-dark: var(--bg-primary); + --bg-panel: var(--bg-secondary); + + /* Accent colors */ + --accent-cyan: #4a9eff; + --accent-cyan-dim: rgba(74, 158, 255, 0.15); + --accent-cyan-hover: #6bb3ff; + --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-orange-dim: rgba(245, 158, 11, 0.15); + --accent-amber: #d4a853; + --accent-amber-dim: rgba(212, 168, 83, 0.15); + --accent-yellow: #eab308; + --accent-purple: #a855f7; + + /* Text hierarchy */ + --text-primary: #e8eaed; + --text-secondary: #9ca3af; + --text-dim: #4b5563; + --text-muted: #374151; + --text-inverse: #0a0c10; + + /* Borders */ + --border-color: #1f2937; + --border-light: #374151; + --border-glow: rgba(74, 158, 255, 0.2); + --border-focus: var(--accent-cyan); + + /* Status colors */ + --status-online: #22c55e; + --status-warning: #f59e0b; + --status-error: #ef4444; + --status-offline: #6b7280; + --status-info: #3b82f6; + + /* ============================================ + SPACING SCALE + ============================================ */ + --space-1: 4px; + --space-2: 8px; + --space-3: 12px; + --space-4: 16px; + --space-5: 20px; + --space-6: 24px; + --space-8: 32px; + --space-10: 40px; + --space-12: 48px; + --space-16: 64px; + + /* ============================================ + TYPOGRAPHY + ============================================ */ + --font-sans: 'JetBrains Mono', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + --font-mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; + + /* Font sizes */ + --text-xs: 10px; + --text-sm: 12px; + --text-base: 14px; + --text-lg: 16px; + --text-xl: 18px; + --text-2xl: 20px; + --text-3xl: 24px; + --text-4xl: 30px; + + /* Font weights */ + --font-normal: 400; + --font-medium: 500; + --font-semibold: 600; + --font-bold: 700; + + /* Line heights */ + --leading-tight: 1.25; + --leading-normal: 1.5; + --leading-relaxed: 1.75; + + /* ============================================ + BORDERS & RADIUS + ============================================ */ + --radius-sm: 4px; + --radius-md: 6px; + --radius-lg: 8px; + --radius-xl: 12px; + --radius-full: 9999px; + + /* ============================================ + SHADOWS + ============================================ */ + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4); + --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.5); + --shadow-glow: 0 0 20px rgba(74, 158, 255, 0.15); + + /* ============================================ + TRANSITIONS + ============================================ */ + --transition-fast: 150ms ease; + --transition-base: 200ms ease; + --transition-slow: 300ms ease; + + /* ============================================ + Z-INDEX SCALE + ============================================ */ + --z-base: 0; + --z-dropdown: 100; + --z-sticky: 200; + --z-fixed: 300; + --z-modal-backdrop: 400; + --z-modal: 500; + --z-toast: 600; + --z-tooltip: 700; + + /* ============================================ + LAYOUT + ============================================ */ + --header-height: 60px; + --nav-height: 44px; + --sidebar-width: 280px; + --stats-strip-height: 36px; + --content-max-width: 1400px; +} + +/* ============================================ + LIGHT THEME OVERRIDES + ============================================ */ +[data-theme="light"] { + --bg-primary: #f8fafc; + --bg-secondary: #f1f5f9; + --bg-tertiary: #e2e8f0; + --bg-card: #ffffff; + --bg-elevated: #f8fafc; + --bg-overlay: rgba(255, 255, 255, 0.9); + + /* Background aliases for components */ + --bg-dark: var(--bg-primary); + --bg-panel: var(--bg-secondary); + + --accent-cyan: #2563eb; + --accent-cyan-dim: rgba(37, 99, 235, 0.1); + --accent-cyan-hover: #1d4ed8; + --accent-green: #16a34a; + --accent-green-dim: rgba(22, 163, 74, 0.1); + --accent-red: #dc2626; + --accent-red-dim: rgba(220, 38, 38, 0.1); + --accent-orange: #d97706; + --accent-orange-dim: rgba(217, 119, 6, 0.1); + --accent-amber: #b45309; + --accent-amber-dim: rgba(180, 83, 9, 0.1); + + --text-primary: #0f172a; + --text-secondary: #475569; + --text-dim: #94a3b8; + --text-muted: #cbd5e1; + --text-inverse: #f8fafc; + + --border-color: #e2e8f0; + --border-light: #cbd5e1; + --border-glow: rgba(37, 99, 235, 0.15); + + --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 20px rgba(37, 99, 235, 0.1); +} + +/* ============================================ + REDUCED MOTION + ============================================ */ +@media (prefers-reduced-motion: reduce) { + :root { + --transition-fast: 0ms; + --transition-base: 0ms; + --transition-slow: 0ms; + } +} diff --git a/static/css/fonts-local.css b/static/css/fonts-local.css index 49e61c6..d605b40 100644 --- a/static/css/fonts-local.css +++ b/static/css/fonts-local.css @@ -1,63 +1,63 @@ -/* Local font declarations for offline mode */ - -/* Inter - Primary UI font */ -@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'); -} - +/* Local font declarations for offline mode */ + +/* Inter - Primary UI font */ +@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 - Monospace/code font */ -@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: 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; @@ -65,12 +65,3 @@ font-display: swap; src: url('/static/vendor/fonts/JetBrainsMono-Bold.woff2') format('woff2'); } - -/* Terminus - Monospace UI font */ -@font-face { - font-family: 'Terminus'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url('/static/vendor/fonts/Terminus.ttf') format('truetype'); -} diff --git a/static/css/global-nav.css b/static/css/global-nav.css index 9b10fbb..7f36cc2 100644 --- a/static/css/global-nav.css +++ b/static/css/global-nav.css @@ -69,7 +69,7 @@ border: 1px solid transparent; border-radius: 6px; color: var(--text-secondary, #b7c1cf); - font-family: 'Space Grotesk', 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 11px; font-weight: 500; cursor: pointer; @@ -116,7 +116,7 @@ border: 1px solid var(--border-light, #2b3645); border-radius: 6px; color: var(--text-primary, #e7ebf2); - font-family: 'Space Grotesk', 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 11px; font-weight: 500; text-decoration: none; @@ -152,7 +152,7 @@ border: 1px solid transparent; border-radius: 6px; color: var(--text-secondary, #b7c1cf); - font-family: 'Space Grotesk', 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 11px; font-weight: 500; cursor: pointer; diff --git a/static/css/index.css b/static/css/index.css index 2cbf607..79d955f 100644 --- a/static/css/index.css +++ b/static/css/index.css @@ -1,13 +1,3 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap'); - -@font-face { - font-family: 'Terminus'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url('/static/vendor/fonts/Terminus.ttf') format('truetype'); -} - * { box-sizing: border-box; margin: 0; @@ -81,7 +71,7 @@ } body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + font-family: var(--font-sans); background: var(--bg-primary); color: var(--text-primary); min-height: 100vh; @@ -348,7 +338,7 @@ body { } .changelog-date { - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 0.7rem; color: var(--text-dim); } @@ -360,7 +350,7 @@ body { } .changelog-list li { - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 0.75rem; color: var(--text-secondary); margin-bottom: 6px; @@ -452,7 +442,7 @@ body { } .mode-card .mode-desc { - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 0.65rem; color: var(--text-dim); margin-top: 4px; @@ -525,7 +515,7 @@ body { } .welcome-footer p { - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 0.7rem; color: var(--text-dim); letter-spacing: 0.1em; @@ -739,7 +729,7 @@ header h1 { border: 1px solid transparent; border-radius: 4px; color: var(--text-secondary); - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 11px; font-weight: 500; cursor: pointer; @@ -786,7 +776,7 @@ header h1 { border: 1px solid var(--accent-cyan); border-radius: 4px; color: var(--accent-cyan); - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 11px; font-weight: 500; text-decoration: none; @@ -822,7 +812,7 @@ header h1 { border: 1px solid transparent; border-radius: 4px; color: var(--text-secondary); - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 11px; font-weight: 500; cursor: pointer; @@ -1665,7 +1655,7 @@ header h1 .tagline { background: var(--accent-green); border: none; color: #fff; - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 12px; font-weight: 600; text-transform: uppercase; @@ -1702,7 +1692,7 @@ header h1 .tagline { background: var(--accent-red); border: none; color: #fff; - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 12px; font-weight: 600; text-transform: uppercase; @@ -2097,7 +2087,7 @@ header h1 .tagline { text-transform: uppercase; letter-spacing: 1px; transition: all 0.2s ease; - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); } .control-btn:hover { @@ -2512,7 +2502,7 @@ header h1 .tagline { border-radius: 4px; color: var(--text-secondary); cursor: pointer; - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 11px; text-transform: uppercase; transition: all 0.2s ease; @@ -4892,7 +4882,7 @@ body::before { color: #000; border: none; padding: 12px 40px; - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 14px; font-weight: 600; letter-spacing: 2px; @@ -6027,7 +6017,7 @@ body::before { } .module-header { - font-family: 'Orbitron', 'Terminus', monospace; + font-family: 'Orbitron', 'JetBrains Mono', monospace; font-size: 10px; font-weight: 600; color: var(--accent-cyan); @@ -6194,7 +6184,7 @@ body::before { /* Listening Mode Selector Buttons */ .radio-mode-btn { padding: 12px 24px; - font-family: 'Orbitron', 'Terminus', monospace; + font-family: 'Orbitron', 'JetBrains Mono', monospace; font-size: 13px; font-weight: 600; text-transform: uppercase; diff --git a/static/css/responsive.css b/static/css/responsive.css index 9f4223f..c7e1f0c 100644 --- a/static/css/responsive.css +++ b/static/css/responsive.css @@ -3,667 +3,658 @@ Shared responsive foundation for all pages ============================================ */ -/* Terminus - bundled monospace */ -@font-face { - font-family: 'Terminus'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url('/static/vendor/fonts/Terminus.ttf') format('truetype'); +/* ============== CSS VARIABLES ============== */ +:root { + /* Touch targets */ + --touch-min: 44px; + --touch-comfortable: 48px; + + /* Responsive spacing */ + --spacing-xs: clamp(4px, 1vw, 8px); + --spacing-sm: clamp(8px, 2vw, 12px); + --spacing-md: clamp(12px, 3vw, 20px); + --spacing-lg: clamp(16px, 4vw, 32px); + + /* Responsive typography */ + --font-xs: clamp(10px, 2.5vw, 11px); + --font-sm: clamp(11px, 2.8vw, 12px); + --font-base: clamp(13px, 3vw, 14px); + --font-md: clamp(14px, 3.5vw, 16px); + --font-lg: clamp(16px, 4vw, 20px); + --font-xl: clamp(20px, 5vw, 28px); + --font-2xl: clamp(24px, 6vw, 40px); + + /* Header height for calculations */ + --header-height: 52px; + --nav-height: 44px; +} + +@media (min-width: 768px) { + :root { + --header-height: 60px; + --nav-height: 48px; + } +} + +@media (min-width: 1024px) { + :root { + --header-height: 96px; + --nav-height: 0px; + } +} + +/* ============== VIEWPORT HEIGHT FIX ============== */ +/* Handles iOS Safari address bar and dynamic viewport */ +.full-height { + height: 100dvh; + height: 100vh; /* Fallback */ +} + +@supports (-webkit-touch-callout: none) { + .full-height { + height: -webkit-fill-available; + } +} + +/* ============== HAMBURGER BUTTON ============== */ +.hamburger-btn { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: var(--touch-min); + height: var(--touch-min); + padding: 10px; + background: transparent; + border: 1px solid var(--border-color, #1f2937); + border-radius: 6px; + cursor: pointer; + position: relative; + z-index: 1001; + flex-shrink: 0; + transition: background 0.2s ease, border-color 0.2s ease; +} + +.hamburger-btn:hover { + background: var(--bg-tertiary, #151a23); + border-color: var(--accent-cyan, #4a9eff); +} + +.hamburger-btn span { + display: block; + width: 18px; + height: 2px; + background: var(--accent-cyan, #4a9eff); + margin: 2px 0; + border-radius: 1px; + transition: transform 0.3s ease, opacity 0.3s ease; +} + +.hamburger-btn.active span:nth-child(1) { + transform: rotate(45deg) translate(4px, 4px); +} + +.hamburger-btn.active span:nth-child(2) { + opacity: 0; +} + +.hamburger-btn.active span:nth-child(3) { + transform: rotate(-45deg) translate(4px, -4px); +} + +/* Hide hamburger on desktop */ +@media (min-width: 1024px) { + .hamburger-btn { + display: none; + } +} + +/* ============== MOBILE DRAWER ============== */ +.mobile-drawer { + position: fixed; + top: 0; + left: 0; + width: min(320px, 85vw); + height: 100dvh; + height: 100vh; /* Fallback */ + background: var(--bg-secondary, #0f1218); + border-right: 1px solid var(--border-color, #1f2937); + transform: translateX(-100%); + transition: transform 0.3s ease; + z-index: 1000; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + padding-top: 60px; +} + +.mobile-drawer.open { + transform: translateX(0); +} + +/* Show sidebar normally on desktop */ +@media (min-width: 1024px) { + .mobile-drawer { + position: static; + transform: none; + width: auto; + height: auto; + padding-top: 0; + z-index: auto; + } +} + +/* ============== DRAWER OVERLAY ============== */ +.drawer-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(2px); + opacity: 0; + visibility: hidden; + transition: opacity 0.3s ease, visibility 0.3s ease; + z-index: 999; +} + +.drawer-overlay.visible { + opacity: 1; + visibility: visible; +} + +/* Hide overlay on desktop */ +@media (min-width: 1024px) { + .drawer-overlay { + display: none; + } +} + +/* ============== TOUCH TARGETS ============== */ +@media (max-width: 1023px) { + /* Ensure minimum touch target size for interactive elements */ + button, + .btn, + .preset-btn, + .mode-nav-btn, + .control-btn, + .nav-action-btn, + .icon-btn { + min-height: var(--touch-min); + min-width: var(--touch-min); + } + + select, + input[type="text"], + input[type="number"], + input[type="search"] { + min-height: var(--touch-min); + padding: 10px 12px; + font-size: 16px; /* Prevents iOS zoom on focus */ + } + + .checkbox-group label, + .radio-group label { + min-height: var(--touch-min); + padding: 10px 14px; + display: flex; + align-items: center; + } +} + +/* ============== RESPONSIVE UTILITIES ============== */ +/* Hide on mobile */ +.hide-mobile { + display: none; +} + +@media (min-width: 768px) { + .hide-mobile { + display: initial; + } +} + +/* Hide on tablet and up */ +.show-mobile-only { + display: initial; +} + +@media (min-width: 768px) { + .show-mobile-only { + display: none; + } +} + +/* Hide on desktop */ +.hide-desktop { + display: initial; +} + +@media (min-width: 1024px) { + .hide-desktop { + display: none; + } +} + +/* Show only on desktop */ +.show-desktop-only { + display: none; +} + +@media (min-width: 1024px) { + .show-desktop-only { + display: initial; + } +} + +/* ============== SCROLLABLE AREAS ============== */ +.scroll-x { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + scrollbar-width: thin; +} + +.scroll-x::-webkit-scrollbar { + height: 4px; +} + +.scroll-x::-webkit-scrollbar-thumb { + background: var(--border-color, #1f2937); + border-radius: 2px; +} + +/* Hide scrollbar on mobile for cleaner look */ +@media (max-width: 767px) { + .scroll-x-mobile-hidden { + scrollbar-width: none; + } + + .scroll-x-mobile-hidden::-webkit-scrollbar { + display: none; + } +} + +/* ============== MOBILE NAVIGATION BAR ============== */ +.mobile-nav-bar { + display: flex; + align-items: center; + gap: 4px; + padding: 6px 10px; + background: var(--bg-tertiary, #151a23); + border-bottom: 1px solid var(--border-color, #1f2937); + overflow-x: auto; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; +} + +.mobile-nav-bar::-webkit-scrollbar { + display: none; +} + +.mobile-nav-btn { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 8px 12px; + background: var(--bg-card, #121620); + border: 1px solid var(--border-color, #1f2937); + border-radius: 6px; + color: var(--text-secondary, #9ca3af); + font-size: var(--font-xs); + font-family: inherit; + white-space: nowrap; + cursor: pointer; + transition: all 0.2s ease; + min-height: 36px; +} + +.mobile-nav-btn:hover, +.mobile-nav-btn.active { + background: var(--bg-elevated, #1a202c); + border-color: var(--accent-cyan, #4a9eff); + color: var(--text-primary, #e8eaed); +} + +.mobile-nav-btn svg { + width: 14px; + height: 14px; + flex-shrink: 0; +} + +/* Hide mobile nav bar on desktop */ +@media (min-width: 1024px) { + .mobile-nav-bar { + display: none; + } +} + +/* ============== RESPONSIVE GRID UTILITIES ============== */ +.grid-responsive { + display: grid; + gap: var(--spacing-sm); +} + +/* 1 column base */ +.grid-1-2 { + grid-template-columns: 1fr; +} + +@media (min-width: 480px) { + .grid-1-2 { + grid-template-columns: repeat(2, 1fr); + } +} + +.grid-2-3 { + grid-template-columns: repeat(2, 1fr); +} + +@media (min-width: 768px) { + .grid-2-3 { + grid-template-columns: repeat(3, 1fr); + } +} + +/* ============== TYPOGRAPHY RESPONSIVE ============== */ +.text-responsive-xs { font-size: var(--font-xs); } +.text-responsive-sm { font-size: var(--font-sm); } +.text-responsive-base { font-size: var(--font-base); } +.text-responsive-md { font-size: var(--font-md); } +.text-responsive-lg { font-size: var(--font-lg); } +.text-responsive-xl { font-size: var(--font-xl); } +.text-responsive-2xl { font-size: var(--font-2xl); } + +/* Ensure minimum readable sizes for tiny text */ +.text-min-readable { + font-size: max(10px, var(--font-xs)); +} + +/* ============== MOBILE LAYOUT FIXES ============== */ +@media (max-width: 1023px) { + /* Fix main content to allow scrolling on mobile */ + .main-content { + height: auto !important; + min-height: calc(100dvh - var(--header-height) - var(--nav-height)); + overflow-y: auto !important; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + } + + /* Container should not clip content */ + .container { + overflow: visible; + height: auto; + min-height: 100dvh; + } + + /* Layout containers need to stack vertically on mobile */ + .wifi-layout-container, + .bt-layout-container { + flex-direction: column !important; + height: auto !important; + max-height: none !important; + min-height: auto !important; + overflow: visible !important; + padding: 10px !important; + } + + /* Visual panels should be scrollable, not clipped */ + .wifi-visuals, + .bt-visuals { + max-height: none !important; + overflow: visible !important; + margin-bottom: 15px; + } + + /* Device lists should have reasonable height on mobile */ + .wifi-device-list, + .bt-device-list { + max-height: 400px; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + } + + /* Visual panels should stack in single column on mobile when visible */ + .wifi-visuals, + .bt-visuals { + display: flex; + flex-direction: column; + gap: 10px; + } + + /* Only apply flex when aircraft visuals are shown (via JS setting display: grid) */ + #aircraftVisuals[style*="grid"] { + display: flex !important; + flex-direction: column !important; + gap: 10px; + } + + /* APRS visuals - only when visible */ + #aprsVisuals[style*="flex"] { + flex-direction: column !important; + } + + .wifi-visual-panel { + grid-column: auto !important; + } +} + +/* ============== MOBILE MAP FIXES ============== */ +@media (max-width: 1023px) { + /* Aircraft map container needs explicit height on mobile */ + .aircraft-map-container { + height: 300px !important; + min-height: 300px !important; + width: 100% !important; + } + + #aircraftMap { + height: 100% !important; + width: 100% !important; + min-height: 250px; + } + + /* APRS map container */ + #aprsMap { + min-height: 300px !important; + height: 300px !important; + width: 100% !important; + } + + /* Satellite embed */ + .satellite-dashboard-embed { + height: 400px !important; + min-height: 400px !important; + } + + /* Map panels should be full width */ + .wifi-visual-panel[style*="grid-column: span 2"] { + grid-column: auto !important; + } + + /* Make map container full width when it has ACARS sidebar */ + .wifi-visual-panel[style*="display: flex"][style*="gap: 0"] { + flex-direction: column !important; + } + + /* ACARS sidebar should be below map on mobile */ + .main-acars-sidebar { + width: 100% !important; + max-width: none !important; + border-left: none !important; + border-top: 1px solid var(--border-color, #1f2937) !important; + } + + .main-acars-sidebar.collapsed { + width: 100% !important; + } + + .main-acars-content { + max-height: 200px !important; + } +} + +/* ============== LEAFLET MOBILE TOUCH FIXES ============== */ +.leaflet-container { + touch-action: pan-x pan-y; + -webkit-tap-highlight-color: transparent; +} + +.leaflet-control-zoom { + touch-action: manipulation; +} + +.leaflet-control-zoom a { + min-width: var(--touch-min, 44px) !important; + min-height: var(--touch-min, 44px) !important; + line-height: var(--touch-min, 44px) !important; + font-size: 18px !important; +} + +/* ============== MOBILE HEADER STATS ============== */ +@media (max-width: 1023px) { + .header-stats { + display: none !important; + } + + /* Simplify header on mobile */ + header h1 { + font-size: 16px !important; + } + + header h1 .tagline, + header h1 .version-badge { + display: none; + } + + header .subtitle { + font-size: 10px !important; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + header .logo svg { + width: 30px !important; + height: 30px !important; + } +} + +/* ============== MOBILE MODE PANELS ============== */ +@media (max-width: 1023px) { + /* Mode panel grids should be single column */ + .data-grid, + .stats-grid, + .sensor-grid { + grid-template-columns: 1fr !important; + } + + /* Section headers should be easier to tap */ + .section h3 { + min-height: var(--touch-min); + padding: 12px !important; + } + + /* Tables need horizontal scroll */ + .message-table, + .sensor-table { + display: block; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + + /* Ensure messages list is scrollable */ + #messageList, + #sensorGrid, + .aprs-list { + max-height: 60vh; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + } +} + +/* ============== WELCOME PAGE MOBILE ============== */ +@media (max-width: 767px) { + .welcome-container { + padding: 15px !important; + max-width: 100% !important; + } + + .welcome-header { + flex-direction: column; + text-align: center; + gap: 10px; + } + + .welcome-logo svg { + width: 50px; + height: 50px; + } + + .welcome-title { + font-size: 24px !important; + } + + .welcome-content { + grid-template-columns: 1fr !important; + } + + .mode-grid { + grid-template-columns: repeat(2, 1fr) !important; + gap: 8px !important; + } + + .mode-card { + padding: 12px 8px !important; + } + + .mode-icon { + font-size: 20px !important; + } + + .mode-name { + font-size: 11px !important; + } + + .mode-desc { + font-size: 9px !important; + } + + .changelog-release { + padding: 10px !important; + } +} + +/* ============== TSCM MODE MOBILE ============== */ +@media (max-width: 1023px) { + .tscm-layout { + flex-direction: column !important; + height: auto !important; + } + + .tscm-spectrum-panel, + .tscm-detection-panel { + width: 100% !important; + max-width: none !important; + height: auto !important; + min-height: 300px; + } +} + +/* ============== LISTENING POST MOBILE ============== */ +@media (max-width: 1023px) { + .radio-controls-section { + flex-direction: column !important; + gap: 15px; + } + + .knobs-row { + flex-wrap: wrap; + justify-content: center; + } + + .radio-module-box { + width: 100% !important; + } } - -/* ============== CSS VARIABLES ============== */ -:root { - /* Touch targets */ - --touch-min: 44px; - --touch-comfortable: 48px; - - /* Responsive spacing */ - --spacing-xs: clamp(4px, 1vw, 8px); - --spacing-sm: clamp(8px, 2vw, 12px); - --spacing-md: clamp(12px, 3vw, 20px); - --spacing-lg: clamp(16px, 4vw, 32px); - - /* Responsive typography */ - --font-xs: clamp(10px, 2.5vw, 11px); - --font-sm: clamp(11px, 2.8vw, 12px); - --font-base: clamp(13px, 3vw, 14px); - --font-md: clamp(14px, 3.5vw, 16px); - --font-lg: clamp(16px, 4vw, 20px); - --font-xl: clamp(20px, 5vw, 28px); - --font-2xl: clamp(24px, 6vw, 40px); - - /* Header height for calculations */ - --header-height: 52px; - --nav-height: 44px; -} - -@media (min-width: 768px) { - :root { - --header-height: 60px; - --nav-height: 48px; - } -} - -@media (min-width: 1024px) { - :root { - --header-height: 96px; - --nav-height: 0px; - } -} - -/* ============== VIEWPORT HEIGHT FIX ============== */ -/* Handles iOS Safari address bar and dynamic viewport */ -.full-height { - height: 100dvh; - height: 100vh; /* Fallback */ -} - -@supports (-webkit-touch-callout: none) { - .full-height { - height: -webkit-fill-available; - } -} - -/* ============== HAMBURGER BUTTON ============== */ -.hamburger-btn { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - width: var(--touch-min); - height: var(--touch-min); - padding: 10px; - background: transparent; - border: 1px solid var(--border-color, #1f2937); - border-radius: 6px; - cursor: pointer; - position: relative; - z-index: 1001; - flex-shrink: 0; - transition: background 0.2s ease, border-color 0.2s ease; -} - -.hamburger-btn:hover { - background: var(--bg-tertiary, #151a23); - border-color: var(--accent-cyan, #4a9eff); -} - -.hamburger-btn span { - display: block; - width: 18px; - height: 2px; - background: var(--accent-cyan, #4a9eff); - margin: 2px 0; - border-radius: 1px; - transition: transform 0.3s ease, opacity 0.3s ease; -} - -.hamburger-btn.active span:nth-child(1) { - transform: rotate(45deg) translate(4px, 4px); -} - -.hamburger-btn.active span:nth-child(2) { - opacity: 0; -} - -.hamburger-btn.active span:nth-child(3) { - transform: rotate(-45deg) translate(4px, -4px); -} - -/* Hide hamburger on desktop */ -@media (min-width: 1024px) { - .hamburger-btn { - display: none; - } -} - -/* ============== MOBILE DRAWER ============== */ -.mobile-drawer { - position: fixed; - top: 0; - left: 0; - width: min(320px, 85vw); - height: 100dvh; - height: 100vh; /* Fallback */ - background: var(--bg-secondary, #0f1218); - border-right: 1px solid var(--border-color, #1f2937); - transform: translateX(-100%); - transition: transform 0.3s ease; - z-index: 1000; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - padding-top: 60px; -} - -.mobile-drawer.open { - transform: translateX(0); -} - -/* Show sidebar normally on desktop */ -@media (min-width: 1024px) { - .mobile-drawer { - position: static; - transform: none; - width: auto; - height: auto; - padding-top: 0; - z-index: auto; - } -} - -/* ============== DRAWER OVERLAY ============== */ -.drawer-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.6); - backdrop-filter: blur(2px); - opacity: 0; - visibility: hidden; - transition: opacity 0.3s ease, visibility 0.3s ease; - z-index: 999; -} - -.drawer-overlay.visible { - opacity: 1; - visibility: visible; -} - -/* Hide overlay on desktop */ -@media (min-width: 1024px) { - .drawer-overlay { - display: none; - } -} - -/* ============== TOUCH TARGETS ============== */ -@media (max-width: 1023px) { - /* Ensure minimum touch target size for interactive elements */ - button, - .btn, - .preset-btn, - .mode-nav-btn, - .control-btn, - .nav-action-btn, - .icon-btn { - min-height: var(--touch-min); - min-width: var(--touch-min); - } - - select, - input[type="text"], - input[type="number"], - input[type="search"] { - min-height: var(--touch-min); - padding: 10px 12px; - font-size: 16px; /* Prevents iOS zoom on focus */ - } - - .checkbox-group label, - .radio-group label { - min-height: var(--touch-min); - padding: 10px 14px; - display: flex; - align-items: center; - } -} - -/* ============== RESPONSIVE UTILITIES ============== */ -/* Hide on mobile */ -.hide-mobile { - display: none; -} - -@media (min-width: 768px) { - .hide-mobile { - display: initial; - } -} - -/* Hide on tablet and up */ -.show-mobile-only { - display: initial; -} - -@media (min-width: 768px) { - .show-mobile-only { - display: none; - } -} - -/* Hide on desktop */ -.hide-desktop { - display: initial; -} - -@media (min-width: 1024px) { - .hide-desktop { - display: none; - } -} - -/* Show only on desktop */ -.show-desktop-only { - display: none; -} - -@media (min-width: 1024px) { - .show-desktop-only { - display: initial; - } -} - -/* ============== SCROLLABLE AREAS ============== */ -.scroll-x { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - scrollbar-width: thin; -} - -.scroll-x::-webkit-scrollbar { - height: 4px; -} - -.scroll-x::-webkit-scrollbar-thumb { - background: var(--border-color, #1f2937); - border-radius: 2px; -} - -/* Hide scrollbar on mobile for cleaner look */ -@media (max-width: 767px) { - .scroll-x-mobile-hidden { - scrollbar-width: none; - } - - .scroll-x-mobile-hidden::-webkit-scrollbar { - display: none; - } -} - -/* ============== MOBILE NAVIGATION BAR ============== */ -.mobile-nav-bar { - display: flex; - align-items: center; - gap: 4px; - padding: 6px 10px; - background: var(--bg-tertiary, #151a23); - border-bottom: 1px solid var(--border-color, #1f2937); - overflow-x: auto; - -webkit-overflow-scrolling: touch; - scrollbar-width: none; -} - -.mobile-nav-bar::-webkit-scrollbar { - display: none; -} - -.mobile-nav-btn { - display: flex; - align-items: center; - justify-content: center; - gap: 6px; - padding: 8px 12px; - background: var(--bg-card, #121620); - border: 1px solid var(--border-color, #1f2937); - border-radius: 6px; - color: var(--text-secondary, #9ca3af); - font-size: var(--font-xs); - font-family: inherit; - white-space: nowrap; - cursor: pointer; - transition: all 0.2s ease; - min-height: 36px; -} - -.mobile-nav-btn:hover, -.mobile-nav-btn.active { - background: var(--bg-elevated, #1a202c); - border-color: var(--accent-cyan, #4a9eff); - color: var(--text-primary, #e8eaed); -} - -.mobile-nav-btn svg { - width: 14px; - height: 14px; - flex-shrink: 0; -} - -/* Hide mobile nav bar on desktop */ -@media (min-width: 1024px) { - .mobile-nav-bar { - display: none; - } -} - -/* ============== RESPONSIVE GRID UTILITIES ============== */ -.grid-responsive { - display: grid; - gap: var(--spacing-sm); -} - -/* 1 column base */ -.grid-1-2 { - grid-template-columns: 1fr; -} - -@media (min-width: 480px) { - .grid-1-2 { - grid-template-columns: repeat(2, 1fr); - } -} - -.grid-2-3 { - grid-template-columns: repeat(2, 1fr); -} - -@media (min-width: 768px) { - .grid-2-3 { - grid-template-columns: repeat(3, 1fr); - } -} - -/* ============== TYPOGRAPHY RESPONSIVE ============== */ -.text-responsive-xs { font-size: var(--font-xs); } -.text-responsive-sm { font-size: var(--font-sm); } -.text-responsive-base { font-size: var(--font-base); } -.text-responsive-md { font-size: var(--font-md); } -.text-responsive-lg { font-size: var(--font-lg); } -.text-responsive-xl { font-size: var(--font-xl); } -.text-responsive-2xl { font-size: var(--font-2xl); } - -/* Ensure minimum readable sizes for tiny text */ -.text-min-readable { - font-size: max(10px, var(--font-xs)); -} - -/* ============== MOBILE LAYOUT FIXES ============== */ -@media (max-width: 1023px) { - /* Fix main content to allow scrolling on mobile */ - .main-content { - height: auto !important; - min-height: calc(100dvh - var(--header-height) - var(--nav-height)); - overflow-y: auto !important; - overflow-x: hidden; - -webkit-overflow-scrolling: touch; - } - - /* Container should not clip content */ - .container { - overflow: visible; - height: auto; - min-height: 100dvh; - } - - /* Layout containers need to stack vertically on mobile */ - .wifi-layout-container, - .bt-layout-container { - flex-direction: column !important; - height: auto !important; - max-height: none !important; - min-height: auto !important; - overflow: visible !important; - padding: 10px !important; - } - - /* Visual panels should be scrollable, not clipped */ - .wifi-visuals, - .bt-visuals { - max-height: none !important; - overflow: visible !important; - margin-bottom: 15px; - } - - /* Device lists should have reasonable height on mobile */ - .wifi-device-list, - .bt-device-list { - max-height: 400px; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - } - - /* Visual panels should stack in single column on mobile when visible */ - .wifi-visuals, - .bt-visuals { - display: flex; - flex-direction: column; - gap: 10px; - } - - /* Only apply flex when aircraft visuals are shown (via JS setting display: grid) */ - #aircraftVisuals[style*="grid"] { - display: flex !important; - flex-direction: column !important; - gap: 10px; - } - - /* APRS visuals - only when visible */ - #aprsVisuals[style*="flex"] { - flex-direction: column !important; - } - - .wifi-visual-panel { - grid-column: auto !important; - } -} - -/* ============== MOBILE MAP FIXES ============== */ -@media (max-width: 1023px) { - /* Aircraft map container needs explicit height on mobile */ - .aircraft-map-container { - height: 300px !important; - min-height: 300px !important; - width: 100% !important; - } - - #aircraftMap { - height: 100% !important; - width: 100% !important; - min-height: 250px; - } - - /* APRS map container */ - #aprsMap { - min-height: 300px !important; - height: 300px !important; - width: 100% !important; - } - - /* Satellite embed */ - .satellite-dashboard-embed { - height: 400px !important; - min-height: 400px !important; - } - - /* Map panels should be full width */ - .wifi-visual-panel[style*="grid-column: span 2"] { - grid-column: auto !important; - } - - /* Make map container full width when it has ACARS sidebar */ - .wifi-visual-panel[style*="display: flex"][style*="gap: 0"] { - flex-direction: column !important; - } - - /* ACARS sidebar should be below map on mobile */ - .main-acars-sidebar { - width: 100% !important; - max-width: none !important; - border-left: none !important; - border-top: 1px solid var(--border-color, #1f2937) !important; - } - - .main-acars-sidebar.collapsed { - width: 100% !important; - } - - .main-acars-content { - max-height: 200px !important; - } -} - -/* ============== LEAFLET MOBILE TOUCH FIXES ============== */ -.leaflet-container { - touch-action: pan-x pan-y; - -webkit-tap-highlight-color: transparent; -} - -.leaflet-control-zoom { - touch-action: manipulation; -} - -.leaflet-control-zoom a { - min-width: var(--touch-min, 44px) !important; - min-height: var(--touch-min, 44px) !important; - line-height: var(--touch-min, 44px) !important; - font-size: 18px !important; -} - -/* ============== MOBILE HEADER STATS ============== */ -@media (max-width: 1023px) { - .header-stats { - display: none !important; - } - - /* Simplify header on mobile */ - header h1 { - font-size: 16px !important; - } - - header h1 .tagline, - header h1 .version-badge { - display: none; - } - - header .subtitle { - font-size: 10px !important; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - header .logo svg { - width: 30px !important; - height: 30px !important; - } -} - -/* ============== MOBILE MODE PANELS ============== */ -@media (max-width: 1023px) { - /* Mode panel grids should be single column */ - .data-grid, - .stats-grid, - .sensor-grid { - grid-template-columns: 1fr !important; - } - - /* Section headers should be easier to tap */ - .section h3 { - min-height: var(--touch-min); - padding: 12px !important; - } - - /* Tables need horizontal scroll */ - .message-table, - .sensor-table { - display: block; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } - - /* Ensure messages list is scrollable */ - #messageList, - #sensorGrid, - .aprs-list { - max-height: 60vh; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - } -} - -/* ============== WELCOME PAGE MOBILE ============== */ -@media (max-width: 767px) { - .welcome-container { - padding: 15px !important; - max-width: 100% !important; - } - - .welcome-header { - flex-direction: column; - text-align: center; - gap: 10px; - } - - .welcome-logo svg { - width: 50px; - height: 50px; - } - - .welcome-title { - font-size: 24px !important; - } - - .welcome-content { - grid-template-columns: 1fr !important; - } - - .mode-grid { - grid-template-columns: repeat(2, 1fr) !important; - gap: 8px !important; - } - - .mode-card { - padding: 12px 8px !important; - } - - .mode-icon { - font-size: 20px !important; - } - - .mode-name { - font-size: 11px !important; - } - - .mode-desc { - font-size: 9px !important; - } - - .changelog-release { - padding: 10px !important; - } -} - -/* ============== TSCM MODE MOBILE ============== */ -@media (max-width: 1023px) { - .tscm-layout { - flex-direction: column !important; - height: auto !important; - } - - .tscm-spectrum-panel, - .tscm-detection-panel { - width: 100% !important; - max-width: none !important; - height: auto !important; - min-height: 300px; - } -} - -/* ============== LISTENING POST MOBILE ============== */ -@media (max-width: 1023px) { - .radio-controls-section { - flex-direction: column !important; - gap: 15px; - } - - .knobs-row { - flex-wrap: wrap; - justify-content: center; - } - - .radio-module-box { - width: 100% !important; - } -} diff --git a/static/css/satellite_dashboard.css b/static/css/satellite_dashboard.css index 72b110c..9d64ecd 100644 --- a/static/css/satellite_dashboard.css +++ b/static/css/satellite_dashboard.css @@ -23,7 +23,7 @@ } body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + font-family: var(--font-sans); background: var(--bg-dark); color: var(--text-primary); min-height: 100vh; @@ -93,7 +93,7 @@ body { } .logo { - font-family: 'Inter', sans-serif; + font-family: var(--font-sans); font-size: 20px; font-weight: 700; letter-spacing: 3px; diff --git a/static/js/core/app.js b/static/js/core/app.js index bfab560..9728497 100644 --- a/static/js/core/app.js +++ b/static/js/core/app.js @@ -373,7 +373,7 @@ function showInfo(text) { const infoEl = document.createElement('div'); infoEl.className = 'info-msg'; - infoEl.style.cssText = 'padding: 12px 15px; margin-bottom: 8px; background: #0a0a0a; border: 1px solid #1a1a1a; border-left: 2px solid #00d4ff; font-family: "Terminus", monospace; font-size: 11px; color: #888; word-break: break-all;'; + infoEl.style.cssText = 'padding: 12px 15px; margin-bottom: 8px; background: #0a0a0a; border: 1px solid #1a1a1a; border-left: 2px solid #00d4ff; font-family: "JetBrains Mono", monospace; font-size: 11px; color: #888; word-break: break-all;'; infoEl.textContent = text; output.insertBefore(infoEl, output.firstChild); } @@ -387,7 +387,7 @@ function showError(text) { const errorEl = document.createElement('div'); errorEl.className = 'error-msg'; - errorEl.style.cssText = 'padding: 12px 15px; margin-bottom: 8px; background: #1a0a0a; border: 1px solid #2a1a1a; border-left: 2px solid #ff3366; font-family: "Terminus", monospace; font-size: 11px; color: #ff6688; word-break: break-all;'; + errorEl.style.cssText = 'padding: 12px 15px; margin-bottom: 8px; background: #1a0a0a; border: 1px solid #2a1a1a; border-left: 2px solid #ff3366; font-family: "JetBrains Mono", monospace; font-size: 11px; color: #ff6688; word-break: break-all;'; errorEl.textContent = '⚠ ' + text; output.insertBefore(errorEl, output.firstChild); } diff --git a/static/js/core/settings-manager.js b/static/js/core/settings-manager.js index 8282e1b..3941c2d 100644 --- a/static/js/core/settings-manager.js +++ b/static/js/core/settings-manager.js @@ -813,11 +813,11 @@ function renderUpdateStatus(data) {