All thoughts on
craft & code.
Essays on motion, frontend performance, and the 1% details that make interfaces feel premium.
@property: Typed CSS Variables That Actually Animate
Custom properties are strings — which is why animating them snaps instead of tweening. @property gives them types, and suddenly gradients, angles, and numbers interpolate.
gsap.to(...)
gl.drawArrays(...)
Scroll Snap: Storytelling in Full-Screen Chapters
Scroll snapping turns a page into chapters — carousels, onboarding flows, full-bleed stories — with pure CSS. And the discipline to know when not to.
Font Loading Without the Flash: A 2026 Strategy
FOUT, FOIT, and layout shift are all self-inflicted. Preload, font-display, and size-adjust fallbacks make web fonts effectively invisible to loading.
Dark Mode Done Properly: It Is Not a Filter
Inverting colors is not designing a dark theme. Elevation flips from shadows to lightness, saturation must drop, and pure black is a mistake. The real checklist.
gsap.to(...)
gl.drawArrays(...)
CSS Subgrid: The Alignment Problem Grid Could Not Solve Alone
Cards in a row with misaligned titles, prices, and buttons — the oldest grid frustration. Subgrid lets children align to their grandparent tracks. Solved.
Staggered Reveals: Choreography, Not Decoration
Twelve cards fading in at once reads as one blob. Stagger them 40ms apart and the eye follows a story. The rules of good stagger timing, in CSS.
Speculation Rules: Instant Navigation by Betting on the Next Click
The browser can now prerender the next page before the user clicks — entire navigations in 0ms. The Speculation Rules API, and how to bet without wasting bandwidth.
gsap.to(...)
gl.drawArrays(...)
OKLCH: The Color Space Your Design System Should Have
HSL lies: 50% lightness in yellow and blue are wildly different brightnesses. OKLCH makes lightness honest — and makes generated palettes finally look designed.
The Popover API: Tooltips and Menus Without the Library
Light dismiss, top-layer stacking, focus handling — everything you imported Floating UI for is now two HTML attributes. The Popover API in practice.
FLIP: The Technique Behind Every Smooth Layout Animation
You cannot animate layout without jank — unless you invert it. FLIP turns expensive layout changes into cheap transforms, and it powers every smooth reorder you have seen.
gsap.to(...)
gl.drawArrays(...)
content-visibility: The Biggest Rendering Win Nobody Ships
One CSS property that tells the browser to skip rendering offscreen sections entirely — often halving initial render time on long pages. Here is how to use it…
Fluid Type Scales: Stop Breakpointing Your Typography
Font sizes that jump at breakpoints are a relic. clamp() plus viewport units give typography that glides between devices — one line per text style.
Container Queries: Components That Own Their Responsiveness
Media queries ask how big the window is. Container queries ask how big MY box is — the question components actually needed. Sidebars stop breaking cards forever.
gsap.to(...)
gl.drawArrays(...)
linear() Easing: Real Springs in Pure CSS
cubic-bezier can only draw one hump — no bounce, no overshoot-and-settle. The linear() function ends that limit and brings true spring physics to CSS.
INP: The Metric That Finally Measures How Your Site Feels
Interaction to Next Paint punishes what users actually hate: taps that do nothing. Here is where INP debt hides and the patterns that pay it down.
CSS :has() — The Parent Selector Changes How You Architect Styles
For twenty years CSS could only look down the tree. :has() looks up, sideways, and forward — killing a whole class of state-tracking JavaScript.
gsap.to(...)
gl.drawArrays(...)
Optical Alignment: When the Math Is Wrong
Perfectly centered is often visibly off. Why play icons, quotation marks, and rounded shapes need optical correction — and how to train your eye to see it.
The View Transitions API: App-Like Navigation Without a SPA
The View Transitions API brings native-app page morphs to plain multi-page sites. Two lines of CSS, no router, no framework — here is how to ship it today.
Scroll animation
JS scroll listeners are a performance tax. How CSS scroll-driven animations replace them with three lines that run jank-free on the compositor.
gsap.to(...)
gl.drawArrays(...)
The 1% Rule : and why it matters
Design Feb 22, 2026 The 1% rule: obsessing over micro-interactions that matter Alex Shanley 3 min read We spend 99% of our time designing layout grids, selecting typography,…
Glass UI: and why you should
How clip-path and isolation stop backdrop-filter from bleeding through stacking contexts.
Why scroll-driven animations so good?
ScrollTrigger, native CSS scroll timelines, and viewport-relative units have changed everything about storytelling on the web.
Got a project in mind? Let's build it.
Or just want to talk shop about motion and frontend craft — say hello.