Simal UI

Color

The Simal palette and semantic tokens, generated from a single source of truth.

src/theme/tokens.ts is the single source of truth. Everything else — the CSS custom properties, the React Navigation theme, the Sheet theme, the swatches on this page — derives from it. Change a colour there and run pnpm theme:css.

Semantic tokens

Use these, not the raw palette. Only they have a dark-mode counterpart. Each swatch shows light on the left, dark on the right.

Surface

--color-background

#F7F5F1 · #121212

--color-foreground

#0A0A0A · #F8F7FB

--color-secondary-foreground

#3D3D3D · #E8E4F2

--color-card

#ffffff · #121212

--color-card-foreground

#0A0A0A · #F8F7FB

--color-card-border

#E8E5DE · #2A2435

--color-card-elevated

#ffffff · #1E1E1E

--color-muted

#EFEAE0 · #1C1922

--color-muted-foreground

#6B6B6B · #E8E3F4

--color-border

#E8E5DE · #474747

Brand

--color-primary

#0A0A0A · #F8F7FB

--color-primary-hover

#2A2A2A · #E8E7EC

--color-primary-press

#000000 · #D8D7DC

--color-primary-contrast

#ffffff · #0A0A0A

--color-primary-foreground

#ffffff · #0A0A0A

--color-primary-tint

#FBFAF7 · #1E1E1E

--color-accent-violet

#5B4BE5 · light only

Status

--color-success

#10B981 · #22C55E

--color-warning

#F59E0B · #FBBF24

--color-error

#DC2626 · #F87171

--color-destructive

#DC2626 · #F87171

--color-destructive-foreground

#ffffff · #ffffff

Chrome

--color-chrome-bg

#F0E4CE · light only

--color-chrome-border

#D8C49C · light only

--color-chrome-border-strong

#C8AF85 · light only

--color-chrome-muted

#E5D3B0 · light only

--color-chrome-pill-bg

#EDD8B8 · light only

--color-chrome-accent

#8B1A26 · light only

--color-chrome-text

#1C0E0E · light only

--color-chrome-muted-text

#6B5E5E · light only

--color-chrome-placeholder

#9A8070 · light only

Palette scales

The raw ramps the semantic tokens are drawn from. Reach for these only when no semantic token fits — they have no dark-mode behaviour.

charcoal

50

#F2F2F2

100

#E5E5E5

200

#C9C9C9

300

#B0B0B0

400

#969696

500

#7D7D7D

600

#616161

700

#474747

800

#383838

850

#2E2E2E

900

#1E1E1E

950

#121212

neutral

50

#FAFAFA

100

#F5F5F5

200

#F0EFEE

300

#D4D4D4

400

#A3A3A3

500

#737373

600

#525252

700

#404040

800

#262626

900

#171717

primary

50

#F2EEFF

100

#E2D9FF

200

#C8B5FF

300

#A78BFA

400

#8B5CF6

500

#7C4DFF

600

#6D46E8

700

#5C3CC5

800

#4A319E

900

#38257A

success

50

#F0FDF4

100

#DCFCE7

200

#BBF7D0

300

#86EFAC

400

#4ADE80

500

#22C55E

600

#16A34A

700

#15803D

800

#166534

900

#14532D

warning

50

#FFFBEB

100

#FEF3C7

200

#FDE68A

300

#FCD34D

400

#FBBF24

500

#F59E0B

600

#D97706

700

#B45309

800

#92400E

900

#78350F

danger

50

#FEF2F2

100

#FEE2E2

200

#FECACA

300

#FCA5A5

400

#F87171

500

#EF4444

600

#DC2626

700

#B91C1C

800

#991B1B

900

#7F1D1D

Adding a colour

Two edits, and both are required. A colour added to tokens.ts alone produces a Tailwind class that compiles to nothing:

  1. src/theme/tokens.ts — the value, in both light and dark.
  2. SEMANTIC_CSS in scripts/gen-theme-css.ts — the --color-* variable name.

Then pnpm theme:css. CI fails if regenerating produces a diff.

A utility with no matching --color-* variable resolves to an invalid value, which CSS treats as initialpure black, not inherit. So a dead colour class is invisible against a dark surface rather than merely unstyled. Three have shipped this way already: destructive, primary-foreground and secondary-foreground.

On this page