diff --git a/canvas/src/components/tabs/ChannelsTab.tsx b/canvas/src/components/tabs/ChannelsTab.tsx
index 39b5e459..676b0548 100644
--- a/canvas/src/components/tabs/ChannelsTab.tsx
+++ b/canvas/src/components/tabs/ChannelsTab.tsx
@@ -370,7 +370,7 @@ export function ChannelsTab({ workspaceId }: Props) {
// Was bg-accent-strong hover:bg-accent — accent is the
// LIGHTER variant; same AA contrast trap fixed in
// ScheduleTab/MemoryTab/OnboardingWizard.
- className="w-full text-xs py-1.5 rounded bg-accent hover:bg-accent-strong text-white transition focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/60 focus-visible:ring-offset-2 focus-visible:ring-offset-surface"
+ className="w-full text-xs py-1.5 rounded bg-accent hover:bg-accent-strong text-white transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface"
>
Connect Channel
diff --git a/canvas/src/components/tabs/ConfigTab.tsx b/canvas/src/components/tabs/ConfigTab.tsx
index 33fcf16e..50ae227b 100644
--- a/canvas/src/components/tabs/ConfigTab.tsx
+++ b/canvas/src/components/tabs/ConfigTab.tsx
@@ -83,11 +83,11 @@ function AgentCardSection({ workspaceId }: { workspaceId: string }) {
{error &&
{error}
}
+ className="px-2 py-1 bg-surface-card hover:bg-surface-elevated hover:text-ink text-[10px] rounded text-ink-mid transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface">Cancel
) : (
@@ -101,7 +101,7 @@ function AgentCardSection({ workspaceId }: { workspaceId: string }) {
)}
{success && Updated
}
+ className="mt-2 text-[10px] text-accent hover:text-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1">Edit Agent Card
)}
@@ -876,7 +876,7 @@ export function ConfigTab({ workspaceId }: Props) {
@@ -1016,7 +1016,7 @@ export function ConfigTab({ workspaceId }: Props) {
onClick={() => handleSave(true)}
disabled={!isDirty || saving}
// Same accent-LIGHTER fix shipped on every other tab.
- className="px-3 py-1.5 bg-accent hover:bg-accent-strong text-xs rounded text-white disabled:opacity-30 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/60 focus-visible:ring-offset-1 focus-visible:ring-offset-surface"
+ className="px-3 py-1.5 bg-accent hover:bg-accent-strong text-xs rounded text-white disabled:opacity-30 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface"
>
{saving ? "Restarting..." : "Save & Restart"}
@@ -1024,14 +1024,14 @@ export function ConfigTab({ workspaceId }: Props) {
type="button"
onClick={() => handleSave(false)}
disabled={!isDirty || saving}
- className="px-3 py-1.5 bg-surface-card hover:bg-surface-card text-xs rounded text-ink-mid disabled:opacity-30 transition-colors"
+ className="px-3 py-1.5 bg-surface-card hover:bg-surface-card text-xs rounded text-ink-mid disabled:opacity-30 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1"
>
Save
diff --git a/canvas/src/components/tabs/EventsTab.tsx b/canvas/src/components/tabs/EventsTab.tsx
index 44de3410..c239153e 100644
--- a/canvas/src/components/tabs/EventsTab.tsx
+++ b/canvas/src/components/tabs/EventsTab.tsx
@@ -75,7 +75,7 @@ export function EventsTab({ workspaceId }: Props) {
// Was hover:bg-surface-card on top of bg-surface-card — silent
// no-op hover. Lift to surface-elevated, matching the Cancel
// pattern from ConfirmDialog.
- className="px-2 py-1 bg-surface-card hover:bg-surface-elevated hover:text-ink text-[10px] rounded text-ink-mid transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/50"
+ className="px-2 py-1 bg-surface-card hover:bg-surface-elevated hover:text-ink text-[10px] rounded text-ink-mid transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1"
>
Refresh
@@ -106,7 +106,7 @@ export function EventsTab({ workspaceId }: Props) {
// toggles or what it controls.
aria-expanded={isOpen}
aria-controls={panelId}
- className="w-full flex items-center gap-2 px-3 py-2 text-left rounded-t hover:bg-surface-elevated/40 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent/50 transition-colors"
+ className="w-full flex items-center gap-2 px-3 py-2 text-left rounded-t hover:bg-surface-elevated/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 transition-colors"
>
{busy === "show" ? "Loading…" : "Show connection info"}
@@ -95,7 +95,7 @@ export function ExternalConnectionSection({ workspaceId }: Props) {
type="button"
onClick={() => setConfirmRotate(true)}
disabled={busy !== null}
- className="px-3 py-1.5 bg-red-900/30 hover:bg-red-900/50 border border-red-800/60 text-xs rounded text-bad disabled:opacity-30 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-red-600/60"
+ className="px-3 py-1.5 bg-red-900/30 hover:bg-red-900/50 border border-red-800/60 text-xs rounded text-bad disabled:opacity-30 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500 focus-visible:ring-offset-1"
>
{busy === "rotate" ? "Rotating…" : "Rotate credentials"}
@@ -124,14 +124,14 @@ export function ExternalConnectionSection({ workspaceId }: Props) {
diff --git a/canvas/src/components/tabs/MemoryTab.tsx b/canvas/src/components/tabs/MemoryTab.tsx
index 3dfd7034..8e560801 100644
--- a/canvas/src/components/tabs/MemoryTab.tsx
+++ b/canvas/src/components/tabs/MemoryTab.tsx
@@ -205,14 +205,14 @@ export function MemoryTab({ workspaceId }: Props) {
@@ -245,7 +245,7 @@ export function MemoryTab({ workspaceId }: Props) {
@@ -280,21 +280,21 @@ export function MemoryTab({ workspaceId }: Props) {
@@ -330,7 +330,7 @@ export function MemoryTab({ workspaceId }: Props) {
@@ -340,7 +340,7 @@ export function MemoryTab({ workspaceId }: Props) {
setShowAdd(false);
setError(null);
}}
- className="px-3 py-1 bg-surface-card hover:bg-surface-elevated text-xs rounded text-ink-mid"
+ className="px-3 py-1 bg-surface-card hover:bg-surface-elevated text-xs rounded text-ink-mid focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1"
>
Cancel
@@ -358,7 +358,7 @@ export function MemoryTab({ workspaceId }: Props) {
@@ -285,7 +285,7 @@ export function ScheduleTab({ workspaceId }: Props) {
onClick={resetForm}
// Was hover:bg-surface-card on top of bg-surface-card —
// silent no-op hover. Lift to surface-elevated.
- className="text-[11px] px-3 py-1 bg-surface-card text-ink-mid rounded hover:bg-surface-elevated hover:text-ink transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/40 focus-visible:ring-offset-1 focus-visible:ring-offset-surface"
+ className="text-[11px] px-3 py-1 bg-surface-card text-ink-mid rounded hover:bg-surface-elevated hover:text-ink transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface"
>
Cancel
diff --git a/canvas/src/components/tabs/SkillsTab.tsx b/canvas/src/components/tabs/SkillsTab.tsx
index f6917c43..563aff58 100644
--- a/canvas/src/components/tabs/SkillsTab.tsx
+++ b/canvas/src/components/tabs/SkillsTab.tsx
@@ -479,7 +479,7 @@ export function SkillsTab({ workspaceId, data }: Props) {
loadRegistry(true)}
- className="text-[10px] text-violet-300 hover:text-violet-200 underline-offset-2 hover:underline"
+ className="text-[10px] text-violet-300 hover:text-violet-200 underline-offset-2 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1"
>
{registryLoading ? "Loading… click to retry" : "Retry"}
diff --git a/canvas/src/components/tabs/TracesTab.tsx b/canvas/src/components/tabs/TracesTab.tsx
index 6932ceed..84f79cd0 100644
--- a/canvas/src/components/tabs/TracesTab.tsx
+++ b/canvas/src/components/tabs/TracesTab.tsx
@@ -60,7 +60,7 @@ export function TracesTab({ workspaceId }: Props) {
onClick={loadTraces}
// Added focus-visible ring; previous version was hover-only,
// invisible to keyboard users.
- className="text-[10px] text-ink-mid hover:text-ink-mid rounded-sm px-1 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/50"
+ className="text-[10px] text-ink-mid hover:text-ink-mid rounded-sm px-1 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1"
>
Refresh
@@ -98,7 +98,7 @@ export function TracesTab({ workspaceId }: Props) {
// panel. Same pattern shipped on EventsTab.
aria-expanded={isOpen}
aria-controls={panelId}
- className="w-full px-3 py-2 flex items-center gap-2 text-left hover:bg-surface-card/60 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent/50 transition-colors"
+ className="w-full px-3 py-2 flex items-center gap-2 text-left hover:bg-surface-card/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 transition-colors"
>
{/* Status dot uses semantic bad/good tokens — was hardcoded
bg-red-400 / bg-emerald-400 which doesn't pin to the
diff --git a/canvas/src/components/tabs/chat/AttachmentImage.tsx b/canvas/src/components/tabs/chat/AttachmentImage.tsx
index ca4df242..a123856f 100644
--- a/canvas/src/components/tabs/chat/AttachmentImage.tsx
+++ b/canvas/src/components/tabs/chat/AttachmentImage.tsx
@@ -143,7 +143,7 @@ export function AttachmentImage({ workspaceId, attachment, onDownload, tone }: P
type="button"
onClick={() => setOpen(true)}
title={`Preview ${attachment.name}`}
- className={`group relative inline-block max-w-full rounded-lg overflow-hidden border focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/60 ${
+ className={`group relative inline-block max-w-full rounded-lg overflow-hidden border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 ${
tone === "user" ? "border-blue-400/30" : "border-line/50"
}`}
aria-label={`Open ${attachment.name} preview`}