From 5034b7a80f7e6223ff196a1d207616839126da1d Mon Sep 17 00:00:00 2001 From: Claude Fable 5 Date: Tue, 28 Jul 2026 20:37:44 +0200 Subject: [PATCH] #180: promote remaining hardcoded base.css colors to design tokens New tokens (light values, dark arrives with the theme block): surface-muted (was fallback-only), danger-contrast, danger-strong, badge ok/error/warn pairs, chip-outline. Replace the phantom --color-primary with the real --color-accent and unify the three danger reds (#a02818/#b91c1c/#ab091e) on --color-danger. attachments-panel maps to bg-subtle, matching its old 6%-grey fallback. Light rendering is visually unchanged. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01QRtCnB3uLdQtFmvp9HXcRX --- apps/web/src/styles/base.css | 39 ++++++++++++++++++---------------- apps/web/src/styles/tokens.css | 20 +++++++++++++++++ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/apps/web/src/styles/base.css b/apps/web/src/styles/base.css index a4b0538..2f70fc1 100644 --- a/apps/web/src/styles/base.css +++ b/apps/web/src/styles/base.css @@ -1401,6 +1401,8 @@ button { margin-left: -0.4rem; border: 2px solid var(--color-bg); border-radius: 50%; + /* Deliberately NOT a theme token: USER_COLORS backgrounds are chosen so + white text clears 4.5:1 (user-color.test.ts) independent of the theme. */ color: #ffffff; font-size: 0.7rem; font-weight: 600; @@ -1443,6 +1445,7 @@ button { left: -1px; padding: 0.05rem 0.3rem; border-radius: 3px 3px 3px 0; + /* White on USER_COLORS, theme-independent — see .presence-avatar. */ color: #ffffff; font-size: 0.7rem; font-weight: 600; @@ -2210,7 +2213,7 @@ ul[data-type='task_list'] li p:last-of-type { } .member-seats__item { - background: var(--color-surface-muted, rgba(127, 127, 127, 0.12)); + background: var(--color-surface-muted); border-radius: var(--radius-sm, 0.375rem); padding: var(--space-1) var(--space-2); font-size: 0.875rem; @@ -3007,7 +3010,7 @@ ul[data-type='task_list'] li p:last-of-type { border-radius: var(--radius-sm, 0.375rem); padding: var(--space-3); margin-bottom: var(--space-3); - background: var(--color-surface-muted, rgba(127, 127, 127, 0.06)); + background: var(--color-bg-subtle); } .attachments-panel__header { @@ -3197,23 +3200,23 @@ ul[data-type='task_list'] li p:last-of-type { padding: 0.1rem 0.5rem; border-radius: 999px; font-size: 0.8125rem; - background: var(--color-surface-muted, #e2e8f0); + background: var(--color-surface-muted); margin-left: var(--space-1); } .system-badge--ok { - background: #d6f2df; - color: #1d6f42; + background: var(--color-badge-ok-bg); + color: var(--color-badge-ok-text); } .system-badge--error { - background: #fbe3e0; - color: #a02818; + background: var(--color-badge-error-bg); + color: var(--color-badge-error-text); } .system-badge--warn { - background: #fdf0d4; - color: #8a5a00; + background: var(--color-badge-warn-bg); + color: var(--color-badge-warn-text); } .system-jobs__notice { @@ -3312,11 +3315,11 @@ ul[data-type='task_list'] li p:last-of-type { .button--danger { border-color: var(--color-danger); background: var(--color-danger); - color: var(--color-accent-contrast); + color: var(--color-danger-contrast); } .button--danger:hover:not(:disabled) { - background: #8a0718; + background: var(--color-danger-strong); } /* Pond creation form in the switcher + pond danger zone */ @@ -3527,7 +3530,7 @@ ul[data-type='task_list'] li p:last-of-type { .comments-section__count { margin-left: var(--space-2); font-size: 0.8125rem; - background: var(--color-surface-muted, #e2e8f0); + background: var(--color-surface-muted); border-radius: 999px; padding: 0.05rem 0.5rem; } @@ -3604,7 +3607,7 @@ ul[data-type='task_list'] li p:last-of-type { background: none; border: none; padding: 0; - color: var(--color-primary, #2f6f4f); + color: var(--color-accent); cursor: pointer; font-size: 0.8125rem; text-decoration: underline; @@ -3641,8 +3644,8 @@ ul[data-type='task_list'] li p:last-of-type { /* Watches (issue #93) */ .watch-toggle--active { - background: var(--color-primary, #2f6f4f); - color: #fff; + background: var(--color-accent); + color: var(--color-accent-contrast); } .watches-list { @@ -3696,8 +3699,8 @@ ul[data-type='task_list'] li p:last-of-type { position: absolute; top: -2px; right: -4px; - background: #a02818; - color: #fff; + background: var(--color-danger); + color: var(--color-danger-contrast); border-radius: 999px; font-size: 0.7rem; padding: 0 0.35rem; @@ -3929,7 +3932,7 @@ ul[data-type='task_list'] li p:last-of-type { } .dt-date--overdue { - color: #b91c1c; + color: var(--color-danger); } /* Task overview block (issue #154). */ diff --git a/apps/web/src/styles/tokens.css b/apps/web/src/styles/tokens.css index 380f34e..0119119 100644 --- a/apps/web/src/styles/tokens.css +++ b/apps/web/src/styles/tokens.css @@ -21,6 +21,9 @@ * token with a #fff fallback; the fallback-less ones dropped their * background entirely (#120). */ --color-surface: #ffffff; + /* Muted pill/badge surfaces (member seats, count pills, neutral badges). + Was a fallback-only value scattered through base.css before #180. */ + --color-surface-muted: #e2e8f0; --color-border: #d9e2ec; /* Boundaries of interactive controls (inputs, selects) need 3:1 against both backgrounds (WCAG 1.4.11) — #d9e2ec is only ~1.3:1. */ @@ -28,11 +31,28 @@ --color-accent: #2f6f4f; --color-accent-contrast: #ffffff; --color-danger: #ab091e; + /* Text sitting ON a danger background (buttons, notification badge) — + paired with --color-danger the same way --color-accent-contrast is + paired with --color-accent; the two must flip together per theme. */ + --color-danger-contrast: #ffffff; + --color-danger-strong: #8a0718; --color-ok: #14803c; /* Favorite stars and tree icons (issue #132) — a readable gold. ICON use only: 3.25:1 passes the 3:1 non-text minimum but NOT the 4.5:1 required for text (audit A11Y-024c). */ --color-favorite: #b8860b; + /* Status badges (admin system page): pastel surface + strong text, each + pair ≥ 4.5:1 in both themes (asserted by theme-contrast.test.ts). */ + --color-badge-ok-bg: #d6f2df; + --color-badge-ok-text: #1d6f42; + --color-badge-error-bg: #fbe3e0; + --color-badge-error-text: #a02818; + --color-badge-warn-bg: #fdf0d4; + --color-badge-warn-text: #8a5a00; + /* Separation ring for user-colored label chips/swatches — invisible on + light, a faint light outline on dark where arbitrary label colors can + melt into the background. */ + --color-chip-outline: transparent; /* Spacing scale (rem-based). */ --space-1: 0.25rem;