# 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. **Requires Angular 20+** due to the `ngx-scrollbar` dependency chain. 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`, `ngx-scrollbar >=19.0.0` (effectively requires Angular 20+), `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 |
| 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 | 12 | — | no | The size of the thumb. |
| trackHeight | number | 2 | — | 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
