diff --git a/frontend/src/components/Flow/BrainView.tsx b/frontend/src/components/Flow/BrainView.tsx index 82fed7e..7af7b6f 100644 --- a/frontend/src/components/Flow/BrainView.tsx +++ b/frontend/src/components/Flow/BrainView.tsx @@ -23,6 +23,7 @@ import { motion } from "motion/react" import { useEffect, useMemo, useState } from "react" import type { BrainGraph } from "@/client" +import { useTheme } from "@/components/theme-provider" import { useIsMobile } from "@/hooks/useMobile" import { scaleIn } from "@/lib/motion" import { BrainEdge, type BrainEdgeData } from "./BrainEdge" @@ -154,6 +155,7 @@ function build(graph: BrainGraph): { nodes: Node[]; edges: Edge[] } { function BrainCanvas() { const navigate = useNavigate() const { fitView } = useReactFlow() + const { resolvedTheme } = useTheme() useFlowSocket() // The socket invalidates every "flows" key on a rebuild, so publishing // anywhere re-fetches this and the layout runs again. @@ -213,6 +215,10 @@ function BrainCanvas() { nodesConnectable={false} elementsSelectable={false} proOptions={{ hideAttribution: true }} + // React Flow stamps this on the wrapper as a class, and the app's own + // token scopes are named `.light` / `.dark` (index.css) — so leaving it + // unset re-themes the whole canvas to light inside a dark shell. + colorMode={resolvedTheme} fitView fitViewOptions={FIT} minZoom={0.1} diff --git a/frontend/src/components/Flow/FlowEditor.tsx b/frontend/src/components/Flow/FlowEditor.tsx index 28d0f69..be7819a 100644 --- a/frontend/src/components/Flow/FlowEditor.tsx +++ b/frontend/src/components/Flow/FlowEditor.tsx @@ -31,6 +31,7 @@ import { type MessageSpec, type NodeDef_Input, } from "@/client" +import { useTheme } from "@/components/theme-provider" import { Button } from "@/components/ui/button" import { Dialog, @@ -205,6 +206,7 @@ function FlowEditorInner({ const { showErrorToast, showSuccessToast } = useCustomToast() const { fitView } = useReactFlow() const updateNodeInternals = useUpdateNodeInternals() + const { resolvedTheme } = useTheme() const { data: flows } = useSuspenseQuery(flowsQueryOptions()) const { data: detail } = useSuspenseQuery(flowQueryOptions(flowName)) @@ -1076,6 +1078,10 @@ function FlowEditorInner({ nodeTypes={nodeTypes} edgeTypes={edgeTypes} proOptions={{ hideAttribution: true }} + // React Flow stamps this on the wrapper as a class, and the app's own + // token scopes are named `.light` / `.dark` (index.css) — so leaving it + // unset re-themes the whole canvas to light inside a dark shell. + colorMode={resolvedTheme} fitView fitViewOptions={FIT_VIEW} // Low enough that the fit can always show the whole graph. A phone is