# 3D Source UI Component Libraries

> All local file paths in this document are relative to the package root (`@3dsource/source-ui-native/`).


> Two Angular UI component libraries by 3D Source: `@3dsource/source-ui-native` (lightweight, zero-dependency UI primitives) and `@3dsource/source-ui` (higher-level components built on Angular CDK/Material). Both use Angular 19+ signals API (`input()`, `output()`), zoneless change detection, `ViewEncapsulation.None`, and CSS custom properties (`--src-*`) for theming.

## Key concepts

- All components use the `src-` selector prefix (e.g. `<src-button>`, `<src-badge>`)
- Inputs use Angular signals: `input()`, `input.required()`, `output()`
- Enum-like inputs are typed as union types derived from `as const` objects (e.g. `SourceButtonAppearanceKeys` = `"plain" | "inline" | "filled" | "default"`)
- Design tokens are SCSS CSS custom properties with `--src-` prefix, organized by category: color (light/dark themes), layout (responsive breakpoints), typeface, UI sizing
- `@3dsource/source-ui` depends on `@3dsource/source-ui-native` — always install both when using source-ui
- Modals have TWO approaches: native `<dialog>`-based via `SourceModalElementService` (source-ui-native, no CDK needed) and CDK Dialog-based via `Dialog.open(SourceModalComponent)` (source-ui, needs `@angular/cdk/dialog`)
- Popovers are opened via `SourcePopoverService`, not template binding
- The library provides TWO levels of styling: Angular Components (with `input()/output()` API) AND CSS-only Source Elements (BEM classes on native HTML tags — no Angular imports needed)
- The `section_3dsourcecom` class must be placed on the root app container element for Source UI styles to apply. Place it on `<app-root>` inner wrapper, the root `<section>`, or `<body>` as a last resort. Do NOT place it on `<html>`. Example: `<body class="section_3dsourcecom">` or `<div class="section_3dsourcecom">` as the first child of `<app-root>`.
- **Dark theme**: add `section_3dsourcecom--dark` class alongside `section_3dsourcecom` to activate the dark color scheme. For CDK overlays, add `cdk-overlay-container--dark` to the overlay container. Toggle between light and dark by adding/removing the `--dark` class. Both light and dark tokens are bundled — no extra import needed.
- **Scrollbar**: global scrollbar styling is applied automatically (`scrollbar-width: thin`). Override with `--srcScrollbarThumbColor` and `--srcScrollbarTrackColor` CSS custom properties on any ancestor element.
- STRICT RULE: Do NOT use Tailwind CSS or any utility-first CSS framework. All styling must use Source UI design tokens (`--src-*` CSS custom properties), Source Element BEM classes (`src-*`), and standard CSS/SCSS. Never generate Tailwind classes (`flex`, `p-4`, `bg-blue-500`, etc.).

## Library selection priority

STRICT RULE: Only install `@3dsource/source-ui` when Angular Material components (form fields, checkbox, radio, select, autocomplete, toggle) or CDK-based features (popover, color-picker, tabs, tooltip, CDK modal) are explicitly needed. Default to `@3dsource/source-ui-native` only.

Choose the appropriate library based on your project type:

1. **Non-Angular projects** (Lovable, Webflow, plain HTML, React, Vue, any non-Angular framework) → Install `@3dsource/source-ui-native` via npm. Import ONLY the compiled CSS file: `@3dsource/source-ui-native/styles/source-ui-native.min.css`. Use Source Elements (BEM CSS classes on native HTML tags). Do NOT install `@3dsource/source-ui` — it requires Angular and will not work.
2. **Angular without CDK/Material** → Install only `@3dsource/source-ui-native`. Use Angular components (`SourceButtonComponent`, `SourceBadgeComponent`, etc.) + Source Elements.
3. **Angular with CDK/Material** → Install both `@3dsource/source-ui-native` and `@3dsource/source-ui`. This gives access to color-picker, popover, tabs, tooltip, CDK modal, and styled Material form fields.

## Libraries

### @3dsource/source-ui-native v3.3.1

Lightweight UI primitives with zero dependencies (only `tslib`). **No Angular peer dependency** — works without Angular entirely. Can be used in any project (React, Vue, plain HTML, Lovable, etc.) by importing just the compiled CSS stylesheet. Includes:
- **Angular Components** (require Angular): badge, banner, button, copyright, divider, hint, icon-button, loading, logo-loading, modal-element, slider
- **Source Elements (CSS-only, no Angular needed)**: badge, banner, button, checkbox, divider, hint, icon-button, input, label, list, modal, radio, select, textarea, toggle — pure CSS classes applied to standard HTML elements

### @3dsource/source-ui v3.2.1

Higher-level components built on top of Angular CDK and Angular Material. Provides custom styling for Material form fields (input, select, autocomplete, checkbox, radio, toggle) to match the Source UI design system. Peer dependencies: `@3dsource/source-ui-native >=2.0.0`, `@angular/core >=19.0.0`, `@angular/material >=19.0.0`, `swiper >=11.2.6`. Components: color-picker, popover, slider-group, tabs, tooltip, toastr styling, Material form field styling.

**Important:** When using `@3dsource/source-ui`, you must provide `MAT_FORM_FIELD_DEFAULT_OPTIONS` with `{ appearance: 'outline' }` globally in your app config for correct form field styling.

## Component API reference (inline)

> Full API for every component inlined below. No external JSON links needed.

### Library: @3dsource/source-ui-native

### SourceBadgeComponent (@3dsource/source-ui-native)
**Selector:** `src-badge` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| backgroundColor | string | "var(--src-ui-accent-default, #017bffff)" | — | no | Background color of the badge. |
| context | SourceBadgeContextKeys | — | default, info, success, warning, attention, error | no | Defines the context ot the badge (e.g. status). |
| size | SourceBadgeSizeKeys | "md" | sm, md, lg, xl | no | Size of the badge. |
| textColor | string | "var(--src-text-body-main-invert, #f9fafbff)" | — | no | Text color inside the badge. |
| customClass | string \| string[] | — | — | no | Custom class(es) to apply to the badge. |
| testID (alias: data-testid) | string | "" | — | no | Test ID for querying the badge in tests. |
| role | string \| null | "status" | — | no | ARIA role for the badge, with a default of "status" for accessibility. |
| ariaLabel | string | — | — | no | ARIA label for the badge, used for accessibility. |

### SourceBannerComponent (@3dsource/source-ui-native)
**Selector:** `src-banner` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| context | SourceBannerContextKeys | "default" | default, info, success, warning, critical, error | no | Defines the banner context. |
| size | SourceBannerSizeKeys | "sm" | sm | no | — |
| isFullWidth | boolean | true | — | no | If true, the banner will take the full width of its container. |
| testID (alias: data-testid) | string | "" | — | no | Test ID for querying the badge in tests. |
| role | string | — | — | no | ARIA role for the banner, used for accessibility (e.g. "region", "alert"). |
| ariaLive | 'polite' \| 'assertive' \| 'off' | — | — | no | ARIA live region setting for the banner, used for accessibility to indicate how updates should be announced. |

### SourceButtonComponent (@3dsource/source-ui-native)
**Selector:** `src-button` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| type | SourceButtonTypeKeys | "button" | button, submit, reset | no | Type of button |
| appearance | SourceButtonAppearanceKeys | "filled" | plain, inline, filled, default | no | Basic visual style of the button |
| weight | SourceButtonWeightKeys | "secondary" | primary, secondary, ghost | no | Is this the principal call to action on the page? |
| size | SourceButtonSizeKeys | "md" | slim, medium, large, sm, md, lg, xl | no | How big it should be? |
| context | SourceButtonContextKeys | "default" | default, error, success, info | no | Color variation of button. Usually represent context of action. |
| customClass | string \| string[] | "" | — | no | Add custom class if you need harder customization. |
| isFullWidth | boolean | false | — | no | Is this button should fill all available width of the container? |
| isPressed | boolean | false | — | no | Pressed state for button |
| isDisabled | boolean | false | — | no | Standard disabled state for button |
| isLoading | boolean | false | — | no | Set true if your button has show loading process after pressing |
| isInverted | boolean | false | — | no | — |
| iconButton | boolean | false | — | no | — |
| srcButtonConfig | SourceButton | — | — | no | Even though it is not recommended, you can set the buttons configuration using one input. A valid use-case for it is settings for buttons in src-modal. |
| formID | string | — | — | no | The form element to associate the button with (its form owner). The value of this attribute must be the id of a form in the same document. |
| testID (alias: data-testid) | string | "" | — | no | Test ID for querying the badge in tests. |
| ariaLabel | string | — | — | no | ARIA label for the button, used for accessibility. |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| onClick | Event | Optional click handler |
| onSubmit | Event | Optional submit handler |

