Fold the brain and health screens into Home

Home is the one overview now: the brain graph flat across the top, the flow
switches, then the health sections. The /brain and /health routes and their
sidebar entries are gone.

- charts report their cursor and clicks, so hovering one filters the list
  beside it to that minute and a click pins it until Escape or Clear
- chart values round to about three significant digits, the legend mounts
  under the plot so it can wrap without leaving the card, and axis ticks
  shorten past a thousand
- the embedded brain leaves the wheel to the page rather than zooming
- number fields no longer draw their up/down spinner (NOTEPAD)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017MeiWk3Yq12n2pTvnQWYvt
This commit is contained in:
2026-08-17 00:17:14 +02:00
co-authored by Claude Fable 5
parent fe346ea7a3
commit affb0a5f8c
15 changed files with 835 additions and 592 deletions
+36 -42
View File
@@ -1,8 +1,6 @@
import { useQuery } from "@tanstack/react-query"
import { useNavigate } from "@tanstack/react-router"
import {
Background,
BackgroundVariant,
type Edge,
type Node,
ReactFlow,
@@ -19,13 +17,11 @@ import {
forceY,
type SimulationNodeDatum,
} from "d3-force"
import { Brain } from "lucide-react"
import { useEffect, useMemo } from "react"
import type { BrainGraph } from "@/client"
import { BrainEdge } from "./BrainEdge"
import { BrainNode, type BrainNodeData } from "./BrainNode"
import { CanvasTitle } from "./CanvasTitle"
import "./flow.css"
import { graphQueryOptions } from "./queries"
import { useFlowSocket } from "./useFlowSocket"
@@ -155,52 +151,50 @@ function BrainCanvas() {
}, [shape, fitView])
return (
<>
<ReactFlow
nodes={nodes}
edges={edges}
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
nodesDraggable={false}
nodesConnectable={false}
elementsSelectable={false}
proOptions={{ hideAttribution: true }}
fitView
fitViewOptions={FIT}
minZoom={0.1}
maxZoom={2}
onNodeClick={(_event, node) => {
const [flow] = (node.data as BrainNodeData).flows
if (flow)
navigate({ to: "/flows/$flowName", params: { flowName: flow } })
}}
className="h-full w-full"
>
<Background variant={BackgroundVariant.Dots} gap={24} size={1.5} />
</ReactFlow>
<div className="pointer-events-none absolute inset-0">
<CanvasTitle>
<span className="flex items-center gap-2 px-3 py-1.5 text-sm font-medium">
<Brain className="size-4 text-muted-foreground" />
Brain
</span>
</CanvasTitle>
</div>
</>
<ReactFlow
nodes={nodes}
edges={edges}
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
nodesDraggable={false}
nodesConnectable={false}
elementsSelectable={false}
proOptions={{ hideAttribution: true }}
fitView
fitViewOptions={FIT}
minZoom={0.1}
maxZoom={2}
// A band inside a page that scrolls. React Flow claims the wheel by
// default, so leaving these on would trap the page under the pointer;
// the fit above keeps the whole graph in view without panning anyway.
zoomOnScroll={false}
zoomOnDoubleClick={false}
panOnDrag={false}
preventScrolling={false}
onNodeClick={(_event, node) => {
const [flow] = (node.data as BrainNodeData).flows
if (flow)
navigate({ to: "/flows/$flowName", params: { flowName: flow } })
}}
className="brain-flat h-full w-full"
/>
)
}
/**
* Every flow at once, merged on what each node talks to.
*
* Read-only by design: what a neuron stands for lives in the flow it came
* from, and clicking one goes there.
* Sits flat on whatever surface the page paints — no card, no canvas of its
* own — because it is the overview at the top of Home rather than a screen you
* navigate to. Read-only by design: what a neuron stands for lives in the flow
* it came from, and clicking one goes there.
*/
export function BrainView() {
return (
<ReactFlowProvider>
<BrainCanvas />
</ReactFlowProvider>
<div className="h-64 w-full sm:h-80">
<ReactFlowProvider>
<BrainCanvas />
</ReactFlowProvider>
</div>
)
}
+8
View File
@@ -112,6 +112,14 @@
transform: translate(-50%, -50%);
}
/*
* Embedded on Home rather than on a canvas of its own: the graph paints no
* surface, so the page's own background shows through behind the neurons.
*/
.react-flow.brain-flat {
--xy-background-color: transparent;
}
.brain-cell {
cursor: pointer;
transition: border-color var(--duration-base) var(--ease-standard);