zsty.us

Before / After · Case Study

Velcro Records — a label homepage that finally feels alive

Their record-label site was one giant hand-edited page, with the signature chain-and-skull pendant swinging as a flat picture on a hard repeating loop. Now the pendant hangs and swings like a real object through drifting fog — with a proper product catalog, fan sign-ups, and real security built underneath.

“A label should feel alive the second you land on it. This one swings.”
🔒velcro.music
jackiej.events — modern site

At a glance

What this rebuild covers.

  • Design

    The chain-and-skull pendant now swings on real simulated physics — it never repeats the same arc twice, and the skull's diamond eyes glint exactly at the top of each swing.

  • Theme & color

    Kept the label's black-stage look but gave it atmosphere: a San Francisco fog band drifts behind the chain, with the VELCRO and RECORDS wordmarks appearing out of the haze and dissolving back into it.

  • Selling & payments

    All 21 products live in one checked catalog that feeds the product pages, the cart, and search listings from a single source of truth — a bad entry gets caught before the site ever publishes.

  • Customer notifications

    Fans can opt in three separate ways — browser alerts, email, or text — and every sign-up records proof of consent, including the exact wording they agreed to.

  • Security

    The old site shipped with zero browser security protections; the new one ships with seven, locked on for every visitor.

  • Speed

    All that motion runs at a smooth 60 frames a second on desktops and phones alike — and every effect politely switches itself off for visitors who prefer reduced motion.

The motion diff

Press play on both. That’s the whole pitch.

Left: the legacy hero — one flat image of the chain rotating on a fixed CSS keyframe, on a plain black stage. Right: the rebuild — the pendant swings on a real verlet pendulum (held forever by an energy thermostat, never a hard loop), a volumetric SF-fog band drifts behind it with the VELCRO wordmark surfacing out of the haze, and the skull’s diamond eyes glint at each swing apex. Runs live in the browser at 60fps — the production page ships no video at all.

🔒velcrowrecords.com
Before
velcrowrecords.com — one image, fixed CSS-keyframe swing
🔒velcro.music
After
velcro.music — verlet pendulum + SF-fog + diamond-eye glints

Receipts — measured

Numbers that moved.

0
Security headers (CSP, HSTS, …)
was 0
1
Single HTML file → typed App Router files
was 1
0
Products modeled as validated records
was 0
  • 1 hand-edited page → a real site
  • 21 products properly cataloged
  • 0 → 7 security protections
  • Canned loop → real-physics swing

The four beats

Problem · Insight · Build · Outcome.

Scroll past the legacy frame. The four beats land in order. At the end, the modern site fades into the same window.

🔒velcrowrecords.com
Legacy
01 · Problem

A 2,338-line single HTML file doing everything

Legacy velcrowrecords.com crammed head meta, CSS, product data, modal logic, the newsletter, video, Snipcart config, and JSON-LD into one Netlify-hosted file. The signature pendant swing was a fixed CSS keyframe rotating one flat image — clean, but it never felt alive, and nothing in it was type-safe or reusable.

02 · Insight

A label sells a feeling — the hero should breathe

The swing is the brand. Real pendulum physics with no hard loop, fog rolling through the wordmark, glints firing at the apex — small touches that make a 30-second visit feel intentional. And the chain itself could be more than a rotating rectangle.

03 · Build

Next.js 16, physics on canvas, a real data layer

Split-architecture rebuild on Next.js 16 + Vercel: a verlet-pendulum hero held by an energy thermostat, a layered SF-fog band, and an optional per-link articulated-chain engine reconstructed from the single product photo (pixel-exact at rest). Behind it, a Zod-validated catalog, consent-first notifications, and a CSP + security-header set the legacy file never had.

04 · Outcome

Live on velcro.music — and it swings

The public hero swings on real physics through drifting fog with glints on the beat, the storefront and notification plumbing sit ready behind it, and the whole thing ships from a typed, split codebase instead of one hand-edited file.

