diff --git a/canvas/src/components/ConversationTraceModal.tsx b/canvas/src/components/ConversationTraceModal.tsx
index deaf575c..90fcaed6 100644
--- a/canvas/src/components/ConversationTraceModal.tsx
+++ b/canvas/src/components/ConversationTraceModal.tsx
@@ -187,7 +187,7 @@ export function ConversationTraceModal({ open, workspaceId: _workspaceId, onClos
isError
? "bg-red-950/50 text-bad"
: isSend
- ? "bg-cyan-950/50 text-cyan-400"
+ ? "bg-cyan-950 text-cyan-300"
: isReceive
? "bg-blue-950/50 text-accent"
: "bg-surface-card text-ink-mid"
diff --git a/canvas/src/components/ErrorBoundary.tsx b/canvas/src/components/ErrorBoundary.tsx
index bd204886..e411a131 100644
--- a/canvas/src/components/ErrorBoundary.tsx
+++ b/canvas/src/components/ErrorBoundary.tsx
@@ -76,7 +76,7 @@ export class ErrorBoundary extends React.Component<
An unexpected error occurred while rendering the application.
-
diff --git a/canvas/src/components/ExternalConnectModal.tsx b/canvas/src/components/ExternalConnectModal.tsx
index 14de5d1c..89ff2524 100644
--- a/canvas/src/components/ExternalConnectModal.tsx
+++ b/canvas/src/components/ExternalConnectModal.tsx
@@ -360,7 +360,7 @@ function SnippetBlock({
diff --git a/canvas/src/components/MissingKeysModal.tsx b/canvas/src/components/MissingKeysModal.tsx
index c9dbc90d..3adc9dee 100644
--- a/canvas/src/components/MissingKeysModal.tsx
+++ b/canvas/src/components/MissingKeysModal.tsx
@@ -451,7 +451,7 @@ function ProviderPickerModal({
@@ -492,7 +492,7 @@ function ProviderPickerModal({
!selectorValue.providerId ||
(showModelInput && model.trim() === "")
}
- className="px-3.5 py-1.5 text-[12px] bg-accent-strong hover:bg-accent text-white rounded-lg transition-colors disabled:opacity-40"
+ className="px-3.5 py-1.5 text-[12px] bg-accent-strong hover:bg-accent text-white rounded-lg transition-colors disabled:opacity-40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1"
>
{allSaved ? "Deploy" : entries.length > 1 ? "Add Keys" : "Add Key"}
diff --git a/canvas/src/components/ProviderModelSelector.tsx b/canvas/src/components/ProviderModelSelector.tsx
index 6620aa55..628a31ad 100644
--- a/canvas/src/components/ProviderModelSelector.tsx
+++ b/canvas/src/components/ProviderModelSelector.tsx
@@ -420,7 +420,7 @@ export function ProviderModelSelector({
spellCheck={false}
autoComplete="off"
data-testid="model-input"
- className="w-full bg-surface-sunken border border-line rounded px-2 py-1.5 text-[11px] text-ink font-mono focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent/20 transition-colors disabled:opacity-50"
+ className="w-full bg-surface-sunken border border-line rounded px-2 py-1.5 text-[11px] text-ink font-mono focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:border-accent transition-colors disabled:opacity-50"
/>
{selected?.wildcard
diff --git a/canvas/src/components/ThemeToggle.tsx b/canvas/src/components/ThemeToggle.tsx
index 322ff3df..5c8cfaec 100644
--- a/canvas/src/components/ThemeToggle.tsx
+++ b/canvas/src/components/ThemeToggle.tsx
@@ -61,8 +61,12 @@ export function ThemeToggle({ className = "" }: { className?: string }) {
return;
}
setTheme(OPTIONS[next].value);
- // Move focus to the new button so arrow-key navigation is continuous
- const btns = (e.currentTarget.closest("[role=radiogroup]") as HTMLElement)?.querySelectorAll("[role=radio]");
+ // Move focus to the new button so arrow-key navigation is continuous.
+ // Use direct-child query to scope strictly to this radiogroup's buttons
+ // and avoid accidentally focusing unrelated [role=radio] elements
+ // elsewhere in the DOM (e.g. React Flow canvas nodes).
+ const radiogroup = e.currentTarget.closest("[role=radiogroup]") as HTMLElement | null;
+ const btns = radiogroup?.querySelectorAll("> [role=radio]");
btns?.[next]?.focus();
},
[]
diff --git a/canvas/src/components/tabs/FilesTab.tsx b/canvas/src/components/tabs/FilesTab.tsx
index f51d40d2..caf22279 100644
--- a/canvas/src/components/tabs/FilesTab.tsx
+++ b/canvas/src/components/tabs/FilesTab.tsx
@@ -226,7 +226,7 @@ function PlatformOwnedFilesTab({ workspaceId }: { workspaceId: string }) {
Delete all {files.filter((f) => !f.dir).length} files? This cannot be undone.
-
+
@@ -240,7 +240,7 @@ function PlatformOwnedFilesTab({ workspaceId }: { workspaceId: string }) {
Delete {confirmDelete}{files.find((f) => f.path === confirmDelete && f.dir) ? " and all its contents" : ""}?
-
+
diff --git a/canvas/src/components/tabs/FilesTab/FilesToolbar.tsx b/canvas/src/components/tabs/FilesTab/FilesToolbar.tsx
index 8b567e41..dcdbba13 100644
--- a/canvas/src/components/tabs/FilesTab/FilesToolbar.tsx
+++ b/canvas/src/components/tabs/FilesTab/FilesToolbar.tsx
@@ -32,7 +32,7 @@ export function FilesToolbar({
value={root}
onChange={(e) => setRoot(e.target.value)}
aria-label="File root directory"
- className="text-[10px] bg-surface-card text-ink-mid border border-line rounded px-1.5 py-0.5 outline-none"
+ className="text-[10px] bg-surface-card text-ink-mid border border-line rounded px-1.5 py-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1"
>
diff --git a/canvas/src/components/tabs/ScheduleTab.tsx b/canvas/src/components/tabs/ScheduleTab.tsx
index db710b3c..f3a2388c 100644
--- a/canvas/src/components/tabs/ScheduleTab.tsx
+++ b/canvas/src/components/tabs/ScheduleTab.tsx
@@ -332,6 +332,13 @@ export function ScheduleTab({ workspaceId }: Props) {