This is the repository for the website for the band LE FOG. It is a Next.js App Router site that streams the band's catalog from Cloudflare R2, gates downloads behind Clerk authentication, and is deployed on Vercel.
The Node version is pinned in .nvmrc (Node 24). CI reads the same
file, so local and CI installs produce the same lockfile.
nvm use
npm ci
cp .env.example .env.local
npm run devFill in .env.local before running the dev server. Every variable is
documented in .env.example. Live values can be pulled with
vercel link && vercel env pull .env.local. Local development must use
the Clerk development instance keys (pk_test_ / sk_test_).
Open localhost:3000 to view the site.
| Command | Purpose |
|---|---|
npm run dev |
Run the development server |
npm run build |
Create a production build |
npm run start |
Serve the production build |
npm run typecheck |
Generate route types, then run tsc |
npm run lint |
Biome lint and format check |
npm run lint:ci |
Biome check as run in CI |
npm run format |
Apply Biome formatting |
npm run test |
Run the Vitest suite once |
npm run test:watch |
Run Vitest in watch mode |
CI (.github/workflows/node.js.yml) runs typecheck, lint:ci, build
and test on every push and pull request to main and dev.
src/
app/ Routes, route-level CSS, API routes, metadata
api/ contact, download and stream handlers
styles/ Global tokens, base, layout and shared styles
components/ One component per file
auth/ Sign-in and sign-up form components
styles/ One stylesheet per component
context/ React providers (audio, theme, icons, global)
lib/
auth/ Access-level rules
constants/ One constant per file
db/r2/ Cloudflare R2 access, one action per file
hooks/ Client hooks
types/ One type or interface per file
utils/ One utility per file
proxy.ts Request proxy (Clerk)
tests/ Vitest suites grouped by feature, plus helpers
The logo is static files in public/images/logo/: wordmark.svg, the
lettering, used as a CSS mask so it takes the theme's text colour, and one
orb-<colourway>.webp per colour in LOGO_ORBS. The orb's place inside
the wordmark is in src/lib/constants/logo-geometry.ts. Icons and the
share image use Next's file conventions in src/app/, apart from the
manifest's PNG icons in public/favicon/.
The full standards live in .claude/CLAUDE.md. In short:
- Files are capped at 200 lines.
- Single quotes in all JS/TS files; indentation is 2 spaces.
- The codebase follows SOLID principles. Actions, types, constants, utilities and components each live in their own file and are shared through imports and exports.
- Related functionality is grouped in nested folders under a common parent.
- Fix the root cause of a problem. Do not silence the linter or formatter with comments, and do not paper over issues with overrides.
- Tests explain why a behavior exists and why it works.
The site is deployed on the Vercel Platform.
Environment variables are managed in Vercel and pulled locally with
vercel env pull.