Compare commits

...

3 Commits

Author SHA1 Message Date
Konrad du Plessis
6c6ade9a45 ux(ui): pastel soft-fill payroll action buttons
The 4 action buttons at the top of /payroll/ were previously a mix
of btn-outline-info / btn-primary / btn-outline-success /
btn-outline-warning — three different treatments, with a lone solid
btn-primary (Batch Pay) pulling the eye disproportionately. Konrad
asked for a more uniform + pastel look.

New .btn-action-soft base class with per-button colour modifiers:
  - Worker Lookup → soft blue (new --btn-action-lookup tokens)
  - Batch Pay    → soft amber (new --btn-action-pay tokens;
                   slightly deeper saturation to preserve its
                   "primary" role without breaking the uniform look)
  - Add Adjustment → reuses --badge-bonus-* (green, "adding money"
                     semantic matches Bonus)
  - Price Overtime → reuses --badge-overtime-* (mauve, same colour
                     as the Overtime badge on the Adjustments tab —
                     so the button matches the data it acts on)

All 4 now share:
  - No border, solid pastel fill, contrasting text
  - Same height, padding, border-radius (0.5rem)
  - Subtle box-shadow lift on hover (filter: brightness)
  - 1px press-down on active
  - Accessible focus-visible outline in --accent
  - Icons inherit text colour

Net CSS change: 4 new tokens (2 per theme × 2 themes) + 5 new
classes. Removes shadow-sm, btn-sm, btn-md-normal, fw-bold
one-offs — all handled by the base class.

docs/design-tokens.md updated to record the new token pairs.

Tests: 69/69.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:10:14 +02:00
Konrad du Plessis
bfe4e4d616 docs(ui): design for payroll action-buttons pastel soft-fill
Four buttons at top of /payroll/ currently mix 3 treatments (outline
+ solid btn-primary one-off). Design swaps all 4 to a unified
.btn-action-soft base class with per-button colour modifiers
(Lookup=blue, Pay=amber, Add=green, Price=mauve). Reuses existing
--badge-*-bg tokens for the Add + Price buttons; adds 2 new token
pairs for Lookup + Pay. Removes the shadow-sm / btn-sm / fw-bold
one-offs — the new class handles sizing + weight.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:07:37 +02:00
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
4 changed files with 228 additions and 17 deletions

View File

