All studies

2026-09 · Aesthetic · Figma · GitHub

Drawn gradients

How a soft gradient field gets made, and then what to do with it. Shapes drawn and blurred until they are one, or the same look written as a stop list — either way projected onto whatever geometry it is given. Shape and theme are separate axes, and everything else is a custom property.

Drawn, then blurred

Start here: this is where the colour comes from. Draw a few overlapping shapes in flat colour and blur them past recognition — the overlaps become the mid-tones a stop list has to be hand-tuned to produce. Each pair below is the same SVG: as drawn, then blurred. They are grouped by colour, three to a family — the theme is a separate axis from the drawing, so any of these shapes takes any of these colours.

Orange

Sunburst — radiating wedges

blur 0.16

Desert — dunes and a low sun

blur 0.18

One leaf, turned three times

transform="rotate(...)"

Blue

Quatrefoil, ribbon, star

--drawn / --raw

Pixels — a coarse mosaic

blur 0.1

Prism — crossed diagonals

blur 0.12

Mint

Ocean — stacked swells

blur 0.2

Crescent, teardrop, wedge

--drawn / --raw

Spots — a scattered field

blur 0.16

Night

Scanlines — analogue bands

blur 0.09

Ripples — concentric rings

blur 0.14

Nebula — drifting clouds

blur 0.24

  1. Draw big, blur hard. The blur is a ratio of the surface, not a fixed length, so a drawing dissolves by the same amount at any size. How much depends on the density: a few large shapes take ~0.26, while a mosaic, a scatter or stacked bands average to one flat colour at that setting and want 0.1 or less. Every pair above names its own.
  2. Bleed past the frame. Blur samples transparency beyond the artwork, so the drawing runs 22% outside the box and is clipped back. Fit it to the frame instead and every edge fades out — a vignette, not a fill.
  3. Overlap on purpose. Colour mixes where shapes cross, so nothing is fully opaque. Three shapes at 85% give more distinct mid-tones than a hand-written stop list usually carries.
  4. Reuse one path. The leaf pair in the orange band is a single curve rotated twice, and the prism in the blue band is one band angled two ways. Repeating one shape reads as a deliberate set, and the parts stay in proportion to each other for free.
  5. Know which one to ship. A large blur is a real compositing cost and it repaints on resize. For a static surface, match the look with the stop recipe every shape below uses; keep the drawn version for hero-scale or animated surfaces, where the extra structure earns it.

Shapes

With a field in hand, it gets projected onto geometry. One drawing and one theme are held constant here so geometry is the only variable — only border-radius and aspect-ratio change, and the artwork is re-projected to cover whatever it is poured into.

Tile

--tile

Circle

--circle

Arch

--arch

Pill

--pill

Themes

A theme sets three colour stops and nothing else, so it composes with any shape and either recipe. `--night` is the exception: it moves the base the colour settles to, and layers over any of them.

Five themes

--dawn --dusk --mint --ice --arc

Settling to ink

--night

Label

48

Placeholder line

Pools moved

--…-pool-x/y, --…-settle

Settle direction

default / --rise

Both recipes at once

--mix, --…-mix: 1 / 0.5 / 0

In use

Content sits in the lower half, where the recipe has settled to the base and nothing needs a scrim to stay legible. --step is the other way round: the surface goes inside a block of type, its steps landing on the same lines.

Card ground

--card

Label

48

Placeholder line

Long to short — the step walks left

--step --ice --night

Overlapping art
34%
Flat colour
61%
Wash
82%

Short to long — the step walks right

--step --arc --drawn

Wash
82%
Flat colour
61%
Overlapping art
34%

Long to short, drawn rather than stopped

--step --arc --drawn --down

Overlapping art
34%
Flat colour
61%
Wash
82%

Two blocks, one field — the upper settle flipped

--step --rise / --step

Overlapping art
34%
Flat colour
61%
Wash
82%
Wash
82%
Flat colour
61%
Overlapping art
34%

Section band

--band

A section header

Section band

Decisions

Type
Aesthetic

A gradient recipe and the surfaces that demonstrate it. Colour gathers at two off-centre pools near one edge and settles to the surface's own base at the other, so a shape reads as lit from a direction rather than as a two-colour blend — and the same recipe is re-projected onto every shape, so a tile, a circle, an arch, a pill and a full-width band all take the same light.

