Color
The semantic color tokens every Helios UI component is built from - foreground, text, background, and border roles, with shared semantic roles.
How the system works
Colors have two layers. Primitives define the raw palette. Semantic tokens describe the purpose of a color: text, foreground, background, border and state. Components consume semantic roles, keeping the visual language consistent across controls and complete screens. These roles live in the shared theme.css stylesheet.
Changing a theme remaps the same roles to light or dark values. Components keep their structure and behavior while their colors update together. The website uses the audited reference palette; the separate Helios Figma library is not edited by these controls. The .dark boundary remaps values while component classes stay the same.
Use the full token name in your application instead of copying a raw hex value. The same role then follows your selected theme and accent, making changes predictable across component states. Compose roles such as text-text-primary and bg-background-primary-default inside the shared theme boundary.
One token system, two themes
Add .dark to the theme boundary. Every semantic role updates together while component layouts and behavior stay consistent.
Map each theme
Keep light values in :root and dark values in .dark.
Use semantic colors
Use tokens such as bg-background-primary-default instead of raw colors.
Keep it centralized
Avoid component-specific dark: overrides, keeping changes predictable.
One accent, every CTA
Buttons, checkboxes, radios, switches, sliders, tabs, selected navigation and focus rings share the same accent ramp. Choose a hue to update the component system.
Foreground
Icon fills and inverse/on-color foregrounds - everything drawn on top of a surface that isn't running text.
text-foreground-fullwhiteneutral-700text-foreground-icon-primaryneutral-950neutral-50text-foreground-icon-hoverblackwhitetext-foreground-icon-secondaryneutral-500neutral-500text-foreground-icon-tertiaryneutral-400neutral-600text-foreground-icon-quaternaryneutral-300neutral-700text-foreground-icon-errorred-600red-400text-foreground-icon-disabledneutral-300neutral-800text-foreground-disabledneutral-400neutral-700text-foreground-disabled-dangerred-300red-400text-input-disabled-foregroundneutral-300neutral-600text-icon-button-disabled-foregroundneutral-300neutral-500Text
The type hierarchy: primary for headings and key values, secondary for supporting copy, tertiary for hints, plus disabled and error states.
text-text-primaryneutral-950neutral-50text-text-secondaryneutral-500neutral-500text-text-tertiaryneutral-400neutral-600text-text-disabledneutral-300neutral-800text-text-disabled-dangerred-300red-300text-text-error-primaryred-500red-400text-input-disabled-textneutral-300neutral-500 / 40%placeholder:text-text-placeholderneutral-400neutral-400text-text-whitewhitewhitetext-text-error-placeholderred-400red-400Background
Surface fills. Full is the outer canvas; primary, secondary, and tertiary describe progressively nested surfaces and their interaction states.
bg-background-fullwhiteneutral-925 (#121212)bg-background-primary-defaultwhiteneutral-800bg-background-inner-defaultwhiteneutral-800 / 60%bg-background-primary-hoverneutral-100neutral-700 / 60%bg-background-primary-activeneutral-200neutral-800bg-background-primary-disabledneutral-100neutral-800bg-input-disabled-backgroundneutral-100neutral-800 / 30%bg-background-secondary-defaultneutral-100neutral-900bg-background-secondary-hoverneutral-200neutral-800bg-background-tertiary-defaultneutral-200neutral-800bg-background-tertiary-hoverneutral-300neutral-700bg-background-tertiary-errorred-100red-950 / 60%bg-avatar-neutral-backgroundneutral-300background/primary/defaultbg-background-quaternary-defaultneutral-300neutral-300bg-background-quaternary-hoverneutral-400neutral-400bg-background-quaternary-errorred-200red-200bg-notification-center-backgroundwhiteneutral-900bg-segmented-control-backgroundneutral-100neutral-925 (#121212)bg-theme-toggle-sidebar-backgroundneutral-200neutral-800bg-theme-toggle-sidebar-selected-backgroundwhiteneutral-700Border
Hairlines and focus rings. Button borders step darker through hover and active; the focus ring is the single blue accent.
border-border-button-defaultneutral-200neutral-700border-border-button-hoverneutral-300neutral-500border-border-button-activeneutral-400neutral-600border-border-button-whitewhitezinc-800border-border-checkbox-defaultneutral-300neutral-700border-border-checkbox-hoverneutral-400neutral-500border-border-checkbox-activeneutral-400neutral-500border-border-component-detail-containerneutral-200neutral-800border-border-ai-profile-cardneutral-200neutral-800border-border-tableneutral-200neutral-800border-border-button-groupneutral-200neutral-600 / 60%border-border-sidebar-profile-hoverneutral-300neutral-600border-separator-borderneutral-200neutral-800border-separator-border-strongneutral-200neutral-700 / 60%ring-border-focus-ringblue-500blue-500Graphs
Chart colors. Track is the background bar/ring behind a series, cursor the hover outline and dashed reference line, neutral an “other”-style data slice. The numbered accents are a categorical ramp — each pairs a base fill with a one-tone-darker active used for hover emphasis (the 400 → 500 recipe every chart follows). In charts these are consumed as CSS variables (e.g. fill=“var(--color-chart-1)”) rather than classes.
bg-chart-trackneutral-200neutral-800bg-chart-cursorneutral-300neutral-700bg-chart-neutralneutral-300neutral-800bg-chart-1teal-400teal-400bg-chart-1-activeteal-500teal-500bg-chart-2lime-400lime-400bg-chart-2-activelime-500lime-500bg-chart-3pink-400pink-400bg-chart-3-activepink-500pink-500bg-chart-4sky-400sky-400bg-chart-4-activesky-500sky-500bg-chart-5purple-400purple-400bg-chart-5-activepurple-500purple-500bg-chart-6blue-400blue-400bg-chart-6-activeblue-500blue-500bg-chart-7emerald-400emerald-400bg-chart-7-activeemerald-500emerald-500bg-chart-8yellow-400yellow-400bg-chart-8-activeyellow-500yellow-500bg-chart-agents-barpurple-300purple-500bg-chart-agents-bar-activepurple-400purple-600State
Semantic feedback colors whose meaning stays stable across themes.
text-state-success-textlime-800lime-800bg-state-success-baselime-200lime-200bg-button-ghost-backgroundblue-100blue-900bg-button-ghost-hoverblue-200blue-800bg-button-ghost-activeblue-300blue-700text-button-ghost-foregroundblue-700blue-300bg-notification-information-backgroundblue-100blue-800 / 50%bg-notification-success-backgroundlime-100lime-800 / 50%bg-notification-error-backgroundrose-100rose-800 / 50%bg-badge-neutral-backgroundneutral-200neutral-800bg-team-menu-count-backgroundneutral-200neutral-700text-team-menu-count-foregroundneutral-500neutral-400bg-tab-count-selected-backgroundblue-100blue-800 / 60%bg-status-lime-backgroundlime-200lime-950 / 60%text-status-lime-textlime-800lime-500bg-status-yellow-backgroundyellow-200yellow-950 / 60%text-status-yellow-textyellow-800yellow-500bg-status-rose-backgroundrose-200rose-950 / 60%text-status-rose-textrose-800rose-500bg-status-cyan-backgroundcyan-200cyan-950 / 60%text-status-cyan-textcyan-800cyan-400bg-status-blue-backgroundblue-200blue-950 / 60%text-status-blue-textblue-800blue-300bg-status-purple-backgroundpurple-100purple-900 / 50%text-status-purple-textpurple-600purple-300bg-status-dot-green-halogreen-100green-800 / 40%bg-status-dot-yellow-haloyellow-200yellow-800 / 40%bg-status-dot-indigo-haloindigo-100indigo-800 / 40%