Feat v0.6.11 css dedup (#46)
All checks were successful
CI/CD / detect-changes (push) Successful in 3s
CI/CD / test-frontend (push) Successful in 5s
CI/CD / test-go-pg (push) Successful in 2m44s
CI/CD / test-sqlite (push) Successful in 2m54s
CI/CD / build-and-deploy (push) Successful in 1m17s

Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #46.
This commit is contained in:
2026-04-01 11:18:28 +00:00
committed by xcaliber
parent ca3f845c34
commit 786bc92768
44 changed files with 311 additions and 317 deletions

View File

@@ -102,13 +102,13 @@ function DebugModal({ engine }) {
</div>
<div class="modal-footer debug-modal-footer">
<div class="debug-footer-left">
<button class="btn-danger btn-small" onClick=${() => { setActiveTab('console'); engine.runDiagnostics(); }}>Diagnostics</button>
<button class="btn-danger btn-small" onClick=${onPurge}>Purge Cache</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => { setActiveTab('console'); engine.runDiagnostics(); }}>Diagnostics</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${onPurge}>Purge Cache</button>
</div>
<div class="debug-footer-right">
<button class="btn-secondary btn-small" onClick=${onClear}>Clear</button>
<button class="btn-secondary btn-small" onClick=${() => engine.copyLog()}>Copy</button>
<button class="btn-secondary btn-small" onClick=${() => engine.downloadLog()}>Export</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${onClear}>Clear</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => engine.copyLog()}>Copy</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => engine.downloadLog()}>Export</button>
</div>
</div>
</div>

View File

