Tokens
The --nyte-* custom properties every primitive paints with
Primitives paint with --nyte-* custom properties only. Override one on an ancestor, ideally the
app root.
.my-app {
--nyte-color-primary: #3b5bdb;
}Import @nyte-ai/ui/styles.css for the tokens plus the Tailwind mapping, or
@nyte-ai/ui/platform-tokens.css for the tokens alone.
Colors are light-dark() pairs, so a primitive follows the color-scheme in effect rather than a
class. See Theming. --nyte-color-focus-ring defaults to
var(--nyte-color-ring) and is the one token a host changes at runtime. See
Focus.
Color
Semantic roles, not a palette. primary is the filled button, muted is the hover wash and the
avatar background, border has four strengths, and bubble-* and sidebar belong to the
conversation surface.
| Token | Value |
|---|---|
--nyte-color-base | light-dark(#141414, #fcfcfc) |
--nyte-color-editor | light-dark(#fcfcfc, #181818) |
--nyte-color-chrome | light-dark(#eeeeee, #262626) |
--nyte-color-sidebar | light-dark(#f7f7f7, #141414) |
--nyte-color-raised | light-dark(#fcfcfc, #2f2f2f) |
--nyte-color-fill | light-dark(#070707, #fafafa) |
--nyte-color-fill-label | light-dark(#fcfcfc, #141414) |
--nyte-color-action-label | #fcfcfc |
--nyte-color-scrim-base | #141414 |
--nyte-color-accent-base | #1084fe |
--nyte-color-hue-neutral | #777777 |
--nyte-color-hue-red | #ff263c |
--nyte-color-hue-orange | #ff6700 |
--nyte-color-hue-violet | #9159fe |
--nyte-color-hue-green | #00c972 |
--nyte-color-accent | light-dark(#0c64c1, #459ffe) |
--nyte-color-success | light-dark(#009957, #38d591) |
--nyte-color-warning | light-dark(#c27400, #ffaf38) |
--nyte-color-destructive | light-dark(#c21d2e, #ff5667) |
--nyte-color-avatar-foreground | light-dark(#3d3d3d, #b7b7b7) |
--nyte-color-avatar-orange-foreground | light-dark(#c24e00, #ff8838) |
--nyte-color-avatar-violet-foreground | light-dark(#6e44c1, #a97efe) |
--nyte-color-bubble-user | light-dark(#070707, #5a5a5a) |
--nyte-color-background | var(--nyte-color-editor) |
--nyte-color-popover | var(--nyte-color-editor) |
--nyte-color-field-background | var(--nyte-color-raised) |
--nyte-color-bubble-agent | var(--nyte-color-chrome) |
--nyte-color-foreground | var(--nyte-color-base) |
--nyte-color-popover-foreground | var(--nyte-color-base) |
--nyte-color-muted-foreground | color-mix(in srgb, var(--nyte-color-base) 60%, transparent) |
--nyte-color-tertiary-foreground | color-mix(in srgb, var(--nyte-color-base) 36%, transparent) |
--nyte-color-primary | var(--nyte-color-fill) |
--nyte-color-primary-hover | color-mix(in srgb, var(--nyte-color-editor) 16%, var(--nyte-color-fill)) |
--nyte-color-primary-foreground | var(--nyte-color-fill-label) |
--nyte-color-bubble-user-foreground | var(--nyte-color-action-label) |
--nyte-color-secondary | light-dark(color-mix(in srgb, var(--nyte-color-hue-neutral) 4%, transparent), color-mix(in srgb, var(--nyte-color-hue-neutral) 8%, transparent)) |
--nyte-color-muted | light-dark(color-mix(in srgb, var(--nyte-color-hue-neutral) 9%, transparent), color-mix(in srgb, var(--nyte-color-hue-neutral) 17%, transparent)) |
--nyte-color-muted-hover | light-dark(color-mix(in srgb, var(--nyte-color-hue-neutral) 17%, transparent), color-mix(in srgb, var(--nyte-color-hue-neutral) 32%, transparent)) |
--nyte-color-destructive-muted | light-dark(color-mix(in srgb, var(--nyte-color-hue-red) 9%, transparent), color-mix(in srgb, var(--nyte-color-hue-red) 17%, transparent)) |
--nyte-color-destructive-hover | light-dark(color-mix(in srgb, var(--nyte-color-hue-red) 17%, transparent), color-mix(in srgb, var(--nyte-color-hue-red) 32%, transparent)) |
--nyte-color-scrim | light-dark(color-mix(in srgb, var(--nyte-color-scrim-base) 50%, transparent), color-mix(in srgb, var(--nyte-color-scrim-base) 70%, transparent)) |
--nyte-color-border-subtle | color-mix(in srgb, var(--nyte-color-base) 4%, transparent) |
--nyte-color-border-weak | color-mix(in srgb, var(--nyte-color-base) 8%, transparent) |
--nyte-color-border | color-mix(in srgb, var(--nyte-color-base) 12%, transparent) |
--nyte-color-border-strong | color-mix(in srgb, var(--nyte-color-base) 30%, transparent) |
--nyte-color-ring | color-mix(in srgb, var(--nyte-color-base) 40%, transparent) |
--nyte-color-focus-ring | var(--nyte-color-ring) |
--nyte-color-avatar-background | var(--nyte-color-muted) |
--nyte-color-avatar-neutral-solid | var(--nyte-color-hue-neutral) |
--nyte-color-avatar-orange-background | light-dark(color-mix(in srgb, var(--nyte-color-hue-orange) 9%, transparent), color-mix(in srgb, var(--nyte-color-hue-orange) 17%, transparent)) |
--nyte-color-avatar-orange-solid | var(--nyte-color-hue-orange) |
--nyte-color-avatar-blue-background | light-dark(color-mix(in srgb, var(--nyte-color-accent-base) 9%, transparent), color-mix(in srgb, var(--nyte-color-accent-base) 17%, transparent)) |
--nyte-color-avatar-blue-foreground | var(--nyte-color-accent) |
--nyte-color-avatar-blue-solid | var(--nyte-color-accent-base) |
--nyte-color-avatar-violet-background | light-dark(color-mix(in srgb, var(--nyte-color-hue-violet) 9%, transparent), color-mix(in srgb, var(--nyte-color-hue-violet) 17%, transparent)) |
--nyte-color-avatar-violet-solid | var(--nyte-color-hue-violet) |
--nyte-color-avatar-green-background | light-dark(color-mix(in srgb, var(--nyte-color-hue-green) 9%, transparent), color-mix(in srgb, var(--nyte-color-hue-green) 17%, transparent)) |
--nyte-color-avatar-green-foreground | var(--nyte-color-success) |
--nyte-color-avatar-green-solid | var(--nyte-color-hue-green) |
Font
One UI family and a five-step scale. label and body share a size and line height, so labels
stay aligned with the fields beside them.
| Token | Value |
|---|---|
--nyte-font-family-ui | -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif |
--nyte-font-size-caption | 11px |
--nyte-font-size-detail | 12px |
--nyte-font-size-label | 13px |
--nyte-font-size-body | 13px |
--nyte-font-size-title | 14px |
--nyte-font-weight-regular | 400 |
--nyte-font-weight-medium | 500 |
--nyte-font-weight-semibold | 600 |
| Token | Value |
|---|---|
--nyte-leading-caption | 14px |
--nyte-leading-detail | 16px |
--nyte-leading-label | 18px |
--nyte-leading-body | 18px |
--nyte-leading-title | 22px |
Radius
avatar is a percentage, so it scales with the size steps. pill is the circle.
| Token | Value |
|---|---|
--nyte-radius-control | 8px |
--nyte-radius-field | 8px |
--nyte-radius-menu | 10px |
--nyte-radius-dialog | 14px |
--nyte-radius-avatar | 42% |
--nyte-radius-pill | 9999px |
Control
The geometry of anything you press or type into. height-md (28px) is the default button and
input height, height-sm (24px) the compact button and the icon button. menu-inset is the left
padding that leaves room for a radio or checkbox indicator.
| Token | Value |
|---|---|
--nyte-control-height-sm | 24px |
--nyte-control-height-md | 28px |
--nyte-control-textarea-min-height | 64px |
--nyte-control-padding-xs | 6px |
--nyte-control-padding-sm | 8px |
--nyte-control-padding-lg | 12px |
--nyte-control-menu-inset | 28px |
--nyte-control-gap-sm | 4px |
--nyte-control-disabled-opacity | 0.56 |
--nyte-control-focus-width | 1px |
--nyte-control-focus-offset | 1px |
Border
| Token | Value |
|---|---|
--nyte-border-control-width | 1px |
--nyte-border-hairline-width | .5px |
Avatar
| Token | Value |
|---|---|
--nyte-avatar-size-xs | 20px |
--nyte-avatar-size-sm | 24px |
--nyte-avatar-size-md | 28px |
--nyte-avatar-size-lg | 36px |
--nyte-avatar-font-xs | 9px |
--nyte-avatar-font-sm | 10px |
--nyte-avatar-font-md | 11px |
--nyte-avatar-font-lg | 14px |
--nyte-avatar-ring-width | .5px |
Space
Three steps. Layout spacing belongs to the app.
| Token | Value |
|---|---|
--nyte-space-1 | 4px |
--nyte-space-2 | 8px |
--nyte-space-4 | 16px |
Motion
fast for state changes on controls, normal for popups. Every primitive collapses its transition
to 0s under prefers-reduced-motion: reduce.
| Token | Value |
|---|---|
--nyte-motion-fast | 100ms |
--nyte-motion-normal | 160ms |
--nyte-motion-ease-out | cubic-bezier(.2,.8,.2,1) |
Elevation
| Token | Value |
|---|---|
--nyte-elevation-field | 0 1px 3px 0 light-dark(#0000001f, #00000000) |
--nyte-elevation-menu | 0 10px 20px -3px light-dark(#0000001a, #00000000), 0 4px 6px -4px light-dark(#0000001a, #00000000), 0 0 0 1px light-dark(#e4e4e40a, #e4e4e400) |
--nyte-elevation-dialog | 0 22px 70px 4px light-dark(#0000008f, #00000000), 0 0 0 .5px light-dark(#0000001a, #00000000) |
Overlay
Sizes and stacking for dialogs and menus. --nyte-menu-max-width and --nyte-menu-max-height read
Base UI's --available-width and --available-height, which the Positioner sets from the viewport.
| Token | Value |
|---|---|
--nyte-dialog-width | calc(100% - 32px) |
--nyte-dialog-max-width | 384px |
--nyte-dialog-max-height | calc(100dvh - 32px) |
| Token | Value |
|---|---|
--nyte-menu-min-width | 160px |
--nyte-menu-max-width | var(--available-width) |
--nyte-menu-max-height | var(--available-height) |
| Token | Value |
|---|---|
--nyte-layer-dialog | 50 |
--nyte-layer-menu | 60 |
Tailwind mapping
@nyte-ai/ui/tailwind.css maps tokens into Tailwind v4's @theme inline, so utilities resolve to
the same variables.
| Tailwind token | Reads |
|---|---|
--font-sans | --nyte-font-family-ui |
--color-primary | --nyte-color-primary |
--color-muted | --nyte-color-muted |
--color-border | --nyte-color-border |
--color-ring | --nyte-color-ring |
--text-body | --nyte-font-size-body |
--text-body--line-height | --nyte-leading-body |
--radius-sm, --radius-md | --nyte-radius-control |
--radius-lg | --nyte-radius-menu |
--radius-xl | --nyte-radius-dialog |