Night Trains
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
The origin
ÖBB launched the Berlin–Paris Nightjet in late 2023, eight years after Deutsche Bahn killed the route. That single fact contains a longer story — peak in the 90s, dismantled by budget aviation, revived in fragments since 2016. I wanted to tell it as a map: amber lines lit, fading to crimson, lit again. Five scroll beats, one dataset, one continent.
The pull
Astro shell with a single Svelte island for the scrollytelling. D3 draws routes onto a Natural Earth map; routes animate in as SVG stroke-dashoffset, fade to crimson as they're discontinued, light back up amber on revival. The hard part was not the rendering — it was the data. The seed dataset I started with had errors (Moscow–Nice listed as 1936 instead of ~2010, CityNightLine end-year off by two years, several unsourced totals). I committed a verification pass first — every row cross-referenced against operator archives, the International Railway Journal, and Railway Gazette — before writing a line of viz code. The seed dropped from 40 routes to 39. sources.json ships in /data/ so anyone can audit the dataset.
What came out
39 verified routes · 5 narrative beats · sources.json shipped