@@ -77,9 +77,9 @@ export default function AuditSection() {
</div>
<div style="margin-top:12px;display:flex;align-items:center;gap:8px;">
<button class="btn-small" disabled=${page <= 1} onClick=${() => setPage(p => p - 1)}>\u2190 Prev</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" disabled=${page <= 1} onClick=${() => setPage(p => p - 1)}>\u2190 Prev</button>
<span class="text-muted" style="font-size:12px;">Page ${page} of ${totalPages} (${total} total)</span>
<button class="btn-small" disabled=${page >= totalPages} onClick=${() => setPage(p => p + 1)}>Next \u2192</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" disabled=${page >= totalPages} onClick=${() => setPage(p => p + 1)}>Next \u2192</button>
</div>
`
}

View File

@@ -118,13 +118,13 @@ export default function BackupSection() {
return html`
<div>
<div style="display:flex;gap:8px;margin-bottom:20px;flex-wrap:wrap;">
<button class="btn btn-primary" onclick=${() => createBackup(false)} disabled=${creating || restoring}>
<button class="sw-btn sw-btn--primary sw-btn--md" onclick=${() => createBackup(false)} disabled=${creating || restoring}>
${creating ? 'Creating\u2026' : 'Download Backup'}
</button>
<button class="btn" onclick=${() => createBackup(true)} disabled=${creating || restoring}>
${creating ? 'Creating\u2026' : 'Save to Server'}
</button>
<button class="btn btn-danger" onclick=${restoreBackup} disabled=${creating || restoring}>
<button class="sw-btn sw-btn--danger sw-btn--md" onclick=${restoreBackup} disabled=${creating || restoring}>
${restoring ? 'Restoring\u2026' : 'Restore from File'}
</button>
</div>
@@ -149,8 +149,8 @@ export default function BackupSection() {
<td>${formatBytes(b.size)}</td>
<td>${formatDate(b.created_at)}</td>
<td>
<button class="btn btn-sm" onclick=${() => downloadBackup(b.name)}>Download</button>
<button class="btn btn-sm btn-danger" onclick=${() => deleteBackup(b.name)} style="margin-left:4px;">Delete</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onclick=${() => downloadBackup(b.name)}>Download</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onclick=${() => deleteBackup(b.name)} style="margin-left:4px;">Delete</button>
</td>
</tr>
`)}

View File

@@ -38,7 +38,7 @@ export default function BroadcastSection() {
<option value="critical">Critical</option>
</select>
</div>
<button class="btn-md btn-primary" onClick=${send} disabled=${sending}>${sending ? 'Sending\u2026' : 'Send Broadcast'}</button>
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${send} disabled=${sending}>${sending ? 'Sending\u2026' : 'Send Broadcast'}</button>
</div>
`;
}

View File

@@ -114,7 +114,7 @@ export default function ConnectionsSection() {
return html`
<div style="margin-bottom:12px;display:flex;align-items:center;gap:8px;">
<button class="btn-md btn-primary" onClick=${openAdd}
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${openAdd}
disabled=${!connTypes.length}>+ Add Connection</button>
${!connTypes.length && html`
<span style="color:var(--text-3);font-size:12px;">
@@ -165,11 +165,11 @@ export default function ConnectionsSection() {
</div>
`)}
<div style="display:flex;gap:8px;margin-top:12px;">
<button class="btn-md btn-primary" disabled=${saving}
<button class="sw-btn sw-btn--primary sw-btn--md" disabled=${saving}
onClick=${save}>
${saving ? 'Saving\u2026' : editId ? 'Update' : 'Add'}
</button>
<button class="btn-md btn-secondary" onClick=${cancel}>Cancel</button>
<button class="sw-btn sw-btn--secondary sw-btn--md" onClick=${cancel}>Cancel</button>
</div>
</div>
`}
@@ -196,7 +196,7 @@ export default function ConnectionsSection() {
<button class="icon-btn" title="Edit" onClick=${() => openEdit(c)}>
\u{270F}\u{FE0F}
</button>
<button class="icon-btn icon-btn-danger" title="Delete"
<button class="icon-btn icon-sw-btn sw-btn--danger sw-btn--md" title="Delete"
onClick=${() => del(c)}>
\u{1F5D1}
</button>

View File

@@ -112,11 +112,11 @@ export default function GroupsSection() {
if (detail) return html`
<div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<button class="btn-small" onClick=${() => setDetail(null)}>\u2190 Back</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setDetail(null)}>\u2190 Back</button>
<h4 style="margin:0;">${detail.name}</h4>
<span class="text-muted" style="font-size:12px;">${detail.scope}</span>
<div style="flex:1"></div>
<button class="btn-small btn-danger" onClick=${deleteGroup}>Delete</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${deleteGroup}>Delete</button>
</div>
<div class="settings-section" style="margin-bottom:16px;">
@@ -134,7 +134,7 @@ export default function GroupsSection() {
</div>
<div style="margin-bottom:16px;">
<button class="btn-small btn-primary" onClick=${savePermissions}>Save Permissions</button>
<button class="sw-btn sw-btn--primary sw-btn--sm" onClick=${savePermissions}>Save Permissions</button>
</div>
<hr style="border:none;border-top:1px solid var(--border);margin:16px 0;" />
@@ -144,7 +144,7 @@ export default function GroupsSection() {
${members.map(m => html`
<div class="admin-surface-row" key=${m.id || m.user_id}>
<span style="flex:1;">${m.username || m.user_id}</span>
<button class="btn-small btn-danger" onClick=${() => removeMember(m.user_id || m.id)}>Remove</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => removeMember(m.user_id || m.id)}>Remove</button>
</div>
`)}
</div>
@@ -160,12 +160,12 @@ export default function GroupsSection() {
</div>
</div>
<div class="form-row" style="margin-top:8px;gap:8px;">
<button type="submit" class="btn-small btn-primary">Add</button>
<button type="button" class="btn-small" onClick=${() => setShowAddMember(false)}>Cancel</button>
<button type="submit" class="sw-btn sw-btn--primary sw-btn--sm">Add</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setShowAddMember(false)}>Cancel</button>
</div>
</form>
`
: html`<button class="btn-small" style="margin-top:8px;" onClick=${() => setShowAddMember(true)}>+ Add Member</button>`
: html`<button class="sw-btn sw-btn--secondary sw-btn--sm" style="margin-top:8px;" onClick=${() => setShowAddMember(true)}>+ Add Member</button>`
}
</div>
`;
@@ -174,7 +174,7 @@ export default function GroupsSection() {
<div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<div style="flex:1"></div>
<button class="btn-md btn-primary" onClick=${() => setShowCreate(true)}>+ Add</button>
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${() => setShowCreate(true)}>+ Add</button>
</div>
${showCreate && html`
@@ -187,8 +187,8 @@ export default function GroupsSection() {
</div>
</div>
<div class="form-row" style="margin-top:8px;gap:8px;">
<button type="submit" class="btn-small btn-primary">Create</button>
<button type="button" class="btn-small" onClick=${() => setShowCreate(false)}>Cancel</button>
<button type="submit" class="sw-btn sw-btn--primary sw-btn--sm">Create</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setShowCreate(false)}>Cancel</button>
</div>
</form>
`}

View File

@@ -252,10 +252,10 @@ export default function PackagesSection() {
options=${TYPE_OPTIONS.map(t => ({ label: t.charAt(0).toUpperCase() + t.slice(1), value: t }))}
/>
<span style="flex:1;" />
<button class="btn-small" onClick=${uploadPackage} disabled=${installing}>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${uploadPackage} disabled=${installing}>
${installing ? 'Installing\u2026' : 'Install Package'}
</button>
<button class="btn-small" onClick=${toggleRegistry}>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${toggleRegistry}>
${registryOpen ? 'Close Registry' : 'Browse Registry'}
</button>
</div>
@@ -276,28 +276,28 @@ export default function PackagesSection() {
${pkg.is_system && html`<span class="badge" style="margin-left:4px;">system</span>`}
</div>
<div class="admin-actions-cell">
<button class="btn-small"
<button class="sw-btn sw-btn--secondary sw-btn--sm"
onClick=${() => toggleEnabled(pkg)}
disabled=${CORE_IDS.has(pkg.id) || pkg.status === 'dormant' || pkg.status === 'pending_review'}
title=${pkg.status === 'dormant' ? 'Requires chat' : pkg.status === 'pending_review' ? 'Grant permissions to activate' : ''}>
${pkg.enabled ? 'Disable' : 'Enable'}
</button>
${hasManifestSettings(pkg) && html`
<button class="btn-small" onClick=${() => toggleSettings(pkg.id)}>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => toggleSettings(pkg.id)}>
${expandedId === pkg.id ? 'Close' : 'Settings'}
</button>
`}
${hasDeclaredPerms(pkg) && html`
<button class="btn-small" onClick=${() => togglePerms(pkg.id)}>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => togglePerms(pkg.id)}>
${permsId === pkg.id ? 'Close' : 'Permissions'}
</button>
`}
${pkg.source !== 'core' && html`
<button class="btn-small" onClick=${() => updatePkg(pkg)}>Update</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => updatePkg(pkg)}>Update</button>
`}
<button class="btn-small" onClick=${() => exportPkg(pkg.id)}>Export</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => exportPkg(pkg.id)}>Export</button>
${pkg.source !== 'core' && !pkg.is_system && html`
<button class="btn-small btn-danger" onClick=${() => deletePkg(pkg)}>Delete</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => deletePkg(pkg)}>Delete</button>
`}
</div>
</div>
@@ -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;" />
</div>
`)}
<button class="btn-small" style="margin-top:4px;" onClick=${() => saveSettings(pkg.id)}>Save</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" style="margin-top:4px;" onClick=${() => saveSettings(pkg.id)}>Save</button>
`
}
</div>
@@ -333,7 +333,7 @@ export default function PackagesSection() {
${perms.map(p => html`
<div key=${p.permission} style="display:flex;gap:8px;align-items:center;margin-bottom:4px;">
<code style="min-width:140px;font-size:12px;">${p.permission}</code>
<button class="btn-small ${p.granted ? 'btn-danger' : 'btn-primary'}"
<button class="sw-btn sw-btn--secondary sw-btn--sm ${p.granted ? 'sw-btn sw-btn--danger sw-btn--md' : 'sw-btn sw-btn--primary sw-btn--md'}"
style="min-width:64px;font-size:11px;"
onClick=${() => p.granted ? revokePerm(pkg.id, p.permission) : grantPerm(pkg.id, p.permission)}>
${p.granted ? 'Revoke' : 'Grant'}
@@ -345,7 +345,7 @@ export default function PackagesSection() {
`)}
</div>
${perms.some(p => !p.granted) && html`
<button class="btn-small btn-primary" onClick=${() => grantAllPerms(pkg.id)}>Grant All</button>
<button class="sw-btn sw-btn--primary sw-btn--sm" onClick=${() => grantAllPerms(pkg.id)}>Grant All</button>
`}
`
}
@@ -376,7 +376,7 @@ export default function PackagesSection() {
</div>
<div class="admin-actions-cell">
${typeBadge(rp.type)}
<button class="btn-small btn-primary"
<button class="sw-btn sw-btn--primary sw-btn--sm"
onClick=${() => installFromRegistry(rp.download_url)}>Install</button>
</div>
</div>

View File

@@ -231,11 +231,11 @@ export default function SettingsSection() {
</div>
<div class="settings-section"><h3>Email</h3>
<button class="btn-small" onClick=${testEmail}>Send Test Email</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${testEmail}>Send Test Email</button>
</div>
<div style="display:flex;gap:8px;align-items:center;margin-top:16px;">
<button class="btn-md btn-primary" onClick=${save} disabled=${saving}>${saving ? 'Saving\u2026' : 'Save Settings'}</button>
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${save} disabled=${saving}>${saving ? 'Saving\u2026' : 'Save Settings'}</button>
</div>
</div>
`;

View File

@@ -61,7 +61,7 @@ export default function StorageSection() {
<div class="settings-section" style="margin-bottom:16px;">
<h4>Orphaned Blobs</h4>
<p class="text-muted" style="font-size:12px;">${orphans.count || 0} orphans found</p>
${(orphans.count || 0) > 0 && html`<button class="btn-small btn-primary" onClick=${cleanup}>Clean Up</button>`}
${(orphans.count || 0) > 0 && html`<button class="sw-btn sw-btn--primary sw-btn--sm" onClick=${cleanup}>Clean Up</button>`}
</div>
`}

View File

@@ -94,10 +94,10 @@ export default function TeamsSection() {
if (detail) return html`
<div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<button class="btn-small" onClick=${() => setDetail(null)}>\u2190 Back</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setDetail(null)}>\u2190 Back</button>
<h4 style="margin:0;">${detail.name}</h4>
<div style="flex:1"></div>
<button class="btn-small btn-danger" onClick=${() => deleteTeam(detail.id)}>Delete Team</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => deleteTeam(detail.id)}>Delete Team</button>
</div>
${detail.description && html`<p class="text-muted" style="font-size:12px;margin-bottom:12px;">${detail.description}</p>`}
@@ -112,7 +112,7 @@ export default function TeamsSection() {
<option value="member">member</option>
<option value="admin">admin</option>
</select>
<button class="btn-small btn-danger" onClick=${() => removeMember(m.id)}>Remove</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => removeMember(m.id)}>Remove</button>
</div>
`)}
</div>
@@ -132,12 +132,12 @@ export default function TeamsSection() {
</div>
</div>
<div class="form-row" style="margin-top:8px;gap:8px;">
<button type="submit" class="btn-small btn-primary">Add</button>
<button type="button" class="btn-small" onClick=${() => setShowAddMember(false)}>Cancel</button>
<button type="submit" class="sw-btn sw-btn--primary sw-btn--sm">Add</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setShowAddMember(false)}>Cancel</button>
</div>
</form>
`
: html`<button class="btn-small" style="margin-top:8px;" onClick=${() => setShowAddMember(true)}>+ Add Member</button>`
: html`<button class="sw-btn sw-btn--secondary sw-btn--sm" style="margin-top:8px;" onClick=${() => setShowAddMember(true)}>+ Add Member</button>`
}
</div>
`;
@@ -147,7 +147,7 @@ export default function TeamsSection() {
<div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<div style="flex:1"></div>
<button class="btn-md btn-primary" onClick=${() => setShowCreate(true)}>+ Add</button>
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${() => setShowCreate(true)}>+ Add</button>
</div>
${showCreate && html`
@@ -157,8 +157,8 @@ export default function TeamsSection() {
<div class="form-group"><label>Description</label><input name="desc" placeholder="Optional" /></div>
</div>
<div class="form-row" style="margin-top:8px;gap:8px;">
<button type="submit" class="btn-small btn-primary">Create</button>
<button type="button" class="btn-small" onClick=${() => setShowCreate(false)}>Cancel</button>
<button type="submit" class="sw-btn sw-btn--primary sw-btn--sm">Create</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setShowCreate(false)}>Cancel</button>
</div>
</form>
`}

View File

@@ -103,7 +103,7 @@ export default function UsersSection() {
<input placeholder="Search users\u2026" value=${search} onInput=${e => setSearch(e.target.value)} autocomplete="off" />
</div>
<div style="flex:1"></div>
<button class="btn-md btn-primary" onClick=${() => setShowCreate(true)}>+ Add</button>
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${() => setShowCreate(true)}>+ Add</button>
</div>
${showCreate && html`
@@ -117,8 +117,8 @@ export default function UsersSection() {
</div>
</div>
<div class="form-row" style="margin-top:8px;gap:8px;">
<button type="submit" class="btn-small btn-primary">Create</button>
<button type="button" class="btn-small" onClick=${() => setShowCreate(false)}>Cancel</button>
<button type="submit" class="sw-btn sw-btn--primary sw-btn--sm">Create</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setShowCreate(false)}>Cancel</button>
</div>
</form>
`}
@@ -134,14 +134,14 @@ export default function UsersSection() {
</div>
<div class="admin-actions-cell">
${u.status === 'pending' && html`
<button class="btn-small btn-primary" onClick=${() => approveUser(u.id)}>Approve</button>
<button class="sw-btn sw-btn--primary sw-btn--sm" onClick=${() => approveUser(u.id)}>Approve</button>
`}
${u.is_active
? html`<button class="btn-small" onClick=${() => toggleActive(u.id, false)}>Disable</button>`
: html`<button class="btn-small" onClick=${() => toggleActive(u.id, true)}>Enable</button>`
? html`<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => toggleActive(u.id, false)}>Disable</button>`
: html`<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => toggleActive(u.id, true)}>Enable</button>`
}
<button class="btn-small" onClick=${() => resetPassword(u.id, u.username)}>Reset PW</button>
<button class="btn-small btn-danger" onClick=${() => deleteUser(u.id, u.username)}>Delete</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => resetPassword(u.id, u.username)}>Reset PW</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => deleteUser(u.id, u.username)}>Delete</button>
</div>
</div>
`)}

View File

@@ -80,10 +80,10 @@ export default function WorkflowsSection() {
if (editing) return html`
<form onSubmit=${updateWorkflow}>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<button type="button" class="btn-small" onClick=${() => setEditing(null)}>\u2190 Back</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setEditing(null)}>\u2190 Back</button>
<h4 style="margin:0;">Edit: ${editing.name}</h4>
<div style="flex:1"></div>
<button type="button" class="btn-small btn-danger" onClick=${() => deleteWorkflow(editing.id)}>Delete</button>
<button type="button" class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => deleteWorkflow(editing.id)}>Delete</button>
</div>
<div class="form-row">
<div class="form-group"><label>Name</label><input name="name" value=${editing.name || ''} /></div>
@@ -113,7 +113,7 @@ export default function WorkflowsSection() {
</div>
<div class="form-row" style="margin-top:16px;gap:8px;">
<button type="submit" class="btn-small btn-primary">Save</button>
<button type="submit" class="sw-btn sw-btn--primary sw-btn--sm">Save</button>
</div>
</form>
`;
@@ -122,7 +122,7 @@ export default function WorkflowsSection() {
<div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<div style="flex:1"></div>
<button class="btn-md btn-primary" onClick=${() => setShowCreate(true)}>+ Add</button>
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${() => setShowCreate(true)}>+ Add</button>
</div>
${showCreate && html`
@@ -138,8 +138,8 @@ export default function WorkflowsSection() {
</div>
<div class="form-group"><label>Description</label><input name="description" placeholder="Optional" /></div>
<div class="form-row" style="margin-top:8px;gap:8px;">
<button type="submit" class="btn-small btn-primary">Create</button>
<button type="button" class="btn-small" onClick=${() => setShowCreate(false)}>Cancel</button>
<button type="submit" class="sw-btn sw-btn--primary sw-btn--sm">Create</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setShowCreate(false)}>Cancel</button>
</div>
</form>
`}

View File

@@ -73,6 +73,6 @@ export function AppearanceSection() {
</div>
</div>
</div>
<button class="btn-md btn-primary" onClick=${save}>Save</button>
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${save}>Save</button>
`;
}

