---
description: UDS (Urban Design System) — use semantic tokens and framework-agnostic Web Components for UI.
alwaysApply: true
---

# UDS Design System

You are building UI with the **Urban Design System (UDS)**.

UDS has two layers:

- **Tokens:** semantic CSS custom properties for color, spacing, type, borders, and shadows.
- **Components:** framework-agnostic Web Components using the `udc-` tag prefix, with React wrappers available for React apps.

## Critical Rules

1. **Never use `--uds-primitive-*` tokens in product UI.** Use semantic tokens: `--uds-color-*`, `--uds-space-*`, `--uds-font-*`, `--uds-border-*`, `--uds-shadow-*`.
2. **Never hardcode colors, spacing, radii, shadows, or fonts.** Use `var(--uds-*)`.
3. **Use Web Component tags for UDS components.** Do not recreate UDS with raw class markup unless you are working on the Web Component implementation itself.
4. **React apps use wrappers, not a separate implementation.** `@uds/react` wraps the same Web Components.

Docs: https://udsdocs.com/  
AI context: https://udsdocs.com/ai-context.json  
Per-component spec: https://udsdocs.com/uds/components/<component>/spec.json

## Setup

```js
import './uds/uds.css';
import { registerUdsComponents } from '@uds/web-components';

registerUdsComponents();
```

React:

```tsx
import { UdsButton, UdsTextInput } from '@uds/react';

export function Example() {
  return (
    <>
      <UdsTextInput label="Full name" required />
      <UdsButton variant="primary">Save</UdsButton>
    </>
  );
}
```

## Naming

- Component tags: `<udc-button>`, `<udc-text-input>`, `<udc-dialog>`
- Subcomponent tags: `<udc-tab>`, `<udc-tab-panel>`, `<udc-dropdown-item>`
- Public API: attributes, properties, slots, events, and documented CSS parts
- Do not invent UDS classes. The old class-based examples are transitional, not the target API.

## Common Pattern Mapping

| If you need... | Use |
|---|---|
| Button / action | `<udc-button>` |
| Link | `<udc-link>` |
| Label | `<udc-label>` |
| Text field | `<udc-text-input>` |
| Multiline text | `<udc-text-area>` |
| Checkbox | `<udc-checkbox>` |
| Radio group | `<udc-radio-group>` + `<udc-radio>` |
| Dropdown / select | `<udc-dropdown>` + `<udc-dropdown-item>` |
| Combobox | `<udc-combobox>` + `<udc-combobox-option>` |
| Date field | `<udc-date-picker>` |
| Toggle / switch | `<udc-toggle>` |
| Search | `<udc-search>` |
| Status label | `<udc-badge>` |
| Filter pill / tag | `<udc-chip>` |
| Divider | `<udc-divider>` |
| Icon surface | `<udc-icon-wrapper>` |
| Spacer | `<udc-spacer>` |
| Breadcrumb | `<udc-breadcrumb>` |
| Tabs | `<udc-tabs>` + `<udc-tab>` + `<udc-tab-panel>` |
| Top app bar | `<udc-nav-header>` |
| Side navigation | `<udc-nav-vertical>` + `<udc-nav-item>` |
| Pagination | `<udc-pagination>` |
| Tile / selection card | `<udc-tile>` |
| List | `<udc-list>` + `<udc-list-item>` |
| Data table | `<udc-data-table>` |
| Data view | `<udc-data-view>` |
| Notification / toast | `<udc-notification>` |
| Dialog / modal | `<udc-dialog>` |
| Tooltip | `<udc-tooltip>` |

## Component Examples

```html
<udc-button variant="primary">Save</udc-button>
<udc-button variant="secondary">Cancel</udc-button>
<udc-button variant="ghost" icon-only aria-label="More actions" leading-icon="more_vert"></udc-button>
```

```html
<udc-text-input
  label="Email"
  type="email"
  helper-text="We'll never share your email"
  required
></udc-text-input>

<udc-text-area
  label="Notes"
  helper-text="Add context for the leasing team"
  max-length="500"
></udc-text-area>
```

