Theming
The token system — primitives, semantic layer, dark mode, and brand overrides.
Asteria's theming is a two-layer CSS custom property system, mirrored 1:1 from the Figma Foundations / Colors page. Components never touch raw hex or primitive scales — only semantic tokens.
Layer 1 — Primitives
Raw scales with no meaning attached: --brand-50 through --brand-950, the same
for gray, error, warning, success, plus spacing and radius. One mode.
You rarely reference these in components.
Brand
True blue. brand/600 is the primary brand color.
50
#EFF4FF
100
#DBE5FE
200
#BFD0FE
300
#93B0FD
400
#6187F9
500
#3B63F5
600
#2450EA
700
#1C3FD1
800
#1E37A9
900
#1E3485
950
#172152
Gray
Neutral scale with a slight cool bias to harmonize with brand blue.
50
#F9FAFB
100
#F2F4F7
200
#E4E7EC
300
#D0D5DD
400
#98A2B3
500
#667085
600
#475467
700
#344054
800
#1D2939
900
#101828
950
#0C111D
Error
Red scale for destructive actions, errors, and critical alerts.
50
#FEF3F2
100
#FEE4E2
200
#FECDCA
300
#FDA29B
400
#F97066
500
#F04438
600
#D92D20
700
#B42318
800
#912018
900
#7A271A
950
#55160C
Warning
Amber scale for cautionary states and non-blocking alerts.
50
#FFFAEB
100
#FEF0C7
200
#FEDF89
300
#FEC84B
400
#FDB022
500
#F79009
600
#DC6803
700
#B54708
800
#93370D
900
#7A2E0E
950
#4E1D09
Success
Green scale for confirmation, completion, and positive feedback.
50
#ECFDF3
100
#D1FADF
200
#A6F4C5
300
#6CE9A6
400
#32D583
500
#12B76A
600
#079455
700
#067647
800
#085D3A
900
#074D31
950
#053321
Layer 2 — Semantic
Meaning-based aliases onto primitives: --bg-primary, --fg-secondary,
--border-default, --focus-ring. Components only ever reference semantic
tokens. Dark mode is a .dark block that remaps semantic → primitive — no
component contains a dark: variant for themed colors.
Light → Dark remap
| Token | Light | Dark |
|---|---|---|
bg/primary | base/white | gray/950 |
bg/secondary | gray/50 | gray/900 |
bg/tertiary | gray/100 | gray/800 |
bg/elevated | base/white | gray/900 |
bg/brand-solid | brand/600 | brand/600 |
bg/brand-solid-hover | brand/700 | brand/500 |
bg/brand-subtle | brand/50 | brand/950 |
fg/primary | gray/900 | gray/50 |
fg/secondary | gray/600 | gray/400 |
fg/tertiary | gray/500 | gray/500 |
fg/disabled | gray/400 | gray/600 |
fg/on-brand | base/white | base/white |
fg/brand | brand/600 | brand/400 |
border/default | gray/200 | gray/800 |
border/strong | gray/300 | gray/700 |
border/brand | brand/600 | brand/400 |
focus/ring | brand/500 | brand/400 |
Status solids (bg/error-solid, bg/warning-solid, bg/success-solid) stay on
their */600 step in both modes; subtles flip */50 → */950.
Signature effects
Two things make Asteria look like Asteria:
- Brand-tinted shadows. Every shadow uses
brand/900at low opacity instead of flat black — depth stays in the brand's color world. - Glow focus ring.
--shadow-glow-focus: a 4px spread ofbrand/500at 24%, zero blur, zero offset. Applied via thefocus-glowutility. Always brand-colored — no error or neutral variants.
Changing the brand color
Override the --brand-* primitive scale after importing tokens.css. Because
everything downstream is semantic aliases, components, shadows, and the focus ring
follow automatically.
Radius personality
Asteria leans squircle: 6 / 8 / 10 / 14 / 20px (radius-xs → radius-xl), plus
radius-full for pills. Inputs and buttons default to radius-md (10px).