Spirograph Explorer
The gear-and-pen toy from every 90s pencil case, rebuilt as three sliders and a parametric formula drawn live in canvas.
Design Technologist at Stripe. Building at the crossover between design and engineering.
The gear-and-pen toy from every 90s pencil case, rebuilt as three sliders and a parametric formula drawn live in canvas.
I lost a penguin race in Super Mario 64 before I understood the camera. That's the leap from painted-on depth to real 3D, and CSS makes it with six properties.
Pinning a menu or tooltip to a button used to mean JavaScript. CSS anchor positioning does it instead: tether with anchor(), place with position-area, size with anchor-size(), and let position-try flip it at an edge.
A grayscale photo plus two flat colors, blended in CSS, make a two-ink duotone. multiply takes the highlights, screen takes the shadows, and the pickers let you re-ink it live.
Staggering a list used to mean stamping --i:0, --i:1, --i:2 onto every child. sibling-index() gives you that number for free, so the animation-delay computes itself. No inline styles, no JavaScript.
Fluid scales, balanced headings, drop caps, optical sizing, hanging punctuation. The browser now ships most of a typesetter's toolkit in pure CSS, switched off by default until you ask for it.
Derive a whole component's states from one color token by pulling its channels out and doing math on them. Drag one hue, watch hover, active, border, and ring re-theme live.
You already drag these handles in the pen tool. cubic-bezier() is the same two handles, bending time instead of a shape. Once you see that, ease-in-out stops being a reflex.
Ink gain, shadow woodtype, metal type under a lamp. Letterpress printers solved these effects mechanically. SVG filter primitives solve them in the browser.
Five bits of school maths do almost all the work in motion: interpolation, easing curves, distance, the unit circle, and summation. Each one here is a draggable demo, reframed around what it actually animates.
A 90s sticky hand toy built with Verlet integration. Drag the handle or the hand: it sticks to walls, stretches slime threads when pulled off, and vibrates on impact.
I kept an old iMac alive for years just to run Freehand MX. Halftones, moirés, film separations.
sin(), cos(), atan2() landed in CSS in 2023. You can now place elements in circles, arcs, and spirals with pure CSS, no JavaScript, no libraries. Here's how the math works.
The first native API that draws real HTML into a canvas context. Not a screenshot, not a workaround. Documenting what I've tried, what surprised me, and why this one matters.
Register a custom property with a type and the browser can interpolate it. Without it, custom properties are untyped strings: transitions and keyframes have no effect on them.
font-variation-settings is a CSS property like any other, which means animation-timeline can drive font weight, tracking, and optical size directly from scroll position. No JavaScript.
A quick reference for the four easing curves in the motion token system, visualised side by side so the differences are immediately readable.
Interactive L, C, H sliders and a hue uniformity comparison: the parts of oklch that don't click until you can touch them.
Variable font axes are animatable CSS properties, which means animation-timeline can drive font weight, letter-spacing, and more directly from scroll position.
When AI tools make it faster to build outside the system than inside it, the problem isn't the tool. It's the system that isn't worth reaching for.
How browsers animate, why cubic-bezier is an approximation, and how linear() lets you use a real spring equation. No JS at runtime.
How far can you push linear() easing before you actually need Framer Motion? Generating spring curves from a physics equation, no JS at runtime.
How to build a motion token system that engineers actually use: primitives, semantics, enter/exit, and when CSS isn't enough.
Trying to reproduce Apple's liquid glass effect using only SVG filters. Documenting what works, what breaks, and why it's harder than it looks.
SVG from scratch, Lottie, dotLottie, CSS: a real comparison covering bundle size, customization, and the moment your designer gives you something none of the libraries support.
SVG is not an image format. It's a coordinate system, a styling surface, and an animation target, all in one. Here's what you actually need to know to use it well.
How @starting-style, transition-behavior: allow-discrete, and interpolate-size finally solve the animations JavaScript used to own: animating display: none and height: auto in pure CSS.
A practical guide to oklch for design systems: perceptually uniform color scales, color-mix(), wide gamut, and animatable color tokens. All without a library.
How to take an interactive Figma prototype (Smart Animate, component states, transitions) and ship it in React using dotLottie and Framer Motion. Based on a real project I designed and built.
A gyroscope experiment built at 11pm with no brief ended up in a production landing page. That's the whole argument.
SVG filters, feTurbulence, CSS noise, and math-driven layouts: how to use the browser as a generative design tool without any external libraries.
Easing curves, staggered animations, and choreography as a design tool: how to think about motion the way a designer thinks about type and space.
A deep dive into the new CSS scroll-driven animations API: how to use animation-timeline, scroll(), and view() to create scroll-linked effects with pure CSS.