Definition
Information becomes scannable when it is split into small, semantically coherent units that the eye can process as one shape. A chunk is a unit of meaning, not a unit of layout — the grouping must follow the reader's task, not the designer's grid. Done right, chunking lets a reader navigate a long report by jumping rather than scrolling.
Why it matters for ShurIQ reports
Brand intelligence briefs run dense — gap cards, evidence chains, score breakdowns, viewport callouts. Without chunking, an executive bounces. With chunking, each card becomes an atomic unit of decision: one claim, one score, one evidence link. Stack-rank rows, viewport sections, and the editorial sidebar all rely on visible separation rules.
Takeaways
- Group by reader intent — what does this person need to decide on this scroll height? — not by data taxonomy.
- Enforce a hierarchy of three: section → card → field. More than three layers of grouping creates ambiguity.
- Use whitespace, borders, or background tone (one of those, not all three) to signal a chunk boundary.
- Re-chunk for each viewport: the same data may need different groupings in the editorial brief versus the viz hub.
Visual motion language
Cards form into their groups with a staggered entry (40ms between elements within a chunk, 250ms between chunks), then snap to the grid. The cadence should make group membership audible to the eye.
Origins
George A. Miller, 1956 — The Magical Number Seven, Plus or Minus Two.
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 · chunking · Cavalry scene
// Motion family: grid-stagger
// Palette: terracotta + 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_chunking_";
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 = "#B8442E";
var DARK = "#8E3322";
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 });
// 8 cols × 4 rows grid of small dots; the top-left 3×3 is the cream "chunk"
var COLS = 8, ROWS = 4, SPACE = 80, R = 18;
var startX = -((COLS - 1) * SPACE) / 2;
var startY = ((ROWS - 1) * SPACE) / 2;
for (var r = 0; r < ROWS; r++) {
for (var c = 0; c < COLS; c++) {
var d = api.primitive("ellipse", PREFIX + "dot_" + r + "_" + c);
api.set(d, {
"generator.radius": [R, R],
"position.x": startX + c * SPACE,
"position.y": startY - r * SPACE,
"opacity": 0
});
api.setFill(d, true);
var inChunk = (r < 3 && c < 3);
api.set(d, { "material.materialColor": inChunk ? CREAM : DARK });
// Row-by-row stagger
var rowFrame = r * 6;
var inFrame = rowFrame + Math.floor(c / 2);
var outFrame = inFrame + 6;
api.keyframe(d, inFrame, { "opacity": 0 });
api.keyframe(d, outFrame, { "opacity": 100 });
}
}
var layerCount = api.getAllSceneLayers().length;
console.log("scene built: chunking (" + layerCount + " layers)");
})();