No ASCII art diagrams. This is HTML. Use SVG, Mermaid, or proper diagram tools.
A Plate is a project page. Wiki, task tracker, and dev log in one HTML file. HTML instead of markdown because HTML is interactive and more expressive: tabs, tables, diagrams, persistent state, custom widgets.
All Plates live in one repo, served by one Vercel deployment. A new Plate is a new folder with an index.html. Push and it's live. The front door at plates.lunchfirm.com lists every registered Plate with a status derived from its log.
plates/
api/
plate.js data API: KV read/write, gates, history
render.js server render: wiki injection, og tags
log-entry.js standalone page per log entry
feed.js Atom feed across all plates
sitemap.js sitemap.xml
upload.js image uploads to R2
middleware.js routing (/slug/, /slug/log/id)
shared/
tokens.css Lunch design tokens
plate.css component styles
plate.js client logic (tabs, theme, data, gate)
plate-guide.md the full reference
plate/index.html this page
vmk26/ lakehouse/ ... one folder per project
Folder name = URL path. plates.lunchfirm.com/vmk26/ serves vmk26/index.html. Every log entry also has its own address: /<slug>/log/<id> is a standalone page with its own title and preview tags, made for sharing and citing a single moment of a project.
Tasks, log entries, wiki content, and the rest persist to Vercel KV, namespaced by slug: visiting /vmk26/ reads vmk26:tasks, vmk26:log, vmk26:wiki. Every edit is a per-entry operation - append, update one, delete one - so two tabs, a phone, and an agent can write at once without stepping on each other. Bulk replaces keep the last ten overwritten values in history; a bad write is a restore, not a loss.
Wiki content lives in KV, not in the HTML file. The file ships an empty shell and the server injects the current wiki when the page is fetched, so link previews and crawlers see real content. Edit in place with the pencil icon, or through the API. The TOC generates from h2 elements. The og image and description are derived at serve time - nothing to maintain.
One KV array (plates:registry) lists every Plate: slug, name, one-line description, done flag. It feeds the front door, the feed, and the sitemap. Status is derived - a log entry in the last 30 days means active, older means resting. done is the only flag set by hand, once, when a project completes.
A Plate can be gated: the password lives server-side and every read - page or API - requires it. Set or remove a gate from the header when logged in; no env vars, no deploys. Gated Plates disappear from the front door, feed, and sitemap. Built for client deliverables.
Posting a log entry is publishing. Every entry lands in the site-wide Atom feed (/feed.xml) linking to its permalink; the sitemap covers the index, Plates, and entries; llms.txt describes the system to agents. Entries can carry photos - the + photo button uploads from the phone straight to R2.
plate/ folder, rename it (the folder name is the slug)plates:registry with the slug and a one-line descriptionThe full contract - API, entry shapes, gates, cross-repo plates, 3D viewers - is in plate-guide.md.
Add a <button class="tab" data-tab="name"> and a matching <div class="panel" data-panel="name">. The shared JS handles switching. Put project-specific CSS/JS in the project folder.
Tokens extracted from the Lunch blog: Crimson Pro (body), IBM Plex Mono (labels and code), warm clay/cocoa palettes with day/night toggle. Spacing, radii, and motion tokens from the Lunch Design System. All in shared/tokens.css.
Plate grew out of using HTML artifacts instead of markdown for project planning with Claude. A Plate often starts before the project itself. It's where early thinking goes, before there's a repo or a client or a plan. The setup is zero because the thinking has to start immediately: copy a folder, change the name, push.