@ -29,17 +29,20 @@
<div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center gap-3 mb-4">
<h1 class="page-title mb-0"><i class="fas fa-wallet me-2" style="color: var(--accent);"></i>Payroll Dashboard</h1>
<div class="d-flex flex-wrap gap-2 payroll-actions">
<button type="button" class="btn btn-outline-info shadow-sm btn-sm btn-md-normal" id="workerLookupBtn">
<i class="fas fa-id-card fa-sm me-1"></i> Worker Lookup
{# Pastel soft-fill action buttons — unified treatment via .btn-action-soft #}
{# + per-button colour modifier. Shadow, sizing, padding all live on the #}
{# base class so the template stays lean. See docs/design-tokens.md. #}
<button type="button" class="btn-action-soft btn-action-lookup" id="workerLookupBtn">
<i class="fas fa-id-card"></i> Worker Lookup
</button>
<button type="button" class="btn btn-primary shadow-sm btn-sm btn-md-normal" id="batchPayBtn" title="Pay all workers with a configured pay schedule for their current pay period">
<i class="fas fa-users fa-sm me-1"></i> Batch Pay
<button type="button" class="btn-action-soft btn-action-pay" id="batchPayBtn" title="Pay all workers with a configured pay schedule for their current pay period">
<i class="fas fa-users"></i> Batch Pay
</button>
<button type="button" class="btn btn-outline-success shadow-sm btn-sm btn-md-normal fw-bold" data-bs-toggle="modal" data-bs-target="#addAdjustmentModal">
<i class="fas fa-plus fa-sm me-1"></i> Add Adjustment
<button type="button" class="btn-action-soft btn-action-add" data-bs-toggle="modal" data-bs-target="#addAdjustmentModal">
<i class="fas fa-plus"></i> Add Adjustment
</button>
<button type="button" class="btn btn-outline-warning shadow-sm btn-sm btn-md-normal" data-bs-toggle="modal" data-bs-target="#priceOvertimeModal">
<i class="fas fa-clock fa-sm me-1"></i> Price Overtime
<button type="button" class="btn-action-soft btn-action-price" data-bs-toggle="modal" data-bs-target="#priceOvertimeModal">
<i class="fas fa-clock"></i> Price Overtime
</button>
</div>
</div>
@ -513,10 +516,14 @@
<td class="ps-4 align-middle"><a href="#" class="worker-lookup-link fw-bold"
data-worker-id="{{ loan.worker.id }}">{{ loan.worker.name }}</a></td>
<td class="align-middle">
{# Loan vs Advance: same semantic palette as the Adjustments tab #}
{# Loan-type rows wear amber (.loan-flag-badge), advances wear blue #}
{# (.advance-flag-badge). Transactional state ("Active" / "Paid Off") #}
{# is separate — see the next cell — and stays on Bootstrap colours. #}
{% if loan.loan_type == 'advance' %}
<span class="badge bg-info text-dark">Advance</span>
<span class="badge advance-flag-badge">Advance</span>
{% else %}
<span class="badge bg-primary">Loan</span>
<span class="badge loan-flag-badge">Loan</span>
{% endif %}
</td>
<td class="align-middle">R {{ loan.principal_amount|floatformat:2 }}</td>
@ -2556,8 +2563,12 @@ document.addEventListener('DOMContentLoaded', function() {
var topRow = document.createElement('div');
topRow.className = 'd-flex justify-content-between align-items-center mb-1';
// Loan-type badge in the Preview-payslip / Worker-lookup modal's
// "Active Loans & Advances" card — mirrors the server-rendered
// /payroll/?status=loans colours so the same loan looks the same
// everywhere. See custom.css .loan-flag-badge / .advance-flag-badge.
var badge = document.createElement('span');
badge.className = 'badge ' + (loan.type === 'advance' ? 'bg-info text-dark' : 'bg-primary');
badge.className = 'badge ' + (loan.type === 'advance' ? 'advance-flag-badge' : 'loan-flag-badge');
badge.textContent = loan.type_label;
topRow.appendChild(badge);

View File

@ -33,6 +33,25 @@ 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
## Button-action tokens (payroll dashboard)
Pastel soft-fill palette for the 4 action buttons at the top of
`/payroll/` (Worker Lookup / Batch Pay / Add Adjustment / Price
Overtime). Defined alongside the badge tokens in the same `:root` /
`[data-theme="light"]` blocks.
| Token pair | Button | Dark BG | Dark FG | Light BG | Light FG |
|---|---|---|---|---|---|
| `--btn-action-lookup-bg/fg` | Worker Lookup | `#3e5c7b` | `#d7e5f2` | `#c7d9e8` | `#243b56` |
| `--btn-action-pay-bg/fg` | Batch Pay | `#7a4d1a` | `#fae0c3` | `#f5d6a8` | `#633e0e` |
| _reuses `--badge-bonus-*`_ | Add Adjustment | (see Bonus row above) | | | |
| _reuses `--badge-overtime-*`_ | Price Overtime | (see Overtime row above) | | | |
The CSS classes are `.btn-action-soft` (shared shape) + one of
`.btn-action-lookup` / `.btn-action-pay` / `.btn-action-add` /
`.btn-action-price` (colour modifier). See the `.btn-action-soft`
block in `custom.css` for hover/active/focus behaviour.
## Where each colour appears
| Semantic | Used by |
@ -40,9 +59,9 @@ Token definitions live in `static/css/custom.css`:
| `--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`) |
| `--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 |
| `--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)

View File

@ -0,0 +1,122 @@
# Payroll Action Buttons — Pastel Soft-Fill (24 Apr 2026)
## Origin
Konrad on the 4 action buttons at the top of `/payroll/`:
> _"Can you use your top notch design skills and make this look better
> and more uniform with also some pastel colors"_
Current state: Worker Lookup (`btn-outline-info`), Batch Pay
(`btn-primary` — the odd one out, solid dark blue), Add Adjustment
(`btn-outline-success`), Price Overtime (`btn-outline-warning`). Three
treatments, four colour families, visually inconsistent.
Scope chosen: **A — pastel soft-fill**. All 4 become solid pastel fill,
no border, with darker text in the same colour family. Each retains a
colour hint for its role; all look like siblings.
## Design
### Base class
`.btn-action-soft` — shared shape for all 4 buttons:
- `display: inline-flex; align-items: center; gap: 0.4rem`
- `padding: 0.4rem 0.9rem`
- `font-size: 0.875rem; font-weight: 500`
- `border: none; border-radius: 0.5rem`
- `transition: filter 150ms, transform 80ms`
- Hover: `filter: brightness(1.08)`
- Active: `transform: translateY(1px)`
- Focus-visible: `outline: 2px solid var(--accent); outline-offset: 2px`
Removes both `btn-outline-*` and `btn-primary` from the template — the
new class is self-sufficient, doesn't layer on top of Bootstrap's
`.btn` family.
### Per-button colour — reuses existing `--badge-*` tokens where possible
| Button | Modifier class | Tokens used (reused) |
|---|---|---|
| Worker Lookup | `.btn-action-lookup` | new `--btn-action-lookup-bg/fg` (soft blue, similar to advance family) |
| Batch Pay | `.btn-action-pay` | new `--btn-action-pay-bg/fg` (soft amber — brand-adjacent, marks it as primary) |
| Add Adjustment | `.btn-action-add` | reuses `--badge-bonus-bg/fg` (green — "adding money" matches Bonus semantic) |
| Price Overtime | `.btn-action-price` | reuses `--badge-overtime-bg/fg` (mauve — matches the Overtime adjustment badge) |
Four new CSS variables per theme (`--btn-action-lookup-bg/fg`,
`--btn-action-pay-bg/fg`) plus two reuses of existing badge tokens. Net
+ 8 CSS vars (4 × 2 themes), + 5 CSS classes, 4 Bootstrap class
applications in the template.
### Dark theme palette
```css
--btn-action-lookup-bg: #3e5c7b; --btn-action-lookup-fg: #d7e5f2;
--btn-action-pay-bg: #7a4d1a; --btn-action-pay-fg: #fae0c3;
/* add: reuses --badge-bonus-bg (#5b8260) / --badge-bonus-fg (#e8f3ea) */
/* price: reuses --badge-overtime-bg (#a16881) / --badge-overtime-fg (#fce4ec) */
```
### Light theme palette
```css
--btn-action-lookup-bg: #c7d9e8; --btn-action-lookup-fg: #243b56;
--btn-action-pay-bg: #f5d6a8; --btn-action-pay-fg: #633e0e;
/* add: reuses --badge-bonus-bg (#d7e8d9) / --badge-bonus-fg (#385640) */
/* price: reuses --badge-overtime-bg (#f3d1dd) / --badge-overtime-fg (#703347) */
```
### Template change
`core/templates/core/payroll_dashboard.html` — find the 4-button group
with class `payroll-actions` (near the top). Replace each button's
class list:
| Before | After |
|---|---|
| `btn btn-outline-info shadow-sm btn-sm btn-md-normal` | `btn-action-soft btn-action-lookup` |
| `btn btn-primary shadow-sm btn-sm btn-md-normal` | `btn-action-soft btn-action-pay` |
| `btn btn-outline-success shadow-sm btn-sm btn-md-normal fw-bold` | `btn-action-soft btn-action-add` |
| `btn btn-outline-warning shadow-sm btn-sm btn-md-normal` | `btn-action-soft btn-action-price` |
Shadow and size modifiers come from `.btn-action-soft` itself — no
need for `shadow-sm` / `btn-sm`. The `fw-bold` on Add Adjustment was
a workaround for the faint outline treatment; the new class has
sufficient presence without it.
## Out of scope
- Extending this treatment to buttons elsewhere in the app — defer to
a future "app-wide button pass" if this looks right
- Changing the icons or labels
- Moving or reorganising the button row
- Button ordering (it stays: Lookup / Batch Pay / Add Adjustment /
Price Overtime)
## Risks
- **Contrast** on the soft-fill pastels might be borderline in light
mode. Implementation will spot-check each with WebAIM contrast-check
logic (target: WCAG AA for UI elements — 3:1 minimum for icon/text
against background).
- **One-off `fw-bold` on Add Adjustment** — the current template has
it to compensate for the faint outline. Removing it with the new
class is intentional; if the new `.btn-action-add` reads too
lightly, re-apply `fw-bold` or bump the text weight in
`.btn-action-soft` base.
- **Batch Pay "is this still the primary?"** — it now wears soft
amber instead of solid dark blue. The amber is slightly more
saturated than the other three, which preserves a visual hierarchy.
If Konrad wants stronger emphasis, we can deepen
`--btn-action-pay-bg` further or add a subtle 1px `--accent` ring.
## Rollback
Single commit, `git revert <sha>`. No data, schema, behavioural
change.
## Next step
Generate a brief implementation plan via writing-plans → execute via
subagent-driven-development. Auto mode active, no checkpoints — this
is a 1-2 task implementation.

View File

@ -89,6 +89,15 @@
--badge-loan-rep-bg: #b48a1a; --badge-loan-rep-fg: #fef4d1;
--badge-advance-bg: #3e5c7b; --badge-advance-fg: #d7e5f2;
--badge-advance-rep-bg: #2f679a; --badge-advance-rep-fg: #d7e5f2;
/* === PAYROLL DASHBOARD action-button tokens (dark theme) ===
Soft-fill pastels for the 4 action buttons at the top of /payroll/
(Worker Lookup / Batch Pay / Add Adjustment / Price Overtime).
Lookup + Pay introduce new tokens; Add + Price reuse the bonus
+ overtime adjustment-badge tokens so the payroll page's action
row visually echoes the badges below it. */
--btn-action-lookup-bg: #3e5c7b; --btn-action-lookup-fg: #d7e5f2;
--btn-action-pay-bg: #7a4d1a; --btn-action-pay-fg: #fae0c3;
}
/* === LIGHT MODE === */
@ -153,6 +162,10 @@
--badge-loan-rep-bg: #f7d873; --badge-loan-rep-fg: #5a4418;
--badge-advance-bg: #bccee0; --badge-advance-fg: #243b56;
--badge-advance-rep-bg: #9ec1dd; --badge-advance-rep-fg: #1d3550;
/* === PAYROLL DASHBOARD action-button tokens (light theme) === */
--btn-action-lookup-bg: #c7d9e8; --btn-action-lookup-fg: #243b56;
--btn-action-pay-bg: #f5d6a8; --btn-action-pay-fg: #633e0e;
}
/* ===================================================================
@ -1941,14 +1954,60 @@ body, .card, .modal-content, .form-control, .form-select,
.badge-type-advance-repayment { background: var(--badge-advance-rep-bg); color: var(--badge-advance-rep-fg); }
/* --- Status flags that borrow a type's colour for semantic consistency.
"Has an active loan or advance" -> Loan-type amber/yellow, so the
worker flag on the Pending tab visually matches the Adjustments
type badge for Loan. Keeps the Loan colour family unified across
the app regardless of which tab you're looking at. --- */
The Pending tab's "Loan" worker flag (Has-an-active-loan-or-advance),
and the Loans-and-Advances tab's per-row type badge (Loan vs Advance),
should all look like the Adjustments tab's Loan + Advance type badges.
Same concept, same colour, every tab. --- */
.loan-flag-badge {
background: var(--badge-loan-bg);
color: var(--badge-loan-fg);
}
.advance-flag-badge {
background: var(--badge-advance-bg);
color: var(--badge-advance-fg);
}
/* ===================================================================
Payroll dashboard action buttons pastel soft-fill (24 Apr 2026)
---------------------------------------------------------------
Replaces the earlier mix of `btn-outline-info` / `btn-primary` /
`btn-outline-success` / `btn-outline-warning` at the top of /payroll/
with a single uniform treatment: solid pastel fill, no border,
contrasting text in the same colour family. All four buttons now
look like siblings while each retains a colour hint of its role.
================================================================= */
.btn-action-soft {
display: inline-flex;
align-items: center;
gap: 0.4rem;
padding: 0.4rem 0.9rem;
font-size: 0.875rem;
font-weight: 500;
border: none;
border-radius: 0.5rem;
line-height: 1.25;
cursor: pointer;
/* `filter: brightness(...)` on hover is GPU-cheap and gives a
subtle lift without having to define 4×2 = 8 hover colours. */
transition: filter 150ms ease, transform 80ms ease, box-shadow 150ms ease;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
.btn-action-soft:hover { filter: brightness(1.08); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.14); }
.btn-action-soft:active { transform: translateY(1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); }
.btn-action-soft:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn-action-soft:disabled { opacity: 0.55; cursor: not-allowed; filter: none; }
/* Icon sits inline with text; inherit colour so it always matches. */
.btn-action-soft .fas { font-size: 0.85em; }
/* --- Per-button colour modifiers.
Lookup + Pay use dedicated --btn-action-*-bg/fg tokens (new).
Add reuses --badge-bonus-* (green, "adding money" semantic).
Price reuses --badge-overtime-* (mauve, matches Overtime badge
on the Adjustments tab). --- */
.btn-action-lookup { background: var(--btn-action-lookup-bg); color: var(--btn-action-lookup-fg); }
.btn-action-pay { background: var(--btn-action-pay-bg); color: var(--btn-action-pay-fg); }
.btn-action-add { background: var(--badge-bonus-bg); color: var(--badge-bonus-fg); }
.btn-action-price { background: var(--badge-overtime-bg); color: var(--badge-overtime-fg); }
/* --- Sticky filter bar (keeps filters visible as the table scrolls) --- */
.adjustments-filter-bar {