# Colors Never hardcode hex/rgb in components. Use semantic CSS variables exposed as Tailwind theme colors. Canonical definitions: `app/globals.css` (`:root` and `.dark`). ## Brand primitives | CSS variable | Light value | Role | | --- | --- | --- | | `--brand-primary` | `#29a19c` | Brand teal | | `--brand-primary-dark` | `#044343` | Deep teal | | `--brand-neutral` | `#222222` | Near-black neutral | | `--brand-gray` | `#999999` | Mid gray | | `--brand-light` | `#e4e4e4` | Light gray | | `--brand-primary-hover` | `#32b5af` | Primary hover | | `--brand-primary-active` | `#218a86` | Primary active | | `--brand-glow` | `rgb(41 161 156 / 0.12)` | Soft glow | | `--brand-highlight` | mix of primary + white | Timeline / highlight accents | Tailwind aliases: `brand`, `brand-dark`, `brand-neutral`, `brand-gray`, `brand-light`, `glow`. ## Semantic palette (prefer these in UI) | Token | Tailwind | Light | Dark | Use | | --- | --- | --- | --- | --- | | Background | `bg-background` | `#ffffff` | `#141818` | Page canvas | | Foreground | `text-foreground` | `#222222` | `#f4f4f4` | Primary text | | Card | `bg-card` / `text-card-foreground` | white / `#222` | `#1c2424` / `#f4f4f4` | Cards, elevated surfaces | | Surface | `bg-surface` / `text-surface-foreground` | `#f7f7f7` | `#1a2222` | Soft bands, inputs (dark) | | Primary | `bg-primary` / `text-primary-foreground` | `#29a19c` / white | same | Main CTA | | Primary hover | `bg-primary-hover` | `#32b5af` | same | Hover | | Primary active | `bg-primary-active` | `#218a86` | same | Pressed | | Secondary | `bg-secondary` / `text-secondary-foreground` | `#044343` / white | `#243535` / `#e4e4e4` | Deep brand / secondary panels | | Muted | `bg-muted` / `text-muted-foreground` | `#e4e4e4` / `#5c5c5c` | `#243030` / `#999999` | Subtle fills, secondary text | | Accent | `bg-accent` / `text-accent-foreground` | teal-tinted white / `#044343` | teal mix / `#e4e4e4` | Hover washes, chips | | Destructive | `bg-destructive` / `text-destructive-foreground` | `#c44747` / white | `#e06a6a` / white | Errors / danger | | Border | `border-border` | `#e4e4e4` | white @ 12% | Dividers, outlines | | Input | `border-input` | `#e4e4e4` | white @ 14% | Form controls | | Ring | `ring-ring` | `#29a19c` | `#29a19c` | Focus rings | | Popover | `bg-popover` | white | `#1c2424` | Menus, dropdowns | ## Semantic intent map | Intent | Tokens | | --- | --- | | Page background | `background` | | Primary text | `foreground` | | Secondary text | `muted-foreground` | | Interactive primary | `primary` → `primary-hover` → `primary-active` | | Borders | `border` | | Focus | `ring` + `border-ring` / `border-primary` | | Disabled | lower opacity on control (`opacity-50`) — do not invent a gray hex | | Danger | `destructive` | | Charts | `chart-1` … `chart-5` | ## Hover / focus / disabled | State | Pattern | | --- | --- | | Hover (primary button) | `hover:bg-primary-hover` | | Active (primary button) | `active:bg-primary-active` + slight `scale-[0.98]` | | Focus visible | `focus-visible:ring-[3px] focus-visible:ring-ring/40` (buttons) or `ring-primary/25` (inputs) | | Disabled | `disabled:opacity-50 disabled:pointer-events-none` | | Invalid | `aria-invalid:border-destructive` + destructive ring | ## Rules 1. **Never** use raw `#29a19c`, `#044343`, etc. in JSX/className. Use `primary`, `brand`, or CSS variables. 2. Prefer semantic names (`primary`, `muted-foreground`) over brand primitives in app UI. 3. Dark mode must work by swapping CSS variables—not by separate hard-coded dark hex in components. 4. Selection color is already themed in `globals.css` (`::selection`). 5. Glow utilities: `bg-glow-primary`, `shadow-glow-primary` — see [gradients.md](./gradients.md). ## Related - [dark-mode.md](./dark-mode.md) - [buttons.md](./buttons.md) - [accessibility.md](./accessibility.md)