### SourceCopyrightComponent (@3dsource/source-ui-native)
**Selector:** `src-copyright` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| linkText | string | "Powered by 3D Source" | — | no | If you need other phrase then Powered by 3D Source change it here |
| isCollapsible | boolean | false | — | no | Mostly used in absolute container above the view |
| testID (alias: data-testid) | string | "" | — | no | — |

### SourceDividerComponent (@3dsource/source-ui-native)
**Selector:** `src-divider` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| testID (alias: data-testid) | string | "" | — | no | — |

### SourceHintComponent (@3dsource/source-ui-native)
**Selector:** `src-hint` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| isError | boolean | false | — | no | Deprecated? Should this hint be shown as an error? Error hint will change color to red. |
| context | SourceHintContextKeys | "default" | default, error, success, info | no | Context of the message. Can be "default", "info", "success" or "error" - change the color of the hint. |
| size | SourceHintSizeKeys | "md" | sm, md, lg, xl | no | Size of the hint. Can be "sm", "md", "lg" or "xl". Default is "md". |
| testID (alias: data-testid) | string | "" | — | no | — |
| id | string | — | — | no | ID attribute for the hint element, useful for aria-describedby on form inputs. |
| role | string | — | — | no | ARIA role for the hint. Automatically set to "alert" when context is "error". |
| ariaLive | 'polite' \| 'assertive' \| 'off' | — | — | no | ARIA live region setting. Automatically set to "assertive" when context is "error". |

### SourceIconButtonComponent (@3dsource/source-ui-native)
**Selector:** `src-icon-button` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| name | unknown | — | — | no | Name of button. Could be used for form |
| type | SourceIconButtonTypeKeys | "button" | button, submit, reset | no | Type of button |
| appearance | SourceIconButtonAppearanceKeys | "filled" | filled, plain, inline | no | Set basic style of button |
| weight | SourceIconButtonWeightKeys | "secondary" | primary, secondary, ghost | no | Shows the importance of the button |
| size | SourceIconButtonSizeKeys | "md" | xs, sm, md, lg, xl, default | no | How big it should be? |
| shape | SourceIconButtonShapeKeys | "square" | square, round | no | Shape of button - square with rounded corners or round |
| context | SourceIconButtonContextKeys | "default" | default, error, success, info, warning | no | Color variation of button. Usually represent context of action. |
| counter | number \| undefined | "undefined" | — | no | Use counter attribute to display counter in the top right corner of the button. |
| isPressed | boolean | false | — | no | Standard active state for button |
| isInverted | boolean | false | — | no | — |
| isDisabled | boolean | false | — | no | Standard disabled state for button |
| testID (alias: data-testid) | string | "" | — | no | Test ID for querying the badge in tests. |
| ariaLabel | string | — | — | no | ARIA label for the button, required for accessibility since icon buttons have no visible text. |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| onClick | Event | Optional click handler |

### SourceLoadingComponent (@3dsource/source-ui-native)
**Selector:** `src-loading` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| size | number | 32 | — | no | Size of the loading circle in pixels. Do not set px - value will be transformed to pixels automatically. |
| progress | number \| null | "null" | — | no | Set the percentage of a process here to make loader works as a progressbar, or leave null to make it just an animated circle. |
| lineCap | SourceLoadingLineCapKeys | "round" | round, square, butt | no | The stroke-linecap attribute is a presentation attribute defining the shape to be used at the end of open subpaths when they are stroked. |
| backgroundStrokeColor | string | "transparent" | — | no | The color of the background line |
| progressStrokeColor | string | "var(--src-ui-accent-default, #017bffff)" | — | no | The color of the filled line. |
| strokeWidth | number | 3 | — | no | The width of the line in pixels. |
| testID (alias: data-testid) | string | "" | — | no | Test ID for querying the badge in tests. |
| role | string | — | — | no | ARIA role for the loader. Defaults to status (indeterminate) or progressbar (when progress is set). |
| ariaLabel | string | — | — | no | ARIA label for the loading indicator. |
| ariaValueNow | number | — | — | no | Current progress value for progressbar role. Automatically set from progress input. |
| ariaValueMin | number | — | — | no | Minimum value for progressbar role. |
| ariaValueMax | number | — | — | no | Maximum value for progressbar role. |

### SourceLogoLoadingComponent (@3dsource/source-ui-native)
**Selector:** `src-logo-loading` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| size | number | 32 | — | no | Size of the loading icon |
| strokeColor | string | "var(--src-ui-accent-default, #017bffff)" | — | no | The color of the stroke line. |
| testID (alias: data-testid) | string | "" | — | no | Test ID for querying the badge in tests. |
| role | string | "status" | — | no | ARIA role for the loading indicator. |
| ariaLabel | string | — | — | no | ARIA label for the loading indicator. |

### SourceModalElementComponent (@3dsource/source-ui-native)
**Selector:** `src-modal-element` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| ariaLabel | string | — | — | no | — |
| closeButtonLabel | string | "Close" | — | no | — |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| closeEvent | unknown | — |
| closed | void | — |

### SourceSliderComponent (@3dsource/source-ui-native)
**Selector:** `src-slider` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| id | string | — | — | no | ID of the input to connect the label and input[type=range]. |
| value | number | — | — | yes | The value of the slider. |
| min | number | — | — | yes | The minimum value of the range. |
| max | number | — | — | yes | The maximum value of the range. |
| thumbSize | number | 16 | — | no | The size of the thumb. |
| trackHeight | number | 4 | — | no | The height of the visual track. The height of the input will not be affected. |
| step | number | 1 | — | no | The step size of the slider. |
| showTicks | boolean | false | — | no | Whether to show ticks at each step. |
| isDisabled | boolean | false | — | no | Whether the slider is disabled. |
| orientation | 'horizontal' \| 'vertical' | "horizontal" | — | no | Orientation of the slider, either horizontal or vertical. |
| testID (alias: data-testid) | string | "" | — | no | Test ID for querying the slider in tests. |
| ariaLabel | string | — | — | no | ARIA label for the slider, used when there is no visible label. |
| ariaValueText | string | — | — | no | Custom text representation of the current value (e.g., 50C instead of 50). |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| onChange | number | Optional change event handler. |
| onInput | number | Optional input event handler. |

### Library: @3dsource/source-ui

### SourcePopoverTriggerComponent (@3dsource/source-ui)
**Selector:** `src-popover-trigger` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| srcPopoverTpl | TemplateRef<HTMLElement> | — | — | yes | — |
| headerTitle | string | — | — | no | — |
| activeClass | string | — | — | no | — |
| hasBackButton | boolean | false | — | no | — |
| hasCloseButton | boolean | true | — | no | — |
| hasBackdrop | boolean | true | — | no | — |
| closeOnBackdropClick | boolean | true | — | no | — |
| popoverMaxHeight | string | "auto" | — | no | — |
| panelCustomClass | string | — | — | no | — |
| testID (alias: data-testid) | string | "" | — | no | — |
| breakpointDesktop | string | "(min-width: 1024px)" | — | no | — |
| positions | ConnectedPosition[] | "[
    {
      originX: 'start',
      originY: 'bottom',
      overlayX: 'start',
      overlayY: 'top',
      offsetY: 4,
    },
    {
      originX: 'start',
      originY: 'top',
      overlayX: 'start',
      overlayY: 'bottom',
      offsetY: -8,
    },
  ]" | — | no | — |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| onPopoverShown | boolean | — |
| onBackButtonClick | OverlayRef | — |

### SourceSliderGroupComponent (@3dsource/source-ui)
**Selector:** `src-slider-group` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| min | number | — | — | yes | The minimum value of the range. |
| max | number | — | — | yes | The maximum value of the range. |
| value | number | — | — | yes | The value of the slider. |
| label | string | "" | — | no | — |
| id | string | "" | — | no | ID of the input to connect the label and input[type=range]. |
| step | number | 1 | — | no | The step size of the slider. |
| units | string | "%" | — | no | Units for input value (e.g., %, in, px). |
| showTicks | boolean | false | — | no | Whether to show ticks at each step. |
| showRange | boolean | false | — | no | Whether to show the range of the slider. |
| isDisabled | boolean | false | — | no | Whether the slider is disabled. |
| testID (alias: data-testid) | string | "" | — | no | Test ID for querying the slider in tests. |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| groupValueChange | number | Output event emitted when the slider value changes. |

### SourceTabLineComponent (@3dsource/source-ui)
**Selector:** `src-tab-line` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| tabs | any[] | — | — | yes | — |
| label | string | — | — | yes | — |
| selectedIndex | number | 0 | — | no | — |
| appearance | SourceTabAppearanceKeys | "default" | default, button | no | — |
| isCompact | boolean | false | — | no | — |
| offsetBefore | number \| undefined | "undefined" | — | no | — |
| offsetAfter | number \| undefined | "undefined" | — | no | — |
| spaceBetween | number \| undefined | "undefined" | — | no | — |
| isFullWidth | boolean | false | — | no | — |
| isSwiper | boolean | false | — | no | — |
| testID (alias: data-testid) | string | "" | — | no | — |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| onSelectTab | number | — |

