Skip to main content
Init extracts .vendo/theme.json. The theme has this exact shape:
Init wires this file into the scaffolded <VendoRoot theme={...}> at build time (sync regenerates it on each build), so a fresh install renders on brand without passing theme by hand. Pass partial runtime overrides through VendoProvider.theme. Shipped chrome derives its colors, typography, radius, density, and motion from these tokens. It does not hardcode a Vendo brand. Generation receives the same theme. Optional .vendo/design-rules.md adds generation-time design rules without changing runtime tokens.

Emitted CSS variables

VendoRoot emits stable CSS custom properties derived from density and motion. Chrome and the prewired primitives read them directly, and you can consume the same variables from your own styles. The --vendo-density-* and --vendo-motion-* names below are stable — new variables may be added under these prefixes, but the ones listed here will not be renamed.

Density

density: "compact" tightens control sizes, padding, and gaps; density: "comfortable" relaxes them. Every compact value is less than or equal to its comfortable counterpart.

Color scheme

VendoRoot derives color-scheme from the WCAG relative luminance of colors.background and exposes it as --vendo-color-scheme. Backgrounds below the flip point (L < 0.179) resolve to dark; everything else, including unparseable values, resolves to light. Chrome uses this variable to activate light-dark() branches, so a dark-brand host automatically gets the dark chrome treatment without any extra configuration. Set colors.background in .vendo/theme.json (or through a VendoProvider.theme override) and the scheme follows.
.vendo/theme.json
Reference --vendo-color-scheme from your own styles if you want custom surfaces to track the same flip:

Motion

motion: "reduced" collapses --vendo-motion-duration to 0ms so chrome respects user reduced-motion preferences. The easing curve stays constant. Reference the variables from your own CSS to keep custom surfaces in sync with the current theme:

Mobile takeover

Shipped overlay, page, and palette chrome switch to a full-viewport takeover at viewports 767px wide and narrower. The takeover covers the host layout instead of docking inside a squeezed column and portals to document.body so transformed host ancestors cannot confine it. It honors iOS safe-area insets on all four edges. On touch devices (pointer: coarse), the composer and palette search render at 16px to prevent iOS auto-zoom, and icon buttons and the overlay close control expand to a 44px touch target. Desktop chrome is unchanged. The takeover surface stamps a stable --fl-kb-inset CSS variable derived from visualViewport so the composer lifts above the on-screen keyboard. Read it from your own styles if you render a custom surface inside a takeover:
--fl-kb-inset is 0px when no keyboard is open and outside of takeover mode.