C4
E-CommerceWeb ApplicationSquare IntegrationGo KartingMotorsportProduct CatalogueGame Design2025–2026

DS Racing Karts

Full e-commerce platform with 499+ go kart parts, Square payment integration, and a custom-built Canvas 2D racing mini-game.

DS Racing Karts logo
ClientDion Scott / DS Racing Karts
LocationLong Reef Crescent, Woodbine, NSW, Australia
TimelineApprox. 3–4 months (late 2025 – early 2026)
Budget$10k+
RoleSolo — design, development, deployment, backend migration, analytics setup, copywriting, SEO, error tracking
01

Overview

DS Racing Karts is a comprehensive e-commerce platform built for one of Sydney's most experienced kart specialists — Dion Scott, a racer and engineer with nearly 40 years in the sport. The client needed a complete digital storefront to sell go kart parts, showcase services, and represent the brand online. C4 Studios delivered a full-stack e-commerce solution featuring 499+ products migrated from Square's catalogue via a custom 4-stage data pipeline (CSV import → category deduplication → image migration via Square Catalog API → AI-powered description generation with Claude Haiku). The platform includes a custom-built 'DSR Grand Prix' slot-car racing mini-game (2,291 lines of hand-written Canvas 2D code), GSAP ScrollTrigger-powered 3D scroll animations throughout, a full admin dashboard with CRUD product management, Sentry error tracking across three runtimes, and comprehensive security hardening including HSTS, CSP, rate limiting, and HMAC-SHA256 webhook verification. This is the largest and most technically ambitious project in the C4 Studios portfolio.

02

Screenshots

03

