SUMI
Build note

How the brush was built

SUMI is a one-brush studio: a blank sheet of washi and a cursor that behaves like a loaded ink brush. The single job of the page is to make you feel the ink respond to how fast you move — slow floods and bleeds, fast dry-drags and splits. Everything below is how that illusion is kept physically honest, and the three passes it took to settle.

01 The concept

A sheet of paper that is inert until you touch it — the Wave 4 premise, told through sumi-e, the East-Asian art of ink painting where a single stroke's character is set by the hand's speed, pressure, and moisture in the brush. Here your pointer is the brush. There is no pen size to pick and no toolbar; the only control is your own movement, and the studio reads it back to you and names each mark in the language of the craft.

Audience: anyone who has ever wanted to feel a brush without wetting one — plus designers curious how far a plain canvas can be pushed. Today's guide character is (boku · sumi), the word for the ink itself.

02 Palette

Argued from the materials on the desk: warm washi, cold-black pine-soot ink, a single cinnabar seal, and the muted brown of a wet ink-stone. The bright red is reserved for marks and lines — the seal, the practice frame — never for body text; small copy uses the darker stone-ink so it always clears contrast.

Washi paper
#F1EBDD
The sheet. Warm, fibrous, a touch of straw — never clinical white.
Sumi ink
#1B1714
Pine-soot black with a brown undertone. The ink and the studio's dark surround.
Seal red
#A6321F
Cinnabar. Kept for the hanko seal and the faint practice grid — marks, not text.
Stone-ink
#6E5A3C
The wet ink-stone's brown. Carries small labels and the soft bleed halo.

03 Type

Display · 表題
Your hand is the brush. 墨 潤 飛白 溜
Zen Old Mincho — a mincho (serif) face with true kanji coverage, so the guide character, the headings, and the stroke names are all set in one authentic hand. Its brush-derived serifs echo the marks you make.
Interface · 本文
Speed 640 px/s · Nib 12.4 px · Ink 72% — the instrument reads you back.
Karla — a grotesque with tabular figures, used for every label and live number so the readout stays steady and legible while the values race.

04 The signature — velocity is the ink

Each pointer move carries a timestamp. Distance over time gives an instantaneous speed in px/s, smoothed with an exponential moving average so a single jittery sample can't spike the stroke. That one number drives two mappings through a smoothstep between a slow reference (120 px/s) and a fast one (1500 px/s):

Width falls from ~30 px to ~5 px as you speed up, then scales again by how much ink is left in the brush. Wetness is the inverse — full when slow and loaded, near zero when fast or run dry.

The stroke is drawn as overlapping dabs between the last point and the current one. Every dab consults a coherent bristle profile generated when you press down: thirteen bristles, each with a lateral offset and a personal dryness threshold. A bristle only lays ink while wetness clears its threshold — so a wet stroke fires every bristle into a solid, haloed band, and a dry stroke fires only a few, leaving flying white (hihaku) streaks of bare paper. Because the profile is fixed for the stroke, those gaps run consistently along it, exactly as real bristles do.

Wet dabs also deposit a faint halo in the stone-ink brown, and a fraction of them register a slow-wicking bleed that keeps spreading for up to a second after the brush has gone — the ink you cannot rush. Ink is composited onto the paper with a multiply blend, so overlaps darken the way real wash soaks. Holding the button still runs poolTick: ink flows with nowhere to go, gathering into a spreading bead and reloading the brush (tamari). Every finished stroke is measured — mean width, mean wetness, mean speed — and named from a small lexicon of ink terms.

05 Iteration log

Pass 1 · Craft
  • Tuned the type scale and the readout grid so the four live numbers sit on a steady tabular rhythm; gave the instrument a two-by-two card so speed/width and load/wetness pair by cause and effect.
  • Balanced the palette against the LEARNINGS contrast note — pulled all body copy to stone-ink / warm greys and reserved seal-red strictly for the seal and the faint practice frame.
  • Rewrote copy to name things concretely (flying white, pooled, run dry) and cut every marketing verb.
Pass 2 · Depth
  • Enriched the signature: added the coherent bristle profile so dry strokes split into consistent flying-white streaks instead of a uniform thin line — the single biggest jump in realism.
  • Added the slow-wicking bleed that keeps spreading after the stroke, and a brush-tip ring that swells and shrinks under your cursor on hover, so you see the velocity→width map before you even press.
  • Second-read detail: cross the ink threshold that means you've "composed the character" and the studio stamps its seal (rakkan) in the corner.
Pass 3 · Hardening
  • 375 px layout: the rail collapses above the sheet, the paper holds a square aspect, and the brand tagline drops so the masthead never wraps.
  • Reduced-motion: the ambient wicking animation is disabled and marks deposit their halo instantly; the paper still paints, because the whole point is that you drive it.
  • DPR capped at 2, layers rebuilt on debounced resize, rAF paused on document.hidden, canvas guarded with a visible fallback if a context can't be had, and focus-visible rings on the sheet and controls.
Pass 4 · Monochrome ink
  • Adversarial QA caught the signature wet stroke rendering as an oil-slick: the bleed halo and pooling beads were drawn in stone-ink, and multiply pushed that low-blue pigment into saturated red/olive rings. Every ink deposit now uses one near-neutral ink token, so the nijimi ramps paper→grey→black with no hue shift — the only warmth left comes from the cream paper, as it should.
  • Killed a halftone dot mesh across the wet body. Two causes: the per-dab bristle comb left a periodic lattice, and stacking dozens of translucent radial gradients baked Chrome's ordered dither into a fixed ~2 px grid. The comb now dissolves as the stroke floods (it only splits into flying white as the brush dries), the wet body is one continuous filled ribbon, and the ink layer composites through a sub-pixel blur that averages the dither away and reads as ink wicking into fibre.
  • Contrast nit: the tiny px/s and % unit labels moved to a lighter ink token to clear 4.5:1 on the near-black instrument.
Headless verification · fast vs slow drag · ink colour
Slow drag (~150 px/s)  → mean nib 27.5 px · wetness 90%   wet · wide
Fast drag (~3000 px/s) → mean nib  4.9 px · wetness  4%   dry · split
Press & hold          → pooled bead · wetness 100%       tamari
Assertion → slow width > fast width, slow wet > fast wet, both deposit ink   PASS
Bleed halo sampled → R≈G≈B, mean saturation 0.10 · no colour ring · no dither grid   MONOCHROME
Console errors: 0 · page errors: 0 · 375px overflow: none

06 Techniques

Pure canvas 2D, no libraries. Three offscreen layers — a procedurally speckled paper, a faint guide (the character plus a cinnabar practice grid, drawn once fonts are ready), and a persistent ink layer — are composited each frame, with the ink multiplied onto the paper. Bristle dabs, radial-gradient bleed halos, the pooling bead, and the time-based wicking all write into the ink layer. The loop only recomposites when something changed and pauses when the tab is hidden, so a still hand means a still page — the Second Person promise.