MilWebWhatsApp
Back to projects

Editorial premium fashion · WhatsApp checkout

RJjstore

Luxury editorial · WhatsApp checkoutPersonal project · demo
Screenshot do projeto RJjstore

Problem

Branded clothing stores sell via Instagram photos, without a storefront that feels like a fashion house and conveys desire and exclusivity.

Solution

Fashion e-commerce with a luxury-studio aesthetic: cinematic hero, horizontal-scroll lookbook, cursor-following dynamic lighting, product quick-view, persistent cart and orders closed straight on WhatsApp, with a switchable Sand and White theme.

How it was built

Next.js 14 (App Router) with zero heavy e-commerce dependencies: no third-party cart, no CMS, no external state manager. Just framer-motion, Lenis (smooth scroll) and next/font (Cormorant Garamond for editorial headings, Inter for the rest). The README documents its own performance budget: First Load JS ≈ 156 kB on the homepage, with every animation resolved in CSS and Framer Motion instead of a canvas or WebGL library. It's the right call for a project where the product is the photography, not a 3D effect.

The cart is a plain Context (CartProvider) holding { id, size, qty }[]. A line's identity key is the product and size pair, not just the product, so the same item in P and G becomes two independent lines. localStorage persistence uses a useRef as a hydration guard: the first useEffect reads storage and populates state, and only a second useEffect, gated on that ref, writes back. Without the guard, the write effect would fire on the very first render with an empty array and wipe the saved cart before it was ever read.

Size selection gates conversion. ProductDetail has an ensureSize() that blocks "Add to bag" and flashes an inline warning if nothing was picked, but the WhatsApp button is never disabled: with no size chosen it just builds the message with "to confirm" instead, so the lead isn't lost to friction. In the full cart, orderMessage() aggregates every line into one formatted text (product, brand, size, subtotal, bold-markdown total) and opens wa.me with encodeURIComponent. The entire conversion flow ends outside the app, with no backend and no payment gateway.

The "luxury editorial" look is built from coordinated motion layers, not a single effects library. LookbookScroll pins the section (position: sticky) and uses Framer Motion's useScroll and useTransform to map scroll progress into three independent transforms: the horizontal rail slides one way, the image inside each card counter-slides another way (scale-125 plus imgX), and the caption moves a third way, producing multilayer parallax with plain CSS transforms. Spotlight (a cursor-following light in soft-light blend mode) is built with useMotionValue and useSpring, and turns itself off via matchMedia('(hover: hover) and (pointer: fine)') and useReducedMotion. It's visual luxury that doesn't penalize mobile or accessibility. The theme toggle between Sand/Espresso and White avoids a wrong-theme flash with a blocking inline script in head that reads localStorage and applies data-theme before React hydrates. And the "neo-skeuomorphic" details (subtle swatch relief, solid-button depth) live isolated in a single token file (lib/theme.ts) so they don't leak into the rest of the UI, which is deliberately flat.

Per-variant cart

Composite id+size key in the Context, persisted to localStorage with an anti-overwrite hydration guard.

Frictionless WhatsApp

Size required for the cart, but the WhatsApp link never blocks: with no selection it falls back to "to confirm".

3-layer lookbook

Sticky scroll with useScroll/useTransform moving rail, image and caption in opposite directions.

No-flash theme

Blocking inline script applies data-theme from localStorage before React hydrates.

More screens

RJjstore editorial heroCatalog with category, brand and price filtersProduct page with color and size selection

Stack

  • Next.js
  • TypeScript
  • Tailwind
  • Framer Motion
  • Lenis

Ready to turn your idea into a digital product?

Tell me what you need. I reply fast and send a free quote, no strings attached.

  • Service contract
  • Post-launch support
  • You own the code
  • Free quote