### SourceTooltipDirective (@3dsource/source-ui)
**Selector:** `[srcTooltip]` · **Kind:** Directive

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| srcTooltip | string \| TemplateRef<void> | — | — | yes | The content to be displayed in the tooltip. It can be a string or a template reference. |
| srcTooltipPosition | SourceTooltipPositionKeys | "top" | top, bottom, left, right | no | The position of the tooltip relative to the target element. Possible values are top, bottom, left, right. |
| srcTooltipHideDelay | number | 0 | — | no | The delay in milliseconds before the tooltip is hidden after mouse leave or blur event. |
| srcTooltipMaxWidth | string | "280px" | — | no | The maximum width of the tooltip. It can be set to any valid CSS width value. |
| srcTooltipCustomClass | string | "" | — | no | An optional custom CSS class or classes to apply to the tooltip for additional styling. |
| sourceTooltipData | SourceTooltipData | — | — | no | Configuration object for the tooltip, allowing for dynamic data binding. |

### ColorPaletteComponent (@3dsource/source-ui)
**Selector:** `src-color-palette` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| selectedHex | string | — | — | yes | — |
| isNeedUpdatePalette | string \| null | — | — | yes | — |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| paletteColorUpdate | string | — |

### ColorSliderComponent (@3dsource/source-ui)
**Selector:** `src-color-slider` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| selectedHex | string | — | — | yes | — |
| orientation | SourceColorPickerOrientationKeys | — | horizontal, vertical | yes | — |
| sliderThickness | number | — | — | yes | — |
| isNeedUpdateSlider | string \| null | — | — | yes | — |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| sliderColorUpdate | string | — |

### SourceColorPickerComponent (@3dsource/source-ui)
**Selector:** `src-color-picker` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| selectedColor | string | — | — | yes | Set the selected color in HEX format. The default value is an empty string. |
| isCompact | boolean | false | — | no | Set the compact mode. The compact mode is used to reduce the size of the color picker. It is suggested to decrease the slider thickness as well. |
| orientation | SourceColorPickerOrientationKeys | "horizontal" | horizontal, vertical | no | Position of the hue slider. |
| hasInput | boolean | true | — | no | Set the visibility of the input field. |
| sliderThickness | number | 28 | — | no | Set the thickness of the hue slider. |
| testID (alias: data-testid) | string | "" | — | no | — |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| colorUpdate | string | Emits the selected color in HEX format when the color is changed. |

### SourceTabComponent (@3dsource/source-ui)
**Selector:** `src-tab` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| isActive | boolean | false | — | no | — |

### SourceTabsComponent (@3dsource/source-ui)
**Selector:** `src-tabs` · **Kind:** Component

**Inputs:**

| Input | Type | Default | Values | Required | Description |
|-------|------|---------|--------|----------|-------------|
| label | string | — | — | yes | Determines the key in tabs object which is responcible for tab label. |
| data | SourceTabData[] | — | — | yes | — |
| selectedIndex | number | 0 | — | no | Index of the tab that is selected. |
| headerTemplate | TemplateRef<any> | — | — | no | — |
| isCompact | boolean | false | — | no | If true, the tab line will have a more compact style with reduced padding and spacing. |
| isFullWidth | boolean | false | — | no | If true, the tab line will stretch to fill the available width. |
| isSwiper | boolean | false | — | no | If true, the tab line will be swipeable, allowing horizontal scrolling for overflow tabs. |
| swiperConfig | SwiperOptions | — | — | no | — |
| testID (alias: data-testid) | string | "" | — | no | A test identifier for the modal, useful for testing purposes. |

**Outputs:**

| Output | Type | Description |
|--------|------|-------------|
| onSelectTab | number | — |


## Source Elements (CSS-only styling)

Source Elements let you style standard HTML elements (`<button>`, `<input>`, `<select>`, etc.) using BEM CSS classes — no Angular component imports needed. Just add the class to a native HTML tag. All styles come from the `source.ui.native.scss` stylesheet.

- [Source Elements API (JSON)](./docs/api/source-elements.json): Machine-readable reference for all CSS-only elements with modifiers, sub-elements, and usage examples.

Use Source Elements when: you don't need Angular signal bindings, you want minimal overhead, or you're prototyping without Angular.

### Badge Element
Apply `src-badge` class to any appropriate HTML tag.
- **Context**: `src-badge--context-default` (default) | `src-badge--context-info` | `src-badge--context-success` | `src-badge--context-warning` | `src-badge--context-attention` | `src-badge--context-error`
- `src-badge__icon` — Prefix/postfix icon wrapper inside badge.
- Customise via CSS custom properties: `--srcBadgeBackgroundColor`, `--srcBadgeTextColor`.

### Banner Element
Apply `src-banner` class to any appropriate HTML tag.
- **Context**: `src-banner--context-info` | `src-banner--context-success` | `src-banner--context-warning` | `src-banner--context-error` | `src-banner--context-critical`
- `src-banner__icon-prefix` — Leading icon slot.
- `src-banner__icon-postfix` — Trailing icon slot (e.g. close button).
- `src-banner__title` — Uppercase bold title within the banner.
- `src-banner__content` — Main body content wrapper.

