Skip to main content
Change Velt’s look (colors, spacing, fonts, radius, shadows) without touching its structure or behavior. It’s the lowest-effort approach, and it layers on top of every other one.
Two shortcuts before you write any CSS: build a theme visually in the Theme Playground, or have the UI Customization Plugin extract the values from your Figma design and write the overrides for you.
className and style props on Velt components do nothing. Style Velt with the variables and classes below, or add classes to your own markup inside a wireframe.

Make your CSS reach Velt

Velt can render inside a shadow DOM, which blocks your stylesheets.
  • CSS variables (--velt-*) always cross the boundary. Theming with variables alone needs nothing here.
  • Class and element selectors don’t. Pick one of these:
Option A: turn shadow DOM off.
Option B: keep it on and inject your CSS into the shadow root. Use type: "styles" for a CSS string, type: "link" for a stylesheet URL.
Wireframes change this. Registering a component’s root wireframe (e.g. VeltCommentDialogWireframe) removes that component’s shadow DOM automatically, so your class CSS reaches it. A nested-only wireframe doesn’t: set shadowDom={false} yourself. Inline style="" always works either way.

Theme with variables

Put all Velt CSS in one stylesheet and override the tokens you need:
Every token is listed in CSS variables; don’t invent names. Older surfaces read a few --legacy-velt-* tokens, which are listed there too.
Rather than hand-picking values, build your theme in the Theme Playground: adjust colors, radius, spacing, and typography against a live preview, then copy the generated variables straight into this stylesheet.

Dark mode

Velt sets data-velt-theme="dark" on the document root when dark mode is on. You supply the values:
Turn it on with the darkMode prop (also dialogDarkMode, pinDarkMode, … for components Velt injects for you), with setDarkMode() app-wide, or by wiring your own prefers-color-scheme listener to it:

Fonts

One global token sets the font across every Velt surface:
Font sizes use the --velt-font-size-* scale. Line-height and weight are per-component.

Override classes

For anything variables don’t cover, target Velt’s classes. Velt’s own styles are high-specificity, so your overrides need !important. That’s the supported way to do class-based Velt CSS, not a hack.
  1. Run with shadowDom={false} and inspect the element.
  2. Prefer its velt-* BEM class over the short legacy twin: velt-comment-dialog--selected, not selected.
  3. Write the rule with !important:
CSS classes lists every structural and stateful class (unread, resolved, selected, hover, filter-applied, …). Class names can shift between versions, so prefer a --velt-* variable where one exists and re-check overrides on upgrade.

Unstyled mode

Restyling most of the UI anyway? Strip Velt’s visual styling with setUnstyledMode() (v6.0.0-beta.10+) and bring your own CSS. Layout and positioning styles are kept so components stay functional. It covers styles in the page head and inside shadow roots, and is reversible.
To also drop Velt’s global styles (the ones outside its own components), set globalStyles: false in your config:

What CSS can and can’t do

Writing display:none to remove parts, or wishing you could move a button? You’ve hit CSS’s ceiling: escalate to wireframes to restructure, or primitives to toggle features.

Checklist

  • shadowDom={false} on components you style with classes.
  • All Velt CSS in one stylesheet.
  • Only token names that exist in CSS variables.
  • Dark values under :root[data-velt-theme="dark"].
  • No display:none to remove features: toggle them with a prop.