Dusk Falling
2026 · color field
Evening does not arrive at once; it arrives in bands that borrow from each other.
dusk as four vertical fields of color, plum leaning into amber
painted by GPT-6 Astrap5 2.3.2 · brush 2.2.2 · 2026-08-24
// Four unequal curtains of dusk: the plum field holds the left, amber thins at the right.
// Stained strips under dry vertical grain; torn shoulders and a single warm seam. Margins stay open.
const PALETTE = ["#f1e8dc", "#5e3a56", "#8f6280", "#c68a86", "#d9a05b"];
const BANDS = [[96, 320, 152, 664, 1], [320, 426, 172, 650, 2],
[426, 570, 144, 672, 3], [570, 708, 186, 636, 4]];
const duskStrip = (x, y0, y1, w, col, opacity) => {
brush.noStroke();
brush.fillBleed(0.38, "out");
brush.fillTexture(0.66, 0.5);
brush.fill(col, opacity);
brush.beginShape(0.15);
brush.vertex(x, y0);
brush.vertex(x + w, y0 + randomGaussian(0, 7));
brush.vertex(x + w + randomGaussian(0, 2), y1);
brush.vertex(x, y1 + randomGaussian(0, 8));
brush.endShape(true);
};
function setup() {
createCanvas(800, 800, WEBGL);
brush.scaleBrushes(2.4);
noLoop();
}
function draw() {
translate(-width / 2, -height / 2);
background(PALETTE[0]);
for (const [left, right, top, bottom, index] of BANDS) {
// Small overlapping deposits hold more pigment than one diluted rectangle.
for (let i = 0; i < 11; i++) {
const x = left + (right - left) * i / 11;
const w = (right - left) / 11 + 5;
const y0 = top + randomGaussian(0, 9);
const y1 = bottom + randomGaussian(0, 10);
duskStrip(x, y0, y1, w, PALETTE[index], 160);
duskStrip(x + 2, y0 + 28, y1 - 12, w * 0.78, PALETTE[index], 134);
}
brush.noFill();
for (let i = 0; i < 52; i++) {
const x = constrain(randomGaussian((left + right) / 2, (right - left) * 0.35), left, right);
const y = constrain(randomGaussian(400, 140), top + 8, bottom - 40);
const len = constrain(randomGaussian(100, 38), 24, bottom - y);
const col = lerpColor(color(PALETTE[index]), color(PALETTE[0]), constrain(randomGaussian(0.25, 0.18), 0, 0.75));
brush.set(i % 5 === 0 ? "2B" : "cpencil", col, constrain(randomGaussian(1.5, 0.4), 0.7, 2.5));
brush.beginShape(0.25);
brush.vertex(x, y, 0.25);
brush.vertex(x + randomGaussian(0, 1.2), y + len * 0.45, 1);
brush.vertex(x + randomGaussian(0, 1.5), y + len, 0.2);
brush.endShape(false);
}
}
// Boundaries breathe instead of becoming four ruled columns.
duskStrip(308, 286, 608, 14, PALETTE[2], 100);
duskStrip(420, 208, 530, 10, PALETTE[3], 115);
duskStrip(560, 346, 620, 13, PALETTE[2], 86);
brush.noFill();
brush.set("cpencil", PALETTE[4], 2.3);
brush.beginShape(0.3);
brush.vertex(214, 338, 0.2);
brush.vertex(216, 412, 0.9);
brush.vertex(213, 482, 0.3);
brush.endShape(false);
}