What I Delivered

  • Complete e-commerce website — full design, development, and deployment
  • Square payment integration with PCI-compliant card tokenisation and server-side payment processing
  • 4-stage data migration pipeline — Square CSV → Supabase import (2-pass category/product) → category deduplication → image migration (Square Catalog API → Supabase Storage) → AI description generation
  • Product catalogue system with 499+ go kart parts synced from Square
  • Individual product pages with image gallery, SKUs, pricing, stock status indicators, breadcrumb navigation, and Product structured data schema
  • Shopping cart with add/remove/quantity management, GST calculation, and localStorage persistence
  • Custom checkout flow with Square Web Payments SDK, customer details, shipping address with Australian state dropdown
  • Order confirmation system with auto-incrementing DSR-XXXXX numbers and branded Resend confirmation emails
  • Category-based product filtering with hierarchical sidebar navigation (parent > child)
  • Product search with PostgreSQL trigram matching (pg_trgm), autocomplete overlay with Ctrl+K hotkey, and rich results
  • Product pagination (24 per page) with ellipsis and prev/next controls
  • Sort functionality (newest, price ascending/descending, name A-Z)
  • 7 detailed service pages — Kart Servicing, Engine Tuning, Chassis Setup, Engine Servicing, Race Preparation, Driver Coaching, Custom Racewear — each with included-items checklists and contextual enquiry CTAs
  • Custom "DSR Grand Prix" slot-car racing mini-game — 2,291 lines of hand-written Canvas 2D code with physics engine, AI opponent, 4 tracks, F1-style countdown, and mobile touch controls
  • GSAP ScrollTrigger-powered 3D scroll animations — history timeline, RPM tachometer, SVG race animation, 3D video container
  • RPM tachometer-style animated statistics counter (500+ Parts, 40 Years, 1000+ Karts) with redline rev-limiter bounce
  • Scroll-pinned SVG race animation — two detailed top-down karts with exhaust glow, kerbs, and finish-line flash
  • Founder biography page with professional photo, racing history narrative, and career highlights
  • Racing teams showcase with 9 team profiles (numbers 338, 43, 114, 5, 555, 272, 285, 22, 249) in modal carousel with swipe navigation
  • Results/achievements timeline (2024 ERC Podiums, 2023 Endurance Victories, 2021 SEK Wins)
  • "Know Your Chassis" educational content — Sprint, Endurance, and DSR Predator technical breakdowns
  • Sponsor showcase with 19+ brand logos in dual-direction infinite CSS scroll carousel
  • Contact form with dynamic subject prefills from service page CTAs, input validation, and HTML-escaped Resend email delivery
  • Newsletter subscription system ("Stay in the Fast Lane") — Supabase upsert + optional Mailchimp double opt-in sync
  • Cookie consent banner with Accept/Decline — localStorage persistence, GA4 conditionally loaded only on consent
  • Google Analytics 4 integration with cookie-consent-gated loading
  • Privacy Policy page (9 sections, Australian Privacy Principles compliant)
  • Terms & Conditions page (10 sections, e-commerce focused)
  • Custom racewear photo gallery with 12 product images in responsive grid with hover zoom
  • "Built for Performance" workshop showcase section with cut-corner image design
  • Responsive design (mobile + tablet + desktop) with mobile navigation overlay and body scroll lock
  • Full SEO setup — per-page metadata, dynamic OG/Twitter/Apple icon generation (Edge runtime), sitemap.xml with all product slugs, robots.txt, LocalBusiness + Product structured data schemas
  • AI-generated product descriptions — Claude Haiku 4.5 filled ~400 empty descriptions with dry-run mode and cost tracking
  • Full admin dashboard with product/order/customer counts, recent orders table, and colour-coded low stock alerts
  • Admin product editor — full CRUD for products including image upload/delete/set primary, variations, inventory, categories, SEO fields
  • Admin category management with hierarchical table (parent bold, child indented with └) and product counts
  • Admin customer list with search across name/email and pagination
  • Admin order management with status badges, customer join, and pagination
  • Supabase Auth with role-based admin access (admin/super_admin) and middleware redirect for unauthenticated requests
  • 12 custom hand-drawn SVG category icons — steering wheel, chain links, brake disc, axle, stub axle, ball bearing, helmet, chequered grid, fuel can, wrench, tie rod, car silhouette
  • Hero video section with autoplay detection, 12-second fallback timeout, and crossfade to cycling background images
  • 3D perspective video container with scroll-driven rotation, red radial glow, and scanline overlay
  • Sentry error tracking across client (10% traces, 100% error replays), server, and edge runtimes with global error boundary
  • Security hardening — HSTS (2-year max-age + preload), CSP, X-Frame-Options DENY, X-Content-Type-Options nosniff, Permissions-Policy, rate limiting on all public API routes, HMAC-SHA256 webhook verification
  • Square webhook handler for real-time order status updates (payment.updated → paid/cancelled)
  • Lenis smooth scrolling (1.2s duration, exponential easing, 2× touch multiplier)
  • PWA-ready web app manifest with standalone display mode and #e60012 theme colour
  • Appointment-only modal popup system for workshop address clicks
  • C4 Studios credit badge in header and footer with animated wordmark
  • All page content writing and copywriting
  • Loading skeleton states for shop page, product page, and admin products page
  • Custom 404 page with racing-themed CTAs
  • Search autocomplete overlay with keyboard navigation (↑/↓/Enter/Escape), Ctrl+K global hotkey, debounced API calls
04

