Skip to content
Adam Braun The Thing Wearing Adam Braun

Lab · Experiment

Micro-interactions

A specimen board of hover effects. Each card holds one live specimen and a note naming the technique that powers it — the tag says whether it's CSS alone or CSS with a small script. Every effect fires on keyboard focus too, and all of them stand down under reduced motion.

01

Underline slide

CSS source ↗

How A linear-gradient background sized 0% → 100% wide does the drawing. The trick is in background-position: it snaps (never transitions) between right and left at the extremes, so the line grows in from the left and exits to the right — a through-line, not a retreat.

02

Highlight swipe

CSS source ↗

How Same gradient-as-background trick, but the height animates: background-size goes from a 0.12em underline to 100%, swelling into a highlighter block. color transitions in sync so the text flips to the page background and keeps its contrast.

03

Gradient sweep

CSS source ↗

How background-clip: text over a transparent color makes the text itself the window. The gradient behind it is 220% wide — accent on the left half, ink on the right — and hover slides background-position so the seam sweeps through the letters.

04

Lightsaber

CSS source ↗

How Two stacked pseudo-elements: a 2px near-white core and a blurred accent glow beneath it, both scaleX() from transform-origin: left — the hilt. The easing curve's y-value exceeds 1, so the blade overshoots the tip and settles. Mouse-out retracts it into the hilt.

05

Sine wave

CSS source ↗

How The underline is an accent-colored strip masked by a repeating SVG sine path (a data URI — masking instead of a background image means it themes with the site). At rest it's compressed flat with scaleY(0.22); hover eases the amplitude up and a keyframe scrolls mask-position one period per loop, so the wave swims.

06

Letter lift

CSS source ↗

How The label is split into per-letter spans at build time — Astro does the splitting, so no JavaScript ships. Each span carries its index as a custom property, and transition-delay: calc(var(--i) * 28ms) does the cascade. The intact text lives in aria-label; the spans are hidden from assistive tech.

07

Scramble

CSS + JS source ↗
Decode transmission

How A small script swaps characters from a glyph set on a requestAnimationFrame loop, locking correct characters left-to-right over 700ms. Monospace, so the width can't jitter while glyphs churn. Under reduced motion the text settles instantly.

08

Iris

CSS + JS source ↗
Peek through

How A duplicate, inverted copy of the link sits on top, clipped by clip-path: circle(var(--r) at var(--x) var(--y)). pointermove writes the coordinates (rAF-throttled); one transition on clip-path both blooms the radius and smooths the follow into a slight trail. Keyboard focus opens a centered iris; reduced motion disables the layer entirely.

Buttons

09

Vertical roll

CSS source ↗

How Two stacked copies of the label in an overflow: hidden button — the second sits absolutely at +100%, so the button stays one label tall. Hover translates the track up its own height and the copy rolls in from below. Under reduced motion the roll becomes a color swap.

10

Proximity magnet

CSS + JS source ↗

How pointermove measures cursor→center distance (rAF-throttled); inside the dashed 120px ring the button translates toward the cursor, pull strength ramping from 0 at the ring to 1 at the center, clamped to 44px. The spring is just a retargeted transform transition — it lags the cursor on approach and eases the button home on exit. Pointer-fine only; off under reduced motion.

Lighthouse

updated