Period Navigator

D David Veksler · 1 year ago d50dec47971250a0439206d03da7a7ad545e9dfa
Parent: 492e5d091

1 file changed +264 −83

Diff

diff --git a/human-evolution.html b/human-evolution.html
index fbe6a2b..aadb972 100644
--- a/human-evolution.html
+++ b/human-evolution.html
@@ -3,7 +3,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Human Evolution: Journey Through Time</title>
+    <title>Human Evolution: Journey Through Time (Concise) - AWESOME Edition v3</title>
     <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css" />
     <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
@@ -62,9 +62,6 @@
         margin: 0;
         overflow: hidden;
         background: var(--dark-bg);
-        /* Optional subtle noise texture for richness:
-           background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cfilter id='n' x='0' y='0'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100' height='100' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
-        */
         color: var(--text-color);
         display: flex;
         flex-direction: column;
@@ -117,26 +114,10 @@
         gap: 1rem;
       }
 
-      @media (max-width: 992px) {
-        #main-content {
-          flex-direction: column;
-        }
-        #controls-sidebar {
-          width: 100%;
-          max-height: 45vh;
-          border-right: none;
-          border-bottom: 1px solid var(--light-bg);
-        }
-        #map-container {
-          flex-grow: 1;
-          height: auto;
-        }
-      }
-
       #map-container {
         flex: 1;
         position: relative;
-        background: #0a0a0a; /* Original, could be var(--dark-bg) too */
+        background: #0a0a0a;
       }
 
       #map {
@@ -186,7 +167,6 @@
         line-height: 1.65;
         font-size: 0.85rem;
       }
-      /* Specific narrative text element to ensure it takes base body styling */
       #narrative-panel .card-body p#narrative-text-element {
           line-height: 1.65;
           font-size: 0.85rem;
@@ -264,7 +244,7 @@
                     filter var(--transition-speed) var(--transition-timing),
                     box-shadow var(--transition-speed) var(--transition-timing);
         border: 1px solid var(--light-bg);
-        margin-top: 0.25rem; /* Retain original */
+        margin-top: 0.25rem;
       }
       .timeline-buttons .btn i,
       #reset-button i {
@@ -272,14 +252,13 @@
         transition: transform var(--transition-speed) var(--transition-timing);
         vertical-align: middle;
       }
-      .timeline-buttons .btn:hover i, /* Only scale icon if button itself is hovered */
+      .timeline-buttons .btn:hover i,
       #reset-button:hover i {
           transform: scale(1.1);
       }
-      .timeline-buttons .btn-group { margin-top: 0.25rem; } /* Retain original */
+      .timeline-buttons .btn-group { margin-top: 0.25rem; }
 
 
-      /* Primary styled buttons (Play, active speed, active quick filters) */
       #play-pause-button,
       .timeline-buttons .speed-btn.active,
       .quick-filter-buttons .btn.active {
@@ -295,22 +274,20 @@
           box-shadow: 0 4px 12px var(--focus-ring-color);
       }
 
-      /* Outline styled buttons (inactive speed, inactive quick filters) */
       .btn-outline-light {
           color: var(--text-muted-color);
           border-color: var(--light-bg);
           background-color: transparent;
       }
       .btn-outline-light:hover,
-      .btn-outline-light.active { /* .active might be added by bootstrap too */
-          color: var(--text-heading-color); /* Text color for active/hover state */
-          background-color: var(--primary-accent-static); /* Use static accent for hover of outline */
+      .btn-outline-light.active {
+          color: var(--text-heading-color); 
+          background-color: var(--primary-accent-static); 
           border-color: var(--primary-accent-static);
       }
-       /* Ensure active quick filter buttons specifically use the gradient */
       .quick-filter-buttons .btn.active,
       .timeline-buttons .speed-btn.active {
-          background: var(--primary-accent-gradient); /* Override general .active if needed */
+          background: var(--primary-accent-gradient); 
           border-color: transparent;
           color: var(--text-heading-color);
       }
@@ -331,6 +308,30 @@
           filter: brightness(110%);
           box-shadow: 0 4px 12px rgba(var(--danger-accent-rgb), 0.5);
       }
