Whale uses one primary ramp, a neutral Zinc scale, and four semantic status hues. Every color is consumed by semantic role — never as a raw hex in product code.
The full ramp is anchored on the brand color #7245F2 (step 500). Interaction
states are derived from the ramp, not sampled per component.
| Step | Value | Typical role |
|---|---|---|
| 50 | #F7F3FF |
Subtle brand surface / selected background |
| 100 | #EFE8FE |
Hover tint on a brand-tinted surface |
| 200 | #D6C6FC |
Disabled primary / soft border |
| 300 | #B49AF9 |
— |
| 400 | #8F6BF5 |
Brand accent on dark surfaces |
| 500 | #7245F2 |
Primary — the strongest interactive cue |
| 600 | #5B30E0 |
Primary hover |
| 700 | #4622B8 |
Primary pressed |
| 800 | #341A8A |
Deep press / high-contrast on light |
| 900 | #241463 |
On-dark deep accent |
Steps 800–900 extend the ramp for deep-press and on-dark use. Steps 50–700 are the primary working range.
A ten-step Zinc scale carries structure, text, and borders.
| Token | Value | Typical role |
|---|---|---|
| grey-0 | #FAFAFA |
App canvas / recessed surface |
| grey-1 | #F4F4F5 |
Muted / hover surface, secondary fill |
| grey-2 | #E4E4E7 |
Standard border (controls, containers) |
| grey-3 | #D4D4D8 |
Strong / dashed border |
| grey-4 | #A1A1AA |
Faint metadata, disabled icons |
| grey-5 | #71717A |
Secondary text |
| grey-6 | #52525B |
Muted foreground |
| grey-7 | #3F3F46 |
Strong secondary foreground |
| grey-8 | #27272A |
High-emphasis neutral |
| grey-9 | #18181B |
Primary foreground text |
| Surface | Value | Role |
|---|---|---|
| Canvas | grey-0 #FAFAFA |
The quiet backdrop behind working surfaces |
| Working surface / card | #FFFFFF |
The white surface that holds content |
| Border | grey-2 #E4E4E7 |
Default boundary between surfaces and controls |
| Muted / secondary | grey-1 #F4F4F5 |
Recessed inner sections |
| Foreground | grey-9 #18181B |
Primary text |
| Muted foreground | grey-6 #52525B |
Secondary text and quiet labels |
Prefer a border over a shadow to separate a surface. Reserve elevation for genuinely floating layers — see Radius, Spacing & Elevation.
Status color is reserved for state that changes a decision. Each hue has a foreground and a soft background.
| Meaning | Foreground | Soft background |
|---|---|---|
| Success | #3FB33E |
#ECF7EC |
| Warning | #FF861B |
#FFF1E3 |
| Information | #1B8CFC |
#E7F2FE |
| Danger | #F33931 |
#FEEBEA |
- Keep status meaning on these tokens; the brand purple must never substitute for success, warning, information, or danger.
- State must remain understandable without color alone — pair a color with text or an icon.
On financial surfaces that show price movement, follow the Asian market convention: up = danger red, down = success green. This reuses the status hues for direction and applies only to market data, not to system status.
Light is the authoritative baseline. Dark is derived per surface from the same tokens (lift the primary toward step 400, invert the neutral scale, keep status hues legible on dark backgrounds).
Each surface declares which modes it supports:
- Light + dark: this portal and outward-facing surfaces.
- Light-only: internal operator back-offices.
A surface that opts into dark must provide a dark value for every token it uses, including any local overrides. A surface that is light-only must not ship a half-finished dark treatment.
- Consume color by semantic role (primary, foreground, border, success, …), never by raw hex, in product code.
- Do not introduce per-page tints, gradients, or approximate shades of the brand or neutral colors.
- Build hierarchy with the neutral scale, spacing, and dividers before adding a colored surface.