Design tokens
Every colour, size, radius, shadow, duration and layer in Hololink UI is a CSS custom property. The source of truth is packages/ui/src/styles/settings/tokens.css. The tables on this page are generated from that file, so they always match what ships.
Two tiers
Section titled “Two tiers”| Tier | Prefix | Role | Who may use it |
|---|---|---|---|
| Primitive | --p-* |
Raw values with no meaning, such as --p-color-indigo-600. |
Only tokens.css, to define --s-* |
| Semantic | --s-* |
Contextual roles that remap per theme, such as --s-color-bg-interactive. |
Components, stories, docs, your app |
Primitives say what a value is. Semantic tokens say what it is for. A semantic token points at a primitive, and themed colours point at a different primitive in light and dark. That indirection is what lets you re-brand or support dark mode by changing the semantic layer only.
/* Primitive: a raw value */--p-color-indigo-600: #4f46e5;
/* Semantic: a role, mapped per theme */--s-color-bg-interactive: light-dark(var(--p-color-indigo-600), var(--p-color-indigo-400));- Consume
--s-*tokens, never--p-*and never literals such as#4f46e5,16pxor150ms. - If no semantic token covers your need, add one to
tokens.cssand map it to a primitive. Do not reach for a primitive. - Per-component hooks are named
--holo-<component>-<prop>and fall back to a semantic token:var(--holo-text-field-bg, var(--s-color-bg-surface)). Override hooks, not component internals. - Theme by overriding
--s-*on:rootor any container. See Theming and dark mode.
Semantic tokens
Section titled “Semantic tokens”Colour
Section titled “Colour”Values show the light and dark branches of light-dark(). Swatches follow the live theme. See Colour for usage guidance.
| Token | Value | Preview |
|---|---|---|
--s-color-bg-app | Light #f8fafcDark #020617 | |
--s-color-bg-surface | Light #ffffffDark #0f172a | |
--s-color-bg-surface-hover | Light #f1f5f9Dark #1e293b | |
--s-color-bg-interactive | Light #4f46e5Dark #818cf8 | |
--s-color-bg-interactive-hover | Light #4338caDark #a5b4fc | |
--s-color-bg-inverse | Light #0f172aDark #f1f5f9 | |
--s-color-bg-backdrop | Light color-mix(in srgb, #0f172a 50%, transparent)Dark color-mix(in srgb, #020617 70%, transparent) | |
--s-color-text-primary | Light #0f172aDark #f8fafc | |
--s-color-text-secondary | Light #475569Dark #cbd5e1 | |
--s-color-text-tertiary | Light #5d6b82Dark #94a3b8 | |
--s-color-text-on-interactive | Light #ffffffDark #020617 | |
--s-color-text-inverse | Light #f8fafcDark #0f172a | |
--s-color-text-link | Light #4f46e5Dark #818cf8 | |
--s-color-text-link-hover | Light #4338caDark #a5b4fc | |
--s-color-border-subtle | Light #e2e8f0Dark #1e293b | |
--s-color-border-strong | Light #cbd5e1Dark #334155 | |
--s-color-border-control | #64748b | |
--s-color-border-interactive | Light #6366f1Dark #818cf8 | |
--s-color-status-success | Light #047857Dark #34d399 | |
--s-color-status-success-bg | Light #ecfdf5Dark #022c22 | |
--s-color-status-warning | Light #b45309Dark #fbbf24 | |
--s-color-status-warning-bg | Light #fffbebDark #451a03 | |
--s-color-status-danger | Light #b91c1cDark #f87171 | |
--s-color-status-danger-bg | Light #fef2f2Dark #450a0a | |
--s-color-status-info | Light #1d4ed8Dark #60a5fa | |
--s-color-status-info-bg | Light #eff6ffDark #172554 | |
--s-color-accent-glow | color-mix(in srgb, #6366f1 40%, transparent) | |
--s-color-accent-grid | color-mix(in srgb, #6366f1 8%, transparent) | |
--s-color-accent-grid-strong | color-mix(in srgb, #6366f1 20%, transparent) |
Colour previews use the live theme. Switch the site theme to see the dark values.
Typography
Section titled “Typography”| Token | Value | Preview |
|---|---|---|
--s-font-sans | 'Outfit', 'Inter', system-ui, -apple-system, sans-serif | Aa Bb 0123 |
--s-font-mono | 'JetBrains Mono', 'Fira Code', monospace | Aa Bb 0123 |
--s-font-size-caption | 0.75rem | Aa |
--s-font-size-label | 0.875rem | Aa |
--s-font-size-body | 1rem | Aa |
--s-font-size-lead | 1.125rem | Aa |
--s-font-size-title | 1.25rem | Aa |
--s-font-size-headline | 1.5rem | Aa |
--s-font-size-display | 1.875rem | Aa |
Spacing
Section titled “Spacing”| Token | Value | Preview |
|---|---|---|
--s-space-2xs | 0.25rem | |
--s-space-xs | 0.5rem | |
--s-space-sm | 0.75rem | |
--s-space-md | 1rem | |
--s-space-lg | 1.5rem | |
--s-space-xl | 2rem | |
--s-space-inset | 1rem | |
--s-space-stack-sm | 0.5rem | |
--s-space-stack-md | 1rem | |
--s-space-stack-lg | 2rem | |
--s-space-inline-sm | 0.5rem | |
--s-space-inline-md | 1rem |
| Token | Value | Preview |
|---|---|---|
--s-radius-subtle | 0.25rem | |
--s-radius-interactive | 0.375rem | |
--s-radius-container | 0.75rem | |
--s-radius-pill | 9999px |
Shadows
Section titled “Shadows”| Token | Value | Preview |
|---|---|---|
--s-shadow-depth-1 | 0 1px 2px 0 rgba(0, 0, 0, 0.05) | |
--s-shadow-depth-2 | 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1) | |
--s-shadow-depth-3 | 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1) | |
--s-shadow-depth-4 | 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1) | |
--s-shadow-glass | 0 8px 32px 0 rgba(31, 38, 135, 0.07) |
Motion
Section titled “Motion”Hover a row to play the transition.
| Token | Value | Preview |
|---|---|---|
--s-duration-fast | 150ms | |
--s-duration-normal | 250ms | |
--s-duration-slow | 350ms |
| Token | Value | Preview |
|---|---|---|
--s-easing-standard | cubic-bezier(0.4, 0, 0.2, 1) | |
--s-easing-bounce | cubic-bezier(0.34, 1.56, 0.64, 1) |
| Token | Value | Preview |
|---|---|---|
--s-transition-smooth | 250ms cubic-bezier(0.4, 0, 0.2, 1) | |
--s-transition-pop | 150ms cubic-bezier(0.34, 1.56, 0.64, 1) |
Z-index
Section titled “Z-index”| Token | Value | Preview |
|---|---|---|
--s-z-index-dropdown | 100 | layer 100 |
--s-z-index-sticky | 200 | layer 200 |
--s-z-index-overlay | 300 | layer 300 |
--s-z-index-modal | 400 | layer 400 |
--s-z-index-popover | 500 | layer 500 |
Primitive tokens
Section titled “Primitive tokens”Primitives are listed so you can map a value back to its source. Do not use them in components or application code.
Show primitive tokens
Neutral colours
Section titled “Neutral colours”| Token | Value | Preview |
|---|---|---|
--p-color-neutral-0 | #ffffff | |
--p-color-neutral-50 | #f8fafc | |
--p-color-neutral-100 | #f1f5f9 | |
--p-color-neutral-200 | #e2e8f0 | |
--p-color-neutral-300 | #cbd5e1 | |
--p-color-neutral-400 | #94a3b8 | |
--p-color-neutral-500 | #64748b | |
--p-color-neutral-550 | #5d6b82 | |
--p-color-neutral-600 | #475569 | |
--p-color-neutral-700 | #334155 | |
--p-color-neutral-800 | #1e293b | |
--p-color-neutral-900 | #0f172a | |
--p-color-neutral-950 | #020617 |
Indigo (brand)
Section titled “Indigo (brand)”| Token | Value | Preview |
|---|---|---|
--p-color-indigo-50 | #eef2ff | |
--p-color-indigo-100 | #e0e7ff | |
--p-color-indigo-200 | #c7d2fe | |
--p-color-indigo-300 | #a5b4fc | |
--p-color-indigo-400 | #818cf8 | |
--p-color-indigo-500 | #6366f1 | |
--p-color-indigo-600 | #4f46e5 | |
--p-color-indigo-700 | #4338ca | |
--p-color-indigo-800 | #3730a3 | |
--p-color-indigo-900 | #312e81 | |
--p-color-indigo-950 | #1e1b4b |
Status palettes
Section titled “Status palettes”| Token | Value | Preview |
|---|---|---|
--p-color-green-50 | #ecfdf5 | |
--p-color-green-400 | #34d399 | |
--p-color-green-500 | #10b981 | |
--p-color-green-700 | #047857 | |
--p-color-green-950 | #022c22 |
| Token | Value | Preview |
|---|---|---|
--p-color-amber-50 | #fffbeb | |
--p-color-amber-400 | #fbbf24 | |
--p-color-amber-500 | #f59e0b | |
--p-color-amber-700 | #b45309 | |
--p-color-amber-950 | #451a03 |
| Token | Value | Preview |
|---|---|---|
--p-color-red-50 | #fef2f2 | |
--p-color-red-400 | #f87171 | |
--p-color-red-500 | #ef4444 | |
--p-color-red-700 | #b91c1c | |
--p-color-red-950 | #450a0a |
| Token | Value | Preview |
|---|---|---|
--p-color-blue-50 | #eff6ff | |
--p-color-blue-400 | #60a5fa | |
--p-color-blue-500 | #3b82f6 | |
--p-color-blue-700 | #1d4ed8 | |
--p-color-blue-950 | #172554 |
Deprecated feedback colours
Section titled “Deprecated feedback colours”--p-color-success, --p-color-warning, --p-color-danger and --p-color-info are kept so existing code does not break. They fail AA contrast as text. Use --s-color-status-* instead.
| Token | Value | Preview |
|---|---|---|
--p-color-success | #10b981 |
| Token | Value | Preview |
|---|---|---|
--p-color-warning | #f59e0b |
| Token | Value | Preview |
|---|---|---|
--p-color-danger | #ef4444 |
| Token | Value | Preview |
|---|---|---|
--p-color-info | #3b82f6 |
| Token | Value | Preview |
|---|---|---|
--p-font-family-sans | 'Outfit', 'Inter', system-ui, -apple-system, sans-serif | Aa Bb 0123 |
--p-font-family-mono | 'JetBrains Mono', 'Fira Code', monospace | Aa Bb 0123 |
--p-font-size-xs | 0.75rem | Aa |
--p-font-size-sm | 0.875rem | Aa |
--p-font-size-base | 1rem | Aa |
--p-font-size-lg | 1.125rem | Aa |
--p-font-size-xl | 1.25rem | Aa |
--p-font-size-2xl | 1.5rem | Aa |
--p-font-size-3xl | 1.875rem | Aa |
--p-font-size-4xl | 2.25rem | Aa |
Spacing
Section titled “Spacing”| Token | Value | Preview |
|---|---|---|
--p-space-0 | 0 | |
--p-space-1 | 0.25rem | |
--p-space-2 | 0.5rem | |
--p-space-3 | 0.75rem | |
--p-space-4 | 1rem | |
--p-space-5 | 1.25rem | |
--p-space-6 | 1.5rem | |
--p-space-8 | 2rem | |
--p-space-10 | 2.5rem | |
--p-space-12 | 3rem | |
--p-space-16 | 4rem |
| Token | Value | Preview |
|---|---|---|
--p-radius-none | 0 | |
--p-radius-sm | 0.25rem | |
--p-radius-md | 0.375rem | |
--p-radius-lg | 0.5rem | |
--p-radius-xl | 0.75rem | |
--p-radius-2xl | 1rem | |
--p-radius-full | 9999px |
Shadows
Section titled “Shadows”| Token | Value | Preview |
|---|---|---|
--p-shadow-sm | 0 1px 2px 0 rgba(0, 0, 0, 0.05) | |
--p-shadow-md | 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1) | |
--p-shadow-lg | 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1) | |
--p-shadow-xl | 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1) | |
--p-shadow-glass | 0 8px 32px 0 rgba(31, 38, 135, 0.07) |
Transitions
Section titled “Transitions”| Token | Value | Preview |
|---|---|---|
--p-transition-duration-fast | 150ms | |
--p-transition-duration-normal | 250ms | |
--p-transition-duration-slow | 350ms | |
--p-transition-timing-ease | cubic-bezier(0.4, 0, 0.2, 1) | |
--p-transition-timing-bounce | cubic-bezier(0.34, 1.56, 0.64, 1) |
Z-index
Section titled “Z-index”| Token | Value | Preview |
|---|---|---|
--p-z-index-under | -1 | layer -1 |
--p-z-index-normal | 1 | layer 1 |
--p-z-index-dropdown | 100 | layer 100 |
--p-z-index-sticky | 200 | layer 200 |
--p-z-index-overlay | 300 | layer 300 |
--p-z-index-modal | 400 | layer 400 |
--p-z-index-popover | 500 | layer 500 |