# Color

Our color system is warm, stone-based, and intentional. It avoids the cold blue-gray palette that defines most software. The effect should feel like paper, not plastic.

**Source of truth:**`app/web/app/styles/daisyui.css`

## Light mode palette

The light theme (`convictional-light`) builds on warm cream and stone tones.

| Token        | Value                  | Role                                   |
| ------------ | ---------------------- | -------------------------------------- |
| `base-50`   | `hsl(38, 50%, 98%)`   | Subtle highlight, hover states         |
| `base-100`  | `#fffdf5`             | Page background, warm off-white        |
| `base-200`  | `#f7f3ea`             | Card backgrounds, secondary surfaces   |
| `base-300`  | `#efebe2`             | Elevated surfaces, input backgrounds    |
| `base-400`  | `hsl(40, 20%, 85%)`   | Borders, dividers                       |
| `base-500`  | `hsl(30, 10%, 65%)`   | Muted text, disabled states             |
| `base-600`  | `hsl(33, 5%, 32%)`    | Secondary text                          |
| `base-700`  | `hsl(30, 6%, 25%)`    | Strong secondary text                   |
| `base-800`  | `hsl(12, 6%, 15%)`    | Near-black text                        |
| `base-900`  | `hsl(24, 10%, 10%)`   | Primary text                           |
| `base-content` | `oklch(19.87% 0.002 95.16)` | Default content color               |

## Dark mode palette

The dark theme (`convictional-dark`) inverts the warmth: dark stone backgrounds with warm light text.

| Token        | Value                  | Role                                   |
| ------------ | ---------------------- | -------------------------------------- |
| `base-50`   | `hsl(20, 14%, 8%)`    | Deepest background                      |
| `base-100`  | `#1c1917`             | Page background, warm near-black       |
| `base-200`  | `hsl(20, 6%, 15%)`    | Card backgrounds                       |
| `base-300`  | `hsl(30, 6%, 20%)`    | Elevated surfaces                      |
| `base-400`  | `hsl(30, 6%, 25%)`    | Borders, dividers                       |
| `base-500`  | `hsl(30, 6%, 40%)`    | Muted elements                        |
| `base-600`  | `hsl(24, 6%, 83%)`    | Secondary text                         |
| `base-700`  | `hsl(20, 6%, 90%)`    | Primary text                          |
| `base-800`  | `hsl(60, 5%, 96%)`    | Strong emphasis text                   |
| `base-900`  | `hsl(60, 9%, 98%)`    | Maximum contrast text                  |
| `base-content` | `oklch(84.32% 0.001 56.04)` | Default content color               |

## Primary blue

`#2b7fff` is consistent across both themes. This is the action color. It means "do something." Buttons, links, interactive elements. It never appears as decoration.

## Neutral pair

The neutral pair swaps between themes to provide high-contrast surfaces:

- Light mode: `neutral: #292524` / `neutral-content: #f7f3ea`
- Dark mode: `neutral: #efebe2` / `neutral-content: #1c1917`

## Semantic colors

Each semantic color has a background + content pair, designed for both themes.

| Semantic | Light BG    | Light Text | Dark BG    | Dark Text | Usage                                    |
| -------- | ----------- | -----------| -----------| ----------| ----------------------------------------- |
| Info     | `#eff6ff`  | `#2b7fff`  | `#162556`  | `#2b7fff` | Informational states, primary actions   |
| Success  | `#f7fee7`  | `#5ea500`  | `#192e03`  | `#7ccf00` | Positive outcomes, confirmations         |
| Warning  | `#fefce8`  | `#d08700`  | `#432004`  | `#f0b100` | Cautions, attention needed               |
| Error    | `#ffe2e2`  | `#e7000b`  | `#460809`  | `#e7000b` | Errors, destructive actions              |

## Accessibility

All text-on-background combinations in the palette meet WCAG AA contrast requirements. The warm stone palette was specifically chosen to maintain readability while avoiding the harshness of pure white (`#fff`) and pure black (`#000`).

When creating new color combinations, test contrast ratios. The primary blue (`#2b7fff`) on white fails AA for body text; that's why it's always used on tinted backgrounds (`info` token) rather than directly on `base-100`.

## Principles

- **Warm, not clinical.** Our palette starts from cream and stone, not white and gray. This is intentional and non-negotiable.
- **Restrained.** We use very few colors. Blue is for action. Everything else is neutral. If you need a new color, you probably don't.
- **Theme-aware.** Every color choice must work in both light and dark modes. Don't hardcode hex values; use the semantic tokens.
