Customization
Every Urbicon UI component is restyleable through one predictable ladder of escape hatches. Pick the lowest rung that solves your problem — lower rungs preserve more of the design system's behavior (dark mode, hover/active cascade, focus rings).
Which tool do I use?
Start from your goal, not from the API. Find the row that matches what you want to change — the Reach for column is the tool to use.
| I want to… | Reach for | Example |
|---|---|---|
| Restyle one element on one instance Highest priority. Merges onto the OUTERMOST (root) slot only — see the trap below. | class | <Button class="rounded-full"> |
| Restyle an inner element (the actual <input>, a header, a chevron…) Type-safe — autocomplete lists the available slot names for each component. | slotClasses.<slot> | <Input slotClasses={{ base: "rounded-full" }} /> |
| App-wide look for a component type (every Button, every Card) defaults apply to every instance; presets are opt-in via preset="name". | preset / BlocksProvider defaults | defaults={{ Button: { slotClasses: { base: "rounded-full" } } }} |
| Style only one variant / intent / state (e.g. only outlined) Prop-conditional rule — what unconditional slotClasses cannot express. | overrides | overrides: [{ variant: "outlined", class: { base: "border" } }] |
| Rebuild a component from scratch (strip every default) Renders the HTML structure only; you own all visuals. | unstyled + slotClasses | <Card unstyled slotClasses={{ base: "…" }} /> |
rounded-none defeats a default rounded-full); non-conflicting classes accumulate. tv() variant styles (library default)BlocksProvider defaults.slotClassesBlocksProvider defaults.overrides[match]preset.slotClasses (when preset="…" is set)preset.overrides[match]Instance slotClasses propInstance class prop (root slot only)
The class Root-Slot Trap
class prop only reaches the outermost (root) slot. Most components wrap several elements. class lands on the root wrapper, not the element you are usually picturing. To style something inside,
go through slotClasses.<slot>.The classic surprise is Input: its root slot is wrapper (the label + field column), and the real <input> element is the base slot. So class="rounded-full" rounds the column, not the field.
class vs. slotClasses on Input
slotClasses is now type-safe on every component:
the keys are derived from the component's tv() slots, so your
editor autocompletes the available slot names (wrapper, container, base, label, message… for Input). Check a component's API reference, or the Slot Names reference, for its slot map.
CSS Token Themes
The simplest way to brand the library. Import a theme CSS file after the base styles to override the primary and secondary accents plus the neutral chassis. The semantic layer (surface, text, border tokens) derives from that chassis, so each theme re-tints it to match the accent's temperature — warm accents get warm surfaces, not cold grey ones.
Use a built-in theme
You can also create your own theme. Use the Theme Builder to generate an OKLCH palette, or write a custom @theme block:
Custom @theme block
Global Component Defaults
When CSS token overrides are not enough, use BlocksProvider to set default slotClasses for every component type. Wrap your app once, and every Button, Card, Input etc. picks up the defaults.
Instance-level slotClasses still override the global ones.
Global defaults via BlocksProvider
Defaults sit near the bottom of the precedence chain above — instance slotClasses and class still win. For
prop-conditional defaults (overrides) and named presets, see the BlocksProvider API.
Global Unstyled Mode
For a completely custom design, set unstyled on BlocksProvider. All components strip their default styles and only render the HTML structure.
Use slotClasses (globally
via defaults or per instance) to apply your own design.
Global unstyled mode
Deep Dives
CSS Token Themes
All built-in themes with live preview and usage instructions.
BlocksProvider API
Global unstyled mode, component defaults, and merge behavior.
Theme Builder
Interactive OKLCH color palette generator with live preview.
Design Tokens
Foundation, semantic, and interaction token reference.
Tier System
The three-tier semantic radius vocabulary — commit / modify / contain — with cascade and override demos.
Editorial Theme
How this docs site is themed — the --docs-* token catalogue, light/dark via light-dark(), activation and override recipes.