---
title: "Unboxing: A Headphone Store Whose Hero Is the Delivery"
description: "How I built a product page you open like a parcel: drag across the tape to slice it, the flaps open from the cut, and you pull the headphones up out of the tissue. A Codex box, the same box opened, and the headphones in three colours."
date: "2026-11-13"
type: "build"
tags: ["interaction", "css", "codex", "image generation", "ecommerce", "creative coding", "nextjs"]
output: "/lab/unbox"
---

The best moment of buying headphones is not the checkout, it is the box arriving. People film it. So this store starts with the box: it is sitting on the page, sealed, and you open it. [Open it at avivashishta.com/lab/unbox](/lab/unbox).

Drag across the tape and a cut follows your pointer. Cut most of it and the box jolts, the flaps open from the cut outwards, and there is tissue paper inside. Pull up and the headphones rise out of it. Then the spec sheet folds open beside them.

<div class="highlight"><p><strong>The short version:</strong> Codex makes a photo of a sealed box, then an edit of that photo with the box opened and full of tissue, so the two line up exactly. The headphones are a separate Codex product shot with two colour edits. The page stacks the two box photos and reveals the open one from the seam out; the headphones sit in a layer clipped at the box's front rim, so they can come up out of it.</p></div>

## Step 1: the box, sealed and open (Codex)

<div class="promptbox">
  <button class="copybtn" type="button" data-copy>Copy prompt</button>
  <div class="prompt">
<p>A plain kraft cardboard shipping box, closed and sealed with a strip of clear packing tape along the centre seam of the top, seen from a high three-quarter angle so the top and front are visible, centered on a pale warm grey seamless background (#EDEDEA), soft studio light, a soft shadow. No text, no logos, no labels, no stickers. Photoreal. Square 1:1, 1024x1024.</p>
  </div>
</div>

The open box is that photo, attached and edited, so it is the same box in the same place:

<div class="promptbox">
  <button class="copybtn" type="button" data-copy>Copy prompt</button>
  <div class="prompt">
<p>The attached image is a closed cardboard box. Show the SAME box opened: the tape cut, the four top flaps folded fully open and outward, and inside, crumpled white tissue paper filling the box up to the rim with a nest in the middle. Keep EVERYTHING else identical: the box's size, position and angle, the camera, the light and the pale grey background. No product inside. No text, no logos. Photoreal. Square 1:1, 1024x1024.</p>
  </div>
</div>

"No product inside" matters: the headphones are their own layer, so they can move.

```bash
bun scripts/prepare-unbox.mjs ./raw
```

## Step 2: slicing the tape

The tape's two ends were measured once on the photo. On the page, pressing near that line and dragging along it projects the pointer onto the line and remembers the furthest it has reached in each direction. The cut drawn is that stretch, so you can start anywhere and cut either way, and wobbling off the tape doesn't count.

```ts
const t = ((px - x0) * dx + (py - y0) * dy) / len2;               // how far along the tape
const off = Math.abs((px - x0) * dy - (py - y0) * dx) / Math.sqrt(len2); // how far off it
```

At 80% the box jolts and opens.

## Step 3: the flaps

The open photo sits exactly on the sealed one, clipped to nothing in the middle. Opening animates the clip out from the seam to the edges, so the flaps seem to part along your cut:

```css
.open { clip-path: inset(0 50% 0 50%); transition: clip-path .75s cubic-bezier(.7,0,.2,1); }
[data-step="open"] .open { clip-path: inset(0); }
```

## Step 4: out of the tissue

The headphones live in a layer clipped at the front rim of the open box, so whatever is below the rim is hidden, as if inside. Dragging up moves them up by how far you have dragged (with a little twist that straightens as they come out) and a shadow on the tissue fades in under them. Let go past halfway and they spring the rest of the way; once out, the clip comes off and they float. The spec sheet's cards fold down one after another.

## The small things

- **"Open it for me"** does each step with one click, for anyone in a hurry or on a keyboard.
- **Three colours** swap the product shot once it is out.
- **"Pack it again"** puts everything back, for the second time you want to open it.

## Build your own

<div class="promptbox">
  <button class="copybtn" type="button" data-copy>Copy prompt</button>
  <div class="prompt">
<p>Build an unboxing product page (React, CSS, no libraries). Assets: a cut-out photo of a sealed box, the same box opened full of tissue (lined up exactly), a cut-out product photo, the tape's two end points and the open box's front rim height as fractions. Stack the two box photos in a square stage. Over them draw the tape as a dashed SVG line; pressing near it and dragging along it extends a cut line between the lowest and highest points reached along the tape. At 80% cut, jolt the stage and animate the open photo's clip-path from inset(0 50% 0 50%) to inset(0) while the sealed photo fades.</p>
<p>Put the product in a layer clipped below the rim (clip-path inset with the bottom at the rim). Dragging up lifts it by the drag distance; past halfway on release it springs out, the clip is removed and it floats. Then show spec cards that fold down in turn, colour options, price, Add to bag and Pack it again. Add a button that does each step for you.</p>
  </div>
</div>
