38686-vm/docs/design-tokens.md
Konrad du Plessis aafa6df189 ux(colors): apply semantic palette to Loans tab + Active Loans card
Konrad caught that /payroll/?status=loans was still using Bootstrap
defaults (bg-primary for Loan, bg-info for Advance) while the other
three tabs had moved to the semantic palette. The Preview-payslip
modal's Active Loans card had the same inconsistency in its JS-built
badge.

- Added .advance-flag-badge as a sibling to .loan-flag-badge; both
  just reference the existing --badge-loan-* / --badge-advance-*
  tokens so no new colours introduced.
- /payroll/?status=loans row badge: bg-primary/bg-info → loan-flag-
  badge/advance-flag-badge.
- Worker-lookup / Preview-payslip modal JS: same swap on the badge
  className.

Loan-family items now wear the same amber/blue colour pair on every
tab + modal they appear on. Transactional status (Active/Paid Off)
stays on Bootstrap greens/yellows — they're lifecycle, not type.

docs/design-tokens.md updated to record the new class + every place
the --badge-loan-* / --badge-advance-* tokens now appear.

Tests: 69/69.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 10:52:02 +02:00

77 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Design Tokens — Semantic Colour Palette
_Last reviewed: 24 Apr 2026._
## How colours are structured
The app has TWO colour categories — they MUST NOT share colours:
1. **Type-of-adjustment** — 7 types × 2 themes. Used wherever a
`PayrollAdjustment` is shown as a badge or a group-header accent.
Token naming: `--badge-<type>-bg` / `--badge-<type>-fg`.
2. **Transactional state** — Bootstrap's `bg-success` /
`bg-warning` / `bg-danger`. Used for Paid, Unpaid, Overdue —
the payment lifecycle, not the kind of adjustment.
Mixing the two would make a green badge mean both "this is a Bonus"
AND "this is Paid" — the user would lose the ability to read the
colour as a signal. Keep the categories separate.
## Type-of-adjustment tokens
| DB type (canonical) | Displayed as | Dark BG | Dark FG | Light BG | Light FG | CSS class |
|---|---|---|---|---|---|---|
| Bonus | Bonus | `#5b8260` | `#e8f3ea` | `#d7e8d9` | `#385640` | `.badge-type-bonus` |
| Overtime | Overtime | `#a16881` | `#fce4ec` | `#f3d1dd` | `#703347` | `.badge-type-overtime` |
| Deduction | Deduction | `#5b4f8c` | `#e0daf3` | `#d8d0ef` | `#3b2f6d` | `.badge-type-deduction` |
| New Loan | Loan | `#9b7f39` | `#fef4d1` | `#f0dc9d` | `#6a5320` | `.badge-type-new-loan` |
| Loan Repayment | Loan Repayment | `#b48a1a` | `#fef4d1` | `#f7d873` | `#5a4418` | `.badge-type-loan-repayment` |
| Advance Payment | Advance | `#3e5c7b` | `#d7e5f2` | `#bccee0` | `#243b56` | `.badge-type-advance-payment` |
| Advance Repayment | Advance Repaid | `#2f679a` | `#d7e5f2` | `#9ec1dd` | `#1d3550` | `.badge-type-advance-repayment` |
Token definitions live in `static/css/custom.css`:
- Dark theme: `:root { ... }` block around lines 85-91
- Light theme: `[data-theme="light"] { ... }` block around lines 149-155
## Where each colour appears
| Semantic | Used by |
|---|---|
| `--badge-bonus-*` (green) | Adjustments tab type badge; By-Type group-header left-border accent |
| `--badge-overtime-*` (mauve) | Adjustments tab type badge; By-Type group-header accent |
| `--badge-deduction-*` (purple) | Adjustments tab type badge; By-Type group-header accent |
| `--badge-loan-*` (amber/yellow) | Adjustments tab type badge; By-Type group-header accent; Pending tab "Loan" worker flag (`.loan-flag-badge`); Loans-and-Advances tab row badge for Loan-type rows (`.loan-flag-badge`); Preview-payslip modal's Active Loans card |
| `--badge-loan-rep-*` (deeper amber, +15% saturation) | Adjustments tab type badge for Loan Repayment; By-Type group-header accent |
| `--badge-advance-*` (blue) | Adjustments tab type badge; By-Type group-header accent; Loans-and-Advances tab row badge for Advance-type rows (`.advance-flag-badge`); Preview-payslip modal's Active Loans card |
| `--badge-advance-rep-*` (deeper blue, +15% saturation) | Adjustments tab type badge for Advance Repayment; By-Type group-header accent |
## Transactional-state colours (Bootstrap — unchanged)
| Use | Class |
|---|---|
| Paid payslip badge | `bg-success` |
| Unpaid status badge | `bg-warning` |
| Overdue worker flag (Pending tab) | `bg-danger` |
## How to add a new colour token
1. Define in BOTH the `:root` and `[data-theme="light"]` blocks in
`static/css/custom.css`. Choose colours that retain enough contrast
against the card background in both themes.
2. Add a row to the mapping table in this doc.
3. Reference via `var(--badge-*-bg)` in CSS — never hard-code hex
anywhere else.
4. If it's a new adjustment type, add:
- A `.badge-type-<slug>` class in the `.badge-type-*` block
(around line 1935 of `custom.css`)
- An entry in the `.adj-group-header[data-type="..."]` block
(around line 1994)
- The new TYPE_CHOICES entry in `core/models.py::PayrollAdjustment`
(and run `makemigrations`)
## Maintenance
This doc is the single source of truth for app-wide colour semantics.
When CSS tokens are added / removed / renamed in `custom.css`, update
this doc in the SAME commit.