
# PR: Improve timeline synchronization during long-distance navigation

## Overview

This change improves the synchronization between the timeline navigation (decade/year selector) and the event cards when jumping long distances.

Previously, when navigating repeatedly through decade and year buttons, the selected year in the navigation and the visible year in the timeline could become out of sync.  
This update focuses on stabilizing the jump behavior and scroll synchronization.

Instead of introducing Virtual Scroll immediately, the issue is addressed with a lighter-weight approach that prioritizes reliable navigation behavior.

---

# Key Changes

## Loading overlay for long-distance jumps

A semi-transparent loading overlay is displayed when navigating to a decade that has not yet been loaded.

This prevents the timeline from jumping before the necessary content is ready.

Files:
- `css/bio.css`
- `js/bio.js`

---

## Long-distance jump detection

Navigation now detects whether a jump crosses decades.

- **Same decade:** smooth scrolling
- **Different decade:** immediate scroll (`auto`) after content is prepared

This helps ensure accurate landing positions during large jumps.

---

## Unified scroll handling

A shared scrolling helper (`scrollToElement`) was introduced so that:

- year navigation
- hash navigation (`#year-XXXX`)
- other anchor-based jumps

all use the same scrolling logic.

This reduces inconsistencies between different navigation paths.

---

## Layout shift correction (image loading)

Images inside event cards may load after the initial scroll jump, causing layout shifts.

To compensate for this, the scroll position is re-adjusted several times shortly after the jump.

Current strategy:
- retry up to 6 times
- within a ~3 second window

This helps maintain the correct anchor alignment even when images load asynchronously.

---

## Scroll spy stabilization

Several improvements were made to the scroll spy logic:

- suppress scroll spy updates during initial page load
- extend the ignore window after manual navigation
- throttle debug logging
- only update when the active year actually changes

This prevents scroll spy from overriding the intended navigation target.

---

## Improved debugging logs

Debug logging now includes additional context such as:

- clicked decade/year
- active timeline decade/year
- focused event year
- date of the top visible event card

This helps diagnose synchronization issues more easily.

---

# Why Virtual Scroll was not introduced

Although Virtual Scroll was considered, the current issue is primarily related to **synchronization during long-distance jumps**, not normal scrolling performance.

Given the current scale (a few thousand event cards) and the need to preserve:

- anchor navigation
- search behavior
- variable-height cards
- complex card interactions

introducing Virtual Scroll at this stage would add significant complexity.

Therefore, the current fix focuses on stabilizing navigation behavior with a simpler approach.

Virtual Scroll can still be considered later if scrolling performance becomes a bottleneck.

---

# Future improvement (optional)

One potential improvement would be to make the position correction **event-driven instead of retry-based**.

Instead of retrying multiple times on a timer, we could observe layout changes around the target section and perform the final correction once the layout has settled (with a timeout fallback).

This could further improve stability when image loading timing varies.

---

# Modified files

bio-header2.html is based on bio-header.html, with adjustments made for this timeline synchronization. bio-header.html was test code based on bio.html that added headers and footers. The header and footer will be finalized later.

| File | Description |
|-----|-----|
| `bio-header2.html` | Created from `bio-header.html` with clearer header/footer markers |
| `css/bio.css` | Added loading overlay styles |
| `js/bio.js` | Added navigation fixes, scroll helpers, loading control, and scroll spy improvements |
