LAWSOFUX · motion lab
Candidate · status: pending review

Opacity-stepped horizontal bands.

A single parameterized generator that draws N horizontal bands stacked vertically with stepped per-band opacity. By swapping which row gets full-cream and whether one row is truncated, the same scaffold expresses three semantically distinct UX heuristics. The convergence is unusual enough to warrant promotion into the named visual grammar.

Summary

This pattern was discovered during the Phase 2 verification of the Laws of UX motion ontology. Three concepts — goal-gradient-effect, zeigarnik-effect, and postels-law — on the lawsofux.com production page resolve to the same underlying scaffold: a vertical stack of horizontal bands with stepped per-band opacity. One generator covers three distinct UX heuristics across three different color domains. That is the case for promotion.

Three roles, one scaffold

Role 1 · proximity-to-goal · goal-gradient
Role 2 · multi-input cascade · postels-law
Role 3 · incompleteness · zeigarnik-effect (note bottom cream row truncated to ~52% width)

Generator parameters

The primitive accepts five core parameters and one optional one. Stagger is fixed at row-by-row top-to-bottom, ~120ms per row, cubic ease-out, with a 2.5s hold before loop.

parameter type role
row_countint (4–9)number of horizontal bands stacked vertically
opacity_startfloat (0–1)fill-opacity of the top band
opacity_endfloat (0–1)fill-opacity of the bottom band; intermediate rows interpolate
cream_rowint | nullrow index that gets full-opacity cream override (null = no override)
truncation_rowint | nullrow index whose width is truncated; null = full width
truncation_pctfloat (0–1)fraction of canvas width the truncated row occupies

Cavalry pseudo-code

function buildOpacityBands(api, prefix, params) {
  var step = params.stripeH + params.gutter;
  var topY = ((params.rowCount - 1) * step) / 2;

  var bg = api.primitive("rectangle", prefix + "bg");
  api.set(bg, { "generator.dimensions": [params.canvasW, params.canvasH] });
  api.setFill(bg, true);
  api.set(bg, { "material.materialColor": params.bg });

  for (var r = 1; r <= params.rowCount; r++) {
    var t = (r - 1) / (params.rowCount - 1);
    var opacity = params.opacityStart + (params.opacityEnd - params.opacityStart) * t;
    var fill = params.mutedColor || params.cream;

    if (params.creamRow === r) { opacity = 1.0; fill = params.cream; }

    var width = params.canvasW * 0.85;
    if (params.truncationRow === r && params.truncationPct) {
      width = params.canvasW * params.truncationPct;
    }

    var shape = api.primitive("rectangle", prefix + "row_" + r);
    api.set(shape, {
      "generator.dimensions": [width, params.stripeH],
      "position.y": topY - (r - 1) * step,
      "opacity": 0
    });
    api.setFill(shape, true);
    api.set(shape, { "material.materialColor": fill });

    var t0 = (r - 1) * 4, t1 = t0 + 8;
    api.keyframe(shape, t0, { "opacity": 0 });
    api.keyframe(shape, t1, { "opacity": Math.round(opacity * 100) });
    api.magicEasing(shape, "opacity", t1, "EaseOut", "");
  }
}

Rationale for promotion

Three independently-designed Laws of UX concepts — encoded by an external designer years before ShurIQ existed — converge on the same underlying scaffold. That convergence is rare and meaningful. When one motion family carries three distinct semantic loads (momentum, cascade, incompleteness) without any visual recoloring of the bands themselves — only opacity steps and one truncation — it stops being a coincidence and starts being a grammar element worth naming.

For shuriq-motion specifically, this primitive is a natural sibling to value-flow (which moves left-to-right) and rubric-axis (which charts a single dimension). opacity-stepped-bands charts a vertical decay across N items — the missing axis: temporal/causal layering rather than spatial flow. Promoting it into the visual grammar gives ShurIQ a reusable component for partial recall, multi-source ingestion with canonical selection, open-loop gap cards, and proximity-to-goal indicators in regulatory-grade brand intelligence reports — patterns we already need but currently render ad hoc.

Decision pending. The user reviews this candidate and decides whether to formally name it (opacity-stepped-bands is the proposed handle) and merge it into shuriq-motion/references/visual-grammar.md. Until then, this page is the spec a future implementer can reference without re-discovering the pattern.