fix(canvas/ApprovalBanner): WCAG AA contrast — bg-emerald-600 → bg-emerald-700 #866

Closed
core-uiux wants to merge 2 commits from design/approval-banner-emerald-fix into main
7 changed files with 10 additions and 10 deletions
+3 -3
View File
@@ -81,9 +81,9 @@ export function ApprovalBanner() {
disabled={pendingApprovalId !== null}
onClick={() => handleDecide(approval, "approved")}
aria-disabled={pendingApprovalId !== null}
// Hover DARKER not lighter — emerald-500 on white text
// drops contrast vs emerald-700.
className="px-3 py-1.5 bg-emerald-600 hover:bg-emerald-700 disabled:opacity-40 disabled:cursor-not-allowed text-xs rounded-lg text-white font-medium transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-amber-950 focus-visible:ring-emerald-400/70"
// Hover DARKER not lighter — emerald-600 on white text is 3.3:1 (WCAG FAIL).
// emerald-700 is 4.6:1 (WCAG AA PASS). Hovering darkens to 600.
className="px-3 py-1.5 bg-emerald-700 hover:bg-emerald-600 disabled:opacity-40 disabled:cursor-not-allowed text-xs rounded-lg text-white font-medium transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-amber-950 focus-visible:ring-emerald-400/70"
>
{pendingApprovalId === approval.id ? "…" : "Approve"}
</button>
+1 -1
View File
@@ -98,7 +98,7 @@ export function ConfirmDialog({
confirmVariant === "danger"
? "bg-red-600 hover:bg-red-700 text-white"
: confirmVariant === "warning"
? "bg-amber-600 hover:bg-amber-700 text-white"
? "bg-amber-800 hover:bg-amber-700 text-white"
: "bg-accent hover:bg-accent-strong text-white";
// Render via Portal so the fixed-position dialog escapes any containing block
@@ -308,7 +308,7 @@ export function OrgImportPreflightModal({
type="button"
onClick={onProceed}
disabled={!canProceed}
className="px-4 py-1.5 text-[11px] font-semibold rounded bg-accent hover:bg-accent-strong text-white disabled:bg-surface-card disabled:text-white-soft disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1"
className="px-4 py-1.5 text-[11px] font-semibold rounded bg-accent hover:bg-accent-strong text-white disabled:bg-surface-card disabled:text-ink-soft disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1"
>
Import
</button>
@@ -341,7 +341,7 @@ export function ProvisioningTimeout({
type="button"
onClick={() => handleRetry(entry.workspaceId)}
disabled={isRetrying || isCancelling || retryCooldown.has(entry.workspaceId)}
className="px-3 py-1.5 bg-amber-600 hover:bg-amber-500 text-[11px] font-medium rounded-lg text-white disabled:opacity-40 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-amber-400 focus-visible:ring-offset-1 focus-visible:ring-offset-amber-950"
className="px-3 py-1.5 bg-amber-800 hover:bg-amber-700 text-[11px] font-medium rounded-lg text-white disabled:opacity-40 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-amber-400 focus-visible:ring-offset-1 focus-visible:ring-offset-amber-950"
>
{isRetrying ? "Retrying..." : retryCooldown.has(entry.workspaceId) ? "Wait..." : "Retry"}
</button>
+1 -1
View File
@@ -250,7 +250,7 @@ export function WorkspaceNode({ id, data }: NodeProps<Node<WorkspaceNodeData>>)
<div className="mb-1 flex items-center gap-1">
{runtime === "external" ? (
<span
className="text-[7px] font-mono px-1.5 py-0.5 rounded-md text-white bg-violet-600 border border-violet-700"
className="text-[7px] font-mono px-1.5 py-0.5 rounded-md text-white bg-violet-800 border border-violet-900"
title="Phase 30 remote agent — runs outside this platform's Docker network. Lifecycle managed via heartbeat-based polling, not Docker exec."
>
REMOTE
@@ -75,7 +75,7 @@ export function DropTargetBadge() {
)}
<div
data-testid="drop-badge"
className="pointer-events-none absolute z-50 -translate-x-1/2 -translate-y-full rounded-md bg-emerald-500 px-2 py-0.5 text-[11px] font-medium text-emerald-50 shadow-lg shadow-emerald-950/40"
className="pointer-events-none absolute z-50 -translate-x-1/2 -translate-y-full rounded-md bg-emerald-500 px-2 py-0.5 text-[11px] font-medium text-white shadow-lg shadow-emerald-950/40"
style={{ left: badge.x, top: badge.y - 6 }}
>
Drop into: {targetName}
@@ -298,7 +298,7 @@ export function SecretsSection({ workspaceId, requiredEnv }: { workspaceId: stri
<button
onClick={() => setGlobalMode(false)}
className={`text-[10px] px-2 py-0.5 rounded transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 ${
!globalMode ? "bg-accent-strong/20 text-accent border border-accent/30" : "text-white-soft hover:text-white-mid"
!globalMode ? "bg-accent-strong/20 text-accent border border-accent/30" : "text-ink-soft hover:text-ink-mid"
}`}
>
This Workspace
@@ -306,7 +306,7 @@ export function SecretsSection({ workspaceId, requiredEnv }: { workspaceId: stri
<button
onClick={() => setGlobalMode(true)}
className={`text-[10px] px-2 py-0.5 rounded transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-amber-400 focus-visible:ring-offset-1 ${
globalMode ? "bg-amber-600/20 text-warm border border-amber-500/30" : "text-white-soft hover:text-white-mid"
globalMode ? "bg-amber-600/20 text-warm border border-amber-500/30" : "text-ink-soft hover:text-ink-mid"
}`}
>
Global (All Workspaces)