```html
<udc-checkbox name="terms">Accept terms</udc-checkbox>

<udc-radio-group name="contact" label="Preferred contact" value="email">
  <udc-radio value="email">Email</udc-radio>
  <udc-radio value="phone">Phone</udc-radio>
</udc-radio-group>

<udc-toggle name="notifications">Email notifications</udc-toggle>
```

```html
<udc-dropdown label="Property" value="riverbend">
  <udc-dropdown-item value="riverbend">Riverbend Estates</udc-dropdown-item>
  <udc-dropdown-item value="lakeside">Lakeside Villas</udc-dropdown-item>
</udc-dropdown>

<udc-search label="Search tenants" placeholder="Search by name"></udc-search>
```

```html
<udc-badge tone="success">Active</udc-badge>
<udc-chip variant="filter" selected>Active</udc-chip>
<udc-notification tone="info" dismissible>3 invoices are pending review.</udc-notification>
```

```html
<udc-tabs selected-panel="overview">
  <udc-tab panel="overview">Overview</udc-tab>
  <udc-tab panel="details">Details</udc-tab>
  <udc-tab-panel panel="overview">Overview content</udc-tab-panel>
  <udc-tab-panel panel="details">Details content</udc-tab-panel>
</udc-tabs>
```

```html
<udc-dialog heading="Confirm archive" open>
  Archive this lease?
  <div slot="actions">
    <udc-button variant="secondary">Cancel</udc-button>
    <udc-button variant="primary" color="danger">Archive</udc-button>
  </div>
</udc-dialog>
```

```html
<udc-nav-header>
  <span slot="brand">Boardroom</span>
  <udc-button slot="actions" variant="ghost" leading-icon="account_circle">Profile</udc-button>
</udc-nav-header>

<udc-nav-vertical aria-label="Main navigation">
  <udc-nav-item href="/dashboard" current>Dashboard</udc-nav-item>
  <udc-nav-item href="/leases">Leases</udc-nav-item>
</udc-nav-vertical>
```

## Events

Listen for UDS custom events:

- `udc-change`: value/checked changes
- `udc-input`: text/search input changes
- `udc-dismiss`: dismissible chip or notification dismissed
- `udc-tab-change`: active tab changed
- `udc-page-change`: pagination changed
- `udc-close`: dialog closed

```js
document.querySelector('udc-text-input')?.addEventListener('udc-input', (event) => {
  console.log(event.detail.value);
});
```

## Token Architecture

Primitive tokens are raw palette values. Do not use them directly.

Semantic tokens describe purpose and adapt to theme changes:

```css
.custom-panel {
  color: var(--uds-color-text-primary);
  background: var(--uds-color-surface-main);
  border: 1px solid var(--uds-color-border-secondary);
  border-radius: var(--uds-border-radius-container-md);
  padding: var(--uds-space-300);
}
```

## Theming

Set theme attributes on `<html>`:

```html
<html data-color-scheme="dark" data-theme="resman" data-font="poppins">
```

Supported attributes:

- `data-color-scheme="dark"`
- `data-theme="resman" | "anyonehome" | "inhabit"`
- `data-font="poppins" | "roboto" | "lexend"`
- `data-font-scale="smaller" | "larger"`
- `data-density="comfortable"`

## Do Not

```css
/* Wrong */
color: #171717;
padding: 16px;
font-family: 'Inter', sans-serif;
```

Do not use the old button class API as the target public API.

## Do

```css
/* Right */
color: var(--uds-color-text-primary);
padding: var(--uds-space-200);
font-family: var(--uds-font-family);
```

```html
<!-- Right target API -->
<udc-button variant="primary">Save</udc-button>
```

## Checklist

Before outputting UI code:

- Uses semantic `--uds-*` tokens only.
- Uses `<udc-*>` component tags where UDS has a component.
- Does not invent UDS class names.
- Keeps component behavior inside the Web Component API.
- Uses React wrappers only as wrappers around Web Components.