+      
+      /* Period Navigator Select Styling */
+      #period-filter-select {
+        background-color: var(--dark-bg);
+        color: var(--text-color);
+        border: 1px solid var(--light-bg);
+        border-radius: var(--border-radius-pill);
+        padding: 0.375rem 2.25rem 0.375rem 0.75rem;
+        font-size: 0.8rem;
+        font-weight: var(--font-weight-medium);
+        transition: border-color var(--transition-speed) var(--transition-timing), 
+                    box-shadow var(--transition-speed) var(--transition-timing);
+      }
+      #period-filter-select:focus {
+        border-color: var(--primary-accent-static);
+        box-shadow: 0 0 0 0.25rem var(--focus-ring-color);
+        background-color: var(--dark-bg); 
+        color: var(--text-color);
+      }
+      #period-filter-select option {
+        background-color: var(--medium-bg);
+        color: var(--text-color);
+      }
+
 
       #species-filter-list {
         max-height: 180px;
@@ -356,7 +357,7 @@
         border-bottom: none;
       }
       #species-filter-list .form-check-label {
-        font-size: 0.8rem; /* Overridden by general p styling, but kept for specificity if needed */
+        font-size: 0.8rem;
         cursor: pointer;
         margin-left: 0.5rem;
         color: var(--text-color);
@@ -402,8 +403,6 @@
       }
 
       #narrative-panel .card-body {
-        /* font-size: 0.8rem; Original, now handled by p#narrative-text-element */
-        /* line-height: 1.5; Original */
         color: var(--text-color);
         overflow-y: auto;
       }
@@ -411,19 +410,19 @@
         color: var(--timeline-period-color);
         font-weight: var(--font-weight-medium);
       }
-       #narrative-text-element { /* Ensured by specific p rule above */
+       #narrative-text-element {
         color: var(--text-color) !important;
       }
 
       .data-limitation-note {
         color: var(--warning-accent);
         font-size: 0.78rem;
-        border-top: 1px dashed var(--light-bg); /* Original had this, now it's a bg box */
         padding-top: 0.6rem;
         margin-top: 0.75rem;
         background-color: rgba(var(--warning-accent-rgb), 0.05);
         padding: 0.5rem;
         border-radius: 4px;
+        border-top: none; /* Removed original dashed top border as it's a box now */
       }
       .data-limitation-note i {
         margin-right: 0.35rem;
@@ -467,7 +466,6 @@
         display: flex;
         align-items: center;
         margin-bottom: 0.3rem;
-        /* font-size: 0.78rem; Handled by general p/span rule */
         padding: 0.1rem 0;
       }
       .legend-color-box {
@@ -490,8 +488,6 @@
         display: flex;
         align-items: center;
         justify-content: center;
-        /* color: white; Handled by p */
-        /* font-size: 1.2rem; Handled by p */
         z-index: 9999;
         flex-direction: column;
       }
@@ -525,18 +521,18 @@
         right: 10px;
         background: var(--medium-bg);
         padding: 0.4rem 0.6rem;
-        border-radius: var(--border-radius-standard); /* Updated radius */
+        border-radius: var(--border-radius-standard);
         z-index: 1000;
-        box-shadow: var(--modern-shadow); /* Updated shadow */
+        box-shadow: var(--modern-shadow);
         border: 1px solid var(--light-bg);
       }
       .climate-toggle-container .form-check-label {
-        font-size: 0.75rem; /* Original */
+        font-size: 0.75rem;
         color: var(--text-muted-color);
       }
       .climate-toggle-container .form-check-input {
-        border-color: var(--primary-accent-static); /* Use static for consistency */
-        background-color: var(--medium-bg); /* Ensure it's not transparent */
+        border-color: var(--primary-accent-static);
+        background-color: var(--medium-bg);
       }
       .climate-toggle-container .form-check-input:checked {
         background-color: var(--primary-accent-static);
@@ -549,8 +545,8 @@
         background-color: var(--medium-bg) !important;
         color: var(--text-color) !important;
         border: 1px solid var(--light-bg) !important;
-        border-radius: var(--border-radius-standard) !important; /* Softer radius */
-        box-shadow: var(--card-element-shadow) !important; /* Subtle shadow */
+        border-radius: var(--border-radius-standard) !important;
+        box-shadow: var(--card-element-shadow) !important;
         transition: background-color var(--transition-speed) var(--transition-timing) !important;
       }
       .leaflet-control-zoom-in:hover,
