610 Digital Labs
See what modern web development can actually do
Six live interactions, built the same way we build client sites. Flip any card to see the real code behind it.
Interactive demos
Pointer events + inertia
Draggable flick-card deck
Drag a card away and it flies off with real momentum, just like flicking a card off a deck.
function onPointerUp(dx, vx) {
const flung = Math.abs(dx) > 80 || Math.abs(vx) > 0.5;
if (!flung) return snapBack(front);
// fling in the direction it was dragged
const dir = dx > 0 ? 1 : -1;
front.style.transform =
`translate3d(${dir * 140}%, 10%, 0) rotate(${dir * 30}deg)`;
front.style.opacity = '0';
front.addEventListener('transitionend', () => {
recycleToBack(front); // move card behind the stack
}, { once: true });
}Cursor-tracked 3D transform
Magnetic tilt + glow button
The button tilts toward your cursor and a spotlight glow follows it, all with no library.
btn.addEventListener('mousemove', (e) => {
const rect = btn.getBoundingClientRect();
const px = (e.clientX - rect.left) / rect.width;
const py = (e.clientY - rect.top) / rect.height;
const rotateY = (px - 0.5) * 16;
const rotateX = (0.5 - py) * 16;
btn.style.transform =
`rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(1.04)`;
// spotlight follows the cursor via a CSS custom property
btn.style.setProperty('--mx', `${px * 100}%`);
btn.style.setProperty('--my', `${py * 100}%`);
});Native CSS scroll timelines
Scroll-driven parallax reveal
Scroll ↓
I move as you scroll
Content animates as you scroll past it, powered by the browser itself — no scroll listener required.
.card {
animation: reveal linear;
animation-timeline: scroll(nearest);
}
@keyframes reveal {
from { opacity: .4; transform: translateY(40px) scale(.9); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
/* runs entirely on the compositor —
no scroll event listener needed */Stroke-dasharray animation
SVG line-draw icon
Hover to redraw
An icon that looks hand-drawn, animating its own outline into view.
const length = path.getTotalLength();
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length; // fully hidden
// shared scroll observer adds .is-revealed —
// this component just listens for it
wrapper.classList.add('is-revealed');
// CSS transitions strokeDashoffset to 0 → "draws" itselfDOM particles + CSS keyframes
Clickable rating burst
A real, accessible star rating control that celebrates your click with a little sparkle burst.
/* classic pure-CSS star rating: reverse the DOM
order, then flex row-reverse to display it
left-to-right again */
.group { display: flex; flex-direction: row-reverse; }
input:checked ~ label,
input:checked ~ input ~ label {
color: var(--brand-secondary);
}
/* JS just listens for 'change' to spawn the sparkle burst */
input.addEventListener('change', () => spawnBurst(label));Keyboard-first UX
Command palette
Press ⌘K (or Ctrl+K) to open a fuzzy-search command palette, the same pattern power users expect from modern apps.
document.addEventListener('keydown', (e) => {
const isK = e.key.toLowerCase() === 'k';
if ((e.metaKey || e.ctrlKey) && isK) {
e.preventDefault();
dialog.showModal(); // free focus trap + Escape + backdrop
}
});
// substring match ranks above subsequence match
function score(query, label) {
if (label.includes(query)) return 2;
return isSubsequence(query, label) ? 1 : 0;
}Want this level of craft on your website?
Everything on this page is a preview of the engineering that goes into every 610 Digital build.
Schedule a Strategy Call