Key Features

  • Full e-commerce platform with 499+ go kart parts, synced from Square's product catalogue via a 4-stage migration pipeline
  • Custom-built "DSR Grand Prix" slot-car racing mini-game — 2,291 lines of Canvas 2D code with curvature-based physics, 4-tier AI difficulty, 4 tracks including a "Campbelltown GP" local Easter egg, F1-style 5-light countdown with false start detection, persistent skid marks, and mobile touch controls
  • Square payment integration — client-side PCI-compliant card tokenisation via Web Payments SDK, server-side createPayment() with idempotency keys and BigInt AUD amounts
  • GSAP 3.14 + ScrollTrigger-powered 3D scroll animations — history timeline with SVG trunk growth, RPM tachometer with rev-limiter bounce, scroll-pinned SVG kart race, 3D perspective video container
  • Animated RPM tachometer stats counter — realistic SVG face (0–16,000 RPM), scroll-driven needle with sinusoidal rev-limiter oscillation at redline, gold-to-red arc gradient, 3 counter-up stat cards
  • Dynamic product catalogue with hierarchical category sidebar, stock filtering, sort (newest/price/name), 24-per-page pagination with ellipsis, and PostgreSQL trigram search
  • Product detail pages with multi-image gallery, SKU display, variation selection, sale pricing, stock status indicators, breadcrumb navigation, sanitised HTML descriptions, and Product structured data (AggregateOffer)
  • Shopping cart with React Context + localStorage persistence, quantity controls, line item management, GST (10%) calculation, and "Estimated Total" display
  • Custom checkout flow — Square Web Payments SDK dynamically loaded, card tokenise → server price validation against DB → Square payment → Supabase order with auto-increment DSR-XXXXX → inventory decrement → Resend branded confirmation email
  • 7-service showcase with expandable accordion cards, Lucide icon mapping, "What's Included" checklists (6 items each), and contextual "Enquire Now" CTAs that pre-fill the contact form subject
  • Founder biography section — Dion Scott profile with 3:4 aspect portrait, racing-red corner accent, blockquote narrative spanning 1989 to present, career credits including Fastrack Experiences V8 coaching
  • Racing teams grid — 9 teams (numbers 338, 43, 114, 5, 555, 272, 285, 22, 249) in full-screen modal carousel with decorative SVG patterns (CheckeredCorner, TireTrack, SpeedLines), keyboard/swipe/dot navigation
  • Results timeline — chronological achievement display (2024 ERC Podiums, 2023 Endurance Victories, 2021 SEK Wins) with red left-border accent and Orbitron digital year labels
  • "Know Your Chassis" educational content — technical breakdowns of Sprint (7 specifications), Endurance, and DSR Predator chassis types with specifications grid
  • Custom racewear gallery — 12 product photos in responsive 2/3/4-column grid with hover-zoom transform and gradient overlay
  • Sponsor showcase with 19+ partner logos in dual-direction infinite CSS scroll (35s linear, 3× duplication), gradient fade edges, and hover image-swap (700ms crossfade)
  • Newsletter subscription system ("Stay in the Fast Lane") — POST to /api/newsletter → Supabase upsert + optional Mailchimp REST API sync with double opt-in (status: "pending"), rate limited 5/15min
  • Cookie consent banner (custom, no external library) — Accept/Decline stored in localStorage as "dsr-cookie-consent", GA4 script tag conditionally rendered only when consent granted
  • Google Analytics 4 — loaded via next/script afterInteractive strategy, zero Google scripts until explicit cookie Accept
  • Contact form with dynamic subject pre-fills from service page CTAs (/contact?subject=Kart+Servicing), HTML-escaped output, Resend delivery to [email protected], rate limited 3/15min
  • Appointment-only modal system — triggered from Footer address click, "private residential property" warning, Contact Us / Got It action buttons, backdrop blur dismiss
  • "Shop by Category" homepage grid with custom SVG category icons linking to filtered shop views
  • Latest Products carousel on homepage — 8 newest products with live pricing from Supabase, priority image loading for first 4
  • History timeline section — 9 nodes with GSAP scroll-driven SVG trunk line growth, alternating left/right cards with fade-in/out on scroll, terminal dot with pulse animation, fullscreen image lightbox with Escape key dismiss
  • Mobile-responsive hamburger navigation with slide-down overlay, body scroll lock, and cart icon with product count badge
  • C4 Studios animated credit badge — GSAP wordmark animation in header and footer
  • Facebook social integration link
  • Email link integration ([email protected])
  • Supabase Storage for product image hosting with Next.js Image optimisation (AVIF/WebP, 30-day edge cache)
  • Admin dashboard — 5 parallel Supabase queries fetching product count, order count, customer count, recent 5 orders, and low stock items (≤3 quantity). Colour-coded stock thresholds (red ≤0, yellow ≤5, green >5)
  • Admin product editor — full CRUD: name, description (HTML), SKU, status (active/draft/archived), visibility (visible/hidden/unavailable), variation management (name/SKU/price/sale price/stock qty), image upload to Supabase Storage with set-primary/delete, category tag selection, SEO title/description fields
  • Supabase Auth with role-based access — email/password sign-in, admin_profiles table with admin/super_admin roles, middleware redirect for unauthenticated admin requests, API route-level auth checks
  • 4-stage data migration pipeline — (1) import-square-csv.js: 2-pass CSV import (Pass 1: categories with dedup, Pass 2: products/variations/inventory), (2) merge-categories.cjs: cleanup duplicate categories, (3) migrate-images.js: Square Catalog API download → Supabase Storage upload, (4) generate-descriptions.cjs: Claude Haiku for ~400 products with dry-run mode and backup JSON
  • Sentry error tracking — client (10% traces, 100% error replays), server, and edge runtimes; error.tsx captures exceptions via Sentry.captureException; global-error.tsx as root boundary fallback
  • Security hardening — HSTS max-age=63072000 (2 years) with includeSubDomains + preload, Content-Security-Policy with script/style/img/connect/frame source whitelisting, X-Frame-Options DENY, X-Content-Type-Options nosniff, Referrer-Policy strict-origin-when-cross-origin, Permissions-Policy camera=()/microphone=()/geolocation=()
  • Rate limiting on all public API routes — checkout (10 requests/5min), contact (3/15min), newsletter (5/15min) — in-memory Map with timestamp expiry
  • Square webhook handler — payment.updated events with fail-closed HMAC-SHA256 signature verification using crypto.timingSafeEqual, maps COMPLETED→paid / FAILED→pending / CANCELLED→cancelled
  • Lenis smooth scrolling wrapping entire application — duration 1.2s, easing function (1 - Math.pow(2, -10 * t)), touchMultiplier 2×, rAF loop with cleanup on unmount
  • PWA-ready manifest — standalone display, #e60012 theme_color, #0a0a0a background_color
  • Scroll-pinned SVG race animation — 300vh pin, two DetailedKart SVG components (body with shading, 4 wheels with tread, helmet with visor, number circle, animated exhaust glow), full track with grass/kerbs/asphalt/finish lines, Kart 1 surge at 75%, drift at 90%, finish flash at 98%
  • 12 custom hand-drawn SVG category icons — SteeringWheelIcon, ChainIcon, BrakeDiscIcon, AxleIcon, StubAxleIcon, BearingIcon, HelmetIcon, ChequeredIcon, FuelCanIcon, WrenchIcon, TieRodIcon, CarIcon — all built as React components with SVG path data
  • Hero video section — autoplay detection with canPlayThrough event, 12-second fallback timeout, crossfade to 4 cycling background images at 5-second intervals, DSR logo image, dual CTA buttons, animated scroll indicator with bounce
  • 3D perspective video container — IntersectionObserver auto-play/pause, scroll-driven transforms (rotateX 0→-8°→0°, rotateY sinusoidal ±3°, scale 0.92→1.03→0.97, translateY -20→0→-10px), perspective: 1200px, red radial glow with sinusoidal intensity, "racing monitor" frame with accent corners and scanline overlay
  • Dynamic SEO image generation — opengraph-image, twitter-image, icon (32×32 "DSR" in red), apple-icon (180×180) — all Edge runtime ImageResponse
  • Dynamic sitemap.xml — fetches all active products from Supabase, outputs static pages + all product slug URLs + category URLs
  • Search autocomplete overlay — Ctrl+K / Cmd+K global hotkey, 300ms debounced API calls, keyboard navigation (↑/↓/Enter/Escape), rich results with product images + category badges + prices, "No results" state
  • Loading skeleton states — animated pulse placeholders for shop page, product page, and admin products page matching actual layout structure
  • Product image gallery — thumbnail strip navigation, primary image display with Next.js Image optimization
  • LocalBusiness structured data on homepage, Product (AggregateOffer) structured data on product pages