View File

@@ -114,7 +114,7 @@ export function ConnectionsSection() {
return html`
<div style="margin-bottom:12px;">
<button class="btn-md btn-primary" onClick=${openAdd}
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${openAdd}
disabled=${!connTypes.length}>+ Add Connection</button>
${!connTypes.length && html`
<span style="margin-left:8px;color:var(--text-3);font-size:12px;">
@@ -169,11 +169,11 @@ export function ConnectionsSection() {
</div>
`)}
<div style="display:flex;gap:8px;margin-top:12px;">
<button class="btn-md btn-primary" disabled=${saving}
<button class="sw-btn sw-btn--primary sw-btn--md" disabled=${saving}
onClick=${save}>
${saving ? 'Saving\u2026' : editId ? 'Update' : 'Add'}
</button>
<button class="btn-md btn-secondary" onClick=${cancel}>Cancel</button>
<button class="sw-btn sw-btn--secondary sw-btn--md" onClick=${cancel}>Cancel</button>
</div>
</div>
`}
@@ -207,7 +207,7 @@ export function ConnectionsSection() {
<button class="icon-btn" title="Edit" onClick=${() => openEdit(c)}>
\u{270F}\u{FE0F}
</button>
<button class="icon-btn icon-btn-danger" title="Delete"
<button class="icon-btn icon-sw-btn sw-btn--danger sw-btn--md" title="Delete"
onClick=${() => del(c)}>
\u{1F5D1}
</button>

View File

@@ -54,7 +54,7 @@ export function GeneralSection() {
If your chosen surface is uninstalled, the global default is used.
</span>
</div>
<button class="btn-md btn-primary" style="margin-top:12px;"
<button class="sw-btn sw-btn--primary sw-btn--md" style="margin-top:12px;"
disabled=${saving} onClick=${save}>
${saving ? 'Saving\u2026' : 'Save'}
</button>

View File

@@ -81,7 +81,7 @@ export default function NotificationsSection() {
onChange=${() => togglePref(type, enabled)} />
<span class="toggle-track"></span>
</label>
<button class="btn-small btn-ghost"
<button class="sw-btn sw-btn--ghost sw-btn--sm"
disabled=${isSaving}
onClick=${() => resetPref(type)}
title="Reset to default">

View File

@@ -124,12 +124,12 @@ export function ProfileSection() {
}
</div>
<div style="display:flex;gap:8px;">
<button class="btn-sm btn-secondary"
<button class="sw-btn sw-btn--secondary sw-btn--sm"
onClick=${() => fileRef.current?.click()}>
Upload
</button>
${avatarUrl && html`
<button class="btn-sm btn-secondary" onClick=${removeAvatar}>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${removeAvatar}>
Remove
</button>
`}
@@ -148,7 +148,7 @@ export function ProfileSection() {
<label>Email</label>
<input type="email" disabled value=${email} />
</div>
<button class="btn-md btn-primary" disabled=${savingProfile}
<button class="sw-btn sw-btn--primary sw-btn--md" disabled=${savingProfile}
onClick=${saveProfile}>
${savingProfile ? 'Saving\u2026' : 'Save Profile'}
</button>
@@ -171,7 +171,7 @@ export function ProfileSection() {
<input type="password" autocomplete="new-password"
value=${confirmPw} onInput=${e => setConfirmPw(e.target.value)} />
</div>
<button class="btn-md btn-primary" disabled=${savingPw}
<button class="sw-btn sw-btn--primary sw-btn--md" disabled=${savingPw}
onClick=${changePassword}>
${savingPw ? 'Updating\u2026' : 'Update Password'}
</button>

View File

@@ -77,9 +77,9 @@ export default function ActivitySection({ teamId }) {
</div>
<div style="margin-top:12px;display:flex;align-items:center;gap:8px;">
<button class="btn-small" disabled=${page <= 1} onClick=${() => setPage(p => p - 1)}>\u2190 Prev</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" disabled=${page <= 1} onClick=${() => setPage(p => p - 1)}>\u2190 Prev</button>
<span class="text-muted" style="font-size:12px;">Page ${page} of ${totalPages} (${total} total)</span>
<button class="btn-small" disabled=${page >= totalPages} onClick=${() => setPage(p => p + 1)}>Next \u2192</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" disabled=${page >= totalPages} onClick=${() => setPage(p => p + 1)}>Next \u2192</button>
</div>
`
}

View File

@@ -114,7 +114,7 @@ export default function ConnectionsSection({ teamId }) {
return html`
<div style="margin-bottom:12px;">
<button class="btn-md btn-primary" onClick=${openAdd}
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${openAdd}
disabled=${!connTypes.length}>+ Add Connection</button>
</div>
@@ -157,11 +157,11 @@ export default function ConnectionsSection({ teamId }) {
</div>
`)}
<div style="display:flex;gap:8px;margin-top:12px;">
<button class="btn-md btn-primary" disabled=${saving}
<button class="sw-btn sw-btn--primary sw-btn--md" disabled=${saving}
onClick=${save}>
${saving ? 'Saving\u2026' : editId ? 'Update' : 'Add'}
</button>
<button class="btn-md btn-secondary" onClick=${cancel}>Cancel</button>
<button class="sw-btn sw-btn--secondary sw-btn--md" onClick=${cancel}>Cancel</button>
</div>
</div>
`}
@@ -187,7 +187,7 @@ export default function ConnectionsSection({ teamId }) {
<button class="icon-btn" title="Edit" onClick=${() => openEdit(c)}>
\u{270F}\u{FE0F}
</button>
<button class="icon-btn icon-btn-danger" title="Delete"
<button class="icon-btn icon-sw-btn sw-btn--danger sw-btn--md" title="Delete"
onClick=${() => del(c)}>
\u{1F5D1}
</button>

View File

@@ -185,7 +185,7 @@ function TeamAdminSurface() {
<span class="settings-topbar-title">
${teamName}
${adminTeams.length > 1 && html`
<button class="btn-small btn-ghost" style="margin-left:8px;font-size:11px;"
<button class="sw-btn sw-btn--ghost sw-btn--sm" style="margin-left:8px;font-size:11px;"
onClick=${() => setSelectedTeam(null)}>Switch Team</button>
`}
</span>

View File

@@ -79,7 +79,7 @@ export default function MembersSection({ teamId }) {
<div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<div style="flex:1"></div>
<button class="btn-md btn-primary" onClick=${openAdd}>+ Add Member</button>
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${openAdd}>+ Add Member</button>
</div>
${showAdd && html`
@@ -98,8 +98,8 @@ export default function MembersSection({ teamId }) {
</div>
</div>
<div class="form-row" style="margin-top:8px;gap:8px;">
<button type="submit" class="btn-small btn-primary">Add</button>
<button type="button" class="btn-small" onClick=${() => setShowAdd(false)}>Cancel</button>
<button type="submit" class="sw-btn sw-btn--primary sw-btn--sm">Add</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setShowAdd(false)}>Cancel</button>
</div>
</form>
`}
@@ -113,7 +113,7 @@ export default function MembersSection({ teamId }) {
onChange=${e => updateRole(m.id || m.user_id, e.target.value)}>
${roles.map(r => html`<option key=${r} value=${r}>${r}</option>`)}
</select>
<button class="btn-small btn-danger" onClick=${() => removeMember(m.id || m.user_id)}>Remove</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => removeMember(m.id || m.user_id)}>Remove</button>
</div>
`)}
</div>
@@ -121,7 +121,7 @@ export default function MembersSection({ teamId }) {
<div style="margin-top:24px;border-top:1px solid var(--border-1);padding-top:12px;">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
<h4 style="margin:0;flex:1;">Team Roles</h4>
<button class="btn-small" onClick=${() => setShowRoles(!showRoles)}>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setShowRoles(!showRoles)}>
${showRoles ? 'Hide' : 'Manage'}
</button>
</div>
@@ -132,7 +132,7 @@ export default function MembersSection({ teamId }) {
<div style="display:flex;gap:8px;align-items:center;">
<input value=${newRole} onInput=${e => setNewRole(e.target.value)}
placeholder="New role name" style="width:150px;" />
<button class="btn-small btn-primary" onClick=${async () => {
<button class="sw-btn sw-btn--primary sw-btn--sm" onClick=${async () => {
if (!newRole.trim()) return;
const updated = [...new Set([...roles, newRole.trim()])];
try {
@@ -147,7 +147,7 @@ export default function MembersSection({ teamId }) {
${roles.filter(r => r !== 'admin' && r !== 'member').map(r => html`
<div class="admin-surface-row" key=${r}>
<span style="flex:1;">${r}</span>
<button class="btn-small btn-danger" onClick=${async () => {
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${async () => {
const updated = roles.filter(x => x !== r);
try {
await sw.api.put('/api/v1/teams/' + teamId + '/roles', { roles: updated });

View File

@@ -65,7 +65,7 @@ export default function SettingsSection({ teamId }) {
`}
<div style="display:flex;gap:8px;align-items:center;margin-top:16px;">
<button class="btn-md btn-primary" onClick=${save} disabled=${saving}>${saving ? 'Saving\u2026' : 'Save Settings'}</button>
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${save} disabled=${saving}>${saving ? 'Saving\u2026' : 'Save Settings'}</button>
</div>
</div>
`;

View File

@@ -46,7 +46,7 @@ export default function WorkflowsSection({ teamId }) {
<div class="admin-tabs" style="display:flex;gap:4px;margin-bottom:16px;">
${TABS.map(t => html`
<button key=${t}
class="btn-small ${tab === t ? 'btn-primary' : ''}"
class="sw-btn sw-btn--secondary sw-btn--sm ${tab === t ? 'sw-btn sw-btn--primary sw-btn--md' : ''}"
onClick=${() => setTab(t)}>${t}</button>
`)}
</div>
@@ -123,8 +123,8 @@ function WorkflowsTab({ teamId }) {
<div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<div style="flex:1"></div>
<button class="btn-md" onClick=${openAdopt}>Adopt Global</button>
<button class="btn-md btn-primary" onClick=${() => setShowCreate(true)}>+ Add</button>
<button class="sw-btn sw-btn--secondary sw-btn--md" onClick=${openAdopt}>Adopt Global</button>
<button class="sw-btn sw-btn--primary sw-btn--md" onClick=${() => setShowCreate(true)}>+ Add</button>
</div>
${showAdopt && html`
@@ -132,7 +132,7 @@ function WorkflowsTab({ teamId }) {
<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
<strong>Adopt a Global Workflow</strong>
<div style="flex:1"></div>
<button class="btn-small" onClick=${() => setShowAdopt(false)}>Cancel</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setShowAdopt(false)}>Cancel</button>
</div>
${available.length === 0 && html`<div class="empty-hint">No global workflows available</div>`}
<div class="admin-list">
@@ -143,7 +143,7 @@ function WorkflowsTab({ teamId }) {
<span class="text-muted" style="margin-left:8px;font-size:11px;">/${w.slug}</span>
</div>
<span class="badge">${w.entry_mode}</span>
<button class="btn-small btn-primary" onClick=${() => adoptWorkflow(w.id)}>Adopt</button>
<button class="sw-btn sw-btn--primary sw-btn--sm" onClick=${() => adoptWorkflow(w.id)}>Adopt</button>
</div>
`)}
</div>
@@ -163,8 +163,8 @@ function WorkflowsTab({ teamId }) {
</div>
<div class="form-group"><label>Description</label><input name="description" placeholder="Optional" /></div>
<div class="form-row" style="margin-top:8px;gap:8px;">
<button type="submit" class="btn-small btn-primary">Create</button>
<button type="button" class="btn-small" onClick=${() => setShowCreate(false)}>Cancel</button>
<button type="submit" class="sw-btn sw-btn--primary sw-btn--sm">Create</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setShowCreate(false)}>Cancel</button>
</div>
</form>
`}
@@ -266,11 +266,11 @@ function WorkflowEditor({ teamId, workflow, onBack }) {
return html`
<form onSubmit=${updateWorkflow}>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<button type="button" class="btn-small" onClick=${onBack}>\u2190 Back</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${onBack}>\u2190 Back</button>
<h4 style="margin:0;">Edit: ${workflow.name}</h4>
<div style="flex:1"></div>
<button type="button" class="btn-small" onClick=${publishWorkflow}>Publish</button>
<button type="button" class="btn-small btn-danger" onClick=${deleteWorkflow}>Delete</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${publishWorkflow}>Publish</button>
<button type="button" class="sw-btn sw-btn--danger sw-btn--sm" onClick=${deleteWorkflow}>Delete</button>
</div>
<div class="form-row">
<div class="form-group"><label>Name</label><input name="name" value=${workflow.name || ''} /></div>
@@ -299,7 +299,7 @@ function WorkflowEditor({ teamId, workflow, onBack }) {
<input type="text" readOnly value=${window.location.origin + (window.__BASE__ || '') + '/api/v1/public/workflows/' + workflow.id + '/start'}
style="flex:1;font-size:11px;padding:4px 8px;background:var(--input-bg);border:1px solid var(--border);border-radius:4px;color:var(--text);font-family:var(--mono);"
onClick=${e => e.target.select()} />
<button type="button" class="btn-small" onClick=${(e) => {
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${(e) => {
const url = window.location.origin + (window.__BASE__ || '') + '/api/v1/public/workflows/' + workflow.id + '/start';
navigator.clipboard.writeText(url).then(() => {
e.target.textContent = 'Copied!';
@@ -311,7 +311,7 @@ function WorkflowEditor({ teamId, workflow, onBack }) {
`}
<div class="form-row" style="margin-top:16px;gap:8px;">
<button type="submit" class="btn-small btn-primary">Save</button>
<button type="submit" class="sw-btn sw-btn--primary sw-btn--sm">Save</button>
</div>
</form>
@@ -320,7 +320,7 @@ function WorkflowEditor({ teamId, workflow, onBack }) {
<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
<h5 style="margin:0;">Stages (${stages.length})</h5>
<div style="flex:1"></div>
<button class="btn-small" onClick=${() => setEditingStage('new')}>+ Add Stage</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setEditingStage('new')}>+ Add Stage</button>
</div>
<div class="admin-list">
@@ -331,8 +331,8 @@ function WorkflowEditor({ teamId, workflow, onBack }) {
<span class="badge">${s.stage_mode || '\u2014'}</span>
<span class="badge">${s.audience || 'team'}</span>
${s.assignment_team_id && html`<span class="badge">team assign</span>`}
<button class="btn-small" onClick=${() => setEditingStage(s.id)}>Edit</button>
<button class="btn-small btn-danger" onClick=${() => deleteStage(s.id)}>\u00d7</button>
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => setEditingStage(s.id)}>Edit</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => deleteStage(s.id)}>\u00d7</button>
</div>
`)}
${stages.length === 0 && html`<div class="empty-hint">No stages defined</div>`}
@@ -502,10 +502,10 @@ function StageForm({ stage, teams, onSave, onCancel }) {
<span class="toggle-track"></span><span>Auto-advance when complete</span>
</label>
<div class="form-row" style="margin-top:12px;gap:8px;">
<button type="button" class="btn-small btn-primary" onClick=${submit}>
<button type="button" class="sw-btn sw-btn--primary sw-btn--sm" onClick=${submit}>
${stage ? 'Update' : 'Add Stage'}
</button>
<button type="button" class="btn-small" onClick=${onCancel}>Cancel</button>
<button type="button" class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${onCancel}>Cancel</button>
</div>
</div>
`;
@@ -578,10 +578,10 @@ function AssignmentsTab({ teamId }) {
${a.sla_breached && html`<span class="badge badge-danger">SLA</span>`}
</div>
<div style="display:flex;gap:4px;">
<button class="btn-small" onClick=${() => unclaim(a.id)}>Release</button>
<button class="btn-small btn-primary"
<button class="sw-btn sw-btn--secondary sw-btn--sm" onClick=${() => unclaim(a.id)}>Release</button>
<button class="sw-btn sw-btn--primary sw-btn--sm"
onClick=${() => { location.href = sw.base + '/w/' + a.channel_id; }}>Open</button>
<button class="btn-small btn-success" onClick=${() => complete(a.id)}>Complete</button>
<button class="sw-btn sw-btn--success sw-btn--sm" onClick=${() => complete(a.id)}>Complete</button>
</div>
</div>
`)}
@@ -597,7 +597,7 @@ function AssignmentsTab({ teamId }) {
<span class="badge">${a.stage_name || `Stage ${a.stage}`}</span>
<span class="text-muted" style="font-size:11px;">${_timeAgo(a.created_at)}</span>
</div>
<button class="btn-small btn-primary" onClick=${() => claim(a.id)}>Claim</button>
<button class="sw-btn sw-btn--primary sw-btn--sm" onClick=${() => claim(a.id)}>Claim</button>
</div>
`)}
${unassigned.length === 0 && html`<div class="empty-hint">No available assignments</div>`}
@@ -648,11 +648,11 @@ function MonitorTab({ teamId }) {
<span class="text-muted" style="font-size:11px;">Age: ${_formatDuration(inst.age_seconds)}</span>
</div>
<div style="display:flex;gap:4px;">
<button class="btn-small"
<button class="sw-btn sw-btn--secondary sw-btn--sm"
onClick=${() => setExpandedSignoff(expandedSignoff === inst.id ? null : inst.id)}>Signoffs</button>
<button class="btn-small"
<button class="sw-btn sw-btn--secondary sw-btn--sm"
onClick=${() => { location.href = sw.base + '/w/' + inst.channel_id; }}>Open</button>
<button class="btn-small btn-danger" onClick=${() => cancelInstance(inst.channel_id)}>Cancel</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => cancelInstance(inst.channel_id)}>Cancel</button>
</div>
${expandedSignoff === inst.id && html`<${SignoffPanel} instanceId=${inst.id} teamId=${teamId} />`}
</div>
@@ -703,8 +703,8 @@ function SignoffPanel({ instanceId, teamId }) {
<div style="display:flex;gap:4px;align-items:center;">
<input value=${comment} onInput=${e => setComment(e.target.value)}
placeholder="Comment (optional)" style="flex:1;font-size:12px;" />
<button class="btn-small btn-success" onClick=${() => submit('approve')}>Approve</button>
<button class="btn-small btn-danger" onClick=${() => submit('reject')}>Reject</button>
<button class="sw-btn sw-btn--success sw-btn--sm" onClick=${() => submit('approve')}>Approve</button>
<button class="sw-btn sw-btn--danger sw-btn--sm" onClick=${() => submit('reject')}>Reject</button>
</div>
${signoffs.length > 0 && html`
<div style="margin-top:6px;">