🔒velcro.music
Modern
For the technically curiousHow it was done
  1. 01

    Where it started

    velcrowrecords.com was a single 2,338-line HTML file hosted on Netlify. Page metadata, styles, product data, modal logic, the newsletter, video embeds, the Snipcart cart configuration, and structured data all lived inline in that one file. The brand's signature pendant swing was one flat image rotating on a fixed 4-second CSS loop.

  2. 02

    What was wrong

    Nothing was reusable, validated, or protected. Editing anything meant hand-editing a wall of markup where one typo could break the page. There were no security headers at all, and the hero — the whole feel of the brand — was a rigid animation that repeated identically forever and never read as a real hanging object.

  3. 03

    The rebuild

    Rebuilt from scratch as a typed, split-file application on our hosting platform. The hero became a real physics simulation: a pendulum pivoting at the clasp with an energy thermostat that keeps it swinging forever without ever decaying or hard-looping, a cast shadow that sweeps in sync, a layered fog band drifting behind the chain, and diamond-eye glints timed to fire at the apex of each swing rather than on a timer.

  4. 04

    The chain trick

    Beyond the shipped hero, an offline pipeline sliced the label's single product photo into per-link sprites along the traced chain strands plus a rigid medallion body, then drove them with a rope simulation so the chain articulates link by link with motion-coupled sheen and sparkle. At rest it recomposites the original photo pixel-exact, and it holds 60 frames a second on both large desktops and phones through capped resolution and adaptive quality tiers.

  5. 05

    What runs now

    velcro.music is live: every product is a schema-validated record checked at build time — one source of truth feeding the pages, the cart adapter, structured data, and AI-agent retrieval. Three independent notification channels (browser push, double-opt-in email, and text with STOP/HELP handling) record consent with a copy version, seven security headers ship on every response, and every animation has a reduced-motion fallback.

Architecture

Old stack
  • Single-file HTML
  • Netlify
  • Snipcart
  • CSS-keyframe swing
  • No type safety
↓
New stack
  • modern web framework
  • design system
  • edge hosting we operate
  • Verlet hero physics
  • input validation

What changed, with evidence

Design

A pendant that actually hangs there

The legacy swing was a fixed CSS keyframe — one rigid image rotating on a hard 4-second loop. Rebuilt as a JS verlet single-pendulum pivoting at the clasp, with an energy thermostat that holds the amplitude forever: it never decays to rest and never repeats exactly, so it reads as a real hanging chain. The drop-shadow and a background cast shadow sweep in sync, and the pendant takes a subtle parallax lean toward the cursor.

Before
One image, linear 4s CSS keyframe, ±8°.
After
Verlet pendulum — never decays, never a hard loop.
  • src/app/page.tsx — verlet integrator + per-frame energy thermostat (g≈0.0007, ±~8°)
  • Asset-separated layers: a static chain-top over the moving pendant so the top link sits over the bail (no shear)
  • prefers-reduced-motion → static hero, no JS swing
Design

SF-fog atmosphere + motion-synced diamond glints

A layered smoke band drifts behind the chain, with the VELCRO / RECORDS wordmarks materializing out of the haze and dissipating as they cross. The skull's two diamond eyes glint cyan at each swing apex — tied to the pendulum, not a fixed timer — so the sparkle fires exactly when the chain is at the top of its arc.

Before
Plain black stage, no atmosphere.
After
Volumetric fog + glints that fire on the swing.
  • SmokeBand: staggered drifting cloud/ring/word puffs with negative delays (globals.css)
  • velcroEyeGlint keyframes peak at the swing extremes (0 / 50 / 100%)
  • Every effect has a prefers-reduced-motion branch
Agent backbone

A per-link chain engine, reconstructed from one photo

Beyond the shipped hero, built a canvas engine (reachable at ?fx=rope) that slices the single product photo into per-link sprites along the traced chain strands plus a rigid medallion body, then drives them with a verlet rope and a kinematic pendulum so the chain articulates link-by-link with motion-coupled sheen and sparkle. The front necklace was isolated from the photo with a circle-fitted medallion rim and whole-link reconstruction where the second chain wove through it.

Before
The whole pendant was a single rotating image.
After
The front chain articulates per link; diamonds catch the swing.
  • scripts/build_rope_rig.py — offline sprite atlas + rig.json builder
  • Rest pose recomposites the source photo pixel-exact (0 px over threshold on black)
  • 60fps at 1440 and 390 via capped DPR + adaptive quality tiers
Retention

A real storefront + consent plumbing under the brand surface

Products are modeled as Zod-validated records — one source of truth for the UI, JSON-LD, the cart adapter, and AI-agent retrieval. Three independent notification channels (web push via VAPID, email with double-opt-in, SMS with STOP/HELP) record IP-hash consent with a copy version. Legal routes, robots, and sitemap ship from the same typed layer.

Before
Everything inlined in one HTML file; no validation, no headers.
After
Typed data layer, consent-first notifications, hardened headers.
  • src/data + Zod schemas — a malformed product fails the build, not runtime
  • src/lib/notifications — push / email / sms repositories + consent versioning
  • next.config.ts — CSP, HSTS, X-Frame-Options, COOP, and 3 more headers

← All rebuilds

Velcro Records — a label homepage that finally feels alive — zsty.us