Definition
Users arrive at every new interface carrying expectations from every other interface they already use. The familiar pattern wins by default — a novel pattern has to earn its keep against the cumulative weight of learned conventions. Originality is a tax the user did not agree to pay.
Why it matters for ShurIQ reports
A brand-intelligence brief reads alongside Bloomberg, Pitchbook, McKinsey decks, and the client's internal dashboards. Stack rankings should resolve as a reader expects (sortable columns, sticky header, pagination); evidence trails should behave like footnote panels they already know. Reserve novelty for the analytical insight — never for the navigation.
Takeaways
- Audit every interaction against the three or four reference products the client already uses daily.
- When breaking convention is genuinely necessary, signal the change with one familiar element (a known icon, a standard tooltip).
- Migration paths matter: when changing a layout pattern in a recurring report, give returning readers a temporary toggle to the old version.
- Use convention to absorb cognitive load so the analytical content can carry novelty.
Visual motion language
Initial layout snaps to a familiar dashboard grid with a steady fade-in; group-form animations follow the conventions the reader has already internalized from spreadsheets and BI tools.
Origins
Jakob Nielsen — Nielsen Norman Group usability research, late 1990s onward.
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 · jakobs-law · Cavalry scene
// Motion family: single-form (two converging squares)
// Palette: olive-mustard + 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_jakobs-law_";
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 = "#8C7C45";
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 });
var sqA = api.primitive("rectangle", PREFIX + "sqA");
api.set(sqA, {
"generator.dimensions": [320, 320],
"position.x": -200, "position.y": 200,
"opacity": 0
});
api.setFill(sqA, false);
api.setStroke(sqA, true);
api.set(sqA, { "stroke.strokeColor": CREAM, "stroke.width": 12 });
var sqB = api.primitive("rectangle", PREFIX + "sqB");
api.set(sqB, {
"generator.dimensions": [320, 320],
"position.x": 200, "position.y": -200,
"opacity": 0
});
api.setFill(sqB, false);
api.setStroke(sqB, true);
api.set(sqB, { "stroke.strokeColor": CREAM, "stroke.width": 12 });
// Fade in then converge
api.keyframe(sqA, 0, { "opacity": 0, "position.x": -260, "position.y": 260 });
api.keyframe(sqA, 12, { "opacity": 100, "position.x": -260, "position.y": 260 });
api.keyframe(sqA, 36, { "opacity": 100, "position.x": -120, "position.y": 120 });
api.magicEasing(sqA, "position.x", 36, "EaseOut", "");
api.magicEasing(sqA, "position.y", 36, "EaseOut", "");
api.keyframe(sqB, 0, { "opacity": 0, "position.x": 260, "position.y": -260 });
api.keyframe(sqB, 12, { "opacity": 100, "position.x": 260, "position.y": -260 });
api.keyframe(sqB, 36, { "opacity": 100, "position.x": 120, "position.y": -120 });
api.magicEasing(sqB, "position.x", 36, "EaseOut", "");
api.magicEasing(sqB, "position.y", 36, "EaseOut", "");
// Subtle horizontal nudge on B
api.keyframe(sqB, 60, { "position.x": 120 });
api.keyframe(sqB, 96, { "position.x": 128 });
api.keyframe(sqB, 132, { "position.x": 120 });
var layerCount = api.getAllSceneLayers().length;
console.log("scene built: jakobs-law (" + layerCount + " layers)");
})();