unoverse://theme/<name>, an MCP resource, never baked into a bundle). A color change is a refresh, not a release.
The law
- No
px/rem/em/#hexanywhere in any component, atom, or template definition. Studioβs publish lint scans for exactly this and blocks (08). - Sizes use the space scale (
"width": "8"= 2rem, Tailwind-style: step N = N Γ 0.25rem), and only real steps:0 1 1.5 2 3 4 5 6 7 8 10 12 16 20 24 28 40 50 75 90 100 120 140 160 180 200(+full/auto). An invented step ("26","3.5") is NOT rounded: it falls through as broken CSS and the element silently reverts to auto sizing. Studioβs publish lint rejects off-scale values. - β No invented component-named tokens (
cardMin,wizardWidth): use the generic scale steps. If the scale genuinely lacks a step, extend the scale instyles/, donβt smuggle a value into a definition.
Style KEYS are closed too: the cross-platform contract
Itβs not just values: the set of style keys (padding, direction, radius, hover, β¦) is a closed vocabulary, exactly the neutral intents the SDK style interpreter maps, and the contract every renderer (web today; iOS, Android, React Native, Flutter as they land) implements. An unknown key is ignored by every renderer, so it is always a typo (colour) or a web-ism that would never port (backdropFilter, gridTemplateColumns).
Both the schema (editor squiggle) and Studioβs publish lint (error) enforce the key set, including inside hover/active and when[].apply. If a design genuinely needs an intent the vocabulary lacks, thatβs a platform conversation (a new key every renderer must implement): never a definition-side workaround.
Why so strict: brand and dark-mode swaps must touch styles/ only. One raw hex in one definition breaks that guarantee for the whole org.
The token layers
Definitions speak semantic. Themes remap semantic β base per brand or mode; a theme-contract guard keeps token names consistent so every theme satisfies every definition.
Standard app sizes (semantic/app-sizes.json)
The named width blocks a templateβs appWidth can reference (05: Sizing). The starter set:
Every size carries a viewport ceiling (
min(100vw, β¦)): the full designed width on desktop, never wider than the screen on mobile. (Panels side-by-side can still exceed a phoneβs width together: the dedicated mobile layout pass will decide stacking/overlay behavior; the ceiling keeps each panel individually safe until then.)
Names are optional: raw CSS in appWidth is always valid, but prefer them: every template in the org stays on the same scale, and retuning a size is one edit here. Add org-specific names freely (the linter validates that any name a template uses is declared). Unlike every other token home these values are raw host-facing CSS on purpose: they size the appβs outer panel, which the embedding page applies, they are never inner styles.
Org scoping
- Components live in TWO tiers. The design system (the installed marketplace package: generic, universal: cards, charts, media) is shared by every org and references token names only. An org component (
rx/<project>/components/: the clientβs own microapp: their finder, their page) is org-private: it belongs to that client and is served under their org. Names are unique across all tiers (lint-enforced), so a bare reference is unambiguous. - Atoms are universal and authoring-time only:
rx/atoms/, one copy; the server expands everyRefbefore serving (atoms are never served or enumerable). - Templates and styles are org-scoped:
rx/<project>/. Each org gets its own complete token set and templates. There are no overlays: if two orgs need different looks from the same universal component, that difference is 100% in theirstyles/. A component only becomes an org component when it IS the clientβs product, not to restyle a shared one.
Styling checklist
- Zero raw values in any definition (linter enforces)
- Only semantic token names referenced (
text.primary, not a palette entry) - No component-named tokens invented
- New brand/mode = a new
themes/file, zero definition edits - Theme keeps the full token contract (guard test)
Next: 06b, Lifecycle Hooks, a component that fetches its own data.

