Skip to content

Lava

Lava is a developer portfolio built around a lava lamp: home, work with case studies, about, notes and contact. Every page has a temperature, from 40 °C on the home page to 100 °C on the contact page; the hotter the page, the faster the wax rises. Moving between pages floods the screen with wax.

Lava comes in two variants, chosen when you create the site: files/Sanity (static, any host) and EmDash (--cms emdash, rendered on request on Cloudflare). The pages are the same in both.

Page Edit it in
Home Pages → Home page (a list of sections)
Work, about, contact, notes, 404 Pages → the page’s own entry
Projects (case studies) Content → Projects
Notes (short articles) Content → Notes
Your name, role, email, navigation, profiles Pages → Site settings
Your photo Pages → About page
Buttons, labels, chat, search, emails, game texts Content → Interface texts
Privacy, terms Pages → Legal

Projects marked Featured come first, then by Order. The home page shows as many as its Selected work section asks for.

Everything works without keys; each feature switches on with its variables in .env.example.

Feature Where Service
Contact form Contact page; messages go to the email in Site settings Resend
Book a call Contact page, loads on click Cal.com
Paid sessions Contact page → Paid sessions (a Stripe Price id per offer) Stripe
Newsletter for notes Notes page, with a welcome email Supabase
Ask about my work Chat on every page, answers from your about page, projects and notes Claude
Search ⌘K or the search button: projects, notes, about built in, or Algolia
Analytics Every page; Google Analytics only after consent Plausible, Umami, Google Analytics

The home page is built from these sections, in any order: Hero, Selected work, Skills (with your photo and the skill groups from the about page), Latest notes and Closing call to action.

src/content/singletons/brand.json (Pages → Brand in Keystatic) picks a palette: Classic (blue, orange, amber), Raspberry, Forest, Ink or Ocean, or Custom with your own three colors: the lamp (the dark theme’s background) and two waxes. Text, buttons, links and the light theme are derived from them and checked for readable contrast; a color that can’t be made readable stops the build with a message. Brand also sets the fonts (text, headings, labels), corners and button shape.

The wax is drawn by a small WebGL program that starts after the page has loaded, so it never slows the first view. Without a graphics card, without JavaScript, or with reduced motion turned on, simple CSS wax (or a still frame) takes its place. Each page’s temperature and the lanes the wax flows in are in src/lib/temperature.ts; the wax keeps clear of the text, since light text on wax isn’t readable.

Lava is ready for more languages: see Languages.

A small game, Pop the wax: pop the blobs before they reach the top of the lamp, with a click, a tap or the keys 1–9. The best score is kept in the visitor’s browser.

  • AGENTS.md describes the project for coding assistants (Claude Code reads it through CLAUDE.md, Cursor through .cursor/rules/).
  • /llms.txt lists your pages, projects and notes for AI assistants, in every language.
  • Pages carry JSON-LD: you as a person on the home page, each project and note.
Terminal window
pnpm dev # local site, editor at /keystatic
pnpm build # production build
pnpm cms sanity schema|seed # move content to Sanity (see Content → Sanity)

In the EmDash variant: npm run dev, npm run deploy (Cloudflare) and npm run emdash:schema (after changing the content model).