Definition
Any task expands to fill the time the user expects to spend on it. If a form is laid out to look like a 10-minute task, it will take 10 minutes — even if the underlying data could be entered in two. Users calibrate effort to perceived duration, not actual duration.
Why it matters for ShurIQ reports
A brief that signals "long read" will be skimmed in long-read posture; a brief that signals "five-minute briefing" will get five focused minutes. The reading surface must telegraph its expected duration honestly: a viz hub with five viewports tells the executive to budget five short engagements, not one long one. Likewise, autofill on filter rails and saved viewport states cut perceived effort and convert dropoff into completion.
Takeaways
- Surface expected duration explicitly ("3-minute read", "5 viewports") so the reader matches their attention budget.
- Use autofill, sticky filter state, and remembered defaults to compress perceived effort on returning visits.
- Cap form length to what the data actually requires; do not pad for visual symmetry.
- Where the task is genuinely long, break it into checkpointed steps so each one feels finishable.
Visual motion language
Form fields and filter rails count-up populated values from cached state with a 200ms reveal; the visible auto-completion communicates "this will be fast."
Origins
Cyril Northcote Parkinson, 1955 — essay published in The Economist.
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 · parkinsons-law · Cavalry scene
// Motion family: single-form (diamond + 4 outward-pulsing arrows)
// 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_parkinsons-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 DARK = "#6E5F2F";
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 });
// Diamond = rotated square outline
var dia = api.primitive("rectangle", PREFIX + "diamond");
api.set(dia, {
"generator.dimensions": [320, 320],
"position.x": 0, "position.y": 0,
"rotation.z": 45,
"opacity": 0
});
api.setFill(dia, false);
api.setStroke(dia, true);
api.set(dia, { "stroke.strokeColor": CREAM, "stroke.width": 12 });
api.keyframe(dia, 0, { "opacity": 0 });
api.keyframe(dia, 18, { "opacity": 100 });
// Center dot
var cd = api.primitive("ellipse", PREFIX + "center");
api.set(cd, {
"generator.radius": [18, 18],
"position.x": 0, "position.y": 0,
"opacity": 0
});
api.setFill(cd, true);
api.set(cd, { "material.materialColor": DARK });
api.keyframe(cd, 6, { "opacity": 0 });
api.keyframe(cd, 22, { "opacity": 100 });
// 4 corner arrows projecting outward (use triangles)
// Diamond corners (after rotation 45°): top, right, bottom, left
// distances ≈ half-diagonal of 320 square = ~226
var d = 290;
var arrows = [
{ x: 0, y: d, rot: 0 }, // top → up
{ x: d, y: 0, rot: 90 }, // right
{ x: 0, y: -d, rot: 180 }, // bottom
{ x: -d, y: 0, rot: -90 } // left
];
for (var i = 0; i < arrows.length; i++) {
var a = arrows[i];
var arr = api.primitive("polygon", PREFIX + "arrow_" + i);
api.set(arr, {
"generator.sides": 3,
"generator.radius": 36,
"position.x": a.x, "position.y": a.y,
"rotation.z": a.rot,
"opacity": 0,
"scale.x": 0.7, "scale.y": 0.7
});
api.setFill(arr, true);
api.set(arr, { "material.materialColor": CREAM });
api.keyframe(arr, 18, { "opacity": 0, "scale.x": 0.7, "scale.y": 0.7 });
api.keyframe(arr, 36, { "opacity": 100, "scale.x": 1.0, "scale.y": 1.0 });
// Sync outward pulse
api.keyframe(arr, 60, { "scale.x": 1.0, "scale.y": 1.0 });
api.keyframe(arr, 84, { "scale.x": 1.3, "scale.y": 1.3 });
api.keyframe(arr, 108, { "scale.x": 1.0, "scale.y": 1.0 });
}
var layerCount = api.getAllSceneLayers().length;
console.log("scene built: parkinsons-law (" + layerCount + " layers)");
})();