Definition
Elements joined by a visible connector — line, arrow, frame, ribbon — read as more strongly related than elements that are merely near or similar. Explicit connection beats implicit grouping. The connection itself does meaning work.
Why it matters for ShurIQ reports
Evidence trails (claim → evidence → source) and value-flow diagrams are exactly the surfaces where uniform connectedness earns its keep. A faint hairline from a stack-rank row to its supporting chart, or from a gap card to its source citation, makes the relationship undeniable. In a network viewport, edge styling carries as much meaning as node styling.
Takeaways
- Use explicit connectors when the relationship must survive a scroll, a re-flow, or a small screen.
- Keep connectors quiet — 0.04 to 0.15 opacity for graph edges, 1px hairlines for evidence links — so they group without dominating.
- Distinguish connector types (supports / contradicts / cites) by stroke style or color, never length alone.
- When a connector would cross the visual hierarchy (e.g., span two viewports), use a callout pattern instead.
Visual motion language
Connectors animate in as a trail behind the connected elements — line draws from source to target with a 200ms ease. Parallel rays for sibling connections share timing for legibility.
Origins
Gestalt psychology — added to the principles of grouping by later perceptual researchers.
Cavalry scene
The script below builds this concept's motion in Cavalry through the Stallion bridge. Pipe to cavalry_run_script via MCP, or paste into Cavalry's JavaScript Editor.
// Laws of UX · law-of-uniform-connectedness · Cavalry scene
// CORRECTED 2026-04-30 · verified from production page
// Motion family: nested concentric rings (NOT a starburst)
// 4 ring outlines, each carrying 3 small dots; outer-to-inner reveal
// Palette: deep cobalt + cream
// To run: pipe to cavalry_run_script tool, or paste into Cavalry's JavaScript Editor
// Built 2026-04-30 by ShurAI
(function () {
var PREFIX = "claude_lawofux_law-of-uniform-connectedness_";
var existing = api.getAllSceneLayers();
for (var i = 0; i < existing.length; i++) {
try {
var nm = api.getNiceName(existing[i]);
if (nm && nm.indexOf("claude_lawofux_") === 0) api.deleteLayer(existing[i]);
} catch (e) {}
}
var BG = "#1A4373";
var CREAM = "#D6CDB0";
var bg = api.primitive("rectangle", PREFIX + "bg");
api.set(bg, { "generator.dimensions": [1080, 1080] });
api.setFill(bg, true);
api.set(bg, { "material.materialColor": BG });
// 4 rings, outer-to-inner reveal. Radii proportional to verified 281/206/133/59 within 1080 canvas.
// Scale factor ~1.5 -> radii 420/310/200/90
var rings = [
{ radius: 420, angles: [12, 210, 305], beat: 0 },
{ radius: 310, angles: [80, 200, 350], beat: 8 },
{ radius: 200, angles: [60, 180, 300], beat: 16 },
{ radius: 90, angles: [30, 130, 240], beat: 24 }
];
var STROKE_W = 4;
for (var k = 0; k < rings.length; k++) {
var ring = rings[k];
// Ring as ellipse with stroke only
var ringId = api.primitive("ellipse", PREFIX + "ring_" + k);
api.set(ringId, {
"generator.radius": [ring.radius, ring.radius],
"position.x": 0, "position.y": 0,
"opacity": 0
});
api.setFill(ringId, false);
api.setStroke(ringId, true);
api.set(ringId, {
"stroke.strokeColor": CREAM,
"stroke.width": STROKE_W
});
api.keyframe(ringId, ring.beat, { "opacity": 0 });
api.keyframe(ringId, ring.beat + 10, { "opacity": 100 });
api.magicEasing(ringId, "opacity", ring.beat + 10, "EaseOut", "");
// 3 dots placed on this ring
for (var d = 0; d < 3; d++) {
var rad = ring.angles[d] * Math.PI / 180;
var dx = Math.cos(rad) * ring.radius;
var dy = Math.sin(rad) * ring.radius; // Y positive=up: positive sin for upper-right? OK
var dot = api.primitive("ellipse", PREFIX + "ring_" + k + "_dot_" + d);
api.set(dot, {
"generator.radius": [18, 18],
"position.x": dx,
"position.y": dy,
"opacity": 0
});
api.setFill(dot, true);
api.set(dot, { "material.materialColor": CREAM });
api.keyframe(dot, ring.beat, { "opacity": 0 });
api.keyframe(dot, ring.beat + 10, { "opacity": 100 });
api.magicEasing(dot, "opacity", ring.beat + 10, "EaseOut", "");
}
}
var layerCount = api.getAllSceneLayers().length;
console.log("scene built: law-of-uniform-connectedness (" + layerCount + " layers)");
})();