Initial commit: nick docs
This commit is contained in:
207
05 - Design System/Colors.md
Normal file
207
05 - Design System/Colors.md
Normal file
@@ -0,0 +1,207 @@
|
||||
---
|
||||
title: Colors
|
||||
tags: [design-system, colors, palette]
|
||||
created: 2026-05-23
|
||||
---
|
||||
|
||||
# Colors
|
||||
|
||||
The palette is built from semantic groups (`primary`, `secondary`, `info`, `success`, `warning`, `error`, plus a 9-step `grey` scale) and exposed via the MUI theme. **Never hard-code hex values in components.**
|
||||
|
||||
> [!warning]
|
||||
> Hardcoded colors break dark mode and any future preset switch. Use `sx={{ color: 'primary.main' }}` or `theme.palette.primary.main`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Semantic groups
|
||||
|
||||
Every color group has the shape:
|
||||
|
||||
```ts
|
||||
{
|
||||
lighter: '#…', // tint background, alerts
|
||||
light: '#…', // hover surfaces, badges
|
||||
main: '#…', // primary use (buttons, links)
|
||||
dark: '#…', // hover state of `main`
|
||||
darker: '#…', // pressed state
|
||||
contrastText: '#…', // WCAG AA on `main`
|
||||
}
|
||||
```
|
||||
|
||||
### 1.1 Primary
|
||||
|
||||
| Token | Light hex (default preset) | Dark hex |
|
||||
|---|---|---|
|
||||
| `primary.lighter` | `#D0ECFE` | `#CCF4FE` |
|
||||
| `primary.light` | `#73BAFB` | `#68CDF9` |
|
||||
| `primary.main` | `#1877F2` | `#078DEE` |
|
||||
| `primary.dark` | `#0C44AE` | `#0351AB` |
|
||||
| `primary.darker` | `#042174` | `#012972` |
|
||||
| `primary.contrastText` | `#FFFFFF` | `#FFFFFF` |
|
||||
|
||||
Used for primary actions, links, focused inputs.
|
||||
|
||||
### 1.2 Secondary
|
||||
|
||||
Typical: a complementary purple/teal. Confirm by reading `theme/options/palette.ts`.
|
||||
|
||||
### 1.3 Info / Success / Warning / Error
|
||||
|
||||
Standard semantic colors:
|
||||
|
||||
| Group | Hue | Used for |
|
||||
|---|---|---|
|
||||
| `info` | cyan/blue | Neutral informative banners |
|
||||
| `success` | green | Confirmed payments, accepted offers |
|
||||
| `warning` | amber | Pending state, mild alerts |
|
||||
| `error` | red | Disputes, validation errors, destructive |
|
||||
|
||||
Each follows the same `lighter/light/main/dark/darker/contrastText` shape.
|
||||
|
||||
### 1.4 Grey
|
||||
|
||||
Nine-step scale (100 → 900). Use for:
|
||||
|
||||
- `grey.100`–`grey.300` → backgrounds, dividers, disabled
|
||||
- `grey.500` → secondary text, muted icons
|
||||
- `grey.700`–`grey.900` → primary text, dark headings
|
||||
|
||||
### 1.5 Text & Background
|
||||
|
||||
```ts
|
||||
text: {
|
||||
primary: grey[800], // body
|
||||
secondary: grey[600], // muted
|
||||
disabled: grey[500],
|
||||
},
|
||||
background: {
|
||||
default: '#FFFFFF', // light mode page
|
||||
paper: '#FFFFFF', // cards, dialogs
|
||||
neutral: grey[200], // page wash
|
||||
},
|
||||
```
|
||||
|
||||
In dark mode these invert (`default` becomes near-black, `paper` slightly lighter, `text.primary` near-white).
|
||||
|
||||
---
|
||||
|
||||
## 2. Action states
|
||||
|
||||
```ts
|
||||
action: {
|
||||
active: alpha(grey[600], 1),
|
||||
hover: alpha(grey[500], 0.08),
|
||||
selected: alpha(grey[500], 0.16),
|
||||
disabled: alpha(grey[500], 0.8),
|
||||
disabledBackground: alpha(grey[500], 0.24),
|
||||
focus: alpha(grey[500], 0.24),
|
||||
hoverOpacity: 0.08,
|
||||
disabledOpacity: 0.48,
|
||||
}
|
||||
```
|
||||
|
||||
Use via `sx={{ bgcolor: 'action.hover' }}` etc.
|
||||
|
||||
---
|
||||
|
||||
## 3. Color presets
|
||||
|
||||
The settings drawer ships several **color presets** that swap only `primary` (and optionally `secondary`) while keeping every other group stable. Typical presets (confirm in `theme/options/presets/`):
|
||||
|
||||
| Preset | Primary hue | Vibe |
|
||||
|---|---|---|
|
||||
| `default` | Blue | Trust, finance |
|
||||
| `purple` | Indigo/Purple | Premium |
|
||||
| `cyan` | Cyan | Tech, fresh |
|
||||
| `blue` | Vibrant blue | Strong CTA |
|
||||
| `orange` | Orange | Energetic |
|
||||
| `red` | Brand red | Bold |
|
||||
|
||||
To add a preset:
|
||||
|
||||
1. Add a `<name>.ts` file in `theme/options/presets/` exporting `{ lighter, light, main, dark, darker, contrastText }`.
|
||||
2. Register in the presets index map.
|
||||
3. Surface in the settings drawer color picker (`src/settings/drawer/`).
|
||||
|
||||
---
|
||||
|
||||
## 4. Contrast verification
|
||||
|
||||
WCAG AA targets:
|
||||
|
||||
| Element | Min contrast |
|
||||
|---|---|
|
||||
| Body text (≥18 px regular or ≥14 px bold) | **4.5 : 1** |
|
||||
| Large text (≥24 px regular or ≥18 px bold) | **3 : 1** |
|
||||
| Icon-only buttons | **3 : 1** for their boundary |
|
||||
| Form input borders | **3 : 1** |
|
||||
|
||||
> [!tip]
|
||||
> When picking a new `main` color, run it through [Stark](https://stark.co/) or the Chrome DevTools "Inspect color" checker against `background.paper` AND `background.default` for both light and dark modes.
|
||||
|
||||
---
|
||||
|
||||
## 5. Using colors in `sx`
|
||||
|
||||
```tsx
|
||||
// Token-based — preferred
|
||||
<Box sx={{ bgcolor: 'primary.main', color: 'primary.contrastText' }} />
|
||||
|
||||
// Function form when you need to derive
|
||||
<Box sx={(theme) => ({ bgcolor: alpha(theme.palette.primary.main, 0.08) })} />
|
||||
|
||||
// In styled component
|
||||
const Item = styled('div')(({ theme }) => ({
|
||||
background: theme.palette.background.paper,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Charts & data viz
|
||||
|
||||
Use the helper `theme.palette.<group>.main` array for series colors. The `chart/` component family (ApexCharts wrapper) reads these tokens so the chart palette stays in sync with the theme.
|
||||
|
||||
For categorical data with >7 series, layer in `secondary.main`, `info.main`, `success.main`, `warning.main`, `error.main`, then darker variants — never invent ad-hoc hex.
|
||||
|
||||
---
|
||||
|
||||
## 7. Diff visualisation (chat, evidence)
|
||||
|
||||
| Concept | Color token |
|
||||
|---|---|
|
||||
| Added / accepted | `success.main` with `success.lighter` background |
|
||||
| Removed / rejected | `error.main` with `error.lighter` background |
|
||||
| Pending review | `warning.main` |
|
||||
| Informational | `info.main` |
|
||||
|
||||
---
|
||||
|
||||
## 8. Avatar backgrounds
|
||||
|
||||
`MuiAvatar` override hashes the user's name to one of the semantic `main` colors so the same person always gets the same background. Implementation in `components/user-avatar/`.
|
||||
|
||||
---
|
||||
|
||||
## 9. Brand vs semantic
|
||||
|
||||
| Use case | Token |
|
||||
|---|---|
|
||||
| Primary CTA button | `primary.main` |
|
||||
| Success snackbar | `success.main` |
|
||||
| Error border on form field | `error.main` |
|
||||
| Page background | `background.default` |
|
||||
| Card background | `background.paper` |
|
||||
| Sidebar background | `background.neutral` |
|
||||
| Divider line | `divider` |
|
||||
| Primary text | `text.primary` |
|
||||
| Muted helper text | `text.secondary` |
|
||||
|
||||
---
|
||||
|
||||
## 10. Related
|
||||
|
||||
- [[Theme Configuration]] · [[Design System Overview]] · [[Typography]]
|
||||
- [[Components]] — components consuming these tokens
|
||||
- [[Settings & Theming]] — preset switcher
|
||||
Reference in New Issue
Block a user