@@ -566,12 +562,12 @@
         border: 1px solid var(--light-bg);
         border-radius: var(--border-radius-standard);
       }
-      .leaflet-popup-content-wrapper { padding: 1px; } /* Leaflet default behavior */
-      .leaflet-popup-content { /* Inner content area */
+      .leaflet-popup-content-wrapper { padding: 1px; } 
+      .leaflet-popup-content { 
         padding: 0.8rem 1rem;
         font-size: 0.85rem;
         line-height: 1.6;
-        margin: 0 !important; /* Override Leaflet's p margin */
+        margin: 0 !important;
       }
       .leaflet-popup-content h5 {
         margin-top: 0;
@@ -590,17 +586,38 @@
       .leaflet-container a.leaflet-popup-close-button:hover {
         color: var(--danger-accent);
       }
+      .popup-species-image {
+        max-height: 100px;
+        width: auto;
+        display: block;
+        margin-left: auto;
+        margin-right: auto;
+        border: 1px solid var(--light-bg);
+        border-radius: var(--border-radius-standard); /* Match other radii */
+      }
+      .popup-learn-more {
+        color: var(--primary-accent-static);
+        text-decoration: none;
+        font-weight: var(--font-weight-medium);
+      }
+      .popup-learn-more:hover {
+        color: var(--primary-accent-end);
+        text-decoration: underline;
+      }
+      .popup-learn-more i {
+        font-size: 0.8em;
+        margin-left: 0.2em;
+      }
 
       /* Focus States */
       *:focus-visible {
         outline: 2px solid var(--focus-ring-color);
         outline-offset: 2px;
-        /* box-shadow: 0 0 0 3px rgba(var(--focus-ring-color-rgb), 0.5); Requires focus-ring-color-rgb */
       }
-      #species-filter-list .form-check-input:focus-visible {
+      #species-filter-list .form-check-input:focus-visible,
+      #period-filter-select:focus-visible { /* Add period filter to custom focus */
         box-shadow: 0 0 0 2px var(--dark-bg), 0 0 0 4px var(--focus-ring-color);
       }
-       /* Ensure tooltips are styled for the new theme if they appear */
       .tooltip-inner {
         background-color: var(--primary-accent-static);
         color: var(--text-heading-color);
@@ -609,18 +626,126 @@
         font-size: 0.75rem;
       }
       .tooltip .tooltip-arrow::before {
-        border-top-color: var(--primary-accent-static) !important; /* Example for top tooltip */
-        border-bottom-color: var(--primary-accent-static) !important; /* Example for bottom tooltip */
+        border-top-color: var(--primary-accent-static) !important; 
+        border-bottom-color: var(--primary-accent-static) !important;
         border-left-color: var(--primary-accent-static) !important;
         border-right-color: var(--primary-accent-static) !important;
       }
 
+      /* Responsive Adjustments */
+      @media (max-width: 992px) {
+        #main-content {
+          flex-direction: column;
+        }
+        #controls-sidebar {
+          width: 100%;
+          max-height: 45vh; /* Original */
+          border-right: none;
+          border-bottom: 1px solid var(--light-bg);
+        }
+        #map-container {
+          flex-grow: 1;
+          height: auto;
+        }
+      }
+
+      @media (max-width: 767.98px) {
+        :root {
+            /* --sidebar-width: 100%; Already handled by .controls-sidebar in this query */
+        }
+
+        header.app-header h1 { font-size: 1.3rem; }
+        header.app-header h1 i { margin-right: 0.5rem; }
+
+        #controls-sidebar {
+            padding: 0.75rem;
+            gap: 0.75rem;
+            max-height: 50vh; 
+        }
+
+        .control-card .card-header { font-size: 0.8rem; padding: 0.5rem 0.75rem; }
+        .control-card .card-body { padding: 0.6rem 0.75rem; }
+
+        #current-period-display { font-size: 1.1rem; }
+        #timeline-value-display { font-size: 0.7rem; margin-bottom: 0.5rem; }
+        #timeline-scrubber { margin: 0.5rem 0; }
+        #timeline-scrubber::-webkit-slider-thumb { width: 18px; height: 18px; }
+        #timeline-scrubber::-moz-range-thumb { width: 18px; height: 18px; }
+
+
+        .timeline-buttons .btn,
+        .quick-filter-buttons .btn,
+        #reset-button { padding: 0.3rem 0.75rem; font-size: 0.75rem; }
+        .timeline-buttons .btn i, #reset-button i { margin-right: 0.25rem; }
+
+        #period-filter-select { font-size: 0.75rem; padding-top: 0.3rem; padding-bottom: 0.3rem; }
+
+        #species-filter-list .form-check-label { font-size: 0.75rem; }
+        #species-filter-list .form-check-input { width: 1em; height: 1em; }
+        #species-filter-list .form-check-input:checked::before { font-size: 0.7em; }
+        .species-color-indicator { width: 10px; height: 10px; }
+
+
+        #narrative-panel .card-body,
+        #narrative-panel .card-body p#narrative-text-element,
+        .data-limitation-note { font-size: 0.75rem; }
+
+        .legend { padding: 0.5rem 0.75rem; max-height: 150px; }
+        .legend h5 { font-size: 0.8rem; }
+        .legend-item { font-size: 0.7rem; }
+        .legend-color-box { width: 10px; height: 10px; }
+
+        .leaflet-popup-content { padding: 0.6rem 0.8rem; font-size: 0.75rem; }
+        .leaflet-popup-content h5 { font-size: 1em; }
+      }
+
+      @media (max-width: 575.98px) {
+        header.app-header { padding: 0 1rem; }
+        header.app-header h1 { font-size: 1.15rem; }
+        header.app-header h1 i { font-size: 0.9em; }
+
+
+        #controls-sidebar { padding: 0.5rem; gap: 0.5rem; }
+
+        .control-card .card-header { font-size: 0.75rem; padding: 0.4rem 0.6rem; }
+        .control-card .card-header i { font-size: 0.85em; }
+        .control-card .card-body { padding: 0.5rem 0.6rem; }
+        .control-card .card-header + .card-body { padding-top: 0.75rem; }
+
+
+        #current-period-display { font-size: 1rem; }
+
+        .timeline-buttons { flex-wrap: wrap; gap: 0.25rem; }
+        .timeline-buttons .btn,
+        .timeline-buttons .btn-group, /* Target group directly for basis */
+        #reset-button { /* Play, Group, Reset */
+             flex-grow: 1; /* Allow them to grow */
+             flex-basis: auto; /* Reset basis or set to a meaningful min-content */
+        }
+         /* Make all three items (Play button, Speed group, Reset button) share space */
+        .d-flex.justify-content-between.align-items-center.mt-2.timeline-buttons > * {
+            flex-basis: calc(33.333% - 0.2rem); /* Approx 1/3 width, accounting for gap */
+            min-width: 80px; /* Prevent them from becoming too small */
+        }
+        .timeline-buttons .btn-group { display: flex; }
+        .timeline-buttons .btn-group .btn { flex-grow: 1; }
+
+
+        .quick-filter-buttons .btn { font-size: 0.7rem; padding: 0.25rem 0.5rem; }
+
+        #species-filter-list { max-height: 120px; }
+        
+        #narrative-panel .card-body,
+        #narrative-panel .card-body p#narrative-text-element,
+        .data-limitation-note { font-size: 0.7rem; }
+        .data-limitation-note i { display: none; }
+      }
+
     </style>
   </head>
 
   <body>
     <div id="loading-screen" class="loading-overlay">
