Skip to content

Perfectly Hooked

A shop, a gallery and a custom-order page for a handmade crochet brand.

Role
Direction
Supplied by
The business supplied the photographs, names and copy.
Stack
Next.js, React, TypeScript, Tailwind CSS, GSAP, Three.js, WebGL, Supabase
Running locally
The Perfectly Hooked home page: a burgundy headline on speckled ivory beside photographs of crochet bags, with a yarn strand hanging between.
Fig. 01The home page on desktop.

01 / 08

The idea

A shop of 23 pieces, a gallery of 14 pictures and loops, and a page to ask for a custom order.

02 / 08

The problem

The business is someone else’s. The photographs, names and prices come from her original site and aren’t confirmed yet.

It isn’t launched: payments and custom requests are built but switched off.

One site had to do three jobs: sell the pieces, show the handmade work, and take a request for something made to order.

The business supplied the photographs, videos and wording, so nothing could be invented to fill a gap: availability wasn’t supplied, so pieces say “Ask about availability”, and delivery fees aren’t made up, so the bag says delivery is arranged after ordering.

Running locally
A product page for the Elara Duo Bag: a large photograph of a houndstooth crochet bag, its price in naira and an Add to bag button.
Fig. 02A product page.

03 / 08

The approach

Every effect borrows from crochet: pictures revealed by sweeping rows, a thread drawn down the page as you scroll, a menu worked like rows of stitches.

Running locally
The full-screen burgundy menu with the pointer on Atelier: a hand-drawn thread is pulled under the word and Shop, Custom orders and About are dimmed.
Fig. 03The menu, pointer on Atelier.

04 / 08

The decisions

Nothing is made up. A piece that isn’t on the business’s price list has no price and a descriptive name, and where an order or a request can’t be taken yet the site says so and offers WhatsApp instead of pretending.

A price is never trusted from the browser. The browser sends only what was ordered; the server looks the names and prices up again, and checks the payment provider’s signature before it believes a payment.

Custom requests are stored with Row Level Security on and no public access, with reference photos in a private bucket, and the form reports success only after the database confirms the save.

Motion respects the visitor. People with Reduce Motion on keep a calm fade-in, and a Full animations switch lets someone on a phone set to Reduce Motion turn the effects back on.

Cookies are a plain choice, not a wall: one slim line, two buttons, and a link in the footer to change it.

05 / 08

The design

Photography first. Square corners, an ivory page with a fine grain, burgundy as the only accent.

On desktop, one strand of yarn hangs down the hero.

Running locally
The shop page: a row of square category filters (All 23, Bags 10, Hats 3 and more) above an uneven grid of crochet bags.
Fig. 04The shop.
A close crop of the blue and pink houndstooth bag: tight stitches, a blue handle edge and a chain of pale pink and lilac beads.
Fig. 05Product photography, up close.

06 / 08

The build

Next.js, TypeScript and Tailwind, with GSAP for motion and Three.js for the yarn. The yarn loads only on wide screens with a mouse, so phones download no 3D code.

Touching an Atelier photograph turns it to water. Stitch your name crochets what you type.

Checkout never lets the browser set a price: the server works it out again.

Public pages are generated ahead of time and cached; only the checkout’s return page and the API routes run on demand.

Originals are kept untouched and the web versions are generated: photographs as AVIF or WebP with a blur preview, and videos as silent loops that load only near the screen and pause when off it.

The basics are built in: a skip link, visible focus, labelled forms with announced errors, and native dialogs for the bag, the menu and the picture viewer.

Framework
Next.js 16, React 19, TypeScript
Motion
GSAP, Three.js, WebGL
Backend
Supabase, Paystack
Source
Private repository
Running locally
Pointer moving over crochet photographs on the Atelier page; each picture bends in water-like ripples around it.
Fig. 06Photographs ripple under the pointer.
The Perfectly Hooked home page on a phone: the burgundy headline, a photograph of a crochet bag and a Shop the collection button.
Fig. 07Phone, first screen.
The full-screen burgundy menu on a phone: Shop, Atelier, Custom orders and About in large pale type, with a WhatsApp button below.
Fig. 08The menu on a phone.
Stitch your name on a phone: a text field holding VICTOR, six yarn swatches and a pink panel with VICTOR crocheted in hot pink stitches.
Fig. 09Stitch your name.

07 / 08

The details

Stitch your name crochets the word you type, row by row. Atelier photographs open in a lightbox.

Running locally
Typing VICTOR into the Stitch your name box, then a pink crochet VICTOR is worked stitch by stitch and row by row on the canvas.
Fig. 10A typed word crocheted in pink yarn.
The letters V, I and C of VICTOR drawn from rows of small hot pink V-shaped crochet stitches on a pale pink ground.
Fig. 11Letters built from V stitches.
A thin burgundy thread runs across the page, loops around the S of the heading Stitch your name and drops down the left margin.
Fig. 12The thread looping around the heading.

08 / 08

Current state

It works and is waiting on its owner. Not public yet: the pictures are captures of it running locally.

Its own notes record a check on the production build: the largest paint at about a second, no layout shift, and about 300 kB of JavaScript on the home page.

What is left is the business’s to confirm: the names and prices matched by look, availability and delivery, and the keys that switch payments and requests on.

Next project

Tara Designs

Victor Ohiri