Colors
Stratum follows the Color Scarcity Principle (ADR-010): one accent color + black + white + grays. Color is powerful because it’s scarce. The best-in-class apps (Wealthsimple, Coinbase, Airbnb) use this pattern — a single accent hue creates strong visual hierarchy without competing colors.
How the color system works
Section titled “How the color system works”There are two layers:
-
Palette (
colors.ts) — raw values:palette.gray900,palette.brand500. This is an internal implementation detail. Never import from the palette in components. -
Semantic tokens (via
theme.colors.*) — named by meaning, not value.theme.colors.textPrimaryis black in light mode, near-white in dark mode. When switching themes or modes, the semantic names stay the same but the values update.
// ✓ Semantic — updates with theme and dark modeconst theme = useTheme();<Text style={{ color: theme.colors.textPrimary }}>Hello</Text>
// ✗ Palette — doesn't respond to theme/dark mode changesimport { palette } from '@/tokens/colors'; // Never do this in componentsSemantic color slots
Section titled “Semantic color slots”Backgrounds
Section titled “Backgrounds”| Token | Description |
|---|---|
theme.colors.background | Page background |
theme.colors.surface | Card and panel background |
theme.colors.surfaceRaised | Elevated surface (above surface level) |
| Token | Description |
|---|---|
theme.colors.textPrimary | Main body text |
theme.colors.textSecondary | Supporting text, slightly dimmed |
theme.colors.textMuted | Placeholder, timestamps, fine print |
theme.colors.textInverse | Text on dark backgrounds |
theme.colors.textOnAccent | Text inside accent-colored containers |
Accent
Section titled “Accent”| Token | Description |
|---|---|
theme.colors.accent | Primary brand color |
theme.colors.accentHover | Darker accent for press states |
theme.colors.accentSubtle | Very light accent tint (chips, badges, pills) |
Signal
Section titled “Signal”These colors communicate functional meaning. Never use them decoratively.
| Token | Description |
|---|---|
theme.colors.success | Success, complete, verified |
theme.colors.successSubtle | Light success tint (badge background) |
theme.colors.warning | Pending, review, expiring |
theme.colors.warningSubtle | Light warning tint |
theme.colors.error | Error, failed, destructive |
theme.colors.errorSubtle | Light error tint |
Borders
Section titled “Borders”| Token | Description |
|---|---|
theme.colors.border | Default divider and input border |
theme.colors.borderStrong | Emphasized border |
theme.colors.borderSubtle | Very light separator |
Overlay
Section titled “Overlay”| Token | Description |
|---|---|
theme.colors.overlay | Modal scrim background |
Per-theme accent colors
Section titled “Per-theme accent colors”| Theme | Light accent | Dark accent |
|---|---|---|
| Slate | #000000 (black) | #FFFFFF (white) |
| Obsidian | Brand teal/indigo | Brighter variant |
| Quartz | #2563EB (electric blue) | Adjusted blue |
const theme = useTheme();
// In a StyleSheet:const styles = StyleSheet.create({ container: { backgroundColor: theme.colors.background }, card: { backgroundColor: theme.colors.surface, borderColor: theme.colors.border }, title: { color: theme.colors.textPrimary }, caption: { color: theme.colors.textMuted },});Do / Don’t
Section titled “Do / Don’t”Do: Use semantic color names — they update automatically across themes and modes.
Don’t: Import from src/tokens/colors.ts (palette) in components.
// ✗import { palette } from '@/tokens/colors';style={{ color: palette.gray900 }}
// ✓const theme = useTheme();style={{ color: theme.colors.textPrimary }}Don’t: Add a second accent color to a component or theme. If your design calls for a second accent, extend the AppTheme interface — but the default system intentionally uses one.
Custom themes
Section titled “Custom themes”When creating a custom theme with createTheme(), you override semantic slots — not palette values:
import { createTheme } from '@/tokens/themes/createTheme';import { slateThemeLight } from '@/tokens/themes/slate';
const brandTheme = createTheme(slateThemeLight, { colors: { accent: '#E11D48', accentHover: '#BE123C', accentSubtle: '#FFF1F2', },});Related
Section titled “Related”- Spacing
- Typography
- Theme protocol — Surface uses the color system automatically