A decade of going.
From a first trip to Germany in 2013 to the seventh continent ahead — every adventure, in order.
<
script>
(function() {
// === TIMELINE DATA (reverse chronological – newest first) ===
const TIMELINE = [
{ year: 2026, continent: ‘asia’, region: ‘Asia’, title: ‘2026: Bhutan & Delhi’,
excerpt: ‘Heading to the Land of the Thunder Dragon — Bhutan, with a stop in Delhi.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/layerslider/projects/Navigation-Slider/asia_large.jpg’,
url: ‘https://stevehaas.us/category/travel/asia/2026-bhutan-delhi/’ },
{ year: 2025, continent: ‘south-america’, region: ‘South America’, title: ‘2025: Amazon River, Iguazu Falls & Rio’,
excerpt: ‘Down the Amazon, to the thunder of Iguazu Falls, and ringing in the New Year on Copacabana.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2025/12/img_2148-1.jpg’,
url: ‘https://stevehaas.us/category/travel/south-america/2025-amazon/’ },
{ year: 2025, continent: ‘africa’, region: ‘Africa’, title: ‘2025: Mozambique, Eswatini & Okavango Delta’,
excerpt: ‘Our return to the Okavango Delta — this time with water — starting in Maputo and Manzini.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2023/07/pixie_1689789731344.png’,
url: ‘https://stevehaas.us/category/travel/africa/2025-mozam-eswa-okavango/’ },
{ year: 2025, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2025: Vancouver, BC’,
excerpt: ‘A long weekend in Vancouver for the AA International Convention.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2025-vancouver/’ },
{ year: 2025, continent: ‘europe’, region: ‘Europe’, title: ‘2025: Paris’,
excerpt: ‘A week in Paris with friends — playing tour guide in a city I never tire of.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
url: ‘https://stevehaas.us/category/travel/europe/2025-paris/’ },
{ year: 2024, continent: ‘south-america’, region: ‘South America’, title: ‘2024: Machu Picchu & Galápagos’,
excerpt: ‘First trip on this continent — Inca ruins above the clouds, then the wonders of the Galápagos.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/layerslider/assets/remote/pexels-photo-14374124–l.jpeg’,
url: ‘https://stevehaas.us/category/travel/south-america/2024-machu-picchu-and-the-galapagos-islands/’ },
{ year: 2024, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2024: Hawaii’,
excerpt: ‘8 days exploring Kauai, Maui, and Oahu — black sand beaches to volcanic peaks.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2024-hawaii/’ },
{ year: 2024, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2024: NYC & Washington, DC’,
excerpt: ‘A trip down the Eastern corridor — Broadway in New York, monuments in DC.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2024-new-york-city-washington-dc/’ },
{ year: 2024, continent: ‘mexico-central’, region: ‘Mexico & C. America’, title: ‘2024: Puerto Vallarta’,
excerpt: ‘Another trip back to the Banderas Bay coast.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Mexico.jpg’,
url: ‘https://stevehaas.us/category/travel/mexico-central-america/2024-puerto-vallarta/’ },
{ year: 2024, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2024: Ashland’,
excerpt: ‘Our annual trip to Ashland to see shows put on by the Oregon Shakespeare Festival.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2024-ashland/’ },
{ year: 2023, continent: ‘africa’, region: ‘Africa’, title: ‘2023: Botswana & Zimbabwe Safari’,
excerpt: ‘First time on this continent — safari across Botswana and Zimbabwe.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2017/12/africagallery_3.jpg’,
url: ‘https://stevehaas.us/category/travel/africa/2023-botswana-and-zimbabwe/’ },
{ year: 2023, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2023: Toronto & Niagara Falls’,
excerpt: ‘Exploring a bit of Toronto and the thunder of Niagara Falls.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/toronto-and-niagara-falls/’ },
{ year: 2023, continent: ‘mexico-central’, region: ‘Mexico & C. America’, title: ‘2023: Puerto Vallarta’,
excerpt: ‘My 5th visit to PVR, Ash\’s 1st — showing someone you love a place you love.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Mexico.jpg’,
url: ‘https://stevehaas.us/category/travel/mexico-central-america/2023-puerto-vallarta/’ },
{ year: 2023, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2023: New York City’,
excerpt: ‘MLK weekend in NYC — Broadway shows and old friends.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2023-new-york-city/’ },
{ year: 2022, continent: ‘mexico-central’, region: ‘Mexico & C. America’, title: ‘2022: Costa Rica’,
excerpt: ‘Cloud forests, beaches, and sloths — our honeymoon in Costa Rica.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Mexico.jpg’,
url: ‘https://stevehaas.us/category/travel/mexico-central-america/2022-costa-rica/’ },
{ year: 2022, continent: ‘europe’, region: ‘Europe’, title: ‘2022: France’,
excerpt: ‘Paris and the châteaux of the Loire Valley.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
url: ‘https://stevehaas.us/category/travel/europe/2022-france/’ },
{ year: 2022, continent: ‘mexico-central’, region: ‘Mexico & C. America’, title: ‘2022: Puerto Vallarta’,
excerpt: ‘First return to PVR since the pandemic.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Mexico.jpg’,
url: ‘https://stevehaas.us/category/travel/mexico-central-america/2022-puerto-vallarta/’ },
{ year: 2022, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2022: New York City’,
excerpt: ‘January 2022 trip to NYC to visit friends and see a few shows.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2022-new-york-city/’ },
{ year: 2021, continent: ‘europe’, region: ‘Europe’, title: ‘2021: Paris & Switzerland’,
excerpt: ‘Europe travel adventures during a pandemic — strange, quiet, unforgettable.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
url: ‘https://stevehaas.us/category/travel/europe/2021-paris-switzerland/’ },
{ year: 2021, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2021: Alaska’,
excerpt: ‘Memorial Day in Alaska — glaciers, mountains, and the long northern light.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2021-alaska/’ },
{ year: 2020, continent: ‘mexico-central’, region: ‘Mexico & C. America’, title: ‘2020: Puerto Vallarta’,
excerpt: ‘3rd annual President\’s Day weekend in PV — right before the world changed.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Mexico.jpg’,
url: ‘https://stevehaas.us/category/travel/mexico-central-america/2020-puerto-vallarta/’ },
{ year: 2019, continent: ‘mexico-central’, region: ‘Mexico & C. America’, title: ‘2019: Puerto Vallarta’,
excerpt: ‘The annual Puerto Vallarta escape continues.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Mexico.jpg’,
url: ‘https://stevehaas.us/category/travel/mexico-central-america/2019-puerto-vallarta/’ },
{ year: 2019, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2019: Sedona & Grand Canyon’,
excerpt: ‘Red rocks, deep canyons, big skies — an end-of-year nature trek.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2019-sedona-grand-canyon/’ },
{ year: 2019, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2019: New York City’,
excerpt: ‘Summer in the city.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2019-new-york-city/’ },
{ year: 2018, continent: ‘europe’, region: ‘Europe’, title: ‘2018: Cologne, Paris, London, NYC’,
excerpt: ‘My first solo trip to Europe.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
url: ‘https://stevehaas.us/category/travel/europe/2018-cologne-paris-london-nyc/’ },
{ year: 2018, continent: ‘mexico-central’, region: ‘Mexico & C. America’, title: ‘2018: Puerto Vallarta’,
excerpt: ‘February in PVR — a tradition forming.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Mexico.jpg’,
url: ‘https://stevehaas.us/category/travel/mexico-central-america/travel-puerto-vallarta/’ },
{ year: 2017, continent: ‘europe’, region: ‘Europe’, title: ‘2017: Istanbul, English Castles, NYC’,
excerpt: ‘A summer split between Istanbul, an English castle hop, and New York.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
url: ‘https://stevehaas.us/category/travel/europe/travel-instanbul-castle-hop-nyc/’ },
{ year: 2017, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2017: Chicago’,
excerpt: ‘Memorial Day weekend along the Chicago lakefront.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2017-chicago-memorial-day-weekend/’ },
{ year: 2017, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2017: Southern California’,
excerpt: ‘Christmas across Pasadena, Glendale, and the Palos Verdes Peninsula.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2017-pasadena-glendale-palos-verdes-peninsula-christmas/’ },
{ year: 2016, continent: ‘europe’, region: ‘Europe’, title: ‘2016: Vienna to Berlin’,
excerpt: ‘A loop through Central Europe — Vienna, Bratislava, Prague, Dresden, Berlin.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
url: ‘https://stevehaas.us/category/travel/europe/2016-vienna-bratislava-prague-dresden-berlin/’ },
{ year: 2016, continent: ‘europe’, region: ‘Europe’, title: ‘2016: Italy’,
excerpt: ‘Milan, Venice, Florence, Rome — the classic Italian arc in winter light.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
url: ‘https://stevehaas.us/category/travel/europe/2016-milan-venice-florence-rome/’ },
{ year: 2016, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2016: Thanksgiving in Philadelphia’,
excerpt: ‘Thanksgiving spent in the cradle of American history.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2016-thanksgiving-in-philadelphia/’ },
{ year: 2016, continent: ‘usa-canada’, region: ‘USA & Canada’, title: ‘2016: Los Angeles’,
excerpt: ‘Closing out the year in Los Angeles.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
url: ‘https://stevehaas.us/category/travel/usa-and-canada/2016-ending-the-year-in-los-angeles/’ },
{ year: 2015, continent: ‘europe’, region: ‘Europe’, title: ‘2015: Luxembourg to Tallinn’,
excerpt: ‘A patchwork summer — small Luxembourg, Roman Trier, sun-soaked Barcelona, and the Baltic.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
url: ‘https://stevehaas.us/category/travel/europe/luxembourg-trier-barcelona-helsinki/’ },
{ year: 2014, continent: ‘europe’, region: ‘Europe’, title: ‘2014: Paris, Edinburgh, London’,
excerpt: ‘A trip that started in Cologne & Bonn and ended in New York City.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
url: ‘https://stevehaas.us/category/travel/europe/par-edin-lon/’ },
{ year: 2014, continent: ‘mexico-central’, region: ‘Mexico & C. America’, title: ‘2014: Cozumel & Chichen Itza’,
excerpt: ‘Mayan ruins and the Caribbean — November 2014.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Mexico.jpg’,
url: ‘https://stevehaas.us/category/travel/mexico-central-america/2014-cozumel-chichen-itza/’ },
{ year: 2013, continent: ‘europe’, region: ‘Europe’, title: ‘2013: Germany, Netherlands, Belgium’,
excerpt: ‘The first international trip. Where it all began.’,
image: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
url: ‘https://stevehaas.us/category/travel/europe/ger-neth-bel/’ },
];
const REGION_LABEL = {
‘africa’: ‘Africa’, ‘asia’: ‘Asia’, ‘europe’: ‘Europe’,
‘mexico-central’: ‘Mexico & C. America’, ‘south-america’: ‘South America’,
‘usa-canada’: ‘USA & Canada’, ‘antarctica’: ‘Antarctica’,
‘australia’: ‘Australia & Oceania’
};
// === WP CATEGORY SLUG → CONTINENT MAPPING ===
// Maps WordPress category slugs to our continent IDs. When new posts are added under
// any category whose slug matches (including nested year-specific categories), they’re
// routed to the correct continent on the timeline.
const SLUG_TO_CONTINENT = {
‘africa’: ‘africa’,
‘asia’: ‘asia’,
‘europe’: ‘europe’,
‘mexico-central-america’: ‘mexico-central’,
‘south-america’: ‘south-america’,
‘usa-and-canada’: ‘usa-canada’,
‘australia’: ‘australia’,
‘antarctica’: ‘antarctica’
};
// Strip HTML tags from WP excerpts
function stripHtml(html) {
const tmp = document.createElement(‘div’);
tmp.innerHTML = html || ”;
return (tmp.textContent || tmp.innerText || ”).replace(/\s+/g, ‘ ‘).trim();
}
// Truncate excerpt to a clean sentence boundary
function trimExcerpt(text, maxLen) {
maxLen = maxLen || 140;
if (!text || text.length <= maxLen) return text;
const cut = text.slice(0, maxLen);
const lastSpace = cut.lastIndexOf(‘ ‘);
return cut.slice(0, lastSpace > 0 ? lastSpace : maxLen) + ‘…’;
}
// Determine which continent a WP post belongs to by walking its category slugs
function continentFromPost(post) {
if (!post._embedded || !post._embedded[‘wp:term’]) return null;
const terms = post._embedded[‘wp:term’].flat();
// Look for any term whose slug matches our continent slugs
for (const term of terms) {
if (SLUG_TO_CONTINENT[term.slug]) return SLUG_TO_CONTINENT[term.slug];
}
// Look for parent category slug in nested categories (year-trip categories like 2025-amazon)
for (const term of terms) {
if (!term.parent) continue;
const parent = terms.find(t => t.id === term.parent);
if (parent && SLUG_TO_CONTINENT[parent.slug]) return SLUG_TO_CONTINENT[parent.slug];
}
return null;
}
// Build a timeline entry from a WP post
function entryFromPost(post) {
const continent = continentFromPost(post);
if (!continent) return null; // skip non-travel posts
const date = new Date(post.date);
const year = date.getFullYear();
const title = stripHtml(post.title && post.title.rendered);
const excerpt = trimExcerpt(stripHtml(post.excerpt && post.excerpt.rendered), 140);
// Try to grab a featured image
let image = null;
if (post._embedded && post._embedded['wp:featuredmedia'] && post._embedded['wp:featuredmedia'][0]) {
const media = post._embedded['wp:featuredmedia'][0];
if (media.media_details && media.media_details.sizes) {
image = (media.media_details.sizes.medium_large && media.media_details.sizes.medium_large.source_url)
|| (media.media_details.sizes.large && media.media_details.sizes.large.source_url)
|| (media.media_details.sizes.medium && media.media_details.sizes.medium.source_url)
|| media.source_url;
} else {
image = media.source_url;
}
}
return {
year: year,
date: post.date,
continent: continent,
region: REGION_LABEL[continent],
title: title,
excerpt: excerpt,
image: image || CONTINENT_FALLBACK_IMG[continent] || CONTINENT_FALLBACK_IMG.usa,
url: post.link,
_live: true // flag so we know this came from the API
};
}
const CONTINENT_FALLBACK_IMG = {
‘africa’: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2023/07/pixie_1689789731344.png’,
‘asia’: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/layerslider/projects/Navigation-Slider/asia_large.jpg’,
‘europe’: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Europe.jpg’,
‘mexico-central’: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/Mexico.jpg’,
‘south-america’: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/layerslider/assets/remote/pexels-photo-14374124–l.jpeg’,
‘usa-canada’: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/2022/09/America.jpg’,
‘australia’: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/layerslider/projects/Navigation-Slider/background.jpg’,
‘antarctica’: ‘https://i0.wp.com/stevehaas.us/wp-content/uploads/layerslider/projects/Navigation-Slider/background.jpg’
};
// === FETCH LATEST POSTS FROM WP REST API ===
// Pulls the most recent 30 posts from any travel category and prepends them
// to the static TIMELINE. If a fetched post has the same URL as a static entry,
// the fetched (fresher) version wins.
let activeTimeline = TIMELINE.slice(); // start with static data
const rail = document.getElementById(‘shtt-rail’);
const yearsContainer = document.getElementById(‘shtt-years’);
function rebuildYearPills() {
const uniqueYears = [‘all’, …new Set(activeTimeline.map(t => t.year))].sort((a, b) => {
if (a === ‘all’) return -1;
if (b === ‘all’) return 1;
return b – a;
});
// Cap to 9 most recent years + All
const limited = uniqueYears.slice(0, 10);
yearsContainer.innerHTML = '';
limited.forEach((y, i) => {
const pill = document.createElement('button');
pill.className = 'shtt-year-pill' + (i === 0 ? ' active' : '');
pill.textContent = y === 'all' ? 'All Years' : y;
pill.dataset.year = y;
pill.addEventListener('click', () => renderTimeline(y));
yearsContainer.appendChild(pill);
});
}
function fetchLatestPosts() {
// Fetch 30 most recent posts with embedded category + featured image data
// _embed=1 gives us featured media + categories in one request
const url = ‘https://stevehaas.us/wp-json/wp/v2/posts?per_page=30&_embed=1&_fields=id,date,link,title,excerpt,_links,_embedded’;
fetch(url, { credentials: 'omit' })
.then(r => r.ok ? r.json() : Promise.reject(r.status))
.then(posts => {
if (!Array.isArray(posts) || posts.length === 0) return;
const liveEntries = posts.map(entryFromPost).filter(Boolean);
if (liveEntries.length === 0) return;
// Merge: live entries first, then static entries that aren't duplicates by URL
const liveUrls = new Set(liveEntries.map(e => e.url));
const staticUnique = TIMELINE.filter(e => !liveUrls.has(e.url));
// Sort by date descending (live entries have .date; static use year)
activeTimeline = [...liveEntries, ...staticUnique].sort((a, b) => {
const aDate = a.date ? new Date(a.date).getTime() : new Date(a.year + '-12-31').getTime();
const bDate = b.date ? new Date(b.date).getTime() : new Date(b.year + '-12-31').getTime();
return bDate - aDate;
});
rebuildYearPills();
renderTimeline('all');
})
.catch(err => {
// Silent fail — static TIMELINE is already rendered, so the user sees content
console.warn('[Steve Haas Travel] Could not fetch latest posts from WP REST API:', err);
});
}
// === Render rail ===
function renderTimeline(filterYear) {
// Update active pill
document.querySelectorAll(‘.shtt-year-pill’).forEach(p => {
p.classList.toggle(‘active’, String(p.dataset.year) === String(filterYear));
});
// Filter
const items = filterYear === 'all'
? activeTimeline
: activeTimeline.filter(t => String(t.year) === String(filterYear));
// Build HTML, grouping by year
rail.innerHTML = '';
let currentYear = null;
let alternator = 0;
items.forEach(item => {
if (item.year !== currentYear) {
currentYear = item.year;
const marker = document.createElement('div');
marker.className = 'shtt-year-marker';
marker.innerHTML = `<div class="shtt-year-badge">${item.year}</div>`;
rail.appendChild(marker);
}
const side = alternator % 2 === 0 ? 'left' : 'right';
alternator++;
const entry = document.createElement('a');
entry.className = `shtt-entry ${side}`;
entry.href = item.url;
entry.innerHTML = `
<div class="shtt-card">
<img class="shtt-card-img" src="${item.image}" alt="${item.title.replace(/"/g, '"')}" loading="lazy">
<div class="shtt-card-body">
<div class="shtt-card-meta shtt-meta-${item.continent}">
<span class="shtt-card-meta-dot"></span>
${REGION_LABEL[item.continent] || item.region}
</div>
<h3 class="shtt-card-title">${item.title}</h3>
<p class="shtt-card-excerpt">${item.excerpt}</p>
<span class="shtt-card-cta">
Read more
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
</span>
</div>
</div>
`;
rail.appendChild(entry);
});
// Trigger fade-in animation via IntersectionObserver
const observer = new IntersectionObserver(entries => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add('visible');
observer.unobserve(e.target);
}
});
}, { threshold: 0.15 });
document.querySelectorAll('.shtt-entry').forEach(el => observer.observe(el));
}
// Initial render with static data (instant), then fetch live data and re-render
rebuildYearPills();
renderTimeline(‘all’);
fetchLatestPosts();
// Smooth scroll for the subscribe nudge in the timeline header
const nudge = document.getElementById(‘shtt-sub-nudge’);
if (nudge) {
nudge.addEventListener(‘click’, function(e) {
const target = document.getElementById(‘subscribe’);
if (!target) return;
e.preventDefault();
const top = target.getBoundingClientRect().top + window.pageYOffset – 80;
window.scrollTo({ top: top, behavior: ‘smooth’ });
setTimeout(() => {
const input = document.getElementById(‘shsub-email’);
if (input) input.focus({ preventScroll: true });
}, 800);
});
}
})();
Get the next adventure in your inbox.
Real stories from the road — photo journals, honest takes, and the occasional 5 AM coffee deck. No spam, no SEO fluff. Just travel writing, sent when a new trip drops.

Keep In Touch