Dark28 — Case Study
back- Next.js
- TypeScript
- React
- Tailwind CSS
The question
Lisbon's Tram 28 passes through layers of history that most tourist guides ignore. I kept finding apps that told the same polished story and skipped the uncomfortable parts — the dictatorship, the colonial memory, the religious weight embedded in the architecture. What if a route helped you understand a city instead of just photograph it?
What I built
An editorial web app that transforms the Tram 28 into a self-guided dark tourism experience. Users discover landmarks filtered by historical theme, read narrative context for each stop, and build a personal plan of places to visit and track.
- Editorial homepage with thematic framing
- Landmark discovery by theme (dictatorship, colonialism, religion, death)
- Detail pages with narrative context per stop
- Save landmarks and track visited places
- Route direction toggle and dark/light theme
- Fully responsive, mobile-first
Technical decisions
Next.js (App Router) — editorial content needs good SEO and fast initial load. Server components simplified data fetching and nested layouts.
TypeScript throughout — enforced clear data contracts between components and caught two broken data shapes before they hit the UI.
Tailwind CSS — rapid iteration on a content-heavy interface without fighting specificity. Consistent spacing without thinking about it.
localStorage + custom hooks — one useLocalStorage hook persisted all user state across four features with no backend required.
What I learned
Designing content-first changes the UI. The narrative weight of each stop shaped the information hierarchy — generic card components didn't work because the content resisted being genericised. TypeScript caught real bugs, not theoretical ones. App Router's server/client boundary required rethinking where state lives.