Definition
The eye resolves complex shapes into the simplest interpretation it can construct. Faced with ambiguity, perception collapses to symmetry, regularity, and unity. Designers cannot stop this — they can only choose whether the simplest read matches the intended meaning.
Why it matters for ShurIQ reports
A complex network viewport or layered chart will be read as its dominant simple shape — a circle, a column, a flow — long before the reader parses any individual node. The implication: every dense visualization must have a clean shape at first glance, with detail revealed on inspection. If the simplest read of a chart says the wrong thing, the chart is wrong.
Takeaways
- Test every chart at squint distance: is the shape the reader sees first the shape you mean?
- Lead with simplified silhouettes; expose detail through interaction, not initial paint.
- When a layout has multiple competing simple shapes, choose one and subordinate the rest.
- Use motion to morph from simple to detailed states, letting the eye follow without losing the shape.
Visual motion language
Complex visualizations enter as a simple aggregate shape (a fading circle, a single column), then mass-collapse outward into their detailed components. The opening shape primes the perceptual frame.
Origins
Max Wertheimer, 1910 — foundational Gestalt principle of perceptual simplicity.
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-pragnanz · Cavalry scene
// Motion family: grid-stagger (2x2 morph cascade)
// Palette: hot-pink + 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-pragnanz_";
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 = "#C44E7E";
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 });
// 2x2 cells: complex(star) → hex+star → hexagon → circle
// Quadrant centers
var quads = [
{ x: -160, y: 160, time: 0 },
{ x: 160, y: 160, time: 14 },
{ x: -160, y: -160, time: 28 },
{ x: 160, y: -160, time: 42 }
];
// Q1 — complex pentagram inscribed (using 5-point star)
var q1 = api.primitive("star", PREFIX + "q1_star");
api.set(q1, {
"generator.points": 5,
"generator.outerRadius": 90,
"generator.innerRadius": 38,
"position.x": quads[0].x, "position.y": quads[0].y,
"opacity": 0
});
api.setFill(q1, false);
api.setStroke(q1, true);
api.set(q1, { "stroke.strokeColor": CREAM, "stroke.width": 6 });
var q1b = api.primitive("polygon", PREFIX + "q1_hex");
api.set(q1b, {
"generator.sides": 6, "generator.radius": 110,
"position.x": quads[0].x, "position.y": quads[0].y,
"opacity": 0
});
api.setFill(q1b, false);
api.setStroke(q1b, true);
api.set(q1b, { "stroke.strokeColor": CREAM, "stroke.width": 6 });
// Q2 — hex with bowtie (we use 6-point star)
var q2 = api.primitive("star", PREFIX + "q2_star");
api.set(q2, {
"generator.points": 6,
"generator.outerRadius": 100,
"generator.innerRadius": 50,
"position.x": quads[1].x, "position.y": quads[1].y,
"opacity": 0
});
api.setFill(q2, false);
api.setStroke(q2, true);
api.set(q2, { "stroke.strokeColor": CREAM, "stroke.width": 6 });
// Q3 — simple hexagon
var q3 = api.primitive("polygon", PREFIX + "q3_hex");
api.set(q3, {
"generator.sides": 6, "generator.radius": 100,
"position.x": quads[2].x, "position.y": quads[2].y,
"opacity": 0
});
api.setFill(q3, false);
api.setStroke(q3, true);
api.set(q3, { "stroke.strokeColor": CREAM, "stroke.width": 6 });
// Q4 — circle (the simplest)
var q4 = api.primitive("ellipse", PREFIX + "q4_circle");
api.set(q4, {
"generator.radius": [100, 100],
"position.x": quads[3].x, "position.y": quads[3].y,
"opacity": 0
});
api.setFill(q4, false);
api.setStroke(q4, true);
api.set(q4, { "stroke.strokeColor": CREAM, "stroke.width": 6 });
// Reveal sequence
api.keyframe(q1, 0, { "opacity": 0 });
api.keyframe(q1, 18, { "opacity": 100 });
api.keyframe(q1b, 0, { "opacity": 0 });
api.keyframe(q1b, 18, { "opacity": 100 });
api.keyframe(q2, 14, { "opacity": 0 });
api.keyframe(q2, 32, { "opacity": 100 });
api.keyframe(q3, 28, { "opacity": 0 });
api.keyframe(q3, 46, { "opacity": 100 });
api.keyframe(q4, 42, { "opacity": 0 });
api.keyframe(q4, 60, { "opacity": 100 });
// Razor sweep: dim the earlier, leave Q4 bright
api.keyframe(q1, 72, { "opacity": 100 });
api.keyframe(q1, 96, { "opacity": 25 });
api.keyframe(q1b, 72, { "opacity": 100 });
api.keyframe(q1b, 96, { "opacity": 25 });
api.keyframe(q2, 78, { "opacity": 100 });
api.keyframe(q2, 102, { "opacity": 25 });
api.keyframe(q3, 84, { "opacity": 100 });
api.keyframe(q3, 108, { "opacity": 30 });
var layerCount = api.getAllSceneLayers().length;
console.log("scene built: law-of-pragnanz (" + layerCount + " layers)");
})();