-      <!-- Spinner is now CSS-only via ::before on loading-overlay -->
       <p class="mt-2 mb-0">Loading Evolution Data...</p>
     </div>
     <header class="app-header">
@@ -636,7 +761,7 @@
               <span id="timeline-value-display"></span>
               <input
                 type="range"
-                class="form-range" /* Bootstrap class, custom styles will override */
+                class="form-range"
                 id="timeline-scrubber"
                 min="0"
                 value="0"
@@ -647,9 +772,10 @@
               <div class="d-flex justify-content-between align-items-center mt-2 timeline-buttons">
                 <button
                   id="play-pause-button"
-                  class="btn btn-sm" /* Removed btn-primary, style handled by ID */
+                  class="btn btn-sm"
                   disabled
                   data-bs-toggle="tooltip"
+                  data-bs-placement="top" 
                   title="Play or Pause animation"
                 >
                   <i class="bi bi-play-fill"></i> <span>Play</span>
@@ -666,7 +792,7 @@
                 </div>
                 <button
                   id="reset-button"
-                  class="btn btn-sm" /* Removed btn-danger, style handled by ID */
+                  class="btn btn-sm"
                   disabled
                   data-bs-toggle="tooltip"
                   title="Reset timeline to start"
@@ -676,6 +802,19 @@
               </div>
             </div>
           </div>
