worldwander-site/index.html

1576 lines
74 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WorldWander - 365 Days. 40 Countries. One Story.</title>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400;1,700&family=Open+Sans:wght@300;400;600;700&family=Dancing+Script:wght@400;700&display=swap" rel="stylesheet">
<style>
/* ============================================
CSS RESET & BASE
============================================ */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; font-size: 16px; }
body {
font-family: 'Open Sans', sans-serif;
background: #F5F0E8;
color: #2C1810;
overflow-x: hidden;
line-height: 1.7;
}
/* ============================================
COLOR PALETTE VARIABLES
============================================ */
:root {
--dark-brown: #2C1810;
--forest-green: #4A6741;
--sandy-gold: #D4A574;
--cream: #F5F0E8;
--saddle-brown: #8B4513;
--deep-green: #2d3e28;
--warm-gold: #c49a6c;
--light-sage: #a8b99a;
}
/* ============================================
TYPOGRAPHY
============================================ */
h1, h2, h3, h4 { font-family: 'Playfair Display', serif; }
.journal-text { font-family: 'Dancing Script', cursive; }
/* ============================================
SCROLL ANIMATIONS
============================================ */
.reveal {
opacity: 0;
transform: translateY(40px);
transition: opacity 0.9s ease, transform 0.9s ease;
}
.reveal.visible {
opacity: 1;
transform: translateY(0);
}
.reveal-left {
opacity: 0;
transform: translateX(-60px);
transition: opacity 0.9s ease, transform 0.9s ease;
}
.reveal-left.visible {
opacity: 1;
transform: translateX(0);
}
.reveal-right {
opacity: 0;
transform: translateX(60px);
transition: opacity 0.9s ease, transform 0.9s ease;
}
.reveal-right.visible {
opacity: 1;
transform: translateX(0);
}
/* ============================================
NAVIGATION BAR
============================================ */
.site-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
background: rgba(44, 24, 16, 0.0);
backdrop-filter: blur(0px);
transition: background 0.4s ease, backdrop-filter 0.4s ease, box-shadow 0.4s ease;
padding: 1rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.site-nav.scrolled {
background: rgba(44, 24, 16, 0.92);
backdrop-filter: blur(12px);
box-shadow: 0 2px 20px rgba(0,0,0,0.3);
padding: 0.6rem 2rem;
}
.nav-logo {
font-family: 'Playfair Display', serif;
font-size: 1.4rem;
font-weight: 700;
color: #F5F0E8;
text-decoration: none;
letter-spacing: 2px;
}
.nav-links {
display: flex;
gap: 1.5rem;
list-style: none;
}
.nav-links a {
color: rgba(245, 240, 232, 0.85);
text-decoration: none;
font-size: 0.85rem;
font-weight: 600;
letter-spacing: 1.5px;
text-transform: uppercase;
transition: color 0.3s;
}
.nav-links a:hover { color: var(--sandy-gold); }
.mobile-menu-btn {
display: none;
background: none;
border: none;
color: var(--cream);
font-size: 1.5rem;
cursor: pointer;
}
@media (max-width: 768px) {
.nav-links { display: none; flex-direction: column; position: absolute; top: 100%; left: 0; right: 0; background: rgba(44,24,16,0.95); padding: 1rem 2rem; gap: 1rem; }
.nav-links.open { display: flex; }
.mobile-menu-btn { display: block; }
}
/* ============================================
HERO SECTION
============================================ */
.hero {
position: relative;
height: 100vh;
min-height: 600px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
overflow: hidden;
}
.hero-bg {
position: absolute;
inset: 0;
background: url('images/chile_andes.jpg') center center / cover no-repeat;
transform: scale(1.1);
transition: transform 0.1s linear;
}
.hero-overlay {
position: absolute;
inset: 0;
background: linear-gradient(
180deg,
rgba(44, 24, 16, 0.3) 0%,
rgba(44, 24, 16, 0.55) 50%,
rgba(44, 24, 16, 0.85) 100%
);
}
.hero-content {
position: relative;
z-index: 2;
color: var(--cream);
max-width: 800px;
padding: 0 2rem;
}
.hero-content h1 {
font-size: clamp(3rem, 8vw, 6rem);
font-weight: 900;
letter-spacing: 6px;
text-transform: uppercase;
margin-bottom: 0.5rem;
text-shadow: 0 4px 30px rgba(0,0,0,0.5);
}
.hero-content .subtitle {
font-family: 'Dancing Script', cursive;
font-size: clamp(1.2rem, 3vw, 2rem);
color: var(--sandy-gold);
margin-bottom: 1.5rem;
}
.hero-content .year-badge {
display: inline-block;
border: 2px solid var(--sandy-gold);
padding: 0.4rem 1.5rem;
font-size: 0.85rem;
letter-spacing: 3px;
text-transform: uppercase;
margin-bottom: 2rem;
}
.scroll-indicator {
position: absolute;
bottom: 2rem;
left: 50%;
transform: translateX(-50%);
z-index: 3;
color: var(--cream);
text-align: center;
animation: bounce 2s infinite;
cursor: pointer;
}
.scroll-indicator span {
display: block;
font-size: 0.7rem;
letter-spacing: 3px;
text-transform: uppercase;
margin-bottom: 0.5rem;
opacity: 0.7;
}
.scroll-indicator .arrow {
font-size: 2rem;
opacity: 0.7;
}
@keyframes bounce {
0%, 100% { transform: translateX(-50%) translateY(0); }
50% { transform: translateX(-50%) translateY(10px); }
}
/* ============================================
PROLOGUE / ORIGIN STORY
============================================ */
.prologue {
max-width: 800px;
margin: 0 auto;
padding: 8rem 2rem;
text-align: center;
}
.prologue .journal-ornament {
font-size: 2rem;
color: var(--sandy-gold);
margin-bottom: 2rem;
letter-spacing: 8px;
}
.prologue h2 {
font-size: clamp(2rem, 4vw, 3rem);
font-weight: 400;
font-style: italic;
color: var(--saddle-brown);
margin-bottom: 2rem;
line-height: 1.4;
}
.prologue .origin-text {
font-size: 1.1rem;
line-height: 2;
color: #5a4030;
margin-bottom: 1.5rem;
}
.prologue .journal-quote {
font-family: 'Dancing Script', cursive;
font-size: 1.6rem;
color: var(--forest-green);
margin: 2.5rem 0;
padding: 1.5rem 2rem;
border-left: 3px solid var(--sandy-gold);
}
.prologue .separator {
width: 60px;
height: 2px;
background: var(--sandy-gold);
margin: 3rem auto;
}
/* ============================================
JOURNEY TIMELINE
============================================ */
.timeline-section {
background: var(--dark-brown);
color: var(--cream);
padding: 6rem 2rem;
overflow: hidden;
}
.timeline-section h2 {
text-align: center;
font-size: clamp(2rem, 4vw, 3rem);
margin-bottom: 0.5rem;
}
.timeline-section .section-sub {
text-align: center;
font-family: 'Dancing Script', cursive;
color: var(--sandy-gold);
font-size: 1.3rem;
margin-bottom: 3rem;
}
.timeline-scroll {
display: flex;
gap: 0;
overflow-x: auto;
padding: 2rem 0;
scroll-snap-type: x proximity;
-webkit-overflow-scrolling: touch;
scrollbar-width: thin;
scrollbar-color: var(--sandy-gold) transparent;
}
.timeline-scroll::-webkit-scrollbar { height: 6px; }
.timeline-scroll::-webkit-scrollbar-track { background: transparent; }
.timeline-scroll::-webkit-scrollbar-thumb { background: var(--sandy-gold); border-radius: 3px; }
.timeline-stop {
flex: 0 0 auto;
width: 180px;
text-align: center;
scroll-snap-align: center;
position: relative;
cursor: pointer;
transition: transform 0.3s;
}
.timeline-stop:hover { transform: translateY(-5px); }
.timeline-stop::after {
content: '';
position: absolute;
top: 28px;
left: 50%;
width: 100%;
height: 2px;
background: var(--sandy-gold);
opacity: 0.3;
}
.timeline-stop:last-child::after { display: none; }
.timeline-dot {
width: 14px;
height: 14px;
border-radius: 50%;
background: var(--sandy-gold);
margin: 0 auto 1rem;
position: relative;
z-index: 1;
box-shadow: 0 0 0 4px rgba(212,165,116,0.2);
transition: box-shadow 0.3s, transform 0.3s;
}
.timeline-stop:hover .timeline-dot {
box-shadow: 0 0 0 8px rgba(212,165,116,0.3);
transform: scale(1.3);
}
.timeline-stop img {
width: 90px;
height: 90px;
border-radius: 50%;
object-fit: cover;
border: 2px solid var(--sandy-gold);
margin-bottom: 0.7rem;
}
.timeline-stop .no-img {
width: 90px;
height: 90px;
border-radius: 50%;
margin: 0 auto 0.7rem;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
border: 2px solid var(--sandy-gold);
background: rgba(212,165,116,0.1);
}
.timeline-stop .country-name {
font-family: 'Playfair Display', serif;
font-size: 0.85rem;
font-weight: 700;
margin-bottom: 0.2rem;
}
.timeline-stop .dates {
font-size: 0.65rem;
opacity: 0.6;
letter-spacing: 1px;
text-transform: uppercase;
}
/* ============================================
CHAPTER SECTIONS
============================================ */
.chapter {
position: relative;
overflow: hidden;
}
.chapter-hero {
position: relative;
height: 70vh;
min-height: 450px;
display: flex;
align-items: flex-end;
overflow: hidden;
}
.chapter-hero-bg {
position: absolute;
inset: 0;
background-size: cover;
background-position: center;
transition: transform 0.1s linear;
}
.chapter-hero-overlay {
position: absolute;
inset: 0;
background: linear-gradient(
0deg,
rgba(44, 24, 16, 0.95) 0%,
rgba(44, 24, 16, 0.4) 40%,
rgba(44, 24, 16, 0.1) 100%
);
}
.chapter-hero-content {
position: relative;
z-index: 2;
padding: 3rem;
max-width: 900px;
color: var(--cream);
}
.chapter-number {
font-family: 'Dancing Script', cursive;
font-size: 1.1rem;
color: var(--sandy-gold);
letter-spacing: 3px;
margin-bottom: 0.3rem;
}
.chapter-title {
font-size: clamp(2.5rem, 5vw, 4rem);
font-weight: 900;
line-height: 1.1;
margin-bottom: 0.5rem;
text-shadow: 0 2px 20px rgba(0,0,0,0.5);
}
.chapter-tagline {
font-family: 'Dancing Script', cursive;
font-size: 1.4rem;
color: var(--sandy-gold);
opacity: 0.9;
}
/* Chapter Body */
.chapter-body {
max-width: 900px;
margin: 0 auto;
padding: 4rem 2rem;
}
.chapter-body .story-text {
font-size: 1.05rem;
line-height: 2;
color: #4a3828;
margin-bottom: 1.5rem;
text-align: justify;
}
.chapter-body .story-text:first-of-type::first-letter {
font-family: 'Playfair Display', serif;
font-size: 4rem;
float: left;
line-height: 1;
margin-right: 0.5rem;
margin-top: 0.1rem;
color: var(--saddle-brown);
font-weight: 700;
}
.chapter-body .story-date {
font-family: 'Playfair Display', serif;
font-weight: 700;
font-size: 1.1rem;
color: var(--saddle-brown);
margin: 2.5rem 0 1rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--sandy-gold);
display: inline-block;
}
/* Photo Gallery Grid within Chapter */
.chapter-gallery {
padding: 2rem;
max-width: 1400px;
margin: 0 auto;
}
.chapter-gallery h3 {
text-align: center;
font-size: 1.8rem;
margin-bottom: 0.3rem;
color: var(--saddle-brown);
}
.chapter-gallery .gallery-sub {
text-align: center;
font-family: 'Dancing Script', cursive;
color: var(--forest-green);
font-size: 1.1rem;
margin-bottom: 2rem;
}
.photo-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 1rem;
}
.photo-card {
position: relative;
border-radius: 8px;
overflow: hidden;
cursor: pointer;
aspect-ratio: 4/3;
background: #e0d6c8;
box-shadow: 0 2px 12px rgba(0,0,0,0.1);
transition: transform 0.4s ease, box-shadow 0.4s ease;
}
.photo-card:hover {
transform: translateY(-5px) scale(1.02);
box-shadow: 0 8px 30px rgba(0,0,0,0.2);
}
.photo-card img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.6s ease;
}
.photo-card:hover img { transform: scale(1.08); }
.photo-card .caption {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 2rem 1rem 0.8rem;
background: linear-gradient(transparent, rgba(44,24,16,0.85));
color: var(--cream);
font-size: 0.85rem;
font-weight: 600;
transform: translateY(100%);
transition: transform 0.4s ease;
}
.photo-card:hover .caption { transform: translateY(0); }
.photo-card .caption .country-tag {
font-size: 0.65rem;
color: var(--sandy-gold);
text-transform: uppercase;
letter-spacing: 2px;
display: block;
margin-bottom: 0.2rem;
}
/* Chapter separator */
.chapter-divider {
text-align: center;
padding: 3rem 0;
}
.chapter-divider .ornament {
color: var(--sandy-gold);
font-size: 1.5rem;
letter-spacing: 8px;
}
/* Gradient placeholder for chapters without images */
.chapter-hero.no-image .chapter-hero-bg {
background: linear-gradient(135deg, var(--forest-green), var(--dark-brown), var(--saddle-brown));
}
/* ============================================
FULL GALLERY SECTION
============================================ */
.gallery-section {
background: var(--dark-brown);
padding: 6rem 2rem;
}
.gallery-section h2 {
text-align: center;
color: var(--cream);
font-size: clamp(2rem, 4vw, 3rem);
margin-bottom: 0.3rem;
}
.gallery-section .section-sub {
text-align: center;
font-family: 'Dancing Script', cursive;
color: var(--sandy-gold);
font-size: 1.3rem;
margin-bottom: 2rem;
}
.filter-buttons {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0.5rem;
margin-bottom: 2.5rem;
padding: 0 1rem;
}
.filter-btn {
background: rgba(245, 240, 232, 0.08);
color: var(--cream);
border: 1px solid rgba(212,165,116,0.3);
padding: 0.5rem 1.2rem;
border-radius: 30px;
font-family: 'Open Sans', sans-serif;
font-size: 0.8rem;
font-weight: 600;
letter-spacing: 1px;
text-transform: uppercase;
cursor: pointer;
transition: all 0.3s ease;
}
.filter-btn:hover,
.filter-btn.active {
background: var(--sandy-gold);
color: var(--dark-brown);
border-color: var(--sandy-gold);
}
.masonry-grid {
max-width: 1400px;
margin: 0 auto;
columns: 4;
column-gap: 1rem;
}
@media (max-width: 1100px) { .masonry-grid { columns: 3; } }
@media (max-width: 768px) { .masonry-grid { columns: 2; } }
@media (max-width: 480px) { .masonry-grid { columns: 1; } }
.masonry-item {
break-inside: avoid;
margin-bottom: 1rem;
border-radius: 8px;
overflow: hidden;
position: relative;
cursor: pointer;
transition: transform 0.4s, opacity 0.5s;
}
.masonry-item.hidden {
display: none;
}
.masonry-item img {
width: 100%;
display: block;
transition: transform 0.5s;
}
.masonry-item:hover img { transform: scale(1.05); }
.masonry-item .m-caption {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 2.5rem 0.8rem 0.6rem;
background: linear-gradient(transparent, rgba(44,24,16,0.9));
color: var(--cream);
font-size: 0.8rem;
font-weight: 600;
opacity: 0;
transition: opacity 0.4s;
}
.masonry-item:hover .m-caption { opacity: 1; }
.masonry-item .m-caption .m-country {
font-size: 0.6rem;
color: var(--sandy-gold);
text-transform: uppercase;
letter-spacing: 2px;
}
/* ============================================
EPILOGUE
============================================ */
.epilogue {
text-align: center;
padding: 8rem 2rem;
background: linear-gradient(180deg, var(--cream) 0%, #e8dfd1 100%);
}
.epilogue h2 {
font-size: clamp(2rem, 4vw, 3rem);
font-style: italic;
color: var(--saddle-brown);
margin-bottom: 2rem;
}
.epilogue .closing-text {
max-width: 700px;
margin: 0 auto 2rem;
font-size: 1.1rem;
line-height: 2;
color: #5a4030;
}
.epilogue .journal-closing {
font-family: 'Dancing Script', cursive;
font-size: 1.8rem;
color: var(--forest-green);
margin: 2rem 0;
}
.epilogue .final-ornament {
color: var(--sandy-gold);
font-size: 1.5rem;
letter-spacing: 10px;
}
/* ============================================
LIGHTBOX
============================================ */
.lightbox {
display: none;
position: fixed;
inset: 0;
z-index: 9999;
background: rgba(0, 0, 0, 0.95);
align-items: center;
justify-content: center;
cursor: zoom-out;
}
.lightbox.active {
display: flex;
}
.lightbox img {
max-width: 92vw;
max-height: 90vh;
object-fit: contain;
border-radius: 4px;
box-shadow: 0 0 60px rgba(0,0,0,0.5);
}
.lightbox-caption {
position: absolute;
bottom: 1.5rem;
left: 50%;
transform: translateX(-50%);
color: var(--cream);
font-family: 'Playfair Display', serif;
font-size: 1.1rem;
text-align: center;
text-shadow: 0 2px 10px rgba(0,0,0,0.8);
max-width: 80%;
}
.lightbox-close {
position: absolute;
top: 1.5rem;
right: 2rem;
color: var(--cream);
font-size: 2.5rem;
cursor: pointer;
background: none;
border: none;
opacity: 0.7;
transition: opacity 0.3s;
z-index: 10000;
}
.lightbox-close:hover { opacity: 1; }
.lightbox-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
color: var(--cream);
font-size: 3rem;
cursor: pointer;
background: none;
border: none;
opacity: 0.5;
transition: opacity 0.3s;
padding: 1rem;
z-index: 10000;
}
.lightbox-nav:hover { opacity: 1; }
.lightbox-prev { left: 1rem; }
.lightbox-next { right: 1rem; }
/* ============================================
FOOTER
============================================ */
footer {
background: var(--dark-brown);
color: rgba(245,240,232,0.5);
text-align: center;
padding: 2rem;
font-size: 0.8rem;
}
footer a { color: var(--sandy-gold); text-decoration: none; }
/* ============================================
UTILITY
============================================ */
.text-center { text-align: center; }
.mt-2 { margin-top: 2rem; }
/* Smooth section transitions */
.section-transition {
height: 100px;
background: linear-gradient(180deg, var(--cream) 0%, var(--dark-brown) 100%);
}
.section-transition-reverse {
height: 100px;
background: linear-gradient(180deg, var(--dark-brown) 0%, var(--cream) 100%);
}
/* Chapter alternating backgrounds */
.chapter:nth-child(even) .chapter-body {
background: rgba(74, 103, 65, 0.03);
}
/* Story read more toggle */
.story-expandable {
max-height: 600px;
overflow: hidden;
position: relative;
transition: max-height 0.8s ease;
}
.story-expandable.expanded {
max-height: none;
}
.story-expandable::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 120px;
background: linear-gradient(transparent, var(--cream));
pointer-events: none;
transition: opacity 0.5s;
}
.story-expandable.expanded::after {
opacity: 0;
}
.chapter:nth-child(even) .story-expandable::after {
background: linear-gradient(transparent, #f7f3ec);
}
.read-more-btn {
display: block;
margin: 1rem auto 0;
background: none;
border: 2px solid var(--saddle-brown);
color: var(--saddle-brown);
padding: 0.6rem 2rem;
font-family: 'Open Sans', sans-serif;
font-size: 0.85rem;
font-weight: 600;
letter-spacing: 1.5px;
text-transform: uppercase;
cursor: pointer;
border-radius: 30px;
transition: all 0.3s;
}
.read-more-btn:hover {
background: var(--saddle-brown);
color: var(--cream);
}
/* Stats bar */
.stats-bar {
display: flex;
justify-content: center;
gap: 4rem;
flex-wrap: wrap;
padding: 3rem 2rem;
background: var(--dark-brown);
color: var(--cream);
}
.stat-item {
text-align: center;
}
.stat-number {
font-family: 'Playfair Display', serif;
font-size: 3rem;
font-weight: 900;
color: var(--sandy-gold);
display: block;
}
.stat-label {
font-size: 0.75rem;
letter-spacing: 2px;
text-transform: uppercase;
opacity: 0.7;
}
</style>
</head>
<body>
<!-- ====== NAVIGATION ====== -->
<nav class="site-nav" id="siteNav">
<a href="#hero" class="nav-logo">WorldWander</a>
<button class="mobile-menu-btn" id="mobileMenuBtn" aria-label="Menu">&#9776;</button>
<ul class="nav-links" id="navLinks">
<li><a href="#prologue">The Story</a></li>
<li><a href="#journey">Journey</a></li>
<li><a href="#ch-argentina">Chapters</a></li>
<li><a href="#gallery">Gallery</a></li>
<li><a href="#epilogue">Epilogue</a></li>
</ul>
</nav>
<!-- ====== HERO ====== -->
<section class="hero" id="hero">
<div class="hero-bg" id="heroBg"></div>
<div class="hero-overlay"></div>
<div class="hero-content">
<div class="year-badge">February 1998 &mdash; February 1999</div>
<h1>WorldWander</h1>
<p class="subtitle">365 days. 40 countries. One story.</p>
</div>
<div class="scroll-indicator" onclick="document.getElementById('prologue').scrollIntoView({behavior:'smooth'})">
<span>Begin the journey</span>
<div class="arrow">&#8595;</div>
</div>
</section>
<!-- ====== PROLOGUE ====== -->
<section class="prologue" id="prologue">
<div class="journal-ornament reveal">&#10047; &bull; &#10047;</div>
<h2 class="reveal">The Origin Story</h2>
<div class="separator reveal"></div>
<p class="origin-text reveal">In 2000, Karen and I took a year off to travel the world and built the original WorldWander website. One day I checked the access logs and was surprised to see the amount of traffic we still get. These pages hold the stories we wrote along the way &mdash; dispatches from bus stations at 4 AM, journal entries scribbled in candlelit restaurants, and reflections penned beneath unfamiliar constellations.</p>
<p class="origin-text reveal">What started as a sabbatical became the defining adventure of our lives. We packed two backpacks, sold the car, quit our jobs, and stepped onto a plane bound for Venezuela. The plan was loose: head south through South America, cross to Asia, wind through the Middle East, and finish in Europe. The reality was infinitely more unpredictable, more beautiful, and more transformative than anything we could have planned.</p>
<div class="journal-quote reveal">"The travel books all state what the price should be from the airport to a particular destination. But sometimes it is a lot more efficient to see for yourself."</div>
<p class="origin-text reveal">What follows is the full, unabridged story of that year &mdash; every missed bus, every jaw-dropping vista, every $2 meal that tasted better than anything back home. Scroll on, and come along for the ride.</p>
</section>
<!-- ====== STATS BAR ====== -->
<div class="stats-bar">
<div class="stat-item reveal"><span class="stat-number">365</span><span class="stat-label">Days</span></div>
<div class="stat-item reveal"><span class="stat-number">40+</span><span class="stat-label">Countries</span></div>
<div class="stat-item reveal"><span class="stat-number">6</span><span class="stat-label">Continents</span></div>
<div class="stat-item reveal"><span class="stat-number">1</span><span class="stat-label">Proposal</span></div>
</div>
<!-- ====== JOURNEY TIMELINE ====== -->
<section class="timeline-section" id="journey">
<h2 class="reveal">The Road Behind</h2>
<p class="section-sub reveal">Scroll to trace our path around the world</p>
<div class="timeline-scroll" id="timelineScroll">
<!-- Generated by JS -->
</div>
</section>
<div class="section-transition-reverse"></div>
<!-- ====== CHAPTERS ====== -->
<div id="chapters-container">
<!-- Chapters are generated by JavaScript -->
</div>
<!-- ====== FULL GALLERY ====== -->
<div class="section-transition"></div>
<section class="gallery-section" id="gallery">
<h2 class="reveal">The Complete Collection</h2>
<p class="section-sub reveal">117 photographs from around the world</p>
<div class="filter-buttons" id="filterButtons">
<!-- Generated by JS -->
</div>
<div class="masonry-grid" id="masonryGrid">
<!-- Generated by JS -->
</div>
</section>
<!-- ====== EPILOGUE ====== -->
<div class="section-transition-reverse"></div>
<section class="epilogue" id="epilogue">
<div class="reveal">
<h2>The Journey Continues...</h2>
<div style="width:60px;height:2px;background:var(--sandy-gold);margin:2rem auto;"></div>
<p class="closing-text">A year of travel changed everything. We learned that the world is simultaneously smaller and grander than we ever imagined. That a bus station at 5 AM in Paraguay can teach you more about patience than any meditation retreat. That the best meals come from strangers who insist you sit down. That love, tested by 365 days of constant togetherness, only grows stronger.</p>
<p class="closing-text">Karen said yes to my proposal at the base of a waterfall in Venezuela. She said yes to every crazy bus ride, every questionable hotel room, every "let's just see what happens" detour. And the world said yes back to us &mdash; with Iguazu Falls at sunrise, Angel Falls through clearing clouds, the mosaics of Hagia Sophia catching afternoon light, and a mokoro gliding silently through the Okavango Delta.</p>
<p class="journal-closing">"We came away wanting to hold each other's hand a little more often and a little bit longer."</p>
<div class="final-ornament">&#10047; &bull; &#10047; &bull; &#10047;</div>
</div>
</section>
<!-- ====== FOOTER ====== -->
<footer>
<p>&copy; WorldWander 1998&ndash;2026 &bull; Karen &amp; Scooter &bull; <a href="#hero">Back to top</a></p>
</footer>
<!-- ====== LIGHTBOX ====== -->
<div class="lightbox" id="lightbox">
<button class="lightbox-close" id="lightboxClose">&times;</button>
<button class="lightbox-nav lightbox-prev" id="lightboxPrev">&#10094;</button>
<button class="lightbox-nav lightbox-next" id="lightboxNext">&#10095;</button>
<img id="lightboxImg" src="" alt="">
<div class="lightbox-caption" id="lightboxCaption"></div>
</div>
<script>
/* ============================================================
DATA: All images and their captions
============================================================ */
const IMAGE_CAPTIONS = {
// Argentina
'argentina_arfall.jpg': 'Iguazu Falls',
'argentina_arfall1.jpg': 'Iguazu Falls, Cascades',
'argentina_barboat.jpg': 'Boat on Lake Nahuel Huapi, Bariloche',
'argentina_barchurch.jpg': 'Alpine Church, Bariloche',
'argentina_barlake.jpg': 'Lake District, Bariloche',
'argentina_bird1.jpg': 'Tropical Bird, Parque Aves',
'argentina_brazil_iguazu.jpg': 'Iguazu Falls from Brazil Side',
'argentina_buenes.jpg': 'Buenos Aires Street Scene',
'argentina_buenos_aires.jpg': 'Downtown Buenos Aires',
'argentina_dogwalk.jpg': 'Dog Walker, Buenos Aires',
'argentina_falls_walkway.jpg': 'Walkway Over the Falls',
'argentina_government.jpg': 'Casa Rosada, Government House',
'argentina_iguazu_falls.jpg': 'Devil\'s Throat, Iguazu',
'argentina_macaw.jpg': 'Scarlet Macaw, Bird Park',
'argentina_park.jpg': 'Recoleta Park, Buenos Aires',
'argentina_tango.jpg': 'Tango Dancers, La Boca',
'argentina_tango1.jpg': 'Street Tango Performance',
'argentina_telecom.jpg': 'Telecom Building, Buenos Aires',
'argentina_toucan.jpg': 'Toucan, Parque Aves',
'argentina_yestreaklaur.jpg': 'Street Art, Buenos Aires',
// Bolivia
'bolivia_catamaran.jpg': 'Catamaran on Lake Titicaca',
'bolivia_copacabana.jpg': 'Copacabana Village',
'bolivia_lapaz.jpg': 'La Paz City Panorama',
'bolivia_sailing.jpg': 'Sailing Lake Titicaca',
'bolivia_sun_island.jpg': 'Isla del Sol, Lake Titicaca',
'bolivia_sunisland.jpg': 'Sun Island Ruins',
// Chile
'chile_andes.jpg': 'The Andes Mountains',
'chile_camp.jpg': 'Lakeside Campsite',
'chile_cattle.jpg': 'Cattle Ranch, Chilean Countryside',
'chile_fish_market.jpg': 'Puerto Montt Fish Market',
'chile_flame.jpg': 'Campfire Under the Stars',
// Venezuela
'venezuela_angel_falls.jpg': 'Angel Falls, World\'s Tallest Waterfall',
'venezuela_arameru.jpg': 'Ara-meru Falls, Canaima',
'venezuela_falls_boat.jpg': 'River Boat to Angel Falls',
'venezuela_tepui.jpg': 'Tepui Mesa, Gran Sabana',
'venezuela_two_falls.jpg': 'Sapo and Sapito Falls',
'venezuela_wuytepui.jpg': 'Auyan Tepui at Sunrise',
// Egypt
'egypt_abusimbel.jpg': 'Abu Simbel Temple',
'egypt_abusimbel1.jpg': 'Ramses at Abu Simbel',
'egypt_alexandria.jpg': 'Fort Qaytbay, Alexandria',
'egypt_aswanfeluka.jpg': 'Felucca on the Nile, Aswan',
'egypt_caironile.jpg': 'Cairo Along the Nile',
'egypt_camelpyramid.jpg': 'Camel Ride at the Pyramids',
'egypt_edfu_temple.jpg': 'Temple of Horus, Edfu',
'egypt_pyramid.jpg': 'The Great Pyramids of Giza',
'egypt_sinai.jpg': 'Sunrise from Mount Sinai',
// Jordan
'jordan_deadsea.jpg': 'Floating in the Dead Sea',
'jordan_jerash.jpg': 'Roman Ruins of Jerash',
'jordan_mosaic.jpg': 'Ancient Mosaic, Mount Nebo',
'jordan_mountnebo.jpg': 'View from Mount Nebo',
'jordan_petra_columns.jpg': 'Colonnade Street, Petra',
'jordan_petra_inside.jpg': 'Inside a Nabatean Tomb, Petra',
'jordan_petra_main.jpg': 'The Siq Gorge, Petra',
'jordan_petra_treasury.jpg': 'The Treasury at Petra',
// Turkey
'turkey_bluemosque_dome.jpg': 'Blue Mosque Interior Dome',
'turkey_bodrum.jpg': 'Bodrum Harbor at Sunset',
'turkey_cappadocia_valley.jpg': 'Fairy Chimneys, Cappadocia',
'turkey_cappadocia.jpg': 'Cave Dwellings, Cappadocia',
'turkey_cavehotel.jpg': 'Cave Hotel Room, Cappadocia',
'turkey_chora_mosaic.jpg': 'Byzantine Mosaic, Chora Church',
'turkey_ephesus_library.jpg': 'Library of Celsus, Ephesus',
'turkey_underground_city.jpg': 'Underground City, Cappadocia',
// Greece
'greece_beachdog.jpg': 'Beach Dog, Greek Islands',
'greece_beachsleep.jpg': 'Afternoon Siesta, Beach',
'greece_campbags_small.jpg': 'Backpacks Ready to Go',
'greece_campbags.jpg': 'Packed and Ready, Greece',
'greece_campers_small.jpg': 'Fellow Travelers',
'greece_campers.jpg': 'Camping Crew, Greece',
'greece_colossus_color.jpg': 'Colossus of Rhodes Site',
'greece_coriethon.jpg': 'Corinth Canal',
// Spain
'spain_alhambra.jpg': 'The Alhambra, Granada',
'spain_barcelona.jpg': 'Sagrada Familia, Barcelona',
'spain_elescorial.jpg': 'El Escorial Palace, Madrid',
'spain_flamenco.jpg': 'Flamenco Dancer, Seville',
'spain_madrid_palace.jpg': 'Royal Palace, Madrid',
'spain_ronda_bridge.jpg': 'Puente Nuevo Bridge, Ronda',
'spain_segovia_aqueduct.jpg': 'Roman Aqueduct, Segovia',
'spain_seville.jpg': 'Seville Cathedral',
// South Africa
'southafrica_baboons.jpg': 'Baboons, Cape Point',
'southafrica_capepoint.jpg': 'Cape of Good Hope',
'southafrica_capesunset.jpg': 'Sunset at Cape Town',
'southafrica_capetown.jpg': 'Table Mountain, Cape Town',
'southafrica_elephant.jpg': 'Elephant on Safari',
'southafrica_giraffe.jpg': 'Giraffe, Kruger Park',
'southafrica_penguins.jpg': 'Jackass Penguins, Boulders Beach',
// Botswana
'botswana_delta_camp.jpg': 'Camp in the Okavango Delta',
'botswana_Deltacamp.jpg': 'Delta Bush Camp',
'botswana_Deltatruck.jpg': 'All-Terrain Transport to Delta',
'botswana_Elebullwatch.jpg': 'Bull Elephant Watching',
'botswana_Elecharge.jpg': 'Elephant Charge!',
'botswana_elephant_charge.jpg': 'Charging Elephant, Okavango',
'botswana_elephant_fire.jpg': 'Elephant and Brush Fire',
'botswana_Elerun.jpg': 'Elephants on the Move',
'botswana_Elestop.jpg': 'Elephant at Water\'s Edge',
'botswana_hippo.jpg': 'Hippo in the Delta',
'botswana_Hippobutt.jpg': 'Hippo Emerging from Water',
'botswana_Inatree.jpg': 'View from a Tree, Delta',
'botswana_Lostshoes.jpg': 'Lost Shoes After Elephant Chase',
'botswana_Ltksboat.jpg': 'Boat on the Delta Waters',
'botswana_mokoro_ride.jpg': 'Mokoro Canoe Ride',
'botswana_Mokorosride.jpg': 'Gliding Through the Reeds',
'botswana_Motorospole.jpg': 'Mokoro Poler at Work',
'botswana_nata_camp.jpg': 'Campsite at Nata',
'botswana_Natacamp.jpg': 'Nata Campground',
'botswana_Okatracking.jpg': 'Tracking Wildlife, Okavango',
'botswana_Shoesrecovered.jpg': 'Shoes Recovered!',
'botswana_tornado.jpg': 'Dust Devil on the Plains',
'botswana_tracking.jpg': 'Guided Bush Walk',
// Cambodia
'cambodia_angkor_wat.jpg': 'Angkor Wat at Dawn',
'cambodia_angkor3.jpg': 'Angkor Temple Corridor',
'cambodia_buddha.jpg': 'Buddha Statue, Angkor',
'cambodia_scene.jpg': 'Cambodian Village Life',
'cambodia_wat.jpg': 'Temple Spires, Angkor',
// Curacao
'curacao_bridge.jpg': 'Queen Emma Pontoon Bridge',
'curacao_cruise.jpg': 'Cruise Ships in Willemstad',
'curacao_market.jpg': 'Floating Market, Curacao',
'curacao_proof.jpg': 'Proof We Were Here!'
};
/* Country metadata for ordering chapters */
const COUNTRIES = {
venezuela: { name: 'Venezuela', tagline: 'Angel Falls & a Proposal', dates: 'February 1998', emoji: '\u{1F1FB}\u{1F1EA}', gradient: '' },
curacao: { name: 'Curacao', tagline: 'Solar Eclipse in the Dutch Antilles', dates: 'February 1998', emoji: '\u{1F1E8}\u{1F1FC}', gradient: '' },
argentina: { name: 'Argentina', tagline: 'Iguazu Falls, Buenos Aires & Tango', dates: 'March 1998', emoji: '\u{1F1E6}\u{1F1F7}', gradient: '' },
bolivia: { name: 'Bolivia', tagline: 'La Paz & Lake Titicaca', dates: 'March 1998', emoji: '\u{1F1E7}\u{1F1F4}', gradient: '' },
chile: { name: 'Chile', tagline: 'The Andes, Lakes & the Pan-American Highway', dates: 'March 1998', emoji: '\u{1F1E8}\u{1F1F1}', gradient: '' },
ecuador: { name: 'Ecuador & Galapagos', tagline: 'Taco Bell, the Equator & Darwin\'s Islands', dates: 'March 1998', emoji: '\u{1F1EA}\u{1F1E8}', gradient: 'linear-gradient(135deg, #2d5a3d, #1a3a4a, #4a6741)' },
egypt: { name: 'Egypt', tagline: 'Pyramids, the Nile & Abu Simbel', dates: 'December 1998', emoji: '\u{1F1EA}\u{1F1EC}', gradient: '' },
jordan: { name: 'Jordan', tagline: 'Petra, the Dead Sea & Ramadan', dates: 'December 1998', emoji: '\u{1F1EF}\u{1F1F4}', gradient: '' },
turkey: { name: 'Turkey', tagline: 'Istanbul, Ephesus & Cappadocia', dates: 'July 1998', emoji: '\u{1F1F9}\u{1F1F7}', gradient: '' },
greece: { name: 'Greece', tagline: 'Athens, the Islands & the Acropolis', dates: 'July 1998', emoji: '\u{1F1EC}\u{1F1F7}', gradient: '' },
spain: { name: 'Spain', tagline: 'Barcelona, Granada, Seville & Ronda', dates: 'October 1998', emoji: '\u{1F1EA}\u{1F1F8}', gradient: '' },
southafrica: { name: 'South Africa', tagline: 'Cape Town, Safari & Garden Route', dates: 'August 1998', emoji: '\u{1F1FF}\u{1F1E6}', gradient: '' },
botswana: { name: 'Botswana', tagline: 'Okavango Delta by Mokoro', dates: 'September 1998', emoji: '\u{1F1E7}\u{1F1FC}', gradient: '' },
cambodia: { name: 'Cambodia', tagline: 'Angkor Wat & the Killing Fields', dates: 'May 1998', emoji: '\u{1F1F0}\u{1F1ED}', gradient: '' },
nepal: { name: 'Nepal', tagline: 'Kathmandu & Himalayan Trekking', dates: 'June 1998', emoji: '\u{1F1F3}\u{1F1F5}', gradient: 'linear-gradient(135deg, #3d4a5a, #5a6741, #2C1810)' },
india: { name: 'India', tagline: 'Delhi, the Taj & Bangalore', dates: 'June 1998', emoji: '\u{1F1EE}\u{1F1F3}', gradient: 'linear-gradient(135deg, #8B4513, #D4A574, #4A6741)' },
thailand: { name: 'Thailand', tagline: 'Bangkok, Chiang Mai & the Islands', dates: 'May 1998', emoji: '\u{1F1F9}\u{1F1ED}', gradient: 'linear-gradient(135deg, #4A6741, #D4A574, #2C1810)' },
singapore: { name: 'Singapore', tagline: 'The Immaculate City-State', dates: 'May 1998', emoji: '\u{1F1F8}\u{1F1EC}', gradient: 'linear-gradient(135deg, #2C1810, #4A6741, #8B4513)' }
};
/* Chapter order */
const CHAPTER_ORDER = [
'venezuela', 'curacao', 'argentina', 'bolivia', 'chile', 'ecuador',
'cambodia', 'nepal', 'india', 'thailand', 'singapore',
'greece', 'turkey', 'egypt', 'jordan',
'spain', 'southafrica', 'botswana'
];
/* Hero images for each chapter */
const CHAPTER_HEROES = {
venezuela: 'venezuela_angel_falls.jpg',
curacao: 'curacao_bridge.jpg',
argentina: 'argentina_iguazu_falls.jpg',
bolivia: 'bolivia_lapaz.jpg',
chile: 'chile_andes.jpg',
egypt: 'egypt_camelpyramid.jpg',
jordan: 'jordan_petra_treasury.jpg',
turkey: 'turkey_ephesus_library.jpg',
greece: 'greece_colossus_color.jpg',
spain: 'spain_alhambra.jpg',
southafrica: 'southafrica_capetown.jpg',
botswana: 'botswana_mokoro_ride.jpg',
cambodia: 'cambodia_angkor_wat.jpg'
};
/* Story text excerpts for each chapter */
const CHAPTER_STORIES = {
venezuela: `<p class="story-text">We arrived into the international Caracas Airport at 2:00 PM. Customs was very easy and our bags came up as we walked up to the baggage claim area. We exchanged $200 US and used the Tourist Information counter to make a hotel reservation. The people working the Tourist counter did not speak English so communicating was by trial and error.</p>
<p class="story-text">We are going to Canaima National Park, the sixth largest in the world, tomorrow so we set out to sign up for our tour package. We loaded up supplies and set out for Angel Falls via the Rio Carrao river, not sure if we would make it. The river was very low but our guides Jose and Jeime are masters at their work. The boat is carved out of a single tree and is over thirty feet long and powered by a Yamaha 48hp outboard motor. One guide sits on the front of the boat with a very large paddle for steering and signals to the other guide the location of oncoming rocks.</p>
<p class="story-date">Tuesday, February 17, 1998</p>
<p class="story-text">It rained throughout the night and when we got up the next morning it was very cloudy and we could not see Angel Falls because of all the clouds. Marlon, Karen and I set out on our 30 minute hike to the falls, hoping it would clear. When we reached our first vantage point the sun came out and the clouds opened and before us stood Angel Falls. Marlon could not believe our luck and asked us if we are usually this lucky and I told him that we have been very lucky in the past.</p>
<p class="story-text">The Tepuis on the way to Angel Falls are without compare to anything we have seen. Angel Falls is located at the top of a Tepuy and the water falls 980 meters or 3,280 feet which makes it the tallest waterfall in the world.</p>
<p class="story-text">For those of you reading this closely, I proposed to Karen in front of Hacha Falls on Sunday, February 15th, in what I thought at the time was the prettiest and most romantic spot on earth. Karen was surprised to hear those words come out of my mouth and she was quick to respond with a very happy YES. Our future looks very bright together filled with happiness, love and a little bit of luck thrown in when you least expect it.</p>`,
curacao: `<p class="story-text">Curacao is a Dutch Island in the Netherland Antilles and is the hub for all of ALM Airlines. We had an overnight layover scheduled and found out the island was in the 100% zone for a solar eclipse. This is a big event and people were visiting from all over the world. Some cruise packages had been booked for a couple of years! We just got lucky and asked to delay our flight by one more day.</p>
<p class="story-text">The best place to observe the eclipse was on the west side of the island called Westpoint. At this location the full eclipse would last 10 seconds longer, so of course we were going there and by city bus. Our quest for the real groupies took us on a hike through desert and a steep climb to the highest point at Westpunt. Once the 100% status is reached, there is hooting and hollering from the crowd. It is an awesome sight &mdash; suddenly cold, dark, and you could see two planets in the sky. Three minutes and twenty-three seconds later, it is over. It is impossible for video or cameras to capture the beauty and mystique of the ring of diamonds. You have to be there to understand.</p>`,
argentina: `<p class="story-text">The area of Iguazu falls is bordered by Argentina, Brazil and Paraguay which provides for some interesting multiple country visits in a single day. The International Bus Terminal in Ciudad Del Este, Paraguay is not something to put on your list of places to visit especially at 4:30 AM because that is when we arrived from Asuncion, Paraguay.</p>
<p class="story-date">March 18</p>
<p class="story-text">The travel books all recommended going to the Brazil side first to take in the true magnificence of the falls. Karen and I walked up and could not believe the size and magnitude of the falls. It was truly impressive. Every corner and observation point yielded an even larger view of the falls. The end of the walkway takes you into the middle of the river and at the edge of a large horseshoe shaped fall.</p>
<p class="story-text">The Argentinean side of the falls is definitely setup for tourists. They have put a lot of effort into building very nice walkways over the various waterfalls and down to the river's edge. It is a surreal feeling to stand a foot above the drop off point of a roaring waterfall. I don't think Disney could have built a nicer waterfall for tourists to enjoy.</p>
<p class="story-date">March 20 &mdash; Buenos Aires</p>
<p class="story-text">Argentina is a large country but over 80 percent of the population lives in Buenos Aires. Buenos Aires had prospered in the early 1900's as a port town and a major beef and agriculture exporter to Europe. The waterway in Puerto Moreno consisted of at least four miles of beautifully restored four story brick buildings. Each building in its day had been part of a large warehouse district. Now they served as the home to hundreds of restaurants, businesses and apartments.</p>
<p class="story-text">We then asked the cab driver to take us to the Tango district. The Tango district is known for the brightly colored buildings and all kinds of street vendors and locals dancing the Tango for a few extra bucks. The Argentina men developed the very complicated dance called the Tango, with lots of body parts touching and fancy footwork. I came away from Argentina wanting to hold Karen's hand a little more often and a little bit longer.</p>
<p class="story-date">March 23 &mdash; Bariloche</p>
<p class="story-text">Bariloche is an Alpine Ski town both tourist and business oriented. It is very quaint and situated on a large lake surrounded by mountains. The town is famous for its chocolate stores and every chocolate kitchen you walked by almost knocked you out from the overwhelming smell of fresh chocolate.</p>`,
bolivia: `<p class="story-text">The catamaran was modern and looked like a living room inside with lounge chairs and windows. A guide filled us in on the details of Lake Titicaca &mdash; the world's 11th largest, world's highest navigable, very deep, trout fishing, Inca ruins, etc. were the highlights. Basically, once you have seen 10 minutes of the lake you have experienced the next 5 hours of the cruise.</p>
<p class="story-text">La Paz is a very high city, 12,000 feet, and is home to many of the world's highest records. The city itself is in a large hole surrounded by hills and is quite striking. It is also safe to walk around the city day or night. Once again, we were arriving to a town with no lodging preferences so we followed another couple to the Gloria Hotel in downtown La Paz.</p>
<p class="story-text">We seem to have to learn our travel lessons repeatedly: secure a taxi price before getting in the car, look at the hotel room before paying for it, do not believe everything your guidebook tells you, and make sure you know the price of your phone calls.</p>`,
chile: `<p class="story-text">After one relaxing day in Bariloche, Argentina we are on the road, or rather on the bus to Osorno, Chile. The drive through the Lake Region of Argentina and over the mountains is beautiful even if we are sitting next to the bus toilet. The livelihood of Chile is its fruit and vegetable exports, so they take very seriously any little bugs entering their country.</p>
<p class="story-text">Karen was determined not to give our business to the siesta-minded Budget but we discovered that they had the best price in town. Five minutes later Karen and I had freedom for the first time in a month. We could go anywhere and do anything at our own leisure.</p>
<p class="story-text">We set out for Fruitillar, Chile only 45 minutes south and located on a beautiful lake with a snow-covered volcano in the background. The campground had thirty spots surrounded by huge trees. Each camp site was bordered by nicely trimmed hedges and rose bushes in full bloom. Sitting in the back corner of each little piece of paradise was a fire pit, running water and a covered picnic table with electricity. Things had finally started to click in Chile.</p>
<p class="story-text">The city of Puerto Montt is the end of the Pan American highway. We navigated our way to the fish market and began a very interesting tour. This was the oddest fish market I had ever been to &mdash; Abalone, Sea Cucumbers, Giant Barnacles and some sort of fish/eel looking thing everywhere you looked.</p>`,
ecuador: `<p class="story-text">After seeing an amazing 100% Solar Eclipse we are on our way to Quito, Ecuador and the Galapagos. Our flight took us through Caracas, an unplanned stop in Bogota, Colombia &mdash; where we accidentally ended up on the streets without going through customs &mdash; and finally to Quito.</p>
<p class="story-text">The Galapagos Islands are located on the Equator, 970 kilometers off Ecuador. There are six larger islands and 12 small islands. Our flight was into Baltra, where we met Jorge our guide, and the rest of our travel companions. There were 16 of us, mostly between the ages of 25 and 40, from Switzerland, Germany, Australia, Japan, Norway, Canada, Denmark, England and us.</p>
<p class="story-text">We had not done it yet for a year: here before my very eyes appeared a mirage. We could not believe it, the last thing we thought we would see for a year &mdash; yes they have TACO BELL in Ecuador. Karen and I are both addicted to Taco Bell and eat it at home at least twice a week. Dinner was great and it lifted our spirits.</p>`,
egypt: `<p class="story-text">From a world wonder standpoint our decision to include Egypt on our travels was an easy one. Arriving via Martin Air from Paris to Cairo with nowhere to stay past midnight. No problem, we've done this before. There are five world wonders here: Pyramids at Giza, Lighthouse in Alexandria, Suez Canal, High Dam in Aswan and Abu Simbel.</p>
<p class="story-text">The road to the pyramids was built in the 1860's. The ancient Greeks considered the Great Pyramids to be one of the original seven wonders of the world. Looking down the road and seeing the Great Pyramids of Giza on the horizon is surreal, you just can't quite believe that the image you have seen so many times is real. Our taxi driver felt we should see the Pyramids at sunset by camel. The pyramids were incredible especially by camel back.</p>
<p class="story-text">Let's talk world wonders. Abu Simbel could have made the list twice &mdash; once for when it was first constructed into a mountainside and again for the moving and reconstruction. Huge stone figures of Ramses sitting on the banks of Lake Nasser. The High Dam, completed in 1971, has 12 turbines that create all of Egypt's electrical power. The Dam also created the world's largest artificial lake, Lake Nasser.</p>
<p class="story-text">The views along the Nile are incredible surreal vistas of deep blue water, rich green crops mixed with the varied colors of the desert cliffs and sands. Karnak Temple is the granddaddy of temples, the biggest and most impressive temple in Egypt. The site was constantly embellished over 1,500 years.</p>`,
jordan: `<p class="story-text">Jordan is a kingdom ruled by the much-loved and respected King Hussein and Queen Noor. It is a predominantly Muslim country, although many religions mix and mingle. Conveniently, English is the second language making it easy to converse with the locals.</p>
<p class="story-text">Currently, we're in the town of Wadi Musa, 5 km from today's destination, Petra, a formerly lost city. 8th century BC Edomites started this ancient town on the trade route, then taken over in the 6th century BC by the Nabateans who carved temples and monuments out of the cliffs. It was home to 20-30,000 people. You may think you have seen it before, because it was featured as the lost city in the movie Indiana Jones and the Last Crusade.</p>
<p class="story-text">One of the most spectacular views is right at the start. A 1.5 km walk through a narrow gorge with a magnificently carved mausoleum at the end made out of rose-colored sandstone. As the Brits would say, "brilliant." The rest of the day took us to the 7,000 seat Roman theater, many huge tombs, and up to the Ad-Deir, the monastery.</p>
<p class="story-text">Leaving the city of Amman, we continued North to Jerash, one of the most extensive Roman cities still in existence. The triumphal arch, hippodrome, oval plaza, 4,000 seat south theater, temple of Zeus &mdash; this city is impressive. It is said that 90% of Jerash is still not excavated.</p>`,
turkey: `<p class="story-text">When you say the word "Turkey" what pops into your mind? For the typical American the response would most definitely be Thanksgiving. Turkey is actually located on both the European and Asian continents and has been the center of religion and politics for thousands of years. After our visit to Turkey I realized that stereotypes and too little knowledge can be a really bad thing.</p>
<p class="story-text">The ancient city of Ephesus was a major trade port to the Far East. What remains today are probably the best-preserved ruins of the ancient world. One of the most interesting features was running water delivered by an underground plumbing system. The Library of Celsus, located in the main square, is the most completely restored structure at Ephesus &mdash; a complete two-story facade with statues and the classic Roman look.</p>
<p class="story-text">The city of Istanbul, once known as Constantinople, has survived as the capital of three major empires: Roman, Byzantine and Ottoman. Istanbul bridges Asia and Europe. The Hagia Sophia Church is one of the most magnificent buildings ever constructed, both central church to Christianity and the major inspiration for mosques of Islam. Across a large park is the Blue Mosque, the highlight of the Islamic religion in Istanbul.</p>
<p class="story-text">The Grand Bazaar consists of 65 streets jammed with 4,000 shops making it the largest mall in the world. It has lots of atmosphere with crowded arched passageways and smiling vendors that know every line in the book.</p>`,
greece: `<p class="story-text">Our departure from India could not come soon enough. We had just spent a long and challenging five months traveling through South America and Asia. We were ready for the comforts of Europe. Arriving in Athens was chaotic but we found the Hotel Astor with a view of the Acropolis.</p>
<p class="story-text">The Acropolis is an incredible sight sitting on a high plateau surrounded by the modern city of Athens. There are several monuments on the Acropolis: Propylaia, Temple of Athena Nike, the Erechtheion, Porch of the Maidens and of course the Parthenon. Just below the Parthenon is the Theater of Dionysus, where Sophocles, Aristophanes, and Euripides first presented their immortal works.</p>
<p class="story-text">Our cruise ship schedule took us through the stunning Greek islands: Delos and Mykonos, Santorini, Heraklion in Crete, and Rhodes. It was refreshing to have the international flavor of our fellow travelers &mdash; everyone eager to meet, swap stories and gather travel advice.</p>
<p class="story-text">We had lunch in the small square at the center of town. We dined on fresh bread, Tzatziki, Greek salad, watermelon and sipped retsina in an open air cafe. My idea of a perfect afternoon and at that moment, life was good.</p>`,
spain: `<p class="story-text">We have become increasingly casual about our travel plans. I think the Eurail Pass has given us a new, higher level of flexibility. From Avignon, France we jumped on the first train going to Barcelona. It was Saturday night at 10:30, perfect timing for Spain's late nights. We walked the waterfront to Ramblas, the main drag, with incredible crowds of people strolling up this huge boulevard.</p>
<p class="story-text">Coming out of the Sagrada Familia subway station is shocking, seeing this fantasy church looming over you. The designer, Antoni Gaudi, worked on this creation for 40 years. It is like no other building in the world. If Salvador Dali had to design a church, it would look like Sagrada Familia.</p>
<p class="story-text">Granada's Alhambra was spectacular, and Ronda's Parador had the perfect location on the edge of the cliff with beautiful rooms and a balcony overlooking the gorge. Paradors are Spain's government-sponsored inns, most often in renovated castles, palaces or monasteries.</p>
<p class="story-text">Unlike at home, all ages of people were mixing and mingling in Spain. The older generation are not at home after eating the "early bird special." You could see grandparents and grandkids dancing in the street and it was after midnight. We had to work on getting onto Spanish time ASAP because at 1 AM we were tired just when everyone else was getting started.</p>`,
southafrica: `<p class="story-text">The Garden Route along the southern coast is spectacular and each time we told a local our next destination their eyes lit up with joy. Cape Town is stunning &mdash; Table Mountain looms over the city, and Chapman's Peak drive has to be one of the world's greatest scenic drives.</p>
<p class="story-text">The Boulders is home for a couple hundred Jackass Penguins. They walk back and forth playing in the water, minding the very ugly baby penguins and posing for pictures with the tourists. This will be the closest you will ever get to wild penguins.</p>
<p class="story-text">The Cape of Good Hope has a baboon problem. They run in large packs and will grab anything left around. Their target was an Official Nature Reserve truck &mdash; they jumped up on the truck with baboon hysteria and began to assert who was boss around here.</p>
<p class="story-text">The Stellenbosch wine region represents a long tradition of wine making started by Dutch settlers in 1679. The Boschendal Winery's buffet lunch at 85 Rand was beyond excellent, the wine superb. We all had too many desserts. Somehow we managed to walk out the restaurant just far enough until one-by-one we began collapsing on the perfectly manicured lawn. This is more popularly referred to as a food coma.</p>`,
botswana: `<p class="story-text">We did it, on the road by 6 AM heading for the Botswana border. It was cold and dark but we were on our way. We were treated to the sight of three lions lying in the road &mdash; a lioness and two cubs &mdash; and also spotted elephants and a vibrant pink sunrise.</p>
<p class="story-text">Our main event in Botswana was to visit the Okavango Delta, the natural highlight of the country. It is a river of grass similar to Florida's Everglades with the addition of hippos, elephants, lions, giraffes and crocs. It is the world's largest inland delta and part of a 1,300 kilometer river.</p>
<p class="story-text">We spotted a large bull elephant hanging out in the shade. We were probably 100 feet from him and everyone was taking pictures. If I was a big elephant trying to take a nap and a bunch of tourists kept making noise, you know what I would do &mdash; Charge! When we see the guides bolt into a full run we knew what to do: Run! Scooter captured the spectacle on video. It looks like we are all extras in a Godzilla movie.</p>
<p class="story-text">Back at camp, Dizzy was cooking baked potatoes, salad, and boerwors. It was so dark that without the campfire or flashlight you couldn't see two inches in front of your face. We heard wild animal noises all night. I am glad we only spent one night in the Delta but it was worth it. I have seen so many Discovery Channel specials on the Okavango Delta and now I know what it is like first hand.</p>`,
cambodia: `<p class="story-text">Several years ago I read an article in Traveler Magazine about Angkor, some ruins in Asia and it looked totally exotic. Cambodia has had a long history that has seen many changes in the last 800 years. The main attraction for a tourist is Angkor Wat, considered a modern wonder of the world even though it is over 800 years old.</p>
<p class="story-text">Angkor Temples are one of the seven modern wonders of the world. They are located in northwest Cambodia outside Siem Reap. They are over 1,000 years old and too big and intact to be called ruins. The whole area is 400 square kilometers with 100 monuments including 24 major temples.</p>
<p class="story-text">Angkor Thom means "great city" &mdash; a walled city built in the 12th century holding Bayon temple and elephant terrace. It is huge and awesome looking with Buddha faces everywhere. A short drive away is Ta Prohm, a temple overgrown by tremendous old banyan tree roots. This temple is my favorite &mdash; wild and mystical looking.</p>
<p class="story-text">Angkor Wat is the largest temple in the world. It is unlike the other temples in that it faces west and was built as a Hindu temple. Its symmetrical towers are on the Cambodian flag. We spent the next two hours roaming around and climbing to the top for the view.</p>`,
nepal: `<p class="story-text">It was time to head to the hottest place on earth, New Delhi, India, and we were not looking forward to it. New Delhi did not disappoint with its combination of heat and pollution, so we decided to leave for Nepal the next day. The Kingdom of Nepal is one of the world's poorest countries by financial standards but we soon would learn that it is filled with riches beyond your wildest imagination.</p>
<p class="story-text">The streets of Thamel in Kathmandu are narrow and crowded with souvenir shops, restaurants, guest houses and people everywhere. We were really liking Nepal. The people are very relaxed, friendly and happy. It was fun just walking down the streets taking it all in. This was surprising because we were into our fourth month of travel and it was refreshing to be excited about a new place.</p>
<p class="story-text">Most trekking in Nepal is called a Tea House trek. The goal is to walk to the base of mountains that climb to 24,000 feet. Mt. Everest is the granddaddy of all mountains and it only takes 14 days to walk to it and another 14 days to walk back. Along the way you stay in local village houses setup for trekkers. Food and lodging can be had for less than five dollars a day.</p>`,
india: `<p class="story-text">"If you look to the left you will see something so amazing that you will never forget it. If you look to the right you will see something so disgusting you will never forget it." India is not for the first time traveler.</p>
<p class="story-text">India is reported to have a population of over 935 million people. Everywhere you go people are in the streets living, eating, going to work. We entered the Hotel York through a dark, dank staircase. Karen took a shower, cried some more because the big metal window-door wouldn't close. This was a $50 hotel in the main downtown district of New Delhi. Welcome to India!</p>
<p class="story-text">India was filled with incredible sights &mdash; India Gate, Lotus Temple, Red Fort, and the Taj Mahal. But everywhere we drove, people were living on the side of the road surrounded by trash heaps being eaten by cows. It was a viscous recycling process. We were in India during the summer, which means it is hot and no foreigners. I spent most of my time at the tourist sites posing with families for pictures. Someone would approach and hand me their baby &mdash; they had simply never seen a white person before.</p>`,
thailand: `<p class="story-text">Thailand was a welcome change from the intensity of India. The country has a warmth and hospitality that is hard to match anywhere in the world. Bangkok is a bustling metropolis &mdash; a city of contrasts between ancient temples and modern skyscrapers, street food vendors and luxury hotels.</p>
<p class="story-text">We traveled north to Chiang Mai, exploring hill tribe villages and ancient temples surrounded by lush jungle. The night markets were a sensory overload of spices, silk, and silver. The southern islands provided our much-needed beach break with crystal clear waters and white sand stretching to the horizon.</p>`,
singapore: `<p class="story-text">Singapore is the most immaculate city-state we have ever visited. After the chaos of Southeast Asia, arriving in Singapore felt like stepping into the future. Everything works, everything is clean, and everything has a rule. They even ship all their laundry to Malaysia for washing and drying &mdash; Singapore will have nothing to do with being dirty.</p>
<p class="story-text">The city is a fascinating mix of Chinese, Malay, and Indian cultures, with world-class food available on every corner for just a few dollars. We spent our days exploring hawker centers, botanical gardens, and the waterfront, preparing ourselves mentally for the next leg of our journey to India.</p>`
};
/* Get images for a country */
function getCountryImages(country) {
return Object.keys(IMAGE_CAPTIONS).filter(f => f.startsWith(country + '_'));
}
/* Get country from filename */
function getCountry(filename) {
return filename.split('_')[0];
}
/* ============================================================
BUILD TIMELINE
============================================================ */
function buildTimeline() {
const container = document.getElementById('timelineScroll');
const allStops = [
{ id: 'venezuela', name: 'Venezuela', img: 'venezuela_angel_falls.jpg', dates: 'Feb 98' },
{ id: 'trinidad', name: 'Trinidad', img: null, dates: 'Feb 98' },
{ id: 'curacao', name: 'Curacao', img: 'curacao_bridge.jpg', dates: 'Feb 98' },
{ id: 'ecuador', name: 'Ecuador', img: null, dates: 'Mar 98' },
{ id: 'galapagos', name: 'Galapagos', img: null, dates: 'Mar 98' },
{ id: 'peru', name: 'Peru', img: null, dates: 'Mar 98' },
{ id: 'bolivia', name: 'Bolivia', img: 'bolivia_lapaz.jpg', dates: 'Mar 98' },
{ id: 'paraguay', name: 'Paraguay', img: null, dates: 'Mar 98' },
{ id: 'argentina', name: 'Argentina', img: 'argentina_iguazu_falls.jpg', dates: 'Mar 98' },
{ id: 'chile', name: 'Chile', img: 'chile_andes.jpg', dates: 'Mar 98' },
{ id: 'hongkong', name: 'Hong Kong', img: null, dates: 'Apr 98' },
{ id: 'thailand', name: 'Thailand', img: null, dates: 'May 98' },
{ id: 'malaysia', name: 'Malaysia', img: null, dates: 'May 98' },
{ id: 'cambodia', name: 'Cambodia', img: 'cambodia_angkor_wat.jpg', dates: 'May 98' },
{ id: 'singapore', name: 'Singapore', img: null, dates: 'May 98' },
{ id: 'nepal', name: 'Nepal', img: null, dates: 'Jun 98' },
{ id: 'india', name: 'India', img: null, dates: 'Jun 98' },
{ id: 'greece', name: 'Greece', img: 'greece_colossus_color.jpg', dates: 'Jul 98' },
{ id: 'turkey', name: 'Turkey', img: 'turkey_ephesus_library.jpg', dates: 'Jul 98' },
{ id: 'southafrica', name: 'South Africa', img: 'southafrica_capetown.jpg', dates: 'Aug 98' },
{ id: 'namibia', name: 'Namibia', img: null, dates: 'Sep 98' },
{ id: 'botswana', name: 'Botswana', img: 'botswana_mokoro_ride.jpg', dates: 'Sep 98' },
{ id: 'zimbabwe', name: 'Zimbabwe', img: null, dates: 'Sep 98' },
{ id: 'germany', name: 'Germany', img: null, dates: 'Oct 98' },
{ id: 'netherlands', name: 'Netherlands', img: null, dates: 'Oct 98' },
{ id: 'spain', name: 'Spain', img: 'spain_barcelona.jpg', dates: 'Oct 98' },
{ id: 'portugal', name: 'Portugal', img: null, dates: 'Nov 98' },
{ id: 'france', name: 'France', img: null, dates: 'Nov 98' },
{ id: 'egypt', name: 'Egypt', img: 'egypt_pyramid.jpg', dates: 'Dec 98' },
{ id: 'jordan', name: 'Jordan', img: 'jordan_petra_treasury.jpg', dates: 'Dec 98' },
{ id: 'palestine', name: 'Palestine', img: null, dates: 'Dec 98' },
];
let html = '';
allStops.forEach(s => {
const chapterId = CHAPTER_ORDER.includes(s.id) ? `ch-${s.id}` : '';
const onclick = chapterId ? `onclick="document.getElementById('${chapterId}').scrollIntoView({behavior:'smooth'})"` : '';
html += `<div class="timeline-stop" ${onclick}>
<div class="timeline-dot"></div>
${s.img ? `<img src="images/${s.img}" alt="${s.name}" loading="lazy">` : `<div class="no-img">${s.name.charAt(0)}</div>`}
<div class="country-name">${s.name}</div>
<div class="dates">${s.dates}</div>
</div>`;
});
container.innerHTML = html;
}
/* ============================================================
BUILD CHAPTERS
============================================================ */
function buildChapters() {
const container = document.getElementById('chapters-container');
let html = '';
CHAPTER_ORDER.forEach((key, idx) => {
const c = COUNTRIES[key];
const images = getCountryImages(key);
const heroImg = CHAPTER_HEROES[key];
const hasImages = images.length > 0;
const story = CHAPTER_STORIES[key] || '<p class="story-text">Stories from this destination are part of the greater WorldWander narrative. Each place left its mark on our journey and in our hearts.</p>';
html += `<div class="chapter" id="ch-${key}">`;
// Chapter Hero
if (hasImages && heroImg) {
html += `<div class="chapter-hero">
<div class="chapter-hero-bg" style="background-image:url('images/${heroImg}')" data-parallax="chapter"></div>
<div class="chapter-hero-overlay"></div>
<div class="chapter-hero-content">
<div class="chapter-number">Chapter ${idx + 1}</div>
<h2 class="chapter-title">${c.name}</h2>
<p class="chapter-tagline">${c.tagline}</p>
</div>
</div>`;
} else {
html += `<div class="chapter-hero no-image">
<div class="chapter-hero-bg" style="background:${c.gradient || 'linear-gradient(135deg, #4A6741, #2C1810, #8B4513)'}" data-parallax="chapter"></div>
<div class="chapter-hero-overlay"></div>
<div class="chapter-hero-content">
<div class="chapter-number">Chapter ${idx + 1}</div>
<h2 class="chapter-title">${c.name}</h2>
<p class="chapter-tagline">${c.tagline}</p>
</div>
</div>`;
}
// Chapter Body with story
html += `<div class="chapter-body">
<div class="story-expandable" id="story-${key}">
${story}
</div>
<button class="read-more-btn" onclick="toggleStory('${key}')">Read full story</button>
</div>`;
// Photo gallery for this chapter
if (hasImages) {
html += `<div class="chapter-gallery">
<h3 class="reveal">${c.name} Gallery</h3>
<p class="gallery-sub reveal">${images.length} photographs</p>
<div class="photo-grid">`;
images.forEach(img => {
const caption = IMAGE_CAPTIONS[img] || img;
html += `<div class="photo-card reveal" onclick="openLightbox('images/${img}', '${caption.replace(/'/g, "\\'")} &mdash; ${c.name}')">
<img src="images/${img}" alt="${caption}" loading="lazy">
<div class="caption"><span class="country-tag">${c.name}</span>${caption}</div>
</div>`;
});
html += `</div></div>`;
}
html += `<div class="chapter-divider"><div class="ornament">&#10047; &bull; &#10047;</div></div>`;
html += `</div><!-- end chapter -->`;
});
container.innerHTML = html;
}
/* ============================================================
BUILD FULL GALLERY
============================================================ */
function buildGallery() {
// Filter buttons
const btnContainer = document.getElementById('filterButtons');
const allCountries = [...new Set(Object.keys(IMAGE_CAPTIONS).map(getCountry))].sort();
let btnHtml = '<button class="filter-btn active" data-filter="all">All</button>';
const regionMap = {
'South America': ['argentina', 'bolivia', 'chile', 'venezuela', 'curacao'],
'Africa': ['botswana', 'southafrica'],
'Middle East': ['egypt', 'jordan', 'turkey'],
'Europe': ['greece', 'spain'],
'Asia': ['cambodia']
};
Object.keys(regionMap).forEach(region => {
btnHtml += `<button class="filter-btn" data-filter="${regionMap[region].join(',')}">${region}</button>`;
});
allCountries.forEach(c => {
const name = c.charAt(0).toUpperCase() + c.slice(1);
btnHtml += `<button class="filter-btn" data-filter="${c}">${name}</button>`;
});
btnContainer.innerHTML = btnHtml;
// Masonry grid
const grid = document.getElementById('masonryGrid');
const allImages = Object.keys(IMAGE_CAPTIONS);
// Shuffle for visual variety
const shuffled = allImages.sort(() => Math.random() - 0.5);
let gridHtml = '';
shuffled.forEach(img => {
const country = getCountry(img);
const caption = IMAGE_CAPTIONS[img];
const countryName = country.charAt(0).toUpperCase() + country.slice(1);
gridHtml += `<div class="masonry-item" data-country="${country}" onclick="openLightbox('images/${img}', '${caption.replace(/'/g, "\\'")} &mdash; ${countryName}')">
<img src="images/${img}" alt="${caption}" loading="lazy">
<div class="m-caption"><span class="m-country">${countryName}</span><br>${caption}</div>
</div>`;
});
grid.innerHTML = gridHtml;
// Filter logic
btnContainer.addEventListener('click', e => {
if (!e.target.classList.contains('filter-btn')) return;
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
e.target.classList.add('active');
const filter = e.target.dataset.filter;
const items = document.querySelectorAll('.masonry-item');
if (filter === 'all') {
items.forEach(item => item.classList.remove('hidden'));
} else {
const countries = filter.split(',');
items.forEach(item => {
if (countries.includes(item.dataset.country)) {
item.classList.remove('hidden');
} else {
item.classList.add('hidden');
}
});
}
});
}
/* ============================================================
STORY EXPAND/COLLAPSE
============================================================ */
function toggleStory(key) {
const el = document.getElementById('story-' + key);
const btn = el.parentElement.querySelector('.read-more-btn');
if (el.classList.contains('expanded')) {
el.classList.remove('expanded');
btn.textContent = 'Read full story';
} else {
el.classList.add('expanded');
btn.textContent = 'Show less';
}
}
/* ============================================================
LIGHTBOX
============================================================ */
let currentLightboxImages = [];
let currentLightboxIdx = 0;
function openLightbox(src, caption) {
const lb = document.getElementById('lightbox');
const img = document.getElementById('lightboxImg');
const cap = document.getElementById('lightboxCaption');
img.src = src;
cap.innerHTML = caption;
lb.classList.add('active');
document.body.style.overflow = 'hidden';
// Build navigation array from visible images
currentLightboxImages = [];
document.querySelectorAll('.photo-card img, .masonry-item:not(.hidden) img').forEach(i => {
const parentCaption = i.alt || '';
currentLightboxImages.push({ src: i.src, caption: parentCaption });
});
currentLightboxIdx = currentLightboxImages.findIndex(i => i.src.includes(src.replace('images/', '')));
}
function closeLightbox() {
document.getElementById('lightbox').classList.remove('active');
document.body.style.overflow = '';
}
function navigateLightbox(dir) {
if (currentLightboxImages.length === 0) return;
currentLightboxIdx = (currentLightboxIdx + dir + currentLightboxImages.length) % currentLightboxImages.length;
const item = currentLightboxImages[currentLightboxIdx];
document.getElementById('lightboxImg').src = item.src;
document.getElementById('lightboxCaption').textContent = item.caption;
}
document.getElementById('lightboxClose').addEventListener('click', closeLightbox);
document.getElementById('lightbox').addEventListener('click', e => {
if (e.target === e.currentTarget) closeLightbox();
});
document.getElementById('lightboxPrev').addEventListener('click', e => { e.stopPropagation(); navigateLightbox(-1); });
document.getElementById('lightboxNext').addEventListener('click', e => { e.stopPropagation(); navigateLightbox(1); });
document.addEventListener('keydown', e => {
if (!document.getElementById('lightbox').classList.contains('active')) return;
if (e.key === 'Escape') closeLightbox();
if (e.key === 'ArrowLeft') navigateLightbox(-1);
if (e.key === 'ArrowRight') navigateLightbox(1);
});
/* ============================================================
SCROLL ANIMATIONS (IntersectionObserver)
============================================================ */
function setupRevealAnimations() {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
document.querySelectorAll('.reveal, .reveal-left, .reveal-right').forEach(el => {
observer.observe(el);
});
}
/* ============================================================
PARALLAX EFFECTS
============================================================ */
function setupParallax() {
let ticking = false;
window.addEventListener('scroll', () => {
if (!ticking) {
requestAnimationFrame(() => {
const scrollY = window.scrollY;
// Hero parallax
const heroBg = document.getElementById('heroBg');
if (heroBg) {
const heroH = window.innerHeight;
if (scrollY < heroH) {
heroBg.style.transform = `scale(1.1) translateY(${scrollY * 0.3}px)`;
}
}
// Chapter hero parallax
document.querySelectorAll('[data-parallax="chapter"]').forEach(bg => {
const rect = bg.parentElement.getBoundingClientRect();
if (rect.bottom > 0 && rect.top < window.innerHeight) {
const offset = (rect.top / window.innerHeight) * 50;
bg.style.transform = `translateY(${offset}px) scale(1.05)`;
}
});
ticking = false;
});
ticking = true;
}
});
}
/* ============================================================
NAV SCROLL EFFECT
============================================================ */
function setupNav() {
const nav = document.getElementById('siteNav');
window.addEventListener('scroll', () => {
if (window.scrollY > 80) {
nav.classList.add('scrolled');
} else {
nav.classList.remove('scrolled');
}
});
// Mobile menu
document.getElementById('mobileMenuBtn').addEventListener('click', () => {
document.getElementById('navLinks').classList.toggle('open');
});
document.querySelectorAll('.nav-links a').forEach(a => {
a.addEventListener('click', () => {
document.getElementById('navLinks').classList.remove('open');
});
});
}
/* ============================================================
INIT
============================================================ */
document.addEventListener('DOMContentLoaded', () => {
buildTimeline();
buildChapters();
buildGallery();
setupRevealAnimations();
setupParallax();
setupNav();
});
</script>
</body>
</html>