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

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

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 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