Landing page for neonpixels.io — a very small studio and one very caffeinated agent, shipping the tools we kept wishing existed.
Built with VitePress and a fully custom Tailwind CSS v4 theme (no default VitePress chrome).
- Node.js — the version pinned in
.nvmrc(nvm use)
npm install
npm run devThe site is a single custom-themed page. The theme lives in .vitepress/theme:
AppLayout.vue— swaps between the landing page and the 404 viewcomponents/NeonPixelsPage.vue— the landing pagecomponents/NotFound.vue— the 404 viewstyle.css— Tailwind entry, theme tokens, keyframes and animation utilities
| Script | What it does |
|---|---|
npm run dev |
Start the local dev server |
npm run build |
Build the static site to .vitepress/dist |
npm run preview |
Preview the production build locally |
npm test |
Run the test suite in watch mode |
npm run test:ci |
Run the test suite once |
npm run typecheck |
Type-check with vue-tsc |
npm run lint |
Check formatting (Prettier) and lint (ESLint) |
npm run lint:fix |
Auto-fix formatting and lint issues |
npm run audit |
Audit production dependencies |
Tests use Vitest with happy-dom and @vue/test-utils. They
cover the components, the SEO/social metadata in config.ts (Open Graph and Twitter
cards, favicons resolve to real files), the Netlify security headers, and the ESLint
accessibility ruleset.
Deploys to Netlify. See netlify.toml for
the build command, publish directory and security headers. The build runs the test
suite before building, so a failing test blocks the deploy.
The enforcing Content-Security-Policy in netlify.toml still allows
script-src 'unsafe-inline'. The build (buildEnd in .vitepress/config.ts)
also publishes a stricter Content-Security-Policy-Report-Only header via a
generated _headers file that hashes VitePress's inline scripts. That header is
wired to a collector — a Reporting-Endpoints header plus report-to /
report-uri directives point violations at the /csp-report Netlify Function
(netlify/functions/csp-report.ts), which
records them to the function logs. The parsing/validation is isolated in
.vitepress/csp/cspReportCollector.ts
so it is unit-testable without the Netlify runtime. Once the logs show no
script-src violations and no csp-report-rejected or csp-report-unparsed
entries over the observation window, 'unsafe-inline' can be dropped from the
enforcing script-src (see the @todo in netlify.toml). The two markers
matter: a request rejected for an unmodelled content type or an unrecognized
body shape would otherwise read as "no violations", so a clean run must show
neither. No environment variables or external services are required — the
collector is same-origin.
Managed with Husky:
- pre-commit — gitleaks secret scan
- pre-push — lint, typecheck and tests
- post-merge — reinstalls dependencies when the lockfile changes
Install gitleaks locally (brew install gitleaks) so the pre-commit hook can run.