From ce1376edc98c89194d27c412c7d78a5ef0f1e7fa Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 27 Aug 2026 20:41:58 -0400 Subject: [PATCH] refactor(ui): the badge layer gets one owner per shape (#3132 items 1-3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ITEM 1 — the dead canon. StatusBadge is recorded canon (#2960) and its only consumer, TaskCard, has been unreachable since 2026-04-08, when TasksListView was deleted in favour of the Knowledge view. Four and a half months of a canon that rendered nowhere, which is worse than no canon: a session pulls #2960, builds from it, and matches a component nobody has seen. TaskCard is deleted (rule 22), and the canon is made real by adoption rather than by being left as a museum piece. ITEM 2 — MY OWN ISSUE OVERSTATED THIS, and the correction is the finding. "Three scoped re-spellings" assumed one shape spelled thrice. Reading them: KnowledgeView a task-status chip, just smaller -> a real duplicate WorkspaceTaskPanel a CLICKABLE cycler: pointer, outlined, transparent background -> a control, not a chip ProjectView PROJECT lifecycle (active/paused/ completed/archived) -> a different vocabulary Only the first was ever a duplicate. The others shared a class NAME and nothing else — which is exactly what would make a future consolidation merge three unrelated things. So: KnowledgeView adopts StatusBadge/PriorityBadge via the `compact` variant the canon already anticipated ("interactive/compact re-spellings are variants of it"); the cycler becomes `.status-cycler`; and project status becomes its own vocabulary. And there was a FOURTH, in ProjectListView — the genuine duplicate of ProjectView's project pill, differing by the amounts two hands differ by: 0.68rem vs 0.7rem, a 14% tint vs 15%, one bordered and one not. Both now use one ProjectStatusBadge. `statusLabel` went with its only caller. ITEM 3 — weight. StatusBadge and PriorityBadge used font-weight 600; the house style allows 400 and 500 only. Also "In Progress" -> "In progress", which was invisible under `text-transform: uppercase` and becomes visible the moment the compact variant turns that off. THE GUARD MISSED FOUR LIVE SITES, which is the part worth keeping. The project pills painted a hue on an inline `color-mix` tint of itself — measured 1.61-2.39:1 — and the checker only knew the `--fs-X-bg` token form. Widened, it finds 48 across the app, 26 of them --fs-accent. That backlog is not this task, so the check now splits: it GATES the token form, which is clean, and REPORTS the inline form with a count and its worst offenders. A gate nobody can satisfy today gets switched off, and then it guards nothing. Gate re-verified by reintroducing a defect — exit 1 with it, exit 0 without. Co-Authored-By: Claude Opus 5 (1M context) --- frontend/src/components/PriorityBadge.vue | 14 +- .../src/components/ProjectStatusBadge.vue | 71 ++++++ frontend/src/components/StatusBadge.vue | 17 +- frontend/src/components/TaskCard.vue | 238 ------------------ .../src/components/WorkspaceTaskPanel.vue | 11 +- frontend/src/views/KnowledgeView.vue | 35 +-- frontend/src/views/ProjectListView.vue | 34 +-- frontend/src/views/ProjectView.vue | 18 +- scripts/check_design_tokens.py | 52 +++- 9 files changed, 160 insertions(+), 330 deletions(-) create mode 100644 frontend/src/components/ProjectStatusBadge.vue delete mode 100644 frontend/src/components/TaskCard.vue diff --git a/frontend/src/components/PriorityBadge.vue b/frontend/src/components/PriorityBadge.vue index 8314db2..a370c85 100644 --- a/frontend/src/components/PriorityBadge.vue +++ b/frontend/src/components/PriorityBadge.vue @@ -3,6 +3,8 @@ import type { TaskPriority } from "@/types/task"; const props = defineProps<{ priority: TaskPriority; + /** Dense surfaces — see StatusBadge. */ + compact?: boolean; }>(); const labels: Record = { @@ -16,7 +18,7 @@ const labels: Record = {