From e19977709364331deecc842bc05702a9dd7df612 Mon Sep 17 00:00:00 2001 From: Jeffrey Smith Date: Wed, 1 Apr 2026 11:17:40 +0000 Subject: [PATCH] Feat v0.6.11 CSS deduplication (#46) Retire old primitives.css button/toast/popup-menu/dropdown/tabs systems. sw-primitives.css is now the single source of truth. - Migrate 29 files from .btn-* to .sw-btn .sw-btn--{variant} .sw-btn--{size} - Delete old toast, popup-menu, dropdown, tabs CSS (no JS references) - Resolve .sw-dropdown and .sw-tabs class name collisions - Resolve .settings-section duplicate (modals.css removed, surfaces.css authoritative) - Add .sw-btn--success variant, --bg-active CSS variable - Fix sdk-test-runner wrong variable names, icd-test-runner button fallbacks - Add scripts/audit-css-collisions.sh Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 50 ++++++++++ ROADMAP-UI.md | 6 +- ROADMAP.md | 2 +- VERSION | 2 +- packages/dashboard/js/main.js | 4 +- packages/editor/css/main.css | 2 +- packages/git-board/css/main.css | 9 +- packages/git-board/js/main.js | 8 +- packages/hello-dashboard/js/main.js | 4 +- packages/icd-test-runner/css/main.css | 40 +------- packages/icd-test-runner/js/ui.js | 30 +++--- packages/sdk-test-runner/css/main.css | 34 +++---- packages/workflow-demo/css/main.css | 12 +-- packages/workflow-demo/js/main.js | 2 +- scripts/audit-css-collisions.sh | 74 +++++++++++++++ .../templates/components/file-upload.html | 2 +- src/css/modals.css | 7 +- src/css/primitives.css | 92 ++----------------- src/css/sw-primitives.css | 2 + src/css/variables.css | 2 + src/css/workflow.css | 12 +-- src/js/sw/components/debug/index.js | 10 +- src/js/sw/surfaces/admin/audit.js | 4 +- src/js/sw/surfaces/admin/backup.js | 8 +- src/js/sw/surfaces/admin/broadcast.js | 2 +- src/js/sw/surfaces/admin/connections.js | 8 +- src/js/sw/surfaces/admin/groups.js | 20 ++-- src/js/sw/surfaces/admin/packages.js | 24 ++--- src/js/sw/surfaces/admin/settings.js | 4 +- src/js/sw/surfaces/admin/storage.js | 2 +- src/js/sw/surfaces/admin/teams.js | 18 ++-- src/js/sw/surfaces/admin/users.js | 16 ++-- src/js/sw/surfaces/admin/workflows.js | 12 +-- src/js/sw/surfaces/settings/appearance.js | 2 +- src/js/sw/surfaces/settings/connections.js | 8 +- src/js/sw/surfaces/settings/general.js | 2 +- src/js/sw/surfaces/settings/notifications.js | 2 +- src/js/sw/surfaces/settings/profile.js | 8 +- src/js/sw/surfaces/team-admin/activity.js | 4 +- src/js/sw/surfaces/team-admin/connections.js | 8 +- src/js/sw/surfaces/team-admin/index.js | 2 +- src/js/sw/surfaces/team-admin/members.js | 14 +-- src/js/sw/surfaces/team-admin/settings.js | 2 +- src/js/sw/surfaces/team-admin/workflows.js | 52 +++++------ 44 files changed, 311 insertions(+), 317 deletions(-) create mode 100644 scripts/audit-css-collisions.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index bd144aa..3a4cd67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,56 @@ All notable changes to Armature are documented here. +## v0.6.11 — CSS Deduplication + +One class per concept. The old `primitives.css` button, toast, popup-menu, +dropdown, and tabs systems are retired. `sw-primitives.css` is the single +source of truth for all Preact component styles. + +### Changed + +- **Buttons**: All 29 files migrated from `.btn-primary` / `.btn-small` / + `.btn-danger` / `.btn-ghost` / `.btn-md` / `.btn-sm` to the BEM-style + `.sw-btn .sw-btn--{variant} .sw-btn--{size}` system. +- **Toasts**: Old `.toast-container` / `.toast` CSS deleted. SDK's + `sw.toast()` API already used `.sw-toast-*` classes — no JS changes. +- **Popup menus**: Old `.popup-menu` / `.popup-menu-item` CSS deleted + (unused — `.sw-menu` is the active system). +- **Dropdown collision resolved**: Old `.sw-dropdown` (styled ` - + `; } diff --git a/src/js/sw/surfaces/admin/connections.js b/src/js/sw/surfaces/admin/connections.js index 1371b0f..e4c48cb 100644 --- a/src/js/sw/surfaces/admin/connections.js +++ b/src/js/sw/surfaces/admin/connections.js @@ -114,7 +114,7 @@ export default function ConnectionsSection() { return html`
- ${!connTypes.length && html` @@ -165,11 +165,11 @@ export default function ConnectionsSection() {
`)}
- - +
`} @@ -196,7 +196,7 @@ export default function ConnectionsSection() { - diff --git a/src/js/sw/surfaces/admin/groups.js b/src/js/sw/surfaces/admin/groups.js index 3567a9d..ac88a6c 100644 --- a/src/js/sw/surfaces/admin/groups.js +++ b/src/js/sw/surfaces/admin/groups.js @@ -112,11 +112,11 @@ export default function GroupsSection() { if (detail) return html`
- +

