A cold archive of the underground — an interactive explorer for a goth / coldwave / witch house / death-industrial crate-digging list.
Browse by scene, search by name or sound, open any entry to go find the music.
Single page: hero → sticky filter bar → search → card grid → detail modal.
Ported from the gothwave-archive.jsx prototype, modeled on the
zapoutdoorz lineup-explorer pattern.
- TanStack Start (React 19 + Vite 7), TypeScript, file-based routing
- Tailwind CSS v4 (
@tailwindcss/vite) + a shadcn/uiDialogfor the modal - Nitro
vercelpreset →.vercel/output(Build Output API v3) - Node >= 22.12 (pinned via
engines.node)
npm install
npm run dev # http://localhost:3000| Script | Does |
|---|---|
npm run dev |
Vite dev server on port 3000 |
npm run build |
Production build → .vercel/output, then tsc --noEmit |
npm run preview |
Preview the production build locally |
npm run lint |
ESLint |
npm run format |
Prettier write |
src/
routes/__root.tsx # app shell: html/head, fonts, og meta, error + 404 boundaries
routes/index.tsx # the explorer: hero, filter bar, grid, Dialog modal, empty state
data/lineup.ts # typed ENTRIES + SCENES taxonomy
components/ui/ # shadcn Dialog primitive (Radix), themed to the prototype
lib/utils.ts # cn() class merge
styles.css # Tailwind v4 @theme tokens, grain + scanline texture, a11y
src/routeTree.gen.ts is generated by the router plugin — do not hand-edit (it
is git-ignored).
src/data/lineup.ts is the single source of truth: 120 entries across 10 scenes
(CLD WCH PWR SYN ETH DRK EBM FLK DUN LBL). The hero counts (entries / scenes)
are computed from this file.
Every entry resolves to three external links: Bandcamp, Discogs, and
YouTube. The default for all three is a deterministic search URL (via the
q() encoder, which strips parenthetical asides) — no profile is pre-verified,
so trust your ears. Where a direct, web-confirmed Bandcamp / official profile
exists, it is set on the entry as bandcamp and used for that one link. Any
medium-confidence candidates are listed in a comment at the top of lineup.ts
for manual review. Never add a handle you have not actually confirmed.
The build emits Vercel's Build Output API v3 layout (.vercel/output) via the
Nitro vercel preset (NITRO_PRESET=vercel, baked into npm run build).
- Git integration: import the repo;
vercel.jsonpinsinstallCommand/buildCommandand setsframework: null. Vercel serves.vercel/outputdirectly. - CLI:
vercel deploy(or--prod).
No environment variables are required.
Visible keyboard focus (:focus-visible ice outline), Esc-to-close and focus
trapping on the modal (Radix Dialog), labelled controls, and a responsive grid
down to ~320px. Honors prefers-reduced-motion.