A node type can now say which outside thing its parameters point at, and nodes sharing one — a broker topic, a URL, a bucket — are drawn as a single neuron on a new /brain canvas. That makes the wiring which runs between flows through a broker visible for the first time; no single flow's canvas can show it. The key is read off stored parameters, so a credential reference never reaches an id. Layout is a d3 force simulation settled once and then frozen, lit by the socket the editor already listens to: a neuron pulses when any node behind it publishes, and its connections light as values pass. Fixes the message pulse while here: interpolating the stroke against the edge's `color-mix()` resting colour went through oklab and left the gamut, which turned every pulse on both canvases fluorescent yellow.
123 lines
3.1 KiB
CSS
123 lines
3.1 KiB
CSS
/*
|
|
* React Flow, routed through the design tokens.
|
|
*
|
|
* Scoped to `.react-flow` rather than added to index.css, so the canvas needs no
|
|
* tokens of its own and follows the theme in both modes without a `colorMode`
|
|
* prop. See the root DESIGN-GUIDELINES.md → Shells.
|
|
*/
|
|
|
|
.react-flow {
|
|
--xy-background-color: var(--background);
|
|
--xy-background-pattern-dots-color: color-mix(
|
|
in srgb,
|
|
var(--muted-foreground) 30%,
|
|
transparent
|
|
);
|
|
--xy-edge-stroke: color-mix(
|
|
in srgb,
|
|
var(--muted-foreground) 55%,
|
|
transparent
|
|
);
|
|
--xy-edge-stroke-selected: var(--primary);
|
|
--xy-edge-stroke-width: 1.5;
|
|
--xy-handle-background-color: var(--card);
|
|
--xy-handle-border-color: var(--muted-foreground);
|
|
--xy-selection-background-color: color-mix(
|
|
in srgb,
|
|
var(--primary) 8%,
|
|
transparent
|
|
);
|
|
--xy-selection-border: 1px solid var(--primary);
|
|
--xy-attribution-background-color: transparent;
|
|
}
|
|
|
|
/* A message arriving lights its edge, then decays back to rest. */
|
|
@media (prefers-reduced-motion: no-preference) {
|
|
.react-flow__edge-path.edge-live {
|
|
animation: edge-pulse var(--duration-pulse) var(--ease-emphasized);
|
|
}
|
|
|
|
/*
|
|
* Both ends are plain colours. The implied `to` would be the edge's resting
|
|
* stroke, which is a `color-mix()` — and interpolating a hex against one of
|
|
* those goes through oklab and leaves the gamut on the way, which turned
|
|
* every pulse fluorescent yellow. Landing on `--muted-foreground` instead is
|
|
* the same hue the edge rests in, so the last step back is invisible.
|
|
*/
|
|
@keyframes edge-pulse {
|
|
from {
|
|
stroke: var(--primary);
|
|
stroke-width: 2.5;
|
|
}
|
|
to {
|
|
stroke: var(--muted-foreground);
|
|
stroke-width: var(--xy-edge-stroke-width);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* A node that just published something says so, once, and settles. */
|
|
@media (prefers-reduced-motion: no-preference) {
|
|
.node-pulse {
|
|
position: absolute;
|
|
inset: -3px;
|
|
border-radius: inherit;
|
|
border: 2px solid var(--primary);
|
|
box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
|
|
pointer-events: none;
|
|
animation: node-pulse var(--duration-pulse) var(--ease-emphasized) forwards;
|
|
}
|
|
|
|
@keyframes node-pulse {
|
|
from {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: scale(1.09);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Handles are neutral: the one brand-secondary affordance here is Run. */
|
|
.react-flow__handle {
|
|
width: 12px;
|
|
height: 12px;
|
|
border-width: 2px;
|
|
}
|
|
|
|
.react-flow__handle.unbound {
|
|
border-style: dashed;
|
|
border-color: color-mix(in srgb, var(--muted-foreground) 40%, transparent);
|
|
}
|
|
|
|
.react-flow__handle-connecting {
|
|
border-color: var(--primary);
|
|
}
|
|
|
|
.react-flow__node:focus-visible,
|
|
.react-flow__node:focus {
|
|
outline: none;
|
|
}
|
|
|
|
/*
|
|
* Brain graph. Both ends of a connection sit at the neuron's centre, so an
|
|
* edge runs straight from circle to circle and disappears under them.
|
|
*/
|
|
.brain-handle {
|
|
opacity: 0;
|
|
left: 50%;
|
|
top: 50%;
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
|
|
.brain-cell {
|
|
cursor: pointer;
|
|
transition: border-color var(--duration-base) var(--ease-standard);
|
|
}
|
|
|
|
.brain-cell:hover {
|
|
border-color: var(--primary);
|
|
}
|