${detail.name}

${detail.scope}
- +
@@ -134,7 +134,7 @@ export default function GroupsSection() {
- +

@@ -144,7 +144,7 @@ export default function GroupsSection() { ${members.map(m => html`
${m.username || m.user_id} - +
`)}
@@ -160,12 +160,12 @@ export default function GroupsSection() {
- - + +
` - : html`` + : html`` } `; @@ -174,7 +174,7 @@ export default function GroupsSection() {
- +
${showCreate && html` @@ -187,8 +187,8 @@ export default function GroupsSection() {
- - + +
`} diff --git a/src/js/sw/surfaces/admin/packages.js b/src/js/sw/surfaces/admin/packages.js index 8b3e2c7..e6aaf45 100644 --- a/src/js/sw/surfaces/admin/packages.js +++ b/src/js/sw/surfaces/admin/packages.js @@ -252,10 +252,10 @@ export default function PackagesSection() { options=${TYPE_OPTIONS.map(t => ({ label: t.charAt(0).toUpperCase() + t.slice(1), value: t }))} /> - - @@ -276,28 +276,28 @@ export default function PackagesSection() { ${pkg.is_system && html`system`}
- ${hasManifestSettings(pkg) && html` - `} ${hasDeclaredPerms(pkg) && html` - `} ${pkg.source !== 'core' && html` - + `} - + ${pkg.source !== 'core' && !pkg.is_system && html` - + `}
@@ -317,7 +317,7 @@ export default function PackagesSection() { style="flex:1;padding:4px 8px;background:var(--bg-1,var(--bg));color:var(--text);border:1px solid var(--border);border-radius:4px;font-size:12px;" /> `)} - + ` } @@ -333,7 +333,7 @@ export default function PackagesSection() { ${perms.map(p => html`
${p.permission} -
${perms.some(p => !p.granted) && html` - + `} ` } @@ -376,7 +376,7 @@ export default function PackagesSection() {
${typeBadge(rp.type)} -
diff --git a/src/js/sw/surfaces/admin/settings.js b/src/js/sw/surfaces/admin/settings.js index a7e96ae..86d8eaf 100644 --- a/src/js/sw/surfaces/admin/settings.js +++ b/src/js/sw/surfaces/admin/settings.js @@ -231,11 +231,11 @@ export default function SettingsSection() {

Email

- +
- +
`; diff --git a/src/js/sw/surfaces/admin/storage.js b/src/js/sw/surfaces/admin/storage.js index 4ed27ab..6d62e25 100644 --- a/src/js/sw/surfaces/admin/storage.js +++ b/src/js/sw/surfaces/admin/storage.js @@ -61,7 +61,7 @@ export default function StorageSection() {

Orphaned Blobs

${orphans.count || 0} orphans found

- ${(orphans.count || 0) > 0 && html``} + ${(orphans.count || 0) > 0 && html``}
`} diff --git a/src/js/sw/surfaces/admin/teams.js b/src/js/sw/surfaces/admin/teams.js index 7611924..aeb8611 100644 --- a/src/js/sw/surfaces/admin/teams.js +++ b/src/js/sw/surfaces/admin/teams.js @@ -94,10 +94,10 @@ export default function TeamsSection() { if (detail) return html`
- +

${detail.name}

- +
${detail.description && html`

${detail.description}

`} @@ -112,7 +112,7 @@ export default function TeamsSection() { - +
`)} @@ -132,12 +132,12 @@ export default function TeamsSection() {
- - + +
` - : html`` + : html`` } `; @@ -147,7 +147,7 @@ export default function TeamsSection() {
- +
${showCreate && html` @@ -157,8 +157,8 @@ export default function TeamsSection() {
- - + +
`} diff --git a/src/js/sw/surfaces/admin/users.js b/src/js/sw/surfaces/admin/users.js index c0e488c..48e03b8 100644 --- a/src/js/sw/surfaces/admin/users.js +++ b/src/js/sw/surfaces/admin/users.js @@ -103,7 +103,7 @@ export default function UsersSection() { setSearch(e.target.value)} autocomplete="off" />
- + ${showCreate && html` @@ -117,8 +117,8 @@ export default function UsersSection() {
- - + +
`} @@ -134,14 +134,14 @@ export default function UsersSection() {
${u.status === 'pending' && html` - + `} ${u.is_active - ? html`` - : html`` + ? html`` + : html`` } - - + +
`)} diff --git a/src/js/sw/surfaces/admin/workflows.js b/src/js/sw/surfaces/admin/workflows.js index 6c32453..f924750 100644 --- a/src/js/sw/surfaces/admin/workflows.js +++ b/src/js/sw/surfaces/admin/workflows.js @@ -80,10 +80,10 @@ export default function WorkflowsSection() { if (editing) return html`
- +

Edit: ${editing.name}

- +
@@ -113,7 +113,7 @@ export default function WorkflowsSection() {
- +
`; @@ -122,7 +122,7 @@ export default function WorkflowsSection() {
- +
${showCreate && html` @@ -138,8 +138,8 @@ export default function WorkflowsSection() {
- - + +
`} diff --git a/src/js/sw/surfaces/settings/appearance.js b/src/js/sw/surfaces/settings/appearance.js index 545a9c4..e65bbc6 100644 --- a/src/js/sw/surfaces/settings/appearance.js +++ b/src/js/sw/surfaces/settings/appearance.js @@ -73,6 +73,6 @@ export function AppearanceSection() { - + `; } diff --git a/src/js/sw/surfaces/settings/connections.js b/src/js/sw/surfaces/settings/connections.js index 4ab1c83..dae29fe 100644 --- a/src/js/sw/surfaces/settings/connections.js +++ b/src/js/sw/surfaces/settings/connections.js @@ -114,7 +114,7 @@ export function ConnectionsSection() { return html`
- ${!connTypes.length && html` @@ -169,11 +169,11 @@ export function ConnectionsSection() {
`)}
- - +
`} @@ -207,7 +207,7 @@ export function ConnectionsSection() { - diff --git a/src/js/sw/surfaces/settings/general.js b/src/js/sw/surfaces/settings/general.js index 688ed6b..ae905f9 100644 --- a/src/js/sw/surfaces/settings/general.js +++ b/src/js/sw/surfaces/settings/general.js @@ -54,7 +54,7 @@ export function GeneralSection() { If your chosen surface is uninstalled, the global default is used.
- diff --git a/src/js/sw/surfaces/settings/notifications.js b/src/js/sw/surfaces/settings/notifications.js index 477bda8..8eb920d 100644 --- a/src/js/sw/surfaces/settings/notifications.js +++ b/src/js/sw/surfaces/settings/notifications.js @@ -81,7 +81,7 @@ export default function NotificationsSection() { onChange=${() => togglePref(type, enabled)} /> - ${avatarUrl && html` - `} @@ -148,7 +148,7 @@ export function ProfileSection() { - @@ -171,7 +171,7 @@ export function ProfileSection() { setConfirmPw(e.target.value)} /> - diff --git a/src/js/sw/surfaces/team-admin/activity.js b/src/js/sw/surfaces/team-admin/activity.js index 32f735a..dfe0d9e 100644 --- a/src/js/sw/surfaces/team-admin/activity.js +++ b/src/js/sw/surfaces/team-admin/activity.js @@ -77,9 +77,9 @@ export default function ActivitySection({ teamId }) {
- + Page ${page} of ${totalPages} (${total} total) - +
` } diff --git a/src/js/sw/surfaces/team-admin/connections.js b/src/js/sw/surfaces/team-admin/connections.js index 83d6a24..5bcc0ab 100644 --- a/src/js/sw/surfaces/team-admin/connections.js +++ b/src/js/sw/surfaces/team-admin/connections.js @@ -114,7 +114,7 @@ export default function ConnectionsSection({ teamId }) { return html`
-
@@ -157,11 +157,11 @@ export default function ConnectionsSection({ teamId }) { `)}
- - +
`} @@ -187,7 +187,7 @@ export default function ConnectionsSection({ teamId }) { - diff --git a/src/js/sw/surfaces/team-admin/index.js b/src/js/sw/surfaces/team-admin/index.js index eaf224a..c101fa8 100644 --- a/src/js/sw/surfaces/team-admin/index.js +++ b/src/js/sw/surfaces/team-admin/index.js @@ -185,7 +185,7 @@ function TeamAdminSurface() { ${teamName} ${adminTeams.length > 1 && html` - `} diff --git a/src/js/sw/surfaces/team-admin/members.js b/src/js/sw/surfaces/team-admin/members.js index ccadd87..e334d67 100644 --- a/src/js/sw/surfaces/team-admin/members.js +++ b/src/js/sw/surfaces/team-admin/members.js @@ -79,7 +79,7 @@ export default function MembersSection({ teamId }) {
- +
${showAdd && html` @@ -98,8 +98,8 @@ export default function MembersSection({ teamId }) {
- - + +
`} @@ -113,7 +113,7 @@ export default function MembersSection({ teamId }) { onChange=${e => updateRole(m.id || m.user_id, e.target.value)}> ${roles.map(r => html``)} - + `)} @@ -121,7 +121,7 @@ export default function MembersSection({ teamId }) {

Team Roles

-
@@ -132,7 +132,7 @@ export default function MembersSection({ teamId }) {
setNewRole(e.target.value)} placeholder="New role name" style="width:150px;" /> - +
`; diff --git a/src/js/sw/surfaces/team-admin/workflows.js b/src/js/sw/surfaces/team-admin/workflows.js index 89e2023..5ef739f 100644 --- a/src/js/sw/surfaces/team-admin/workflows.js +++ b/src/js/sw/surfaces/team-admin/workflows.js @@ -46,7 +46,7 @@ export default function WorkflowsSection({ teamId }) {
${TABS.map(t => html` `)}
@@ -123,8 +123,8 @@ function WorkflowsTab({ teamId }) {
- - + +
${showAdopt && html` @@ -132,7 +132,7 @@ function WorkflowsTab({ teamId }) {
Adopt a Global Workflow
- +
${available.length === 0 && html`
No global workflows available
`}
@@ -143,7 +143,7 @@ function WorkflowsTab({ teamId }) { /${w.slug}
${w.entry_mode} - +
`)} @@ -163,8 +163,8 @@ function WorkflowsTab({ teamId }) {
- - + +
`} @@ -266,11 +266,11 @@ function WorkflowEditor({ teamId, workflow, onBack }) { return html`
- +

Edit: ${workflow.name}

- - + +
@@ -299,7 +299,7 @@ function WorkflowEditor({ teamId, workflow, onBack }) { e.target.select()} /> - +
@@ -320,7 +320,7 @@ function WorkflowEditor({ teamId, workflow, onBack }) {
Stages (${stages.length})
- +
@@ -331,8 +331,8 @@ function WorkflowEditor({ teamId, workflow, onBack }) { ${s.stage_mode || '\u2014'} ${s.audience || 'team'} ${s.assignment_team_id && html`team assign`} - - + +
`)} ${stages.length === 0 && html`
No stages defined
`} @@ -502,10 +502,10 @@ function StageForm({ stage, teams, onSave, onCancel }) { Auto-advance when complete
- - +
`; @@ -578,10 +578,10 @@ function AssignmentsTab({ teamId }) { ${a.sla_breached && html`SLA`}
- - + - +
`)} @@ -597,7 +597,7 @@ function AssignmentsTab({ teamId }) { ${a.stage_name || `Stage ${a.stage}`} ${_timeAgo(a.created_at)} - + `)} ${unassigned.length === 0 && html`
No available assignments
`} @@ -648,11 +648,11 @@ function MonitorTab({ teamId }) { Age: ${_formatDuration(inst.age_seconds)}
- - - +
${expandedSignoff === inst.id && html`<${SignoffPanel} instanceId=${inst.id} teamId=${teamId} />`} @@ -703,8 +703,8 @@ function SignoffPanel({ instanceId, teamId }) {
setComment(e.target.value)} placeholder="Comment (optional)" style="flex:1;font-size:12px;" /> - - + +
${signoffs.length > 0 && html`
-- 2.49.1