← All work
AI Art · Brand Language · Typography · 2026

I taught the code to draw by hand,
then I taught it to tremble

A canvas illustration engine, no libraries and no build, drawing seven scenes that draw themselves. I did not generate an image from a prompt: I set the reference for the hand feel, the color ramp and the rules, and the agent wrote the engine.

Role Directing the system, art, writing the rules
Medium A canvas that paints itself in real time
Tech Canvas 2D, vanilla JS
Year 2026
brush primitives
scenes in the library
stamps between two points
libraries, zero build

An illustration that arrives finished looks like one

I wanted a mark that feels drawn, not produced. Every finished file holds the same instant in time on every load, and that is what gives it away. So instead of another file in a folder I wrote an engine: the scene is built in front of the eye, line after line.

Everything after that was built around one question: what turns a sequence of dots into a line somebody smeared.

Anatomy

What happens between two neighboring points

Every layer in the engine is a decision. The fastest way to see which one carries the feeling is to switch them off one by one.

2.5

The two marks on the track are the range the engine kept, 1.6 to 3.4. Below it you get geometry, above it you get a tremor.

Flip the switches: the exact same points, with the layers and without them.

I chose the hand before I chose the code

Before a single line of code I chose where the hand feel comes from: a painting clip of mine, where you watch a real brush touch canvas. One concrete reference decides more than ten adjectives.

That produced the rule: every stroke gets a hand profile of its own. How far it drifts, at what rate, under what pressure. One hand draws one line, and nobody draws the same line twice.

The proof

One scene, two hands, at the same time

Same points, same delays. The only difference: one side runs the hand profile, the other draws clean geometry.

GeometryHand

Click to redraw, with different hands.

Three ways to lay down pigment, not one more

Three primitives, and that is it: a smeared line, a spiral fill, and a wash surface. The rule above them is simple, every scene must combine lines and surfaces. Only lines stays a sketch, only surfaces loses the hand.

Smeared lineA soft dab dragged along a path, with dense stamps in between.
Spiral fillFrom the edge inward, turn after turn, like a hand filling a patch.
Wash surfaceWide translucent rows back and forth, until the area gets a body.

I pulled the blue out, and everything warmed up

The ramp was derived from my own canvases: deep plum, raspberry, orange, gold and cream. Every stroke gets a position on the ramp, and sometimes a journey across it, so color becomes a direction rather than a mix.

Once I tried anchoring the dark end in blue. Technically it worked. To the eye it came out cold, and blue left the brand that same day.

24.07.2026

Drag the handle: the exact same stroke, at any point on the ramp. Tap the swatch on the side to see why blue left the brand.

Seven scenes, each one drawing itself from scratch

Every scene is a list of strokes with a delay, a duration and a ramp position, which makes it readable like sheet music. The skeleton reads first, the detail follows, then the scene fades and draws itself again with new hands. The same scene, never the same drawing.

Click a scene to draw it again, with a different hand.

Seven scenes, and not one looks like anyone else's

The same engine with a different reference, a different ramp and different rules produces an entirely different language. This is not an effect you download from somewhere, it is one brand's signature.

Build a language like this for your brand →

The moment you touch it, the drawing changes hands

The hero is drawn with two hands, two tracks in parallel. Free painting opens only once it finishes, and from the first touch the cycle stops for good: the system tells the story to the end, then hands over the brush. Whatever you add stays.

Your brush

When the scene finishes, the brush moves on. Every mark you add stays.

A brush that tells no story, it only answers the hand

There is a second brush too, entirely different. The first one knows what it draws. The second knows nothing in advance, it only converts the motion of a hand into color: a bundle of bristles along the direction of travel, a thin shadow underneath, a thin band of light on top.

It is deliberately faint, because it decorates the emptiness instead of fighting the headline. This is the brush that lives in the PlaySoul hero, and from there it entered the language.

Move the mouse across the surface. On touch, slide across it.

Two brand rules born out of the drawing

The first: copy never describes what the scene shows. If a bridge is being stretched on screen, the words will not say bridge or cross. The moment both say the same thing, both get weaker.

