three charcoal strokes on bare paper — an arc, a counter-stroke, a heavy accent — and a red seal
painted by DeepSeek V4p5 2.3.2 · brush 2.2.2 · 2026-08-24
// composition: exactly three charcoal gestures held in the lower-left diagonal half; the rest of the paper stays vast and bare
// layering: long rising arc (two passes + one grey echo) -> straighter counter-stroke crossing it -> short heavy accent low -> spray spatter at the crossing -> small red seal
const PALETTE = [
"#f4edda", // warm paper
"#1c1b1a", // ink black charcoal
"#8f887a", // grey echo stroke
"#b23a2c", // seal red
];
const ARC = [
[108, 758], [176, 694], [268, 592], [382, 470], [492, 362], [566, 296], [606, 262],
];
const COUNTER = [[142, 392], [268, 470], [398, 538], [520, 606], [604, 650]];
const ACCENT = [[196, 700], [262, 726], [302, 738]];
function gesture(pts, brushName, col, w, jx, jy, curvature) {
brush.set(brushName, col, w);
brush.beginShape(curvature);
for (const [x, y] of pts) {
brush.vertex(x + randomGaussian(0, jx), y + randomGaussian(0, jy));
}
brush.endShape(false);
}
function setup() {
createCanvas(800, 800, WEBGL);
angleMode(DEGREES);
brush.scaleBrushes(2.5);
noLoop();
}
function draw() {
translate(-width / 2, -height / 2);
background("#f4edda");
// gesture one — the long arc, loaded then dry: two passes
gesture(ARC, "charcoal", "#1c1b1a", 4.6, 2, 2, 0.55);
gesture(ARC, "charcoal", "#141312", 3.0, 3, 3, 0.55);
// its grey echo — offset, only the middle of the arc, the breath after the stroke
gesture(
ARC.slice(1, 6).map(([x, y]) => [x + 17, y + 12]),
"charcoal", "#8f887a", 2.4, 2.5, 2.5, 0.55
);
// gesture two — the straighter counter-stroke crossing the arc
gesture(COUNTER, "charcoal", "#1c1b1a", 3.8, 2, 2, 0.2);
gesture(COUNTER.slice(1, 4), "charcoal", "#141312", 2.4, 2.5, 2.5, 0.2);
// gesture three — short, heavy, low
gesture(ACCENT, "charcoal", "#141312", 7.0, 1.5, 1.5, 0.35);
gesture(ACCENT, "charcoal", "#1c1b1a", 4.6, 2, 2, 0.35);
// spatter at the crossing — where the two strokes fought
brush.set("spray", "#1c1b1a", 2.6);
for (let i = 0; i < 6; i++) {
const sx = 332 + randomGaussian(0, 26);
const sy = 508 + randomGaussian(0, 22);
brush.line(sx, sy, sx + random(14, 42), sy + random(-18, 14));
}
// flung ink flecks along the arc's direction of travel
brush.noStroke();
brush.fillBleed(0.15, "out");
brush.fillTexture(0.6, 0.7);
for (let i = 0; i < 13; i++) {
const t = randomGaussian(0, 1);
const fx = 338 + t * 44 + randomGaussian(0, 14);
const fy = 506 - t * 34 + randomGaussian(0, 12);
brush.fill("#1c1b1a", 185);
brush.circle(fx, fy, random(0.8, 2.6), true);
}
// the seal — one small red square, slightly tilted, breathing space around it
push();
translate(626, 700);
rotate(4);
brush.noStroke();
brush.fillBleed(0.2, "out");
brush.fillTexture(0.55, 0.65);
brush.fill("#b23a2c", 205);
brush.polygon([
[-15 + randomGaussian(0, 1.2), -15 + randomGaussian(0, 1.2)],
[15 + randomGaussian(0, 1.2), -14 + randomGaussian(0, 1.2)],
[14 + randomGaussian(0, 1.2), 15 + randomGaussian(0, 1.2)],
[-14 + randomGaussian(0, 1.2), 14 + randomGaussian(0, 1.2)],
]);
brush.fill("#b23a2c", 120);
brush.polygon([[-13, -12], [13, -13], [12, 13], [-12, 12]]);
pop();
}