Contribution

How a change gets into the Velio design system, for designers, engineers and AI agents alike. Agents also read AGENTS.md, which holds the hard rules.

How a change happens

Every change, from a new color to a renamed prop, follows the same steps.

  1. Audit. Look at what exists in code, on the docs site and in Figma before proposing anything. Note what is missing, inconsistent or unused.
  2. Propose. Write down the options and a recommendation. Name anything that affects VelioBot (part names, props, actions), since those are breaking changes.
  3. Decide. The design owner approves the change. Nothing ships unapproved.
  4. Change the source. Edit the one file that owns the thing (see “Where things live”). Never patch generated files or copy values into a page.
  5. Show it on the docs site. Run npm run dev and check the affected pages in light, dark and at phone width. The Recipes and Screens pages are the regression surface for anything Gen UI renders.
  6. Review. The design owner looks at the site before anything goes further.
  7. Mirror to Figma. Anything that also lives in Figma (variables, text styles, effect styles, icons, the docs site frame) is updated there in the same change, then read back and compared.
  8. Record it. Add a changelog entry, move the roadmap item, and add a decision note if the change sets or breaks a convention.
  9. Check. npm run check and npm run build must both pass.

Where things live

To changeEditThen
A color, type role, space, radius, size, shadow, blur or motion valuetokens/velio.tokens.jsonnpm run tokens; update the Figma variable
An iconsystem/icons/fill/<name>.svg, exported from the Figma icon framenpm run icons
How a component lookssystem/components/<name>.cssCheck the component page and Recipes
A component’s props, slots, states or markupgenui/parts.jsUpdate docs/genui.md if the contract changed
Examples, anatomy, do and don’tgenui/part-docs.js
Product guidance for a componentsrc/content/components/<slug>.md
A Gen UI composition rulegenui/rules.js, plus a passing and failing pair in genui/rule-examples.js
Sidebar navigationsrc/lib/site.ts
The changelogsrc/data/changelog.ts
The roadmapsrc/data/roadmap.ts
Docs site chromesrc/layouts/Base.astro, src/styles/site.cssUpdate the Figma site frame
A page scriptThe page’s <script>, wrapped in astro:page-load with a guard for its own root element (the site navigates in place)Click to the page from another page, not only reload it

Rules everyone follows

  • One system. Gen UI parts are Velio components. Never make a second Button or a Gen UI-only token.
  • Roles, not raw values. Components use color, type, space, radius, size, effect and motion tokens only. If a value is missing, add a token rather than hard-coding it. npm run check enforces this.
  • Use tokens by role. Pick bg-raised or label for what the thing is, not for the color or size you want.
  • Code and Figma stay in step. A change to anything that exists in both is made in both, in the same change. Figma variables and styles carry the same names as the tokens (bg/raised is --v-bg-raised).
  • The JSON contract is stable. Part names, prop names and action payloads are what VelioBot emits and the apps parse. Renaming one means updating recipes, rules, part docs and docs/genui.md, and logging it as a breaking change.
  • Write plainly. Short sentences, sentence case, no marketing language. Say what something does, not why it is great.

Figma

The Figma file is Social (file key 8kS9tvExzNdaDxmFlbz50X). It mirrors the system on the System page.

  • Variables: Color (Light and Dark modes, one variable per color role), Typography, Layout and Motion, plus a hidden Primitives collection for the palette. Names split the token path with slashes: --v-bg-raised is bg/raised, --v-on-accent is on/accent. Each variable’s web code syntax is var(--v-…).
  • Styles: text styles named by type role, effect styles named by shadow token, and paint styles for the three gradients, all bound to variables. Don’t add styles that are not in the system.
  • Icons: the fill frame on the System page. Export new icons from there into system/icons/fill/.
  • Docs site frame: the overview frame mirrors the site’s layout and sidebar. Update it when the shell or the navigation changes.
  • Agents editing Figma through the plugin API: Nohemi and Satoshi can’t be loaded by the API. Set the text to a loadable font first, then bind fontWeight and after it fontFamily to the Typography variables; Figma resolves the real font. Read the result back after every write.

Keeping the changelog

Add an entry to src/data/changelog.ts for every approved change, in the same change that makes it. Newest first.

  • date is the day it was approved (YYYY-MM-DD). Several entries can share a date.
  • kind is foundation, component, genui or site. It sets the dot color.
  • title names what changed (for example, “Relaxed body line heights”), not the work done.
  • groups hold bullet lists, with an optional heading each. Each bullet is one change, with before and after values where they help. Wrap token and file names in backticks.
  • Add an image only when a picture explains the change better than words.

Keeping the roadmap

src/data/roadmap.ts has three lists: planned, ongoing and done. Move items between them as work starts and finishes. When an item is done, it also gets a changelog entry. Known gaps found during an audit go into planned with a one-line note.

Before you finish

npm run check   # tokens, icons, rules, examples and docs in step
npm run build   # the static site builds

Then look at the pages you touched, in both themes.