anycoder-b84ce37d / index.html
AtomicLSD's picture
Upload folder using huggingface_hub
558f7ea verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NASA Worldview</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<style>
/* CSS Reset & Base */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--color-primary: #4eccc4;
--color-primary-dark: #3db8b0;
--color-bg-dark: #1a1d21;
--color-bg-panel: #262b31;
--color-bg-panel-hover: #2f353d;
--color-border: #444;
--color-text: #eee;
--color-text-muted: #888;
--color-text-secondary: #aaa;
--color-accent-red: #b71c1c;
--color-accent-red-hover: #d32f2f;
--sidebar-width: 320px;
--toolbar-height: 56px;
--timeline-height: 64px;
--radius-sm: 4px;
--radius-md: 8px;
--shadow-sm: 0 2px 4px rgba(0,0,0,0.3);
--shadow-md: 0 4px 12px rgba(0,0,0,0.4);
--transition-fast: 0.15s ease;
--transition-normal: 0.3s ease;
}
body, html {
width: 100%;
height: 100%;
overflow: hidden;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background: var(--color-bg-dark);
color: var(--color-text);
font-size: 14px;
}
/* App Container */
#app {
position: relative;
width: 100vw;
height: 100vh;
display: flex;
}
/* Built with anycoder link */
.anycoder-link {
position: fixed;
top: 8px;
left: 50%;
transform: translateX(-50%);
z-index: 10000;
background: rgba(78, 204, 196, 0.15);
border: 1px solid var(--color-primary);
padding: 6px 16px;
border-radius: 20px;
font-size: 12px;
color: var(--color-primary);
text-decoration: none;
backdrop-filter: blur(8px);
transition: all var(--transition-fast);
}
.anycoder-link:hover {
background: var(--color-primary);
color: var(--color-bg-dark);
}
/* Sidebar */
#wvSidebarEl {
position: absolute;
top: 0;
left: 0;
bottom: var(--timeline-height);
width: var(--sidebar-width);
background: var(--color-bg-panel);
z-index: 1000;
display: flex;
flex-direction: column;
transition: transform var(--transition-normal);
box-shadow: var(--shadow-md);
}
#wvSidebarEl.collapsed {
transform: translateX(-100%);
}
/* Sidebar Header */
.sidebar-header {
padding: 12px 16px;
border-bottom: 1px solid var(--color-border);
display: flex;
align-items: center;
justify-content: space-between;
background: var(--color-bg-dark);
}
#wv-logo {
width: 36px;
height: 36px;
background: var(--color-primary);
border-radius: var(--radius-sm);
display: flex;
align-items: center;
justify-content: center;
font-weight: 800;
color: var(--color-bg-dark);
font-size: 13px;
letter-spacing: -0.5px;
cursor: pointer;
transition: transform var(--transition-fast);
}
#wv-logo:hover {
transform: scale(1.05);
}
.sidebar-toggle-btn {
background: none;
border: none;
color: var(--color-text);
cursor: pointer;
font-size: 16px;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-sm);
transition: all var(--transition-fast);
}
.sidebar-toggle-btn:hover {
background: var(--color-bg-panel-hover);
color: var(--color-primary);
}
/* Navigation Tabs */
.nav-tabs {
display: flex;
border-bottom: 1px solid var(--color-border);
background: var(--color-bg-dark);
}
.nav-item {
flex: 1;
text-align: center;
padding: 14px 0;
cursor: pointer;
color: var(--color-text-muted);
font-size: 13px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
position: relative;
transition: all var(--transition-fast);
border: none;
background: none;
}
.nav-item:hover {
color: var(--color-text);
background: var(--color-bg-panel-hover);
}
.nav-item.active {
color: var(--color-primary);
}
.nav-item.active::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2px;
background: var(--color-primary);
}
/* Tab Content */
.tab-content {
flex: 1;
overflow: hidden;
position: relative;
}
.tab-pane {
position: absolute;
inset: 0;
overflow-y: auto;
opacity: 0;
visibility: hidden;
transition: opacity var(--transition-fast);
}
.tab-pane.active {
opacity: 1;
visibility: visible;
}
/* Scroll Container */
#layers-scroll-container, #events-scroll-container {
padding: 12px;
}
/* Layer Groups */
.layer-group {
margin-bottom: 16px;
background: var(--color-bg-dark);
border-radius: var(--radius-md);
overflow: hidden;
}
.layer-group-header {
padding: 12px 14px;
font-weight: 600;
color: var(--color-text);
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.8px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
background: var(--color-bg-panel-hover);
transition: background var(--transition-fast);
user-select: none;
}
.layer-group-header:hover {
background: #3a424b;
}
.layer-group-header i {
transition: transform var(--transition-fast);
color: var(--color-text-muted);
font-size: 12px;
}
.layer-group-header.collapsed i {
transform: rotate(-90deg);
}
.group-content {
padding: 8px 0;
}
.group-content.collapsed {
display: none;
}
/* Layer Items */
.layer-item {
display: flex;
align-items: flex-start;
padding: 10px 14px;
cursor: pointer;
user-select: none;
transition: all var(--transition-fast);
position: relative;
}
.layer-item:hover {
background: rgba(78, 204, 196, 0.05);
}
.layer-item.active {
background: rgba(78, 204, 196, 0.1);
}
.layer-item.active::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 3px;
background: var(--color-primary);
}
.layer-visibility {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
color: var(--color-text-muted);
transition: color var(--transition-fast);
flex-shrink: 0;
}
.layer-visibility.visible {
color: var(--color-primary);
}
.layer-visibility i {
font-size: 16px;
}
.layer-info {
flex: 1;
min-width: 0;
}
.layer-title {
font-size: 13px;
color: var(--color-text);
font-weight: 500;
line-height: 1.4;
margin-bottom: 2px;
}
.layer-subtitle {
font-size: 11px;
color: var(--color-text-muted);
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.layer-badge {
background: var(--color-bg-panel-hover);
padding: 2px 8px;
border-radius: 12px;
font-size: 10px;
color: var(--color-text-secondary);
}
.layer-notice {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
width: 18px;
height: 18px;
background: #ff9800;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
font-weight: bold;
color: #000;
}
/* Base Layer Items (radio style) */
.base-layer-item {
padding: 12px 14px;
cursor: pointer;
transition: all var(--transition-fast);
border-left: 3px solid transparent;
}
.base-layer-item:hover {
background: rgba(78, 204, 196, 0.05);
}
.base-layer-item.active {
background: rgba(78, 204, 196, 0.1);
border-left-color: var(--color-primary);
}
.base-layer-title {
font-size: 13px;
color: var(--color-text);
font-weight: 500;
margin-bottom: 4px;
}
.base-layer-title span {
font-weight: 400;
color: var(--color-text-muted);
font-size: 11px;
}
.base-layer-source {
font-size: 11px;
color: var(--color-text-muted);
padding-left: 16px;
position: relative;
}
.base-layer-source::before {
content: '';
position: absolute;
left: 4px;
top: 6px;
width: 6px;
height: 6px;
background: var(--color-primary);
border-radius: 50%;
opacity: 0;
transition: opacity var(--transition-fast);
}
.base-layer-item.active .base-layer-source::before {
opacity: 1;
}
/* Add Layers Button */
.add-layers-container {
padding: 16px;
border-top: 1px solid var(--color-border);
}
.add-layers-btn {
width: 100%;
height: 40px;
background: var(--color-accent-red);
border: none;
border-radius: var(--radius-sm);
color: #fff;
font-size: 13px;
font-weight: 500;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
transition: all var(--transition-fast);
}
.add-layers-btn:hover {
background: var(--color-accent-red-hover);
}
.add-layers-btn i {
font-size: 12px;
}
/* Events Tab */
.event-item {
padding: 14px;
border-bottom: 1px solid var(--color-border);
cursor: pointer;
transition: background var(--transition-fast);
}
.event-item:hover {
background: var(--color-bg-panel-hover);
}
.event-category {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 11px;
text-transform: uppercase;
font-weight: 600;
margin-bottom: 8px;
}
.event-category.wildfire { color: #ff5722; }
.event-category.storm { color: #2196f3; }
.event-category.volcano { color: #795548; }
.event-category.flood { color: #03a9f4; }
.event-title {
font-size: 13px;
color: var(--color-text);
font-weight: 500;
margin-bottom: 6px;
line-height: 1.4;
}
.event-meta {
font-size: 11px;
color: var(--color-text-muted);
display: flex;
gap: 16px;
}
/* Main Map Area */
#wv-map {
flex: 1;
position: relative;
background: #0a0a0a;
}
#mapCanvas {
width: 100%;
height: 100%;
}
/* Toolbar */
#wvToolbarEl {
position: absolute;
top: 12px;
left: calc(var(--sidebar-width) + 12px);
right: 12px;
height: var(--toolbar-height);
display: flex;
justify-content: space-between;
align-items: center;
pointer-events: none;
z-index: 999;
transition: left var(--transition-normal);
}
#wvToolbarEl.full-width {
left: 12px;
}
.toolbar-left, .toolbar-right {
display: flex;
align-items: center;
gap: 8px;
pointer-events: auto;
}
.toolbar-brand {
background: var(--color-bg-panel);
padding: 10px 16px;
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
display: flex;
align-items: center;
gap: 12px;
}
.toolbar-brand-title {
font-size: 15px;
font-weight: 600;
color: #fff;
}
.toolbar-brand-subtitle {
font-size: 11px;
color: var(--color-text-muted);
}
.wv-toolbar-button {
width: 44px;
height: 44px;
background: var(--color-bg-panel);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all var(--transition-fast);
position: relative;
}
.wv-toolbar-button:hover {
background: var(--color-bg-panel-hover);
border-color: #666;
color: var(--color-primary);
}
.wv-toolbar-button:active {
background: #1e2226;
}
.wv-toolbar-button i {
font-size: 18px;
}
.wv-toolbar-button .badge {
position: absolute;
top: -4px;
right: -4px;
width: 18px;
height: 18px;
background: var(--color-accent-red);
border-radius: 50%;
font-size: 10px;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
}
/* Search Overlay */
.search-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
padding: 16px;
background: var(--color-bg-panel);
border-bottom: 1px solid var(--color-border);
transform: translateY(-100%);
transition: transform var(--transition-normal);
z-index: 1001;
}
.search-overlay.active {
transform: translateY(0);
}
.search-input-container {
display: flex;
gap: 12px;
align-items: center;
}
.search-input {
flex: 1;
height: 44px;
background: var(--color-bg-dark);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
padding: 0 16px;
color: var(--color-text);
font-size: 14px;
}
.search-input:focus {
outline: none;
border-color: var(--color-primary);
}
.search-close {
width: 44px;
height: 44px;
background: none;
border: none;
color: var(--color-text);
cursor: pointer;
font-size: 18px;
}
/* Timeline */
#timeline-container {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: var(--timeline-height);
background: var(--color-bg-panel);
border-top: 1px solid var(--color-border);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
z-index: 1000;
gap: 20px;
}
.timeline-left, .timeline-right {
display: flex;
align-items: center;
gap: 12px;
}
.timeline-btn {
width: 40px;
height: 40px;
background: none;
border: none;
color: var(--color-text-muted);
cursor: pointer;
border-radius: var(--radius-sm);
display: flex;
align-items: center;
justify-content: center;
transition: all var(--transition-fast);
}
.timeline-btn:hover {
color: var(--color-text);
background: var(--color-bg-panel-hover);
}
.timeline-btn i {
font-size: 16px;
}
.timeline-btn.now-btn {
width: auto;
padding: 0 16px;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.5px;
color: var(--color-text);
}
.timeline-date-container {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.timeline-date {
font-size: 18px;
font-weight: 700;
color: #fff;
letter-spacing: 1px;
font-family: 'SF Mono', Monaco, monospace;
cursor: pointer;
padding: 10px 20px;
border-radius: var(--radius-sm);
transition: all var(--transition-fast);
display: flex;
align-items: center;
gap: 12px;
}
.timeline-date:hover {
background: var(--color-bg-panel-hover);
}
.timeline-date i {
font-size: 14px;
color: var(--color-primary);
}
.animate-btn {
color: var(--color-primary) !important;
background: rgba(78, 204, 196, 0.1) !important;
}
.animate-btn:hover {
background: rgba(78, 204, 196, 0.2) !important;
}
.animate-btn.playing {
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
/* Date Picker Modal */
.datepicker-modal {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.7);
z-index: 10000;
display: none;
align-items: center;
justify-content: center;
backdrop-filter: blur(4px);
}
.datepicker-modal.active {
display: flex;
}
.datepicker {
background: var(--color-bg-panel);
border-radius: var(--radius-md);
padding: 24px;
min-width: 320px;
box-shadow: var(--shadow-md);
}
.datepicker-header {
text-align: center;
font-size: 18px;
font-weight: 600;
margin-bottom: 20px;
color: var(--color-primary);
}
.datepicker-inputs {
display: flex;
gap: 12px;
margin-bottom: 20px;
}
.datepicker-inputs select, .datepicker-inputs input {
flex: 1;
height: 44px;
background: var(--color-bg-dark);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
padding: 0 12px;
color: var(--color-text);
font-size: 14px;
}
.datepicker-actions {
display: flex;
gap: 12px;
}
.datepicker-actions button {
flex: 1;
height: 44px;
border-radius: var(--radius-sm);
border: none;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all var(--transition-fast);
}
.datepicker-ok {
background: var(--color-primary);
color: var(--color-bg-dark);
}
.datepicker-ok:hover {
background: var(--color-primary-dark);
}
.datepicker-cancel {
background: var(--color-bg-dark);
color: var(--color-text);
}
.datepicker-cancel:hover {
background: var(--color-bg-panel-hover);
}
/* Mobile Zoom Buttons */
.mobile-zoom {
position: absolute;
bottom: 80px;
right: 16px;
display: flex;
flex-direction: column;
gap: 8px;
z-index: 998;
}
.mobile-zoom button {
width: 48px;
height: 48px;
background: var(--color-bg-panel);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
transition: all var(--transition-fast);
}
.mobile-zoom button:hover {
background: var(--color-bg-panel-hover);
color: var(--color-primary);
}
/* Coordinates Display */
.coords-display {
position: absolute;
bottom: 80px;
left: 16px;
background: var(--color-bg-panel);
padding: 10px 16px;
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
font-size: 12px;
color: var(--color-text-muted);
font-family: 'SF Mono', Monaco, monospace;
z-index: 998;
display: none;
}
.coords-display.active {
display: block;
}
/* Alert Dropdown */
.alert-dropdown {
position: absolute;
top: 72px;
right: 16px;
background: var(--color-bg-panel);
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
box-shadow: var(--shadow-md);
z-index: 999;
min-width: 280px;
display: none;
}
.alert-dropdown.active {
display: block;
}
.alert-header {
padding: 14px 16px;
border-bottom: 1px solid var(--color-border);
display: flex;
align-items: center;
gap: 10px;
font-size: 13px;
font-weight: 500;
}
.alert-header i {
color: #ff9800;
}
.alert-item {
padding: 12px 16px;
border-bottom: 1px solid var(--color-border);
font-size: 12px;
color: var(--color-text-secondary);
cursor: pointer;
transition: background var(--transition-fast);
}
.alert-item:hover {
background: var(--color-bg-panel-hover);
}
.alert-item:last-child {
border-bottom: none;
}
/* Comparison Mode Bar */
.comparison-bar {
position: absolute;
top: 72px;
left: 50%;
transform: translateX(-50%) translateY(-100%);
background: var(--color-bg-panel);
padding: 12px 20px;
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
display: flex;
align-items: center;
gap: 20px;
z-index: 998;
transition: transform var(--transition-normal);
}
.comparison-bar.active {
transform: translateX(-50%) translateY(0);
}
.comparison-title {
font-size: 13px;
font-weight: 600;
}
.comparison-modes {
display: flex;
gap: 8px;
}
.comparison-mode {
padding: 8px 16px;
background: var(--color-bg-dark);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
color: var(--color-text-muted);
font-size: 12px;
cursor: pointer;
transition: all var(--transition-fast);
}
.comparison-mode:hover, .comparison-mode.active {
color: var(--color-primary);
border-color: var(--color-primary);
}
/* Loading Spinner */
.map-loading {
position: absolute;
inset: 0;
background: var(--color-bg-dark);
display: flex;
align-items: center;
justify-content: center;
z-index: 997;
transition: opacity var(--transition-normal);
}
.map-loading.hidden {
opacity: 0;
pointer-events: none;
}
.spinner {
width: 48px;
height: 48px;
border: 3px solid var(--color-border);
border-top-color: var(--color-primary);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
/* Toast Notification */
.toast {
position: fixed;
bottom: 100px;
left: 50%;
transform: translateX(-50%) translateY(100px);
background: var(--color-bg-panel);
padding: 14px 24px;
border-radius: var(--radius-md);
border: 1px solid var(--color-primary);
color: var(--color-text);
font-size: 13px;
z-index: 10001;
transition: transform var(--transition-normal);
display: flex;
align-items: center;
gap: 12px;
}
.toast.active {
transform: translateX(-50%) translateY(0);
}
.toast i {
color: var(--color-primary);
}
/* Responsive */
@media (max-width: 768px) {
:root {
--sidebar-width: 100%;
}
#wvSidebarEl {
bottom: 0;
transform: translateX(-100%);
}
#wvSidebarEl.mobile-open {
transform: translateX(0);
}
#wvSidebarEl.collapsed {
transform: translateX(-100%);
}
#wvToolbarEl {
left: 12px !important;
}
.toolbar-brand {
display: none;
}
.mobile-only {
display: flex !important;
}
#timeline-container {
padding: 0 12px;
}
.timeline-date {
font-size: 14px;
padding: 8px 12px;
}
}
@media (min-width: 769px) {
.mobile-only {
display: none !important;
}
}
/* Utility */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Custom Scrollbar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: var(--color-bg-dark);
}
::-webkit-scrollbar-thumb {
background: var(--color-border);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* Leaflet Customization */
.leaflet-control-attribution {
background: var(--color-bg-panel) !important;
color: var(--color-text-muted) !important;
font-size: 10px !important;
padding: 4px 8px !important;
border-radius: var(--radius-sm) 0 0 0 !important;
}
.leaflet-control-attribution a {
color: var(--color-primary) !important;
}
/* Projection Toggle Modal */
.projection-modal {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.7);
z-index: 10000;
display: none;
align-items: center;
justify-content: center;
}
.projection-modal.active {
display: flex;
}
.projection-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
background: var(--color-bg-panel);
padding: 24px;
border-radius: var(--radius-md);
}
.projection-option {
width: 120px;
height: 120px;
background: var(--color-bg-dark);
border: 2px solid var(--color-border);
border-radius: var(--radius-md);
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
transition: all var(--transition-fast);
}
.projection-option:hover, .projection-option.active {
border-color: var(--color-primary);
}
.projection-option i {
font-size: 40px;
color: var(--color-text-muted);
}
.projection-option.active i {
color: var(--color-primary);
}
.projection-option span {
font-size: 12px;
color: var(--color-text);
}
/* Measure Tool */
.measure-tooltip {
background: var(--color-bg-panel);
border: 1px solid var(--color-primary);
color: var(--color-text);
padding: 8px 12px;
border-radius: var(--radius-sm);
font-size: 12px;
white-space: nowrap;
}
</style>
</head>
<body>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with anycoder</a>
<div id="app">
<!-- Sidebar -->
<section id="wvSidebarEl">
<div class="sidebar-header">
<div id="wv-logo" title="Reset to Defaults">WV</div>
<button class="sidebar-toggle-btn" id="collapseSidebarBtn" aria-label="Toggle Sidebar">
<i class="fa-solid fa-chevron-left"></i>
</button>
</div>
<div class="nav-tabs">
<button class="nav-item active" data-tab="layers">Layers</button>
<button class="nav-item" data-tab="events">Events</button>
</div>
<div class="tab-content">
<!-- Layers Tab -->
<div class="tab-pane active" id="layers-tab">
<div id="layers-scroll-container">
<!-- Reference Layers -->
<div class="layer-group">
<div class="layer-group-header" onclick="toggleGroup(this)">
<span>Reference</span>
<i class="fa-solid fa-chevron-down"></i>
</div>
<div class="group-content">
<div class="layer-item" data-layer="labels" onclick="toggleOverlay('labels', this)">
<div class="layer-visibility" id="labels-visibility">
<i class="fa-solid fa-eye-slash"></i>
</div>
<div class="layer-info">
<div class="layer-title">Place Labels</div>
<div class="layer-subtitle">Esri, TomTom, OpenStreetMap</div>
</div>
</div>
<div class="layer-item" data-layer="features" onclick="toggleOverlay('features', this)">
<div class="layer-visibility" id="features-visibility">
<i class="fa-solid fa-eye-slash"></i>
</div>
<div class="layer-info">
<div class="layer-title">Coastlines / Borders / Roads</div>
<div class="layer-subtitle">© OpenStreetMap contributors</div>
</div>
</div>
<div class="layer-item active" data-layer="coastlines" onclick="toggleOverlay('coastlines', this)">
<div class="layer-visibility visible" id="coastlines-visibility">
<i class="fa-solid fa-eye"></i>
</div>
<div class="layer-info">
<div class="layer-title">Coastlines</div>
<div class="layer-subtitle">© OpenStreetMap contributors</div>
</div>
</div>
</div>
</div>
<!-- Base Layers -->
<div class="layer-group">
<div class="layer-group-header" onclick="toggleGroup(this)">
<span>Base Layers</span>
<i class="fa-solid fa-chevron-down"></i>
</div>
<div class="group-content">
<div class="base-layer-item" data-base="pace" onclick="setBaseLayer('pace', this)">
<div class="base-layer-title">Corrected Reflectance (True Color) <span>PACE / OCI</span></div>
<div class="base-layer-source">Ocean Color Instrument</div>
</div>
<div class="base-layer-item" data-base="noaa21" onclick="setBaseLayer('noaa21', this)">
<div class="base-layer-title">Corrected Reflectance (True Color) <span>NOAA-21 / VIIRS</span></div>
<div class="base-layer-source">Visible Infrared Imaging Radiometer Suite</div>
<div class="layer-notice">!</div>
</div>
<div class="base-layer-item" data-base="noaa20" onclick="setBaseLayer('noaa20', this)">
<div class="base-layer-title">Corrected Reflectance (True Color) <span>NOAA-20 / VIIRS</span></div>
<div class="base-layer-source">Visible Infrared Imaging Radiometer Suite</div>
</div>
<div class="base-layer-item" data-base="snpp" onclick="setBaseLayer('snpp', this)">
<div class="base-layer-title">Corrected Reflectance (True Color) <span>Suomi NPP / VIIRS</span></div>
<div class="base-layer-source">Visible Infrared Imaging Radiometer Suite</div>
</div>
<div class="base-layer-item" data-base="aqua" onclick="setBaseLayer('aqua', this)">
<div class="base-layer-title">Corrected Reflectance (True Color) <span>Aqua / MODIS</span></div>
<div class="base-layer-source">Moderate Resolution Imaging Spectroradiometer</div>
</div>
<div class="base-layer-item active" data-base="terra" onclick="setBaseLayer('terra', this)">
<div class="base-layer-title">Corrected Reflectance (True Color) <span>Terra / MODIS</span></div>
<div class="base-layer-source">Moderate Resolution Imaging Spectroradiometer <span class="layer-badge">v6.1 NRT</span></div>
</div>
</div>
</div>
</div>
<div class="add-layers-container">
<button class="add-layers-btn" onclick="showAddLayers()">
<i class="fa-solid fa-plus"></i>
Add Layers
</button>
</div>
</div>
<!-- Events Tab -->
<div class="tab-pane" id="events-tab">
<div id="events-scroll-container">
<div class="event-item" onclick="flyToEvent(-34.6037, -58.3816, 'Wildfire in Argentina')">
<div class="event-category wildfire">
<i class="fa-solid fa-fire"></i>
Wildfire
</div>
<div class="event-title">Wildfire in Buenos Aires Province</div>
<div class="event-meta">
<span><i class="fa-regular fa-clock"></i> 2 hours ago</span>
<span><i class="fa-solid fa-location-dot"></i> Argentina</span>
</div>
</div>
<div class="event-item" onclick="flyToEvent(35.6762, 139.6503, 'Typhoon approaching Japan')">
<div class="event-category storm">
<i class="fa-solid fa-hurricane"></i>
Severe Storm
</div>
<div class="event-title">Typhoon Khanun approaching Honshu</div>
<div class="event-meta">
<span><i class="fa-regular fa-clock"></i> 5 hours ago</span>
<span><i class="fa-solid fa-location-dot"></i> Japan</span>
</div>
</div>
<div class="event-item" onclick="flyToEvent(64.9631, -19.0208, 'Volcanic eruption in Iceland')">
<div class="event-category volcano">
<i class="fa-solid fa-volcano"></i>
Volcano
</div>
<div class="event-title">Fagradalsfjall eruption continues</div>
<div class="event-meta">
<span><i class="fa-regular fa-clock"></i> 1 day ago</span>
<span><i class="fa-solid fa-location-dot"></i> Iceland</span>
</div>
</div>
<div class="event-item" onclick="flyToEvent(23.8103, 90.4125, 'Flooding in Bangladesh')">
<div class="event-category flood">
<i class="fa-solid fa-water"></i>
Flood
</div>
<div class="event-title">Monsoon flooding in Dhaka region</div>
<div class="event-meta">
<span><i class="fa-regular fa-clock"></i> 2 days ago</span>
<span><i class="fa-solid fa-location-dot"></i> Bangladesh</span>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Mobile Sidebar Toggle -->
<button class="mobile-only wv-toolbar-button" style="position: fixed; top: 12px; left: 12px; z-index: 1001;" onclick="toggleMobileSidebar()">
<i class="fa-solid fa-layer-group"></i>
<span class="badge">9</span>
</button>
<!-- Toolbar -->
<div id="wvToolbarEl">
<div class="toolbar-left">
<div class="toolbar-brand">
<div>
<div class="toolbar-brand-title">NASA Worldview</div>
<div class="toolbar-brand-subtitle">Earth Science Data System</div>
</div>
</div>
</div>
<div class="toolbar-right">
<button class="wv-toolbar-button" title="Location Search" onclick="toggleSearch()">
<i class="fa-solid fa-magnifying-glass-location"></i>
</button>
<button class="wv-toolbar-button" title="Share" onclick="shareMap()">
<i class="fa-solid fa-share-from-square"></i>
</button>
<button class="wv-toolbar-button" title="Switch Projection" onclick="toggleProjectionModal()">
<i class="fa-solid fa-earth-asia"></i>
</button>
<button class="wv-toolbar-button" title="Take Snapshot" onclick="takeSnapshot()">
<i class="fa-solid fa-camera"></i>
</button>
<button class="wv-toolbar-button" title="Information" onclick="showInfo()">
<i class="fa-solid fa-circle-info"></i>
<span class="badge">2</span>
</button>
</div>
</div>
<!-- Search Overlay -->
<div class="search-overlay" id="searchOverlay">
<div class="search-input-container">
<input type="text" class="search-input" id="searchInput" placeholder="Search for places, coordinates, or features..." onkeypress="handleSearchKey(event)">
<button class="search-close" onclick="toggleSearch()">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
</div>
<!-- Map -->
<div id="wv-map">
<div id="mapCanvas"></div>
<div class="map-loading" id="mapLoading">
<div class="spinner"></div>
</div>
</div>
<!-- Mobile Zoom Controls -->
<div class="mobile-zoom">
<button onclick="map.zoomIn()" title="Zoom In">
<i class="fa-solid fa-plus"></i>
</button>
<button onclick="map.zoomOut()" title="Zoom Out">
<i class="fa-solid fa-minus"></i>
</button>
</div>
<!-- Coordinates Display -->
<div class="coords-display" id="coordsDisplay">
<span id="coordsText">0.0000°, 0.0000°</span>
</div>
<!-- Alert Dropdown -->
<div class="alert-dropdown" id="alertDropdown">
<div class="alert-header">
<i class="fa-solid fa-triangle-exclamation"></i>
<span>Layer Notifications</span>
</div>
<div class="alert-item" onclick="showAlertDetail('noaa21')">
<strong>NOAA-21 VIIRS</strong> - Data availability delayed by 2 hours
</div>
<div class="alert-item" onclick="showAlertDetail('terra')">
<strong>Terra MODIS</strong> - Orbital maintenance scheduled
</div>
</div>
<!-- Comparison Mode Bar -->
<div class="comparison-bar" id="comparisonBar">
<span class="comparison-title">Comparison Mode</span>
<div class="comparison-modes">
<button class="comparison-mode active" onclick="setComparisonMode('swipe')">Swipe</button>
<button class="comparison-mode" onclick="setComparisonMode('opacity')">Opacity</button>
<button class="comparison-mode" onclick="setComparisonMode('spy')">Spy</button>
</div>
<button class="wv-toolbar-button" style="width: 32px; height: 32px;" onclick="toggleComparison()">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<!-- Timeline -->
<div id="timeline-container">
<div class="timeline-left">
<button class="timeline-btn" title="Previous Day" onclick="changeDate(-1)">
<i class="fa-solid fa-arrow-left"></i>
</button>
<button class="timeline-btn now-btn" title="Go to Today" onclick="goToToday()">
NOW
</button>
<button class="timeline-btn" title="Next Day" onclick="changeDate(1)">
<i class="fa-solid fa-arrow-right"></i>
</button>
</div>
<div class="timeline-date-container">
<div class="timeline-date" onclick="openDatePicker()">
<span id="dateDisplay">2026 JAN 29</span>
<i class="fa-solid fa-calendar"></i>
</div>
</div>
<div class="timeline-right">
<button class