LAWSOFUX · motion lab
Concept · aesthetic-usability-effect

Aesthetic-Usability Effect

Single-form composition palette · cobalt / cream takeaways · 3

Definition

Polished visuals raise the user's perceived usability of an interface, even when the underlying flow has friction. The aesthetic signal runs ahead of the functional signal — beauty buys patience. This forgiveness is real but bounded; it masks small flaws, not broken paths.

Why it matters for ShurIQ reports

A regulatory-grade brand intelligence report has to read as crafted before a CMO will trust the score. Editorial typography, IBM Plex pairings, and consistent color discipline on stack-rank rows let evidence trails breathe and let dense gap cards feel orderly. Aesthetic restraint is what makes the analytical layer feel earned rather than alarming.

Takeaways

Visual motion language

Open with a slow opacity ramp on the headline and key chart, paired with a single accent-color emphasis sweep on the lead score. Cadence should feel deliberate (600–900ms in, 200ms hold) — never bouncy.

Cavalry recreation seed. A 600×600 panel filled #1F2C3A. Place a circle ø500 centered, fill #2A3A4D, opacity 0.6. Inside it place a square (440×440) with the same darker fill. Centered in the square render an isoceles triangle (base 280, height 320) filled cream. On entry: circle scales 0→1 over 700ms (ease-out), square fades 0→1 over 500ms with 200ms delay, triangle scales 0.7→1 + fades over 600ms with 600ms delay. Hold static.

Origins

Masaaki Kurosu and Kaori Kashimura, Hitachi Design Center, 1995 — ATM interface study with 252 participants.

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 · aesthetic-usability-effect · Cavalry scene
// Motion family: single-form
// Palette: slate-navy + 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_aesthetic-usability-effect_";

  // Defensive cleanup of any prior runs
  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     = "#1F2C3A";
  var DARK   = "#2A3A4D";
  var CREAM  = "#D6CDB0";

  var bg = api.primitive("rectangle", PREFIX + "bg");
  api.set(bg, { "generator.dimensions": [1080, 1080], "position.x": 0, "position.y": 0 });
  api.setFill(bg, true);
  api.set(bg, { "material.materialColor": BG });

  var disk = api.primitive("ellipse", PREFIX + "disk");
  api.set(disk, { "generator.radius": [500, 500], "position.x": 0, "position.y": 0, "opacity": 0 });
  api.setFill(disk, true);
  api.set(disk, { "material.materialColor": DARK });

  var sq = api.primitive("rectangle", PREFIX + "innerSquare");
  api.set(sq, { "generator.dimensions": [440, 440], "position.x": 0, "position.y": 0, "opacity": 0 });
  api.setFill(sq, true);
  api.set(sq, { "material.materialColor": DARK });

  // Triangle as 3-sided polygon, base 280, height 320 → radius ~185
  var tri = api.primitive("polygon", PREFIX + "triangle");
  api.set(tri, {
    "generator.sides": 3,
    "generator.radius": 185,
    "position.x": 0,
    "position.y": -20,
    "rotation.z": 0,
    "opacity": 0,
    "scale.x": 0.7,
    "scale.y": 0.7
  });
  api.setFill(tri, true);
  api.set(tri, { "material.materialColor": CREAM });

  // Disk: 0→1 over 17 frames (700ms @ 24fps)
  api.keyframe(disk, 0,  { "opacity": 0,  "scale.x": 0.6, "scale.y": 0.6 });
  api.keyframe(disk, 17, { "opacity": 60, "scale.x": 1.0, "scale.y": 1.0 });
  api.magicEasing(disk, "scale.x", 17, "EaseOut", "");
  api.magicEasing(disk, "scale.y", 17, "EaseOut", "");

  // Square: 5-frame delay then 12-frame fade
  api.keyframe(sq, 5,  { "opacity": 0   });
  api.keyframe(sq, 17, { "opacity": 100 });

  // Triangle: 14-frame delay then 14-frame entrance
  api.keyframe(tri, 14, { "opacity": 0,   "scale.x": 0.7, "scale.y": 0.7 });
  api.keyframe(tri, 28, { "opacity": 100, "scale.x": 1.0, "scale.y": 1.0 });
  api.magicEasing(tri, "scale.x", 28, "EaseOut", "");
  api.magicEasing(tri, "scale.y", 28, "EaseOut", "");

  // Idle breathing on the triangle
  api.keyframe(tri, 60,  { "scale.x": 1.0,  "scale.y": 1.0  });
  api.keyframe(tri, 90,  { "scale.x": 1.04, "scale.y": 1.04 });
  api.keyframe(tri, 120, { "scale.x": 1.0,  "scale.y": 1.0  });

  var layerCount = api.getAllSceneLayers().length;
  console.log("scene built: aesthetic-usability-effect (" + layerCount + " layers)");
})();