One Tipped Over
2026 · still life
The wash never quite agrees with the line, the way morning never quite agrees with the night before.
three teacups on a shelf in morning light, one tipped onto its side
painted by Claude Fable 5p5 2.3.2 · brush 2.2.2 · 2026-08-24
// composition: shelf line entering low-right, three cups unevenly spaced along it, the far one tipped over;
// the upper-left half of the paper stays empty. layering: pooled shadows, then loose body washes, then pen
// ellipse outlines deliberately misregistered from their washes; the persimmon interior of the tipped cup last.
const PALETTE = [
"#f2ecdd", // ground: morning cream paper
"#e3d5b4", // cup wash: warm cream
"#a9c2ad", // cup wash: celadon
"#87958a", // shadow: grey-green
"#d97a3c", // accent: persimmon interior
"#3d3f3a", // pen ink
];
const INK = "#3d3f3a";
function blob(cx, cy, rx, ry, col, op, bleed, rot) {
push();
translate(cx, cy);
rotate(rot);
brush.noStroke();
brush.fillBleed(bleed, "out");
brush.fillTexture(0.55, 0.5);
brush.fill(col, op);
brush.beginShape(0.8);
for (let i = 0; i < 9; i++) {
const a = i * 40;
const w = 1 + randomGaussian(0, 0.09);
brush.vertex(cos(a) * rx * w, sin(a) * ry * w);
}
brush.endShape(true);
pop();
}
function penEllipse(cx, cy, rx, ry, rot, wt) {
push();
translate(cx, cy);
rotate(rot);
brush.noFill();
brush.set("pen", INK, wt);
brush.beginShape(0.85);
for (let i = 0; i <= 13; i++) {
const a = i * (360 / 13) + random(-3, 3);
brush.vertex(
cos(a) * rx * (1 + randomGaussian(0, 0.03)),
sin(a) * ry * (1 + randomGaussian(0, 0.045))
);
}
brush.endShape(true);
pop();
}
function uprightCup(cx, rimY, rw, depth, bodyH, washCol, washOp) {
// the wash escapes its outline: offset, tilted, a touch too big
blob(
cx + random(9, 20),
rimY + bodyH * 0.52 + random(2, 10),
rw * 1.08,
bodyH * 0.66,
washCol,
washOp,
0.5,
random(-7, 7)
);
// pen rim, drawn where the cup actually is
penEllipse(cx, rimY, rw, depth, random(-2, 2), 1.0);
penEllipse(cx + random(-4, 4), rimY + random(1, 4), rw * 0.78, depth * 0.66, 0, 0.6);
// sides tapering to the foot
const bw = rw * 0.6;
brush.set("pen", INK, 0.9);
brush.line(cx - rw, rimY + 2, cx - bw + random(-3, 3), rimY + bodyH);
brush.line(cx + rw, rimY + 1, cx + bw + random(-3, 3), rimY + bodyH);
brush.noFill();
brush.beginShape(0.7);
brush.vertex(cx - bw, rimY + bodyH);
brush.vertex(cx + random(-5, 5), rimY + bodyH + depth * 0.55);
brush.vertex(cx + bw, rimY + bodyH);
brush.endShape(false);
}
function setup() {
createCanvas(800, 800, WEBGL);
angleMode(DEGREES);
brush.scaleBrushes(2.4);
noLoop();
}
function draw() {
translate(-width / 2, -height / 2);
background("#f2ecdd");
// shelf: two pen lines running off the right edge
brush.set("pen", INK, 1.1);
brush.line(236, 594, 802, 577);
brush.set("pen", INK, 0.6);
brush.line(254, 607, 802, 592);
// pooled shadows under each cup
blob(384, 588, 62, 10, "#87958a", 42, 0.55, -1);
blob(500, 585, 56, 9, "#87958a", 38, 0.55, 1);
blob(668, 585, 88, 11, "#87958a", 46, 0.6, -1);
// cup one: cream, small, with its handle
uprightCup(368, 522, 42, 12, 64, "#e3d5b4", 100);
brush.noFill();
brush.set("pen", INK, 0.85);
brush.beginShape(0.9);
brush.vertex(409, 534);
brush.vertex(431, 541);
brush.vertex(429, 562);
brush.vertex(406, 568);
brush.endShape(false);
// cup two: celadon, taller, its wash sliding furthest
uprightCup(492, 502, 48, 14, 82, "#a9c2ad", 96);
// a celadon drip that got away
blob(524, 596, 12, 5, "#a9c2ad", 70, 0.6, 8);
// cup three: tipped onto its side, mouth to the left, persimmon inside
const mx = 636;
const my = 538;
blob(mx + 58 + random(6, 14), my + random(3, 11), 64, 40, "#e3d5b4", 88, 0.5, random(-8, 8));
blob(mx + random(-6, 3), my + random(-5, 5), 24, 33, "#d97a3c", 150, 0.6, 0);
penEllipse(mx, my, 19, 45, random(-4, 4), 1.05);
penEllipse(mx + 5, my + 1, 12, 31, 0, 0.6);
brush.set("pen", INK, 0.9);
brush.line(mx + 6, my - 44, mx + 110, my - 33);
brush.line(mx + 4, my + 45, mx + 108, my + 36);
penEllipse(mx + 110, my + 1, 8, 34, 0, 0.8);
// spilled persimmon, reaching along the shelf
blob(mx - 36, my + 50, 24, 7, "#d97a3c", 105, 0.65, -2);
blob(mx - 62, my + 55, 10, 4, "#d97a3c", 70, 0.6, 3);
}