LAWSOFUX · motion lab
Concept · law-of-common-region

Law of Common Region

Grid stagger reveal palette · forest / cream takeaways · 3

Definition

Elements enclosed inside a shared boundary are read as belonging together, regardless of their visual similarity. A border, a tinted background, or a card edge is enough to forge a group in the reader's eye. The boundary does the grouping work without any other cue.

Why it matters for ShurIQ reports

Gap cards, evidence panels, and stack-rank rows all rely on bounded regions to communicate "this is one unit of meaning." A faint card border or a 4% tinted background is what turns a wall of data into discrete claims. Lose the bounding and the report dissolves into noise; over-bound it and every card competes for attention.

Takeaways

Visual motion language

Cards animate in with a bounded-region reveal — the boundary draws first, then the contents fade in. The sequence makes group membership the reader's first impression.

Cavalry recreation seed. 320×320 square stroke 10px cream-tinted. Inside, 3×3 grid of 36px dots, all dark forest, except center dot cream. Pulse the cream center dot scale 1→1.15 over 1.4s sine, loop. Subtle outer-square stroke opacity oscillation 0.6→1 on a 2s phase-offset.

Origins

Gestalt psychology — early 20th century perceptual organization research.

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-common-region · Cavalry scene
// Motion family: single-form (square outline + 3x3 grid + center pulse)
// Palette: forest-green + 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-common-region_";

  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     = "#2D5A3F";
  var DARK   = "#1E4530";
  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 });

  // Outer container square outline
  var box = api.primitive("rectangle", PREFIX + "box");
  api.set(box, {
    "generator.dimensions": [400, 400],
    "position.x": 0, "position.y": 0,
    "opacity": 0
  });
  api.setFill(box, false);
  api.setStroke(box, true);
  api.set(box, { "stroke.strokeColor": CREAM, "stroke.width": 10 });
  api.keyframe(box, 0,  { "opacity": 0   });
  api.keyframe(box, 18, { "opacity": 60  });

  // 3x3 grid of dots
  var COLS = 3, ROWS = 3, SPACE = 110, R = 22;
  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);
      var isCenter = (r === 1 && c === 1);
      api.set(d, {
        "generator.radius": [R, R],
        "position.x": startX + c * SPACE,
        "position.y": startY - r * SPACE,
        "opacity": 0
      });
      api.setFill(d, true);
      api.set(d, { "material.materialColor": isCenter ? CREAM : DARK });

      var inF = 12 + (r * 3 + c) * 2;
      api.keyframe(d, inF,      { "opacity": 0   });
      api.keyframe(d, inF + 10, { "opacity": 100 });

      if (isCenter) {
        api.keyframe(d, 60,  { "scale.x": 1.0,  "scale.y": 1.0  });
        api.keyframe(d, 90,  { "scale.x": 1.15, "scale.y": 1.15 });
        api.keyframe(d, 120, { "scale.x": 1.0,  "scale.y": 1.0  });
      }
    }
  }

  // Stroke opacity oscillation on box
  api.keyframe(box, 30,  { "opacity": 100 });
  api.keyframe(box, 60,  { "opacity": 60  });
  api.keyframe(box, 90,  { "opacity": 100 });
  api.keyframe(box, 120, { "opacity": 60  });

  var layerCount = api.getAllSceneLayers().length;
  console.log("scene built: law-of-common-region (" + layerCount + " layers)");
})();