Diamond Tracer
A click-to-propagate backward-pass visualizer on a diamond computation graph. The learner walks ∂y/∂a down from the output y, through two parallel branches (×2 and ×3) that reconverge at the input node a, and discovers the multipath rule of reverse-mode autodiff: when a variable fans out, the gradients from each path SUM at the fan-out point.
The forward model is y = 2a + 3a, so dy/da = 5. The backward walk reaches the same answer by carrying gradient 1 from y, splitting it equally through +, scaling each branch by the local derivative, and summing the two arrivals at a.
∂y/∂y = 1. The gradient starts at the output. The backward pass walks the graph top to bottom — the reverse of the forward pass. Click the + node to propagate the gradient backward.
Installation
npx shadcn@latest add https://craftbits.dev/r/diamond-tracer.jsonUsage
import { DiamondTracer } from "@craft-bits/viz/diamond-tracer";
<DiamondTracer />Hook into stage changes to drive an external phase ribbon:
<DiamondTracer
onStageChange={(stage) => {
/* phase ribbon: highlight `stage` */
}}
/>Understanding the component
- The diamond graph. Five nodes laid out top-to-bottom for backward flow:
y(output) →+(addition) →×2and×3(two parallel multiply branches) →a(input). Forward values are rendered inside each node so the learner can cross-check the walk against the algebra. - Stage machine. Four stages drive the palette, narration, and which nodes are clickable:
start(only+is active),split(both×2and×3are active, in any order),both-done(auto-transitions to summation),complete(sum has landed, Reset appears). Every stage transition emitsonStageChange. - Click
+. The addition node flashes warning-tone. Two pulses emit simultaneously from+, travel down both edges, and gradient-1badges fade in at×2and×3. Both mul nodes start breathing — they're now clickable. - Click
×2or×3. The clicked node flashes accent-tone. A mid-edge badge briefly shows the chain-rule multiplication (1×2or1×3), then resolves to the result. A pulse travels down the edge toa, where a small badge lands. - Summation. Once both branches have arrived, the walker auto-advances. A
2 + 3text appears abovea, then flashes to= 5. The two arrival badges fade out, the final∂y/∂a = 5badge fades in, and the input node lights up success-tone with a one-shot glow. - Reduced motion. Under
prefers-reduced-motion: reduce, every spring collapses to an instant attribute set, pulses snap to their endpoints, and the breathing rings on ready nodes disappear.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
transition | Transition | SPRINGS.smooth | Override the spring used by per-node flashes and badge fades. |
onStageChange | (stage) => void | — | Fires when the walker advances to split, both-done, or complete. |
onReset | () => void | — | Fires when the user clicks Reset after completion. |
className | string | — | Merged onto the root via cn(). |
Accessibility
- The graph SVG is
role="img"with anaria-labelsummarising the current stage and the expressiony = 2a + 3a. - Each interactive node is its own
role="button"circle with a node-specificaria-label. Only the currently-ready nodes are focusable — the rest carry notabIndex. EnterandSpacewhile a node is focused activate the same handler as a click — the entire walk is keyboard-reachable.- An
aria-live="assertive"region announces which branch just landed and which node is next, so the walker is usable without sight. - The narration paragraph has
aria-live="polite"and mutes during the in-flight animation so screen readers don't trip over per-frame redraws. - Colour is never the only signal: stage is encoded in the narration prose, the live-region status text, and a
data-stageattribute on the root. - Motion respects
prefers-reduced-motion: reduce— pulses snap, breathing rings disable, and every spring collapses to an instant attribute set.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/math/DiamondTracer.tsx). The source was a lesson-bound component — it importedSvgLabelandChallengeBtnfrom the lesson chrome, depended on per-track palette tokens (--color-accent-500,--color-warn-400, etc.), and inlined ad-hoc spring names (gentle,snappy) that don't exist in the canonical motion module. The viz extract drops the lesson chrome, remaps every colour tovar(--cb-*)semantic tokens so consumer themes repaint freely, re-keys the springs toSPRINGS.smooth/SPRINGS.snap/SPRINGS.bouncy, and exposes stage changes viaonStageChangeso the multipath teaching moment can drive an external UI.