@import './rtl-overrides.css'; @import './panels.css'; /* ============================================================ Theme Colors — overridden by [data-theme="light"] below ============================================================ */ :root { /* Backgrounds */ --bg: #0a0a0a; --bg-secondary: #111; --surface: #141414; --surface-hover: #1e1e1e; --surface-active: #1a1a2e; /* Borders */ --border: #2a2a2a; --border-strong: #444; --border-subtle: #1a1a1a; /* Text */ --text: #e8e8e8; --text-secondary: #ccc; --text-dim: #888; --text-muted: #666; --text-faint: #555; --text-ghost: #444; --accent: #fff; /* Overlays & shadows */ --overlay-subtle: rgba(255, 255, 255, 0.03); --overlay-light: rgba(255, 255, 255, 0.05); --overlay-medium: rgba(255, 255, 255, 0.1); --overlay-heavy: rgba(255, 255, 255, 0.2); --shadow-color: rgba(0, 0, 0, 0.5); --darken-light: rgba(0, 0, 0, 0.15); --darken-medium: rgba(0, 0, 0, 0.2); --darken-heavy: rgba(0, 0, 0, 0.3); /* Scrollbar */ --scrollbar-thumb: #333; --scrollbar-thumb-hover: #555; /* Input */ --input-bg: #1a1a1a; /* Panels */ --panel-bg: #141414; --panel-border: #2a2a2a; /* Map */ --map-bg: #020a08; --map-grid: #0a2a20; --map-country: #0a2018; --map-stroke: #0f5040; /* Font stack */ --font-mono: 'SF Mono', 'Monaco', 'Cascadia Code', 'Fira Code', 'DejaVu Sans Mono', 'Liberation Mono', monospace; --font-body: var(--font-mono); } [dir="rtl"] { --font-body: 'Tajawal', 'Geeza Pro', 'SF Arabic', 'Tahoma', system-ui, sans-serif; } :lang(zh-CN), :lang(zh) { --font-body: 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', system-ui, sans-serif; } /* ============================================================ Semantic Colors — dark-mode defaults, light overrides below ============================================================ */ :root { /* Severity levels */ --semantic-critical: #ff4444; --semantic-high: #ff8800; --semantic-elevated: #ffaa00; --semantic-normal: #44aa44; --semantic-low: #3388ff; --semantic-info: #3b82f6; --semantic-positive: #44ff88; /* Threat levels */ --threat-critical: #ef4444; --threat-high: #f97316; --threat-medium: #eab308; --threat-low: #22c55e; --threat-info: #3b82f6; /* DEFCON levels */ --defcon-1: #ff0040; --defcon-2: #ff4400; --defcon-3: #ffaa00; --defcon-4: #00aaff; --defcon-5: #2d8a6e; /* Status indicators */ --status-live: #44ff88; --status-cached: #ffaa00; --status-unavailable: #ff4444; /* Legacy color aliases (used by existing var() references) */ --red: #ff4444; --green: #44ff88; --yellow: #ffaa00; } /* ============================================================ Light Theme — overrides theme colors AND semantic colors Bright/neon dark-mode colors need darker variants for light backgrounds ============================================================ */ [data-theme="light"] { /* Semantic color overrides — darker variants for light backgrounds */ --semantic-high: #ea580c; /* Tailwind orange-600 (was #ff8800, 2.27:1) */ --semantic-elevated: #d97706; /* Tailwind amber-600 (was #ffaa00, 1.81:1) */ --semantic-normal: #15803d; /* Tailwind green-700 (was #44aa44, 2.81:1) */ --semantic-positive: #16a34a; /* Tailwind green-600 (was #44ff88, too bright for light bg) */ --threat-high: #c2410c; /* Tailwind orange-700 (was #f97316, 2.66:1) */ --threat-medium: #ca8a04; /* Tailwind yellow-600 (was #eab308, 1.82:1) */ --threat-low: #15803d; /* Tailwind green-700 (was #22c55e, 2.16:1) */ --defcon-3: #d97706; /* Tailwind amber-600 (was #ffaa00, 1.81:1) */ --defcon-4: #0284c7; /* Tailwind sky-600 (was #00aaff, 2.43:1) */ --status-live: #16a34a; /* Tailwind green-600 (was #44ff88, 1.25:1) */ --status-cached: #d97706; /* Tailwind amber-600 (was #ffaa00, 1.81:1) */ --green: #16a34a; /* Tailwind green-600 (was #44ff88) */ --yellow: #d97706; /* Tailwind amber-600 (was #ffaa00) */ /* Backgrounds */ --bg: #f8f9fa; --bg-secondary: #f0f1f3; --surface: #ffffff; --surface-hover: #f0f0f0; --surface-active: #e8e8f0; /* Borders */ --border: #d4d4d4; --border-strong: #b0b0b0; --border-subtle: #e8e8e8; /* Text */ --text: #1a1a1a; --text-secondary: #333; --text-dim: #6b6b6b; --text-muted: #767676; /* WCAG AA: 4.54:1 vs #f8f9fa */ --text-faint: #aaa; --text-ghost: #bbb; --accent: #111111; /* Overlays & shadows */ --overlay-subtle: rgba(0, 0, 0, 0.02); --overlay-light: rgba(0, 0, 0, 0.04); --overlay-medium: rgba(0, 0, 0, 0.08); --overlay-heavy: rgba(0, 0, 0, 0.12); --shadow-color: rgba(0, 0, 0, 0.1); --darken-light: rgba(0, 0, 0, 0.1); --darken-medium: rgba(0, 0, 0, 0.15); --darken-heavy: rgba(0, 0, 0, 0.2); /* Scrollbar */ --scrollbar-thumb: #c0c0c0; --scrollbar-thumb-hover: #999; /* Input */ --input-bg: #f0f0f0; /* Panels */ --panel-bg: #ffffff; --panel-border: #d4d4d4; /* Map */ --map-bg: #e8f0f8; --map-grid: #b0c8d8; --map-country: #f0e8d8; --map-stroke: #c8b8a8; } * { margin: 0; padding: 0; box-sizing: border-box; } html { height: 100%; width: 100%; overflow: hidden; } body { font-family: var(--font-body); font-size: 12px; line-height: 1.5; background: var(--bg); color: var(--text); overflow: hidden; height: 100%; width: 100%; min-height: 100vh; min-width: 100vw; } /* Pause all animations when tab is hidden or idle */ body.animations-paused *, body.animations-paused *::before, body.animations-paused *::after { animation-play-state: paused !important; transition: none !important; } /* ============================================================ Theme Transition — smooth 200ms animation for theme switches ============================================================ */ *, *::before, *::after { transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease; } /* Suppress transitions during initial page load (FOUC prevention) */ .no-transition *, .no-transition *::before, .no-transition *::after { transition: none !important; } /* Map and canvas elements manage their own rendering */ canvas, .maplibregl-map, .maplibregl-canvas, .deck-canvas { transition: none !important; } #app { height: 100%; width: 100%; min-height: 100vh; min-width: 100vw; display: flex; flex-direction: column; position: absolute; top: 0; left: 0; right: 0; bottom: 0; } .header { display: flex; align-items: center; justify-content: space-between; padding: 8px 16px; background: var(--surface); border-bottom: 1px solid var(--border); height: 40px; flex-shrink: 0; } .header-left { display: flex; align-items: center; gap: 16px; } /* Variant Switcher */ .variant-switcher { display: flex; align-items: center; gap: 2px; background: var(--overlay-subtle); border: 1px solid var(--border); border-radius: 4px; padding: 2px 4px; margin-right: 6px; } .variant-option { display: flex; align-items: center; gap: 4px; padding: 2px 6px; border-radius: 3px; text-decoration: none; color: var(--text-dim); font-size: 9px; font-weight: 600; letter-spacing: 1px; transition: all 0.25s ease; cursor: pointer; } .variant-option .variant-icon { font-size: 11px; filter: grayscale(80%); transition: filter 0.25s ease; } .variant-option .variant-label { max-width: 0; overflow: hidden; opacity: 0; transition: max-width 0.3s ease, opacity 0.2s ease; } .variant-option:hover .variant-label, .variant-option.active .variant-label { max-width: 50px; opacity: 1; } .variant-option:hover { color: var(--text); } .variant-option:hover .variant-icon { filter: grayscale(0%); } .variant-option.active { color: var(--green); background: rgba(68, 255, 136, 0.1); pointer-events: none; } .variant-option.active .variant-icon { filter: grayscale(0%) drop-shadow(0 0 4px var(--green)); } .variant-option[data-variant="tech"].active { color: var(--semantic-info); background: rgba(74, 158, 255, 0.1); } .variant-option[data-variant="tech"].active .variant-icon { filter: grayscale(0%) drop-shadow(0 0 4px var(--semantic-info)); } .variant-divider { width: 1px; height: 12px; background: var(--border); margin: 0 2px; } .variant-switcher:hover .variant-option .variant-label { max-width: 50px; opacity: 1; } .logo { font-weight: bold; font-size: 14px; letter-spacing: 2px; color: var(--accent); } .logo-mobile { display: none; font-weight: bold; font-size: 14px; letter-spacing: 2px; color: var(--accent); } .version { font-size: 9px; color: var(--muted); opacity: 0.5; margin-left: 6px; font-weight: normal; letter-spacing: 0.5px; vertical-align: middle; } /* Update toast notification */ .update-toast { position: fixed; top: 12px; right: 16px; display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: linear-gradient(135deg, #1a2332 0%, #0f1923 100%); border: 1px solid rgba(68, 255, 136, 0.25); border-radius: 10px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(68, 255, 136, 0.08); z-index: 10003; opacity: 0; transform: translateY(-20px); transition: opacity 0.3s ease, transform 0.3s ease; pointer-events: none; max-width: 340px; } .update-toast.visible { opacity: 1; transform: translateY(0); pointer-events: auto; } .update-toast-icon { flex-shrink: 0; display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 8px; background: rgba(68, 255, 136, 0.12); color: var(--green); } .update-toast-body { flex: 1; min-width: 0; } .update-toast-title { font-size: 13px; font-weight: 600; color: #e8e8e8; letter-spacing: 0.2px; } .update-toast-detail { font-size: 11px; color: #888; margin-top: 2px; letter-spacing: 0.3px; } .update-toast-action { flex-shrink: 0; padding: 6px 14px; font-size: 11px; font-weight: 600; letter-spacing: 0.3px; color: #0a0a0a; background: var(--green); border: none; border-radius: 6px; cursor: pointer; transition: filter 0.15s, transform 0.15s; } .update-toast-action:hover { filter: brightness(1.15); transform: scale(1.03); } .update-toast-action:active { transform: scale(0.97); } .update-toast-dismiss { flex-shrink: 0; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; font-size: 16px; color: #666; background: none; border: none; border-radius: 4px; cursor: pointer; transition: color 0.15s, background 0.15s; padding: 0; line-height: 1; } .update-toast-dismiss:hover { color: #ccc; background: rgba(255, 255, 255, 0.08); } .beta-badge { display: inline-flex; align-items: center; margin-left: 6px; padding: 1px 7px; font-size: 9px; font-weight: 600; letter-spacing: 0.5px; color: #0a0a0a; background: #f59e0b; border-radius: 8px; vertical-align: middle; } .credit-link { font-size: 9px; color: var(--muted); opacity: 0.6; font-weight: normal; letter-spacing: 0.5px; text-decoration: none; transition: opacity 0.2s; } .credit-link:hover { opacity: 1; color: var(--accent); } /* Hide X logo on desktop, show text */ .credit-link .x-logo { display: none; } .status-indicator { display: flex; align-items: center; gap: 6px; font-size: 10px; color: var(--text-dim); } .status-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); animation: pulse-dot 2s infinite; } @keyframes pulse-dot { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } /* Region Selector in Header */ .region-selector { display: flex; align-items: center; } .region-select { padding: 4px 24px 4px 10px; background: var(--bg); border: 1px solid var(--border); color: var(--text); font-family: inherit; font-size: 11px; cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%23888' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 8px center; } .region-select:hover { border-color: var(--green); } .region-select:focus { outline: none; border-color: var(--green); } .header-center { display: flex; gap: 8px; } .focus-label { font-size: 10px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-right: 6px; } .focus-select { padding: 4px 24px 4px 10px; background: var(--bg); border: 1px solid var(--border); color: var(--text); font-family: inherit; font-size: 11px; cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%2388a0a8' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 8px center; min-width: 100px; } .focus-select:hover { border-color: var(--text-dim); } .focus-select:focus { outline: none; border-color: var(--primary); } .focus-select option { background: var(--panel-bg); color: var(--text); } .header-right { display: flex; align-items: center; gap: 12px; } .theme-toggle-btn { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; background: transparent; border: 1px solid var(--border); border-radius: 4px; color: var(--text-dim); cursor: pointer; transition: color 0.2s, border-color 0.2s; } .theme-toggle-btn:hover { color: var(--text-primary); border-color: var(--text-dim); } .fullscreen-btn { padding: 4px 8px; background: transparent; border: 1px solid var(--border); color: var(--text); font-family: inherit; font-size: 14px; cursor: pointer; line-height: 1; } .fullscreen-btn:hover { border-color: var(--text-dim); } .fullscreen-btn.active { background: rgba(59, 130, 246, 0.12); border-color: var(--accent); color: var(--accent); } .mobile-settings-btn { display: none; align-items: center; justify-content: center; background: none; border: 1px solid transparent; border-radius: 4px; color: var(--text-dim); cursor: pointer; padding: 4px; margin-left: 6px; transition: color 0.2s, transform 0.3s; } .mobile-settings-btn:hover { color: var(--accent); transform: rotate(45deg); } .github-link { color: var(--text-dim); margin-left: 8px; display: flex; align-items: center; transition: color 0.2s; } .github-link:hover { color: var(--text); } .search-btn { padding: 4px 10px; background: transparent; border: 1px solid var(--border); color: var(--text); font-family: inherit; font-size: 11px; cursor: pointer; display: flex; align-items: center; gap: 6px; margin-right: 8px; } .search-btn:hover { border-color: var(--accent); color: var(--accent); } .copy-link-btn { padding: 4px 10px; background: transparent; border: 1px solid var(--border); color: var(--text); font-family: inherit; font-size: 11px; cursor: pointer; transition: all 0.2s; } .copy-link-btn:hover { border-color: var(--accent); color: var(--accent); } .copy-link-btn.copied { background: var(--text); color: var(--bg); border-color: var(--text); } .download-wrapper { position: relative; } .download-btn { padding: 4px 10px; background: color-mix(in srgb, var(--green) 10%, transparent); border: 1px solid color-mix(in srgb, var(--green) 30%, transparent); color: var(--green); font-family: inherit; font-size: 11px; cursor: pointer; transition: all 0.2s; display: flex; align-items: center; gap: 6px; } .download-btn:hover { background: color-mix(in srgb, var(--green) 18%, transparent); border-color: var(--green); color: var(--green); } .download-dropdown { position: absolute; top: 100%; right: 0; width: 280px; background: var(--border-subtle); border: 1px solid var(--border); border-radius: 6px; box-shadow: 0 8px 24px var(--shadow-color); z-index: 1000; display: none; margin-top: 4px; padding: 10px; } .download-dropdown.open { display: block; } .dl-dd-tagline { font-size: 11px; color: var(--text-dim); margin-bottom: 10px; line-height: 1.4; } .dl-dd-buttons { display: flex; flex-direction: column; gap: 6px; } .dl-dd-btn { display: block; padding: 8px 12px; border-radius: 4px; font-size: 12px; font-weight: 500; text-decoration: none; text-align: center; transition: opacity 0.15s; color: #e0e0e0; } .dl-dd-btn:hover { opacity: 0.85; } .dl-dd-btn.mac { background: #2d5a2d; border: 1px solid #3a7a3a; } .dl-dd-btn.win { background: #2d4a5a; border: 1px solid #3a6a8a; } .dl-dd-btn.linux { background: #5a4a2d; border: 1px solid #8a7a3a; } .dl-dd-btn.primary { font-weight: 600; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1); } .dl-dd-toggle { display: block; width: 100%; background: none; border: none; color: var(--accent); font-size: 11px; cursor: pointer; padding: 8px 0 4px; font-family: inherit; text-align: center; } .dl-dd-toggle:hover { text-decoration: underline; } .dl-dd-others { display: none; flex-direction: column; gap: 6px; margin-top: 6px; } .dl-dd-others.show { display: flex; } .search-btn kbd { background: var(--bg-secondary); padding: 2px 5px; border-radius: 3px; font-size: 10px; font-family: inherit; } .main-content { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; overflow-x: hidden; background: var(--bg); width: 100%; } .map-section { height: 50vh; min-height: 350px; max-height: 90vh; /* Allow resize up to 90% of viewport */ border: 1px solid var(--border); background: var(--surface); display: flex; flex-direction: column; flex-shrink: 0; position: relative; } .map-section.hidden { display: none; } .map-section .panel-header { flex-shrink: 0; gap: 6px; } .map-section .map-container { flex: 1; position: relative; } .map-resize-handle { position: absolute; bottom: 0; left: 0; right: 0; height: 8px; cursor: ns-resize; background: linear-gradient(to bottom, transparent, var(--border)); z-index: 200; display: flex; align-items: center; justify-content: center; } .map-resize-handle::after { content: ''; width: 40px; height: 3px; background: var(--text-dim); border-radius: 2px; opacity: 0.5; transition: opacity 0.2s; } .map-resize-handle:hover::after { opacity: 1; } .map-section.resizing { user-select: none; overflow: hidden; } .map-section.resizing .map-resize-handle::after { background: var(--green); opacity: 1; } .map-section.pinned { position: sticky; top: 0; z-index: 100; } .map-pin-btn { background: transparent; border: 1px solid var(--border); color: var(--text-dim); padding: 4px 8px; border-radius: 4px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s; } .map-pin-btn:hover { background: var(--surface-hover); color: var(--text); border-color: var(--text-dim); } .map-pin-btn.active { background: var(--green); border-color: var(--green); color: var(--bg); } .map-pin-btn.active:hover { background: var(--green-dim); } /* Hidden by default — shown only inside 768px media query */ .map-collapse-btn { display: none; } .panels-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); grid-auto-flow: row dense; grid-auto-rows: minmax(200px, 380px); gap: 4px; padding: 4px; align-content: start; align-items: stretch; min-height: 0; position: relative; z-index: 1; /* This ensures panels scroll UNDER the pinned map (z-index: 100) */ } .panel { background: var(--surface); border: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; height: 100%; min-height: 200px; min-width: 0; cursor: grab; transition: transform 0.15s, box-shadow 0.15s; position: relative; contain: content; } /* .panel.resized: Custom height set - use grid-row span for height */ /* Row span classes for resizable panels */ .panel.span-1 { grid-row: span 1 !important; min-height: 200px !important; } .panel.span-2 { grid-row: span 2 !important; min-height: 400px !important; } .panel.span-3 { grid-row: span 3 !important; min-height: 600px !important; } .panel.span-4 { grid-row: span 4 !important; min-height: 800px !important; } .panel.col-span-1 { grid-column: span 1 !important; } .panel.col-span-2 { grid-column: span 2 !important; } .panel.col-span-3 { grid-column: span 3 !important; } .panel-resize-handle { position: absolute; bottom: 0; left: 0; right: 0; height: 20px; cursor: ns-resize; background: linear-gradient(to top, rgba(68, 136, 255, 0.15), transparent); z-index: 100; transition: background 0.2s; touch-action: none; pointer-events: auto !important; user-select: none; } .panel-resize-handle:hover, .panel-resize-handle.active { background: linear-gradient(to top, rgba(68, 136, 255, 0.5), transparent); } .panel-resize-handle::after { content: '⋯'; position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%); font-size: 16px; letter-spacing: 2px; color: var(--text-dim); transition: color 0.2s; } .panel-resize-handle:hover::after { color: var(--accent); } /* Right-edge handle - mirrors the bottom handle exactly */ .panel-col-resize-handle { position: absolute; top: 0; right: 0; bottom: 0; width: 20px; cursor: ew-resize; background: linear-gradient(to left, rgba(68, 136, 255, 0.15), transparent); z-index: 100; transition: background 0.2s; touch-action: none; pointer-events: auto !important; user-select: none; } .panel-col-resize-handle:hover, .panel-col-resize-handle.active { background: linear-gradient(to left, rgba(68, 136, 255, 0.5), transparent); } .panel-col-resize-handle::after { content: '⋮'; position: absolute; right: 3px; top: 50%; transform: translateY(-50%); font-size: 16px; letter-spacing: 2px; color: var(--text-dim); transition: color 0.2s; } .panel-col-resize-handle:hover::after { color: var(--accent); } body.panel-resize-active iframe { pointer-events: none !important; } .panel.resizing { cursor: ns-resize; user-select: none; } /* Horizontal drag cursor */ .panel.col-resizing { cursor: ew-resize; user-select: none; } @media (max-width: 768px) { .panel-col-resize-handle { display: none; } } .panel:active { cursor: grabbing; } .panel.hidden { display: none; } .panel.dragging { opacity: 0.5; transform: scale(1.02); box-shadow: 0 8px 24px rgba(0, 255, 136, 0.2); will-change: transform, opacity; } .panel-header { display: flex; align-items: center; justify-content: space-between; padding: 6px 10px; background: var(--overlay-subtle); border-bottom: 1px solid var(--border); flex-shrink: 0; position: relative; transition: background-color 0.3s ease, border-color 0.3s ease; } .panel-header-error { background: rgba(255, 50, 50, 0.15); border-bottom-color: rgba(255, 80, 80, 0.5); } .panel-header-error .panel-title { color: var(--semantic-critical); } .panel-header-error .panel-count { background: rgba(255, 80, 80, 0.3); color: var(--semantic-critical); } .header-clock { position: absolute; left: 50%; transform: translateX(-50%); font-size: 11px; font-family: var(--font-mono); color: var(--text-secondary); letter-spacing: 0.5px; pointer-events: none; text-transform: uppercase; } .panel-header-left { display: flex; align-items: center; gap: 8px; } .panel-title { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 1px; color: var(--text); } .panel-count { font-size: 10px; color: var(--text-dim); background: var(--border); padding: 2px 6px; border-radius: 2px; transition: color 0.3s ease, background 0.3s ease; } .panel-count.bump { animation: count-bump 0.5s ease-out; } @keyframes count-bump { 0% { transform: scale(1); background: var(--border); color: var(--text-dim); } 40% { transform: scale(1.3); background: var(--accent); color: var(--bg); } 100% { transform: scale(1); background: var(--border); color: var(--text-dim); } } .panel-data-badge { font-size: 9px; letter-spacing: 0.4px; padding: 2px 6px; border-radius: 10px; border: 1px solid transparent; color: var(--text); } .panel-data-badge.live { color: var(--status-live); border-color: rgba(86, 217, 130, 0.45); background: rgba(86, 217, 130, 0.12); } .panel-data-badge.cached { color: var(--semantic-elevated); border-color: rgba(245, 191, 89, 0.45); background: rgba(245, 191, 89, 0.12); } .panel-data-badge.unavailable { color: var(--semantic-critical); border-color: rgba(255, 139, 139, 0.45); background: rgba(255, 139, 139, 0.12); } /* Panel Summarize Button */ .panel-summarize-btn { background: var(--overlay-medium); border: 1px solid var(--overlay-medium); border-radius: 3px; cursor: pointer; font-size: 11px; padding: 2px 6px; margin-right: 6px; opacity: 0.85; transition: opacity 0.15s, transform 0.15s, background 0.15s; } .panel-summarize-btn:hover { opacity: 1; background: var(--overlay-medium); transform: scale(1.05); } .panel-summarize-btn:disabled { cursor: wait; opacity: 0.4; } .panel-summarize-spinner { display: inline-block; width: 10px; height: 10px; border: 1.5px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.8s linear infinite; } /* Panel Summary Container */ .panel-summary { margin: 8px; padding: 10px; background: linear-gradient(135deg, rgba(68, 136, 255, 0.08), rgba(136, 68, 255, 0.08)); border-radius: 6px; border-left: 3px solid var(--accent); font-size: 11px; line-height: 1.5; max-height: 100px; overflow-y: auto; flex-shrink: 0; } .panel-summary-content { display: flex; align-items: flex-start; gap: 8px; } .panel-summary-text { flex: 1; color: var(--text); } .panel-summary-close { background: transparent; border: none; color: var(--text-dim); cursor: pointer; font-size: 14px; padding: 0 4px; line-height: 1; opacity: 0.6; } .panel-summary-close:hover { opacity: 1; color: var(--text); } .panel-summary-loading { color: var(--text-dim); font-style: italic; } .panel-summary-error { color: var(--accent-red); } .panel-info-wrapper { position: relative; display: inline-flex; } .panel-info-btn { width: 14px; height: 14px; border-radius: 50%; border: 1px solid var(--text-dim); background: transparent; color: var(--text-dim); font-size: 9px; font-weight: 600; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; transition: all 0.15s ease; } .panel-info-btn:hover { border-color: var(--accent); color: var(--accent); background: rgba(0, 200, 255, 0.1); } .panel-info-tooltip { position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%); background: var(--border-subtle); border: 1px solid var(--border-strong); border-radius: 4px; padding: 10px 12px; font-size: 11px; line-height: 1.5; color: var(--text); min-width: 220px; max-width: 300px; z-index: 1000; box-shadow: 0 4px 16px var(--shadow-color); opacity: 0; visibility: hidden; transition: opacity 0.15s ease, visibility 0.15s ease; } .panel-info-tooltip.visible { opacity: 1; visibility: visible; } .panel-info-tooltip::before { content: ''; position: absolute; top: -6px; left: 50%; transform: translateX(-50%); border: 6px solid transparent; border-bottom-color: var(--border-strong); } .panel-info-tooltip::after { content: ''; position: absolute; top: -4px; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-bottom-color: var(--border-subtle); } .panel-info-tooltip strong { color: var(--accent); display: block; margin-bottom: 4px; } .panel-info-tooltip ul { margin: 6px 0 0; padding-left: 14px; } .panel-info-tooltip li { margin: 2px 0; color: var(--text-dim); } .panel-content { flex: 1; overflow-y: auto; padding: 8px; min-width: 0; } .panel-content::-webkit-scrollbar { width: 4px; } .panel-content::-webkit-scrollbar-track { background: transparent; } .panel-content::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; } /* Wide panel (spans 2 columns and 2 rows for video content) */ .panel-wide { grid-column: span 2; grid-row: span 2; min-height: 350px; max-height: none; } /* Live News Panel */ .live-news-toolbar { display: flex; justify-content: space-between; align-items: flex-start; gap: 4px; padding: 6px 8px; background: var(--darken-heavy); border-bottom: 1px solid var(--border); flex-shrink: 0; } .live-news-toolbar .live-news-switcher { flex: 1; min-width: 0; } .live-news-switcher { display: flex; flex-wrap: wrap; gap: 4px; padding: 0; background: transparent; border: none; min-width: 0; } .live-channel-btn { padding: 4px 8px; background: transparent; border: 1px solid var(--border); color: var(--text-dim); font-family: inherit; font-size: 10px; cursor: pointer; transition: all 0.2s; text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap; } .live-channel-btn:hover { border-color: var(--text-dim); color: var(--text); } .live-channel-btn.active { background: var(--red); border-color: var(--red); color: white; } .live-channel-btn.loading { opacity: 0.6; pointer-events: none; } .live-channel-btn.loading::after { content: '...'; animation: loadingDots 1s infinite; } .live-channel-btn.offline { opacity: 0.5; border-style: dashed; } .live-channel-btn { cursor: grab; } .live-channel-btn.live-channel-dragging { opacity: 0.6; cursor: grabbing; } /* Live News – Channel settings button (same style as webcam view buttons) */ .live-news-settings-btn { padding: 4px 8px; background: transparent; border: 1px solid var(--border); color: var(--text-dim); font-family: inherit; font-size: 10px; cursor: pointer; transition: all 0.2s; display: flex; align-items: center; justify-content: center; flex-shrink: 0; align-self: flex-start; } .live-news-settings-btn:hover { border-color: var(--text-dim); color: var(--text); } /* Channel management list: same layout as LIVE panel channel switcher */ .live-news-manage-list { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; } /* Each row = same style as .live-channel-btn */ .live-news-manage-row { display: inline-flex; align-items: center; gap: 4px; padding: 6px 12px; background: transparent; border: 1px solid var(--border); color: var(--text-dim); font-family: inherit; font-size: 12px; text-transform: uppercase; letter-spacing: 0.75px; white-space: nowrap; cursor: grab; transition: all 0.2s; } .live-news-manage-row:active { cursor: grabbing; } .live-news-manage-row:hover { border-color: var(--text-dim); color: var(--text); } .live-news-manage-row-dragging { opacity: 0.6; cursor: grabbing; } .live-news-manage-remove { padding: 4px 8px; font-size: 10px; min-height: auto; color: var(--red); background: transparent; border: 1px solid var(--border); cursor: pointer; border-radius: 0; text-transform: uppercase; letter-spacing: 0.5px; } .live-news-manage-remove:hover { text-decoration: underline; border-color: var(--red); } .live-news-manage-remove-in-form { font-weight: 600; border-color: var(--red); color: var(--red); } .live-news-manage-remove-in-form:hover { background: rgba(255, 80, 80, 0.15); } .live-news-manage-row-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; } .live-news-manage-row-remove-x { display: none; font-size: 10px; color: var(--text-faint); cursor: pointer; padding: 0 2px; line-height: 1; transition: color 0.15s; } .live-news-manage-row:hover .live-news-manage-row-remove-x { display: inline; } .live-news-manage-row-remove-x:hover { color: var(--red); } .live-news-manage-edit { padding: 4px 8px; font-size: 10px; min-height: auto; color: var(--text-dim); background: transparent; border: 1px solid var(--border); cursor: pointer; border-radius: 0; text-transform: uppercase; letter-spacing: 0.5px; } .live-news-manage-edit:hover { color: var(--text); border-color: var(--text-dim); } .live-news-manage-row-editing { cursor: default; flex-wrap: wrap; gap: 8px; padding: 8px 10px; background: transparent; border: 1px solid var(--border); white-space: normal; } .live-news-manage-row-editing .live-news-manage-edit-handle, .live-news-manage-row-editing .live-news-manage-edit-name { padding: 10px 12px; font-size: 14px; min-width: 160px; min-height: 40px; background: var(--bg); border: 1px solid var(--border); color: var(--text); border-radius: 4px; } .live-news-manage-save, .live-news-manage-cancel { padding: 8px 16px; font-size: 13px; min-height: 40px; border: 1px solid var(--border); cursor: pointer; background: var(--bg); color: var(--text); border-radius: 4px; } .live-news-manage-save:hover { border-color: var(--green); color: var(--green); } .live-news-manage-cancel:hover { border-color: var(--text-dim); } .live-news-manage-add-section { display: flex; flex-direction: column; gap: 10px; } .live-news-manage-add-title { font-size: 14px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; color: var(--text); } .live-news-manage-add { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; } .live-news-manage-add-field { display: flex; flex-direction: column; gap: 4px; } .live-news-manage-add-label { font-size: 12px; font-weight: 600; color: var(--text); } .live-news-manage-handle, .live-news-manage-name { padding: 10px 12px; font-size: 14px; min-height: 44px; width: 200px; max-width: 100%; background: var(--bg); border: 1px solid var(--border); color: var(--text); border-radius: 4px; } .live-news-manage-handle.invalid { border-color: #f44; box-shadow: 0 0 0 1px rgba(255, 68, 68, 0.3); } .live-news-manage-add-btn { padding: 10px 18px; font-size: 14px; min-height: 44px; background: var(--border); border: 1px solid var(--border); color: var(--text); cursor: pointer; border-radius: 4px; } .live-news-manage-add-btn:hover { background: var(--text-dim); color: var(--bg); } /* Standalone live channels window (?live-channels=1) */ .live-channels-window-shell { min-height: 100vh; display: flex; flex-direction: column; background: var(--bg); color: var(--text); } .live-channels-window-header { display: flex; justify-content: space-between; align-items: center; padding: 8px 14px; border-bottom: 1px solid var(--border); background: var(--darken-heavy); flex-shrink: 0; } .live-channels-window-shell .modal-close { padding: 10px 14px; font-size: 20px; min-width: 44px; min-height: 44px; border-radius: 4px; } .live-channels-window-toolbar { margin-bottom: 4px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; } .live-news-manage-restore-defaults { padding: 8px 14px; font-size: 13px; min-height: 40px; color: var(--text-dim); background: transparent; border: 1px solid var(--border); cursor: pointer; border-radius: 4px; } .live-news-manage-restore-defaults:hover { color: var(--text); border-color: var(--text-dim); } .live-channels-window-title { font-size: 14px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; } .live-channels-window-content { padding: 10px 14px; flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 8px; } .live-channels-window-shell .live-news-manage-list { min-height: 0; overflow-y: auto; align-content: flex-start; } .live-channels-window-shell .live-news-manage-add-section { margin-top: 20px; } /* Channel management modal overlay */ .live-channels-modal-overlay { position: fixed; inset: 0; z-index: 9999; background: rgba(0, 0, 0, 0.6); display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.15s ease; } .live-channels-modal-overlay.active { opacity: 1; } .live-channels-modal { position: relative; width: 680px; max-width: 95vw; max-height: 85vh; overflow-y: auto; background: var(--bg); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); } .live-channels-modal .live-channels-window-shell { min-height: auto; } .live-channels-modal-close { position: absolute; top: 8px; right: 8px; z-index: 1; background: transparent; border: none; color: var(--text-dim); font-size: 22px; cursor: pointer; padding: 4px 10px; border-radius: 4px; line-height: 1; } .live-channels-modal-close:hover { color: var(--text); background: var(--darken); } /* Available channels section */ .live-news-manage-available-section { border-top: 1px solid var(--border); padding-top: 8px; margin-top: 4px; } .live-news-manage-available-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; gap: 16px; } .live-news-manage-available-header .live-news-manage-add-title { margin-bottom: 0; } .live-news-manage-search-wrap { position: relative; flex: 1; max-width: 240px; } .live-news-manage-search-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--text-dim); pointer-events: none; display: flex; align-items: center; opacity: 0.6; } .live-news-manage-search-input { width: 100%; padding: 6px 12px 6px 32px; background: var(--darken-heavy); border: 1px solid var(--border); border-radius: 4px; color: var(--text); font-size: 13px; outline: none; transition: border-color 0.2s, box-shadow 0.2s; } .live-news-manage-search-input:focus { border-color: var(--text-dim); background: var(--bg); } .live-news-manage-search-input::placeholder { color: var(--text-dim); } .live-news-manage-empty { padding: 30px 10px; text-align: center; color: var(--text-dim); font-size: 14px; background: var(--darken); border: 1px dashed var(--border); border-radius: 6px; margin-top: 4px; } /* Tab bar */ .live-news-manage-tab-bar { display: flex; gap: 0; border-bottom: 1px solid var(--border); margin-bottom: 8px; overflow-x: auto; } .live-news-manage-tab-bar::-webkit-scrollbar { display: none; } .live-news-manage-tab-btn { font-family: inherit; font-size: 10px; text-transform: uppercase; letter-spacing: 0.75px; padding: 6px 10px; background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-faint); cursor: pointer; white-space: nowrap; transition: all 0.15s; } .live-news-manage-tab-btn:hover { color: var(--text-dim); } .live-news-manage-tab-btn.active { color: var(--text); border-bottom-color: var(--text); } /* Tab content panels */ .live-news-manage-tab-content { display: none; } .live-news-manage-tab-content.active { display: block; } /* 2-column card grid */ .live-news-manage-card-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; } /* Channel card */ .live-news-manage-card { display: flex; align-items: center; gap: 8px; padding: 10px; background: var(--surface); border: 1px solid var(--border); cursor: pointer; transition: all 0.15s; } .live-news-manage-card:hover { border-color: var(--text-faint); background: var(--surface-hover); } .live-news-manage-card.added { border-color: rgba(68, 255, 136, 0.3); background: rgba(68, 255, 136, 0.05); cursor: pointer; } .live-news-manage-card.added:hover { border-color: rgba(255, 80, 80, 0.5); background: rgba(255, 80, 80, 0.08); } .live-news-manage-card:active { transform: scale(0.97); } /* Card icon (initials) */ .live-news-manage-card-icon { width: 28px; height: 28px; border-radius: 4px; background: var(--surface-hover); border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 700; color: var(--text-dim); flex-shrink: 0; text-transform: uppercase; } /* Card text */ .live-news-manage-card-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; } .live-news-manage-card-name { font-size: 11px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .live-news-manage-card-handle { font-size: 9px; color: var(--text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* Add/check indicator */ .live-news-manage-card-action { font-size: 14px; color: var(--text-faint); flex-shrink: 0; transition: color 0.15s; } .live-news-manage-card:hover .live-news-manage-card-action { color: var(--green); } .live-news-manage-card.added .live-news-manage-card-action { color: var(--green); } .live-news-manage-card:hover .live-news-manage-card-action { color: var(--green); } .live-news-manage-card.added .live-news-manage-card-action { color: var(--green); } .live-news-manage-card.added:hover .live-news-manage-card-action { color: var(--red); } /* Tab count badge */ .live-news-manage-tab-count { font-size: 9px; color: var(--text-faint); margin-left: 4px; } .live-offline { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; min-height: 200px; color: var(--text-dim); text-align: center; gap: 8px; } .live-offline .offline-icon { font-size: 32px; opacity: 0.5; } .live-offline .offline-text { font-size: 12px; } .live-offline .offline-retry { margin-top: 8px; padding: 6px 12px; background: var(--panel-bg); border: 1px solid var(--border); color: var(--text); font-size: 11px; cursor: pointer; border-radius: 4px; } .live-offline .offline-retry:hover { border-color: var(--text-dim); } .bot-check-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 4px; } .bot-check-actions .bot-check-signin { background: var(--accent, #4a9eff); border-color: var(--accent, #4a9eff); color: #fff; } @keyframes loadingDots { 0%, 20% { content: '.'; } 40% { content: '..'; } 60%, 100% { content: '...'; } } .live-mute-btn { background: transparent; border: none; color: var(--text-dim); cursor: pointer; padding: 4px; display: flex; align-items: center; justify-content: center; transition: color 0.2s; } .live-mute-btn:hover { color: var(--text); } .live-mute-btn.unmuted { color: var(--green); } .live-news-fullscreen { position: fixed !important; top: 0 !important; left: 0 !important; width: 100vw !important; height: 100vh !important; z-index: 10000 !important; border-radius: 0 !important; margin: 0 !important; } .live-news-fullscreen .panel-content, .live-news-fullscreen .map-container { height: calc(100vh - 80px) !important; } .live-news-fullscreen .live-news-player, .live-news-fullscreen .live-news-native-video, .live-news-fullscreen .live-news-embed-frame { height: 100% !important; } body.live-news-fullscreen-active { overflow: hidden; } body.live-news-fullscreen-active .time-slider, body.live-news-fullscreen-active .deckgl-layer-toggles, body.live-news-fullscreen-active .map-legend, body.live-news-fullscreen-active .map-controls, body.live-news-fullscreen-active .map-timestamp, body.live-news-fullscreen-active .map-bottom-grid, body.live-news-fullscreen-active .map-resize-handle { visibility: hidden !important; pointer-events: none !important; } body.live-news-fullscreen-active .community-widget { display: none; } /* Hide map overlays and sibling panels behind fullscreen panel (#829, #859) */ body.live-news-fullscreen-active .layer-toggles, body.live-news-fullscreen-active .map-legend { display: none !important; } body.live-news-fullscreen-active .panels-grid > *:not(.live-news-fullscreen) { visibility: hidden !important; } .live-indicator-btn { background: transparent; border: none; color: var(--text); cursor: pointer; padding: 4px 8px; display: flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; transition: opacity 0.2s; } .live-indicator-btn:hover { opacity: 0.8; } .live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--red); animation: live-blink 1.5s ease-in-out infinite; } .live-dot.paused { background: var(--text-dim); animation: none; } .live-indicator-btn.paused { color: var(--text-dim); } @keyframes live-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } } #live-news .panel-content { padding: 0; flex: 1; display: flex; } .live-news-player { width: 100%; flex: 1; background: var(--bg); aspect-ratio: 16 / 9; } .live-news-player iframe { width: 100%; height: 100%; display: block; } /* Live Webcams Panel */ .panel[data-panel="live-webcams"] .panel-content { padding: 0; flex: 1; display: flex; flex-direction: column; overflow: hidden; } .webcam-content { overflow: hidden !important; } .webcam-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 4px; padding: 6px 8px; background: var(--darken-heavy); border-bottom: 1px solid var(--border); flex-shrink: 0; } .webcam-toolbar-group { display: flex; gap: 4px; } .webcam-region-btn, .webcam-view-btn { padding: 4px 8px; background: transparent; border: 1px solid var(--border); color: var(--text-dim); font-family: inherit; font-size: 10px; cursor: pointer; transition: all 0.2s; text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap; display: flex; align-items: center; justify-content: center; } .webcam-region-btn:hover, .webcam-view-btn:hover { border-color: var(--text-dim); color: var(--text); } .webcam-region-btn.active { background: var(--red); border-color: var(--red); color: white; } .webcam-view-btn.active { background: var(--red); border-color: var(--red); color: white; } .webcam-grid { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 2px; flex: 1; min-height: 0; height: 0; background: #000; overflow: hidden; } .webcam-cell { position: relative; overflow: hidden; cursor: pointer; background: #000; min-height: 0; height: 100%; } .webcam-cell:hover .webcam-cell-label { opacity: 1; } .webcam-cell-label { position: absolute; top: 0; left: 0; right: 0; padding: 6px 10px; background: linear-gradient(180deg, rgba(0, 0, 0, 0.8) 0%, transparent 100%); display: flex; align-items: center; gap: 6px; z-index: 2; opacity: 0.85; transition: opacity 0.2s; pointer-events: none; } .webcam-expand-btn { pointer-events: auto; margin-left: auto; background: rgba(0, 0, 0, 0.5); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 3px; color: #fff; padding: 2px 4px; cursor: pointer; opacity: 0; transition: opacity 0.2s; line-height: 1; } .webcam-cell:hover .webcam-expand-btn { opacity: 0.7; } .webcam-expand-btn:hover { opacity: 1 !important; background: rgba(255, 255, 255, 0.15); } .webcam-city { font-family: var(--font-mono); font-size: 10px; font-weight: 700; color: #fff; letter-spacing: 1px; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8); } .webcam-live-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--red); animation: live-blink 1.5s ease-in-out infinite; flex-shrink: 0; } .webcam-iframe { width: 100%; height: 100%; border: 0; display: block; pointer-events: auto; } .webcam-single { position: relative; flex: 1; background: #000; aspect-ratio: 16 / 9; } .webcam-embed-fallback { position: absolute; inset: 0; z-index: 3; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 16px; text-align: center; background: rgba(0, 0, 0, 0.78); backdrop-filter: blur(2px); } .webcam-embed-fallback-text { color: var(--text); font-size: 12px; max-width: 280px; } .webcam-embed-fallback-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; } .webcam-embed-fallback .offline-retry { margin: 0; } .webcam-switcher { display: flex; gap: 4px; padding: 6px 8px; background: var(--darken-heavy); border-top: 1px solid var(--border); flex-shrink: 0; flex-wrap: wrap; } .webcam-feed-btn { padding: 4px 8px; background: transparent; border: 1px solid var(--border); color: var(--text-dim); font-family: inherit; font-size: 10px; cursor: pointer; transition: all 0.2s; text-transform: uppercase; letter-spacing: 0.5px; } .webcam-feed-btn:hover { border-color: var(--text-dim); color: var(--text); } .webcam-feed-btn.active { background: var(--red); border-color: var(--red); color: white; } .webcam-back-btn { display: flex; align-items: center; gap: 4px; border-color: var(--text-dim); margin-inline-end: 4px; } .webcam-placeholder { display: flex; align-items: center; justify-content: center; height: 100%; min-height: 200px; color: var(--text-dim); font-size: 12px; } @media (max-width: 768px) { .webcam-grid { grid-template-columns: 1fr; grid-template-rows: auto; } .webcam-grid .webcam-cell:nth-child(n+3) { display: none; } .webcam-view-btn { display: none; } } /* Mobile: make toolbars swipeable (horizontal scroll) */ @media (max-width: 768px) { /* Live News channels */ .live-news-switcher { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; touch-action: pan-x; padding-bottom: 2px; } .live-news-switcher::-webkit-scrollbar { display: none; } .live-news-switcher { scrollbar-width: none; } .live-channel-btn { scroll-snap-align: start; flex: 0 0 auto; } /* Webcams regions */ .webcam-toolbar { align-items: flex-start; } .webcam-toolbar-group { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; touch-action: pan-x; min-width: 0; flex-wrap: nowrap; } .webcam-toolbar-group::-webkit-scrollbar { display: none; } .webcam-toolbar-group { scrollbar-width: none; } .webcam-region-btn { scroll-snap-align: start; flex: 0 0 auto; } } /* News Items */ .item { padding: 8px 0; border-bottom: 1px solid var(--border); } .item:last-child { border-bottom: none; } .item.alert { border-left: 2px solid var(--red); padding-left: 8px; margin-left: -8px; } .item-source { font-size: 9px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; display: flex; align-items: center; gap: 6px; } .alert-tag { background: var(--red); color: var(--bg); padding: 1px 4px; font-size: 8px; font-weight: bold; animation: pulse-alert 1s infinite; } .lang-badge { display: inline-block; padding: 1px 4px; border-radius: 2px; background: var(--surface-light); color: var(--text-dim); font-size: 8px; font-weight: 500; margin-inline-start: 6px; border: 1px solid var(--border); vertical-align: middle; line-height: normal; } @keyframes pulse-alert { 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } } /* CII Share button */ .cii-share-btn { background: none; border: 1px solid var(--border); color: var(--text-muted); font-size: 12px; cursor: pointer; padding: 1px 4px; border-radius: 3px; margin-left: auto; transition: color 0.2s, border-color 0.2s; } .cii-share-btn:hover { color: var(--semantic-info); border-color: var(--semantic-info); } /* Toast */ .toast-notification { position: fixed; bottom: 32px; left: 50%; transform: translateX(-50%) translateY(20px); background: var(--surface-active); color: var(--text-secondary); padding: 10px 20px; border-radius: 8px; border: 1px solid var(--border); font-size: 13px; z-index: 10002; opacity: 0; transition: opacity 0.3s, transform 0.3s; pointer-events: none; } .toast-notification.visible { opacity: 1; transform: translateX(-50%) translateY(0); } /* Story Modal */ .story-modal-overlay { position: fixed; inset: 0; z-index: 10001; background: var(--bg); display: flex; flex-direction: column; align-items: center; justify-content: center; backdrop-filter: blur(8px); } .story-modal { position: relative; display: flex; flex-direction: column; align-items: center; gap: 20px; max-height: 95vh; } .story-close-x { position: absolute; top: -44px; right: -4px; background: var(--overlay-medium); border: none; color: var(--text-dim); width: 36px; height: 36px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.2s, color 0.2s; z-index: 1; } .story-close-x:hover { background: var(--overlay-medium); color: var(--accent); } .story-modal-content { max-height: 75vh; overflow: auto; border-radius: 14px; box-shadow: 0 12px 48px var(--shadow-color), 0 0 0 1px var(--overlay-light); } .story-image { display: block; max-height: 75vh; width: auto; border-radius: 14px; } .story-loading, .story-error { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 60px 40px; color: var(--text-dim); font-size: 14px; } .story-spinner { width: 32px; height: 32px; border: 3px solid var(--border); border-top-color: var(--semantic-info); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .story-error { color: var(--threat-critical); } .story-share-bar { display: flex; gap: 6px; background: var(--overlay-light); padding: 8px 12px; border-radius: 16px; border: 1px solid var(--overlay-light); } .story-share-btn { display: flex; flex-direction: column; align-items: center; gap: 4px; background: none; border: none; color: var(--text-dim); padding: 10px 16px; border-radius: 12px; cursor: pointer; font-size: 11px; font-family: inherit; transition: background 0.2s, color 0.2s; } .story-share-btn:hover { background: var(--overlay-medium); color: var(--accent); } .story-share-btn svg { flex-shrink: 0; } .story-share-btn.story-save:hover { color: var(--semantic-info); } .story-share-btn.story-whatsapp:hover { color: var(--semantic-normal); } .story-share-btn.story-twitter:hover { color: var(--accent); } .story-share-btn.story-linkedin:hover { color: var(--semantic-info); } .story-share-btn.story-copy:hover { color: var(--threat-medium); } .country-intel-share-btn { background: none; border: 1px solid #ff444440; color: var(--semantic-critical); font-size: 16px; cursor: pointer; padding: 2px 8px; border-radius: 4px; margin-left: auto; transition: background 0.2s; } .country-intel-share-btn:hover { background: rgba(255, 68, 68, 0.15); } .category-tag { font-size: 8px; padding: 1px 5px; border-radius: 3px; font-weight: 600; border: 1px solid; text-transform: uppercase; letter-spacing: 0.3px; } .item-title { color: var(--text); text-decoration: none; font-size: 12px; line-height: 1.4; display: block; } .item-title:hover { color: var(--accent); } .item-time { font-size: 9px; color: var(--text-dim); margin-top: 4px; } /* Clustering */ .source-count { background: var(--accent); color: var(--bg); padding: 1px 5px; font-size: 8px; font-weight: bold; border-radius: 8px; } .cluster-meta { display: flex; align-items: center; justify-content: space-between; margin-top: 4px; gap: 8px; } .top-sources { display: flex; gap: 4px; flex-wrap: wrap; } .top-source { font-size: 8px; padding: 1px 4px; border-radius: 2px; background: var(--panel-border); color: var(--text-dim); } .top-source.tier-1 { background: rgba(0, 255, 136, 0.15); color: var(--green); } .top-source.tier-2 { background: rgba(0, 170, 255, 0.15); color: var(--accent); } .top-source.tier-3 { background: rgba(255, 170, 0, 0.15); color: var(--yellow); } /* Source credibility tier badge */ .tier-badge { font-size: 9px; font-weight: 600; padding: 1px 5px; border-radius: 3px; margin-right: 4px; letter-spacing: 0.3px; } .tier-badge.tier-1 { background: linear-gradient(135deg, rgba(0, 255, 136, 0.25), rgba(0, 200, 100, 0.15)); color: var(--green); border: 1px solid rgba(0, 255, 136, 0.4); } .tier-badge.tier-2 { background: rgba(0, 170, 255, 0.15); color: var(--accent); border: 1px solid rgba(0, 170, 255, 0.3); } /* "Also reported by" label */ .also-reported { font-size: 8px; color: var(--text-dim); margin-right: 4px; font-style: italic; } /* Enhanced tier indicators for top sources */ .top-source.tier-1 { font-weight: 500; border: 1px solid rgba(0, 255, 136, 0.3); } .top-source.tier-2 { border: 1px solid rgba(0, 170, 255, 0.2); } .item.clustered { border-left: 2px solid var(--border); padding-left: 8px; margin-left: -8px; } .item.clustered.alert { border-left: 2px solid var(--red); } .item.clustered:hover { border-left-color: var(--accent); } /* Related assets */ .related-assets { margin-top: 8px; padding: 8px; border-radius: 8px; background: var(--bg); border: 1px solid rgba(0, 255, 170, 0.2); } .related-assets-header { font-size: 9px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.6px; display: flex; gap: 6px; align-items: center; margin-bottom: 6px; } .related-assets-range { color: var(--accent); } .related-assets-list { display: flex; flex-direction: column; gap: 6px; } .related-asset { display: grid; grid-template-columns: auto 1fr auto; gap: 6px; align-items: center; padding: 6px 8px; border-radius: 6px; background: var(--bg); border: 1px solid rgba(0, 255, 170, 0.15); color: var(--text); cursor: pointer; text-align: left; } .related-asset:hover { border-color: rgba(0, 255, 170, 0.5); box-shadow: 0 0 10px rgba(0, 255, 170, 0.2); } .related-asset-type { font-size: 8px; text-transform: uppercase; color: var(--accent); letter-spacing: 0.4px; } .related-asset-name { font-size: 10px; color: var(--text); } .related-asset-distance { font-size: 9px; color: var(--text-dim); } /* Velocity */ .velocity-badge { font-size: 8px; padding: 1px 5px; border-radius: 8px; font-weight: bold; } .velocity-badge.elevated { background: rgba(255, 170, 0, 0.2); color: var(--yellow); } .velocity-badge.spike { background: rgba(var(--semantic-critical), 0.2); color: var(--red); animation: pulse-velocity 1.5s infinite; } @keyframes pulse-velocity { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } /* Sentiment */ .sentiment-badge { font-size: 9px; padding: 0 3px; } .sentiment-badge.negative { color: var(--red); } .sentiment-badge.positive { color: var(--green); } /* Deviation indicators */ .deviation-indicator { font-size: 9px; font-weight: bold; margin-left: 8px; padding: 1px 6px; border-radius: 8px; } .deviation-indicator.elevated { background: rgba(255, 170, 0, 0.2); color: var(--yellow); } .deviation-indicator.spike { background: rgba(var(--semantic-critical), 0.2); color: var(--red); animation: pulse-alert 1s infinite; } .deviation-indicator.quiet { background: var(--overlay-heavy); color: var(--text-dim); } /* Signal Modal */ .signal-modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: var(--bg); display: none; justify-content: center; align-items: center; z-index: 9999; } .signal-modal-overlay.active { display: flex; } .signal-modal { background: var(--bg); border: 1px solid var(--accent); border-radius: 4px; width: 90%; max-width: 500px; max-height: 80vh; overflow: hidden; box-shadow: 0 0 30px rgba(0, 170, 255, 0.3); animation: signal-pulse 0.5s ease-out; will-change: transform, opacity; } @keyframes signal-pulse { 0% { transform: scale(0.9); opacity: 0; } 50% { transform: scale(1.02); } 100% { transform: scale(1); opacity: 1; } } .signal-modal-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; background: var(--accent); color: var(--bg); } .signal-modal-title { font-weight: bold; font-size: 14px; letter-spacing: 1px; } .signal-modal-close { background: none; border: none; color: var(--bg); font-size: 20px; cursor: pointer; padding: 0 4px; } .signal-modal-content { padding: 16px; max-height: 400px; overflow-y: auto; } .signal-item { padding: 12px; margin-bottom: 12px; background: var(--darken-heavy); border-left: 3px solid var(--accent); border-radius: 2px; } .signal-item:last-child { margin-bottom: 0; } .signal-item.velocity_spike { border-left-color: var(--red); } .signal-item.keyword_spike { border-left-color: var(--semantic-high); } .signal-item.prediction_leads_news { border-left-color: var(--yellow); } .signal-item.silent_divergence { border-left-color: var(--green); } .signal-item.convergence { border-left-color: var(--defcon-4); } .signal-item.triangulation { border-left-color: var(--semantic-high); } .signal-item.flow_drop { border-left-color: var(--semantic-info); } .signal-item.flow_price_divergence { border-left-color: var(--semantic-normal); } .signal-type { font-size: 10px; text-transform: uppercase; color: var(--text-dim); margin-bottom: 4px; } .signal-title { font-weight: bold; font-size: 13px; color: var(--text); margin-bottom: 6px; } .signal-description { font-size: 12px; color: var(--text); line-height: 1.4; margin-bottom: 8px; } .signal-actions { margin-top: 8px; } .suppress-keyword-btn { border: 1px solid rgba(255, 140, 66, 0.5); background: rgba(255, 140, 66, 0.12); color: var(--semantic-high); font-size: 11px; padding: 4px 8px; border-radius: 4px; cursor: pointer; } .suppress-keyword-btn:hover { background: rgba(255, 140, 66, 0.2); } .signal-meta { display: flex; gap: 12px; font-size: 10px; color: var(--text-dim); } .signal-confidence { color: var(--accent); } .signal-topics { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 8px; } .signal-topic { font-size: 9px; padding: 2px 6px; background: rgba(0, 170, 255, 0.15); color: var(--accent); border-radius: 8px; } .signal-modal-footer { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-top: 1px solid var(--panel-border); } .signal-audio-toggle { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-dim); cursor: pointer; } .signal-dismiss-btn { background: var(--accent); border: none; color: var(--bg); padding: 6px 16px; font-size: 11px; cursor: pointer; border-radius: 2px; text-transform: uppercase; letter-spacing: 0.5px; } .signal-dismiss-btn:hover { opacity: 0.9; } /* Header flash for signals */ .header.signal-flash { animation: header-flash 0.5s ease-out 3; } @keyframes header-flash { 0%, 100% { background: var(--panel-bg); } 50% { background: rgba(0, 170, 255, 0.3); } } /* Playback Control */ .playback-control { position: relative; } .playback-toggle { background: var(--panel-bg); border: 1px solid var(--panel-border); color: var(--text-dim); padding: 4px 8px; font-size: 12px; cursor: pointer; border-radius: 2px; } .playback-toggle:hover { color: var(--accent); border-color: var(--accent); } .playback-panel { position: absolute; top: 100%; right: 0; margin-top: 8px; background: var(--panel-bg); border: 1px solid var(--accent); border-radius: 4px; width: 280px; z-index: 100; box-shadow: 0 4px 20px var(--shadow-color); } .playback-panel.hidden { display: none; } .playback-header { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; border-bottom: 1px solid var(--panel-border); font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--accent); } .playback-close { background: none; border: none; color: var(--text-dim); font-size: 16px; cursor: pointer; padding: 0; } .playback-slider-container { padding: 12px; } .playback-slider { width: 100%; height: 4px; -webkit-appearance: none; appearance: none; background: var(--panel-border); border-radius: 2px; outline: none; } .playback-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; background: var(--accent); border-radius: 50%; cursor: pointer; } .playback-time { text-align: center; margin-top: 8px; font-size: 12px; color: var(--green); font-weight: bold; } .playback-time.historical { color: var(--yellow); } .playback-controls { display: flex; justify-content: center; gap: 4px; padding: 8px 12px 12px; } .playback-btn { background: var(--panel-border); border: none; color: var(--text); padding: 6px 10px; font-size: 10px; cursor: pointer; border-radius: 2px; } .playback-btn:hover { background: var(--accent); color: var(--bg); } .playback-btn.playback-live { background: var(--green); color: var(--bg); font-weight: bold; } .playback-btn.playback-live.active { background: var(--green); } /* Playback mode indicator */ body.playback-mode .header { border-bottom: 2px solid var(--yellow); } body.playback-mode .status-dot { background: var(--yellow); animation: none; } /* Map */ .map-container { width: 100%; height: 100%; position: relative; overflow: hidden; background: var(--map-bg); /* Let the map library handle all touch gestures (pinch-zoom, pan) instead of the browser intercepting them on mobile/Android */ touch-action: none; } .map-wrapper { width: 100%; height: 100%; transition: transform 0.3s ease; position: relative; transform-origin: 0 0; } .map-cluster-canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; } #mapOverlays { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } #mapOverlays>* { pointer-events: auto; } .map-flash { position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%; background: rgba(0, 255, 170, 0.85); box-shadow: 0 0 14px rgba(0, 255, 170, 0.9); pointer-events: none; animation: mapFlashPulse var(--flash-duration, 2000ms) ease-out forwards; } .map-flash::after { content: ''; position: absolute; inset: -14px; border-radius: 50%; border: 2px solid rgba(0, 255, 170, 0.7); animation: mapFlashRing var(--flash-duration, 2000ms) ease-out forwards; } @keyframes mapFlashPulse { 0% { transform: scale(0.6); opacity: 1; } 100% { transform: scale(2.6); opacity: 0; } } @keyframes mapFlashRing { 0% { transform: scale(0.4); opacity: 0.9; } 100% { transform: scale(3.6); opacity: 0; } } .map-svg { display: block; width: 100%; height: 100%; } .map-controls { position: absolute; top: 10px; right: 10px; display: flex; flex-direction: column; gap: 4px; z-index: 500; pointer-events: auto; } .map-control-btn { width: 28px; height: 28px; background: var(--bg); border: 1px solid var(--border); color: var(--text); font-size: 14px; cursor: pointer; display: flex; align-items: center; justify-content: center; } .map-control-btn:hover { background: var(--border); } .time-slider { position: absolute; top: 10px; left: 10px; display: flex; align-items: center; gap: 8px; z-index: 100; background: var(--bg); padding: 6px 10px; border: 1px solid var(--border); border-radius: 4px; } .time-slider-label { font-size: 9px; color: var(--text-dim); letter-spacing: 1px; font-weight: bold; } .time-slider-buttons { display: flex; gap: 2px; } .time-btn { padding: 3px 6px; background: transparent; border: 1px solid var(--border); color: var(--text-dim); font-family: inherit; font-size: 9px; cursor: pointer; transition: all 0.2s ease; } .time-btn:hover { border-color: var(--primary); color: var(--primary); } .time-btn.active { background: var(--primary); border-color: var(--primary); color: var(--bg); font-weight: bold; } .layer-toggles:not(.deckgl-layer-toggles) { position: absolute; bottom: 10px; left: 10px; display: flex; gap: 4px; flex-wrap: wrap; z-index: 100; max-width: 300px; } .layer-toggles:not(.deckgl-layer-toggles) .layer-toggle { padding: 3px 8px; background: var(--bg); border: 1px solid var(--border); color: var(--text-dim); font-family: inherit; font-size: 9px; cursor: pointer; text-transform: uppercase; position: relative; transition: color 0.2s ease, border-color 0.2s ease, opacity 0.2s ease; } .layer-toggles:not(.deckgl-layer-toggles) .layer-toggle.active { color: var(--green); border-color: var(--green); } .layer-toggles:not(.deckgl-layer-toggles) .layer-toggle.auto-hidden { color: var(--text-dim); border-color: var(--overlay-heavy); } .layer-toggles:not(.deckgl-layer-toggles) .layer-toggle.auto-hidden::after { content: 'AUTO'; position: absolute; top: -6px; right: 2px; font-size: 6px; letter-spacing: 0.4px; color: var(--text-dim); opacity: 0.7; } .layer-toggles:not(.deckgl-layer-toggles) .layer-toggle.loading { animation: layer-loading 0.8s ease-in-out infinite; border-color: var(--yellow); color: var(--yellow); } @keyframes layer-loading { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } .layer-help-btn { width: 20px; height: 20px; padding: 0; background: var(--bg); border: 1px solid var(--border); border-radius: 50%; color: var(--text-dim); font-family: inherit; font-size: 11px; font-weight: bold; cursor: pointer; transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; } .layer-help-btn:hover { color: var(--accent); border-color: var(--accent); background: var(--bg); } .layer-help-popup { position: absolute; bottom: 40px; left: 10px; width: 360px; max-height: 70vh; background: var(--bg); border: 1px solid var(--border); border-radius: 4px; z-index: 200; overflow: hidden; box-shadow: 0 8px 32px var(--shadow-color); } .layer-help-header { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; background: var(--bg); border-bottom: 1px solid var(--border); font-size: 11px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; color: var(--accent); } .layer-help-close { width: 20px; height: 20px; padding: 0; background: transparent; border: none; color: var(--text-dim); font-size: 16px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: color 0.2s; } .layer-help-close:hover { color: var(--accent); } .layer-help-content { padding: 8px; overflow-y: auto; max-height: calc(70vh - 45px); } .layer-help-section { margin-bottom: 12px; } .layer-help-section:last-child { margin-bottom: 4px; } .layer-help-title { font-size: 9px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; color: var(--green); margin-bottom: 6px; padding-left: 4px; border-left: 2px solid var(--green); } .layer-help-item { display: flex; gap: 8px; font-size: 10px; color: var(--text-dim); padding: 4px 6px; line-height: 1.4; } .layer-help-item span { flex-shrink: 0; min-width: 80px; font-weight: bold; color: var(--accent); font-size: 9px; } .layer-help-item:hover { background: var(--overlay-subtle); } .layer-help-note { font-size: 9px; color: var(--yellow); font-style: italic; padding: 2px 6px; margin-top: 2px; opacity: 0.8; } .hotspot { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; pointer-events: auto; cursor: pointer; z-index: 50; } .hotspot-marker { width: 12px; height: 12px; border-radius: 50%; background: var(--yellow); border: 2px solid var(--bg); box-shadow: 0 0 8px var(--yellow); } .hotspot-marker.high { background: var(--red); box-shadow: 0 0 12px var(--red); animation: pulse-red 1s infinite; } .hotspot-marker.elevated { background: var(--yellow); box-shadow: 0 0 10px var(--yellow); } .hotspot-label { position: absolute; top: 16px; left: 50%; transform: translateX(-50%) scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; white-space: nowrap; font-size: 8px; color: var(--text); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); text-transform: uppercase; letter-spacing: 1px; } .hotspot-breaking { position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%); white-space: nowrap; font-size: 7px; font-weight: bold; color: var(--bg); background: var(--red); padding: 1px 4px; letter-spacing: 0.5px; animation: pulse-breaking 0.8s ease-in-out infinite; } @keyframes pulse-breaking { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } @keyframes pulse-red { 0%, 100% { opacity: 0.8; transform: scale(1); } 50% { opacity: 1; transform: scale(1.1); } } /* Cable paths */ .cable-path { fill: none; stroke: var(--status-live); stroke-width: 1.5; opacity: 0.6; filter: drop-shadow(0 0 3px var(--status-live)); cursor: pointer; pointer-events: stroke; transition: all 0.2s ease; } .cable-path:hover { stroke-width: 3; opacity: 1; filter: drop-shadow(0 0 8px var(--status-live)) drop-shadow(0 0 15px var(--status-live)); animation: cable-pulse 0.6s ease-in-out infinite; } .cable-path.cable-fault { stroke: var(--semantic-critical); filter: drop-shadow(0 0 4px var(--semantic-critical)); } .cable-path.cable-degraded { stroke: var(--semantic-elevated); filter: drop-shadow(0 0 4px var(--semantic-elevated)); } .cable-path.cable-health-fault { stroke: #ff3232; stroke-dasharray: 6 3; opacity: 0.9; filter: drop-shadow(0 0 5px #ff3232); animation: cable-health-fault-pulse 1.4s ease-in-out infinite; } .cable-path.cable-health-degraded { stroke: #ffa500; opacity: 0.8; filter: drop-shadow(0 0 4px #ffa500); } @keyframes cable-health-fault-pulse { 0%, 100% { opacity: 0.9; } 50% { opacity: 0.5; } } @keyframes cable-pulse { 0%, 100% { opacity: 1; stroke-width: 3; } 50% { opacity: 0.5; stroke-width: 4; } } /* Pipeline paths */ .pipeline-path { cursor: pointer; pointer-events: stroke; transition: all 0.2s ease; } .pipeline-path.pipeline-oil { filter: drop-shadow(0 0 3px var(--semantic-high)); } .pipeline-path.pipeline-gas { filter: drop-shadow(0 0 3px var(--defcon-4)); } .pipeline-path.pipeline-products { filter: drop-shadow(0 0 3px var(--semantic-elevated)); } .pipeline-path:hover { stroke-width: 4 !important; opacity: 1 !important; } .pipeline-path.pipeline-oil:hover { filter: drop-shadow(0 0 8px var(--semantic-high)) drop-shadow(0 0 15px var(--semantic-high)); } .pipeline-path.pipeline-gas:hover { filter: drop-shadow(0 0 8px var(--defcon-4)) drop-shadow(0 0 15px var(--defcon-4)); } .pipeline-path.pipeline-products:hover { filter: drop-shadow(0 0 8px var(--semantic-elevated)) drop-shadow(0 0 15px var(--semantic-elevated)); } /* Related asset highlights */ .asset-highlight { animation: asset-pulse 1.2s ease-in-out infinite; } .base-marker.asset-highlight, .datacenter-marker.asset-highlight, .nuclear-marker.asset-highlight { z-index: 30; box-shadow: 0 0 12px rgba(0, 255, 170, 0.6); } .pipeline-path.asset-highlight { stroke-width: 4.5 !important; filter: drop-shadow(0 0 10px var(--accent)); animation: asset-pulse-glow 1.2s ease-in-out infinite; } .cable-path.asset-highlight { stroke-width: 3.5; opacity: 1; filter: drop-shadow(0 0 10px rgba(0, 255, 170, 0.8)); animation: asset-pulse-glow 1.2s ease-in-out infinite; } @keyframes asset-pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.05); opacity: 0.7; } } @keyframes asset-pulse-glow { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } /* Pipeline popup header colors */ .popup-header.pipeline.oil { border-bottom-color: var(--semantic-high); } .popup-header.pipeline.gas { border-bottom-color: var(--defcon-4); } .popup-header.pipeline.products { border-bottom-color: var(--semantic-elevated); } /* Cable popup header */ .popup-header.cable { border-bottom-color: var(--status-live); } /* Cable advisory & repair ship markers */ .cable-advisory-marker, .repair-ship-marker { position: absolute; display: flex; flex-direction: column; align-items: center; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; cursor: pointer; z-index: 52; } .cable-advisory-marker.fault { --cable-advisory-color: var(--semantic-critical); animation: cable-advisory-pulse 1.4s ease-in-out infinite; } .cable-advisory-marker.degraded { --cable-advisory-color: var(--semantic-elevated); } .cable-advisory-icon { font-size: 14px; filter: drop-shadow(0 0 6px var(--cable-advisory-color, var(--semantic-critical))); } .cable-advisory-label { font-size: 8px; color: var(--cable-advisory-color, var(--semantic-critical)); text-transform: uppercase; letter-spacing: 0.4px; margin-top: 2px; white-space: nowrap; text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); } .repair-ship-marker { --repair-ship-color: var(--semantic-low); } .repair-ship-marker.on-station { --repair-ship-color: var(--status-live); } .repair-ship-icon { font-size: 14px; filter: drop-shadow(0 0 6px var(--repair-ship-color, var(--semantic-low))); } .repair-ship-label { font-size: 8px; color: var(--repair-ship-color, var(--semantic-low)); text-transform: uppercase; letter-spacing: 0.4px; margin-top: 2px; white-space: nowrap; text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); } @keyframes cable-advisory-pulse { 0%, 100% { opacity: 1; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); } 50% { opacity: 0.7; transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.15)); } } /* Protest / Social Unrest markers */ .protest-marker { position: absolute; display: flex; flex-direction: column; align-items: center; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; cursor: pointer; z-index: 53; --protest-color: var(--semantic-high); } .protest-marker.low { --protest-color: var(--semantic-elevated); } .protest-marker.medium { --protest-color: var(--semantic-high); } .protest-marker.high { --protest-color: var(--semantic-critical); animation: protest-pulse 1.5s ease-in-out infinite; } .protest-marker.riot { --protest-color: var(--semantic-critical); } .protest-marker.validated { filter: drop-shadow(0 0 8px var(--protest-color)); } .protest-icon { font-size: 14px; color: var(--protest-color); filter: drop-shadow(0 0 4px var(--protest-color)); } .protest-label { font-size: 8px; color: var(--protest-color); text-transform: uppercase; letter-spacing: 0.4px; margin-top: 2px; white-space: nowrap; text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); max-width: 80px; overflow: hidden; text-overflow: ellipsis; } .protest-marker.cluster .protest-icon { font-size: 16px; } .protest-marker.cluster .cluster-badge { position: absolute; top: -4px; right: -8px; background: var(--protest-color); color: var(--bg); font-size: 9px; font-weight: bold; padding: 1px 4px; border-radius: 8px; min-width: 14px; text-align: center; box-shadow: 0 1px 3px var(--shadow-color); } @keyframes protest-pulse { 0%, 100% { opacity: 1; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); } 50% { opacity: 0.8; transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.2)); } } /* Datacenter cluster markers */ .datacenter-marker { position: absolute; display: flex; flex-direction: column; align-items: center; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; cursor: pointer; z-index: 54; --datacenter-color: var(--semantic-info); } .datacenter-marker.existing { --datacenter-color: var(--semantic-info); } .datacenter-marker.planned { --datacenter-color: var(--semantic-low); } .datacenter-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.2)); } .datacenter-icon { font-size: 16px; filter: drop-shadow(0 0 6px var(--datacenter-color)); } .datacenter-label { font-size: 8px; color: var(--datacenter-color); text-transform: uppercase; letter-spacing: 0.4px; margin-top: 2px; white-space: nowrap; text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); max-width: 80px; overflow: hidden; text-overflow: ellipsis; } .datacenter-marker.cluster .datacenter-icon { font-size: 20px; } .datacenter-marker.cluster .cluster-badge { position: absolute; top: -4px; right: -8px; background: var(--datacenter-color); color: var(--bg); font-size: 9px; font-weight: bold; padding: 1px 4px; border-radius: 8px; min-width: 14px; text-align: center; box-shadow: 0 1px 3px var(--shadow-color); } /* Popup styles for datacenter clusters */ .popup-header.datacenter.cluster { background: linear-gradient(90deg, #9966ff40 0%, transparent 100%); border-left: 3px solid var(--semantic-info); } /* Popup styles for protests */ .popup-header.protest { background: linear-gradient(90deg, var(--protest-color, var(--semantic-high)) 0%, transparent 100%); } .popup-header.protest.high { --protest-color: var(--semantic-critical); } .popup-header.protest.medium { --protest-color: var(--semantic-high); } .popup-header.protest.low { --protest-color: var(--semantic-elevated); } .popup-icon { font-size: 16px; margin-right: 6px; } .popup-badge.verified { background: var(--semantic-normal); color: var(--bg); } .popup-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; } .popup-tag { background: var(--panel-bg); border: 1px solid var(--border); border-radius: 3px; padding: 2px 6px; font-size: 9px; text-transform: uppercase; color: var(--text-muted); } .popup-related { margin-top: 8px; font-size: 10px; color: var(--text-muted); font-style: italic; } .stat-value.alert { color: var(--semantic-critical); font-weight: bold; } /* Internet Outage markers */ .outage-marker { position: absolute; display: flex; flex-direction: column; align-items: center; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; cursor: pointer; z-index: 51; } .outage-marker.partial { --outage-color: var(--semantic-elevated); } .outage-marker.major { --outage-color: var(--semantic-high); } .outage-marker.total { --outage-color: var(--semantic-critical); animation: outage-pulse 1.5s ease-in-out infinite; } .outage-icon { font-size: 14px; filter: drop-shadow(0 0 4px var(--outage-color, var(--semantic-elevated))); } .outage-label { font-size: 8px; color: var(--outage-color, var(--semantic-elevated)); white-space: nowrap; text-transform: uppercase; letter-spacing: 0.5px; margin-top: 2px; text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); } @keyframes outage-pulse { 0%, 100% { opacity: 1; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); } 50% { opacity: 0.6; transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.2)); } } /* Outage popup header */ .popup-header.outage.total { border-bottom-color: var(--semantic-critical); } .popup-header.outage.major { border-bottom-color: var(--semantic-high); } .popup-header.outage.partial { border-bottom-color: var(--semantic-elevated); } /* Conflict zones */ .conflict-zone { fill: rgba(var(--semantic-critical), 0.2); stroke: var(--red); stroke-width: 1; stroke-dasharray: 4, 2; animation: pulse-conflict 2s ease-in-out infinite; transition: opacity 0.2s ease; } .conflict-label { fill: var(--red); font-size: 9px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg), 0 0 12px var(--bg); pointer-events: none; display: none; /* Replaced by HTML overlay */ } .conflict-label-overlay { position: absolute; transform: translate(-50%, -50%) scale(var(--label-scale, 1)); transform-origin: center; color: var(--red); font-size: 10px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg), 0 0 12px var(--bg); cursor: pointer; white-space: nowrap; z-index: 55; transition: opacity 0.2s ease; } .conflict-label-overlay:hover { color: var(--semantic-critical); text-shadow: 0 0 6px var(--bg), 0 0 12px var(--bg), 0 0 18px var(--red); } @keyframes pulse-conflict { 0%, 100% { fill: rgba(255, 68, 68, 0.15); } 50% { fill: rgba(255, 68, 68, 0.3); } } /* Base markers */ .base-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; width: 8px; height: 8px; border-radius: 50%; z-index: 51; cursor: pointer; transition: opacity 0.2s ease, transform 0.2s ease; } .base-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.3)); } .base-marker.us-nato { background: var(--semantic-low); box-shadow: 0 0 6px var(--semantic-low); } .base-marker.china { background: var(--semantic-high); box-shadow: 0 0 6px var(--semantic-high); } .base-marker.russia { background: var(--semantic-critical); box-shadow: 0 0 6px var(--semantic-critical); } /* UK - Union Jack blue */ .base-marker.uk { background: var(--semantic-low); box-shadow: 0 0 6px var(--semantic-low); } /* France - French blue */ .base-marker.france { background: var(--semantic-info); box-shadow: 0 0 6px var(--semantic-info); } /* India - Saffron orange */ .base-marker.india { background: var(--semantic-high); box-shadow: 0 0 6px var(--semantic-high); } /* Italy - Italian green */ .base-marker.italy { background: #009246; box-shadow: 0 0 6px #009246; } /* UAE - Emirates green */ .base-marker.uae { background: #00732f; box-shadow: 0 0 6px #00732f; } /* Turkey - Turkish red */ .base-marker.turkey { background: #e30a17; box-shadow: 0 0 6px #e30a17; } /* Japan - Rising sun red */ .base-marker.japan { background: #bc002d; box-shadow: 0 0 6px #bc002d; } /* Other nations */ .base-marker.other { background: var(--text-dim); box-shadow: 0 0 6px var(--text-dim); } .base-label { position: absolute; top: 14px; left: 50%; transform: translateX(-50%) scale(calc(var(--label-scale, 1) * var(--marker-scale, 1))); transform-origin: top center; font-size: 8px; font-weight: 600; color: var(--text); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); white-space: nowrap; text-transform: uppercase; pointer-events: none; opacity: 0; transition: opacity 0.2s ease; } .base-marker:hover .base-label, .base-marker.active .base-label { opacity: 1; } .base-marker.us-nato .base-label { color: var(--semantic-low); } .base-marker.china .base-label { color: var(--semantic-high); } .base-marker.russia .base-label { color: var(--semantic-critical); } .base-marker.uk .base-label { color: var(--semantic-low); } .base-marker.france .base-label { color: var(--semantic-info); } .base-marker.india .base-label { color: var(--semantic-high); } .base-marker.italy .base-label { color: #009246; } .base-marker.uae .base-label { color: #00732f; } .base-marker.turkey .base-label { color: #e30a17; } .base-marker.japan .base-label { color: #bc002d; } .base-marker.other .base-label { color: var(--text-dim); } /* Port markers */ .port-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; width: 10px; height: 10px; border-radius: 2px; z-index: 50; cursor: pointer; transition: opacity 0.2s ease, transform 0.2s ease; display: flex; align-items: center; justify-content: center; } .port-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.3)); } .port-marker.port-container { background: var(--semantic-normal); box-shadow: 0 0 6px var(--semantic-normal); } .port-marker.port-oil { background: #aa4422; box-shadow: 0 0 6px #aa4422; } .port-marker.port-lng { background: var(--semantic-high); box-shadow: 0 0 6px var(--semantic-high); } .port-marker.port-naval { background: var(--semantic-low); box-shadow: 0 0 6px var(--semantic-low); } .port-marker.port-mixed { background: var(--text-dim); box-shadow: 0 0 6px var(--text-dim); } .port-marker.port-bulk { background: var(--text-dim); box-shadow: 0 0 6px var(--text-dim); } .port-icon { display: none; } .port-label { position: absolute; top: 14px; left: 50%; transform: translateX(-50%) scale(calc(var(--label-scale, 1) * var(--marker-scale, 1))); transform-origin: top center; font-size: 7px; font-weight: 600; color: var(--text); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); white-space: nowrap; text-transform: uppercase; pointer-events: none; opacity: 0; transition: opacity 0.2s ease; } .port-marker:hover .port-label { opacity: 1; } .port-marker.port-container .port-label { color: var(--semantic-normal); } .port-marker.port-oil .port-label { color: #aa4422; } .port-marker.port-lng .port-label { color: var(--semantic-high); } .port-marker.port-naval .port-label { color: var(--semantic-low); } .port-marker.port-mixed .port-label { color: var(--text-dim); } .port-marker.port-bulk .port-label { color: var(--text-dim); } /* Iran event markers */ .iran-event-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; border-radius: 50%; border: 1.5px solid rgba(255, 80, 80, 0.9); box-shadow: 0 0 8px rgba(255, 50, 50, 0.6); animation: quake-pulse 2s ease-in-out infinite; cursor: pointer; z-index: 54; transition: opacity 0.2s ease; } .iran-event-marker:hover { box-shadow: 0 0 14px rgba(255, 50, 50, 0.9); transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.3)); } /* Earthquake markers */ .earthquake-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; border-radius: 50%; background: rgba(255, 165, 0, 0.6); border: 2px solid var(--semantic-high); box-shadow: 0 0 10px rgba(255, 165, 0, 0.8); animation: quake-pulse 1.5s ease-in-out infinite; cursor: pointer; z-index: 53; transition: opacity 0.2s ease; } .earthquake-marker:hover { background: rgba(255, 165, 0, 0.9); } .earthquake-label { position: absolute; top: 100%; left: 50%; transform: translateX(-50%) scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; white-space: nowrap; font-size: 8px; color: var(--semantic-high); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); font-weight: bold; margin-top: 2px; transition: opacity 0.2s ease; } @keyframes quake-pulse { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } } /* Natural Event markers (NASA EONET) */ .fire-dot { position: absolute; transform: translate(-50%, -50%); border-radius: 50%; opacity: 0.8; z-index: 53; pointer-events: none; box-shadow: 0 0 4px currentColor; } .nat-event-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; display: flex; flex-direction: column; align-items: center; cursor: pointer; z-index: 54; transition: opacity 0.2s ease, transform 0.2s ease; } .nat-event-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.2)); } .nat-event-icon { font-size: 20px; filter: drop-shadow(0 0 4px var(--shadow-color)); } .nat-event-label { font-size: 8px; color: var(--accent); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); font-weight: bold; white-space: nowrap; margin-top: 2px; max-width: 120px; overflow: hidden; text-overflow: ellipsis; } .nat-event-magnitude { font-size: 7px; color: var(--yellow); text-shadow: 0 0 4px var(--bg); font-weight: bold; } /* Category-specific colors */ .nat-event-marker.severeStorms .nat-event-label { color: var(--semantic-low); } .nat-event-marker.wildfires .nat-event-label { color: var(--semantic-high); } .nat-event-marker.volcanoes .nat-event-label { color: var(--semantic-high); } .nat-event-marker.floods .nat-event-label { color: var(--semantic-info); } .nat-event-marker.landslides .nat-event-label { color: #8b4513; } .nat-event-marker.drought .nat-event-label { color: var(--semantic-elevated); } .nat-event-marker.dustHaze .nat-event-label { color: var(--text-dim); } .nat-event-marker.snow .nat-event-label { color: var(--semantic-low); } .nat-event-marker.tempExtremes .nat-event-label { color: var(--semantic-critical); } .nat-event-marker.seaLakeIce .nat-event-label { color: var(--semantic-low); } .nat-event-marker.waterColor .nat-event-label { color: var(--semantic-normal); } .nat-event-marker.manmade .nat-event-label { color: var(--semantic-info); } /* Popup header for natural events */ .popup-header.nat-event { background: rgba(255, 136, 0, 0.1); } .popup-header.nat-event .popup-title { color: var(--semantic-high); } .popup-header.nat-event.severeStorms { background: rgba(0, 191, 255, 0.1); } .popup-header.nat-event.severeStorms .popup-title { color: var(--semantic-low); } .popup-header.nat-event.wildfires { background: rgba(255, 102, 0, 0.15); } .popup-header.nat-event.wildfires .popup-title { color: var(--semantic-high); } .popup-header.nat-event.volcanoes { background: rgba(255, 51, 0, 0.15); } .popup-header.nat-event.volcanoes .popup-title { color: var(--semantic-high); } .popup-header.nat-event.floods { background: rgba(65, 105, 225, 0.1); } .popup-header.nat-event.floods .popup-title { color: var(--semantic-info); } /* Nuclear markers */ .nuclear-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; width: 10px; height: 10px; border-radius: 2px; z-index: 52; cursor: pointer; transition: opacity 0.2s ease; } .nuclear-marker.active { background: var(--semantic-elevated); box-shadow: 0 0 8px var(--semantic-elevated), 0 0 16px var(--semantic-elevated); animation: nuclear-pulse 1.2s ease-in-out infinite; } .nuclear-marker.contested { background: var(--semantic-critical); box-shadow: 0 0 10px var(--semantic-critical), 0 0 20px var(--semantic-critical); animation: nuclear-alert 0.6s ease-in-out infinite; } .nuclear-marker.inactive { background: var(--text-muted); box-shadow: 0 0 4px var(--text-muted); } .nuclear-label { position: absolute; top: 14px; left: 50%; transform: translateX(-50%) scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; white-space: nowrap; font-size: 7px; color: var(--semantic-elevated); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); font-weight: bold; text-transform: uppercase; transition: opacity 0.2s ease; } .nuclear-marker.contested .nuclear-label { color: var(--semantic-critical); } @keyframes nuclear-pulse { 0%, 100% { opacity: 0.8; } 50% { opacity: 1; } } @keyframes nuclear-alert { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } } /* Gamma Irradiators */ .irradiator-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; width: 8px; height: 8px; border-radius: 50%; background: var(--status-live); box-shadow: 0 0 6px var(--status-live), 0 0 12px #00ffaa40; z-index: 51; cursor: pointer; border: 1px solid var(--semantic-normal); } .irradiator-marker:hover { background: var(--status-live); box-shadow: 0 0 10px var(--status-live), 0 0 20px #00ffaa60; } .irradiator-label { position: absolute; top: 12px; left: 50%; transform: translateX(-50%) scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; white-space: nowrap; font-size: 6px; color: var(--status-live); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); font-weight: bold; text-transform: uppercase; opacity: 0.8; } .popup-header.irradiator { background: linear-gradient(135deg, #00442220, #00221110); border-left: 3px solid var(--status-live); } /* AI Data Centers */ .datacenter-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; width: 12px; height: 12px; border-radius: 2px; background: var(--semantic-info); box-shadow: 0 0 8px #8844ff80, 0 0 16px #8844ff40; z-index: 52; cursor: pointer; border: 1px solid var(--semantic-info); display: flex; align-items: center; justify-content: center; } .datacenter-marker.existing { background: var(--semantic-info); border-color: var(--semantic-info); box-shadow: 0 0 8px #8844ff80, 0 0 16px #8844ff40; } .datacenter-marker.planned { background: transparent; border: 1px dashed var(--semantic-info); box-shadow: 0 0 8px #8844ff40; } .datacenter-marker:hover { background: var(--semantic-info); box-shadow: 0 0 12px var(--semantic-info), 0 0 24px #8844ff60; } .datacenter-marker.planned:hover { background: #8844ff40; } .datacenter-icon { font-size: 7px; line-height: 1; } .datacenter-label { position: absolute; top: 14px; left: 50%; transform: translateX(-50%) scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; white-space: nowrap; font-size: 6px; color: var(--semantic-info); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); font-weight: bold; text-transform: uppercase; opacity: 0.8; max-width: 60px; overflow: hidden; text-overflow: ellipsis; } .popup-header.datacenter { background: linear-gradient(135deg, #33225520, #22113310); border-left: 3px solid var(--semantic-info); } .popup-header.datacenter.existing { border-left-color: var(--semantic-info); } .popup-header.datacenter.planned { border-left-color: var(--semantic-elevated); } /* Heatmap */ .heatmap { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; padding: 4px; } .heatmap-cell { padding: 8px 4px; text-align: center; border-radius: 2px; background: var(--border); } .heatmap-cell.up-3 { background: var(--map-country); } .heatmap-cell.up-2 { background: var(--map-country); } .heatmap-cell.up-1 { background: var(--map-country); } .heatmap-cell.down-1 { background: var(--surface); } .heatmap-cell.down-2 { background: var(--surface); } .heatmap-cell.down-3 { background: var(--surface); } .sector-name { font-size: 9px; color: var(--text-dim); margin-bottom: 2px; } .sector-change { font-size: 11px; font-weight: bold; } .sector-change.up { color: var(--green); } .sector-change.down { color: var(--red); } /* Markets */ .market-item { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--border); } .market-item:last-child { border-bottom: none; } .market-info { display: flex; flex-direction: column; gap: 2px; } .market-name { font-size: 11px; color: var(--text); } .market-symbol { font-size: 9px; color: var(--text-dim); } .market-data { display: flex; align-items: center; gap: 6px; text-align: right; } .market-data .mini-sparkline { display: block; flex-shrink: 0; opacity: 0.8; } .market-price { font-size: 12px; font-weight: bold; color: var(--text); display: block; } .market-change { font-size: 10px; } .market-change.up { color: var(--green); } .market-change.down { color: var(--red); } /* Gulf Economies */ .gulf-section { margin-bottom: 8px; } .gulf-section:last-child { margin-bottom: 0; } .gulf-section-title { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-dim); padding: 6px 0 2px; border-bottom: 1px solid var(--border); margin-bottom: 2px; } /* Commodities */ .commodities-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; } .commodity-item { background: var(--border); padding: 8px; border-radius: 2px; } .commodity-name { font-size: 9px; color: var(--text-dim); text-transform: uppercase; } .commodity-price { font-size: 14px; font-weight: bold; color: var(--text); } .commodity-change { font-size: 10px; } .commodity-change.up { color: var(--green); } .commodity-change.down { color: var(--red); } .commodity-item .mini-sparkline { display: block; margin: 2px 0; opacity: 0.8; } /* Predictions */ .prediction-item { padding: 10px 0; border-bottom: 1px solid var(--border); } .prediction-item:last-child { border-bottom: none; } .prediction-question { font-size: 11px; color: var(--text); margin-bottom: 4px; line-height: 1.4; } a.prediction-link { text-decoration: none; color: var(--text); display: block; } a.prediction-link:hover { color: var(--accent, var(--semantic-info)); text-decoration: underline; } .prediction-meta { display: flex; gap: 8px; align-items: center; margin: 2px 0; } .prediction-volume, .prediction-expiry { font-size: 9px; color: var(--muted); } .prediction-bar { height: 24px; background: var(--border); border-radius: 3px; overflow: hidden; display: flex; } .prediction-yes { background: var(--green); display: flex; align-items: center; justify-content: center; min-width: 40px; transition: width 0.3s ease; } .prediction-no { background: var(--red); display: flex; align-items: center; justify-content: center; min-width: 40px; transition: width 0.3s ease; } .prediction-label { font-size: 10px; font-weight: bold; color: var(--bg); text-shadow: 0 0 2px var(--overlay-heavy); white-space: nowrap; padding: 0 4px; } /* Monitors */ .monitor-input-container { margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--border); } .monitor-input { width: 100%; padding: 8px; background: var(--bg); border: 1px solid var(--border); color: var(--text); font-family: inherit; font-size: 11px; margin-bottom: 8px; } .monitor-input::placeholder { color: var(--text-dim); } .monitor-add-btn { width: 100%; padding: 6px; background: var(--green); border: none; color: var(--bg); font-family: inherit; font-size: 10px; font-weight: bold; cursor: pointer; text-transform: uppercase; } .monitor-add-btn:hover { opacity: 0.9; } .monitor-tag { display: inline-flex; align-items: center; gap: 6px; padding: 4px 8px; background: var(--border); border-radius: 2px; margin: 2px; font-size: 10px; } .monitor-tag-color { width: 8px; height: 8px; border-radius: 50%; } .monitor-tag-remove { cursor: pointer; opacity: 0.6; } .monitor-tag-remove:hover { opacity: 1; } /* Loading */ .loading { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--text-dim); font-size: 11px; } .loading::after { content: ''; width: 12px; height: 12px; border: 2px solid var(--border); border-top-color: var(--text); border-radius: 50%; animation: spin 1s linear infinite; margin-left: 8px; } @keyframes spin { to { transform: rotate(360deg); } } /* Unified Panel Loading - Radar Style */ .panel-loading { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 32px 16px; min-height: 120px; } .panel-loading-radar { width: 64px; height: 64px; margin-bottom: 16px; position: relative; border: 2px solid rgba(68, 255, 136, 0.3); border-radius: 50%; overflow: hidden; } .panel-radar-sweep { position: absolute; top: 50%; left: 50%; width: 50%; height: 2px; background: linear-gradient(90deg, transparent, var(--status-live)); transform-origin: left center; animation: panel-radar-sweep 2s linear infinite; } .panel-radar-dot { position: absolute; top: 50%; left: 50%; width: 6px; height: 6px; margin: -3px; background: var(--status-live); border-radius: 50%; box-shadow: 0 0 10px var(--status-live); } @keyframes panel-radar-sweep { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .panel-loading-text { font-size: 12px; color: var(--accent); letter-spacing: 0.5px; } .panel-loading-text.retrying { color: var(--yellow, #f0c040); } /* Error */ .error-message { color: var(--red); font-size: 10px; padding: 8px; text-align: center; } .config-error-message { color: var(--semantic-elevated); font-size: 10px; padding: 8px; text-align: center; line-height: 1.6; } .config-error-settings-btn { display: inline-block; margin-top: 6px; padding: 2px 10px; font-size: 9px; color: var(--semantic-elevated); background: rgba(255, 210, 124, 0.1); border: 1px solid rgba(255, 210, 124, 0.3); border-radius: 3px; cursor: pointer; font-family: inherit; } .config-error-settings-btn:hover { background: rgba(255, 210, 124, 0.2); } /* Modal */ .modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: var(--bg); display: none; align-items: center; justify-content: center; z-index: 9999; } .modal-overlay.active { display: flex; } .modal { background: var(--surface); border: 1px solid var(--border); padding: 20px; max-width: 500px; width: 90%; max-height: 80vh; overflow-y: auto; } .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .modal-title { font-size: 14px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; } .modal-close { background: none; border: none; color: var(--text-dim); font-size: 20px; cursor: pointer; } .confirm-modal-message { margin: 0 0 16px; font-size: 14px; line-height: 1.5; } .confirm-modal-actions { display: flex; justify-content: flex-end; gap: 10px; } /* Standalone settings window (?settings=1) */ .settings-window-shell { min-height: 100vh; display: flex; flex-direction: column; background: var(--bg); color: var(--text); } .settings-window-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--darken-heavy); flex-shrink: 0; } .settings-window-header-text { flex: 1; min-width: 0; } .settings-window-title { font-size: 14px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; display: block; } .settings-window-caption { margin: 4px 0 0; font-size: 12px; font-weight: normal; text-transform: none; letter-spacing: 0; color: var(--text-dim); line-height: 1.3; } .settings-window-shell .panel-toggle-grid { padding: 16px; flex: 1; } .panel-toggle-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; } .panel-toggle-item { display: flex; align-items: center; gap: 8px; padding: 8px; background: var(--bg); border: 1px solid var(--border); cursor: pointer; } .panel-toggle-item:hover { border-color: var(--text-dim); } .panel-toggle-item.active { border-color: var(--green); } .panel-toggle-checkbox { width: 14px; height: 14px; border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; font-size: 10px; } .panel-toggle-item.active .panel-toggle-checkbox { background: var(--green); border-color: var(--green); color: var(--bg); } .panel-toggle-label { font-size: 10px; text-transform: uppercase; } /* Sources Modal */ .sources-modal { max-width: 600px; width: 95%; } .sources-counter { font-size: 11px; color: var(--text-dim); margin-left: auto; margin-right: 12px; } .sources-search, .panels-search { margin-bottom: 12px; } .sources-search input, .panels-search input { width: 100%; padding: 8px 10px; background: var(--bg); border: 1px solid var(--border); color: var(--text); font-family: inherit; font-size: 11px; } .sources-search input:focus, .panels-search input:focus { outline: none; border-color: var(--text-dim); } .sources-toggle-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; max-height: 50vh; overflow-y: auto; margin-bottom: 12px; } .source-toggle-item { display: flex; align-items: center; gap: 6px; padding: 6px 8px; background: var(--bg); border: 1px solid var(--border); cursor: pointer; font-size: 10px; } .source-toggle-item:hover { border-color: var(--text-dim); } .source-toggle-item.active { border-color: var(--green); } .source-toggle-checkbox { width: 12px; height: 12px; border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; font-size: 9px; flex-shrink: 0; } .source-toggle-item.active .source-toggle-checkbox { background: var(--green); border-color: var(--green); color: var(--bg); } .source-toggle-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .panels-footer { display: flex; justify-content: flex-end; padding-top: 8px; } .panels-reset-layout { padding: 6px 12px; background: var(--bg); border: 1px solid var(--border); color: var(--text); font-family: inherit; font-size: 10px; cursor: pointer; text-transform: uppercase; } .panels-reset-layout:hover { border-color: var(--text-dim); } .sources-footer { display: flex; align-items: center; gap: 8px; } .sources-footer button { flex: 1; padding: 6px 12px; background: var(--bg); border: 1px solid var(--border); color: var(--text); font-family: inherit; font-size: 10px; cursor: pointer; text-transform: uppercase; } .sources-footer button:hover { border-color: var(--text-dim); } @media (max-width: 600px) { .sources-toggle-grid { grid-template-columns: repeat(2, 1fr); } } /* Map Popups */ .map-popup { position: fixed; width: 380px; max-height: calc(100vh - 120px); background: var(--bg); border: 1px solid var(--red); z-index: 1000; overflow-y: auto; box-shadow: 0 4px 24px rgba(255, 68, 68, 0.3); } .map-popup.map-popup-sheet { left: 12px !important; right: 12px !important; top: auto !important; bottom: 0; width: auto !important; max-width: none; max-height: min(68vh, calc(100vh - 80px)); border-bottom: none; border-radius: 16px 16px 0 0; box-shadow: 0 -12px 32px rgba(0, 0, 0, 0.35); transform: translate3d(0, 110%, 0); transition: transform 0.22s ease-out; will-change: transform; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; } .map-popup.map-popup-sheet.open { transform: translate3d(0, 0, 0); } .map-popup.map-popup-sheet.dragging { transition: none; } .map-popup-sheet-handle { display: block; width: 56px; height: 24px; margin: 6px auto 2px; padding: 0; border: none; border-radius: 999px; background: transparent; cursor: pointer; position: sticky; top: 0; z-index: 3; } .map-popup-sheet-handle::before { content: ''; display: block; width: 36px; height: 4px; margin: 10px auto 0; border-radius: 999px; background: var(--text-dim); opacity: 0.8; } .popup-header { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 1; background: var(--bg); } /* Solid backdrop for sticky header - ensures content doesn't show through */ .popup-header::before { content: ''; position: absolute; inset: 0; background: var(--bg); z-index: -1; } .popup-header.iranEvent { background: rgba(255, 68, 68, 0.1); } .popup-header.iranEvent.high { border-left: 3px solid #ff3232; } .popup-header.iranEvent.medium { border-left: 3px solid #ffa500; } .popup-header.iranEvent.low { border-left: 3px solid #cccc00; } .popup-header.conflict { background: rgba(255, 68, 68, 0.1); } .popup-header.hotspot { background: rgba(68, 255, 136, 0.1); } .popup-header.earthquake { background: rgba(255, 165, 0, 0.1); } .popup-header.ais { background: rgba(0, 209, 255, 0.12); } .popup-title { font-size: 16px; font-weight: bold; color: var(--red); letter-spacing: 1px; flex: 1; } .popup-header.hotspot .popup-title { color: var(--green); } .popup-header.earthquake .popup-title { color: var(--semantic-high); } .popup-header.ais .popup-title { color: var(--defcon-4); } .popup-title.magnitude { font-size: 28px; } .popup-badge { padding: 4px 10px; font-size: 10px; font-weight: bold; border-radius: 2px; letter-spacing: 1px; } .popup-badge.high { background: var(--red); color: var(--bg); } .popup-badge.medium { background: var(--yellow); color: var(--bg); } .popup-badge.elevated { background: var(--yellow); color: var(--bg); } .popup-badge.low { background: var(--text-muted); color: var(--text); } .popup-close { background: none; border: none; color: var(--text-dim); font-size: 20px; cursor: pointer; padding: 0 4px; min-width: 36px; min-height: 36px; line-height: 1; touch-action: manipulation; } .popup-close:hover { color: var(--text); } .popup-body { padding: 16px; } .map-popup.map-popup-sheet .popup-body { padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)); } .popup-subtitle { font-size: 12px; color: var(--green); margin-bottom: 12px; letter-spacing: 0.5px; } .popup-description { font-size: 12px; line-height: 1.6; color: var(--text); margin-bottom: 16px; } .popup-location { font-size: 14px; color: var(--text); margin-bottom: 16px; } .popup-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; } .popup-stat { display: flex; flex-direction: column; gap: 4px; } .stat-label { font-size: 9px; color: var(--text-dim); letter-spacing: 1px; text-transform: uppercase; } .stat-value { font-size: 12px; color: var(--green); } .popup-section { margin-bottom: 16px; } .section-label { font-size: 9px; color: var(--text-dim); letter-spacing: 1px; display: block; margin-bottom: 8px; } .evidence-list { margin: 4px 0 0; padding-left: 16px; font-size: 11px; color: var(--text-secondary); line-height: 1.5; } .evidence-item { margin-bottom: 4px; } .popup-tags { display: flex; flex-wrap: wrap; gap: 6px; } .popup-tag { padding: 4px 10px; background: transparent; border: 1px solid var(--border); color: var(--text); font-size: 10px; border-radius: 2px; } .popup-list { list-style: none; padding: 0; margin: 0; } .popup-list li { position: relative; padding-left: 16px; margin-bottom: 6px; font-size: 11px; color: var(--red); } .popup-list li::before { content: '●'; position: absolute; left: 0; color: var(--red); } .popup-news { display: flex; flex-direction: column; gap: 12px; } .popup-news-item { display: flex; flex-direction: column; gap: 4px; } .popup-news-item .news-source { font-size: 9px; color: var(--red); text-transform: uppercase; letter-spacing: 0.5px; } .popup-news-item .news-title { font-size: 11px; color: var(--text); text-decoration: none; line-height: 1.4; } .popup-news-item .news-title:hover { color: var(--accent); } .popup-link { display: inline-block; color: var(--green); text-decoration: none; font-size: 11px; margin-top: 8px; } .popup-link:hover { text-decoration: underline; } /* Hotspot subtitles on map */ .hotspot-subtext { position: absolute; top: 24px; left: 50%; transform: translateX(-50%) scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; white-space: nowrap; font-size: 7px; color: var(--yellow); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); font-style: italic; opacity: 0.8; } /* Strategic waterway markers */ .waterway-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; cursor: pointer; z-index: 50; } .waterway-diamond { width: 10px; height: 10px; background: var(--status-live); transform: rotate(45deg); box-shadow: 0 0 6px rgba(0, 255, 170, 0.6); transition: all 0.2s ease; } .waterway-marker:hover .waterway-diamond { background: var(--status-live); box-shadow: 0 0 10px rgba(68, 255, 204, 0.8); transform: rotate(45deg) scale(1.2); } /* AIS disruptions */ .ais-disruption-marker { position: absolute; display: flex; flex-direction: column; align-items: center; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); cursor: pointer; z-index: 53; gap: 2px; } .ais-disruption-marker.high { --ais-color: var(--semantic-elevated); } .ais-disruption-marker.elevated { --ais-color: var(--semantic-elevated); } .ais-disruption-marker.low { --ais-color: var(--defcon-4); } .ais-disruption-icon { font-size: 16px; filter: drop-shadow(0 0 6px var(--ais-color, var(--defcon-4))); } .ais-disruption-label { font-size: 8px; text-transform: uppercase; letter-spacing: 0.6px; color: var(--ais-color, var(--defcon-4)); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); white-space: nowrap; } .ais-density-spot { pointer-events: none; mix-blend-mode: screen; filter: blur(0.2px); } /* APT markers */ .apt-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; white-space: nowrap; cursor: pointer; z-index: 53; opacity: 0.7; } .apt-marker:hover { opacity: 1; } .apt-icon { font-size: 10px; color: var(--semantic-info); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); } .apt-label { font-size: 7px; color: var(--semantic-info); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); letter-spacing: 0.5px; transform: scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; } /* Breaking tag */ .breaking-tag { position: absolute; white-space: nowrap; font-size: 8px; font-weight: bold; color: var(--bg); background: var(--red); padding: 2px 6px; border: 1px solid var(--red); letter-spacing: 0.5px; animation: pulse-breaking 0.8s ease-in-out infinite; z-index: 55; } /* Map grid lines */ .map-grid-line { stroke: rgba(0, 255, 136, 0.15); stroke-width: 0.5; fill: none; } .map-grid-label { font-size: 8px; fill: var(--text-dim); opacity: 0.5; } /* Map legend bar */ .map-legend { position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 16px; padding: 6px 16px; background: var(--bg); border: 1px solid var(--border); font-size: 9px; color: var(--text-dim); letter-spacing: 0.5px; z-index: 100; } .map-legend-item { display: flex; align-items: center; gap: 6px; } .map-legend-icon { font-size: 10px; } .map-legend-icon.ship { color: var(--status-live); } .map-legend-icon.nuke { color: var(--semantic-elevated); } .map-legend-icon.base { color: var(--semantic-low); } .map-legend-icon.cable { color: var(--status-live); } .map-legend-icon.conflict { color: var(--semantic-critical); } .map-legend-icon.earthquake { color: var(--semantic-elevated); } .map-legend-icon.apt { color: var(--semantic-high); } .legend-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; } .legend-dot.high { background: var(--semantic-critical); box-shadow: 0 0 6px var(--semantic-critical); } .legend-dot.elevated { background: var(--semantic-elevated); box-shadow: 0 0 4px var(--semantic-elevated); } .legend-dot.low { background: var(--status-live); } .conflict-click-area { position: absolute; z-index: 50; transition: opacity 0.2s ease; } /* Map timestamp */ .map-timestamp { position: absolute; bottom: 8px; right: 10px; font-size: 9px; color: var(--text-dim); z-index: 100; } /* Signal Pulse on Status Dot */ .status-dot.signal-pulse { animation: signal-dot-pulse 0.5s ease-out 6; background: var(--defcon-4); } @keyframes signal-dot-pulse { 0%, 100% { transform: scale(1); box-shadow: 0 0 0 rgba(0, 170, 255, 0.8); } 50% { transform: scale(1.8); box-shadow: 0 0 8px rgba(0, 170, 255, 1); } } /* Status Panel */ /* Status rows (used in settings status tab) */ .status-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 11px; } .status-row .status-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; } .status-row .status-dot.ok { background: var(--green); } .status-row .status-dot.warning { background: var(--yellow); } .status-row .status-dot.error { background: var(--red); } .status-row .status-dot.disabled { background: var(--text-faint); } .status-row:has(.status-dot.disabled) { opacity: 0.5; } .status-name { flex: 1; color: var(--text); } .status-detail { color: var(--text-dim); font-size: 10px; } .status-time { color: var(--text-dim); font-size: 10px; } /* Status tab inside Unified Settings */ .us-status-content { padding: 4px 0; max-height: 50vh; overflow-y: auto; } .us-status-section { padding: 8px 12px; } .us-status-section-title { font-size: 9px; color: var(--text-dim); text-transform: uppercase; margin-bottom: 6px; } .us-status-footer { padding: 6px 12px; border-top: 1px solid var(--border); font-size: 9px; color: var(--text-dim); } /* Export Panel */ .export-panel-container { position: relative; } .export-btn { background: transparent; border: 1px solid var(--border); color: var(--text-dim); padding: 4px 8px; font-size: 11px; cursor: pointer; border-radius: 3px; } .export-btn:hover { border-color: var(--accent); color: var(--accent); } .export-menu { position: absolute; top: 100%; right: 0; margin-top: 4px; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; z-index: 1000; box-shadow: 0 4px 12px var(--shadow-color); min-width: 120px; } .export-menu.hidden { display: none; } .export-option { display: block; width: 100%; padding: 8px 12px; background: none; border: none; color: var(--text); font-size: 11px; text-align: left; cursor: pointer; } .export-option:hover { background: var(--border); } .export-option:first-child { border-radius: 3px 3px 0 0; } .export-option:last-child { border-radius: 0 0 3px 3px; } /* Weather Markers */ .weather-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; cursor: pointer; display: flex; flex-direction: column; align-items: center; z-index: 60; } .weather-icon { font-size: 16px; color: var(--semantic-elevated); text-shadow: 0 0 4px rgba(255, 170, 0, 0.8); } .weather-marker.extreme .weather-icon { color: var(--semantic-critical); text-shadow: 0 0 6px rgba(255, 0, 0, 0.9); animation: weather-pulse 1s ease-in-out infinite; } .weather-marker.severe .weather-icon { color: var(--semantic-high); text-shadow: 0 0 5px rgba(255, 102, 0, 0.8); } .weather-marker.moderate .weather-icon { color: var(--semantic-elevated); } .weather-marker.minor .weather-icon { color: var(--semantic-elevated); } .weather-label { font-size: 8px; color: var(--text); background: var(--bg); padding: 1px 4px; border-radius: 2px; white-space: nowrap; max-width: 80px; overflow: hidden; text-overflow: ellipsis; transform: scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; } @keyframes weather-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } /* Weather popup styles */ .popup-header.weather { background: linear-gradient(135deg, var(--semantic-high), var(--semantic-high)); } .popup-header.weather.extreme { background: linear-gradient(135deg, var(--semantic-critical), #aa0000); } .popup-header.weather.severe { background: linear-gradient(135deg, var(--semantic-high), var(--semantic-high)); } .popup-header.weather.moderate { background: linear-gradient(135deg, var(--semantic-elevated), var(--semantic-high)); } .popup-header.weather.minor { background: linear-gradient(135deg, var(--semantic-elevated), var(--semantic-elevated)); } .popup-headline { font-weight: bold; margin-bottom: 8px; color: var(--text); } /* Economic Markers */ .economic-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; cursor: pointer; display: flex; flex-direction: column; align-items: center; z-index: 50; opacity: 0.85; transition: opacity 0.2s ease; } .economic-marker:hover { opacity: 1; z-index: 100; } .economic-icon { font-size: 14px; filter: drop-shadow(0 0 3px var(--shadow-color)); } .economic-marker.exchange .economic-icon { filter: drop-shadow(0 0 4px rgba(76, 175, 80, 0.6)); } .economic-marker.central-bank .economic-icon { filter: drop-shadow(0 0 4px rgba(33, 150, 243, 0.6)); } .economic-marker.financial-hub .economic-icon { filter: drop-shadow(0 0 4px rgba(255, 193, 7, 0.6)); } .economic-label { font-size: 7px; color: var(--text); background: var(--bg); padding: 1px 3px; border-radius: 2px; white-space: nowrap; margin-top: 1px; opacity: 0; transition: opacity 0.2s ease; transform: scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; } .economic-marker:hover .economic-label { opacity: 1; } .map-wrapper[data-layer-hidden-bases="true"] .base-marker, .map-wrapper[data-layer-hidden-iranAttacks="true"] .iran-event-marker, .map-wrapper[data-layer-hidden-nuclear="true"] .nuclear-marker, .map-wrapper[data-layer-hidden-natural="true"] .earthquake-marker, .map-wrapper[data-layer-hidden-natural="true"] .nat-event-marker, .map-wrapper[data-layer-hidden-economic="true"] .economic-marker, .map-wrapper[data-layer-hidden-conflicts="true"] .conflicts, .map-wrapper[data-layer-hidden-conflicts="true"] .conflict-label-overlay, .map-wrapper[data-layer-hidden-conflicts="true"] .conflict-click-area { opacity: 0; pointer-events: none; } .map-wrapper:not([data-labels-hidden-bases="true"]) .base-label, .map-wrapper:not([data-labels-hidden-economic="true"]) .economic-label { opacity: 1; } .map-wrapper[data-labels-hidden-bases="true"] .base-label, .map-wrapper[data-labels-hidden-nuclear="true"] .nuclear-label, .map-wrapper[data-labels-hidden-natural="true"] .earthquake-label, .map-wrapper[data-labels-hidden-natural="true"] .nat-event-label, .map-wrapper[data-labels-hidden-economic="true"] .economic-label, .map-wrapper[data-labels-hidden-conflicts="true"] .conflict-label-overlay { opacity: 0; } .popup-header.economic { background: linear-gradient(135deg, var(--semantic-normal), var(--semantic-normal)); } .popup-header.economic.central-bank { background: linear-gradient(135deg, var(--semantic-info), var(--semantic-info)); } .popup-header.economic.financial-hub { background: linear-gradient(135deg, var(--semantic-elevated), var(--semantic-high)); } /* Spaceport Markers */ .spaceport-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; z-index: 55; cursor: pointer; transition: transform 0.2s ease; } .spaceport-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.3)); } .spaceport-icon { font-size: 16px; filter: drop-shadow(0 0 4px var(--defcon-4)); } .spaceport-marker.active .spaceport-icon { filter: drop-shadow(0 0 8px var(--status-live)) drop-shadow(0 0 16px var(--status-live)); } .spaceport-marker.planned .spaceport-icon { filter: drop-shadow(0 0 4px var(--semantic-elevated)); opacity: 0.7; } .spaceport-marker.inactive .spaceport-icon { filter: grayscale(1); opacity: 0.5; } .spaceport-label { position: absolute; top: 20px; left: 50%; transform: translateX(-50%) scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; white-space: nowrap; font-size: 7px; color: var(--defcon-4); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); font-weight: bold; text-transform: uppercase; opacity: 0; transition: opacity 0.2s ease; } .spaceport-marker:hover .spaceport-label { opacity: 1; } .spaceport-marker.active .spaceport-label { color: var(--status-live); } .spaceport-marker.planned .spaceport-label { color: var(--semantic-elevated); } /* Spaceport popup header */ .popup-header.spaceport { background: linear-gradient(135deg, #00224420, #001a3310); border-left: 3px solid var(--defcon-4); } .popup-header.spaceport.active { border-left-color: var(--status-live); } .popup-header.spaceport.planned { border-left-color: var(--semantic-elevated); } /* Critical Minerals Markers */ .mineral-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; z-index: 54; cursor: pointer; transition: transform 0.2s ease; } .mineral-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.3)); } .mineral-icon { font-size: 14px; filter: drop-shadow(0 0 4px var(--semantic-info)); } .mineral-marker.producing .mineral-icon { filter: drop-shadow(0 0 6px var(--status-live)) drop-shadow(0 0 12px #44ff8860); } .mineral-marker.developing .mineral-icon { filter: drop-shadow(0 0 4px var(--semantic-elevated)); opacity: 0.8; } .mineral-marker.exploration .mineral-icon { filter: drop-shadow(0 0 3px var(--text-dim)); opacity: 0.6; } .mineral-label { position: absolute; top: 18px; left: 50%; transform: translateX(-50%) scale(calc(var(--label-scale, 1) / var(--marker-scale, 1))); transform-origin: top center; white-space: nowrap; font-size: 7px; color: var(--semantic-info); text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); font-weight: bold; text-transform: uppercase; opacity: 0; transition: opacity 0.2s ease; } .mineral-marker:hover .mineral-label { opacity: 1; } .mineral-marker.producing .mineral-label { color: var(--status-live); } .mineral-marker.developing .mineral-label { color: var(--semantic-elevated); } /* Mineral popup header */ .popup-header.mineral { background: linear-gradient(135deg, #331a4420, #221a3310); border-left: 3px solid var(--semantic-info); } .popup-header.mineral.producing { border-left-color: var(--status-live); } .popup-header.mineral.developing { border-left-color: var(--semantic-elevated); } /* ============================================ TECH VARIANT MARKERS ============================================ */ /* Startup Hub Markers */ .startup-hub-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; z-index: 56; cursor: pointer; transition: transform 0.2s ease; } .startup-hub-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.3)); } .startup-hub-icon { font-size: 16px; filter: drop-shadow(0 0 4px var(--status-live)); } .startup-hub-marker.mega .startup-hub-icon { font-size: 20px; filter: drop-shadow(0 0 8px var(--semantic-info)) drop-shadow(0 0 16px #ff44ff60); } .startup-hub-marker.major .startup-hub-icon { filter: drop-shadow(0 0 6px var(--defcon-4)) drop-shadow(0 0 12px #00aaff60); } .startup-hub-marker.emerging .startup-hub-icon { filter: drop-shadow(0 0 4px var(--semantic-elevated)); opacity: 0.85; } .startup-hub-label { position: absolute; left: 50%; top: 100%; transform: translateX(-50%); white-space: nowrap; font-size: 8px; padding: 2px 4px; background: var(--bg); border-radius: 2px; text-transform: uppercase; opacity: 0; transition: opacity 0.2s ease; margin-top: 2px; color: var(--status-live); } .startup-hub-marker:hover .startup-hub-label { opacity: 1; } .startup-hub-marker.mega .startup-hub-label { color: var(--semantic-info); opacity: 1; } .startup-hub-marker.major .startup-hub-label { color: var(--defcon-4); } /* Startup Hub popup header */ .popup-header.startup-hub { background: linear-gradient(135deg, #00331a20, #00221510); border-left: 3px solid var(--status-live); } .popup-header.startup-hub.mega { border-left-color: var(--semantic-info); background: linear-gradient(135deg, #331a3320, #22153310); } .popup-header.startup-hub.major { border-left-color: var(--defcon-4); } .popup-badge.mega { background: var(--semantic-info); color: var(--bg); } .popup-badge.major { background: var(--defcon-4); color: var(--bg); } .popup-badge.emerging { background: var(--semantic-elevated); color: var(--bg); } /* Cloud Region Markers */ .cloud-region-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; z-index: 54; cursor: pointer; transition: transform 0.2s ease; } .cloud-region-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.3)); } .cloud-region-icon { font-size: 12px; filter: drop-shadow(0 0 4px var(--accent)); } .cloud-region-marker.aws .cloud-region-icon { filter: drop-shadow(0 0 4px var(--semantic-high)); } .cloud-region-marker.gcp .cloud-region-icon { filter: drop-shadow(0 0 4px var(--semantic-info)); } .cloud-region-marker.azure .cloud-region-icon { filter: drop-shadow(0 0 4px var(--semantic-info)); } .cloud-region-marker.cloudflare .cloud-region-icon { filter: drop-shadow(0 0 4px var(--threat-high)); } .cloud-region-label { position: absolute; left: 50%; top: 100%; transform: translateX(-50%); white-space: nowrap; font-size: 7px; padding: 1px 3px; background: var(--bg); border-radius: 2px; text-transform: uppercase; opacity: 0; transition: opacity 0.2s ease; margin-top: 2px; } .cloud-region-marker:hover .cloud-region-label { opacity: 1; } .cloud-region-marker.aws .cloud-region-label { color: var(--semantic-high); } .cloud-region-marker.gcp .cloud-region-label { color: var(--semantic-info); } .cloud-region-marker.azure .cloud-region-label { color: var(--semantic-info); } .cloud-region-marker.cloudflare .cloud-region-label { color: var(--threat-high); } /* Cloud Region popup header */ .popup-header.cloud-region { background: linear-gradient(135deg, #00221a20, #00111010); border-left: 3px solid var(--accent); } .popup-header.cloud-region.aws { border-left-color: var(--semantic-high); } .popup-header.cloud-region.gcp { border-left-color: var(--semantic-info); } .popup-header.cloud-region.azure { border-left-color: var(--semantic-info); } .popup-header.cloud-region.cloudflare { border-left-color: var(--threat-high); } .popup-badge.aws { background: var(--semantic-high); color: var(--bg); } .popup-badge.gcp { background: var(--semantic-info); color: var(--accent); } .popup-badge.azure { background: var(--semantic-info); color: var(--accent); } .popup-badge.cloudflare { background: var(--threat-high); color: var(--accent); } /* Tech HQ Markers */ .tech-hq-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; z-index: 55; cursor: pointer; transition: transform 0.2s ease; } .tech-hq-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.3)); } .tech-hq-icon { font-size: 14px; filter: drop-shadow(0 0 4px var(--semantic-info)); } .tech-hq-marker.faang .tech-hq-icon { font-size: 16px; filter: drop-shadow(0 0 6px var(--status-live)) drop-shadow(0 0 12px #00ffaa60); } .tech-hq-marker.unicorn .tech-hq-icon { filter: drop-shadow(0 0 6px var(--semantic-info)) drop-shadow(0 0 12px #ff44ff60); } .tech-hq-marker.public .tech-hq-icon { filter: drop-shadow(0 0 4px var(--defcon-4)); opacity: 0.9; } .tech-hq-label { position: absolute; left: 50%; top: 100%; transform: translateX(-50%); white-space: nowrap; font-size: 8px; padding: 2px 4px; background: var(--bg); border-radius: 2px; text-transform: uppercase; opacity: 0; transition: opacity 0.2s ease; margin-top: 2px; font-weight: bold; } .tech-hq-marker:hover .tech-hq-label { opacity: 1; } .tech-hq-marker.faang .tech-hq-label { color: var(--status-live); opacity: 1; } .tech-hq-marker.unicorn .tech-hq-label { color: var(--semantic-info); } .tech-hq-marker.public .tech-hq-label { color: var(--defcon-4); } /* Tech HQ popup header */ .popup-header.tech-hq { background: linear-gradient(135deg, #1a1a3320, #11112210); border-left: 3px solid var(--semantic-info); } .popup-header.tech-hq.faang { border-left-color: var(--status-live); } .popup-header.tech-hq.unicorn { border-left-color: var(--semantic-info); } .popup-badge.faang { background: var(--status-live); color: var(--bg); } .popup-badge.unicorn { background: var(--semantic-info); color: var(--bg); } .popup-badge.public { background: var(--defcon-4); color: var(--accent); } /* Cluster badges for grouped markers */ .cluster-badge { position: absolute; top: -6px; right: -6px; background: var(--red); color: var(--accent); font-size: 9px; font-weight: bold; min-width: 14px; height: 14px; border-radius: 7px; display: flex; align-items: center; justify-content: center; padding: 0 3px; border: 1px solid var(--bg); z-index: 10; } .tech-hq-marker.cluster { z-index: 60; } .tech-hq-marker.cluster .tech-hq-icon { font-size: 18px; } .tech-event-marker.cluster { width: 18px; height: 18px; z-index: 1001; } .tech-event-marker.cluster .cluster-badge { background: var(--accent); color: var(--border); } /* Cluster popups */ .cluster-popup { max-height: 300px; overflow-y: auto; } .cluster-summary { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; } .cluster-summary .summary-item { font-size: 10px; padding: 2px 6px; border-radius: 3px; background: var(--overlay-medium); } .cluster-summary .summary-item.faang { color: var(--status-live); } .cluster-summary .summary-item.unicorn { color: var(--semantic-info); } .cluster-summary .summary-item.public { color: var(--defcon-4); } .cluster-summary .summary-item.soon { color: var(--yellow); } .cluster-list { list-style: none; padding: 0; margin: 8px 0 0 0; font-size: 11px; } .cluster-list .cluster-item { padding: 4px 0; border-bottom: 1px solid var(--overlay-medium); } .cluster-list .cluster-item:last-child { border-bottom: none; } .cluster-list .cluster-item.faang { color: var(--status-live); } .cluster-list .cluster-item.unicorn { color: var(--semantic-info); } .cluster-list .cluster-item.public { color: var(--defcon-4); } .cluster-list .cluster-item.urgent { color: var(--red); } .cluster-list .cluster-item.soon { color: var(--yellow); } /* Accelerator Markers */ .accelerator-marker { position: absolute; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; z-index: 53; cursor: pointer; transition: transform 0.2s ease; } .accelerator-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.3)); } .accelerator-icon { font-size: 14px; filter: drop-shadow(0 0 4px var(--semantic-high)); } .accelerator-marker.accelerator .accelerator-icon { filter: drop-shadow(0 0 6px var(--semantic-high)) drop-shadow(0 0 12px #ff660060); } .accelerator-marker.incubator .accelerator-icon { filter: drop-shadow(0 0 4px var(--status-live)); } .accelerator-marker.studio .accelerator-icon { filter: drop-shadow(0 0 4px var(--semantic-critical)); } .accelerator-label { position: absolute; left: 50%; top: 100%; transform: translateX(-50%); white-space: nowrap; font-size: 7px; padding: 2px 4px; background: var(--bg); border-radius: 2px; text-transform: uppercase; opacity: 0; transition: opacity 0.2s ease; margin-top: 2px; } .accelerator-marker:hover .accelerator-label { opacity: 1; } .accelerator-marker.accelerator .accelerator-label { color: var(--semantic-high); } .accelerator-marker.incubator .accelerator-label { color: var(--status-live); } .accelerator-marker.studio .accelerator-label { color: var(--semantic-critical); } /* Accelerator popup header */ .popup-header.accelerator { background: linear-gradient(135deg, #331a1020, #221a0810); border-left: 3px solid var(--semantic-high); } .popup-header.accelerator.incubator { border-left-color: var(--status-live); } .popup-header.accelerator.studio { border-left-color: var(--semantic-critical); } .popup-badge.accelerator { background: var(--semantic-high); color: var(--accent); } .popup-badge.incubator { background: var(--status-live); color: var(--bg); } .popup-badge.studio { background: var(--semantic-critical); color: var(--accent); } /* Notable alumni list in accelerator popup */ .popup-notable { margin-top: 8px; padding: 6px 8px; background: rgba(255, 102, 0, 0.1); border-radius: 4px; } .notable-label { display: block; font-size: 8px; color: var(--text-dim); text-transform: uppercase; margin-bottom: 4px; } .notable-list { font-size: 10px; color: var(--semantic-high); } /* Economic Panel */ .economic-indicators { display: flex; flex-direction: column; gap: 1px; background: var(--border); } .economic-indicator { background: var(--surface); padding: 8px 12px; } .indicator-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; } .indicator-name { font-size: 10px; color: var(--text); font-weight: 500; } .indicator-id { font-size: 9px; color: var(--text-dim); font-family: monospace; } .indicator-value { display: flex; justify-content: space-between; align-items: baseline; } .indicator-value .value { font-size: 14px; font-weight: bold; color: var(--accent); } .indicator-value .change { font-size: 10px; color: var(--text-dim); } .indicator-value .change.positive { color: var(--green); } .indicator-value .change.negative { color: var(--red); } .indicator-date { font-size: 9px; color: var(--text-dim); margin-top: 2px; } .economic-footer { padding: 6px 12px; border-top: 1px solid var(--border); text-align: right; } .economic-source { font-size: 9px; color: var(--text-dim); } /* Economic Panel Tabs */ .economic-tabs { display: flex; gap: 2px; padding: 6px 8px; border-bottom: 1px solid var(--border); background: var(--darken-heavy); } .economic-tab { flex: 1; padding: 4px 8px; font-size: 10px; border: none; background: transparent; color: var(--text-dim); cursor: pointer; border-radius: 4px; transition: all 0.15s; } .economic-tab:hover { background: rgba(68, 255, 136, 0.1); color: var(--text); } .economic-tab.active { background: rgba(68, 255, 136, 0.2); color: var(--green); } .economic-content { padding: 8px; max-height: 300px; overflow-y: auto; } .economic-empty { padding: 16px; text-align: center; color: var(--text-dim); font-size: 11px; } /* Government Spending */ .spending-summary { padding: 8px; background: rgba(68, 255, 136, 0.05); border-radius: 4px; margin-bottom: 8px; } .spending-total { font-size: 14px; font-weight: 600; color: var(--green); } .spending-period { display: block; font-size: 9px; color: var(--text-dim); font-weight: 400; margin-top: 2px; } .spending-list { display: flex; flex-direction: column; gap: 6px; } .spending-award { padding: 8px; background: var(--overlay-subtle); border-radius: 4px; border-left: 2px solid var(--border); } .spending-award:hover { background: var(--overlay-light); border-left-color: var(--green); } .award-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; } .award-icon { font-size: 12px; } .award-amount { font-size: 12px; font-weight: 600; color: var(--green); } .award-recipient { font-size: 11px; color: var(--text); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .award-agency { font-size: 9px; color: var(--text-dim); margin-top: 2px; } .award-desc { font-size: 9px; color: var(--text-dim); margin-top: 4px; line-height: 1.3; } /* Trade Policy Panel */ .economic-warning { padding: 6px 10px; font-size: 10px; color: var(--semantic-elevated); background: rgba(255, 170, 50, 0.08); border-bottom: 1px solid rgba(255, 170, 50, 0.15); } .trade-restrictions-list, .trade-barriers-list { display: flex; flex-direction: column; gap: 6px; } .trade-restriction-card, .trade-barrier-card { padding: 8px 10px; background: var(--overlay-subtle); border-radius: 4px; border-left: 2px solid var(--border); transition: all 0.15s; } .trade-restriction-card:hover, .trade-barrier-card:hover { background: var(--overlay-light); border-left-color: var(--green); } .trade-restriction-header, .trade-barrier-header { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; } .trade-country { font-size: 11px; font-weight: 600; color: var(--text); } .trade-badge { font-size: 9px; padding: 1px 5px; background: rgba(68, 255, 136, 0.1); color: var(--text-dim); border-radius: 3px; white-space: nowrap; } .trade-status { font-size: 9px; padding: 1px 5px; border-radius: 3px; font-weight: 600; margin-left: auto; white-space: nowrap; } .trade-status.status-active { background: rgba(255, 80, 80, 0.15); color: var(--red); } .trade-status.status-notified { background: rgba(255, 170, 50, 0.15); color: var(--semantic-elevated); } .trade-status.status-terminated { background: rgba(68, 255, 136, 0.1); color: var(--green); } .sc-status-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin: 0 4px; vertical-align: middle; } .sc-dot-red { background: var(--red, #ff5252); } .sc-dot-yellow { background: var(--yellow, #ffd740); } .sc-dot-green { background: var(--green, #69f0ae); } .sc-risk-critical { color: var(--red, #ff5252); font-weight: 600; } .sc-risk-high { color: var(--orange, #ffab40); font-weight: 600; } .sc-risk-moderate { color: var(--yellow, #ffd740); } .sc-risk-low { color: var(--green, #69f0ae); } .trade-sector { font-size: 10px; color: var(--text-dim); } .trade-description { font-size: 10px; color: var(--text-dim); margin-top: 2px; line-height: 1.3; } .trade-affected { font-size: 9px; color: var(--text-faint); margin-top: 2px; } .trade-barrier-title { font-size: 10px; color: var(--text-secondary); font-weight: 500; line-height: 1.3; } .trade-restriction-footer, .trade-barrier-footer { display: flex; align-items: center; justify-content: space-between; margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--border); } .trade-date { font-size: 9px; color: var(--text-faint); } .trade-source-link { font-size: 9px; color: var(--accent); text-decoration: none; } .trade-source-link:hover { text-decoration: underline; } /* Trade Tariffs Table */ .trade-tariffs-table { width: 100%; } .trade-tariffs-table table { width: 100%; border-collapse: collapse; font-size: 11px; } .trade-tariffs-table thead th { text-align: left; font-size: 9px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; padding: 4px 8px 6px; border-bottom: 1px solid var(--border); } .trade-tariffs-table tbody td { padding: 5px 8px; color: var(--text); border-bottom: 1px solid var(--border); } .trade-tariffs-table tbody tr:last-child td { border-bottom: none; } .trade-tariffs-table tbody tr:hover { background: var(--overlay-subtle); } /* Trade Flows */ .trade-flows-list { display: flex; flex-direction: column; gap: 6px; } .trade-flow-card { padding: 8px 10px; background: var(--overlay-subtle); border-radius: 4px; display: flex; align-items: center; gap: 10px; } .trade-flow-card:hover { background: var(--overlay-light); } .trade-flow-year { font-size: 12px; font-weight: 600; color: var(--text-dim); min-width: 36px; } .trade-flow-metrics { flex: 1; display: flex; gap: 12px; } .trade-flow-metric { display: flex; flex-direction: column; gap: 1px; } .trade-flow-label { font-size: 9px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.3px; } .trade-flow-value { font-size: 12px; font-weight: 600; color: var(--text); } .trade-flow-change { font-size: 10px; } .trade-flow-change.change-positive { color: var(--green); } .trade-flow-change.change-negative { color: var(--red); } /* Search Modal (Cmd+K) */ .search-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: var(--bg); display: flex; align-items: flex-start; justify-content: center; padding-top: 15vh; z-index: 2000; backdrop-filter: blur(4px); } .search-modal { width: 560px; max-width: 90vw; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 20px 60px var(--shadow-color); overflow: hidden; } .search-header { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--bg); } .search-icon { font-size: 14px; color: var(--text-dim); background: var(--border); padding: 2px 6px; border-radius: 4px; font-weight: bold; } .search-input { flex: 1; background: transparent; border: none; color: var(--text); font-family: inherit; font-size: 14px; outline: none; } .search-input::placeholder { color: var(--text-dim); } .search-kbd { font-size: 10px; color: var(--text-dim); background: var(--border); padding: 2px 6px; border-radius: 3px; font-family: inherit; } .search-results { max-height: 400px; overflow-y: auto; } .search-section-header { padding: 8px 16px; font-size: 10px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 1px; background: var(--bg); border-bottom: 1px solid var(--border); } .search-result-item { display: flex; align-items: center; gap: 12px; padding: 10px 16px; cursor: pointer; transition: background 0.1s; } .search-result-item:hover, .search-result-item.selected { background: var(--border); } .search-result-item.selected { border-left: 2px solid var(--green); } .search-result-icon { font-size: 16px; width: 24px; text-align: center; } .search-result-content { flex: 1; min-width: 0; } .search-result-title { font-size: 12px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .search-result-title mark { background: rgba(68, 255, 136, 0.3); color: var(--green); padding: 0 2px; border-radius: 2px; } .search-result-item.command-item { border-left: 2px solid var(--semantic-normal, #4488ff); } .search-result-item.command-item .search-result-type { font-size: 9px; text-transform: uppercase; opacity: 0.5; } .search-result-subtitle { font-size: 10px; color: var(--text-dim); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .search-result-type { font-size: 9px; color: var(--text-dim); text-transform: uppercase; background: var(--bg); padding: 2px 6px; border-radius: 3px; } .search-empty { padding: 40px 16px; text-align: center; color: var(--text-dim); } .search-empty-icon { font-size: 32px; margin-bottom: 12px; opacity: 0.5; } .search-empty-hint { font-size: 11px; margin-top: 8px; opacity: 0.7; } .search-empty-examples { font-size: 11px; margin-top: 12px; opacity: 0.5; } .search-empty-examples kbd { background: var(--bg-tertiary, rgba(255, 255, 255, 0.08)); border-radius: 3px; padding: 2px 6px; font-size: 10px; font-family: inherit; margin: 0 2px; } .search-footer { display: flex; gap: 16px; padding: 8px 16px; border-top: 1px solid var(--border); background: var(--bg); font-size: 10px; color: var(--text-dim); } .search-footer kbd { font-size: 9px; background: var(--border); padding: 1px 4px; border-radius: 2px; margin-right: 4px; } /* Mobile search FAB — always visible floating button */ .search-mobile-fab { display: none; } @media (max-width: 768px) { .search-mobile-fab { display: flex; align-items: center; justify-content: center; position: fixed; bottom: calc(24px + env(safe-area-inset-bottom, 0px)); right: 16px; width: 56px; height: 56px; background: var(--accent, #4488ff); border: none; border-radius: 50%; box-shadow: 0 4px 20px rgba(68, 136, 255, 0.4), 0 2px 8px rgba(0, 0, 0, 0.3); color: #fff; font-size: 22px; cursor: pointer; z-index: 500; -webkit-tap-highlight-color: transparent; } .search-mobile-fab:active { transform: scale(0.9); opacity: 0.85; } } /* Mobile bottom sheet search */ .search-overlay.search-mobile { align-items: flex-end; padding-top: 0; background: rgba(0, 0, 0, 0.5); } .search-overlay.search-mobile .search-sheet { width: 100%; max-height: 50vh; background: var(--surface); border-radius: 16px 16px 0 0; display: flex; flex-direction: column; transform: translateY(100%); transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1); } .search-overlay.search-mobile.open .search-sheet { transform: translateY(0); } .search-sheet-handle { width: 36px; height: 4px; background: var(--text-dim); opacity: 0.4; border-radius: 2px; margin: 8px auto; } .search-sheet-header { display: flex; align-items: center; gap: 8px; padding: 8px 16px 12px; } .search-sheet-icon { font-size: 16px; } .search-sheet-header .search-input { flex: 1; font-size: 15px; background: transparent; border: none; color: var(--text); font-family: inherit; outline: none; } .search-sheet-cancel { background: none; border: none; color: var(--accent, #4488ff); font-size: 20px; font-family: inherit; cursor: pointer; padding: 4px 8px; line-height: 1; } .search-sheet-chips { display: flex; gap: 6px; padding: 0 16px 10px; overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; } .search-sheet-chips::-webkit-scrollbar { display: none; } .search-chip { flex-shrink: 0; padding: 6px 14px; border-radius: 16px; border: 1px solid var(--border); background: var(--bg); color: var(--text); font-size: 12px; font-family: inherit; cursor: pointer; white-space: nowrap; } .search-chip:active { background: var(--border); } @media (max-width: 768px) { .search-btn { display: none !important; } .search-overlay.search-mobile .search-results { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; } .search-overlay.search-mobile .search-result-item { min-height: 48px; padding: 12px 16px; } .search-overlay.search-mobile .search-result-title { font-size: 14px; } .search-overlay.search-mobile .search-section-header { font-size: 11px; padding: 10px 16px; } .search-overlay.search-mobile .search-result-subtitle { display: none; } .search-overlay.search-mobile .search-result-type { display: none; } } /* Flight Delay Markers */ .flight-delay-marker { position: absolute; display: flex; flex-direction: column; align-items: center; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; cursor: pointer; z-index: 53; --flight-color: var(--semantic-info); } .flight-delay-marker.normal { --flight-color: var(--status-live); } .flight-delay-marker.minor { --flight-color: var(--semantic-elevated); } .flight-delay-marker.moderate { --flight-color: var(--semantic-high); } .flight-delay-marker.major { --flight-color: var(--semantic-high); animation: flight-pulse 2s ease-in-out infinite; } .flight-delay-marker.severe { --flight-color: var(--semantic-critical); animation: flight-pulse 1s ease-in-out infinite; } .flight-delay-icon { font-size: 18px; filter: drop-shadow(0 0 6px var(--flight-color)); } .flight-delay-label { font-size: 9px; color: var(--flight-color); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 2px; white-space: nowrap; text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); font-weight: bold; } @keyframes flight-pulse { 0%, 100% { opacity: 1; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); } 50% { opacity: 0.7; transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.15)); } } /* Flight Popup Styles */ .popup-header.flight { background: linear-gradient(90deg, var(--flight-color, var(--semantic-info)) 0%, transparent 100%); } .popup-header.flight.normal { --flight-color: var(--status-live); } .popup-header.flight.minor { --flight-color: var(--semantic-elevated); } .popup-header.flight.moderate { --flight-color: var(--semantic-high); } .popup-header.flight.major { --flight-color: var(--semantic-high); } .popup-header.flight.severe { --flight-color: var(--semantic-critical); } .popup-location { font-size: 10px; color: var(--text-dim); margin-bottom: 8px; } /* ============================================ Military Flight Tracking Markers ============================================ */ .military-flight-marker { position: absolute; display: flex; flex-direction: column; align-items: center; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; cursor: pointer; z-index: 55; --mil-color: var(--status-live); opacity: 0.7; } .military-flight-marker:hover { opacity: 1; } /* US Military - olive */ .military-flight-marker.usaf, .military-flight-marker.usn, .military-flight-marker.usmc, .military-flight-marker.usa { --mil-color: var(--semantic-normal); } /* UK Military - forest green */ .military-flight-marker.raf, .military-flight-marker.rn { --mil-color: var(--semantic-normal); } /* French - teal */ .military-flight-marker.faf { --mil-color: var(--semantic-normal); } /* German - olive */ .military-flight-marker.gaf { --mil-color: #6b8e23; } /* China - red */ .military-flight-marker.plaaf, .military-flight-marker.plan { --mil-color: #dc143c; } /* Russia - orange */ .military-flight-marker.vks { --mil-color: var(--semantic-high); } /* Israel - spring green */ .military-flight-marker.iaf { --mil-color: var(--status-live); } /* NATO - blue */ .military-flight-marker.nato { --mil-color: var(--semantic-info); } .military-flight-marker.interesting { opacity: 0.9; } .military-flight-marker.bomber, .military-flight-marker.reconnaissance { --mil-color: var(--semantic-critical); opacity: 0.9; } .military-flight-icon { width: 20px; height: 20px; position: relative; transition: transform 0.3s ease; } /* Crosshair horizontal line */ .military-flight-icon::before { content: ''; position: absolute; top: 50%; left: 0; right: 0; height: 3px; background: var(--mil-color); transform: translateY(-50%); box-shadow: 0 0 6px var(--mil-color), 0 0 12px var(--mil-color); } /* Crosshair vertical line */ .military-flight-icon::after { content: ''; position: absolute; left: 50%; top: 0; bottom: 0; width: 3px; background: var(--mil-color); transform: translateX(-50%); box-shadow: 0 0 6px var(--mil-color), 0 0 12px var(--mil-color); } /* Special aircraft types get different crosshair styles */ .military-flight-icon.bomber::before, .military-flight-icon.bomber::after { background: var(--semantic-critical); box-shadow: 0 0 4px var(--semantic-critical); } .military-flight-icon.reconnaissance::before, .military-flight-icon.reconnaissance::after, .military-flight-icon.awacs::before, .military-flight-icon.awacs::after { background: var(--status-live); box-shadow: 0 0 4px var(--status-live); } .military-flight-icon.fighter { width: 22px; height: 22px; } .military-flight-icon.fighter::before, .military-flight-icon.fighter::after { box-shadow: 0 0 5px var(--mil-color); } .military-flight-label { font-size: 7px; color: var(--mil-color); text-transform: uppercase; letter-spacing: 0.3px; margin-top: 1px; white-space: nowrap; text-shadow: 0 0 3px var(--shadow-color), 0 0 6px var(--shadow-color); font-weight: bold; font-family: 'Courier New', monospace; opacity: 0.8; } .military-flight-altitude { font-size: 6px; color: var(--text-dim); font-family: 'Courier New', monospace; opacity: 0.6; text-shadow: 0 0 2px var(--shadow-color); } .military-flight-track { stroke: var(--mil-color, var(--defcon-4)); stroke-opacity: 0.5; } .military-flight-track.usaf, .military-flight-track.usn { stroke: var(--semantic-low); } .military-flight-track.plaaf, .military-flight-track.plan { stroke: var(--semantic-critical); } .military-flight-track.vks { stroke: var(--semantic-high); } @keyframes mil-pulse { 0%, 100% { opacity: 1; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); } 50% { opacity: 0.8; transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.1)); } } @keyframes mil-alert { 0%, 100% { opacity: 1; filter: drop-shadow(0 0 6px var(--mil-color)) drop-shadow(0 0 10px var(--mil-color)); } 50% { opacity: 0.9; filter: drop-shadow(0 0 10px var(--mil-color)) drop-shadow(0 0 20px var(--mil-color)); } } /* ============================================ Military Vessel Tracking Markers ============================================ */ .military-vessel-marker { position: absolute; display: flex; flex-direction: column; align-items: center; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; cursor: pointer; z-index: 54; --vessel-color: var(--status-live); } .military-vessel-marker.usn { --vessel-color: var(--semantic-low); } .military-vessel-marker.rn { --vessel-color: var(--semantic-critical); } .military-vessel-marker.plan { --vessel-color: var(--semantic-critical); } .military-vessel-marker.vks { --vessel-color: var(--semantic-high); } .military-vessel-marker.carrier { --vessel-color: var(--semantic-elevated); z-index: 56; } .military-vessel-marker.submarine { --vessel-color: var(--semantic-info); } .military-vessel-marker.dark-vessel { --vessel-color: var(--semantic-critical); animation: dark-vessel-alert 0.8s ease-in-out infinite; } .military-vessel-marker.interesting { animation: vessel-pulse 1.5s ease-in-out infinite; } .military-vessel-icon { width: 16px; height: 16px; position: relative; transition: transform 0.3s ease; } /* Diamond shape - rotated square */ .military-vessel-icon::before { content: ''; position: absolute; top: 50%; left: 50%; width: 10px; height: 10px; background: transparent; border: 2px solid var(--vessel-color); transform: translate(-50%, -50%) rotate(45deg); box-shadow: 0 0 4px var(--vessel-color); } /* Center dot */ .military-vessel-icon::after { content: ''; position: absolute; top: 50%; left: 50%; width: 4px; height: 4px; background: var(--vessel-color); border-radius: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 3px var(--vessel-color); } /* Submarine - hollow circle */ .military-vessel-icon.submarine::before { border-radius: 50%; transform: translate(-50%, -50%); } /* Carrier - filled diamond */ .military-vessel-icon.carrier::before { background: var(--vessel-color); opacity: 0.6; } .military-vessel-label { font-size: 8px; color: var(--vessel-color); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 2px; white-space: nowrap; text-shadow: 0 0 4px var(--bg), 0 0 8px var(--bg); font-weight: bold; max-width: 80px; overflow: hidden; text-overflow: ellipsis; } .dark-vessel-indicator { position: absolute; top: -8px; right: -8px; font-size: 12px; animation: blink 0.5s step-end infinite; } .military-vessel-track { stroke: var(--vessel-color, var(--status-live)); stroke-opacity: 0.6; } @keyframes vessel-pulse { 0%, 100% { opacity: 1; transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); } 50% { opacity: 0.85; transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.08)); } } @keyframes dark-vessel-alert { 0%, 100% { opacity: 1; --vessel-color: var(--semantic-critical); } 50% { opacity: 0.7; --vessel-color: var(--semantic-high); } } @keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } } /* ============================================ Military Cluster Markers ============================================ */ .military-cluster-marker { position: absolute; display: flex; flex-direction: column; align-items: center; transform: translate(-50%, -50%); cursor: pointer; z-index: 57; --cluster-color: var(--status-live); opacity: 0.65; } .military-cluster-marker:hover { opacity: 1; } .military-cluster-marker.flight-cluster { --cluster-color: var(--status-live); } .military-cluster-marker.vessel-cluster { --cluster-color: var(--status-live); } .military-cluster-marker.exercise { --cluster-color: var(--semantic-high); opacity: 0.8; } .military-cluster-marker.patrol { --cluster-color: var(--semantic-normal); } .military-cluster-marker.deployment, .military-cluster-marker.transport { --cluster-color: #6b8e23; } /* Targeting reticle style for cluster count */ .military-cluster-marker .cluster-count { font-size: 12px; font-weight: bold; color: var(--cluster-color); font-family: 'Courier New', monospace; text-shadow: 0 0 4px var(--shadow-color); position: relative; padding: 4px 8px; } /* Corner brackets for targeting look */ .military-cluster-marker .cluster-count::before { content: ''; position: absolute; top: 0; left: 0; width: 8px; height: 8px; border-left: 2px solid var(--cluster-color); border-top: 2px solid var(--cluster-color); } .military-cluster-marker .cluster-count::after { content: ''; position: absolute; top: 0; right: 0; width: 8px; height: 8px; border-right: 2px solid var(--cluster-color); border-top: 2px solid var(--cluster-color); } .military-cluster-marker .cluster-label { font-size: 7px; color: var(--cluster-color); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 3px; white-space: nowrap; font-weight: bold; font-family: 'Courier New', monospace; text-shadow: 0 0 3px var(--shadow-color); opacity: 0.85; position: relative; } /* Bottom brackets */ .military-cluster-marker .cluster-label::before { content: ''; position: absolute; bottom: -2px; left: -4px; width: 6px; height: 6px; border-left: 1px solid var(--cluster-color); border-bottom: 1px solid var(--cluster-color); } .military-cluster-marker .cluster-label::after { content: ''; position: absolute; bottom: -2px; right: -4px; width: 6px; height: 6px; border-right: 1px solid var(--cluster-color); border-bottom: 1px solid var(--cluster-color); } @keyframes cluster-pulse { 0%, 100% { opacity: 0.6; transform: translate(-50%, -50%) scale(1); } 50% { opacity: 0.85; transform: translate(-50%, -50%) scale(1.02); } } /* Military Popup Styles */ /* Military popup headers - ensure readable text */ .popup-header.militaryFlight, .popup-header.militaryVessel, .popup-header.military-flight, .popup-header.military-vessel { background: linear-gradient(90deg, rgba(0, 180, 180, 0.4) 0%, transparent 100%); } .popup-header.militaryFlightCluster, .popup-header.militaryVesselCluster, .popup-header.military-cluster { background: linear-gradient(90deg, rgba(57, 255, 20, 0.3) 0%, transparent 100%); } /* US Military - blue tint */ .popup-header.military-flight.usaf, .popup-header.military-flight.usn, .popup-header.military-flight.usmc, .popup-header.military-flight.usa { background: linear-gradient(90deg, rgba(59, 130, 246, 0.4) 0%, transparent 100%); } /* NATO/UK - purple tint */ .popup-header.military-flight.nato, .popup-header.military-flight.raf { background: linear-gradient(90deg, rgba(99, 102, 241, 0.4) 0%, transparent 100%); } /* Israel - light blue tint */ .popup-header.military-flight.iaf { background: linear-gradient(90deg, rgba(96, 165, 250, 0.4) 0%, transparent 100%); } /* China - lighter red tint for contrast */ .popup-header.military-flight.plaaf, .popup-header.military-flight.plan { background: linear-gradient(90deg, rgba(248, 113, 113, 0.4) 0%, transparent 100%); } /* Russia - orange tint for better contrast */ .popup-header.military-flight.vks { background: linear-gradient(90deg, rgba(251, 146, 60, 0.4) 0%, transparent 100%); } /* Military popup content - ensure readable text */ .popup-header.military-flight .popup-title, .popup-header.military-vessel .popup-title, .popup-header.military-cluster .popup-title, .popup-header.militaryFlight .popup-title, .popup-header.militaryVessel .popup-title, .popup-header.militaryFlightCluster .popup-title, .popup-header.militaryVesselCluster .popup-title { color: var(--accent); } /* Military popup subtitle - always white for contrast */ .popup-body .popup-subtitle { color: var(--accent); } /* Stat values in military popups - green for readability */ .popup-body .stat-value { color: var(--green, var(--status-live)); } /* Attribution text - brighter */ .popup-attribution { color: var(--text-muted); } .cluster-flights, .cluster-vessels { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; font-size: 11px; } .cluster-flight-item, .cluster-vessel-item { padding: 4px 8px; background: var(--overlay-light); border-radius: 4px; color: var(--accent); border-left: 2px solid var(--accent); } .cluster-more { padding: 4px 8px; color: var(--text-muted); font-style: italic; } .popup-description.alert { color: var(--semantic-critical); font-weight: bold; } .popup-attribution { font-size: 10px; color: var(--text-muted); margin-top: 12px; text-align: right; } /* ============================================ Activity Indicators & New Item Badges ============================================ */ /* Panel "new" badge in header */ .panel-new-badge { display: inline-flex; align-items: center; justify-content: center; background: var(--accent); color: var(--bg); font-size: 9px; font-weight: bold; padding: 2px 6px; border-radius: 10px; margin-left: 8px; letter-spacing: 0.3px; text-transform: uppercase; white-space: nowrap; } .panel-new-badge.pulse { animation: badge-pulse 1.5s ease-in-out infinite; } @keyframes badge-pulse { 0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 var(--overlay-heavy); } 50% { transform: scale(1.05); box-shadow: 0 0 8px 2px var(--overlay-heavy); } } /* Panel header glow when has new items */ .panel.has-new .panel-header { background: linear-gradient(90deg, var(--overlay-medium) 0%, transparent 100%); } .panel.has-new .panel-title { color: var(--accent); } /* "NEW" tag on individual news items */ .new-tag { display: inline-block; background: var(--green); color: var(--bg); font-size: 8px; font-weight: bold; padding: 1px 4px; border-radius: 3px; margin-right: 4px; letter-spacing: 0.5px; animation: new-tag-fade 2s ease-out forwards; } @keyframes new-tag-fade { 0% { opacity: 1; } 70% { opacity: 1; } 100% { opacity: 0.6; } } /* Highlight glow on new items (first 30 seconds) */ .item.item-new-highlight { background: linear-gradient(90deg, rgba(68, 255, 136, 0.1) 0%, transparent 50%); border-left-color: var(--green) !important; animation: item-glow 2s ease-out; } @keyframes item-glow { 0% { background: linear-gradient(90deg, rgba(68, 255, 136, 0.25) 0%, transparent 60%); } 100% { background: linear-gradient(90deg, rgba(68, 255, 136, 0.1) 0%, transparent 50%); } } /* Subtle indicator for items user hasn't seen */ .item.item-new { border-left-color: var(--accent); } /* Flash highlight animation (for search results) */ .flash-highlight { animation: flash-highlight 1.5s ease-out; } @keyframes flash-highlight { 0% { background: var(--overlay-heavy); } 100% { background: transparent; } } /* Panel flash when new items arrive */ .panel.flash-new { animation: panel-flash 0.5s ease-out; } @keyframes panel-flash { 0% { box-shadow: 0 0 20px rgba(68, 255, 136, 0.4); } 100% { box-shadow: none; } } /* ============================================ Virtual Scrolling / Windowed List ============================================ */ /* Windowed list container */ .windowed-list { contain: strict; overflow-y: auto; overflow-x: hidden; } /* Chunk containers for windowed rendering */ .windowed-chunk { contain: content; } /* Placeholder for unrendered chunks */ .windowed-chunk:not(.rendered) { min-height: 100px; /* Estimated height before render */ } /* Virtual list viewport */ .virtual-viewport { overflow-y: auto; overflow-x: hidden; height: 100%; contain: strict; } .virtual-content { position: relative; } .virtual-item { contain: content; will-change: transform; } .virtual-spacer { pointer-events: none; } /* Performance hints for scrolling */ .panel-content { will-change: scroll-position; contain: layout style; } /* Mobile Warning Modal */ .mobile-warning-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: var(--bg); backdrop-filter: blur(4px); display: none; align-items: center; justify-content: center; z-index: 3000; padding: 20px; } .mobile-warning-overlay.active { display: flex; } .mobile-warning-modal { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; max-width: 360px; width: 100%; box-shadow: 0 8px 32px var(--shadow-color); animation: mobile-warning-appear 0.3s ease-out; will-change: transform, opacity; } @keyframes mobile-warning-appear { from { opacity: 0; transform: scale(0.9) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } } .mobile-warning-header { display: flex; align-items: center; gap: 10px; padding: 16px 20px; border-bottom: 1px solid var(--border); } .mobile-warning-icon { font-size: 24px; } .mobile-warning-title { font-size: 16px; font-weight: 600; color: var(--text); } .mobile-warning-content { padding: 20px; color: var(--text-dim); font-size: 13px; line-height: 1.6; } .mobile-warning-content p { margin: 0 0 12px 0; } .mobile-warning-content p:last-child { margin-bottom: 0; } .mobile-warning-footer { display: flex; flex-direction: column; gap: 12px; padding: 16px 20px; border-top: 1px solid var(--border); background: var(--darken-medium); border-radius: 0 0 8px 8px; } .mobile-warning-remember { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-dim); cursor: pointer; } .mobile-warning-remember input[type="checkbox"] { width: 14px; height: 14px; cursor: pointer; } .mobile-warning-btn { width: 100%; padding: 12px 20px; background: var(--accent); color: var(--bg); border: none; border-radius: 6px; font-size: 13px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; font-family: inherit; } .mobile-warning-btn:hover { background: var(--text); transform: translateY(-1px); } .mobile-warning-btn:active { transform: translateY(0); } /* ========================================================================== PizzINT DEFCON Indicator ========================================================================== */ .pizzint-indicator { position: relative; z-index: 1000; font-family: var(--font-mono); } .pizzint-toggle { display: flex; align-items: center; gap: 6px; background: transparent; border: 1px solid var(--overlay-heavy); border-radius: 4px; padding: 4px 8px; cursor: pointer; transition: all 0.2s; } .pizzint-toggle:hover { background: var(--overlay-medium); border-color: var(--border-strong); } .pizzint-icon { font-size: 14px; } .pizzint-defcon { font-size: 10px; font-weight: bold; padding: 2px 5px; border-radius: 3px; background: var(--text-ghost); color: var(--accent); } .pizzint-score { font-size: 10px; color: var(--text-dim); } .pizzint-panel { position: absolute; top: 100%; left: 0; margin-top: 8px; width: 320px; background: var(--bg); border: 1px solid var(--overlay-heavy); border-radius: 12px; overflow: hidden; box-shadow: 0 8px 32px var(--shadow-color); } .pizzint-panel.hidden { display: none; } .pizzint-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--overlay-medium); } .pizzint-title { font-size: 14px; font-weight: bold; color: var(--accent); } .pizzint-close { background: none; border: none; color: var(--text-faint); font-size: 20px; cursor: pointer; padding: 0; line-height: 1; } .pizzint-close:hover { color: var(--accent); } .pizzint-status-bar { padding: 12px 16px; background: var(--overlay-light); } .pizzint-defcon-label { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--text); text-align: center; } .pizzint-locations { padding: 8px 16px; max-height: 180px; overflow-y: auto; } .pizzint-location { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; border-bottom: 1px solid var(--overlay-light); font-size: 11px; } .pizzint-location:last-child { border-bottom: none; } .pizzint-location-name { color: var(--text); flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-right: 8px; } .pizzint-location-status { padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: bold; text-transform: uppercase; } .pizzint-location-status.spike { background: var(--defcon-1); color: var(--accent); } .pizzint-location-status.high { background: var(--defcon-2); color: var(--accent); } .pizzint-location-status.elevated { background: var(--defcon-3); color: var(--bg); } .pizzint-location-status.nominal { background: var(--defcon-4); color: var(--accent); } .pizzint-location-status.quiet { background: var(--status-live); color: var(--bg); } .pizzint-location-status.closed { background: var(--text-ghost); color: var(--text-dim); } .pizzint-tensions { padding: 12px 16px; border-top: 1px solid var(--overlay-medium); } .pizzint-tensions-title { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--text-faint); margin-bottom: 8px; } .pizzint-tension-row { display: flex; justify-content: space-between; align-items: center; padding: 4px 0; font-size: 11px; } .pizzint-tension-label { color: var(--text); } .pizzint-tension-score { display: flex; align-items: center; gap: 6px; } .pizzint-tension-value { color: var(--accent); font-weight: bold; } .pizzint-tension-trend { font-size: 10px; } .pizzint-tension-trend.rising { color: var(--defcon-2); } .pizzint-tension-trend.falling { color: var(--status-live); } .pizzint-tension-trend.stable { color: var(--text-dim); } .pizzint-footer { display: flex; justify-content: space-between; padding: 8px 16px; border-top: 1px solid var(--overlay-medium); font-size: 10px; color: var(--text-ghost); } .pizzint-footer a { color: var(--text-faint); text-decoration: none; } .pizzint-footer a:hover { color: var(--accent); } /* ========================================================================== Mobile Hamburger Menu ========================================================================== */ .hamburger-btn { display: none; align-items: center; justify-content: center; background: none; border: none; color: var(--text); cursor: pointer; padding: 4px; -webkit-tap-highlight-color: transparent; } .mobile-search-btn { display: none; align-items: center; justify-content: center; background: none; border: none; color: var(--text-dim); cursor: pointer; padding: 4px; margin-left: auto; -webkit-tap-highlight-color: transparent; } .mobile-menu-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); z-index: 9999; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; -webkit-tap-highlight-color: transparent; display: none; } .mobile-menu-overlay.open { opacity: 1; pointer-events: auto; } .mobile-menu { position: fixed; left: 0; top: 0; bottom: 0; width: 280px; max-width: 80vw; background: var(--surface); border-right: 1px solid var(--border); z-index: 10000; transform: translateX(-100%); transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); overflow-y: auto; -webkit-overflow-scrolling: touch; display: none; } .mobile-menu.open { transform: translateX(0); } .mobile-menu-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; } .mobile-menu-title { font-weight: bold; font-size: 14px; letter-spacing: 2px; color: var(--accent); } .mobile-menu-close { background: none; border: none; color: var(--text-dim); cursor: pointer; padding: 4px; display: flex; align-items: center; -webkit-tap-highlight-color: transparent; } .mobile-menu-close:hover { color: var(--text); } .mobile-menu-divider { height: 1px; background: var(--border); margin: 4px 0; } .mobile-menu-item { display: flex; align-items: center; width: 100%; padding: 14px 20px; gap: 12px; background: none; border: none; color: var(--text); font-family: inherit; font-size: 14px; cursor: pointer; text-decoration: none; min-height: 44px; -webkit-tap-highlight-color: transparent; transition: background 0.15s ease; } .mobile-menu-item:hover { background: var(--overlay-subtle); } .mobile-menu-item:active { background: var(--overlay-medium); } .mobile-menu-item-icon { width: 20px; text-align: center; font-size: 16px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; } .mobile-menu-item-label { flex: 1; text-align: left; } .mobile-menu-check { color: var(--green); font-size: 14px; } .mobile-menu-chevron { color: var(--text-dim); font-size: 12px; } .mobile-menu-item.active { color: var(--green); background: rgba(68, 255, 136, 0.06); } .mobile-menu-version { padding: 16px 20px; font-size: 11px; color: var(--text-ghost); } .region-sheet-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); z-index: 10001; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; -webkit-tap-highlight-color: transparent; display: none; } .region-sheet-backdrop.open { opacity: 1; pointer-events: auto; } .region-bottom-sheet { position: fixed; left: 0; right: 0; bottom: 0; max-height: 60vh; background: var(--surface); border-radius: 16px 16px 0 0; z-index: 10002; transform: translateY(100%); transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); overflow-y: auto; -webkit-overflow-scrolling: touch; display: none; padding-bottom: env(safe-area-inset-bottom, 0); } .region-bottom-sheet.open { transform: translateY(0); } .region-sheet-header { padding: 16px 20px 12px; font-size: 15px; font-weight: 600; color: var(--text); text-align: center; } .region-sheet-divider { height: 1px; background: var(--border); } .region-sheet-option { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 14px 20px; background: none; border: none; color: var(--text); font-family: inherit; font-size: 15px; cursor: pointer; min-height: 44px; -webkit-tap-highlight-color: transparent; transition: background 0.15s ease; } .region-sheet-option:hover { background: var(--overlay-subtle); } .region-sheet-option:active { background: var(--overlay-medium); } .region-sheet-option.active { color: var(--green); } .region-sheet-check { color: var(--green); font-size: 16px; min-width: 20px; text-align: right; } @media (max-width: 768px) { .hamburger-btn { display: flex; } .mobile-search-btn { display: none; } .mobile-menu-overlay { display: block; } .mobile-menu { display: block; } .region-sheet-backdrop { display: block; } .region-bottom-sheet { display: block; } .variant-switcher, .version, .beta-badge, .credit-link, .github-link, .region-selector, .mobile-settings-btn, .header-right { display: none !important; } .header { gap: 8px; padding: 8px 12px; } .header-left { flex: 1; gap: 8px; } .status-indicator span { display: none; } } /* ========================================================================== Mobile Touch Optimization ========================================================================== */ /* Narrow viewport only — keep 768 in sync with MOBILE_BREAKPOINT_PX in src/utils/index.ts */ @media (max-width: 768px) { /* Expand touch targets for all map markers using ::before pseudo-element */ /* This creates an invisible touch area around small markers */ #mapOverlays [class*='-marker']::before, #mapOverlays .hotspot::before, #mapOverlays .conflict-click-area::before { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 44px; height: 44px; min-width: 44px; min-height: 44px; border-radius: 50%; pointer-events: auto; /* Uncomment to debug: background: rgba(255, 0, 0, 0.2); */ } .conflict-click-area { min-width: 44px; min-height: 44px; } /* Ensure hotspot container is large enough for touch */ .hotspot { min-width: 44px; min-height: 44px; display: flex; align-items: center; justify-content: center; } /* Increase marker visual sizes slightly for better visibility */ .hotspot-marker { width: 16px; height: 16px; } .base-marker { width: 12px; height: 12px; } /* Add spacing to prevent marker overlap on dense areas */ .hotspot, .base-marker, .nuclear-marker, .economic-marker { z-index: 50; } /* Hide ALL labels on mobile for cleaner view */ .hotspot-label, .base-label, .earthquake-label, .nuclear-label, .economic-label, .weather-label, .outage-label, .cable-advisory-label, .repair-ship-label, .protest-label, .flight-delay-label, .military-flight-label, .military-vessel-label, .cluster-label, .irradiator-label, .spaceport-label, .mineral-label, .conflict-label-overlay, .country-label { display: none !important; } /* Hide layer toggle buttons on mobile - use fixed layers */ .layer-toggles { display: none !important; } /* Single-column panel layout on mobile */ .panels-grid { display: flex !important; flex-direction: column; gap: 8px; padding: 8px; } body { font-size: 14px; } .panel-title { font-size: 13px; } .panel { width: 100% !important; min-height: 250px; max-height: min(70vh, 500px); } .panel-content { font-size: 13px; -webkit-overflow-scrolling: touch; } /* Full-viewport map on mobile (Google Maps-like experience) */ .map-section { height: calc(100vh - 48px) !important; height: calc(100dvh - 48px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)) !important; min-height: 60vh !important; max-height: 100dvh !important; } /* Collapsed map on mobile — higher specificity overrides .map-section above */ .main-content .map-section.collapsed { height: auto !important; min-height: 0 !important; max-height: none !important; } .main-content .map-section.collapsed .map-container, .main-content .map-section.collapsed .map-resize-handle, .main-content .map-section.collapsed .map-controls, .main-content .map-section.collapsed .time-slider, .main-content .map-section.collapsed .tv-exit-btn { display: none; } /* Map collapse toggle button — mobile only */ .map-collapse-btn { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; padding: 4px 10px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg-secondary); color: var(--text-secondary); font-size: 12px; cursor: pointer; white-space: nowrap; } .map-collapse-btn:active { background: var(--bg-tertiary, var(--border)); } /* Hide pin button and resize handles on mobile */ .map-pin-btn, .map-resize-handle, .panel-resize-handle { display: none !important; } /* Simplify time slider on mobile */ .map-controls { top: calc(env(safe-area-inset-top, 0px) + 8px); right: calc(env(safe-area-inset-right, 0px) + 8px); } .time-slider { top: calc(env(safe-area-inset-top, 0px) + 8px); left: calc(env(safe-area-inset-left, 0px) + 8px); right: calc(env(safe-area-inset-right, 0px) + 56px); max-width: none; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding: 4px 8px; gap: 6px; } .time-slider::-webkit-scrollbar { display: none; } .time-slider-label { display: none; } .time-slider-buttons { flex-wrap: nowrap; min-width: max-content; } /* Larger map controls */ .map-control-btn { width: 44px; height: 44px; font-size: 20px; } /* Time slider buttons */ .time-btn { flex: 0 0 auto; padding: 8px 12px; min-height: 36px; } /* Map popup positioning for mobile - ensure it's visible */ .map-popup { max-width: calc(100vw - 32px); max-height: 60vh; overflow-y: auto; } .map-popup.map-popup-sheet { left: 10px !important; right: 10px !important; max-height: min(72vh, calc(100vh - 64px)); } .popup-close { min-width: 44px; min-height: 44px; } /* Hide some UI elements that clutter mobile view */ .map-timestamp { font-size: 9px; } .map-legend { display: none; } /* Hide DEFCON indicator and FOCUS region selector on mobile */ .pizzint-indicator, .focus-label, .focus-select { display: none !important; } /* Mobile: show "World Monitor" instead of "MONITOR" */ .logo { display: none; } .logo-mobile { display: inline; } /* Mobile: hide "Global Situation" panel title */ .map-section .panel-title { display: none; } /* Mobile: hide the UTC clock */ .header-clock { display: none !important; } /* Mobile: hide community discussion widget (accessible via settings) */ .community-widget { display: none !important; } .focus-label { display: none; } /* Simplify layer help popup for mobile */ .layer-help-popup { max-width: calc(100vw - 20px); max-height: 70vh; } /* Ensure conflict click areas are large enough */ .conflict-click-area { cursor: pointer; pointer-events: auto; } } /* Extra small screens */ @media (max-width: 480px) { .layer-toggles { max-height: 80px; overflow-x: auto; overflow-y: hidden; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; } .layer-toggle { flex-shrink: 0; padding: 6px 10px; font-size: 9px; min-width: 50px; } .map-popup { left: 10px !important; right: 10px !important; width: auto !important; max-width: none; } .map-popup.map-popup-sheet { left: 8px !important; right: 8px !important; } .header { padding: 8px; } } /* ========================================================================== GDELT Intelligence Panel ========================================================================== */ .gdelt-intel-tabs { display: flex; gap: 2px; padding: 8px 10px 0; overflow-x: auto; border-bottom: 1px solid var(--border); background: var(--bg); scrollbar-width: none; -ms-overflow-style: none; } .gdelt-intel-tabs::-webkit-scrollbar { display: none; } .gdelt-intel-tab { display: flex; align-items: center; gap: 4px; padding: 6px 10px; background: transparent; border: none; border-bottom: 2px solid transparent; color: var(--text-dim); font-size: 11px; font-family: inherit; cursor: pointer; transition: all 0.15s ease; white-space: nowrap; flex-shrink: 0; } .gdelt-intel-tab:hover { color: var(--text); background: var(--overlay-subtle); } .gdelt-intel-tab.active { color: var(--accent); border-bottom-color: var(--accent); } .gdelt-intel-tab .tab-icon { font-size: 12px; } .gdelt-intel-tab .tab-label { font-weight: 500; } .gdelt-intel-articles { display: flex; flex-direction: column; gap: 1px; } .gdelt-intel-article { display: block; padding: 10px 12px; background: var(--surface); text-decoration: none; transition: background 0.15s ease; border-left: 2px solid transparent; } .gdelt-intel-article:hover { background: var(--overlay-light); border-left-color: var(--accent); } .gdelt-intel-article.tone-negative { border-left-color: var(--danger); } .gdelt-intel-article.tone-positive { border-left-color: var(--success); } .gdelt-intel-article .article-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; gap: 8px; } .gdelt-intel-article .article-source { font-size: 10px; color: var(--accent); font-weight: 500; text-transform: uppercase; letter-spacing: 0.3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 60%; } .gdelt-intel-article .article-time { font-size: 10px; color: var(--text-dim); flex-shrink: 0; } .gdelt-intel-article .article-title { font-size: 12px; color: var(--text); line-height: 1.4; display: -webkit-box; line-clamp: 2; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } /* Hotspot GDELT Context */ .hotspot-gdelt-context { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); } .hotspot-gdelt-header { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; font-size: 11px; color: var(--text-dim); font-weight: 500; } .hotspot-gdelt-header::before { content: '📡'; font-size: 12px; } .hotspot-gdelt-articles { display: flex; flex-direction: column; gap: 6px; } .hotspot-gdelt-article { display: block; padding: 8px; background: var(--darken-medium); border-radius: 4px; text-decoration: none; transition: background 0.15s ease; } .hotspot-gdelt-article:hover { background: var(--darken-heavy); } .hotspot-gdelt-article .article-meta { display: flex; justify-content: space-between; font-size: 9px; color: var(--text-dim); margin-bottom: 3px; } .hotspot-gdelt-article .article-title { font-size: 11px; color: var(--text); line-height: 1.35; display: -webkit-box; line-clamp: 2; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } .hotspot-gdelt-loading { padding: 12px; text-align: center; color: var(--text-dim); font-size: 11px; } /* CII Panel */ .cii-list { display: flex; flex-direction: column; gap: 8px; padding: 8px; } .cii-country { background: var(--darken-medium); border-radius: 4px; padding: 8px; cursor: pointer; transition: background 0.1s ease, border-color 0.1s ease; border: 1px solid transparent; } .cii-country:hover { background: var(--surface-hover); border-color: var(--border); } .cii-header { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; } .cii-emoji { font-size: 12px; } .cii-name { flex: 1; font-size: 12px; font-weight: 500; color: var(--text); } .cii-score { font-size: 14px; font-weight: 700; color: var(--accent); font-family: var(--font-mono); } .cii-header .trend-up { color: var(--semantic-critical); font-size: 11px; } .cii-header .trend-down { color: var(--semantic-normal); font-size: 11px; } .cii-header .trend-stable { color: var(--text-dim); font-size: 11px; } .cii-bar-container { height: 4px; background: var(--overlay-medium); border-radius: 2px; overflow: hidden; margin-bottom: 6px; } .cii-bar { height: 100%; border-radius: 2px; transition: width 0.3s ease; } .cii-components { display: flex; gap: 8px; font-size: 10px; color: var(--text-dim); font-family: var(--font-mono); } .cii-components span { cursor: help; } /* CII Learning Mode */ .cii-learning-banner { display: flex; align-items: center; gap: 8px; padding: 8px 10px; background: rgba(255, 170, 0, 0.15); border: 1px solid rgba(255, 170, 0, 0.3); border-radius: 4px; margin-bottom: 8px; } .cii-learning-banner .learning-icon { font-size: 16px; } .cii-learning-banner .learning-text { flex: 1; } .cii-learning-banner .learning-title { font-size: 10px; font-weight: bold; color: var(--semantic-elevated); text-transform: uppercase; letter-spacing: 0.5px; } .cii-learning-banner .learning-desc { font-size: 9px; color: var(--text-dim); } .cii-learning-banner .learning-progress { width: 60px; height: 3px; background: var(--overlay-medium); border-radius: 2px; overflow: hidden; } .cii-learning-banner .learning-bar { height: 100%; background: var(--semantic-elevated); transition: width 1s ease; } /* Dim scores during learning */ .cii-learning .cii-country { opacity: 0.6; } /* CII Awaiting focal points state - modern radar scan */ .cii-awaiting { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 32px 20px; text-align: center; gap: 16px; } .cii-scan-ring { width: 48px; height: 48px; border-radius: 50%; border: 2px solid rgba(100, 200, 255, 0.2); position: relative; animation: scan-pulse 2s ease-in-out infinite; } .cii-scan-ring::before { content: ''; position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; border-radius: 50%; border: 2px solid transparent; border-top-color: rgba(100, 200, 255, 0.8); animation: scan-rotate 1.5s linear infinite; } .cii-scan-dot { position: absolute; top: 50%; left: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px; background: rgba(100, 200, 255, 0.8); border-radius: 50%; animation: scan-blink 1s ease-in-out infinite; } @keyframes scan-rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes scan-pulse { 0%, 100% { transform: scale(1); opacity: 0.8; } 50% { transform: scale(1.05); opacity: 1; } } @keyframes scan-blink { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } } .cii-awaiting-text { font-size: 13px; font-weight: 500; color: var(--text-secondary); letter-spacing: 0.3px; } .cii-awaiting-sources { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; } .cii-source-chip { font-size: 10px; padding: 3px 8px; background: rgba(100, 200, 255, 0.1); border: 1px solid rgba(100, 200, 255, 0.2); border-radius: 10px; color: rgba(100, 200, 255, 0.7); text-transform: uppercase; letter-spacing: 0.5px; } @keyframes pulse { 0%, 100% { opacity: 0.5; transform: scale(1); } 50% { opacity: 1; transform: scale(1.05); } } /* Tech Readiness Panel */ .tech-readiness-list { display: flex; flex-direction: column; gap: 2px; } .readiness-item { display: flex; align-items: center; gap: 8px; padding: 6px 8px; background: var(--overlay-subtle); border-radius: 4px; transition: background 0.2s; } .readiness-item:hover { background: var(--overlay-light); } .readiness-rank { font-size: 10px; color: var(--text-dim); min-width: 24px; } .readiness-flag { font-size: 16px; } .readiness-info { flex: 1; min-width: 0; } .readiness-name { font-size: 12px; font-weight: 500; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .readiness-components { display: flex; gap: 8px; font-size: 10px; color: var(--text-dim); margin-top: 2px; } .readiness-components span { display: flex; align-items: center; gap: 2px; } .readiness-score { font-size: 14px; font-weight: 600; min-width: 32px; text-align: right; } .readiness-score.high { color: var(--green); } .readiness-score.medium { color: var(--yellow); } .readiness-score.low { color: var(--text-dim); } .readiness-footer { display: flex; justify-content: space-between; font-size: 10px; color: var(--text-dim); margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); } /* Tech Readiness Loading State */ .tech-fetch-progress { display: flex; flex-direction: column; align-items: center; padding: 24px 16px; gap: 16px; } .tech-fetch-icon { position: relative; width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; } .tech-globe { font-size: 24px; z-index: 1; } .tech-globe-ring { position: absolute; inset: 0; border: 2px solid rgba(100, 200, 255, 0.2); border-radius: 50%; } .tech-globe-ring::before { content: ''; position: absolute; inset: -2px; border: 2px solid transparent; border-top-color: rgba(100, 200, 255, 0.8); border-radius: 50%; animation: tech-spin 1.5s linear infinite; } @keyframes tech-spin { to { transform: rotate(360deg); } } .tech-fetch-title { font-size: 12px; font-weight: 500; color: var(--text); text-align: center; } .tech-fetch-indicators { display: flex; flex-direction: column; gap: 6px; width: 100%; max-width: 200px; } .tech-indicator-item { display: flex; align-items: center; gap: 8px; font-size: 11px; padding: 6px 10px; background: var(--overlay-subtle); border-radius: 4px; animation: tech-item-pulse 2s ease-in-out infinite; } @keyframes tech-item-pulse { 0%, 100% { opacity: 0.4; background: var(--overlay-subtle); } 50% { opacity: 1; background: rgba(100, 200, 255, 0.08); } } .tech-indicator-icon { font-size: 12px; } .tech-indicator-name { flex: 1; color: var(--text-dim); } .tech-indicator-status { width: 6px; height: 6px; border-radius: 50%; background: rgba(100, 200, 255, 0.5); animation: tech-dot-blink 1s ease-in-out infinite; } @keyframes tech-dot-blink { 0%, 100% { opacity: 0.3; transform: scale(0.8); } 50% { opacity: 1; transform: scale(1.2); } } .tech-fetch-note { font-size: 10px; color: var(--text-dim); text-align: center; } /* Cascade Panel Styles */ .cascade-panel { display: flex; flex-direction: column; gap: 12px; padding: 8px 0; } .cascade-stats { display: flex; gap: 12px; font-size: 11px; color: var(--text-dim); padding: 8px 12px; background: var(--overlay-subtle); border-radius: 4px; } .cascade-selector { display: flex; flex-direction: column; gap: 8px; } .cascade-filters { display: flex; gap: 4px; flex-wrap: wrap; } .cascade-filter-btn { padding: 4px 8px; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; color: var(--text-dim); font-size: 11px; cursor: pointer; transition: all 0.2s; } .cascade-filter-btn:hover { background: var(--overlay-medium); color: var(--text); } .cascade-filter-btn.active { background: rgba(68, 255, 136, 0.15); border-color: var(--green); color: var(--green); } .cascade-select { width: 100%; padding: 8px; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; color: var(--text); font-size: 12px; cursor: pointer; } .cascade-select:disabled { opacity: 0.5; cursor: not-allowed; } .cascade-analyze-btn { padding: 8px 16px; background: var(--green); border: none; border-radius: 4px; color: var(--bg); font-size: 12px; font-weight: bold; cursor: pointer; transition: all 0.2s; } .cascade-analyze-btn:hover:not(:disabled) { background: var(--status-live); } .cascade-analyze-btn:disabled { opacity: 0.5; cursor: not-allowed; } .cascade-hint { text-align: center; color: var(--text-dim); font-size: 11px; padding: 20px; } .cascade-result { display: flex; flex-direction: column; gap: 12px; } .cascade-source { display: flex; align-items: center; gap: 8px; padding: 10px; background: rgba(68, 255, 136, 0.1); border: 1px solid var(--green); border-radius: 4px; } .cascade-emoji { font-size: 14px; } .cascade-source-name { font-weight: bold; flex: 1; } .cascade-source-type { font-size: 10px; color: var(--text-dim); text-transform: uppercase; } .cascade-section { display: flex; flex-direction: column; gap: 6px; } .cascade-section-title { font-size: 11px; font-weight: bold; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; } .cascade-countries { display: flex; flex-direction: column; gap: 4px; max-height: 200px; overflow-y: auto; } .cascade-country { display: flex; align-items: center; gap: 8px; padding: 6px 8px; background: var(--overlay-subtle); border-radius: 4px; } .cascade-country-name { flex: 1; } .cascade-impact { font-size: 10px; text-transform: uppercase; font-weight: bold; } .cascade-capacity { font-size: 10px; color: var(--text-dim); } .cascade-redundancy { display: flex; align-items: center; gap: 8px; padding: 6px 8px; background: rgba(68, 255, 136, 0.05); border-radius: 4px; } .cascade-redundancy-name { flex: 1; font-size: 11px; } .cascade-redundancy-capacity { font-size: 11px; color: var(--green); font-weight: bold; } /* Strategic Risk Panel */ .strategic-risk-panel { display: flex; flex-direction: column; gap: 12px; padding: 8px; } .risk-gauge { display: flex; align-items: center; justify-content: center; gap: 24px; padding: 16px; background: linear-gradient(135deg, var(--overlay-subtle) 0%, var(--overlay-light) 100%); border-radius: 12px; border: 1px solid var(--border); } .risk-score-container { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; } .risk-score-ring { width: 100px; height: 100px; border-radius: 50%; background: conic-gradient(from 135deg, var(--score-color, var(--semantic-normal)) 0deg, var(--score-color, var(--semantic-normal)) var(--score-deg, 0deg), var(--overlay-medium) var(--score-deg, 0deg), var(--overlay-medium) 270deg); display: flex; align-items: center; justify-content: center; position: relative; } .risk-score-ring::before { content: ''; position: absolute; width: 80px; height: 80px; border-radius: 50%; background: var(--surface); } .risk-score-inner { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; } .risk-score { font-size: 32px; font-weight: bold; line-height: 1; } .risk-level { font-size: 10px; font-weight: bold; text-transform: uppercase; letter-spacing: 0.5px; margin-top: 2px; } .risk-trend-container { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; } .risk-trend-label { font-size: 10px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; } .risk-trend { display: flex; align-items: center; gap: 6px; font-size: 16px; font-weight: bold; } .risk-metrics { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; } .risk-metric { display: flex; flex-direction: column; align-items: center; padding: 8px 4px; background: var(--overlay-subtle); border-radius: 6px; border: 1px solid var(--border); transition: all 0.2s ease; } .risk-metric:hover { background: var(--overlay-light); border-color: var(--accent); } .risk-metric-value { font-size: 18px; font-weight: bold; color: var(--accent); } .risk-metric-label { font-size: 8px; color: var(--text-dim); text-transform: uppercase; text-align: center; letter-spacing: 0.3px; line-height: 1.2; } .risk-section { display: flex; flex-direction: column; gap: 6px; } .risk-section-title { font-size: 10px; font-weight: bold; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; padding-bottom: 4px; border-bottom: 1px solid var(--border); } .risk-list { display: flex; flex-direction: column; gap: 4px; } .risk-item { display: flex; align-items: flex-start; gap: 6px; padding: 6px 8px; background: rgba(255, 136, 0, 0.08); border-radius: 4px; border-left: 2px solid var(--yellow); } .risk-rank { font-size: 10px; font-weight: bold; color: var(--yellow); min-width: 14px; } .risk-text { font-size: 10px; line-height: 1.3; } .risk-countries { display: flex; flex-direction: column; gap: 3px; max-height: 120px; overflow-y: auto; } .risk-country { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 8px; padding: 5px 8px; background: var(--overlay-subtle); border-radius: 4px; } .risk-country-name { font-size: 11px; font-weight: 500; } .risk-country-score { font-size: 13px; font-weight: bold; min-width: 28px; text-align: right; } .risk-country-level { font-size: 9px; text-transform: uppercase; color: var(--text-dim); min-width: 50px; } .risk-alerts { display: flex; flex-direction: column; gap: 4px; max-height: 150px; overflow-y: auto; } .risk-alert { display: flex; flex-direction: column; gap: 2px; padding: 6px 8px; background: var(--overlay-subtle); border-radius: 4px; } .risk-alert-header { display: flex; align-items: center; gap: 4px; } .risk-alert-type { font-size: 11px; } .risk-alert-priority { font-size: 9px; } .risk-alert-title { font-size: 10px; font-weight: bold; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .risk-alert-summary { font-size: 9px; color: var(--text-dim); line-height: 1.3; display: -webkit-box; line-clamp: 2; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } .risk-alert-time { font-size: 8px; color: var(--text-dim); text-align: right; } .risk-item-clickable, .risk-alert-clickable { cursor: pointer; transition: all 0.15s ease; } .risk-item-clickable:hover, .risk-alert-clickable:hover { background: rgba(68, 136, 255, 0.15); border-left-color: var(--semantic-low); } .risk-location-icon { color: var(--semantic-low); font-size: 10px; margin-left: auto; opacity: 0.7; } .risk-item-clickable:hover .risk-location-icon, .risk-alert-clickable:hover .risk-location-icon { opacity: 1; } .risk-footer { display: flex; align-items: center; justify-content: space-between; padding-top: 6px; margin-top: 4px; border-top: 1px solid var(--border); } .risk-updated { font-size: 9px; color: var(--text-dim); } .risk-refresh-btn { padding: 3px 10px; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; color: var(--text); font-size: 10px; cursor: pointer; transition: all 0.2s; } .risk-refresh-btn:hover { background: var(--overlay-medium); border-color: var(--accent); } .risk-empty { font-size: 11px; color: var(--text-dim); text-align: center; padding: 12px; font-style: italic; } /* Data Availability States */ .risk-no-data { display: flex; flex-direction: column; align-items: center; padding: 20px 12px; text-align: center; background: rgba(255, 136, 0, 0.08); border-radius: 8px; border: 1px dashed rgba(255, 136, 0, 0.3); } .risk-no-data-icon { font-size: 32px; margin-bottom: 8px; } .risk-no-data-title { font-size: 14px; font-weight: bold; color: var(--semantic-high); margin-bottom: 4px; } .risk-no-data-desc { font-size: 11px; color: var(--text-dim); line-height: 1.4; } .risk-warning-banner { display: flex; align-items: center; gap: 6px; padding: 6px 10px; background: rgba(255, 170, 0, 0.15); border-radius: 6px; border: 1px solid rgba(255, 170, 0, 0.3); margin-bottom: 4px; } .risk-warning-icon { font-size: 12px; } .risk-warning-text { font-size: 10px; color: var(--semantic-elevated); font-weight: 500; } .risk-status-banner { display: flex; align-items: center; gap: 6px; padding: 5px 10px; border-radius: 6px; margin-bottom: 4px; } .risk-status-ok { background: rgba(68, 170, 68, 0.12); border: 1px solid rgba(68, 170, 68, 0.25); } .risk-status-icon { font-size: 11px; color: var(--semantic-normal); } .risk-status-text { font-size: 10px; color: var(--semantic-normal); font-weight: 500; } /* Learning Mode Override - must come after base banner styles */ .risk-status-learning { background: rgba(255, 170, 0, 0.15) !important; border: 1px solid rgba(255, 170, 0, 0.3) !important; } .risk-status-learning .risk-warning-icon, .risk-status-learning .risk-status-icon { color: var(--semantic-elevated); } .risk-status-learning .risk-warning-text, .risk-status-learning .risk-status-text { color: var(--semantic-elevated); } .risk-status-learning .learning-progress-mini { width: 40px; height: 2px; background: var(--overlay-medium); border-radius: 1px; overflow: hidden; margin-left: auto; } .risk-status-learning .learning-bar { height: 100%; background: var(--semantic-elevated); transition: width 1s ease; } /* Data Sources */ .risk-sources { display: flex; flex-direction: column; gap: 4px; } .risk-source-row { display: grid; grid-template-columns: 16px 1fr auto auto; align-items: center; gap: 6px; padding: 5px 8px; background: var(--overlay-subtle); border-radius: 4px; font-size: 11px; } .risk-source-status { font-size: 10px; text-align: center; } .risk-source-name { color: var(--text); } .risk-source-time { font-size: 9px; color: var(--text-dim); } .risk-source-enable { padding: 2px 6px; background: transparent; border: 1px solid var(--accent); border-radius: 3px; color: var(--accent); font-size: 9px; cursor: pointer; transition: all 0.2s; } .risk-source-enable:hover { background: var(--accent); color: var(--bg); } /* Compact source chips */ .risk-sources-compact { display: flex; flex-wrap: wrap; gap: 4px; } .risk-source-chip { display: flex; align-items: center; gap: 4px; padding: 3px 8px; background: var(--overlay-subtle); border-radius: 12px; border: 1px solid; font-size: 9px; } .risk-source-dot { font-size: 8px; } .risk-source-chip .risk-source-name { font-size: 9px; } /* Action buttons */ .risk-actions { display: flex; justify-content: center; padding: 8px 0; } .risk-action-btn { padding: 6px 16px; background: transparent; border: 1px solid var(--border); border-radius: 4px; color: var(--text); font-size: 11px; cursor: pointer; transition: all 0.2s; } .risk-action-btn:hover { background: var(--overlay-medium); border-color: var(--accent); } .risk-action-primary { background: var(--accent); border-color: var(--accent); color: var(--bg); } .risk-action-primary:hover { background: var(--semantic-normal); border-color: var(--semantic-normal); } /* ============================================ QUICK WINS: Intelligence UI Enhancements ============================================ */ /* --- Hotspot Popup: Escalation Display --- */ .escalation-section { background: var(--overlay-subtle); border-radius: 6px; padding: 10px; margin: 8px 0; } .escalation-display { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; } .escalation-score { display: flex; flex-direction: column; align-items: center; padding: 8px 14px; border-radius: 6px; min-width: 70px; } .escalation-score .score-value { font-size: 18px; font-weight: 700; color: var(--accent); } .escalation-score .score-label { font-size: 9px; font-weight: 600; color: var(--accent); letter-spacing: 0.5px; } .escalation-trend { display: flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; } .escalation-trend .trend-icon { font-size: 16px; } .escalation-indicators { display: flex; flex-direction: column; gap: 3px; font-size: 10px; color: var(--text-dim); } .indicator-tag { padding: 2px 0; } /* --- Dynamic Escalation Breakdown --- */ .escalation-breakdown { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--overlay-medium); } .breakdown-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; font-size: 10px; } .baseline-label { color: var(--text-dim); } .change-label { font-weight: 600; } .change-label.rising { color: var(--semantic-critical); } .change-label.falling { color: var(--semantic-normal); } .breakdown-components { display: flex; flex-direction: column; gap: 4px; } .breakdown-row { display: flex; align-items: center; gap: 8px; } .component-label { font-size: 9px; color: var(--text-dim); width: 45px; flex-shrink: 0; text-transform: uppercase; letter-spacing: 0.3px; } .component-bar-bg { flex: 1; height: 6px; background: var(--overlay-medium); border-radius: 3px; overflow: hidden; } .component-bar { height: 100%; border-radius: 3px; transition: width 0.3s ease; } .component-bar.news { background: linear-gradient(90deg, var(--semantic-info), var(--semantic-low)); } .component-bar.cii { background: linear-gradient(90deg, var(--semantic-high), var(--semantic-elevated)); } .component-bar.geo { background: linear-gradient(90deg, var(--semantic-critical), var(--semantic-critical)); } .component-bar.military { background: linear-gradient(90deg, var(--semantic-info), var(--semantic-info)); } .component-value { font-size: 9px; color: var(--text-dim); width: 20px; text-align: right; flex-shrink: 0; } /* --- Hotspot Popup: Historical Context --- */ .history-section { background: rgba(100, 100, 255, 0.05); border-radius: 6px; padding: 10px; margin: 8px 0; border-left: 3px solid rgba(100, 150, 255, 0.4); } .history-content { display: flex; flex-direction: column; gap: 6px; } .history-event { font-size: 11px; line-height: 1.4; } .history-event .history-label { color: var(--text-dim); font-weight: 500; margin-right: 4px; } .history-event .history-value { color: var(--text); } .history-event.cyclical { color: var(--warning); font-style: italic; } /* --- Hotspot Popup: Why It Matters --- */ .why-matters-section { background: rgba(255, 200, 100, 0.08); border-radius: 6px; padding: 10px; margin: 8px 0; border-left: 3px solid rgba(255, 180, 0, 0.5); } .why-matters-text { font-size: 11px; line-height: 1.5; color: var(--text); margin: 0; font-style: italic; } /* --- Signal Modal: Context Display --- */ .signal-context { background: var(--overlay-subtle); border-radius: 6px; padding: 10px; margin-top: 8px; border-left: 3px solid var(--accent); } .signal-context-item { margin-bottom: 8px; font-size: 11px; line-height: 1.4; } .signal-context-item:last-child { margin-bottom: 0; } .signal-context-item .context-label { color: var(--accent); font-weight: 600; font-size: 9px; text-transform: uppercase; letter-spacing: 0.3px; display: block; margin-bottom: 2px; } .signal-context-item .context-value { color: var(--text); } .signal-context-item.why-matters { border-left-color: var(--semantic-elevated); } .signal-context-item.actionable .context-label { color: var(--status-live); } .signal-context-item.confidence-note { font-size: 10px; color: var(--text-dim); font-style: italic; } .location-link { background: rgba(68, 136, 255, 0.15); border: 1px solid rgba(68, 136, 255, 0.4); border-radius: 4px; color: var(--semantic-low); padding: 4px 10px; font-family: var(--font-mono); font-size: 12px; cursor: pointer; transition: all 0.15s ease; } .location-link:hover { background: rgba(68, 136, 255, 0.3); border-color: var(--semantic-low); color: var(--semantic-low); } /* --- Signal Modal: Focal Points & News Correlation --- */ .signal-focal-points, .signal-news-correlation { background: rgba(139, 92, 246, 0.08); border: 1px solid rgba(139, 92, 246, 0.25); border-radius: 6px; padding: 10px; margin: 10px 0; } .signal-news-correlation { background: rgba(68, 136, 255, 0.08); border-color: rgba(68, 136, 255, 0.25); } .focal-points-header, .news-correlation-header { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--semantic-info); margin-bottom: 8px; } .news-correlation-header { color: var(--semantic-low); } .focal-point-item { font-size: 11px; color: var(--text); padding: 4px 0; border-bottom: 1px solid var(--overlay-light); } .focal-point-item:last-child { border-bottom: none; } .news-correlation-text { font-family: var(--font-mono); font-size: 10px; color: var(--text); white-space: pre-wrap; margin: 0; line-height: 1.5; } .signal-location { margin: 8px 0; } .signal-item.military_surge { border-left-color: var(--semantic-critical); } /* --- News Panel: Propaganda Risk Badges --- */ .propaganda-badge { display: inline-flex; align-items: center; gap: 2px; padding: 1px 5px; border-radius: 3px; font-size: 8px; font-weight: 600; margin-left: 4px; vertical-align: middle; } .propaganda-badge.high { background: rgba(255, 60, 60, 0.2); color: var(--semantic-critical); border: 1px solid rgba(255, 60, 60, 0.3); } .propaganda-badge.medium { background: rgba(255, 170, 0, 0.15); color: var(--semantic-elevated); border: 1px solid rgba(255, 170, 0, 0.3); } .top-source .propaganda-badge { font-size: 7px; padding: 0 3px; margin-left: 2px; } /* --- Intelligence Findings Badge --- */ .intel-findings-badge { display: flex; align-items: center; gap: 4px; padding: 4px 10px; background: transparent; border: 1px solid var(--border); border-radius: 4px; color: var(--text); font-size: 11px; cursor: pointer; transition: all 0.2s; position: relative; } .intel-findings-badge:hover { background: var(--overlay-light); border-color: var(--accent); } .intel-findings-badge.active { background: var(--overlay-medium); border-color: var(--accent); } .intel-findings-badge .findings-icon { font-size: 12px; } .intel-findings-badge .findings-count { background: var(--border); padding: 1px 5px; border-radius: 8px; font-size: 10px; font-weight: 600; min-width: 14px; text-align: center; } .intel-findings-badge.status-none { border-color: var(--overlay-heavy); } .intel-findings-badge.status-none .findings-count { background: var(--overlay-heavy); color: var(--text-dim); } .intel-findings-badge.status-low { border-color: rgba(74, 158, 255, 0.4); } .intel-findings-badge.status-low .findings-count { background: rgba(74, 158, 255, 0.3); color: var(--semantic-low); } .intel-findings-badge.status-high { border-color: rgba(255, 149, 0, 0.5); animation: findings-pulse 2s infinite; } .intel-findings-badge.status-high .findings-count { background: rgba(255, 149, 0, 0.3); color: var(--semantic-elevated); } .intel-findings-badge.pulse { animation: findings-new 0.5s ease-out; } @keyframes findings-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(255, 149, 0, 0); } 50% { box-shadow: 0 0 8px 2px rgba(255, 149, 0, 0.3); } } @keyframes findings-new { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } } /* --- Intelligence Findings Dropdown --- */ .intel-findings-dropdown { position: absolute; top: 100%; right: 0; width: 380px; background: var(--border-subtle); border: 1px solid var(--border); border-radius: 6px; box-shadow: 0 8px 24px var(--shadow-color); z-index: 1000; display: none; margin-top: 4px; } .intel-findings-dropdown.open { display: block; } .findings-header { display: flex; justify-content: space-between; align-items: center; padding: 10px 12px; border-bottom: 1px solid var(--border); } .findings-header .header-title { font-size: 12px; font-weight: 600; color: var(--text); } .findings-badge { padding: 3px 8px; border-radius: 4px; font-size: 9px; font-weight: 600; } .findings-badge.none { background: var(--overlay-heavy); color: var(--text-dim); } .findings-badge.moderate { background: rgba(74, 158, 255, 0.2); color: var(--semantic-low); } .findings-badge.high { background: rgba(255, 149, 0, 0.2); color: var(--semantic-elevated); } .findings-badge.critical { background: rgba(255, 59, 48, 0.3); color: var(--semantic-critical); animation: critical-pulse 1.5s ease-in-out infinite; } .popup-toggle-row { display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; border-bottom: 1px solid var(--border); cursor: pointer; user-select: none; transition: background 0.15s; } .popup-toggle-row:hover { background: var(--overlay-subtle); } .popup-toggle-label { font-size: 11px; color: var(--text-dim); } .popup-toggle-switch { position: relative; width: 32px; height: 18px; border-radius: 9px; background: var(--overlay-heavy); transition: background 0.2s; flex-shrink: 0; } .popup-toggle-switch.on { background: #3b82f6; } .popup-toggle-knob { position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: #888; transition: transform 0.2s, background 0.2s; } .popup-toggle-switch.on .popup-toggle-knob { transform: translateX(14px); background: #fff; } .findings-content { padding: 10px 12px; max-height: 400px; overflow-y: auto; } .findings-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 24px 12px; color: var(--text-dim); } .findings-empty .empty-icon { font-size: 24px; opacity: 0.5; } .findings-empty .empty-text { font-size: 11px; text-align: center; } .findings-list { display: flex; flex-direction: column; gap: 8px; } .finding-item { padding: 10px 12px; background: var(--overlay-subtle); border-radius: 6px; border-left: 3px solid var(--accent); cursor: pointer; transition: background 0.2s; } .finding-item:hover { background: var(--overlay-light); } .finding-item.critical { border-left-color: var(--semantic-critical); background: rgba(255, 59, 48, 0.05); } .finding-item.high { border-left-color: var(--semantic-elevated); } .finding-item.medium { border-left-color: var(--semantic-low); } .finding-item.low { border-left-color: var(--text-muted); } .finding-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; } .finding-type { font-size: 11px; font-weight: 600; color: var(--text); } .finding-confidence { padding: 2px 6px; border-radius: 4px; font-size: 9px; font-weight: 600; } .finding-confidence.critical { background: rgba(255, 59, 48, 0.3); color: var(--semantic-critical); animation: critical-pulse 1.5s ease-in-out infinite; } .finding-confidence.high { background: rgba(255, 149, 0, 0.2); color: var(--semantic-elevated); } .finding-confidence.medium { background: rgba(74, 158, 255, 0.2); color: var(--semantic-low); } .finding-confidence.low { background: var(--overlay-heavy); color: var(--text-dim); } @keyframes critical-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } } .finding-description { font-size: 10px; color: var(--text-dim); line-height: 1.4; margin-bottom: 6px; } .finding-meta { display: flex; justify-content: space-between; align-items: center; } .finding-insight { font-size: 9px; color: var(--accent); font-style: italic; max-width: 70%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .finding-time { font-size: 9px; color: var(--text-dim); } .findings-more { text-align: center; padding: 8px; font-size: 10px; color: var(--accent); border-top: 1px solid var(--border); margin-top: 8px; cursor: pointer; transition: background 0.2s; } .findings-more:hover { background: var(--overlay-light); } /* Findings Modal */ .findings-modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: var(--bg); display: flex; align-items: center; justify-content: center; z-index: 10000; backdrop-filter: blur(4px); } .findings-modal { background: var(--border-subtle); border: 1px solid var(--border); border-radius: 8px; width: 90%; max-width: 600px; max-height: 80vh; display: flex; flex-direction: column; box-shadow: 0 8px 32px var(--shadow-color); } .findings-modal-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--border); } .findings-modal-title { font-size: 14px; font-weight: 600; color: var(--text-primary); } .findings-modal-close { background: none; border: none; color: var(--text-dim); font-size: 20px; cursor: pointer; padding: 4px 8px; line-height: 1; } .findings-modal-close:hover { color: var(--text-primary); } .findings-modal-content { overflow-y: auto; padding: 8px; } .findings-modal-item { padding: 10px 12px; margin-bottom: 8px; background: var(--overlay-subtle); border-radius: 6px; border-left: 3px solid var(--accent); cursor: pointer; transition: background 0.2s; } .findings-modal-item:hover { background: var(--overlay-light); } .findings-modal-item.critical { border-left-color: var(--semantic-critical); background: rgba(255, 59, 48, 0.05); } .findings-modal-item.high { border-left-color: var(--semantic-elevated); } .findings-modal-item.medium { border-left-color: var(--semantic-low); } .findings-modal-item.low { border-left-color: var(--text-muted); } .findings-modal-item-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; } .findings-modal-item-type { font-size: 12px; font-weight: 500; color: var(--text-primary); } .findings-modal-item-priority { font-size: 9px; font-weight: 600; padding: 2px 6px; border-radius: 4px; background: var(--overlay-heavy); color: var(--text-dim); } .findings-modal-item-priority.critical { background: rgba(255, 59, 48, 0.3); color: var(--semantic-critical); } .findings-modal-item-priority.high { background: rgba(255, 149, 0, 0.2); color: var(--semantic-elevated); } .findings-modal-item-priority.medium { background: rgba(74, 158, 255, 0.2); color: var(--semantic-low); } .findings-modal-item-desc { font-size: 11px; color: var(--text-dim); line-height: 1.4; margin-bottom: 6px; } .findings-modal-item-meta { display: flex; justify-content: space-between; font-size: 10px; } .findings-modal-item-insight { color: var(--accent); font-style: italic; } .findings-modal-item-time { color: var(--text-dim); } /* ===== Tech Events Panel ===== */ .tech-events-panel { display: flex; flex-direction: column; gap: 8px; height: 100%; } .tech-events-loading, .tech-events-error { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 20px; color: var(--text-dim); } .tech-events-error { color: var(--red); } .tech-events-error .retry-btn { margin-top: 8px; padding: 4px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 4px; color: var(--text); cursor: pointer; font-size: 10px; } .tech-events-error .retry-btn:hover { background: var(--border); } .tech-events-tabs { display: flex; gap: 4px; padding: 0 2px; } .tech-events-tabs .tab { flex: 1; padding: 5px 8px; background: transparent; border: 1px solid var(--border); border-radius: 4px; color: var(--text-dim); font-size: 9px; cursor: pointer; transition: all 0.15s ease; } .tech-events-tabs .tab:hover { background: var(--overlay-light); color: var(--text); } .tech-events-tabs .tab.active { background: var(--accent); color: var(--bg); border-color: var(--accent); } .tech-events-stats { display: flex; align-items: center; gap: 12px; padding: 4px 8px; font-size: 9px; color: var(--text-dim); } .tech-events-stats .stat { display: flex; align-items: center; gap: 4px; } .tech-events-stats .source-link { margin-left: auto; color: var(--text-dim); text-decoration: none; font-size: 9px; } .tech-events-stats .source-link:hover { color: var(--accent); } .tech-events-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; } .tech-event { display: flex; gap: 10px; padding: 8px; background: var(--overlay-subtle); border-radius: 4px; border-left: 3px solid var(--border); transition: all 0.15s ease; } .tech-event:hover { background: var(--overlay-light); } .tech-event.is-today { background: rgba(255, 170, 0, 0.1); border-left-color: var(--yellow); } .tech-event.is-this-week:not(.is-today) { border-left-color: var(--green); } .tech-event.type-conference { border-left-color: var(--semantic-info); } .tech-event.type-earnings { border-left-color: var(--semantic-info); } .tech-event.type-ipo { border-left-color: var(--semantic-critical); } .event-date { display: flex; flex-direction: column; align-items: center; justify-content: center; min-width: 40px; padding: 4px; background: var(--darken-heavy); border-radius: 4px; } .event-month { font-size: 8px; font-weight: 600; color: var(--text-dim); letter-spacing: 0.5px; } .event-day { font-size: 16px; font-weight: 700; color: var(--text); line-height: 1; } .today-badge { font-size: 7px; font-weight: 600; color: var(--yellow); margin-top: 2px; } .soon-badge { font-size: 7px; font-weight: 600; color: var(--semantic-high); margin-top: 2px; } .tech-event.is-soon { background: rgba(255, 153, 102, 0.1); border-left-color: var(--semantic-high); } .event-content { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; } .event-header { display: flex; align-items: center; gap: 6px; } .event-icon { font-size: 12px; flex-shrink: 0; } .event-title { flex: 1; font-size: 11px; font-weight: 500; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .event-url { color: var(--text-dim); text-decoration: none; font-size: 10px; flex-shrink: 0; } .event-url:hover { color: var(--accent); } .event-meta { display: flex; align-items: center; gap: 8px; font-size: 9px; color: var(--text-dim); } .event-dates { color: var(--text-dim); } .event-location { color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 120px; } .event-map-link { background: none; border: none; padding: 2px 4px; cursor: pointer; font-size: 10px; opacity: 0.6; transition: opacity 0.15s; } .event-map-link:hover { opacity: 1; } /* Tech Events Map Markers */ .tech-event-marker { position: absolute; background: var(--semantic-info); border: 2px solid var(--accent); border-radius: 50%; width: 12px; height: 12px; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 2px 6px var(--shadow-color); transform: translate(-50%, -50%) scale(var(--marker-scale, 1)); transform-origin: center; will-change: transform; } .tech-event-marker:hover { transform: translate(-50%, -50%) scale(calc(var(--marker-scale, 1) * 1.3)); z-index: 1000; } .tech-event-marker.upcoming-soon { background: var(--yellow); animation: pulse-marker 2s ease-in-out infinite; } @keyframes pulse-marker { 0%, 100% { box-shadow: 0 0 0 0 rgba(255, 170, 0, 0.5); } 50% { box-shadow: 0 0 0 6px rgba(255, 170, 0, 0); } } .tech-event-popup { min-width: 180px; max-width: 250px; } .tech-event-popup h4 { font-size: 11px; font-weight: 600; margin-bottom: 4px; color: var(--text); } .tech-event-popup .popup-meta { font-size: 9px; color: var(--text-dim); display: flex; flex-direction: column; gap: 2px; } .tech-event-popup .popup-link { margin-top: 6px; font-size: 9px; color: var(--semantic-info); text-decoration: none; } .tech-event-popup .popup-link:hover { text-decoration: underline; } /* Service Status Panel */ .service-status-loading, .service-status-error { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 16px; gap: 8px; color: var(--text-dim); font-size: 11px; } .service-status-error { color: var(--red); } .service-status-error .retry-btn { margin-top: 4px; padding: 4px 10px; font-size: 10px; background: transparent; border: 1px solid var(--border); border-radius: 4px; color: var(--text-dim); cursor: pointer; } .service-status-error .retry-btn:hover { background: var(--border); } .service-status-summary { display: flex; gap: 8px; padding: 8px; background: var(--darken-medium); border-radius: 4px; margin-bottom: 8px; } .service-status-summary .summary-item { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; } .service-status-summary .summary-count { font-size: 18px; font-weight: 700; line-height: 1; } .service-status-summary .summary-label { font-size: 8px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-dim); } .service-status-summary .summary-item.operational .summary-count { color: var(--green); } .service-status-summary .summary-item.degraded .summary-count { color: var(--yellow); } .service-status-summary .summary-item.outage .summary-count { color: var(--red); } .service-status-filters { display: flex; gap: 4px; padding-bottom: 8px; flex-wrap: wrap; } .status-filter-btn { padding: 4px 8px; font-size: 9px; background: transparent; border: 1px solid var(--border); border-radius: 3px; color: var(--text-dim); cursor: pointer; transition: all 0.15s; } .status-filter-btn:hover { background: var(--overlay-light); color: var(--text); } .status-filter-btn.active { background: var(--accent); color: var(--bg); border-color: var(--accent); } .service-status-list { display: flex; flex-direction: column; gap: 2px; } .service-status-item { display: flex; align-items: center; gap: 8px; padding: 6px 8px; background: var(--overlay-subtle); border-radius: 4px; font-size: 11px; } .service-status-item .status-icon { font-size: 10px; flex-shrink: 0; } .service-status-item .status-name { flex: 1; color: var(--text); } .service-status-item .status-badge { font-size: 8px; font-weight: 600; padding: 2px 6px; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.3px; } .service-status-item.operational .status-icon { color: var(--green); } .service-status-item.degraded .status-icon { color: var(--yellow); } .service-status-item.outage .status-icon { color: var(--red); } .service-status-item.unknown .status-icon { color: var(--text-dim); } .service-status-item .status-badge.operational { background: rgba(0, 200, 83, 0.15); color: var(--green); } .service-status-item .status-badge.degraded { background: rgba(255, 170, 0, 0.15); color: var(--yellow); } .service-status-item .status-badge.outage { background: rgba(255, 82, 82, 0.15); color: var(--red); } .service-status-item .status-badge.unknown { background: var(--overlay-light); color: var(--text-dim); } .all-operational { text-align: center; padding: 12px; font-size: 10px; color: var(--green); background: rgba(0, 200, 83, 0.1); border-radius: 4px; margin-top: 8px; } /* ===== deck.gl Map Styles ===== */ .map-container.deckgl-mode { position: relative; width: 100%; height: 100%; } .deckgl-map-wrapper { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; /* Prevent browser from intercepting touch gestures (pinch-zoom, pan) so MapLibre/deck.gl can handle them directly — fixes Android pinch-zoom */ touch-action: none; } #deckgl-basemap { position: absolute; top: 0; left: 0; width: 100%; height: 100%; /* Let MapLibre handle all touch gestures (pinch-zoom, pan, rotate) instead of the browser intercepting them for page zoom on Android */ touch-action: none; } #deckgl-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; background: transparent !important; } #deckgl-overlay canvas { pointer-events: auto; background: transparent !important; } /* Globe Beta Badge */ .globe-beta-badge { display: inline-block; padding: 3px 10px; font-family: var(--font-mono, 'JetBrains Mono', monospace); font-size: 11px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: #00e5ff; background: rgba(0, 229, 255, 0.08); border: 1px solid rgba(0, 229, 255, 0.4); border-radius: 4px; box-shadow: 0 0 6px rgba(0, 229, 255, 0.3), 0 0 20px rgba(0, 229, 255, 0.15), inset 0 0 8px rgba(0, 229, 255, 0.05); animation: globe-beta-pulse 2.5s ease-in-out infinite; pointer-events: none; align-self: flex-end; } @keyframes globe-beta-pulse { 0%, 100% { box-shadow: 0 0 6px rgba(0, 229, 255, 0.3), 0 0 20px rgba(0, 229, 255, 0.15), inset 0 0 8px rgba(0, 229, 255, 0.05); } 50% { box-shadow: 0 0 10px rgba(0, 229, 255, 0.5), 0 0 30px rgba(0, 229, 255, 0.25), inset 0 0 12px rgba(0, 229, 255, 0.1); } } /* deck.gl Controls */ .deckgl-controls { position: absolute; top: 10px; right: 10px; display: flex; flex-direction: column; gap: 8px; z-index: 500; pointer-events: auto; } .deckgl-controls .zoom-controls { display: flex; flex-direction: column; gap: 2px; } .deckgl-controls .map-btn { width: 32px; height: 32px; background: var(--bg); border: 1px solid var(--border); color: var(--text); font-size: 16px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; pointer-events: auto; position: relative; z-index: 1; } .deckgl-controls .map-btn:hover { background: var(--bg); border-color: var(--green); } .deckgl-controls .view-selector { display: none; /* Hidden - region selector moved to header */ margin-top: 4px; } .deckgl-controls .view-select { width: 100%; padding: 6px 8px; background: var(--bg); border: 1px solid var(--border); color: var(--text); font-family: inherit; font-size: 10px; cursor: pointer; } .deckgl-controls .view-select:hover { border-color: var(--green); } /* deck.gl Time Slider */ .deckgl-time-slider { position: absolute; top: 10px; left: 10px; z-index: 100; background: var(--bg); padding: 8px 12px; border: 1px solid var(--border); border-radius: 4px; } .deckgl-time-slider .time-options { display: flex; gap: 2px; } .deckgl-time-slider .time-btn { padding: 4px 8px; background: transparent; border: 1px solid var(--border); color: var(--text-dim); font-family: inherit; font-size: 10px; cursor: pointer; transition: all 0.2s ease; } .deckgl-time-slider .time-btn:hover { border-color: var(--green); color: var(--green); } .deckgl-time-slider .time-btn.active { background: var(--green); border-color: var(--green); color: var(--bg); font-weight: bold; } /* deck.gl Layer Toggles */ .deckgl-layer-toggles { position: absolute; bottom: 10px; left: 10px; z-index: 100; background: var(--bg); border: 1px solid var(--border); border-radius: 4px; max-width: 260px; max-height: 50vh; display: flex; flex-direction: column; overflow: hidden; flex-wrap: nowrap; } .deckgl-layer-toggles .toggle-header { display: flex; justify-content: space-between; align-items: center; padding: 6px 10px; border-bottom: 1px solid var(--border); font-size: 10px; font-weight: bold; color: var(--text-dim); text-transform: uppercase; letter-spacing: 1px; flex-shrink: 0; } .deckgl-layer-toggles .toggle-collapse { background: none; border: none; color: var(--text-dim); cursor: pointer; font-size: 10px; } .deckgl-layer-toggles .toggle-list { padding: 4px; display: flex; flex-direction: column; gap: 2px; flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; } .deckgl-layer-toggles .toggle-list.collapsed { display: none; } .deckgl-layer-toggles .layer-toggle { display: flex; align-items: center; gap: 6px; padding: 5px 8px; cursor: pointer; border-radius: 3px; border: 1px solid transparent; background: var(--bg); transition: background 0.15s ease, border-color 0.15s ease; position: relative; font-size: 10px; text-transform: uppercase; color: var(--text); } .deckgl-layer-toggles .layer-toggle:hover { background: var(--bg); } .deckgl-layer-toggles .layer-toggle.zoom-hidden .toggle-label { opacity: 0.45; } .deckgl-layer-toggles .layer-toggle.zoom-hidden::after { content: '🔍+'; position: absolute; top: -4px; right: 2px; font-size: 7px; opacity: 0.65; pointer-events: none; } .deckgl-layer-toggles .layer-toggle input[type="checkbox"] { -webkit-appearance: none; appearance: none; width: 16px; height: 16px; min-width: 16px; border: 2px solid var(--border); border-radius: 3px; background: transparent; cursor: pointer; margin: 0; position: relative; flex-shrink: 0; } .deckgl-layer-toggles .layer-toggle input[type="checkbox"]:checked { background: var(--green); border-color: var(--green); } .deckgl-layer-toggles .layer-toggle input[type="checkbox"]:checked::after { content: '✓'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: var(--bg); font-size: 10px; font-weight: bold; line-height: 1; } .deckgl-layer-toggles .toggle-icon { font-size: 12px; width: 16px; height: 16px; min-width: 16px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; overflow: hidden; } .deckgl-layer-toggles .toggle-label { font-size: 10px; font-weight: 500; color: var(--text); letter-spacing: 0.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .deckgl-layer-toggles .layer-toggle.loading .toggle-label { color: var(--yellow); animation: layer-loading 0.8s ease-in-out infinite; } .deckgl-layer-toggles .layer-toggle.has-data .toggle-label { color: var(--green); } .deckgl-layer-toggles .layer-toggle.has-data { border-color: rgba(68, 255, 136, 0.2); } /* deck.gl Legend - horizontal bar at bottom center */ .deckgl-legend { position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%); z-index: 100; display: flex; align-items: center; gap: 12px; background: var(--bg); border: 1px solid var(--border); border-radius: 4px; padding: 5px 12px; } .deckgl-legend .legend-label-title { font-size: 9px; font-weight: bold; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; } .deckgl-legend .legend-item { display: inline-flex; align-items: center; gap: 4px; } .deckgl-legend .legend-item svg { flex-shrink: 0; } .deckgl-legend .legend-label { font-size: 9px; color: var(--text-dim); white-space: nowrap; } /* deck.gl Timestamp */ .deckgl-timestamp { position: absolute; top: 10px; left: 50%; /* Explicitly unset bottom/right to prevent stretching if map-timestamp class is also applied */ bottom: auto !important; right: auto !important; width: auto; height: auto; transform: translateX(-50%); z-index: 100; background: var(--bg); padding: 4px 12px; border: 1px solid var(--border); border-radius: 3px; font-size: 9px; color: var(--text-dim); font-family: inherit; letter-spacing: 0.5px; } /* deck.gl Tooltip */ .deckgl-tooltip { background: var(--bg); padding: 8px 12px; border: 1px solid var(--border); border-radius: 4px; font-size: 11px; color: var(--text); max-width: 250px; pointer-events: none; } .deckgl-tooltip strong { color: var(--accent); font-weight: 600; } /* MapLibre GL overrides for dark theme */ .maplibregl-map { font-family: inherit; background: transparent !important; } .maplibregl-canvas-container, .maplibregl-canvas { background: transparent !important; } /* Override MapLibre GL default grab cursor - use default pointer */ .maplibregl-canvas-container.maplibregl-interactive, .maplibregl-canvas-container.maplibregl-interactive .maplibregl-canvas { cursor: default !important; } .maplibregl-canvas-container.maplibregl-interactive:active, .maplibregl-canvas-container.maplibregl-interactive:active .maplibregl-canvas { cursor: grabbing !important; } /* Ensure deck.gl doesn't add any overlay */ #deckgl-overlay, #deckgl-overlay>*, #deckgl-overlay canvas { background: transparent !important; background-color: transparent !important; } /* Override deck.gl default grab cursor - use default pointer */ #deckgl-overlay canvas { cursor: default !important; } #deckgl-overlay canvas:active { cursor: grabbing !important; } .maplibregl-popup-content { background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 4px; padding: 10px 14px; font-size: 11px; } .maplibregl-popup-tip { border-top-color: var(--bg); } .maplibregl-ctrl-attrib { background: var(--bg) !important; color: var(--text-dim) !important; font-size: 9px !important; } .maplibregl-ctrl-attrib a { color: var(--text-dim) !important; } /* Hide MapLibre navigation controls (we use custom ones) */ .maplibregl-ctrl-top-right, .maplibregl-ctrl-bottom-right { display: none; } /* Map tile attribution */ .map-attribution { position: absolute; bottom: 2px; right: 4px; font-size: 9px; color: var(--text-dim); opacity: 0.6; z-index: 10; pointer-events: auto; } .map-attribution a { color: var(--text-dim); text-decoration: none; } .map-attribution a:hover { text-decoration: underline; } /* deck.gl mode indicator */ .map-container.deckgl-mode::after { content: 'WebGL'; position: absolute; bottom: 10px; right: 170px; z-index: 99; background: rgba(0, 200, 100, 0.15); color: var(--green); padding: 2px 6px; border-radius: 2px; font-size: 8px; font-weight: bold; letter-spacing: 0.5px; text-transform: uppercase; opacity: 0.7; } /* Responsive adjustments for deck.gl on smaller desktops */ @media (max-width: 1200px) { .deckgl-layer-toggles { max-width: 180px; } .deckgl-legend { padding: 4px 10px; gap: 8px; } .deckgl-legend .legend-label-title, .deckgl-legend .legend-label { font-size: 8px; } } /* Mobile: prevent horizontal overflow from deck.gl legend */ @media (max-width: 520px) { .deckgl-legend { left: 8px; right: 8px; transform: none; justify-content: center; flex-wrap: wrap; gap: 6px 8px; padding: 6px 10px; overflow: hidden; } .deckgl-legend .legend-item { max-width: 100%; } } /* Scrollbar styling for layer toggles */ .deckgl-layer-toggles::-webkit-scrollbar { width: 4px; } .deckgl-layer-toggles::-webkit-scrollbar-track { background: transparent; } .deckgl-layer-toggles::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; } .deckgl-layer-toggles::-webkit-scrollbar-thumb:hover { background: var(--text-dim); } /* ============================================ ML Features - ONNX Runtime Integration ============================================ */ /* Cluster Summary */ .cluster-summary { font-size: 11px; color: var(--text-dim); padding: 6px 8px; line-height: 1.4; border-left: 2px solid var(--accent); margin: 6px 0; background: var(--overlay-subtle); } .cluster-summary.loading { font-style: italic; opacity: 0.7; } .cluster-summary.error { color: var(--red); border-left-color: var(--red); } /* ML Loading Spinner */ .ml-loading-inline { display: inline-block; width: 10px; height: 10px; border: 1.5px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Entity Pills */ .entity-pills { display: flex; flex-wrap: wrap; gap: 4px; margin: 4px 0; } .entity-pill { font-size: 9px; padding: 2px 6px; border-radius: 10px; background: var(--surface); border: 1px solid var(--border); cursor: pointer; transition: border-color 0.2s; } .entity-pill:hover { border-color: var(--text-dim); } .entity-pill.person { border-color: var(--semantic-low); } .entity-pill.organization { border-color: var(--threat-low); } .entity-pill.location { border-color: var(--semantic-elevated); } /* Insights Panel */ .insights-section { margin-bottom: 12px; } .insights-section-title { font-size: 9px; text-transform: uppercase; color: var(--text-dim); margin-bottom: 6px; letter-spacing: 0.5px; } /* World Brief - AI Summary */ .insights-brief { margin-bottom: 12px; padding: 10px; background: linear-gradient(135deg, rgba(68, 136, 255, 0.08), rgba(136, 68, 255, 0.08)); border-radius: 6px; border-left: 3px solid var(--accent); } .insights-brief .insights-section-title { color: var(--accent); margin-bottom: 8px; } .insights-brief-text { font-size: 12px; line-height: 1.5; color: var(--text); } .insights-unavailable, .insights-error, .insights-empty { font-size: 11px; color: var(--text-dim); font-style: italic; padding: 8px 0; } .insights-error { color: var(--red); } /* Insights Panel - Loading Status */ .insights-status { display: flex; align-items: center; gap: 10px; padding: 16px 8px; color: var(--text-dim); font-size: 12px; } .insights-spinner { width: 16px; height: 16px; border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.8s linear infinite; } .insights-status-text { animation: pulse 1.5s ease-in-out infinite; } @keyframes pulse { 0%, 100% { opacity: 0.6; } 50% { opacity: 1; } } /* Insights Panel - Progress Bar */ .insights-progress { padding: 12px 8px; } .insights-progress-bar { height: 4px; background: var(--border); border-radius: 2px; overflow: hidden; margin-bottom: 10px; } .insights-progress-fill { height: 100%; background: linear-gradient(90deg, var(--accent), var(--semantic-info)); border-radius: 2px; transition: width 0.3s ease; } .insights-progress-info { display: flex; justify-content: space-between; align-items: center; font-size: 11px; } .insights-progress-step { color: var(--accent); font-weight: 600; } .insights-progress-message { color: var(--text-dim); animation: pulse 1.5s ease-in-out infinite; } /* Insights Panel - Provider Badge */ .insights-provider { font-size: 8px; padding: 2px 6px; background: rgba(68, 136, 255, 0.15); color: var(--accent); border-radius: 8px; text-transform: uppercase; letter-spacing: 0.5px; margin-left: 6px; vertical-align: middle; } /* Insights Panel - Stats */ .insights-stats { display: flex; gap: 12px; margin-bottom: 12px; padding: 8px; background: var(--overlay-subtle); border-radius: 4px; } .insight-stat { text-align: center; flex: 1; } .insight-stat-value { display: block; font-size: 18px; font-weight: 600; color: var(--text); } .insight-stat-label { font-size: 9px; color: var(--text-dim); text-transform: uppercase; } .insight-stat.alert .insight-stat-value { color: var(--red); } /* Insights Panel - Stories */ .insight-story { padding: 8px 0; border-bottom: 1px solid var(--border); } .insight-story:last-child { border-bottom: none; } .insight-story-header { display: flex; align-items: flex-start; gap: 6px; } .insight-story-title { font-size: 11px; color: var(--text); line-height: 1.4; } .insight-badges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; padding-left: 12px; } .insight-badge { font-size: 9px; padding: 1px 5px; border-radius: 3px; background: var(--surface); color: var(--text-dim); } .insight-badge.confirmed { background: rgba(74, 222, 128, 0.15); color: var(--green); } .insight-badge.multi { background: var(--overlay-light); color: var(--text); } .insight-badge.velocity { background: rgba(251, 191, 36, 0.15); color: var(--yellow); } .insight-badge.velocity.elevated { background: rgba(251, 146, 60, 0.15); color: var(--orange); } .insight-badge.velocity.high { background: rgba(239, 68, 68, 0.15); color: var(--red); } .insight-badge.alert { background: rgba(239, 68, 68, 0.15); color: var(--red); } /* Sentiment Dots */ .insight-sentiment-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; margin-top: 5px; } .insight-sentiment-dot.positive { background: var(--green); } .insight-sentiment-dot.negative { background: var(--red); } .insight-sentiment-dot.neutral { background: var(--text-dim); } /* Sentiment Bar */ .insights-sentiment-bar { margin-bottom: 12px; padding: 8px; background: var(--overlay-subtle); border-radius: 4px; } .sentiment-bar-track { display: flex; height: 6px; border-radius: 3px; overflow: hidden; margin-bottom: 4px; } .sentiment-bar-negative { background: var(--red); height: 100%; } .sentiment-bar-neutral { background: var(--text-dim); height: 100%; } .sentiment-bar-positive { background: var(--green); height: 100%; } .sentiment-bar-labels { display: flex; justify-content: space-between; font-size: 10px; font-weight: 500; } .sentiment-label.negative { color: var(--red); } .sentiment-label.neutral { color: var(--text-dim); } .sentiment-label.positive { color: var(--green); } .sentiment-tone { text-align: center; font-size: 10px; margin-top: 6px; color: var(--text-dim); } .sentiment-tone.negative { color: var(--red); } .sentiment-tone.positive { color: var(--green); } /* ML-Detected Stories Section */ .insights-missed { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border); } .insights-missed .insights-section-title { color: var(--semantic-low); } .insight-story.missed { opacity: 0.85; border-left: 2px solid var(--semantic-low); padding-left: 8px; margin-left: 0; } .insight-sentiment-dot.ml-flagged { background: var(--semantic-low); box-shadow: 0 0 6px rgba(107, 138, 253, 0.5); } .insight-badge.ml-detected { background: rgba(107, 138, 253, 0.15); color: var(--semantic-low); border-color: rgba(107, 138, 253, 0.3); } /* Geographic Convergence Section */ .insights-convergence { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); } .insights-convergence .insights-section-title { color: var(--orange); } .convergence-zone { padding: 8px; margin-bottom: 8px; background: rgba(251, 146, 60, 0.05); border-radius: 4px; border-left: 2px solid var(--orange); } .convergence-region { font-size: 11px; font-weight: 600; color: var(--text); margin-bottom: 4px; } .convergence-description { font-size: 10px; color: var(--text-dim); line-height: 1.4; margin-bottom: 4px; } .convergence-stats { font-size: 9px; color: var(--text-muted); } /* Focal Points (Intelligence Synthesis) */ .insights-focal { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); } .focal-point { padding: 10px; margin-bottom: 8px; background: rgba(139, 92, 246, 0.05); border-radius: 4px; border-left: 3px solid var(--text-muted); } .focal-point.critical { border-left-color: var(--red); background: rgba(239, 68, 68, 0.08); } .focal-point.elevated { border-left-color: var(--orange); background: rgba(251, 146, 60, 0.08); } .focal-point.watch { border-left-color: var(--blue); background: rgba(59, 130, 246, 0.05); } .focal-point-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; } .focal-point-name { font-size: 12px; font-weight: 600; color: var(--text); } .focal-point-urgency { font-size: 9px; font-weight: 600; padding: 2px 6px; border-radius: 3px; text-transform: uppercase; } .focal-point-urgency.critical { background: var(--red); color: white; } .focal-point-urgency.elevated { background: var(--orange); color: white; } .focal-point-urgency.watch { background: var(--surface-elevated); color: var(--text-dim); } .focal-point-signals { display: flex; gap: 4px; margin-bottom: 6px; font-size: 14px; } .focal-point-stats { font-size: 10px; color: var(--text-dim); margin-bottom: 4px; } .focal-point-headline { display: block; font-size: 10px; color: var(--text-muted); font-style: italic; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: none; cursor: pointer; transition: color 0.15s ease; } .focal-point-headline:hover { color: var(--accent); text-decoration: underline; } /* ============ Unified Settings Modal ============ */ .unified-settings-btn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); color: var(--text-dim); cursor: pointer; transition: color 0.2s, border-color 0.2s, transform 0.3s; } .unified-settings-btn:hover { color: var(--accent); border-color: var(--text-faint); transform: rotate(45deg); } .unified-settings-btn svg { width: 14px; height: 14px; } .unified-settings-modal { max-width: 600px; width: 95%; max-height: 80vh; } .unified-settings-tabs { display: flex; border-bottom: 1px solid var(--border); margin-bottom: 12px; } .unified-settings-tab { flex: 1; padding: 10px 12px; background: none; border: none; border-bottom: 2px solid transparent; color: var(--text-dim); font-family: inherit; font-size: 11px; font-weight: 600; letter-spacing: 0.5px; text-transform: uppercase; cursor: pointer; transition: color 0.15s, border-color 0.15s; } .unified-settings-tab:hover { color: var(--text); } .unified-settings-tab.active { border-bottom-color: var(--text); color: var(--text); } .unified-settings-tab-panel { display: none; padding: 0 4px; } .unified-settings-tab-panel.active { display: block; } /* Source region pills */ .unified-settings-region-wrapper { position: relative; } .unified-settings-region-wrapper::after { content: ''; position: absolute; right: 0; top: 0; bottom: 0; width: 40px; background: linear-gradient(to right, transparent, var(--surface)); pointer-events: none; } .unified-settings-region-bar { display: flex; gap: 6px; overflow-x: auto; padding: 8px 0; scrollbar-width: none; } .unified-settings-region-bar::-webkit-scrollbar { display: none; } .unified-settings-region-pill { background: var(--bg); border: 1px solid var(--border); border-radius: 16px; padding: 5px 12px; font-family: inherit; font-size: 10px; text-transform: uppercase; letter-spacing: 0.3px; color: var(--text-dim); cursor: pointer; white-space: nowrap; transition: border-color 0.15s, color 0.15s, background 0.15s; } .unified-settings-region-pill:hover { border-color: var(--text-dim); color: var(--text); } .unified-settings-region-pill.active { background: rgba(68, 255, 136, 0.08); border-color: rgba(68, 255, 136, 0.4); color: var(--green); } /* Unified settings selects */ .unified-settings-select, .unified-settings-lang-select { background: var(--bg); border: 1px solid var(--border); color: var(--text); width: 100%; padding: 8px 10px; font-family: inherit; font-size: 12px; cursor: pointer; margin-top: 4px; } .unified-settings-select:focus, .unified-settings-lang-select:focus { outline: none; border-color: var(--text-dim); } /* Responsive grids */ @media (max-width: 500px) { .unified-settings-modal .panel-toggle-grid, .unified-settings-modal .sources-toggle-grid { grid-template-columns: repeat(2, 1fr); } } /* ============ AI Flow Toggle Styles (shared) ============ */ .ai-flow-section-label { font-size: 9px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: var(--text-faint); padding: 10px 0 4px; border-top: 1px solid #333; } .ai-flow-section-label:first-child { border-top: none; padding-top: 0; } .ai-flow-toggle-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding: 8px 0; flex-wrap: wrap; } .ai-flow-toggle-label-wrap { flex: 1; min-width: 0; } .ai-flow-toggle-label { font-size: 12px; color: var(--text-primary); font-weight: 500; } .ai-flow-toggle-desc { font-size: 10px; color: var(--text-dim); margin-top: 2px; line-height: 1.3; } .ai-flow-toggle-warn { width: 100%; color: #f59e0b; font-size: 10px; margin-top: 4px; line-height: 1.3; } /* Toggle switch */ .ai-flow-switch { position: relative; display: inline-block; width: 32px; height: 18px; flex-shrink: 0; margin-top: 1px; cursor: pointer; } .ai-flow-switch input { opacity: 0; width: 0; height: 0; position: absolute; } .ai-flow-slider { position: absolute; inset: 0; background: #555; border-radius: 18px; transition: background 0.2s; } .ai-flow-slider::before { content: ''; position: absolute; width: 14px; height: 14px; left: 2px; top: 2px; background: #999; border-radius: 50%; transition: transform 0.2s, background 0.2s; } .ai-flow-switch input:checked+.ai-flow-slider { background: #22c55e; } .ai-flow-switch input:checked+.ai-flow-slider::before { transform: translateX(14px); background: #fff; } /* Ollama CTA */ .ai-flow-cta { border-top: 1px solid #333; margin-top: 8px; padding-top: 10px; } .ai-flow-cta-title { font-size: 11px; color: var(--text-primary); font-weight: 500; } .ai-flow-cta-desc { font-size: 10px; color: var(--text-dim); margin-top: 2px; } .ai-flow-cta-link { display: inline-block; margin-top: 4px; font-size: 11px; color: #60a5fa; text-decoration: none; transition: color 0.15s; } .ai-flow-cta-link:hover { color: #93c5fd; text-decoration: underline; } /* Discussion link in settings */ .us-discussion-link { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 6px; background: var(--overlay-subtle); border: 1px solid var(--border); color: var(--text); text-decoration: none; font-size: 12px; font-weight: 500; transition: border-color 0.2s, background 0.2s; } .us-discussion-link:hover { border-color: hsl(229, 48%, 55%); background: rgba(99, 120, 198, 0.1); } .us-discussion-dot { width: 8px; height: 8px; border-radius: 50%; background: hsl(229, 48%, 55%); flex-shrink: 0; } /* Data management buttons in settings */ .us-data-mgmt { display: flex; gap: 10px; padding: 0 16px 12px; } .us-data-mgmt .settings-btn { flex: 1; } .us-hidden-input { display: none; } .us-data-mgmt-toast { padding: 0 16px; font-size: 12px; min-height: 0; transition: opacity 0.2s; } .us-data-mgmt-toast:empty { display: none; } .us-data-mgmt-toast.ok { color: #34d399; } .us-data-mgmt-toast.error { color: #f87171; } .us-toast-reload { color: #60a5fa; margin-left: 6px; } /* Footer status */ .ai-flow-popup-footer { display: flex; align-items: center; gap: 6px; padding: 8px 12px; border-top: 1px solid #333; } .ai-flow-status-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; background: #555; } .ai-flow-status-dot.active { background: #22c55e; } .ai-flow-status-dot.browser-only { background: #f59e0b; } .ai-flow-status-dot.disabled { background: #ef4444; } .ai-flow-status-text { font-size: 10px; color: var(--text-dim); } /* Disabled state in Insights panel */ .insights-disabled { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 24px 16px; text-align: center; } .insights-disabled-icon { font-size: 28px; opacity: 0.4; margin-bottom: 8px; } .insights-disabled-title { font-size: 13px; color: var(--text-dim); margin-bottom: 4px; } .insights-disabled-hint { font-size: 11px; color: var(--text-muted); } /* ============ Critical Posture Banner ============ */ .critical-posture-banner { position: fixed; top: 50px; left: 0; right: 0; z-index: 999; padding: 10px 20px; display: flex; align-items: center; justify-content: space-between; gap: 16px; animation: banner-slide-in 0.3s ease-out; } .critical-posture-banner.dismissed { display: none; } .critical-posture-banner.severity-critical { background: linear-gradient(90deg, #8B0000, #DC143C); border-bottom: 2px solid var(--semantic-critical); } .critical-posture-banner.severity-elevated { background: linear-gradient(90deg, var(--semantic-elevated), var(--semantic-high)); border-bottom: 2px solid var(--semantic-elevated); } .banner-content { display: flex; align-items: center; gap: 12px; flex: 1; } .banner-icon { font-size: 18px; } .banner-headline { font-weight: 600; color: white; font-size: 14px; } .banner-stats { color: var(--accent); font-size: 12px; } .banner-strike { background: var(--overlay-heavy); padding: 2px 8px; border-radius: 3px; font-size: 11px; font-weight: 600; color: white; } .banner-view, .banner-dismiss { background: var(--overlay-heavy); border: none; color: white; padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 12px; } .banner-view:hover, .banner-dismiss:hover { background: var(--overlay-heavy); } .banner-dismiss { padding: 6px 10px; font-size: 16px; } @keyframes banner-slide-in { from { transform: translateY(-100%); opacity: 0; } to { transform: translateY(0); opacity: 1; } } /* Push content down when critical banner is visible */ body.has-critical-banner .panels-grid { padding-top: 50px; } /* ============ Breaking News Alert Banner ============ */ .breaking-news-container { position: fixed; top: 50px; left: 0; right: 0; z-index: 1001; display: flex; flex-direction: column; gap: 2px; pointer-events: none; } .breaking-alert { pointer-events: auto; padding: 8px 16px; display: flex; align-items: center; gap: 12px; animation: banner-slide-in 0.3s ease-out; color: #fff; font-family: var(--font-mono); font-size: 13px; } .breaking-alert.severity-critical { background: linear-gradient(90deg, #8B0000, #DC143C); border-bottom: 2px solid var(--semantic-critical); } .breaking-alert.severity-high { background: linear-gradient(90deg, var(--semantic-high, #c2410c), #b45309); border-bottom: 2px solid var(--semantic-high, #c2410c); } .breaking-alert-icon { font-size: 18px; flex-shrink: 0; } .breaking-alert-content { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; overflow: hidden; } .breaking-alert-level { font-weight: 700; font-size: 11px; letter-spacing: 0.5px; padding: 1px 6px; background: var(--overlay-heavy); border-radius: 3px; flex-shrink: 0; } .breaking-alert.severity-critical .breaking-alert-level { animation: pulse-breaking 0.8s ease-in-out infinite; } .breaking-alert-headline { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .breaking-alert-meta { font-size: 11px; color: rgba(255, 255, 255, 0.7); white-space: nowrap; flex-shrink: 0; } .breaking-alert-dismiss { background: var(--overlay-heavy); border: none; color: white; padding: 4px 10px; border-radius: 4px; cursor: pointer; font-size: 16px; flex-shrink: 0; } .breaking-alert-dismiss:hover { background: rgba(255, 255, 255, 0.3); } body.has-breaking-alert .panels-grid { margin-top: var(--breaking-alert-offset, 0px); transition: margin-top 0.3s ease; } @media (prefers-reduced-motion: reduce) { .breaking-alert { animation: none; } .breaking-alert.severity-critical .breaking-alert-level { animation: none; } } /* ============ Strategic Posture Panel ============ */ .posture-panel { display: flex; flex-direction: column; gap: 12px; padding: 12px; } .posture-theater { border-radius: 8px; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; } .posture-theater:hover { transform: translateY(-2px); box-shadow: 0 4px 12px var(--shadow-color); } .posture-compact { padding: 8px 12px; background: var(--overlay-light); display: flex; align-items: center; justify-content: space-between; } .posture-expanded { padding: 12px; background: var(--overlay-medium); } .posture-expanded.critical { border-left: 3px solid var(--semantic-critical); background: rgba(255, 68, 68, 0.1); } .posture-expanded.elevated { border-left: 3px solid var(--semantic-elevated); background: rgba(255, 170, 0, 0.1); } .posture-theater-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; } .posture-name { font-weight: 600; font-size: 13px; } .posture-badge { font-size: 11px; padding: 2px 6px; border-radius: 3px; } .posture-critical { background: rgba(var(--semantic-critical), 0.2); color: var(--semantic-critical); } .posture-elevated { background: rgba(255, 170, 0, 0.2); color: var(--semantic-elevated); } .posture-normal { background: rgba(68, 170, 68, 0.2); color: var(--semantic-normal); } /* Compact chip layout for posture panel */ .posture-compact { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--overlay-subtle); border-radius: 6px; cursor: pointer; transition: background 0.15s ease; } .posture-compact:hover { background: var(--overlay-light); } .posture-compact .posture-name { font-weight: 500; font-size: 12px; min-width: 60px; } .posture-chips { display: flex; gap: 6px; flex: 1; } .posture-chip { font-size: 11px; padding: 2px 6px; border-radius: 4px; font-weight: 500; display: flex; align-items: center; gap: 3px; } .posture-chip.air { background: rgba(100, 180, 255, 0.15); color: rgba(100, 180, 255, 0.9); } .posture-chip.naval { background: rgba(100, 220, 180, 0.15); color: rgba(100, 220, 180, 0.9); } /* Expanded theater with inline forces */ .posture-forces { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; } .posture-force-row { display: flex; align-items: center; gap: 8px; } .posture-domain { font-size: 9px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; width: 28px; flex-shrink: 0; } .posture-stats { display: flex; flex-wrap: wrap; gap: 4px; } .posture-stat { font-size: 11px; padding: 2px 6px; background: var(--overlay-light); border-radius: 4px; display: flex; align-items: center; gap: 3px; color: var(--accent); } .posture-stat.carrier { background: rgba(255, 180, 100, 0.15); color: rgba(255, 200, 130, 0.9); } .posture-footer { display: flex; align-items: center; gap: 8px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--overlay-medium); font-size: 11px; } .posture-focus { color: var(--text-muted); margin-left: auto; } /* Legacy styles kept for compatibility */ .posture-section-label { font-size: 10px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 8px; margin-bottom: 4px; } .posture-breakdown { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; margin-bottom: 6px; } .posture-row { display: flex; align-items: center; gap: 6px; font-size: 12px; } .posture-icon { width: 18px; text-align: center; } .posture-count { font-weight: 600; min-width: 24px; } .posture-label { color: var(--accent); } .posture-meta { display: flex; align-items: center; gap: 12px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--overlay-medium); } .posture-strike { background: rgba(var(--semantic-critical), 0.2); color: var(--semantic-critical); padding: 2px 8px; border-radius: 3px; font-size: 11px; font-weight: 600; } .posture-trend { font-size: 11px; } .trend-up { color: var(--semantic-critical); } .trend-down { color: var(--semantic-normal); } .trend-stable { color: var(--text-dim); } .posture-target { font-size: 11px; color: var(--accent); margin-top: 6px; } .posture-summary-mini { font-size: 11px; color: var(--accent); } /* posture-footer already defined above with new compact layout */ .posture-footer-old { display: flex; align-items: center; justify-content: space-between; padding-top: 8px; border-top: 1px solid var(--overlay-medium); font-size: 11px; color: var(--text-muted); } .posture-refresh-btn { background: none; border: none; color: var(--accent); cursor: pointer; font-size: 14px; } .posture-refresh-btn:hover { color: white; } .posture-no-data { text-align: center; padding: 24px; } .posture-no-data-icon { font-size: 32px; margin-bottom: 8px; } .posture-no-data-title { font-weight: 600; margin-bottom: 4px; } .posture-no-data-desc { font-size: 12px; color: var(--accent); } .posture-retry-btn { margin-top: 12px; padding: 8px 16px; background: var(--overlay-medium); border: 1px solid var(--overlay-heavy); border-radius: 4px; color: var(--accent); cursor: pointer; font-size: 12px; transition: all 0.2s; } .posture-retry-btn:hover { background: var(--overlay-heavy); color: white; } .posture-stale-warning { background: rgba(255, 170, 0, 0.15); border: 1px solid rgba(255, 170, 0, 0.3); border-radius: 4px; padding: 8px 12px; margin-bottom: 12px; font-size: 11px; color: var(--semantic-elevated); text-align: center; } /* Enhanced Loading States */ .posture-loading { text-align: center; padding: 24px 16px; } .posture-loading-radar { width: 80px; height: 80px; margin: 0 auto 16px; position: relative; border: 2px solid rgba(68, 255, 136, 0.3); border-radius: 50%; overflow: hidden; } .posture-radar-sweep { position: absolute; top: 50%; left: 50%; width: 50%; height: 2px; background: linear-gradient(90deg, transparent, var(--status-live)); transform-origin: left center; animation: radar-sweep 2s linear infinite; } .posture-radar-dot { position: absolute; top: 50%; left: 50%; width: 8px; height: 8px; margin: -4px; background: var(--status-live); border-radius: 50%; box-shadow: 0 0 12px var(--status-live); } @keyframes radar-sweep { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .posture-loading-title { font-weight: 600; font-size: 14px; margin-bottom: 16px; color: var(--accent); } .posture-loading-stages { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; } .posture-stage { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-muted); transition: color 0.3s; } .posture-stage.active { color: var(--status-live); } .posture-stage.complete { color: var(--accent); } .posture-stage-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--overlay-heavy); transition: all 0.3s; } .posture-stage.active .posture-stage-dot { background: var(--status-live); box-shadow: 0 0 8px var(--status-live); animation: pulse-dot 1s ease-in-out infinite; } .posture-stage.complete .posture-stage-dot { background: rgba(68, 255, 136, 0.6); } @keyframes pulse-dot { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.3); opacity: 0.7; } } .posture-loading-tip { font-size: 11px; color: var(--text-muted); font-style: italic; } .posture-loading-note { font-size: 10px; color: var(--text-dim); margin-top: 8px; padding: 6px 10px; background: var(--overlay-light); border-radius: 4px; text-align: center; } .posture-loading-elapsed { font-size: 10px; color: var(--text-muted); margin-top: 6px; font-variant-numeric: tabular-nums; } /* No Data State Improvements */ .posture-no-data-icon.pulse { animation: icon-pulse 2s ease-in-out infinite; } @keyframes icon-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.6; transform: scale(1.1); } } .posture-data-sources { display: flex; flex-direction: column; gap: 8px; margin: 16px 0; padding: 12px; background: var(--overlay-subtle); border-radius: 6px; } .posture-source { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--accent); } .posture-source-icon { font-size: 16px; } .posture-source-icon.connecting { animation: blink 1s ease-in-out infinite; } .posture-source-icon.waiting { opacity: 0.4; } @keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } } .posture-error-hint { margin-top: 12px; padding: 8px 12px; background: var(--overlay-light); border-radius: 4px; font-size: 11px; color: var(--text-muted); text-align: left; } .posture-error-hint strong { color: var(--accent); } /* ── Country Intel Modal ── */ .country-intel-overlay { position: fixed; inset: 0; z-index: 10000; background: var(--bg); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: opacity 0.2s ease; } .country-intel-overlay.active { opacity: 1; pointer-events: auto; } .country-intel-modal { background: var(--surface); border: 1px solid var(--overlay-medium); border-radius: 12px; width: 480px; max-width: 92vw; max-height: 80vh; overflow-y: auto; box-shadow: 0 20px 60px var(--shadow-color); transform: translateY(20px); transition: transform 0.2s ease; } .country-intel-overlay.active .country-intel-modal { transform: translateY(0); } .country-intel-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--overlay-medium); } .country-intel-title { display: flex; align-items: center; gap: 10px; font-size: 16px; font-weight: 600; color: var(--accent); } .country-flag { font-size: 24px; } .country-intel-close { background: none; border: none; color: var(--text-muted); font-size: 24px; cursor: pointer; padding: 4px 8px; border-radius: 6px; transition: all 0.15s; } .country-intel-close:hover { background: var(--overlay-medium); color: var(--accent); } .country-intel-content { padding: 16px 20px; } /* CII section */ .cii-section { margin-bottom: 16px; } .cii-label { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--accent); margin-bottom: 6px; } .cii-badge { font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 4px; letter-spacing: 0.5px; } .cii-score-bar { flex: 1; height: 6px; background: var(--overlay-medium); border-radius: 3px; overflow: hidden; } .cii-score-fill { height: 100%; border-radius: 3px; transition: width 0.5s ease; } .cii-score-value { font-size: 12px; font-weight: 600; color: var(--accent); min-width: 48px; text-align: right; } .cii-components { display: flex; gap: 12px; font-size: 12px; color: var(--text-muted); margin-top: 6px; } .cii-trend { margin-left: auto; text-transform: capitalize; } .cii-trend.rising { color: var(--semantic-high); } .cii-trend.falling { color: var(--semantic-normal); } .cii-trend.stable { color: var(--text-muted); } /* Signal chips */ .active-signals { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; } .signal-chip { font-size: 11px; padding: 4px 10px; border-radius: 20px; background: var(--overlay-light); color: var(--accent); border: 1px solid var(--overlay-medium); } .signal-chip.protest { border-color: rgba(255, 170, 0, 0.3); color: var(--semantic-elevated); } .signal-chip.military { border-color: rgba(100, 180, 255, 0.3); color: var(--semantic-low); } .signal-chip.outage { border-color: rgba(255, 100, 100, 0.3); color: var(--semantic-critical); } .signal-chip.quake { border-color: rgba(180, 120, 255, 0.3); color: var(--semantic-info); } .signal-chip.stock-loading { border-color: var(--overlay-medium); color: var(--text-dim); font-style: italic; } .signal-chip.stock.stock-up { border-color: rgba(68, 170, 68, 0.3); color: var(--semantic-normal); } .signal-chip.stock.stock-down { border-color: rgba(255, 68, 68, 0.3); color: var(--semantic-critical); } /* Intel brief */ .intel-brief-section { min-height: 100px; } .intel-brief-loading { padding: 8px 0; } .intel-skeleton { height: 14px; background: linear-gradient(90deg, var(--overlay-light) 25%, var(--overlay-medium) 50%, var(--overlay-light) 75%); background-size: 200% 100%; animation: skeleton-shimmer 1.5s infinite; border-radius: 4px; margin-bottom: 10px; } .intel-skeleton.short { width: 60%; } .intel-loading-text { display: block; text-align: center; font-size: 11px; color: var(--text-faint); margin-top: 12px; } @keyframes skeleton-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } .country-markets-section { padding: 8px 0; border-bottom: 1px solid var(--overlay-light); margin-bottom: 8px; } .markets-label { font-size: 11px; font-weight: 600; color: var(--text-muted); margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.5px; } .market-item { margin-bottom: 6px; } .market-title { font-size: 12px; color: var(--accent); margin-bottom: 3px; line-height: 1.3; } .market-title .market-link { color: var(--semantic-info); text-decoration: none; font-size: 11px; } .market-bar { display: flex; height: 16px; border-radius: 3px; overflow: hidden; font-size: 10px; font-weight: 600; line-height: 16px; } .market-yes { background: rgba(34, 197, 94, 0.4); color: var(--threat-low); text-align: center; min-width: 28px; } .market-no { background: rgba(239, 68, 68, 0.2); color: rgba(239, 68, 68, 0.6); text-align: center; min-width: 28px; } .market-vol { font-size: 10px; color: var(--text-faint); margin-top: 1px; } .intel-brief { font-size: 13px; line-height: 1.7; color: var(--accent); } .intel-brief p { margin: 0 0 12px; } .intel-brief strong { color: var(--accent); } .intel-footer { display: flex; align-items: center; gap: 10px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--overlay-light); font-size: 11px; color: var(--text-faint); } .intel-cached { color: var(--text-muted); } .intel-fresh { color: var(--semantic-normal); } .intel-error { padding: 16px; text-align: center; color: rgba(255, 100, 100, 0.7); font-size: 13px; } /* ============================================ MACRO SIGNALS / MARKET RADAR PANEL ============================================ */ .macro-signals-container { padding: 4px 0; } .macro-verdict { display: flex; align-items: center; gap: 8px; padding: 8px 12px; margin-bottom: 8px; border-radius: 6px; background: var(--overlay-light); border-left: 3px solid var(--overlay-heavy); } .macro-verdict.verdict-buy { border-left-color: var(--semantic-normal); background: rgba(76, 175, 80, 0.08); } .macro-verdict.verdict-cash { border-left-color: var(--semantic-high); background: rgba(255, 152, 0, 0.08); } .verdict-label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; } .verdict-value { font-size: 16px; font-weight: 700; letter-spacing: 1px; } .verdict-buy .verdict-value { color: var(--semantic-normal); } .verdict-cash .verdict-value { color: var(--semantic-high); } .verdict-detail { font-size: 11px; color: var(--text-muted); margin-left: auto; } .signals-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 6px; } .signal-card { background: var(--overlay-subtle); border: 1px solid var(--overlay-light); border-radius: 6px; padding: 8px; transition: background 0.15s; } .signal-card:hover { background: var(--overlay-light); } .signal-card-link { text-decoration: none; color: inherit; } .signal-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; } .signal-name { font-size: 11px; color: var(--accent); font-weight: 500; } .signal-badge { font-size: 9px; padding: 2px 6px; border-radius: 3px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; } .badge-bullish { background: rgba(76, 175, 80, 0.2); color: var(--semantic-normal); } .badge-bearish { background: rgba(244, 67, 54, 0.2); color: var(--semantic-critical); } .badge-neutral { background: var(--overlay-medium); color: var(--accent); } .signal-body { display: flex; align-items: center; gap: 6px; min-height: 24px; } .signal-body-fg { justify-content: center; } .signal-sparkline-wrap { flex-shrink: 0; } .signal-sparkline { display: block; } .signal-value { font-size: 11px; color: var(--accent); } .signal-detail { font-size: 10px; color: var(--text-faint); margin-top: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .signal-detail a { color: rgba(79, 195, 247, 0.6); text-decoration: none; } .signal-detail a:hover { text-decoration: underline; } .fg-donut { display: block; margin: 0 auto; } /* ============================================ ETF FLOWS PANEL ============================================ */ .etf-flows-container { padding: 4px 0; } .etf-summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; padding: 8px; margin-bottom: 8px; border-radius: 6px; background: var(--overlay-light); } .etf-summary-item { text-align: center; } .etf-summary-label { display: block; font-size: 10px; color: var(--text-muted); margin-bottom: 2px; } .etf-summary-value { display: block; font-size: 13px; font-weight: 600; color: var(--accent); } .etf-summary-value.flow-inflow { color: var(--semantic-normal); } .etf-summary-value.flow-outflow { color: var(--semantic-critical); } .etf-table-wrap { overflow-x: auto; } .etf-table { width: 100%; border-collapse: collapse; font-size: 12px; } .etf-table th { text-align: left; font-size: 10px; color: var(--text-muted); padding: 4px 6px; border-bottom: 1px solid var(--overlay-medium); font-weight: 500; text-transform: uppercase; } .etf-table td { padding: 5px 6px; border-bottom: 1px solid var(--overlay-light); } .etf-ticker { font-weight: 600; color: var(--accent); } .etf-issuer { color: var(--text-muted); font-size: 11px; } .etf-flow.flow-inflow { color: var(--semantic-normal); } .etf-flow.flow-outflow { color: var(--semantic-critical); } .etf-flow.flow-neutral { color: var(--text-muted); } .etf-volume { color: var(--accent); } .etf-change { font-weight: 500; } /* ============================================ STABLECOIN PANEL ============================================ */ .stablecoin-container { padding: 4px 0; } .stable-health { display: flex; align-items: center; gap: 10px; padding: 8px 12px; margin-bottom: 8px; border-radius: 6px; background: var(--overlay-light); } .health-label { font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.5px; } .health-good .health-label { background: rgba(76, 175, 80, 0.2); color: var(--semantic-normal); } .health-caution .health-label { background: rgba(255, 152, 0, 0.2); color: var(--semantic-high); } .health-warning .health-label { background: rgba(244, 67, 54, 0.2); color: var(--semantic-critical); } .health-detail { font-size: 11px; color: var(--text-muted); } .stable-section { margin-bottom: 8px; } .stable-section-title { font-size: 10px; text-transform: uppercase; color: var(--text-muted); padding: 4px 8px; font-weight: 600; letter-spacing: 0.5px; } .stable-row { display: flex; align-items: center; justify-content: space-between; padding: 5px 8px; border-bottom: 1px solid var(--overlay-light); } .stable-info { display: flex; align-items: center; gap: 6px; } .stable-symbol { font-weight: 600; font-size: 12px; color: var(--accent); min-width: 50px; } .stable-name { font-size: 11px; color: var(--text-muted); } .stable-price { font-size: 12px; color: var(--accent); font-family: monospace; } .stable-peg { display: flex; align-items: center; gap: 6px; } .peg-badge { font-size: 9px; padding: 2px 6px; border-radius: 3px; font-weight: 600; text-transform: uppercase; } .peg-on .peg-badge { background: rgba(76, 175, 80, 0.2); color: var(--semantic-normal); } .peg-slight .peg-badge { background: rgba(255, 152, 0, 0.2); color: var(--semantic-high); } .peg-off .peg-badge { background: rgba(244, 67, 54, 0.2); color: var(--semantic-critical); } .peg-dev { font-size: 10px; color: var(--text-faint); } .stable-supply-header { display: grid; grid-template-columns: 60px 1fr 1fr 70px; padding: 2px 8px; font-size: 10px; color: var(--text-faint); border-bottom: 1px solid var(--overlay-light); } .stable-supply-row { display: grid; grid-template-columns: 60px 1fr 1fr 70px; padding: 5px 8px; font-size: 12px; border-bottom: 1px solid var(--overlay-light); } .stable-mcap { color: var(--accent); } .stable-vol { color: var(--text-muted); } .stable-change { font-weight: 500; text-align: right; } /* Shared change classes for new panels */ .change-positive { color: var(--semantic-normal); } .change-negative { color: var(--semantic-critical); } .change-neutral { color: var(--text-muted); } .runtime-config-summary { font-size: 11px; color: var(--accent); margin-bottom: 10px; } .runtime-alert { border: 1px solid var(--overlay-medium); border-radius: 8px; padding: 12px; background: var(--darken-medium); } .runtime-alert h3 { margin: 0 0 6px; font-size: 11px; font-weight: normal; letter-spacing: 0.5px; } .runtime-alert p { margin: 0 0 6px; font-size: 10px; color: var(--text-muted); } .runtime-alert.runtime-alert-warn { border-color: rgba(255, 210, 124, 0.45); } .runtime-alert.runtime-alert-ok { border-color: rgba(125, 227, 157, 0.45); } .runtime-alert-missing { color: var(--semantic-elevated); font-size: 12px; } .runtime-open-settings-btn { border: 1px solid rgba(125, 227, 157, 0.45); background: rgba(125, 227, 157, 0.08); color: var(--status-live); border-radius: 4px; padding: 5px 10px; font: inherit; font-size: 11px; cursor: pointer; } .runtime-open-settings-btn:hover { background: rgba(125, 227, 157, 0.16); } .runtime-config-list { display: flex; flex-direction: column; gap: 10px; } .runtime-feature { border: 1px solid var(--overlay-medium); border-radius: 8px; padding: 10px; background: var(--darken-light); } .runtime-feature-header { display: flex; justify-content: space-between; align-items: center; gap: 8px; } .runtime-feature-header label { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 600; } .runtime-feature-desc, .runtime-feature-fallback { margin: 6px 0; font-size: 11px; color: var(--text-secondary); } .runtime-pill { font-size: 10px; padding: 2px 6px; border-radius: 999px; border: 1px solid var(--overlay-heavy); } .runtime-pill.ok, .runtime-secret-status.ok { color: var(--status-live); } .runtime-pill.warn, .runtime-secret-status.warn, .runtime-feature-fallback.fallback { color: var(--semantic-elevated); } .runtime-pill.staged, .runtime-secret-status.staged { color: var(--status-live); opacity: 0.7; } .runtime-secrets { display: flex; flex-direction: column; gap: 6px; } .runtime-secret-row { display: grid; grid-template-columns: 1fr auto auto; grid-template-areas: 'key status check' 'meta meta meta' 'input input input' 'hint hint hint'; gap: 4px 8px; align-items: center; } .runtime-secret-row code { font-size: 10px; } .runtime-secret-status { grid-area: status; font-size: 10px; } .runtime-secret-meta { grid-area: meta; font-size: 10px; color: var(--text-secondary); } .runtime-input-wrapper { grid-area: input; position: relative; } .runtime-input-wrapper.has-suffix input { padding-right: 72px; } .runtime-secret-row input, .runtime-secret-row select { width: 100%; background: var(--overlay-medium); border: 1px solid var(--overlay-medium); border-radius: 6px; color: var(--accent); padding: 6px 8px; font-size: 11px; } /* Direct-child inputs/selects (not inside wrapper) still need grid-area */ .runtime-secret-row>input, .runtime-secret-row>select { grid-area: input; } .runtime-secret-link { position: absolute; right: 3px; top: 50%; transform: translateY(-50%); font-size: 10px; font-weight: 600; color: var(--accent); background: rgba(96, 165, 250, 0.1); border: 1px solid rgba(96, 165, 250, 0.25); border-radius: 3px; padding: 2px 8px; text-decoration: none; cursor: pointer; transition: background 0.15s, border-color 0.15s; } .runtime-secret-link:hover { background: rgba(96, 165, 250, 0.2); border-color: var(--accent); } .runtime-secret-row input.hidden-input { display: none !important; } .runtime-secret-check { grid-area: check; } .runtime-secret-hint { grid-area: hint; } /* ============================================ Country Brief Page (full-page overlay) ============================================ */ .country-brief-overlay { position: fixed; inset: 0; z-index: 10000; background: var(--bg); backdrop-filter: blur(6px); opacity: 0; pointer-events: none; transition: opacity 0.2s ease; overflow-y: auto; } .country-brief-overlay.active { opacity: 1; pointer-events: auto; } .country-brief-page { background: var(--surface); border: 1px solid var(--overlay-medium); border-radius: 16px; width: 960px; max-width: 96vw; margin: 32px auto; min-height: calc(100vh - 64px); box-shadow: 0 24px 80px var(--shadow-color); transform: translateY(12px); transition: transform 0.2s ease; } .country-brief-overlay.active .country-brief-page { transform: translateY(0); } /* Header */ .cb-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; border-bottom: 1px solid var(--overlay-medium); position: sticky; top: 0; background: var(--surface); border-radius: 16px 16px 0 0; z-index: 1; } .cb-header-left { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } .cb-header-right { display: flex; align-items: center; gap: 6px; } .cb-flag { font-size: 28px; } .cb-country-name { font-size: 18px; font-weight: 700; color: var(--accent); } .cb-badge { font-size: 10px; font-weight: 700; padding: 3px 10px; border-radius: 4px; letter-spacing: 0.5px; } .cb-trend { font-size: 12px; text-transform: capitalize; } .cb-trend.trend-up { color: var(--semantic-high); } .cb-trend.trend-down { color: var(--semantic-normal); } .cb-trend.trend-stable { color: var(--text-muted); } .cb-tier-badge { font-size: 10px; padding: 2px 8px; border-radius: 4px; background: rgba(255, 170, 0, 0.12); color: var(--semantic-elevated); border: 1px solid rgba(255, 170, 0, 0.25); } .cb-close { background: none; border: none; color: var(--text-muted); font-size: 28px; cursor: pointer; padding: 4px 8px; border-radius: 8px; line-height: 1; transition: all 0.15s; } .cb-close:hover { background: var(--overlay-medium); color: var(--accent); } .cb-link-share-btn, .cb-share-btn, .cb-print-btn, .cb-export-btn { background: none; border: 1px solid var(--overlay-medium); color: var(--text-muted); cursor: pointer; padding: 6px 8px; border-radius: 6px; transition: all 0.15s; display: flex; align-items: center; } .cb-link-share-btn:hover, .cb-share-btn:hover, .cb-print-btn:hover, .cb-export-btn:hover { background: var(--overlay-medium); color: var(--accent); border-color: var(--overlay-heavy); } /* Body & Grid */ .cb-body { padding: 24px; } .cb-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; } /* Sections */ .cb-section { margin-bottom: 24px; } .cb-section-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: var(--text-dim); margin-bottom: 12px; } /* Risk Score Ring */ .cb-risk-content { display: flex; align-items: flex-start; gap: 20px; } .cb-score-ring { position: relative; display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .cb-score-value { position: absolute; font-size: 28px; font-weight: 800; top: 50%; left: 50%; transform: translate(-50%, -60%); } .cb-score-label { position: absolute; font-size: 11px; color: var(--text-faint); top: 50%; left: 50%; transform: translate(-50%, 60%); } .cb-components { flex: 1; } .cb-comp-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; } .cb-comp-icon { font-size: 14px; width: 20px; text-align: center; } .cb-comp-label { font-size: 11px; color: var(--text-muted); width: 70px; } .cb-comp-bar { flex: 1; height: 5px; background: var(--overlay-light); border-radius: 3px; overflow: hidden; } .cb-comp-fill { height: 100%; border-radius: 3px; transition: width 0.5s ease; } .cb-comp-val { font-size: 11px; font-weight: 600; color: var(--accent); width: 24px; text-align: right; } /* Not Tracked State */ .cb-not-tracked { display: flex; align-items: center; gap: 10px; padding: 16px; background: var(--overlay-subtle); border: 1px dashed var(--overlay-medium); border-radius: 8px; color: var(--text-muted); font-size: 12px; } .cb-not-tracked-icon { font-size: 20px; } /* Signal Chips */ .cb-signals-grid { display: flex; flex-wrap: wrap; gap: 6px; } .signal-chip.displacement { border-color: rgba(100, 200, 255, 0.3); color: var(--semantic-low); } .signal-chip.climate { border-color: rgba(255, 150, 50, 0.3); color: var(--semantic-high); } .signal-chip.conflict { border-color: rgba(255, 80, 80, 0.3); color: var(--semantic-critical); } /* Brief Text */ .cb-brief-text { font-size: 13px; line-height: 1.7; color: var(--accent); } .cb-brief-text p { margin-bottom: 10px; } .cb-brief-text strong { color: var(--accent); } .cb-citation { color: var(--semantic-low); text-decoration: none; font-size: 10px; font-weight: 700; vertical-align: super; cursor: pointer; transition: color 0.15s; } .cb-citation:hover { color: var(--semantic-low); text-decoration: underline; } .cb-export-menu { position: absolute; right: 0; top: 100%; margin-top: 4px; background: var(--surface, var(--surface)); border: 1px solid var(--overlay-medium); border-radius: 8px; padding: 4px; z-index: 10; min-width: 140px; } .cb-export-menu.hidden { display: none; } .cb-export-option { display: block; width: 100%; padding: 8px 12px; background: none; border: none; color: var(--accent); font-family: inherit; font-size: 12px; text-align: left; border-radius: 6px; cursor: pointer; } .cb-export-option:hover { background: var(--overlay-light); color: var(--accent); } .cb-brief-footer { display: flex; align-items: center; gap: 10px; margin-top: 12px; font-size: 11px; color: var(--text-faint); } /* Top News */ .cb-news-content { display: grid; gap: 6px; } .cb-news-card { display: flex; gap: 8px; align-items: flex-start; text-decoration: none; border: 1px solid var(--overlay-light); border-radius: 8px; padding: 8px; background: var(--overlay-subtle); transition: background 0.15s ease, border-color 0.15s ease; } .cb-news-card:hover { background: var(--overlay-light); border-color: var(--overlay-medium); } .cb-news-threat { width: 7px; height: 7px; border-radius: 50%; margin-top: 6px; flex-shrink: 0; } .cb-news-body { min-width: 0; } .cb-news-title { font-size: 12px; line-height: 1.35; color: var(--accent); margin-bottom: 3px; } .cb-news-meta { font-size: 10px; color: var(--text-dim); } /* Markets */ .cb-market-item { padding: 6px 0; border-bottom: 1px solid var(--overlay-light); } .cb-market-item:last-child { border-bottom: none; } .cb-market-title { font-size: 12px; color: var(--accent); margin-bottom: 6px; } .cb-market-link { color: var(--semantic-low); text-decoration: none; font-size: 11px; } .cb-news-highlight { background: rgba(100, 180, 255, 0.12); border-color: rgba(100, 180, 255, 0.25); transition: background 0.3s, border-color 0.3s; } /* Infrastructure */ .cb-infra-group { margin-bottom: 12px; } .cb-infra-type { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); margin-bottom: 6px; } .cb-infra-item { display: flex; align-items: center; justify-content: space-between; padding: 6px 0; font-size: 12px; color: var(--accent); } .cb-infra-dist { font-size: 10px; padding: 2px 6px; border-radius: 4px; background: var(--overlay-light); color: var(--text-muted); } /* Timeline Placeholder */ .cb-timeline-mount { min-height: 120px; background: var(--overlay-subtle); border: 1px dashed var(--overlay-medium); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: var(--text-ghost); font-size: 11px; } .cb-timeline-mount:empty::after { content: 'Timeline loading...'; } /* Loading / Empty States */ .cb-loading-state { padding: 40px 24px; } .cb-empty { color: var(--text-faint); font-size: 12px; font-style: italic; } /* Mobile Responsive */ @media (max-width: 768px) { .country-brief-page { margin: 0; max-width: 100vw; min-height: 100vh; border-radius: 0; border: none; } .cb-header { border-radius: 0; padding: 12px 16px; } .cb-body { padding: 16px; } .cb-grid { grid-template-columns: 1fr; } .cb-timeline-section { display: none; } .cb-risk-content { flex-direction: column; align-items: center; } .cb-signals-grid { display: grid; grid-template-columns: 1fr 1fr; } } @media (max-width: 480px) { .cb-country-name { font-size: 15px; } .cb-flag { font-size: 22px; } } /* Print styles */ @media print { .country-brief-overlay { position: static; background: none; backdrop-filter: none; overflow: visible; } .country-brief-page { width: 100%; max-width: 100%; margin: 0; border: none; box-shadow: none; border-radius: 0; min-height: auto; } .cb-header { position: static; background: var(--accent); border-radius: 0; } .cb-close, .cb-link-share-btn, .cb-share-btn, .cb-print-btn, .cb-export-btn, .cb-export-menu { display: none; } .cb-grid { grid-template-columns: 1fr; } .cb-timeline-section { display: none; } body>*:not(.country-brief-overlay) { display: none !important; } } /* ============================================================ Community Discussion Widget — Floating Pill ============================================================ */ .community-widget { position: fixed; bottom: 24px; right: 24px; z-index: 9000; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; animation: cw-float-in 0.4s cubic-bezier(0.22, 1, 0.36, 1); } .community-widget.cw-hiding { animation: cw-float-out 0.3s ease-in forwards; } @keyframes cw-float-in { 0% { transform: translateY(10px) scale(0.95); opacity: 0; } 100% { transform: translateY(0) scale(1); opacity: 1; } } @keyframes cw-float-out { 0% { transform: translateY(0) scale(1); opacity: 1; } 100% { transform: translateY(10px) scale(0.95); opacity: 0; } } .cw-pill { display: flex; align-items: center; gap: 10px; background: var(--panel-bg, #141414); border: 1px solid var(--border, #2a2a2a); border-radius: 28px; padding: 8px 8px 8px 16px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); } .cw-dot { width: 8px; height: 8px; border-radius: 50%; background: hsl(229, 48%, 55%); flex-shrink: 0; animation: cw-dot-pulse 2s ease-in-out infinite; } @keyframes cw-dot-pulse { 0%, 100% { opacity: 1; box-shadow: 0 0 0 0 hsla(229, 48%, 55%, 0.4); } 50% { opacity: 0.6; box-shadow: 0 0 8px 2px hsla(229, 48%, 55%, 0.3); } } .cw-text { font-size: 13px; font-weight: 600; color: var(--text, #e8e8e8); white-space: nowrap; } .cw-cta { padding: 6px 14px; background: hsl(229, 48%, 55%); border: none; border-radius: 20px; color: #fff; font-size: 12px; font-weight: 600; cursor: pointer; text-decoration: none; white-space: nowrap; transition: background 0.2s; } .cw-cta:hover { background: hsl(229, 48%, 62%); } .cw-close { background: none; border: none; color: var(--text-ghost, #444); font-size: 16px; cursor: pointer; padding: 4px 6px; border-radius: 50%; flex-shrink: 0; line-height: 1; transition: color 0.15s, background 0.15s; } .cw-close:hover { color: var(--text-dim, #888); background: var(--overlay-light, rgba(255, 255, 255, 0.05)); } .cw-dismiss { font-size: 10px; color: var(--text-ghost, #444); cursor: pointer; background: none; border: none; padding: 0 8px; transition: color 0.2s; } .cw-dismiss:hover { color: var(--text-dim, #888); } /* ── Ultra-wide layout: map left, panels beside it ── */ @media (min-width: 1600px) { .main-content { display: grid; grid-template-columns: 60% 1fr; grid-template-rows: 1fr; gap: 4px; overflow: hidden; } .main-content.map-hidden { grid-template-columns: 1fr; } .main-content.map-hidden .panels-grid { grid-column: 1; } .map-section { grid-column: 1; grid-row: 1; height: 100% !important; min-height: 0; max-height: none; overflow: hidden; display: flex; flex-direction: column; border-bottom: none; } .map-section.pinned { height: 100% !important; } .map-container-smooth { transition: height 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important; } .map-section-smooth { transition: height 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important; } .map-bottom-grid:empty { border-top: none; padding: 0; } .map-resize-handle { position: relative; bottom: auto; left: auto; right: auto; height: 12px; background: var(--border-subtle); margin: 0; cursor: ns-resize; } .map-resize-handle:hover { background: var(--accent); } .map-section.pinned { position: relative; } .map-resize-handle { display: flex; } .panels-grid { grid-column: 2; grid-row: 1; min-height: 0; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); grid-auto-rows: minmax(200px, 380px); align-content: start; overflow-y: auto; } } /* ========================================================================== Telegram Intel Panel ========================================================================== */ .telegram-intel-tabs { display: flex; gap: 2px; padding: 8px 10px 0; overflow-x: auto; border-bottom: 1px solid var(--border); background: var(--bg); scrollbar-width: none; -ms-overflow-style: none; } .telegram-intel-tabs::-webkit-scrollbar { display: none; } .telegram-intel-tab { padding: 6px 10px; background: transparent; border: none; border-bottom: 2px solid transparent; color: var(--text-dim); font-size: 11px; font-family: inherit; cursor: pointer; transition: all 0.15s ease; white-space: nowrap; flex-shrink: 0; } .telegram-intel-tab:hover { color: var(--text); background: var(--overlay-subtle); } .telegram-intel-tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 500; } .telegram-intel-items { display: flex; flex-direction: column; gap: 1px; } .telegram-intel-item { display: block; padding: 10px 12px; background: var(--surface); text-decoration: none; transition: background 0.15s ease; border-left: 2px solid transparent; } .telegram-intel-item:hover { background: var(--overlay-light); border-left-color: var(--accent); } .telegram-intel-item-header { display: flex; align-items: center; margin-bottom: 4px; gap: 8px; } .telegram-intel-channel { font-size: 10px; color: var(--accent); font-weight: 500; text-transform: uppercase; letter-spacing: 0.3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 50%; } .telegram-intel-topic { font-size: 9px; color: var(--text-dim); background: var(--overlay-subtle); padding: 1px 5px; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.3px; } .telegram-intel-time { font-size: 10px; color: var(--text-dim); flex-shrink: 0; margin-left: auto; } .telegram-intel-text { font-size: 12px; color: var(--text); line-height: 1.4; display: -webkit-box; line-clamp: 3; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } /* ─── Globe Map Styles ──────────────────────────────────────────────────────── */ .globe-mode { background: #000 !important; overflow: hidden; } @keyframes globe-pulse { 0% { transform: scale(1); opacity: 0.6; } 70% { transform: scale(2.5); opacity: 0; } 100% { transform: scale(2.5); opacity: 0; } }