The second was learned from a failure. In the PlaySoul hero the animation pulled the eye away from the headline. Since then every piece of motion is ranked against what has to be read first. Two focal points of motion in one screen is a bug, not richness.

Rule one

The banned words move with the scene

Cannot be written
grow, plant, roots, fruit, blossom
Can be written
stay, hold, what already works
Rule two

Motion serves the eye path

The thing that has to be read first

The default here is the failure. Flip the switch to see what it was doing to the headline.

The letters and the brush obey the same rules

A visual language that is beautifully drawn and thoughtlessly typeset breaks in the middle. The typographic decisions below were written together with the engine, not after it, and each one is defined once and then runs on its own across every page.

01 · The scale

Five steps, not one more

Every step is shown here in its real spec, exactly as it runs on this page. Sizes move with the width of the screen, weight and tracking stay fixed.

A language that draws itself 800 · clamp(30,5.2vw,60) · -.035em
What happens between two points 700 · clamp(22,3vw,34) · -.03em
A heading inside a card 700 · 19px · -.02em
Body text, the measure by which the readability of the whole page is judged. 400 · 16.5px · 1.85
Brand Language 700 · 10px · .18em · caps
02 · Discipline

Two weights per screen, not four

An extra weight feels at first like another tool of expression, and after three of them nobody can tell what matters. The same block, once with two weights and once with four.

The reference

I chose the hand before I chose the code

Before a single line of code I set where the hand feel comes from. One concrete reference decides more than ten adjectives, so everything was derived from a single painting clip and not from an abstract description.

Two weights on screen: 400 and 800
03 · The measure

A line is measured in characters, not pixels

The pixel count changes with every screen and every type size. What stays stable is the number of characters in a line, which is why every measure on this page is written in ch.

The hand is steady most of the way and drifts only in moments, and in the first eight percent of the stroke there is the tremble of the brush landing, exactly like the instant a brush touches a surface before it settles. The radius swells in the middle of the stroke and narrows at the ends, and pressure breathes instead of jumping.

50ch in range
04 · Widows and orphans

A single word at the end looks like a mistake

One of those is enough to lower the impression of an entire page. Headings get balanced line breaks, and body text gets treatment that prevents a lone word on the last line. The only fix that is forbidden is the manual one: a forced line break looks perfect at one width and falls apart at every other.

A visual language defined once in code, then running on its own everywhere

Three lines, four words on the last one.
05 · The meeting point

The brush width is measured from the letter

The illustration and the text have to feel like one family, so the brush width in the canvas below was not chosen by eye. The browser measures the stem width of the body font at body size, and the brush calibrates itself to it on load.

The scene is built in front of the eye, line after line.

Stem, Heebo 400measuring...
Brush radiusmeasuring...
Body size16.5px

An engine that draws all the time has to be cheap

An effect that drains a battery comes off the site within a week. These six decisions are what let this language live on real pages.

Zero librariesCanvas 2D and vanilla JS. No framework, no build, no dependency chain.
Brush spriteThe brush tip is baked once per hue and placed with drawImage, instead of a live gradient per dab.
DPR capped at 2Beyond that it is four times the pixels for a difference the eye does not catch.
A loop that stopsEvery canvas runs only while it is on screen, via IntersectionObserver.
A watchdog for rAFIf the browser freezes frames, the engine falls back to a timer and the drawing never stalls mid-stroke.
Reduced motionAnyone who asked for less motion gets the finished scene immediately, in one frame, with no loop.

The art is in directing the system

I did not generate an image from a prompt. I set where the hand feel comes from, which ramp is allowed, and what the copy is forbidden to do. The agent wrote the engine. Every decision that determined how this looks is mine.

And the smallest details carry all of it: the tremble in the first eight percent of a stroke, and a dab of light offset by less than a pixel. That is where an effect becomes a language.

Every brand deserves a mark you cannot download from a stock library

I build visual languages that live in code: the reference, the ramp, the rules, and the engine that runs them on every page. No template, and nothing you can download.