05

Stack & Tooling

  • Next.js 14 (App Router)
  • React 18
  • TypeScript 5.7
  • Tailwind CSS 3.4
  • GSAP 3.14 + ScrollTrigger
  • @gsap/react 2.1
  • Lenis 1.3 (smooth scrolling)
  • Square SDK 38.0 (Payments API — server-side)
  • Square Web Payments SDK (client-side card tokenisation)
  • Supabase JS 2.47 + SSR 0.5 (Postgres, Auth, Storage)
  • PostgreSQL via Supabase (pg_trgm + uuid-ossp extensions)
  • Resend 6.11 (transactional email)
  • Sentry 10.49 (client, server, edge error tracking)
  • Google Analytics 4 (cookie-consent-gated)
  • Mailchimp REST API (newsletter sync, optional double opt-in)
  • Canvas 2D API (custom game engine — zero external libraries)
  • Lucide React 0.460 (icon library)
  • clsx 2.1 + tailwind-merge 2.6 (class utilities)
  • sanitize-html 2.17 (HTML sanitisation for product descriptions)
  • Anthropic Claude Haiku 4.5 (build-time product description generation)
  • csv-parse 5.6 (CSV processing for data migration)
  • dotenv 16.4 (environment variable management)
  • PostCSS 8.4 + Autoprefixer 10.4
  • Node.js 22+
  • Vercel (hosting)
