All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 5m1s
CI / OCR Service Tests (pull_request) Successful in 26s
CI / Backend Unit Tests (pull_request) Successful in 6m32s
CI / fail2ban Regex (pull_request) Successful in 46s
CI / Semgrep Security Scan (pull_request) Successful in 22s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m8s
SDD Gate / RTM Check (pull_request) Successful in 15s
SDD Gate / Contract Validate (pull_request) Successful in 22s
SDD Gate / Constitution Impact (pull_request) Successful in 19s
Completes DESIGN_RULES §1 so the rest of the Mappe shared components have a full token substrate: - Add --radius-sm/md/full and --shadow-sm/md as first-class :root tokens in layout.css. Radius is theme-invariant; --shadow-sm/md get distinct, stronger dark values in BOTH dark blocks (the @media and [data-theme='dark'] selectors stay in sync) because the light navy-on-sand shadow is invisible on dark surfaces. - Add $lib/shared/avatarPalette.ts: the canonical 10-color person/avatar palette as a single exported constant (single source of truth for <Avatar>, issue #855). Three §5 hues failed the >=4.5:1 white-initials contrast floor and ship as AA-darkened variants (sage #527e61, amber #a46800, sand #897239); the bright hues stay the decorative tag-dot colors in layout.css. Guarded by avatarPalette.spec.ts (length, hex, distinct, WCAG AA). Tag-sand naming and the theme storage key were already correct in layout.css/app.html; this only closed the remaining token gaps. No consumer rewiring (deferred to #855). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
33 lines
1.4 KiB
TypeScript
33 lines
1.4 KiB
TypeScript
/**
|
|
* Canonical 10-color person/avatar palette — single source of truth.
|
|
*
|
|
* Used by `<Avatar>` (issue #855), hashed by name so the same person renders the
|
|
* same color on every screen (DESIGN_RULES §5). Do not duplicate these values in
|
|
* CSS or another module; import this constant instead.
|
|
*
|
|
* White Montserrat initials sit on each color, so every swatch must meet WCAG AA
|
|
* (≥4.5:1) for normal text — avatar initials are 700-weight but ≤16px, below the
|
|
* large-text threshold. The background is theme-invariant (identical hex in light
|
|
* and dark, white initials in both), so one white-on-color check covers both
|
|
* themes. Guarded by `avatarPalette.spec.ts`.
|
|
*
|
|
* Three §1 brand hues failed white-on-color and use AA-darkened variants here;
|
|
* the bright originals remain the decorative tag-dot colors in `layout.css`
|
|
* (tag dots carry no text, so the contrast floor does not apply to them):
|
|
* sage #5a8a6a → #527e61 (3.98 → 4.65:1)
|
|
* amber #c17a00 → #a46800 (3.47 → 4.61:1)
|
|
* sand #9a8040 → #897239 (3.79 → 4.64:1)
|
|
*/
|
|
export const AVATAR_PALETTE = [
|
|
'#527e61', // sage (AA-adjusted from #5a8a6a)
|
|
'#a0522d', // sienna
|
|
'#a46800', // amber (AA-adjusted from #c17a00)
|
|
'#607080', // slate
|
|
'#7a4f9a', // violet
|
|
'#c0446e', // rose
|
|
'#3060b0', // cobalt
|
|
'#4a7a3a', // moss
|
|
'#897239', // sand (AA-adjusted from #9a8040)
|
|
'#c05540' // coral
|
|
] as const;
|