+
+          <!-- NEW: Period Navigation Card -->
+          <div class="control-card card">
+              <div class="card-header"><i class="bi bi-collection-play"></i> Period Navigator</div>
+              <div class="card-body">
+                  <label for="period-filter-select" class="form-label visually-hidden">Select a Time Period</label>
+                  <select class="form-select" id="period-filter-select" data-bs-toggle="tooltip" title="Jump to a specific period">
+                      <option selected disabled value="">Select a period...</option>
+                      <!-- Options will be populated by JavaScript -->
+                  </select>
+              </div>
+          </div>
+
           <div class="control-card card">
             <div class="card-header"><i class="bi bi-people-fill"></i> Species Filter</div>
             <div class="card-body">
@@ -777,13 +916,15 @@
             narrativeTextElement: null,
             loadingScreen: null,
             controlsContentDiv: null,
-            climateToggle: null
+            climateToggle: null,
+            periodFilterSelect: null // Added for Period Navigator
         };
     
         function populateDomElements() {
             const idMap = {
                 controlsContentDiv: 'controls-content',
-                climateToggle: 'climate-toggle-switch'
+                climateToggle: 'climate-toggle-switch',
+                periodFilterSelect: 'period-filter-select' // Added
             };
             for (const key in domElements) {
                 if (key === 'playPauseIcon' || key === 'playPauseText') continue;
@@ -843,6 +984,29 @@
             }
         }
     
+        function populatePeriodFilter() {
+            if (!domElements.periodFilterSelect || !timePeriodsData || timePeriodsData.length === 0) {
+                if (domElements.periodFilterSelect) domElements.periodFilterSelect.disabled = true;
+                return;
+            }
+            domElements.periodFilterSelect.disabled = false;
+            domElements.periodFilterSelect.innerHTML = ''; // Clear existing options
+
+            const defaultOption = document.createElement('option');
+            defaultOption.textContent = 'Select a period...';
+            defaultOption.value = ""; 
+            defaultOption.disabled = true;
+            // defaultOption.selected = true; // Will be handled by updateUIForCurrentPeriod setting the correct index
+            domElements.periodFilterSelect.appendChild(defaultOption);
+
+            timePeriodsData.forEach((period, index) => {
+                const option = document.createElement('option');
+                option.value = index;
+                option.textContent = period.periodName || `Period ${index + 1}`;
+                domElements.periodFilterSelect.appendChild(option);
+            });
+        }
+
     
         function initializeApplication() {
             if (!domElements.loadingScreen || !domElements.controlsContentDiv) {
@@ -855,7 +1019,7 @@
             domElements.controlsContentDiv.classList.remove('d-none');
 
             Object.values(domElements).forEach(el => {
-                if (el && typeof el.disabled === 'boolean') {
+                if (el && el.id !== 'period-filter-select' && typeof el.disabled === 'boolean') { // Don't enable period filter select here
                     el.disabled = false;
                 }
             });
@@ -865,10 +1029,11 @@
 
             populateAllSpeciesList();
             populateSpeciesFilter();
+            populatePeriodFilter(); // Populate period filter
             currentPeriodIndex = 0;
-            updateSpeedButtonsActiveState(); // Includes ensuring 1x is active
-            updateQuickFilterActiveState('filter-all'); // Set 'All' as active by default
-            updateUIForCurrentPeriod();
+            updateSpeedButtonsActiveState(); 
+            updateQuickFilterActiveState('filter-all'); 
+            updateUIForCurrentPeriod(); // This will now also set periodFilterSelect
 
 
             const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
@@ -907,7 +1072,7 @@
                 input.addEventListener('change', (event) => {
                     selectedSpecies[event.target.value] = event.target.checked;
                     updateUIForCurrentPeriod(); 
-                    updateQuickFilterActiveState(null); // Clear All/None/Homo if individual changes
+                    updateQuickFilterActiveState(null); 
                 });
                 const colorIndicator = document.createElement('span');
                 colorIndicator.className = 'species-color-indicator';
@@ -915,11 +1080,10 @@
     
                 const label = document.createElement('label');
                 label.className = 'form-check-label'; label.htmlFor = input.id;
-                // label.style.color = 'var(--text-color)'; // Set by global CSS
                 label.textContent = s.name;
     
                 itemDiv.appendChild(input);
-                itemDiv.appendChild(colorIndicator); // Swapped order with label for better alignment with custom checkbox
+                itemDiv.appendChild(colorIndicator); 
                 itemDiv.appendChild(label);
                 domElements.speciesFilterList.appendChild(itemDiv);
             });
@@ -936,6 +1100,7 @@
                     domElements.narrativeTextElement.textContent = "End of timeline data.";
                 }
                 if(domElements.legendItemsContainer) domElements.legendItemsContainer.innerHTML = '<small class="text-muted">No active period.</small>';