06

Integrations & Backend

  • Square Payments API — server-side paymentsApi.createPayment() in /api/checkout with card tokenisation, idempotency UUID, BigInt AUD amounts, buyer email, location ID
  • Square Web Payments SDK — dynamically loaded client-side script, card.attach() to DOM ref, card.tokenize() for PCI-compliant card data, production/sandbox environment switching
  • Square Catalog API — used in scripts/migrate-images.js to fetch all ITEM + IMAGE catalog objects for downloading and re-uploading product photos to Supabase Storage
  • Square Webhooks — inbound payment.updated events at /api/webhooks/square, HMAC-SHA256 signature verification (notification URL + body hashed with webhook secret, timing-safe comparison), maps COMPLETED/FAILED/CANCELLED to Supabase order status
  • Supabase Postgres — 12 tables, 15+ indexes (GIN tsvector + trigram for search), 19 RLS policies, GENERATED ALWAYS stock_status column, auto-incrementing DSR-XXXXX order numbers via PostgreSQL sequence + trigger, decrement_inventory() SECURITY DEFINER function
  • Supabase Auth — email/password for admin panel, role-based access via admin_profiles table (admin/super_admin), middleware session refresh on every request, middleware redirect for unauthenticated admin requests
  • Supabase Storage — product-images bucket, file upload from admin panel, public URLs served through Next.js Image with AVIF/WebP optimization and 30-day edge cache
  • Resend — transactional email: (1) order confirmation emails with branded HTML template (racing red accents, item table, pricing breakdown), from [email protected]; (2) contact form submissions from [email protected] to [email protected] with reply-to sender
  • Google Analytics 4 — loaded via next/script afterInteractive only after cookie consent granted, measurement ID from NEXT_PUBLIC_GA_MEASUREMENT_ID env var, zero scripts loaded on decline
  • Mailchimp REST API — optional newsletter sync from /api/newsletter, extracts datacenter from API key, POST to /lists/{id}/members with status "pending" (double opt-in), graceful fallback if keys not configured
  • Anthropic Claude API — Haiku 4.5 used in scripts/generate-descriptions.cjs for build-time product description generation (~400 products), dry-run mode for testing, backup JSON export, cost tracking per request
  • Sentry — @sentry/nextjs 10.49, configured across client (10% tracesSampleRate, 0% session replays, 100% error replays), server (10% traces), and edge (10% traces) runtimes, source maps uploaded with hideSourceMaps: true
  • Facebook — social media link to @dsracingkarts page from footer and contact page
  • Next.js Image CDN — remote patterns for Supabase Storage (*.supabase.co) and Square S3 CDN, AVIF/WebP format support, 30-day minimumCacheTTL, custom deviceSizes and imageSizes
07

