UI engineering case study: everything below is live, drag the card

TimeCraft: designing
a board that moves.

A production Kanban SaaS I designed, built, and deployed solo. This page shows the interaction engineering behind its marketing surface: hand-rolled drag physics, an optimistic-UI simulation, and a cursor-reactive canvas background. No libraries, no video mockups.

Try the live demo
BACKLOG3
Rate-limit the sync endpoint
TC-139 · 3d ago
Dark mode for the board view
TC-127 · 5d ago
DOING1
Presence cursors on card hover
TC-131 · 1d ago
DONE1
Board keyboard shortcuts
TC-118 · synced ✓
feature
Ship the drag physics for hero card
TC-142 · nowsynced ✓
↑ pointer events + spring integration (rAF loop) · velocity-based tilt · nearest-column snap · simulated server ack · no drag library
EXPLAINING OPTIMISTIC UI

The card moves first. The server catches up.

This section demonstrates how I communicate a technical concept visually: the card commits to its new column in 0 ms while a simulated server ack lands a beat later. State machine: idle → moved → syncing → synced, with the delay exposed as a design token you can tweak.

DOING
DONE
Merge the sync retry patch
TC-140idle
0 mscard lands in DONE: your board, everyone's screen
450 msserver ack · synced ✓

Design decisions

motion

One hero moment, not scattered fades

All motion budget went to the draggable card, the product’s core verb. Scroll reveals appear only where they explain sequence. Reduced-motion is respected end to end.

background

A grid, not a gradient blob

The ambient layer is an isometric dot grid on canvas: cursor-lit, cached offscreen for one blit per frame. It quotes the board metaphor instead of decorating around it.

type & color

Purple system, mono metadata

Bricolage Grotesque for voice, Space Mono for card IDs and timestamps, the “craft/tooling” cue. One purple ramp on near-white; no invented accent colors.

Engineering under the hood

ordering

Fractional indexing

A card move writes one row, not a renumbered column: each card keys into a fraction string between its neighbours. The same scheme orders columns and tasks.

state

Optimistic UI + rollback

Every mutation snapshots the store, applies instantly, and reverts if the API call fails. The snapshot-and-revert cycle is unit-tested.

authz

Multi-tenant RBAC

Permissions are a typed union mapped to role sets, enforced at the API layer through a single authorize() gate, with no ad-hoc role checks in routes.

ai

AI task breakdown

A goal streams back from the Claude API over SSE, one subtask per line. Each line is validated with Zod before it ever reaches the board.

ship

Owned deploy path

GitHub Actions builds a multi-stage Docker image, pushes it to GHCR, and an EC2 box pulls it behind Caddy auto-HTTPS, tuned for a memory-constrained instance.

About this project

TimeCraft is a real product I built and operate end to end: concept, copy, visual system, every line of interaction code, and the production app behind it. Built with vanilla pointer events, canvas, and a requestAnimationFrame spring integrator. Concurrent state is what I work on daily.

TimeCraft

Noravut Chanthalay
Full-Stack Engineer · Next.js / React / TypeScript · Bangkok, Thailand
2.5 years production experience on an enterprise GRC platform, end-to-end from PostgreSQL schema design to deployment. Strongest on permission models, data modelling, and concurrent state.
interaction designmotion engineeringbrand & copycanvas rendering

Let's talk

Open to full-stack roles and interesting projects. The fastest way to reach me is email.

noravut.ch@gmail.com