Slab
Slab is a studio and agency site in neo-brutalism: thick lines, hard shadows, flat color blocks and big type. It has a home page, services with fixed-price offers, work with case studies, about, a journal and contact. Headlines press into place word by word, a ticker band scrolls your services, buttons press into their shadow and pages wipe in from the side.
Slab 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.
Pages and their content
Section titled “Pages and their content”| Page | Edit it in |
|---|---|
| Home | Pages → Home page (a list of sections) |
| Services, work, about, journal, contact, 404 | Pages → the page’s own entry |
| Case studies | Content → Projects |
| Journal posts | Content → Journal |
| Studio name, tagline, email, location, navigation, header button, profiles | Pages → Site settings |
| Buttons, labels, chat, search, emails, game texts | Content → Interface texts |
| Privacy, terms | Pages → Legal |
Projects marked Featured come first, then by Order. Each project has a headline result (a number and a label) shown on its card, and a color for it. Journal posts pick a color too.
In headlines, a word wrapped in *stars* lands on a color block, as in
“We design and build software people *actually* use.”
Integrations
Section titled “Integrations”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 |
| Fixed-price offers | Services page → Fixed-price offers (a Stripe Price id per offer) | Stripe |
| Newsletter | Journal page, with a welcome email | Supabase |
| Ask the studio | Chat on every page, answers from your services, prices, work, about page and journal | Claude |
| Search | ⌘K or the search button: work, journal, services, about | built in, or Algolia |
| Analytics | Every page; Google Analytics only after consent | Plausible, Umami, Google Analytics |
Sections
Section titled “Sections”The home page is built from these sections, in any order: Hero (with up to three stickers), Ticker band, Services (from the services page), Selected work, How we work (steps), Numbers, Latest journal posts and Closing call to action.
Colors and brand
Section titled “Colors and brand”src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three fills: the
accent (buttons, highlights, the hero block) and a second and third color for cards
and stickers. Text on a fill is always ink, so each fill is lightened until it is readable; a
color that can’t get there stops the build with a message. Paper, ink, links and the dark theme
are derived from the fills. Brand also sets the fonts (text, headings, labels) and the corners
(square or slightly rounded).
Languages
Section titled “Languages”Slab is ready for more languages: see Languages.
The 404 page
Section titled “The 404 page”A small game, Stack the slabs: a slab slides back and forth above a stack; drop it with a click, a tap, Space or the Drop button. Whatever hangs over is cut off, so the next slab is narrower. The best height is kept in the visitor’s browser.
AI assistants and search engines
Section titled “AI assistants and search engines”AGENTS.mddescribes the project for coding assistants (Claude Code reads it throughCLAUDE.md, Cursor through.cursor/rules/), including what makes the look./llms.txtlists your pages, case studies and journal posts for AI assistants, in every language.- Pages carry JSON-LD: the studio, its services and questions, each case study and post.
Commands
Section titled “Commands”pnpm dev # local site, editor at /keystaticpnpm build # production buildpnpm 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).