← All roasts
DS-002·Data viz · 2026·260g

Night Trains

A scroll-driven story of Europe's sleeper-train network from 1995 to 2025. Thirty-nine routes, cross-referenced against operator archives and rail-industry press.

Role
Solo · research + build
Year
2026
Category
Interactive
Weight
260g
Price
Single-origin

Roast
4/5
Notes
Cartographic · Scrolly · Sourced
Stack
Astro · Svelte · D3 · TopoJSON

Pulled on 2026 · Best by: always
Visit the live site ↗

The origin

ÖBB launched the Berlin–Paris Nightjet in late 2023, eight years after Deutsche Bahn ended the route. That single fact carries a longer story: a peak in the 90s, a network dismantled by budget aviation, then a fragmented revival from 2016 onward. I wanted to tell it as a map: amber lines lighting up, fading to crimson, then lighting up again. Five scroll beats, one dataset, one continent.

The pull

Astro provides the shell, with a single Svelte island for the scrollytelling. D3 draws routes onto a Natural Earth map. Routes animate in with SVG stroke-dashoffset, fade to crimson when discontinued, and return to amber on revival. The hard part was not rendering; it was the data. The seed dataset had errors: Moscow–Nice listed as 1936 instead of around 2010, CityNightLine's end year off by two years, and several unsourced totals. I completed a verification pass first — every row cross-referenced against operator archives, the International Railway Journal, and Railway Gazette — before writing a line of visualization code. The dataset moved from 40 routes to 39. sources.json ships in /data/ so anyone can audit the work.

What came out

39 verified routes · 5 narrative beats · sources.json shipped