clay ← Back to site
Build guide · Site 11 of 25

Journaling that feels like play.

CLAY is one of 25 sites designed and built by Formwork to show off web design, motion and taste. Here's exactly how this squishy one came together — and how you can make the same thing.

The idea

The brief was one word: joy. CLAY is a fictional journaling app that "feels like play," so the whole site had to feel touchable — like a jar of soft toys you want to press with your thumb. That pointed straight at claymorphism: puffy, rounded, candy-coloured shapes that look moulded from clay, floating over warm cream.

The stack

The signature: clay from three shadows

There's no secret asset. A "clay" surface is just a bright pastel fill wearing three shadows at once: a soft outer drop shadow for weight, an inset light highlight in the top-left, and an inset dark press in the bottom-right. Together they read as a lump of clay lit from above.

.clay{
  background: var(--tone);
  box-shadow:
    16px 22px 40px -10px var(--sh),        /* outer soft drop  */
    inset 7px 9px 16px rgba(255,255,255,.72),  /* top-left light */
    inset -9px -13px 22px rgba(38,20,64,.14);  /* bottom-right press */
}

Stars and hearts can't be drawn with a box, so they're tiny inline SVGs that reuse the same logic: a base fill, two shared radial gradients for highlight and press, and a CSS drop-shadow() that hugs the outline. The "squish" on buttons and cards is the same shadow set, animated — hover lifts and inflates it, :active collapses it inward so the whole thing presses into the page.

The hero shapes go one step further: poke one and it springs. A click sets a negative "squish" value that an under-damped spring pulls back to rest each frame — compress, overshoot, settle. Feeding that scalar into a squash-and-stretch scale (wider when pressed, taller on the rebound) is what sells it as real clay:

// per frame: spring the squish back toward 0
const acc = -K * s.squish - C * s.squishV;
s.squishV += acc * dt;
s.squish  += s.squishV * dt;
// squash & stretch — volume-ish preserving
const sx = 1 - s.squish * 0.6;   // wider when compressed
const sy = 1 + s.squish * 0.9;   // flatter when compressed

Details that matter

Ship it on GitHub Pages

Everything here is static, so hosting is three commands:

git init -b main && git add -A && git commit -m "ship clay"
gh repo create formwork-clay --public --source=. --push
gh api --method POST /repos/OWNER/formwork-clay/pages \
  -f 'source[branch]=main' -f 'source[path]=/'

Use relative paths (./main.js, not /main.js) because project Pages live under /repo-name/. Drop in an empty .nojekyll file so every asset serves verbatim, and you're live.

That's the whole recipe: three shadows, a sine wave, two rounded fonts and static hosting. The other 24 sites each swap the central trick — shaders, kinetic type, particles — but the discipline stays the same: one idea, executed until it feels effortless.