From c518107b8e7e1362e6193aa6cb96bdef990c9094 Mon Sep 17 00:00:00 2001 From: Cameron Pope Date: Fri, 1 May 2026 09:53:31 -0600 Subject: [PATCH 1/5] style(admin): add theme-icon, redispatch-row, and md-field form CSS --- src/admin-ui/components.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/admin-ui/components.ts b/src/admin-ui/components.ts index fcdcb9a..645aaed 100644 --- a/src/admin-ui/components.ts +++ b/src/admin-ui/components.ts @@ -93,6 +93,11 @@ export const componentsCss = ` font-family: var(--font-mono); } +.theme-icon-sun { display: none; } +.theme-icon-moon { display: inline-flex; } +[data-theme="dark"] .theme-icon-sun { display: inline-flex; } +[data-theme="dark"] .theme-icon-moon { display: none; } + .sidebar-footer { margin-top: auto; padding: var(--sp-2) var(--sp-2) 0; @@ -386,6 +391,8 @@ export const componentsCss = ` .tbl tbody tr.active { background: var(--bg-active); } .tbl tbody tr.failed-row td { background: rgba(220, 38, 38, 0.025); } .tbl tbody tr.failed-row:hover td { background: rgba(220, 38, 38, 0.05); } +.tbl tbody tr.redispatch-row td { background: var(--st-warn-bg); } +.tbl tbody tr.redispatch-row:hover td { background: var(--bg-hover); } .mono { font-family: var(--font-mono); @@ -939,6 +946,20 @@ dialog::backdrop { background: rgba(0,0,0,0.5); } .md-field select, .md-field textarea { width: 100%; + background: var(--bg-elev); + border: 1px solid var(--border-default); + border-radius: var(--r-sm); + padding: 7px 10px; + font-size: 12.5px; + color: var(--fg-primary); + transition: border-color 80ms ease, box-shadow 80ms ease; +} +.md-field input:focus, +.md-field select:focus, +.md-field textarea:focus { + outline: none; + border-color: var(--border-focus); + box-shadow: var(--shadow-focus); } .md-field textarea { font-family: var(--font-mono); From 58024cde18c1adafea281f67332106fcf5281da1 Mon Sep 17 00:00:00 2001 From: Cameron Pope Date: Fri, 1 May 2026 09:54:42 -0600 Subject: [PATCH 2/5] style(admin): add theme-toggle button to sidebar footer --- src/admin-ui/sidebar.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/admin-ui/sidebar.ts b/src/admin-ui/sidebar.ts index 2ef8096..e5c60d2 100644 --- a/src/admin-ui/sidebar.ts +++ b/src/admin-ui/sidebar.ts @@ -60,6 +60,10 @@ export function sidebarHtml(): string {
Admin
signed in
+ From 07b7e48e245ec070c89a826b60be7d0f4a3ef00f Mon Sep 17 00:00:00 2001 From: Cameron Pope Date: Fri, 1 May 2026 09:55:42 -0600 Subject: [PATCH 3/5] style(admin): replace hardcoded hex badge colors with design-token classes in pipelines --- src/admin-ui/pages/pipelines.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/admin-ui/pages/pipelines.ts b/src/admin-ui/pages/pipelines.ts index bbcb5c8..95a93b1 100644 --- a/src/admin-ui/pages/pipelines.ts +++ b/src/admin-ui/pages/pipelines.ts @@ -50,26 +50,26 @@ export const pipelinesScript = ` } empty.classList.add('hidden'); - const statusColors = { - unknown: '#bdc3c7', - dispatched: '#95a5a6', - running: '#3498db', - completed: '#2ecc71', - failed: '#e74c3c', - timed_out: '#f39c12' + const statusClass = { + unknown: 'neutral', + dispatched: 'neutral', + running: 'running', + completed: 'success', + failed: 'fail', + timed_out: 'warn' }; - const execColors = { gha: '#27ae60', fly: '#8e44ad', plan: '#2980b9' }; - function makeBadge(color, text) { - return '' + window.esc(text) + ''; + function makeBadge(cls, text) { + return '' + window.esc(text) + ''; } function statusBadge(status) { - return makeBadge(statusColors[status] || '#95a5a6', status || 'dispatched'); + return makeBadge(statusClass[status] || 'neutral', status || 'dispatched'); } function execBadge(mode, runnerMode) { const short = mode === 'fly-machines' ? 'fly' : mode === 'planning' ? 'plan' : 'gha'; - return makeBadge(execColors[short] || '#7f8c8d', short) - + (short !== 'plan' && runnerMode ? ' (' + window.esc(runnerMode) + ')' : ''); + const cls = short === 'fly' ? 'info' : 'neutral'; + return makeBadge(cls, short) + + (short !== 'plan' && runnerMode ? ' (' + window.esc(runnerMode) + ')' : ''); } // Group planning + implement phases that belong to the same job: @@ -110,7 +110,7 @@ export const pipelinesScript = ` const issueLabel = (impl.issueIdentifier || impl.issueId) + (impl.issueTitle ? ': ' + window.esc(impl.issueTitle) : ''); const dn2 = plan.dispatchNumber || 1; const isRedispatch = dn2 > 1; - if (isRedispatch) tr.style.backgroundColor = '#fff3cd'; + if (isRedispatch) tr.classList.add('redispatch-row'); const dnBadge = isRedispatch ? '' + dn2 + '' : '' + dn2; @@ -136,7 +136,7 @@ export const pipelinesScript = ` const issueLabel = (entry.issueIdentifier || entry.issueId) + (entry.issueTitle ? ': ' + window.esc(entry.issueTitle) : ''); const dn3 = entry.dispatchNumber || 1; const isRedispatch = dn3 > 1; - if (isRedispatch) tr.style.backgroundColor = '#fff3cd'; + if (isRedispatch) tr.classList.add('redispatch-row'); const dnBadge = isRedispatch ? '' + dn3 + '' : '' + dn3; From fdf3539cab71e1ad80879a475e18b30eae9f5712 Mon Sep 17 00:00:00 2001 From: Cameron Pope Date: Fri, 1 May 2026 09:57:59 -0600 Subject: [PATCH 4/5] style(admin): replace inline badge styles and legacy button classes in projects --- src/admin-ui/pages/projects.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/admin-ui/pages/projects.ts b/src/admin-ui/pages/projects.ts index 3d48baa..9a64703 100644 --- a/src/admin-ui/pages/projects.ts +++ b/src/admin-ui/pages/projects.ts @@ -58,7 +58,7 @@ export const projectsHtml = `
Add Mapping - +
@@ -130,8 +130,8 @@ export const projectsHtml = `
@@ -159,14 +159,14 @@ export const projectsScript = ` const tr = document.createElement('tr'); const ek = window.esc(key); const execBadge = m.executionMode === 'fly-machines' - ? 'fly' - : 'gha'; + ? 'fly' + : 'gha'; const planBadge = m.planningEnabled - ? 'on' - : 'off'; + ? 'on' + : 'off'; const providerBadge = m.provider === 'bedrock' - ? 'bedrock' - : 'anthropic'; + ? 'bedrock' + : 'anthropic'; tr.innerHTML = '' + ek + '' + '' + window.esc(m.owner) + '/' + window.esc(m.repo) + '' + '' + execBadge + '' @@ -175,9 +175,9 @@ export const projectsScript = ` + '' + planBadge + '' + '' + providerBadge + '' + '' - + ' ' - + ' ' - + '' + + ' ' + + ' ' + + '' + ''; tbody.appendChild(tr); } @@ -349,7 +349,7 @@ export const projectsScript = ` const tr = document.createElement('tr'); tr.innerHTML = '' + window.esc(s.name) + '' + 'Set' - + ''; + + ''; tbody.appendChild(tr); } } catch (err) { From 03af737acca1645513ea60b6d03e4aaec73db319 Mon Sep 17 00:00:00 2001 From: Cameron Pope Date: Fri, 1 May 2026 09:59:46 -0600 Subject: [PATCH 5/5] style(admin): dynamic at-cap subtitle and View blockers nav link in overview --- src/admin-ui/pages/overview.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/admin-ui/pages/overview.ts b/src/admin-ui/pages/overview.ts index 93c380e..2865788 100644 --- a/src/admin-ui/pages/overview.ts +++ b/src/admin-ui/pages/overview.ts @@ -63,12 +63,13 @@ export const overviewHtml = `

Why isn’t this running?

-
Full blocker taxonomy on Plan 4 — Blockers page
+
Teams at concurrency cap
+
- +
@@ -264,6 +265,7 @@ export const overviewScript = ` function renderAtCapacity(running, mappings) { const body = document.getElementById('overview-atcap-body'); const empty = document.getElementById('overview-atcap-empty'); + const subtitle = document.getElementById('overview-atcap-subtitle'); if (!body || !empty) return; body.innerHTML = ''; const atCap = Object.entries(mappings).filter(function (pair) { @@ -273,6 +275,7 @@ export const overviewScript = ` const cnt = running.filter(function (r) { return r.teamKey === key; }).length; return cnt >= cap; }); + if (subtitle) subtitle.textContent = atCap.length + ' team' + (atCap.length === 1 ? '' : 's') + ' at cap'; if (atCap.length === 0) { empty.classList.remove('hidden'); return;