Performance / SEO / Accessibility

  • Next.js Image component used throughout with AVIF/WebP formats, custom deviceSizes (640–1920), and 30-day edge cache TTL
  • Google Fonts loaded with display: swap for FOUT prevention — Oswald (headings), Inter (body), Orbitron (digital/stats)
  • Game loaded via next/dynamic with ssr: false — zero SSR cost, code-split, lazy-loaded on demand from GameTeaser
  • Game state managed via useRef (not useState) in rAF loop to avoid React re-renders during gameplay
  • Scenery generation uses seeded random (sin hash) for deterministic caching across frames
  • Skid marks capped at 300 with batch purge of 50 to prevent memory accumulation
  • Product pagination (24/page) prevents loading all 499+ products at once
  • Loading skeleton states for shop, product, and admin pages to prevent CLS
  • Supabase queries use select with specific columns (no SELECT *) for minimal payload
  • Admin dashboard runs 5 parallel Supabase queries via Promise.all for fast dashboard load
  • CSS infinite scroll animations use will-change: transform for GPU acceleration
  • Lenis smooth scrolling with requestAnimationFrame loop and cleanup on unmount
  • Sentry configured with 10% trace sampling to minimise performance overhead
  • Sentry source maps hidden from users (hideSourceMaps: true)
  • IntersectionObserver for video auto-play/pause to avoid unnecessary media decoding
  • Dynamic imports for Square Web Payments SDK — only loaded on checkout page
  • Product images served through Next.js Image optimization pipeline: Supabase Storage → CDN → client with responsive srcset
08

Challenges & Constraints

  • Square catalogue migration — Building a 4-stage data pipeline to import 499+ products with categories, variations, pricing, inventory, and images from Square's CSV export format, handling escaped commas, "Name (SQUARE_ID)" notation, and "Parent > Child" category nesting
  • E-commerce architecture without a platform — Constructing a complete shop experience (browse, filter, search, cart, checkout, payment, order management) on Next.js + Supabase without Shopify/WooCommerce, requiring custom cart context, price validation, inventory management, and order tracking
  • Mini-game development in production — Designing and building a 2,291-line Canvas 2D racing game with physics, AI, and multiple tracks that runs smoothly alongside a content-heavy e-commerce site, using useRef patterns to avoid React re-render overhead in the animation loop
  • 3D scroll animation performance — Orchestrating multiple simultaneous GSAP ScrollTrigger instances (history timeline, tachometer, race animation, video container) on a homepage that also loads product images and embeds a game, requiring careful GPU acceleration and intersection-observer gating
  • Product image pipeline — Migrating hundreds of product images from Square's S3-hosted catalogue (via Catalog API) to Supabase Storage, then serving through Next.js Image with AVIF/WebP optimization and 30-day CDN caching
  • PCI-compliant payment flow — Implementing Square's client-side card tokenisation + server-side payment processing with idempotency keys, BigInt currency handling, fail-closed webhook verification (HMAC-SHA256 with timing-safe comparison), and graceful order status management on payment failure
  • AI description generation at scale — Using Claude Haiku to generate meaningful descriptions for ~400 products that had empty or minimal descriptions, with dry-run mode, backup JSON, cost tracking, and preservation of existing specification content
  • Security hardening across the stack — Implementing comprehensive security headers (HSTS, CSP, X-Frame-Options), rate limiting on all public API endpoints, HTML sanitisation for user-generated content, input sanitisation for search queries, and role-based admin access with middleware protection
09

What I'd Improve Next

  • Live inventory sync — Replace the current CSV-based import with Square's real-time inventory webhooks to keep stock levels automatically synchronised between Square POS and the website
  • Product reviews and ratings — Add a customer review system with star ratings, moderation queue, and review-driven sort/filter to build social proof and improve product page SEO with Review structured data
  • Related products and cross-selling — Implement "Customers also bought" and "You may also like" sections on product pages using category-based or purchase-history recommendations
  • Shipping calculator — Integrate a shipping rate API (Australia Post, Sendle) to provide real-time shipping quotes at checkout instead of the current "quoted separately" approach
  • Order tracking dashboard — Build a customer-facing order tracking page where buyers can check order status, view shipping updates, and access their order history without needing to contact support

Like what you see?

Every project starts with a conversation.

Start a Project