MILWEB®
MILWEB®
MW/030RJJSTOREESTUDIO

RJjstore

RJjstore — pantalla inicial
ESTUDIO
MILWEB
TIPO
PRODUCTO DIGITAL
ESTADO
EN LÍNEA

02 / LA IDEA

Moda premium editorial · checkout en WhatsApp

Las tiendas de ropa de marca venden por foto en Instagram, sin una vitrina con cara de casa de moda que transmita deseo y exclusividad.

03 / EXPERIENCIA
  1. 01 / 01

    Clave compuesta id+talla en el Context, persistida en localStorage con guarda de hidratación anti-sobrescritura.

    RJjstore — 01
  2. 02 / 02

    Talla obligatoria para el carrito, pero el link de WhatsApp nunca se traba: sin selección, agrega "a convenir".

    RJjstore — 02
  3. 03 / 03

    Scroll fijo con useScroll/useTransform moviendo riel, imagen y leyenda en direcciones opuestas.

    RJjstore — 03
  4. 04 / 04

    Script inline bloqueante aplica data-theme del localStorage antes de la hidratación de React.

    RJjstore — 04
Hero editorial de RJjstore

04 / BAJO EL CAPÓ

  • 01Next.js 14 (App Router) sin ninguna dependencia pesada de e-commerce: cero carrito de terceros, cero CMS, cero state manager externo. Solo f…+

    Next.js 14 (App Router) sin ninguna dependencia pesada de e-commerce: cero carrito de terceros, cero CMS, cero state manager externo. Solo framer-motion, Lenis (smooth scroll) y next/font (Cormorant Garamond para los títulos editoriales, Inter para el resto). El README documenta su propio presupuesto de rendimiento: First Load JS ≈ 156 kB en la home, con todas las animaciones resueltas en CSS y Framer Motion en vez de bibliotecas de canvas o WebGL. Es la decisión correcta para un proyecto donde el producto es la fotografía, no un efecto 3D.

  • 02El carrito es un Context puro (CartProvider) guardando { id, size, qty }[]. La clave de identidad de una línea es el par producto y talla, n…+

    El carrito es un Context puro (CartProvider) guardando { id, size, qty }[]. La clave de identidad de una línea es el par producto y talla, no solo el producto, así que la misma prenda en P y G se vuelve dos líneas independientes. La persistencia en localStorage usa un useRef como guarda de hidratación: el primer useEffect lee el storage y puebla el state, y solo un segundo useEffect, que revisa la ref, vuelve a escribir. Sin esa guarda, el efecto de escritura se dispararía en el primer render con array vacío y borraría el carrito guardado antes incluso de leerlo.

  • 03La talla es obligatoria antes de cualquier conversión. El ProductDetail mantiene un ensureSize() que bloquea el "Agregar a la bolsa" y encie…+

    La talla es obligatoria antes de cualquier conversión. El ProductDetail mantiene un ensureSize() que bloquea el "Agregar a la bolsa" y enciende un aviso inline si no se eligió nada, pero el botón de WhatsApp nunca queda deshabilitado: sin talla, arma el mensaje con "a convenir" en su lugar, para no perder el lead por fricción. En el carrito completo, orderMessage() agrega todas las líneas en un único texto formateado (producto, marca, talla, subtotal, total en negrita markdown de WhatsApp) y abre el wa.me con encodeURIComponent. Todo el flujo de conversión termina fuera de la app, sin backend y sin gateway de pago.

  • 04La estética "editorial de lujo" se construye en capas de motion coordinadas, no en una única lib de efectos. El LookbookScroll fija la secci…+

    La estética "editorial de lujo" se construye en capas de motion coordinadas, no en una única lib de efectos. El LookbookScroll fija la sección (position: sticky) y usa useScroll y useTransform de Framer Motion para mapear el progreso de scroll en tres transforms independientes: el riel horizontal se desliza en un sentido, la imagen dentro de cada card se contra-desliza en otro (scale-125 más imgX) y la leyenda se mueve en un tercero, creando parallax multicapa solo con CSS transforms. El Spotlight (luz que sigue el cursor en soft-light) está implementado con useMotionValue y useSpring, y se apaga solo vía matchMedia('(hover: hover) and (pointer: fine)') y useReducedMotion. Es lujo visual que no penaliza mobile ni accesibilidad. El toggle de tema entre Arena/Espresso y Blanco evita el flash de tema equivocado con un script inline y bloqueante en el head que lee el localStorage y aplica data-theme antes de la hidratación de React. Y los detalles "neo-esqueumórficos" (relieve sutil en los swatches de color, profundidad en el botón sólido) viven aislados en un único archivo de tokens (lib/theme.ts) para no filtrarse al resto de la UI, que es deliberadamente flat.

CONSTRUIDO CONNext.js · TypeScript · Tailwind · Framer Motion · LenisCÓDIGO

06 / RESULTADO

Editorial de lujo · checkout en WhatsApp

PROYECTO PROPIO · DEMO

[ QUIERO ALGO PARECIDO ]

07 / PANTALLAS SELECCIONADAS
Hero editorial de RJjstore
PANTALLA 01Hero editorial de RJjstore
Catálogo con filtros de categoría, marca y precio
PANTALLA 02Catálogo con filtros de categoría, marca y precio
Página de producto con selección de color y talla
PANTALLA 03Página de producto con selección de color y talla
SIGUIENTE EXPERIENCIA24 / RJS LATICÍNIOS

RJS Laticínios

RJS Laticínios

TODOS LOS PROYECTOS

TODOS LOS PROYECTOS