| Name | Last commit date | |
|---|---|---|
| .. | ||
| screens | 4 days ago | |
| DESIGN.md | 4 days ago | |
| export.mjs | 4 days ago | |
| paper-export.json | 4 days ago | |
| paper.mjs | 4 days ago | |
| README.md | 2 days ago | |
| tokens.css | 4 days ago | |
| tokens.json | 4 days ago | |
Lattice design system (exported copy)
The design system lives in the Paper file Lattice design system: Guidelines (start there), Foundations, Components, Patterns and App screens. This folder is its exported copy, for code and for agents that cannot reach Paper.
| File | What it is | Edit it? |
|---|---|---|
tokens.css |
Every token as CSS custom properties; light on :root, dark under [data-theme="dark"] or .dark |
No, generated |
tokens.json |
The same tokens with their light and dark values, use, and the app variable each mirrors | No, generated |
DESIGN.md |
The written rules from the Guidelines page, then every token in tables | No, generated |
paper-export.json |
The raw pull from Paper the three files above are rendered from | No, generated |
export.mjs |
The exporter | Yes |
paper.mjs |
The Paper file's id and a client for Paper's MCP server | Yes |
screens/ |
Draws the App screens page from the running app (below) | Yes |
README.md |
This file | Yes |
Regenerate from Paper
With the Paper desktop app running and the file reachable from your account:
node design-system/export.mjs
pnpm vitest run src/styles/design-system-drift.test.ts
The exporter starts Paper's MCP server (paper mcp; set PAPER_BIN if
paper is not on PATH or in ~/.paper/bin), reads the design tokens, the
spec:motion and spec:shadow blocks on Foundations (durations, curves,
the --motion-* pairs of the two, and shadows have no Paper token type),
and the Start here and Guidelines
artboards, saves that pull as paper-export.json, and renders the rest from it.
node design-system/export.mjs --from design-system/paper-export.json
re-renders without Paper.
Paper has no theme modes, so a dark value is its own token there
(--color-dark-chrome, --shadow-dark-popover); the export folds each into its
light twin. A font token holds the face Paper can draw and its description
carries the real stack after stack:, which is what the export writes.
Who reads these files
The Lattice app does not import tokens.css. Its own CSS stays its source:
src/styles/theme.css and foundations.css also declare scopes this export
does not cover (the theme and tint previews in Settings), and the drift check
below is the contract that keeps the app and this copy equal. tokens.css,
tokens.json and DESIGN.md are for everything else: the website, new
software built from the system, and agents without Paper.
The drift check
src/styles/design-system-drift.test.ts resolves every token whose
description names an app variable (app: --surface-chrome) in the app's own
theme.css and foundations.css, in the right theme, tint, accent or Settings
scope, and fails on any difference. A code-theme token (app: code-theme github --syntax-keyword) is checked against the palette the editor computes for that
theme (codeThemeProperties in src/settings/code-themes.ts). It never changes either side: when it fails,
decide which one is right, change that one at its source (the Paper file, or
the app's CSS), and re-export. Tokens with app: none are documentation only.
Hand it to another agent
- An agent with the Paper MCP: give it the Paper link and tell it to read the
Guidelines page first, then use the file's tokens (
get_tokens) and look at the components it needs. - An agent without Paper (cloud, another machine): give it this folder. It
should read
DESIGN.mdfirst and take every value fromtokens.cssortokens.json. Rules marked [Lattice] are specific to Lattice; the rest are meant for a new product too.
The review loop
The maintainer reviews the product, never the system pages: the app on the Paper file's App screens page, the website and films on their own review pages or boards.
- The maintainer comments on what is under review. For the app, that is a comment pinned to a screen's artboard in Paper.
- The agent reads the open threads (
list_comment_threads, thenget_comment_threadfor each in full) and fixes the screen in Paper, or the website or film on its own surface. - When a comment implies a rule or a value of the system (a colour, a spacing
step, a motion curve, a rule on the Guidelines page), that agent, not the
maintainer, updates the Paper file: the token or rule, and the components and
patterns that show it. It runs
node design-system/export.mjsand the drift check. - An app screen's change reaches the app's code only once the maintainer picks
it; the drift check then holds the app and the exported copy together. The
agent resolves the thread (
set_comment_thread_status) when its change is in, and names the thread in the pull request.
App screens
The App screens page holds the app's main screens (main window, Agent panel,
references, Markdown, HTML and slides viewers, Settings, welcome) in light and
dark, as editable layers whose colours, fonts and radii are the file's tokens.
They are drawn from the app as it runs, not from screenshots, by screens/:
each screen is staged on the mock-backend page over the tutorial project and
its built PDF (scenes.mjs), every rendered element becomes a Paper layer at
its measured place (serialize.js), and draw.mjs writes it to the artboard
of that name. Redraw a screen this way after the app changes rather than
editing it by hand to match:
pnpm perf:bench --serve --dev --port 0 # prints the page's URL; keep it running
BENCH_URL=<url> node design-system/screens/agent.mjs <synara checkout> # the Agent panel, first
BENCH_URL=<url> node design-system/screens/draw.mjs [screen…] # --dry-run to only write HTML
The Agent panel is Synara's own chat view at the pinned revision, rendered by
agent.mjs in Synara's browser test harness in Lattice's embed mode and host
theme. Slides come from the Open Slide runtime over a throwaway copy of the
deck (pnpm --dir tools/open-slide-runtime install first). Colours that match
no token are counted; inside the app's own chrome every colour is a token, or a
token at reduced opacity.
Builds that embed the private Timeless family set the interface, reading and display roles in its faces; the screens bind those roles to the font tokens. Paper cannot draw Timeless (or the bundled Ioskeley Mono), so each font token holds the closest face Paper has, chosen by glyph overlap and set width against the app's own face: Inter (interface), Libre Caslon Text (reading), Lora (display), Roboto Mono (code). The export still writes the app's stacks.