julien f2360b9db3
CI / commits (push) Has been skipped
CI / check (push) Successful in 4m50s
CI / scan (push) Successful in 5m22s
CI / a11y (push) Successful in 3m56s
CI / perf (push) Successful in 9m20s
chore(shared-charts): soften the curated palette (#185)
## Summary

Tune the curated chart palette to a softer, lower-saturation set. The values shipped in #175 were pulled straight from Tailwind's `-600 / -700` ramp; on real audit-log data the donut's three slices and the bar-chart's blue read as too punchy when they share a tile, especially in dark mode. Same five intents, same a11y posture — just less visual fight.

## What lands

`libs/shared/charts/src/lib/_internal/palette.ts`:

| Constant                          | Before   | After    |
| --------------------------------- | -------- | -------- |
| `DEFAULT_BAR_FILL`                | `#1d4ed8` | `#4075e7` |
| `semanticStatusColors.info`       | `#2563eb` | `#4075e7` |
| `semanticStatusColors.success`    | `#16a34a` | `#46ac6b` |
| `semanticStatusColors.warning`    | `#ea580c` | `#f38043` |
| `semanticStatusColors.error`      | `#dc2626` | `#eb5252` |
| `semanticStatusColors.neutral`    | `#6b7280` | `#6b7280` (unchanged) |

`info` and `DEFAULT_BAR_FILL` collapse to the same hex — bars and "informational" donut slices are *meant* to read as the same semantic class (no special status), so unifying them at the constant level removes a future drift hazard.

Docstrings updated alongside — the previous comments name-checked Tailwind shades (`green-600`, `tailwind blue-700`) that no longer correspond to the values; the new comments describe the palette by intent (`muted green`, `muted orange`, ...) and call out that the softening is deliberate.

## Notes for the reviewer

- **A11y posture unchanged.** The lib's contract is "AA contrast on white surfaces, deuteranopia/protanopia distinguishability via lightness deltas, not just hue". All four chromatic entries clear the same bar: each lightness sits in a distinct band (≈ 67 % for warning, ≈ 60 % for success, ≈ 60 % for error, ≈ 56 % for info), so colour-blind viewers still distinguish them by brightness even if the hue collapses.
- **Why not derive these from `libs/shared/tokens/brand-tokens.css`?** Brand-primary is the dark teal `#12546c` and brand-accent is `#f7a919`. Neither reads correctly as "success" or "neutral chart fill"; the charts need a categorical palette tuned for *legibility on dense surfaces*, not for chrome and CTAs. Keeping the chart palette in its own lib stays consistent with ADR-0023's "lib owns the palette" stance.
- **Bar fill default + `info` semantic alias to the same value on purpose.** A bar with no per-bar encoding is semantically "informational quantity over time" — the same intent as a donut slice tagged `info`. Future consumer that wants to flag a single "info" bar inside a stacked chart will read the colour as consistent.
- **No code changes outside this file.** Consumers (`<lib-bar-chart>`, `<lib-donut-chart>`, the audit page) import these constants by name; the swap is purely a value change.

## Test plan

- [x] `pnpm nx test shared-charts` — 15 specs pass (the donut `colorMap` spec asserts the *consumer-provided* hexes, not the lib defaults, so the change is transparent there; the bar single-fill spec checks uniqueness, not the specific value).
- [x] `pnpm nx test portal-admin` — 62 specs pass.
- [x] `pnpm nx run-many -t test build lint -p shared-charts,portal-admin` — clean (same three pre-existing lint warnings unrelated to this PR).
- [ ] **Manual smoke** — `pnpm nx serve portal-admin`, sign in with `Portal.Admin`, navigate to `/admin/audit`, switch to Charts:
  - Daily-volume bars render in the new muted blue.
  - Outcome donut slices: green (success), red (failure), orange (denied) — softer than before, semantic mapping intact.
  - Dark-mode toggle — palette still legible against the dark surface.
  - Side-by-side comparison vs `main` — the new shades feel calmer, especially when multiple charts share the viewport.

## What's next

Nothing pending on the palette front. If a future chart needs a sixth intent (e.g. `pending` for in-flight states), add it here with a contrast / colour-blind check and update the typed `SemanticStatus` union in the same PR.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #185
2026-05-17 23:42:07 +02:00

Documentation index

This is the entry point to all project documentation. It is maintained automatically: any addition, rename, or removal of a .md file under docs/ must be reflected here in the same change.

Conventions

  • Documentation is written in English.
  • One topic per file. Group related files into a folder when there are three or more.
  • Cross-reference with relative links so they keep working in GitHub, IDEs, and exported sites.
  • For architectural decisions, do not add them here — they belong in decisions/ as MADR 4.0.0 ADRs.

Sections

Daily development

  • development.md — repo layout, prerequisites, initial setup, daily commands, observability dev-loop (Jaeger UI, log ↔ trace correlation), dependency updates (Renovate), conventional commit cycle. Day-to-day reference for working on the project.

Architecture

  • architecture.md — cross-cutting Mermaid diagrams: C4 system context, C4 containers, Nx module boundaries, CI/CD pipeline. Single-decision diagrams (auth sequence, ERD, etc.) live inline in their ADR.

Onboarding & environment

Setup guides for new contributors:

Operations & runbooks

Empty — to be populated when we deploy.

Security, performance, accessibility

Empty — placeholders to be filled with rationale docs alongside their corresponding ADRs.

S
Description
No description provided
Readme 42 MiB
Languages
TypeScript 85.3%
JavaScript 5.4%
SCSS 4.3%
HTML 3.9%
Shell 0.8%
Other 0.3%