LAWSOFUX · motion lab
Concept · peak-end-rule

Peak-End Rule

Grid stagger reveal palette · cobalt / cream takeaways · 3

Definition

An experience is remembered by its emotional peak and its final moment, not by its average. A long brief with one strong insight and a clean ending outperforms a uniformly competent brief in the reader's memory. Negative peaks weigh more than positive ones, so failures at the peak or end are disproportionately costly.

Why it matters for ShurIQ reports

Every recurring intelligence brief should be engineered with a deliberate peak (the hero insight, the shocking gap, the tracked delta) and a deliberate end (a clear recommendation, a memorable visual, a single takeaway). The middle can be dense — what the reader will recall is whether the peak landed and whether the closing said something they could carry into the next meeting.

Takeaways

Visual motion language

Peak moments use a color-emphasis glow-burst with extended hold (1.5–2s); the closing recommendation fades in solo on a quiet field, with no competing motion.

Cavalry recreation seed. 5×5 grid of 60px dots, 80px spacing. All dark navy. At t=600ms highlight dot at row 3 col 3 (peak): fill cream and scale 1→1.2→1 in 500ms. At t=1.6s highlight dot at row 5 col 5 (end): same animation. Hold 2s. Optional: a faint cream line connects the peak and end at t=2.2s.

Origins

Daniel Kahneman, Barbara Fredrickson, Charles Schreiber, and Donald Redelmeier, 1993.

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 · peak-end-rule · Cavalry scene
// Motion family: grid-stagger (5x5 grid + two highlight events)
// Palette: cobalt + 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_peak-end-rule_";

  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    = "#1E5C8C";
  var DARK  = "#163E5C";
  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 COLS = 5, ROWS = 5, SPACE = 90, R = 28;
  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);
      api.set(d, { "material.materialColor": DARK });
      api.keyframe(d, 0,  { "opacity": 0  });
      api.keyframe(d, 14, { "opacity": 70 });
    }
  }

  // Peak: row 2 col 2 (center)
  var peak = api.primitive("ellipse", PREFIX + "peak");
  api.set(peak, {
    "generator.radius": [R, R],
    "position.x": startX + 2 * SPACE,
    "position.y": startY - 2 * SPACE,
    "opacity": 0,
    "scale.x": 1.0, "scale.y": 1.0
  });
  api.setFill(peak, true);
  api.set(peak, { "material.materialColor": CREAM });
  api.keyframe(peak, 24, { "opacity": 0,   "scale.x": 1.0, "scale.y": 1.0 });
  api.keyframe(peak, 36, { "opacity": 100, "scale.x": 1.2, "scale.y": 1.2 });
  api.keyframe(peak, 48, { "opacity": 100, "scale.x": 1.0, "scale.y": 1.0 });

  // End: row 4 col 4 (bottom-right)
  var end = api.primitive("ellipse", PREFIX + "end");
  api.set(end, {
    "generator.radius": [R, R],
    "position.x": startX + 4 * SPACE,
    "position.y": startY - 4 * SPACE,
    "opacity": 0,
    "scale.x": 1.0, "scale.y": 1.0
  });
  api.setFill(end, true);
  api.set(end, { "material.materialColor": CREAM });
  api.keyframe(end, 60, { "opacity": 0,   "scale.x": 1.0, "scale.y": 1.0 });
  api.keyframe(end, 72, { "opacity": 100, "scale.x": 1.2, "scale.y": 1.2 });
  api.keyframe(end, 84, { "opacity": 100, "scale.x": 1.0, "scale.y": 1.0 });

  // Faint connecting line peak → end
  var line = api.primitive("rectangle", PREFIX + "line");
  var p1x = startX + 2 * SPACE, p1y = startY - 2 * SPACE;
  var p2x = startX + 4 * SPACE, p2y = startY - 4 * SPACE;
  var dx = p2x - p1x, dy = p2y - p1y;
  var len = Math.sqrt(dx*dx + dy*dy);
  var ang = Math.atan2(dy, dx) * (180 / Math.PI);
  api.set(line, {
    "generator.dimensions": [len, 3],
    "position.x": (p1x + p2x) / 2,
    "position.y": (p1y + p2y) / 2,
    "rotation.z": ang,
    "opacity": 0
  });
  api.setFill(line, true);
  api.set(line, { "material.materialColor": CREAM });
  api.keyframe(line, 90,  { "opacity": 0  });
  api.keyframe(line, 110, { "opacity": 50 });

  var layerCount = api.getAllSceneLayers().length;
  console.log("scene built: peak-end-rule (" + layerCount + " layers)");
})();