+                if(domElements.periodFilterSelect) domElements.periodFilterSelect.value = ""; // Select placeholder
                 return;
             }
     
@@ -943,6 +1108,9 @@
             if(domElements.currentPeriodDisplay) domElements.currentPeriodDisplay.textContent = period.periodName || "Unknown Period";
             if(domElements.timelineValueDisplay) domElements.timelineValueDisplay.textContent = period.timeRange || `Period ${currentPeriodIndex + 1}`;
             if (domElements.timelineScrubber) domElements.timelineScrubber.value = currentPeriodIndex;
+            if (domElements.periodFilterSelect) { // Set period filter select
+                 domElements.periodFilterSelect.value = currentPeriodIndex;
+            }
             
             if(domElements.narrativeTextElement) {
                 domElements.narrativeTextElement.style.color = 'var(--text-color)';
@@ -956,14 +1124,20 @@
                 if (s && s.name && selectedSpecies[s.name]) {
                     visibleSpeciesInLegend.push(s); 
     
+                    // ENHANCED POPUP CONTENT
+                    let learnMoreLink = s.learnMoreUrl ? `<p class="mb-1 mt-1 small"><a href="${s.learnMoreUrl}" target="_blank" rel="noopener noreferrer" class="popup-learn-more">Learn More <i class="bi bi-box-arrow-up-right"></i></a></p>` : '';
+                    let speciesImage = s.imageUrl ? `<img src="${s.imageUrl}" alt="${s.name}" class="img-fluid rounded mb-2 popup-species-image">` : '';
+
                     let popupContent = `<h5>${s.name}</h5>
+                                        ${speciesImage}
                                         <p class="mb-1 small"><strong>Timeline:</strong> ${s.timeline || 'N/A'}</p>
-                                        <p class="mb-0 small">${s.notes || 'No specific notes.'}</p>`;
+                                        <p class="mb-0 small">${s.notes || 'No specific notes.'}</p>
+                                        ${learnMoreLink}`;
     
                     if (s.estimatedRangeGeoJson && Object.keys(s.estimatedRangeGeoJson).length > 0) {
                         try {
                             L.geoJSON(s.estimatedRangeGeoJson, {
-                                style: { // AWESOME EDITION STYLE
+                                style: { 
                                     fillColor: s.color || '#888888',
                                     weight: 1.5, 
                                     opacity: 1,
@@ -979,7 +1153,7 @@
                             if (path && Object.keys(path).length > 0) {
                                try {
                                     L.geoJSON(path, {
-                                        style: { // AWESOME EDITION STYLE
+                                        style: { 
                                             color: s.migrationColor || s.color || '#888888',
                                             weight: 3, 
                                             opacity: 0.75,
@@ -1009,7 +1183,6 @@
                 const colorBox = document.createElement('span');
                 colorBox.className = 'legend-color-box'; colorBox.style.backgroundColor = s.color || '#cccccc';
                 const nameSpan = document.createElement('span'); nameSpan.textContent = s.name;
-                // nameSpan.style.color = 'var(--text-color)'; // Set by global CSS
                 itemDiv.appendChild(colorBox); itemDiv.appendChild(nameSpan);
                 domElements.legendItemsContainer.appendChild(itemDiv);
             });
@@ -1055,7 +1228,7 @@
                         if (sheet && sheet.type && sheet.coordinates) { 
                            try {
                                 L.geoJSON(sheet, {
-                                    style: { // AWESOME EDITION STYLE
+                                    style: { 
                                         color: 'rgba(173, 216, 230, 0.5)', 
                                         fillColor: '#A2D1E6', 
                                         fillOpacity: 0.35,
@@ -1080,7 +1253,6 @@
             }
         }
     
-        // --- Animation & Controls ---
         function animationLoop(timestamp) {
             if (!isPlaying) return;
     
@@ -1130,6 +1302,7 @@
             pauseAnimation();
             currentPeriodIndex = 0;
             if (domElements.timelineScrubber) domElements.timelineScrubber.value = 0;
+            // periodFilterSelect will be updated by updateUIForCurrentPeriod
             playbackSpeed = 1;
             updateSpeedButtonsActiveState();
             if (allSpeciesList && allSpeciesList.length > 0) {
@@ -1140,37 +1313,35 @@
                     cb.checked = true;
                 });
             }
-            updateQuickFilterActiveState('filter-all'); // Reset to 'All'
-            updateUIForCurrentPeriod();
+            updateQuickFilterActiveState('filter-all'); 
+            updateUIForCurrentPeriod(); // This will sync periodFilterSelect
         }
     
         function updateSpeedButtonsActiveState() {
             document.querySelectorAll('.speed-btn').forEach(btn => {
                 btn.classList.remove('active');
-                btn.classList.add('btn-outline-light'); // Ensure outline is re-applied
+                btn.classList.add('btn-outline-light'); 
                 if (parseInt(btn.dataset.speed) === playbackSpeed) {
                     btn.classList.add('active');
-                    btn.classList.remove('btn-outline-light'); // Remove outline for active state
+                    btn.classList.remove('btn-outline-light'); 
                 }
             });
         }
 
-        // Function to update active state for quick filter buttons
         function updateQuickFilterActiveState(activeButtonId) {
             document.querySelectorAll('.quick-filter-buttons .btn').forEach(btn => {
                 btn.classList.remove('active');
-                btn.classList.add('btn-outline-light'); // Ensure outline is re-applied
+                btn.classList.add('btn-outline-light'); 
             });
             if (activeButtonId) {
                 const activeButton = document.getElementById(activeButtonId);
                 if (activeButton) {
                     activeButton.classList.add('active');
-                    activeButton.classList.remove('btn-outline-light'); // Remove outline for active state
+                    activeButton.classList.remove('btn-outline-light'); 
                 }
             }
         }
     
-        // --- Event Listeners ---
         function addEventListeners() {
             if (!domElements.timelineScrubber || !domElements.playPauseButton || !domElements.resetButton) { 
                 console.error("Cannot add event listeners: Core DOM elements for controls not found.");
@@ -1223,9 +1394,19 @@
                     }
                 });
             }
+
+            if (domElements.periodFilterSelect) { // Event listener for Period Navigator
+                domElements.periodFilterSelect.addEventListener('change', (event) => {
+                    const selectedIndex = parseInt(event.target.value);
+                    if (!isNaN(selectedIndex) && selectedIndex >= 0 && selectedIndex < timePeriodsData.length) {
+                        currentPeriodIndex = selectedIndex;
+                        pauseAnimation(); 
+                        updateUIForCurrentPeriod();
+                    }
+                });
+            }
         }
     
-        // --- Initial Load ---
         document.addEventListener('DOMContentLoaded', () => {
             populateDomElements(); 
             addEventListeners();