### Button Element
Apply `src-button` class to any appropriate HTML tag.
- **Weight**: `src-button--primary` | `src-button--secondary` (default) | `src-button--ghost`
- **Appearance**: `src-button--plain` | `src-button--inline`
- **Size**: `src-button--size-sm` | `src-button--size-md` (default) | `src-button--size-lg` | `src-button--size-xl` | `src-button--full-width`
- **Context**: `src-button--context-info` | `src-button--context-success` | `src-button--context-error`
- **State**: `src-button--pressed`
- [Demo](https://preview.3dsource.com/front-libraries/master/#/components/SourceButtonElement)

### Checkbox Element
Apply `src-checkbox` class to any appropriate HTML tag.
- `src-checkbox__label` — Text label beside the checkbox.
- [Demo](https://preview.3dsource.com/front-libraries/master/#/components/FormElements)

### Divider Element
Apply `src-divider` class to any appropriate HTML tag.
- Customise via CSS custom properties: `--srcDividerColor`, `--srcDividerThickness`, `--srcDividerOffsetTop`, `--srcDividerOffsetBottom`.

### Hint Element
Apply `src-hint` class to any appropriate HTML tag.
- **Context**: `src-hint--context-error` | `src-hint--context-info` | `src-hint--context-success` | `src-hint--error`
- `src-hint__icon` — Prefix icon slot.

### Icon Button Element
Apply `src-icon-button` class to any appropriate HTML tag.
- **Appearance**: `src-icon-button--plain` | `src-icon-button--inline`
- **Weight**: `src-icon-button--primary` | `src-icon-button--secondary` (default) | `src-icon-button--ghost`
- **Size**: `src-icon-button--size-sm` | `src-icon-button--size-md` (default) | `src-icon-button--size-lg` | `src-icon-button--size-xl`
- **Shape**: `src-icon-button--round`
- **Context**: `src-icon-button--context-info` | `src-icon-button--context-success` | `src-icon-button--context-warning` | `src-icon-button--context-error`
- **State**: `src-icon-button--pressed`
- [Demo](https://preview.3dsource.com/front-libraries/master/#/components/SourceIconButtonElement)

### Input Element
Apply `src-input` class to any appropriate HTML tag.
- **Weight**: `src-input--primary` (default) | `src-input--secondary` | `src-input--ghost`
- **Size**: `src-input--size-sm` | `src-input--size-md` (default) | `src-input--size-lg` | `src-input--size-xl`
- **Context**: `src-input--context-success` | `src-input--context-error`
- **State**: `src-input--disabled`
- [Demo](https://preview.3dsource.com/front-libraries/master/#/components/SourceInputElement)

### Label Element
Apply `src-label` class to any appropriate HTML tag.

### List Element
Apply `src-list` class to any appropriate HTML tag.
- **Size**: `src-list--compact`
- `src-list__item` — The main class for the list item element.
- `src-list__item--flex` — Class modifier for a flex list item. Use this when your content includes an icon or has a more complex structure. You can still style it in your CSS.
- `src-list__item--disabled` — List item disabled state. The "disabled" attribute is also supported.
- `src-list__item--selected` — Selected state for the list item.
- `src-list__item--context-error` — Visually distinct appearance to emphasize a critical action.
- [Demo](https://preview.3dsource.com/front-libraries/master/#/components/SourceListElement)

### Modal Element
Apply `src-modal` class to any appropriate HTML tag.
- `src-modal__header` — Header area with bottom border.
- `src-modal__body` — Scrollable content area with padding.
- `src-modal__body--icon` — Two-column grid layout (icon + content).
- `src-modal__icon` — Icon in the first column of icon-body layout.
- `src-modal__title` — Bold title text.
- `src-modal__scroll-box` — Scrollable content area spanning full grid width.
- `src-modal__footer` — Action buttons row, right-aligned, with top border.
- `src-modal__footer-group` — Button group within footer.
- `src-modal__close` — Absolutely positioned close button at top-right.

### Radio Group Element
Apply `src-radio-group` class to any appropriate HTML tag.
- **Layout**: `src-radio-group--horizontal`
- `src-radio` — Flex container for a single radio button. Wraps input[type="radio"] with custom appearance.
- `src-radio__label` — Text label beside the radio button.
- [Demo](https://preview.3dsource.com/front-libraries/master/#/components/FormElements)

### Select Element
Apply `src-select` class to any appropriate HTML tag.
- **Weight**: `src-select--primary` (default) | `src-select--secondary` | `src-select--ghost`
- **Size**: `src-select--size-sm` | `src-select--size-md` (default) | `src-select--size-lg` | `src-select--size-xl`
- **Context**: `src-select--context-success` | `src-select--context-error`
- **State**: `src-select--disabled`
- [Demo](https://preview.3dsource.com/front-libraries/master/#/components/SourceSelectElement)

### Textarea Element
Apply `src-textarea` class to any appropriate HTML tag.
- **Weight**: `src-textarea--secondary` | `src-textarea--ghost`
- **Size**: `src-textarea--size-sm` | `src-textarea--size-md` (default) | `src-textarea--size-lg` | `src-textarea--size-xl`
- **Context**: `src-textarea--context-success` | `src-textarea--context-error`
- **State**: `src-textarea--disabled`

### Toggle Element
Apply `src-toggle` class to any appropriate HTML tag.
- `src-toggle__label` — Text label beside the toggle.
- [Demo](https://preview.3dsource.com/front-libraries/master/#/components/FormElements)

## Stylesheet import paths

STRICT RULE: Use ONLY the paths listed below. Do NOT fabricate paths like `@3dsource/source-ui-native/src/lib/styles/...` or `dist/...`.

**SCSS import (Angular projects with a builder) — add to your `styles.scss`:**
```
// source-ui-native only:
@use '../node_modules/@3dsource/source-ui-native/styles/source.ui.native.scss' as source-ui-native;

// source-ui-native + source-ui (both):
@use '../node_modules/@3dsource/source-ui-native/styles/source.ui.native.scss' as source-ui-native;
@use '../node_modules/@3dsource/source-ui/styles/source.ui.scss' as source-ui;
```

**Compiled CSS import (non-Angular / CSS-only / no builder) — add to `<head>` or import in your bundler:**
```
node_modules/@3dsource/source-ui-native/styles/source-ui-native.min.css
```

IMPORTANT: SCSS entry files use dots in the name (`source.ui.native.scss`), while compiled CSS uses dashes (`source-ui-native.min.css`). Do not confuse them.

## Icons

The library is icon-agnostic — no icon font is bundled. Icons are projected into components via `<ng-content>` (Angular) or placed directly inside elements (CSS-only).

STRICT RULE: Do NOT use the Material Icons font (`<link href="https://fonts.google.com/icon?family=Material+Icons">` or the `material-icons` CSS class). The font-based icon approach conflicts with Source UI styles. Use **SVG icons** instead.

Recommended icon source: [Material Symbols (Rounded)](https://fonts.google.com/icons?icon.style=Rounded) with settings: Style Rounded, Weight 400, Fill On, Optical size 20dp.

### SVG icon setup (Angular projects)

1. Create an `assets/icons/` folder in your project.
2. Download SVG icons from your design or from [Material Symbols](https://fonts.google.com/icons?icon.style=Rounded).
3. In each SVG file: set `fill="currentColor"` (for CSS color control), remove `width`/`height` attributes, keep `viewBox`.
4. Create an `SvgIconComponent` in your project (this component is NOT part of the library — copy it into your codebase):

```typescript
import { HttpClient } from '@angular/common/http';
import { Component, effect, inject, input, signal, untracked } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { first } from 'rxjs';

@Component({
  selector: 'src-icon',
  imports: [],
  template: `@if (svg()) {
    <div [innerHTML]="svg()" class="src-icon" [style.--srcIconSize]="size()"></div>
  }`,
  styles: [`
    .src-icon { width: var(--srcIconSize); height: var(--srcIconSize); color: inherit; }
    .src-icon svg { width: 100%; height: 100%; fill: currentColor; }
  `],
})
export class SvgIconComponent {
  name = input<string>('');
  size = input<string>('20px');
  PATH_TO_ICON_FOLDER = 'assets/icons';
  svg = signal<SafeHtml | null>(null);
  http = inject(HttpClient);
  sanitizer = inject(DomSanitizer);

  _ = effect(() => {
    const path = this.PATH_TO_ICON_FOLDER + '/' + this.name() + '.svg';
    untracked(() => {
      this.http.get(path, { responseType: 'text' }).pipe(first()).subscribe({
        next: (rawSvg) => this.svg.set(this.sanitizer.bypassSecurityTrustHtml(rawSvg)),
        error: () => console.warn('Icon "' + this.name() + '" not found at ' + path),
      });
    });
  });
}
```

5. Usage: `<src-icon name="close"></src-icon>`, `<src-icon name="chevron_left" size="32px"></src-icon>`
6. Default size: `20px`. Color inherits from parent element.

### SVG icon setup (non-Angular / CSS-only projects)

Inline the SVG directly in your HTML:
```html
<button class="src-icon-button">
  <svg viewBox="0 0 24 24" fill="currentColor"><path d="..."/></svg>
</button>
```

### Icon design tokens

- `--src-icon-size` — default icon size (16px)
- `--src-icon-default`, `--src-icon-info`, `--src-icon-success`, `--src-icon-error`, `--src-icon-warning` — contextual icon colors

- [Icons documentation](https://preview.3dsource.com/front-libraries/master/#/icons)

## Material Form Components (source-ui)

`@3dsource/source-ui` provides custom styling for Angular Material form fields. These are NOT separate Angular components — the library overrides default Material styles when you import `source.ui.scss`. Styled Material components:
- `<mat-form-field>` with `<input matInput>` — text input
- `<mat-form-field>` with `<mat-select>` — dropdown select
- `<mat-form-field>` with `<input matInput [matAutocomplete]>` — autocomplete
- `<mat-checkbox>` — styled checkbox
- `<mat-radio-group>` / `<mat-radio-button>` — styled radio
- `<mat-slide-toggle>` — styled toggle

All Material form fields support the same sizing system as Source Elements via class modifiers on the `<mat-form-field>` tag. Default size is `md` (no class needed). Context state classes use `--context-` prefix: `--context-success`, `--context-error` (previously `--state-success` / `--state-error`).

- [Demo](https://preview.3dsource.com/front-libraries/master/#/components/FormComponents)

## Full component registry

- [Component Registry](./docs/api/_registry.json): Index of all 20 components across both libraries with selectors, kinds, and JSON file references

## Design Tokens (inline)

> Auto-generated from 1029 total tokens. Below is a curated subset of semantic tokens most useful for development. Full token data: design-tokens.json.

### primitives (scope: global)
Source: `variables/primitives/primitives.scss`

| Token | Value |
|-------|-------|
| --src-space-0 | 0px |
| --src-space-px | 1px |
| --src-space-0-5 | 2px |
| --src-space-1 | 4px |
| --src-space-1-5 | 6px |
| --src-space-2 | 8px |
| --src-space-2-5 | 10px |
| --src-space-3 | 12px |
| --src-space-3-5 | 14px |
| --src-space-4 | 16px |
| --src-space-5 | 20px |
| --src-space-6 | 24px |
| --src-space-7 | 28px |
| --src-space-8 | 32px |
| --src-space-9 | 36px |
| --src-space-10 | 40px |
| --src-space-11 | 44px |
| --src-space-12 | 48px |
| --src-space-14 | 56px |
| --src-space-16 | 64px |
| --src-space-20 | 80px |
| --src-space-24 | 96px |
| --src-space-28 | 112px |
| --src-space-32 | 128px |
| --src-space-36 | 144px |
| --src-space-40 | 160px |
| --src-space-44 | 176px |
| --src-space-48 | 192px |
| --src-space-52 | 208px |
| --src-space-56 | 224px |
| --src-space-60 | 240px |
| --src-space-64 | 256px |
| --src-space-72 | 288px |
| --src-space-80 | 320px |
| --src-space-96 | 384px |
| --src-color-primary-50 | #f1f6ffff |
| --src-color-primary-100 | #d6e9ffff |
| --src-color-primary-200 | #add4ffff |
| --src-color-primary-300 | #7dbbffff |
| --src-color-primary-400 | #4ea4ffff |
| --src-color-primary-500 | #017bffff |
| --src-color-primary-600 | #016fe6ff |
| --src-color-primary-700 | #0162ccff |
| --src-color-primary-800 | #014ca3ff |
| --src-color-primary-900 | #003a7aff |
| --src-color-primary-950 | #00244dff |
| --src-color-alpha-accent-10 | #017bff14 |
| --src-color-alpha-accent-50 | #017bff1f |
| --src-color-alpha-accent-100 | #017bff29 |
| --src-color-alpha-accent-200 | #017bff3d |
| --src-color-alpha-accent-300 | #017bff52 |
| --src-color-alpha-accent-400 | #017bff5c |

### color-light (scope: global)
Source: `variables/color/light.scss`

| Token | Value |
|-------|-------|
| --src-surface-background | var(--src-color-grey-50) |
| --src-surface-background-inverse | var(--src-color-grey-800) |
| --src-ui-accent-default | var(--src-color-primary-500) |
| --src-ui-accent-default-hover | var(--src-color-primary-600) |
| --src-ui-accent-disabled | var(--src-color-alpha-test-200) |
| --src-ui-accent-success | var(--src-color-green-500) |
| --src-ui-accent-success-hover | var(--src-color-green-600) |
| --src-ui-accent-error | var(--src-color-red-500) |
| --src-ui-accent-error-hover | var(--src-color-red-600) |
| --src-ui-accent-active | var(--src-color-grey-700) |
| --src-ui-accent-active-hover | var(--src-color-grey-900) |
| --src-ui-secondary-default | var(--src-color-alpha-default-10) |
| --src-ui-secondary-default-hover | var(--src-color-alpha-default-50) |
| --src-ui-secondary-disabled | var(--src-color-alpha-white-10) |
| --src-ui-secondary-active | var(--src-color-alpha-accent-50) |
| --src-ui-secondary-info | var(--src-color-alpha-accent-10) |
| --src-ui-secondary-info-hover | var(--src-color-alpha-accent-50) |
| --src-ui-secondary-success | var(--src-color-alpha-success-10) |
| --src-ui-secondary-success-hover | var(--src-color-alpha-success-50) |
| --src-ui-secondary-error | var(--src-color-alpha-destruct-10) |
| --src-ui-secondary-error-hover | var(--src-color-alpha-destruct-100) |
| --src-ui-secondary-progress | var(--color-alpha-progress-10) |
| --src-ui-input-default | var(--src-color-alpha-white-10) |
| --src-ui-input-secondary | var(--src-color-alpha-default-10) |
| --src-ui-input-hover | var(--src-color-alpha-accent-10) |
| --src-ui-input-disabled | var(--src-color-alpha-default-50) |
| --src-ui-input-success | var(--src-color-alpha-white-10) |
| --src-ui-input-success-hover | var(--src-color-alpha-success-10) |
| --src-ui-input-error | var(--src-color-alpha-white-10) |
| --src-ui-input-error-hover | var(--src-color-alpha-destruct-10) |
| --src-surface-curtain | var(--src-color-alpha-default-600) |
| --src-surface-fade | var(--src-color-alpha-white-600) |
| --src-surface-bg | var(--src-color-alpha-default-200) |
| --src-ui-light | var(--src-light) |
| --src-border-control-default | var(--src-color-neutral-300) |
| --src-border-control-hover | var(--src-color-neutral-500) |
| --src-border-button-basic | var(--src-color-grey-200) |
| --src-border-button-basic-hover | var(--src-color-grey-400) |
| --src-border-button-info | var(--src-color-primary-300) |
| --src-border-button-info-hover | var(--src-color-primary-500) |
| --src-border-button-success | var(--src-color-green-400) |
| --src-border-button-success-hover | var(--src-color-green-500) |
| --src-border-button-error | var(--src-color-red-300) |
| --src-border-button-error-hover | var(--src-color-red-500) |
| --src-border-button-disabled | var(--src-color-grey-200) |
| --src-border-input-basic | var(--src-color-grey-300) |
| --src-border-input-hover | var(--src-color-grey-400) |
| --src-border-input-filled | var(--src-color-grey-300) |
| --src-border-input-active | var(--src-color-primary-500) |
| --src-border-input-success | var(--src-color-green-500) |
| --src-border-input-success-hover | var(--src-color-green-600) |
| --src-border-input-error | var(--src-color-red-500) |
| --src-border-input-error-hover | var(--src-color-red-500) |
| --src-border-container-basic | var(--src-color-grey-300) |
| --src-border-container-hover | var(--src-color-grey-400) |
| --src-border-container-light | var(--src-color-alpha-default-50) |
| --src-border-container-active | var(--src-color-primary-400) |
| --src-border-container-success | var(--src-color-green-200) |
| --src-border-container-error | var(--src-color-red-200) |
| --src-text-body-main | var(--src-color-grey-900) |
| --src-text-body-secondary | var(--src-color-grey-600) |
| --src-text-body-grey | var(--src-color-grey-400) |
| --src-text-body-lable | var(--src-color-grey-500) |
| --src-text-body-disabled | var(--src-color-grey-400) |
| --src-text-body-main-invert | var(--src-color-grey-50) |
| --src-text-body-secondary-invert | var(--src-color-grey-300) |
| --src-icon-default | var(--src-color-grey-700) |
| --src-icon-label | var(--src-color-grey-500) |
| --src-icon-hover | var(--src-color-grey-900) |
| --src-icon-grey | var(--src-color-grey-400) |
| --src-icon-disabled | var(--src-color-grey-400) |
| --src-icon-main-invert | var(--src-light) |
| --src-icon-secondary-invert | var(--src-color-grey-200) |
| --src-icon-info | var(--src-color-primary-500) |
| --src-icon-info-hover | var(--src-color-primary-600) |
| --src-icon-success | var(--src-color-green-600) |
| --src-icon-success-hover | var(--src-color-green-700) |
| --src-icon-error | var(--src-color-red-500) |
| --src-icon-error-hover | var(--src-color-red-600) |
| --src-icon-warning | var(--src-color-tertiary-600) |
| --src-icon-warning-hover | var(--src-color-tertiary-700) |
| --src-icon-attention | var(--src-color-yellow-800) |
| --src-icon-attention-hover | var(--src-color-yellow-900) |
| --src-graphics-positive | var(--src-color-green-500) |
| --src-graphics-negative | var(--src-color-red-500) |
| --src-graphics-accent | var(--src-color-primary-500) |
| --src-graphics-dark-grey | var(--src-color-grey-500) |
| --src-graphics-orange | #f5a80fff |
| --src-graphics-yellow | #f0e442ff |
| --src-graphics-turquoise | #00ced1ff |
| --src-graphics-brown | #8b4513ff |
| --src-graphics-black | var(--src-color-grey-700) |
| --src-text-body-accent | var(--src-color-primary-600) |
| --src-text-body-success | var(--src-color-green-600) |
| --src-text-body-destruct | var(--src-color-red-600) |
| --src-text-ui-primary-main | var(--src-light) |
| --src-text-ui-primary-secondary | var(--src-color-grey-200) |
| --src-text-ui-primary-disabled | var(--src-color-grey-400) |
| --src-text-ui-primary-main-invert | var(--src-color-grey-50) |
| --src-text-ui-primary-secondary-invert | var(--src-color-grey-200) |
| --src-text-ui-secondary-main | var(--src-color-grey-900) |
| --src-text-ui-secondary-secondary | var(--src-color-grey-600) |
| --src-text-ui-secondary-grey | var(--src-color-grey-400) |
| --src-text-ui-secondary-disabled | var(--src-color-grey-400) |
| --src-text-ui-secondary-main-invert | var(--src-color-grey-50) |
| --src-text-ui-secondary-secondary-invert | var(--src-color-grey-300) |
| --src-shadow-hard | var(--src-color-alpha-test-200) |
| --src-shadow-light | var(--src-color-alpha-default-50) |
| --src-shadow-accent-light | var(--src-color-alpha-accent-100) |
| --src-shadow-accent-hard | var(--src-color-alpha-accent-200) |
| --src-shadow-success | var(--src-color-alpha-success-50) |
| --src-shadow-success-hover | var(--src-color-alpha-success-200) |
| --src-shadow-error | var(--src-color-alpha-destruct-100) |
| --src-shadow-error-hover | var(--src-color-alpha-destruct-200) |
| --src-text-ui-accent-main | var(--src-color-primary-600) |
| --src-text-ui-accent-hover | var(--src-color-primary-700) |
| --src-text-ui-success-main | var(--src-color-green-600) |
| --src-text-ui-success-hover | var(--src-color-green-700) |
| --src-text-ui-distruct-main | var(--src-color-red-500) |
| --src-text-ui-distruct-hover | var(--src-color-red-600) |
| --src-surface-container-main | var(--src-light) |
| --src-surface-container-on-top | var(--src-color-alpha-default-10) |
| --src-surface-container-secondary | var(--src-color-grey-50) |
| --src-surface-container-info | var(--src-color-primary-50) |
| --src-surface-container-success | var(--src-color-green-50) |
| --src-surface-container-error | var(--src-color-red-50) |
| --src-surface-toast-basic | var(--src-color-alpha-default-50) |
| --src-surface-toast-info | var(--src-color-primary-600) |
| --src-surface-toast-success | var(--src-color-green-600) |
| --src-surface-toast-error | var(--src-color-red-500) |
| --src-border-infoPrompt-basic | var(--src-color-grey-300) |
| --src-border-infoPrompt-light | var(--src-color-alpha-default-50) |
| --src-border-infoPrompt-info | var(--src-color-primary-200) |
| --src-border-infoPrompt-success | var(--src-color-green-200) |
| --src-border-infoPrompt-error | var(--src-color-red-200) |
| --src-gradient-light-start | var(--src-color-alpha-test-100) |
| --src-gradient-light-end | var(--src-color-alpha-default-10) |
| --src-gradient-accent-light | var(--src-color-alpha-accent-10) |
| --src-gradient-accent-hard | var(--src-color-alpha-accent-50) |
| --src-gradient-success | var(--color-alpha-success-50) |
| --src-gradient-success-hover | var(--color-alpha-success-200) |
| --src-gradient-error | var(--color-alpha-destruct-100) |
| --src-gradient-error-hover | var(--color-alpha-destruct-200) |
| --src-tech-sticker | var(--src-color-tertiary-100) |
| --wireframe-main | var(--src-color-neutral-600) |
| --wireframe-secondary | var(--src-color-neutral-500) |
| --wireframe-light | var(--src-color-neutral-300) |
| --wireframe-surface-primary | var(--src-light) |
| --wireframe-surface-secondary | var(--src-color-alpha-default-50) |
| --wireframe-border | var(--src-color-alpha-default-200) |
| --wireframe-invert | var(--src-light) |
| --src-tech-description | var(--src-color-tertiary-900) |
| --src-light | #ffffffff |
| --src-dark | #000000ff |
| --src-ui-status-basic-neutral | var(--src-color-grey-500) |
| --src-ui-status-basic-neutral-hover | var(--src-color-grey-600) |
| --src-ui-status-basic-critical | var(--src-color-red-500) |
| --src-ui-status-basic-critical-hover | var(--src-color-red-600) |
| --src-ui-status-basic-info | var(--src-color-primary-500) |
| --src-ui-status-basic-info-hover | var(--src-color-primary-600) |
| --src-ui-status-basic-success | var(--src-color-green-500) |
| --src-ui-status-basic-success-hover | var(--src-color-green-500) |
| --src-ui-status-basic-warning | var(--src-color-tertiary-500) |
| --src-ui-status-basic-warning-hover | var(--src-color-tertiary-600) |
| --src-ui-status-basic-attention | var(--src-color-yellow-500) |
| --src-ui-status-basic-attention-hover | var(--src-color-yellow-600) |
| --src-ui-status-light-neutral | var(--src-color-alpha-default-100) |
| --src-ui-status-light-neutral-hover | var(--src-color-alpha-default-200) |
| --src-ui-status-light-critical | var(--src-color-alpha-destruct-100) |
| --src-ui-status-light-critical-hover | var(--src-color-alpha-destruct-200) |
| --src-ui-status-light-info | var(--src-color-alpha-accent-200) |
| --src-ui-status-light-info-hover | var(--src-color-alpha-accent-300) |
| --src-ui-status-light-success | var(--src-color-alpha-success-100) |
| --src-ui-status-light-success-hover | var(--src-color-alpha-success-200) |
| --src-ui-status-light-warning | var(--src-color-alpha-warning-200) |
| --src-ui-status-light-warning-hover | var(--src-color-alpha-warning-300) |
| --src-ui-status-light-attention | var(--src-color-alpha-attention-200) |
| --src-ui-status-light-attention-hover | var(--src-color-alpha-attention-300) |
| --src-text-ui-warning-main | var(--src-color-tertiary-600) |
| --src-text-ui-warning-hover | var(--src-color-tertiary-700) |
| --src-text-ui-attention-main | var(--src-color-yellow-800) |
| --src-text-ui-attention-hover | var(--src-color-yellow-900) |

### color-dark (scope: global)
Source: `variables/color/dark.scss`

| Token | Value |
|-------|-------|
| --src-surface-background | var(--src-color-grey-900) |
| --src-surface-background-inverse | var(--src-color-grey-800) |
| --src-ui-accent-default | var(--src-color-primary-400) |
| --src-ui-accent-default-hover | var(--src-color-primary-500) |
| --src-ui-accent-disabled | var(--src-color-alpha-white-100) |
| --src-ui-accent-success | var(--src-color-green-600) |
| --src-ui-accent-success-hover | var(--src-color-green-500) |
| --src-ui-accent-error | var(--src-color-red-600) |
| --src-ui-accent-error-hover | var(--src-color-red-500) |
| --src-ui-accent-active | var(--src-color-grey-200) |
| --src-ui-accent-active-hover | var(--src-color-grey-50) |
| --src-ui-secondary-default | var(--src-color-alpha-white-50) |
| --src-ui-secondary-default-hover | var(--src-color-alpha-default-100) |
| --src-ui-secondary-disabled | var(--src-color-alpha-default-100) |
| --src-ui-secondary-active | var(--src-color-alpha-accent-100) |
| --src-ui-secondary-info | var(--src-color-alpha-accent-200) |
| --src-ui-secondary-info-hover | var(--src-color-alpha-accent-100) |
| --src-ui-secondary-success | var(--src-color-alpha-success-200) |
| --src-ui-secondary-success-hover | var(--src-color-alpha-success-50) |
| --src-ui-secondary-error | var(--src-color-alpha-destruct-200) |
| --src-ui-secondary-error-hover | var(--src-color-alpha-destruct-100) |
| --src-ui-secondary-progress | var(--src-color-alpha-progress-10) |
| --src-ui-input-default | var(--src-color-alpha-white-10) |
| --src-ui-input-secondary | var(--src-color-alpha-default-200) |
| --src-ui-input-hover | var(--src-color-alpha-default-200) |
| --src-ui-input-disabled | var(--src-color-alpha-default-200) |
| --src-ui-input-success | var(--src-color-alpha-white-10) |
| --src-ui-input-success-hover | var(--src-color-alpha-success-50) |
| --src-ui-input-error | var(--src-color-alpha-white-10) |
| --src-ui-input-error-hover | var(--src-color-alpha-destruct-50) |
| --src-surface-curtain | var(--src-color-alpha-default-600) |
| --src-surface-fade | var(--src-color-alpha-default-200) |
| --src-surface-bg | var(--src-color-alpha-white-50) |
| --src-ui-light | var(--src-dark) |
| --src-border-control-default | var(--src-color-neutral-300) |
| --src-border-control-hover | var(--src-color-neutral-100) |
| --src-border-button-basic | var(--src-color-grey-600) |
| --src-border-button-basic-hover | var(--src-color-grey-500) |
| --src-border-button-info | var(--src-color-primary-500) |
| --src-border-button-info-hover | var(--src-color-primary-400) |
| --src-border-button-success | var(--src-color-green-700) |
| --src-border-button-success-hover | var(--src-color-green-600) |
| --src-border-button-error | var(--src-color-red-500) |
| --src-border-button-error-hover | var(--src-color-red-600) |
| --src-border-button-disabled | var(--src-color-grey-800) |
| --src-border-input-basic | var(--src-color-grey-700) |
| --src-border-input-hover | var(--src-color-grey-500) |
| --src-border-input-filled | var(--src-color-grey-700) |
| --src-border-input-active | var(--src-color-primary-500) |
| --src-border-input-success | var(--src-color-green-600) |
| --src-border-input-success-hover | var(--src-color-green-400) |
| --src-border-input-error | var(--src-color-red-700) |
| --src-border-input-error-hover | var(--src-color-red-700) |
| --src-border-container-basic | var(--src-color-grey-800) |
| --src-border-container-hover | var(--src-color-grey-600) |
| --src-border-container-light | var(--src-color-alpha-white-50) |
| --src-border-container-active | var(--src-color-primary-500) |
| --src-border-container-success | var(--src-color-green-800) |
| --src-border-container-error | var(--src-color-red-800) |
| --src-text-body-main | var(--src-color-grey-50) |
| --src-text-body-secondary | var(--src-color-grey-300) |
| --src-text-body-grey | var(--src-color-grey-400) |
| --src-text-body-lable | var(--src-color-grey-300) |
| --src-text-body-disabled | var(--src-color-grey-500) |
| --src-text-body-main-invert | var(--src-color-grey-900) |
| --src-text-body-secondary-invert | var(--src-color-grey-600) |
| --src-icon-default | var(--src-color-grey-200) |
| --src-icon-label | var(--src-color-grey-400) |
| --src-icon-hover | var(--src-color-grey-50) |
| --src-icon-grey | var(--src-color-grey-400) |
| --src-icon-disabled | var(--src-color-grey-600) |
| --src-icon-main-invert | var(--src-light) |
| --src-icon-secondary-invert | var(--src-color-grey-200) |
| --src-icon-info | var(--src-color-primary-500) |
| --src-icon-info-hover | var(--src-color-primary-400) |
| --src-icon-success | var(--src-color-green-500) |
| --src-icon-success-hover | var(--src-color-green-400) |
| --src-icon-error | var(--src-color-red-400) |
| --src-icon-error-hover | var(--src-color-red-300) |
| --src-icon-warning | var(--src-color-tertiary-400) |
| --src-icon-warning-hover | var(--src-color-tertiary-300) |
| --src-icon-attention | var(--src-color-yellow-400) |
| --src-icon-attention-hover | var(--src-color-yellow-600) |
| --src-graphics-positive | var(--src-color-green-400) |
| --src-graphics-negative | var(--src-color-red-400) |
| --src-graphics-accent | var(--src-color-primary-500) |
| --src-graphics-dark-grey | var(--src-color-grey-400) |
| --src-graphics-orange | #ffb92dff |
| --src-graphics-yellow | #f0e442ff |
| --src-graphics-turquoise | #00ced1ff |
| --src-graphics-brown | #8b4513ff |
| --src-graphics-black | var(--src-color-grey-200) |
| --src-text-body-accent | var(--src-color-primary-400) |
| --src-text-body-success | var(--src-color-green-400) |
| --src-text-body-destruct | var(--src-color-red-400) |
| --src-text-ui-primary-main | var(--src-light) |
| --src-text-ui-primary-secondary | var(--src-color-grey-200) |
| --src-text-ui-primary-disabled | var(--src-color-grey-400) |
| --src-text-ui-primary-main-invert | var(--src-color-grey-900) |
| --src-text-ui-primary-secondary-invert | var(--src-color-grey-700) |
| --src-text-ui-secondary-main | var(--src-color-grey-50) |
| --src-text-ui-secondary-secondary | var(--src-color-grey-200) |
| --src-text-ui-secondary-grey | var(--src-color-grey-400) |
| --src-text-ui-secondary-disabled | var(--src-color-grey-500) |
| --src-text-ui-secondary-main-invert | var(--src-color-grey-900) |
| --src-text-ui-secondary-secondary-invert | var(--src-color-grey-600) |
| --src-shadow-hard | var(--src-color-alpha-dark-100) |
| --src-shadow-light | var(--src-color-alpha-dark-50) |
| --src-shadow-accent-light | var(--src-color-alpha-accent-300) |
| --src-shadow-accent-hard | var(--src-color-alpha-accent-400) |
| --src-shadow-success | var(--src-color-alpha-success-200) |
| --src-shadow-success-hover | var(--src-color-alpha-success-50) |
| --src-shadow-error | var(--src-color-alpha-destruct-200) |
| --src-shadow-error-hover | var(--src-color-alpha-destruct-100) |
| --src-text-ui-accent-main | var(--src-color-primary-400) |
| --src-text-ui-accent-hover | var(--src-color-primary-300) |
| --src-text-ui-success-main | var(--src-color-green-400) |
| --src-text-ui-success-hover | var(--src-color-green-300) |
| --src-text-ui-distruct-main | var(--src-color-red-400) |
| --src-text-ui-distruct-hover | var(--src-color-red-300) |
| --src-surface-container-main | var(--src-color-grey-800) |
| --src-surface-container-on-top | var(--src-color-alpha-white-10) |
| --src-surface-container-secondary | var(--src-color-basic-black) |
| --src-surface-container-info | var(--src-color-blue-950) |
| --src-surface-container-success | var(--src-color-green-950) |
| --src-surface-container-error | var(--src-color-red-950) |
| --src-surface-toast-basic | var(--src-color-alpha-default-200) |
| --src-surface-toast-info | var(--src-color-primary-400) |
| --src-surface-toast-success | var(--src-color-green-400) |
| --src-surface-toast-error | var(--src-color-red-400) |
| --src-border-infoPrompt-basic | var(--src-color-grey-800) |
| --src-border-infoPrompt-light | var(--src-color-alpha-white-50) |
| --src-border-infoPrompt-info | var(--src-color-primary-800) |
| --src-border-infoPrompt-success | var(--src-color-green-800) |
| --src-border-infoPrompt-error | var(--src-color-red-800) |
| --src-gradient-light-start | var(--src-color-alpha-dark-200) |
| --src-gradient-light-end | var(--src-color-alpha-dark-100) |
| --src-gradient-accent-light | var(--src-color-alpha-accent-300) |
| --src-gradient-accent-hard | var(--src-color-alpha-accent-400) |
| --src-gradient-success | var(--src-color-alpha-success-200) |
| --src-gradient-success-hover | var(--src-color-alpha-success-50) |
| --src-gradient-error | var(--src-color-alpha-destruct-200) |
| --src-gradient-error-hover | var(--src-color-alpha-destruct-100) |
| --src-tech-sticker | var(--src-color-tertiary-800) |
| --wireframe-main | var(--src-color-neutral-300) |
| --wireframe-secondary | var(--src-color-neutral-400) |
| --wireframe-light | var(--src-color-neutral-500) |
| --wireframe-surface-primary | var(--src-dark) |
| --wireframe-surface-secondary | var(--src-color-alpha-white-50) |
| --wireframe-border | var(--src-color-alpha-white-100) |
| --wireframe-invert | var(--src-dark) |
| --src-tech-description | var(--src-color-tertiary-50) |
| --src-light | #ffffffff |
| --src-dark | #ffffffff |
| --src-ui-status-basic-neutral | var(--src-color-alpha-white-100) |
| --src-ui-status-basic-neutral-hover | var(--src-color-alpha-white-600) |
| --src-ui-status-basic-critical | var(--src-color-alpha-success-100) |
| --src-ui-status-basic-critical-hover | var(--src-color-alpha-success-50) |
| --src-ui-status-basic-info | var(--src-color-alpha-accent-300) |
| --src-ui-status-basic-info-hover | var(--src-color-alpha-accent-200) |
| --src-ui-status-basic-success | var(--src-color-alpha-success-200) |
| --src-ui-status-basic-success-hover | var(--src-color-alpha-success-100) |
| --src-ui-status-basic-warning | var(--src-color-alpha-warning-300) |
| --src-ui-status-basic-warning-hover | var(--src-color-alpha-warning-200) |
| --src-ui-status-basic-attention | var(--src-color-alpha-attention-300) |
| --src-ui-status-basic-attention-hover | var(--src-color-alpha-attention-200) |
| --src-ui-status-light-neutral | var(--src-color-alpha-white-100) |
| --src-ui-status-light-neutral-hover | var(--src-color-alpha-white-600) |
| --src-ui-status-light-critical | var(--src-color-alpha-success-100) |
| --src-ui-status-light-critical-hover | var(--src-color-alpha-success-50) |
| --src-ui-status-light-info | var(--src-color-alpha-accent-300) |
| --src-ui-status-light-info-hover | var(--src-color-alpha-accent-200) |
| --src-ui-status-light-success | var(--src-color-alpha-success-200) |
| --src-ui-status-light-success-hover | var(--src-color-alpha-success-100) |
| --src-ui-status-light-warning | var(--src-color-alpha-warning-300) |
| --src-ui-status-light-warning-hover | var(--src-color-alpha-warning-200) |
| --src-ui-status-light-attention | var(--src-color-alpha-attention-300) |
| --src-ui-status-light-attention-hover | var(--src-color-alpha-attention-200) |
| --src-text-ui-warning-main | var(--src-color-tertiary-400) |
| --src-text-ui-warning-hover | var(--src-color-tertiary-500) |
| --src-text-ui-attention-main | var(--src-color-tertiary-200) |
| --src-text-ui-attention-hover | var(--src-color-tertiary-100) |

### typeface (scope: global)
Source: `variables/typeface/web.scss`

| Token | Value |
|-------|-------|
| --src-font-family-header | Inter |
| --src-font-family-body | Inter |
| --src-font-family-mono | PT Mono |
| --src-font-weight-bold | Bold |
| --src-font-weight-semiBold | SemiBold |
| --src-font-weight-medium | Medium |
| --src-font-weight-regular | Regular |
| --src-font-size-tech | 9px |
| --src-font-size-xs | 12px |
| --src-font-size-sm | 14px |
| --src-font-size-base | 16px |
| --src-font-size-md | 20px |
| --src-font-size-lg | 24px |
| --src-font-size-xl | 28px |
| --src-font-size-2xl | 32px |
| --src-font-size-3xl | 40px |
| --src-font-line-tech | 12px |
| --src-font-size-4xl | 48px |
| --src-font-line-xs | 16px |
| --src-font-line-sm | 20px |
| --src-font-line-base | 24px |
| --src-font-line-md | 28px |
| --src-font-line-lg | 32px |
| --src-font-line-xl | 36px |
| --src-font-line-2xl | 44px |
| --src-font-line-3xl | 52px |
| --src-font-line-4xl | 56px |
| --src-font-spacing-tech | 1.2000000476837158px |
| --src-font-spacing-xl | -0.20000000298023224px |
| --src-font-spacing-2xl | -0.30000001192092896px |
| --src-font-spacing-3xl | -0.5px |
| --src-font-spacing-4xl | -1px |

### ui-md (scope: global)
Source: `variables/ui/_md.scss`

| Token | Value |
|-------|-------|
| --src-media-thumbnail | 48px |
| --src-media-preview | 1024px |
| --src-padding-xs | var(--src-space-2) |
| --src-padding-sm | var(--src-space-3) |
| --src-padding-md | var(--src-space-4) |
| --src-padding-lg | var(--src-space-5) |
| --src-padding-xl | var(--src-space-7) |
| --src-height-xs | var(--src-space-4) |
| --src-icon-size | var(--src-space-5) |
| --src-icon-line-width | 1.440000057220459px |
| --src-height-sm | var(--src-space-5) |
| --src-border-border | 1px |
| --src-border-rounded-none | 0px |
| --src-height-base | var(--src-space-9) |
| --src-height-lg | 52px |
| --src-border-rounded-xs | var(--src-space-1) |
| --src-border-rounded | var(--src-space-1-5) |
| --src-border-rounded-parent | var(--src-space-2-5) |
| --src-border-rounded-lg | var(--src-space-4) |
| --src-border-rounded-full | 9999px |
| --src-gap-md | var(--src-space-1-5) |
| --src-text-lineHeight | var(--src-font-line-sm) |
| --src-gap-xl | var(--src-space-3-5) |
| --src-text-fontSize | var(--src-font-size-sm) |
| --src-text-weight-base | var(--src-font-weight-medium) |
| --src-gap-lg | var(--src-space-2-5) |
| --src-gap-none | 0px |
| --src-gap-sm | var(--src-space-1) |
| --src-text-weight-bold | var(--src-font-weight-bold) |
| --src-text-weight-medium | var(--src-font-weight-semiBold) |
| --src-shadow-focused | var(--src-space-1) |
| --src-shadow-ambient-inner | -1px |
| --src-shadow-ambient-inner-light | 1px |
| --src-shadow-ambient-outer | 1px |
| --src-shadow-blur | 1px |

### layout-md (scope: @media (min-width: 768px))
Source: `variables/layout/_md.scss`

| Token | Value |
|-------|-------|
| --src-layout-padding-const-xs | var(--src-space-1) |
| --src-layout-padding-const-sm | var(--src-space-2) |
| --src-layout-padding-const-md | var(--src-space-3) |
| --src-layout-padding-const-lg | var(--src-space-4) |
| --src-layout-padding-const-xl | var(--src-space-6) |
| --src-layout-padding-const-2xl | var(--src-space-8) |
| --src-layout-padding-var-xs | var(--src-space-2) |
| --src-layout-padding-table-sm | var(--src-space-3) |
| --src-layout-padding-var-sm | var(--src-space-3) |
| --src-layout-padding-var-md | var(--src-space-4) |
| --src-layout-padding-var-lg | var(--src-space-5) |
| --src-layout-padding-var-xl | var(--src-space-8) |
| --src-layout-padding-var-2xl | var(--src-space-11) |
| --src-layout-gap-const-none | 0px |
| --src-layout-gap-const-xs | var(--src-space-1) |
| --src-layout-gap-const-sm | var(--src-space-2) |
| --src-layout-gap-const-md | var(--src-space-3) |
| --src-layout-gap-const-lg | var(--src-space-4) |
| --src-layout-gap-const-xl | var(--src-space-6) |
| --src-layout-gap-const-2xl | var(--src-space-8) |
| --src-layout-gap-var-none | 0px |
| --src-layout-gap-var-sm | var(--src-space-2) |
| --src-layout-gap-var-md | var(--src-space-3) |
| --src-layout-gap-var-lg | var(--src-space-4) |
| --src-layout-gap-var-xl | var(--src-space-8) |
| --src-layout-height-const-sm | var(--src-space-7) |
| --src-layout-height-const-md | var(--src-space-8) |
| --src-layout-height-const-lg | var(--src-space-9) |
| --src-layout-height-const-h-xl | var(--src-space-10) |
| --src-layout-height-const-h-2xl | var(--src-space-16) |
| --src-layout-height-var-xs | var(--src-space-8) |
| --src-layout-height-var-sm | var(--src-space-10) |
| --src-layout-height-var-base | var(--src-space-20) |
| --src-layout-height-var-md | var(--src-space-28) |
| --src-layout-height-var-lg | var(--src-space-24) |
| --src-layout-height-var-xl | var(--src-space-36) |
| --src-layout-radius-var-rounded-kid | var(--src-space-2) |
| --src-layout-radius-var-rounded-parent | var(--src-space-3) |
| --src-layout-radius-rounded-none | 0px |
| --src-layout-border-border | 1px |
| --src-layout-table-height | var(--src-space-14) |
| --src-layout-radius-const-rounded-sm | var(--src-space-1-5) |
| --src-layout-radius-const-rounded | var(--src-space-2) |
| --src-layout-radius-const-rounded-md | var(--src-space-3) |
| --src-layout-radius-const-rounded-lg | var(--src-space-4) |
| --src-layout-radius-const-rounded-xl | var(--src-space-6) |
| --src-layout-radius-const-rounded-2xl | var(--src-space-8) |
| --src-layout-radius-rounded-ui-full | 9999px |
| --src-shadow-basic | var(--src-space-1-5) |
| --src-graphs-label | var(--src-space-2) |
| --src-graphs-label-var | var(--src-space-2-5) |
| --src-graphs-height-label-var | var(--src-space-7) |
| --src-graphs-height-label-const | var(--src-space-5) |
| --src-graphs-height-s | var(--src-space-8) |
| --screen-width | 768px |
| --card-width | 320px |
| --preview-width | 216px |
| --src-typography-var-p-sm-fontSize | var(--src-font-size-sm) |
| --src-typography-var-p-sm-weight | var(--src-font-weight-regular) |
| --src-typography-var-p-sm-lineHeight | var(--src-font-line-sm) |
| --src-typography-var-p-md-fontSize | var(--src-font-size-base) |
| --src-typography-var-p-md-weight | var(--src-font-weight-regular) |
| --src-typography-var-p-md-lineHeight | var(--src-font-line-base) |
| --src-typography-var-h-sm-fontSize | var(--src-font-size-md) |
| --src-typography-var-h-sm-weight | var(--src-font-weight-semiBold) |
| --src-typography-var-h-sm-lineHeight | var(--src-font-line-md) |
| --src-typography-var-h-md-fontSize | var(--src-font-size-lg) |
| --src-typography-var-h-md-weight | var(--src-font-weight-semiBold) |
| --src-typography-var-h-md-lineHeight | var(--src-font-line-lg) |
| --src-typography-var-h-lg-fontSize | var(--src-font-size-xl) |
| --src-typography-var-h-lg-weight | var(--src-font-weight-semiBold) |
| --src-typography-var-h-lg-lineHeight | var(--src-font-line-xl) |
| --src-typography-var-h-xl-fontSize | var(--src-font-size-3xl) |
| --src-typography-var-h-xl-weight | var(--src-font-weight-semiBold) |
| --src-typography-var-h-xl-lineHeight | var(--src-font-line-3xl) |
| --src-typography-var-p-lg-fontSize | var(--src-font-size-lg) |
| --src-typography-var-p-lg-weight | var(--src-font-weight-regular) |
| --src-typography-var-p-lg-lineHeight | var(--src-font-line-lg) |

## Demo site

- [Live demo site](https://preview.3dsource.com/front-libraries/master/): Interactive examples of all components with live code snippets (uses HashLocationStrategy — routes like `/#/components/SourceButtonComponent`)

## Optional

- [Full component registry JSON](./docs/api/_registry.json): Machine-readable index for programmatic discovery