There are two ways to make that field and both are kept, because they are good at different things. The stop list is a hand-written set of radial and linear stops: cheap, static, exact. --drawn replaces it with two or three overlapping shapes in SVG blurred past recognition, which is how such a field is actually made — the overlaps supply mid-tones a stop list has to be tuned into producing, and a shape with points leaves soft spokes no arrangement of stops will give you. --mix puts both on one surface and cross-fades between them.

--step is the odd one in the set and the reason the recipe has to be re-projectable: a block of bands, one per line of type, each starting where its own label ends, so the ragged end of the copy is the staircase and the field runs across all three bands as one shape.

  1. The gradient is drawn, then blurred.

    --drawn swaps the stop list for an SVG of two or three overlapping shapes blurred past recognition. The overlaps supply the mid-tones a stop list has to be hand-tuned to produce, and shapes with points — a star, a leaf — leave soft spokes that no arrangement of radial stops will give you. Two things make it work: the blur is a ratio of the surface rather than a fixed length, so it dissolves by the same amount at any size — and the ratio is per drawing, since a dense one (a mosaic, a scatter, stacked bands) averages to a single flat colour at the 0.26 a few large shapes want, and needs 0.1 or less; and the artwork bleeds 22% past the frame before being clipped, because blur samples the transparency outside the drawing and a fitted drawing fades to a vignette at every edge. --raw shows the same drawing before the blur, which is the useful half when building a new one. It carries no construction outline: at half fill-opacity the shapes already read from their own edges, and a stroke around each one fences off the overlaps — the part of the drawing actually worth seeing. --…-raw-stroke puts an outline back for anyone who wants one. On --night a drawing also has to cover the frame. Where the artwork leaves a gap the base shows through, and that gap reads as a highlight on paper but as a hole on ink — a mosaic with empty cells and crossed bands with open diamonds both blur to a blotchy field there, so they stay on the light themes and the night set is drawn edge to edge.

  2. The two recipes can be cross-faded, not only swapped.

    --drawn drops the stop list — background-image: none — because there the drawing is the surface, and that makes the swap a cut: nothing is underneath to fade into. --mix keeps both on one surface, the drawing over the stops, and --…-mix is its opacity: 1 is the drawn surface, 0 is the stopped one, and the middle is a genuine double exposure. It is the only part of the recipe besides the base that interpolates, which is what lets a state be eased through rather than cut to — the index card rests at 1 and dissolves to 0 when it is looked at. The curve is symmetric on purpose: a quint ease-out looks right on a single element and is the wrong shape for a cross-fade, down to 0.28 a fifth of the way in and then three fifths of the duration spent between 0.09 and 0, which reads as a cut followed by nothing. cubic-bezier(0.65, 0, 0.35, 1) over 520ms keeps the change in the middle, where both images are on screen together and the double exposure is the whole effect.

  3. Two radial pools over a vertical settle, never a single linear ramp.

    Colour gathers at two off-centre origins near the top edge and dissolves outward; a linear-gradient underneath carries the last of it down to the base. One linear ramp corner-to-corner is what makes cheap gradients band — the eye finds the axis. With the pools offset from each other there is no axis to find, and the falloff stays smooth at any size.

  4. It settles to the surface colour, not to a second hue.

    The bottom ~40% is plain #fff. That is what makes the shape read as lit from one corner rather than as a two-colour blend, and it is why body copy can sit on the lower half without a scrim.

  5. Saturation drops faster than lightness.

    The hot stop is the only saturated colour; the wash stop is already half-way to the base. Fading a gradient by lightness alone leaves a muddy middle — dropping saturation first keeps the mid-tones clean.

  6. One recipe, re-projected per shape.

    --drawn-gradients-art is declared once and every surface uses it; the shape modifiers change only border-radius and aspect-ratio. The pools are positioned in percentages, so a circle, a pill and a full-width band each get the same light from the same relative direction rather than needing their own gradient.

  7. Content type is a ratio of the surface, like the radius.

    The figure, label and micro line are calc()s of --…-size, not fixed rem. Set in rem they stayed put while the card scaled, so a card shown small kept full-size type and the label ran outside its own box. The ratios resolve to the original values at the default size; only the legend that names a set keeps a fixed size, because it sits beside the surfaces rather than on them.

Inspiration
two supplied screenshots, kept as ref.png and ref2.png — a weather widget for the two pools and the settle, a stepped block for --step's interlock.

notes.md — the full record, including what was tried and dropped