design changes
This commit is contained in:
398
src/app/page.tsx
398
src/app/page.tsx
@ -7,9 +7,9 @@ import Section from "@/components/Section";
|
||||
import Button from "@/components/Button";
|
||||
import BannerSlider from "@/components/BannerSlider";
|
||||
import Image from "next/image";
|
||||
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
|
||||
import { AnimatePresence } from "framer-motion";
|
||||
import { useInstagram } from "@/hooks/useInstagram";
|
||||
import { useState, useEffect, useRef, useCallback } from "react";
|
||||
import ProductCategory from "@/components/ProductCategory";
|
||||
import SocialMedia from "@/components/SocialMedia";
|
||||
|
||||
// Premium animation variants
|
||||
const fadeInUp = {
|
||||
@ -46,14 +46,6 @@ const categories = [
|
||||
"Dragees",
|
||||
"Gelatos",
|
||||
];
|
||||
const categoryImages = [
|
||||
"/categories/c1.svg",
|
||||
"/categories/c2.svg",
|
||||
"/categories/c3.svg",
|
||||
"/categories/c4.svg",
|
||||
"/categories/c5.svg",
|
||||
"/categories/c6.svg",
|
||||
];
|
||||
|
||||
const partnerImages = [
|
||||
"/partners/p1.svg",
|
||||
@ -127,14 +119,18 @@ export default function Home() {
|
||||
return () => clearInterval(timer);
|
||||
}, []);
|
||||
|
||||
const { posts, loading, error, isTokenExpired } = useInstagram();
|
||||
|
||||
// Memoize expensive components
|
||||
const BrandStorySection = useMemo(
|
||||
() => (
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white font-renner">
|
||||
<Header />
|
||||
<BannerSlider />
|
||||
|
||||
{/* Brand Story */}
|
||||
|
||||
<Section background="white" id="about">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 md:gap-12 lg:gap-16 items-center">
|
||||
{/* Left Column - Text */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 items-center">
|
||||
{/* Brand Story - Left Text */}
|
||||
<motion.div
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
@ -143,7 +139,7 @@ export default function Home() {
|
||||
className="space-y-6 md:space-y-8 order-2 lg:order-1 px-4 md:px-0" // ← Added mobile padding
|
||||
>
|
||||
<motion.h2
|
||||
className="text-3xl md:text-4xl lg:text-5xl font-bold text-[#3C2A21] font-moneta text-gradient"
|
||||
className="text-3xl md:text-4xl lg:text-5xl font-bold text-[#3C2A21] font-moneta text-gradient p-4 md:p-0"
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
fontSize: "clamp(32px, 5vw, 58px)",
|
||||
@ -208,21 +204,17 @@ export default function Home() {
|
||||
</Button>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
{/* Right Column - Image */}
|
||||
{/* Brand Story - Right Image */}
|
||||
<motion.div
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
variants={fadeInRight}
|
||||
className="relative order-1 lg:order-2 w-screen md:w-auto -mx-4 md:mx-0" // ← Made full-width on mobile
|
||||
className="relative order-1 lg:order-2 w-screen md:w-auto -mx-4 md:mx-0"
|
||||
>
|
||||
<motion.div
|
||||
className="relative w-full h-[300px] md:h-[400px] lg:h-[500px] rounded-none md:rounded-xl overflow-hidden shadow-premium hover:shadow-premium-hover transition-all duration-500" // ← Removed rounded corners on mobile
|
||||
whileHover={{
|
||||
scale: 1.02,
|
||||
transition: { duration: 0.3 },
|
||||
}}
|
||||
className="relative w-full h-[300px] md:h-[400px] lg:h-[500px] overflow-hidden shadow-premium hover:shadow-premium-hover transition-all duration-500 clip-diagonal-bottom-left"
|
||||
whileHover={{ scale: 1.02, transition: { duration: 0.3 } }}
|
||||
>
|
||||
<Image
|
||||
src="/bst/bs1.svg"
|
||||
@ -232,40 +224,21 @@ export default function Home() {
|
||||
draggable={false}
|
||||
quality={85}
|
||||
/>
|
||||
{/* Premium overlay for depth */}
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/20 via-transparent to-transparent" />
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</Section>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white font-renner">
|
||||
<Header />
|
||||
<BannerSlider />
|
||||
|
||||
{BrandStorySection}
|
||||
|
||||
{/* Chocolate Tempering Section */}
|
||||
<Section background="white">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 md:gap-12 lg:gap-16 items-center">
|
||||
{/* Left Column - Image */}
|
||||
{/* Chocolate Tempering - Left Video */}
|
||||
<motion.div
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
variants={fadeInLeft}
|
||||
className="relative order-1 lg:order-1 w-screen md:w-auto -mx-4 md:mx-0" // ← Added for mobile edge-to-edge
|
||||
className="relative order-3 lg:order-3 w-screen md:w-auto -mx-4 md:mx-0 py-4 md:py-0"
|
||||
>
|
||||
<motion.div
|
||||
className="relative w-full h-[400px] md:h-[500px] lg:h-[700px] rounded-none md:rounded-xl overflow-hidden shadow-premium hover:shadow-premium-hover transition-all duration-500" // ← Changed to rounded-none for mobile
|
||||
whileHover={{
|
||||
scale: 1.02,
|
||||
transition: { duration: 0.3 },
|
||||
}}
|
||||
className="relative w-full h-[400px] md:h-[500px] lg:h-[700px] overflow-hidden shadow-premium hover:shadow-premium-hover transition-all duration-500 clip-diagonal-top-right"
|
||||
whileHover={{ scale: 1.02, transition: { duration: 0.3 } }}
|
||||
>
|
||||
<video
|
||||
src="/bst/v1.mp4"
|
||||
@ -276,20 +249,18 @@ export default function Home() {
|
||||
playsInline
|
||||
preload="auto"
|
||||
aria-label="Chocolate pouring from metallic spout - Mozimo chocolate tempering process"
|
||||
style={{ display: "block" }}
|
||||
/>
|
||||
{/* Premium overlay for depth */}
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/20 via-transparent to-transparent" />
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
{/* Right Column - Text */}
|
||||
{/* Chocolate Tempering - Right Text */}
|
||||
<motion.div
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
variants={fadeInRight}
|
||||
className="space-y-4 md:space-y-6 order-2 lg:order-2 px-4 md:px-0" // ← Added px-4 for mobile padding
|
||||
className="space-y-4 md:space-y-6 order-4 lg:order-4 px-4 md:px-0 ml-4 md:ml-8 lg:ml-12"
|
||||
>
|
||||
<div className="space-y-3 md:space-y-4">
|
||||
<motion.h2
|
||||
@ -316,6 +287,7 @@ export default function Home() {
|
||||
letterSpacing: "0%",
|
||||
fontStyle: "italic",
|
||||
color: "#703133",
|
||||
fontFamily: "Renner*",
|
||||
}}
|
||||
whileHover={{ scale: 1.02 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
@ -324,7 +296,6 @@ export default function Home() {
|
||||
</motion.h3>
|
||||
</div>
|
||||
|
||||
{/* Premium decorative line */}
|
||||
<motion.div
|
||||
className="w-100 h-px bg-gradient-to-r from-transparent via-[#8B4513] to-transparent"
|
||||
initial={{ scaleX: 0 }}
|
||||
@ -442,318 +413,9 @@ export default function Home() {
|
||||
</motion.div>
|
||||
</Section>
|
||||
|
||||
{/* Product Categories Section */}
|
||||
<Section background="white" id="categories">
|
||||
<div
|
||||
ref={categoriesSectionRef}
|
||||
className="grid grid-cols-1 lg:grid-cols-2 gap-0 items-stretch min-h-[400px] md:min-h-[500px]"
|
||||
>
|
||||
{/* Left Column - Categories List */}
|
||||
<motion.div
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
variants={fadeInLeft}
|
||||
className="flex flex-col justify-center h-full bg-white px-4 md:px-8 py-6 md:py-12 order-2 lg:order-1"
|
||||
>
|
||||
<ul className="space-y-4 md:space-y-6">
|
||||
{categories.map((category, idx) => (
|
||||
<motion.li
|
||||
key={category}
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.6, delay: idx * 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<button
|
||||
className={`group flex items-center gap-4 transition-all duration-700 ease-out w-full text-left font-moneta hover:scale-105
|
||||
${
|
||||
idx === currentCategory
|
||||
? "text-[#703133] font-normal"
|
||||
: "text-[#703133] opacity-60 font-light"
|
||||
}
|
||||
`}
|
||||
style={{
|
||||
fontFamily: "MonetaSans-Regular",
|
||||
fontWeight: idx === currentCategory ? 400 : 300,
|
||||
fontSize:
|
||||
idx === currentCategory
|
||||
? "clamp(22px, 5vw, 64px)"
|
||||
: "clamp(18px, 4vw, 56px)",
|
||||
lineHeight: "120%",
|
||||
letterSpacing: "0%",
|
||||
transition: "all 0.7s cubic-bezier(0.25,0.46,0.45,0.94)",
|
||||
}}
|
||||
onClick={() => setCurrentCategory(idx)}
|
||||
onMouseEnter={() => setCurrentCategory(idx)}
|
||||
tabIndex={-1}
|
||||
>
|
||||
{/* Show only on mobile */}
|
||||
<div className="block lg:hidden w-10 h-10 rounded-full overflow-hidden shrink-0">
|
||||
<img
|
||||
src={categoryImages[idx]}
|
||||
alt={category}
|
||||
className="w-full h-full object-cover"
|
||||
draggable={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Category name */}
|
||||
<span className="text-left">{category}</span>
|
||||
</button>
|
||||
</motion.li>
|
||||
))}
|
||||
</ul>
|
||||
</motion.div>
|
||||
|
||||
{/* Right Column - Large Category Image (desktop only) */}
|
||||
<motion.div
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
variants={fadeInRight}
|
||||
className="relative hidden lg:flex items-center justify-center h-full min-h-[300px] md:min-h-[400px] bg-white order-1 lg:order-2"
|
||||
>
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.img
|
||||
key={currentCategory}
|
||||
src={categoryImages[currentCategory]}
|
||||
alt={categories[currentCategory]}
|
||||
initial={{ opacity: 0, scale: 1.05 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.95 }}
|
||||
transition={{ duration: 0.7, ease: [0.25, 0.46, 0.45, 0.94] }}
|
||||
className="w-full h-full object-cover rounded-2xl shadow-premium hover:shadow-premium-hover transition-all duration-500 img-premium"
|
||||
draggable={false}
|
||||
style={{ maxHeight: "600px", maxWidth: "100%" }}
|
||||
/>
|
||||
</AnimatePresence>
|
||||
</motion.div>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<ProductCategory />
|
||||
{/* Social Media Call to Action */}
|
||||
<Section background="cream" padding="md">
|
||||
<motion.div
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
variants={fadeInUp}
|
||||
className="text-center mb-8 md:mb-12"
|
||||
>
|
||||
<h2
|
||||
className="text-3xl md:text-4xl lg:text-5xl font-moneta text-[#703133] mb-6 md:mb-8 text-gradient"
|
||||
style={{
|
||||
fontWeight: 400,
|
||||
fontSize: "clamp(28px, 5vw, 48px)",
|
||||
lineHeight: "120%",
|
||||
letterSpacing: "0%",
|
||||
fontFamily: "MonetaSans-Regular",
|
||||
}}
|
||||
>
|
||||
Follow us on Instagram
|
||||
</h2>
|
||||
</motion.div>
|
||||
|
||||
<div className="flex overflow-x-auto no-scrollbar snap-x snap-mandatory gap-4 px-4 sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:gap-6 md:gap-8 max-w-7xl mx-auto">
|
||||
{loading ? (
|
||||
<>
|
||||
{[1, 2, 3].map((i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
className="bg-white rounded-lg shadow-premium h-64 md:h-96 skeleton snap-start w-[calc(80vw-1rem)] flex-shrink-0 sm:w-auto"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: i * 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
) : error ? (
|
||||
isTokenExpired ? (
|
||||
<div className="col-span-full text-center py-12 sm:col-span-2 lg:col-span-3">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
viewport={{ once: true }}
|
||||
className="max-w-md mx-auto"
|
||||
>
|
||||
<div className="w-16 h-16 bg-gradient-to-br from-amber-200 to-orange-300 rounded-full mx-auto mb-4 flex items-center justify-center shadow-premium">
|
||||
<span className="text-2xl">🔗</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold text-[#703133] mb-2">
|
||||
Instagram Connection Expired
|
||||
</h3>
|
||||
<p className="text-gray-600 mb-4">
|
||||
Our Instagram connection needs to be refreshed. We're
|
||||
working on getting it back up!
|
||||
</p>
|
||||
<div className="text-sm text-gray-500">
|
||||
In the meantime, follow us @mozimo_chocolate
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{/* Left Block - Chocolate Spread Jar */}
|
||||
<motion.div
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
variants={fadeInLeft}
|
||||
className="bg-white rounded-lg shadow-premium overflow-hidden hover:shadow-premium-hover transition-all duration-500 transform hover:-translate-y-2 snap-start w-[calc(80vw-1rem)] flex-shrink-0 sm:w-auto"
|
||||
whileHover={{ scale: 1.02 }}
|
||||
>
|
||||
<div className="relative h-64 md:h-96 bg-gradient-to-br from-amber-50 to-orange-50 flex items-center justify-center">
|
||||
<motion.div
|
||||
className="text-center"
|
||||
whileHover={{ scale: 1.05 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<div className="w-32 h-32 bg-gradient-to-br from-amber-200 to-orange-300 rounded-full mx-auto mb-4 flex items-center justify-center shadow-premium">
|
||||
<span className="text-4xl">🍫</span>
|
||||
</div>
|
||||
<div className="bg-white rounded-lg p-4 mx-4 shadow-premium">
|
||||
<div className="font-semibold text-[#703133] text-lg">
|
||||
MOZIMO
|
||||
</div>
|
||||
<div className="text-sm text-gray-600">
|
||||
SINGLE ORIGIN HAZELNUT SPREAD 45%
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Middle Block - Magazine Article */}
|
||||
<motion.div
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
variants={fadeInUp}
|
||||
className="bg-white rounded-lg shadow-premium overflow-hidden hover:shadow-premium-hover transition-all duration-500 transform hover:-translate-y-2 snap-start w-[calc(80vw-1rem)] flex-shrink-0 sm:w-auto"
|
||||
whileHover={{ scale: 1.02 }}
|
||||
>
|
||||
<div className="p-4 md:p-6">
|
||||
<div className="bg-red-600 h-32 rounded-lg mb-4 flex items-center justify-center shadow-premium">
|
||||
<span className="text-white text-2xl">🍫</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4 mb-4">
|
||||
<div className="bg-gray-200 h-20 rounded-lg flex items-center justify-center shadow-premium">
|
||||
<span className="text-lg">🍰</span>
|
||||
</div>
|
||||
<div className="bg-gray-200 h-20 rounded-lg flex items-center justify-center shadow-premium">
|
||||
<span className="text-lg">👨🍳</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-gray-700 space-y-2 leading-relaxed">
|
||||
<p>
|
||||
<strong>By RUPALI DEAN</strong>
|
||||
</p>
|
||||
<p>
|
||||
<strong>
|
||||
MOZIMO'S CHOCOLATE PIE BY PRIYANKA GUPTA
|
||||
</strong>
|
||||
</p>
|
||||
<p>
|
||||
isolat[ing] beans to not only single ori- but also to
|
||||
single farms so as to express unique complexity.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Right Block - World Chocolate Day */}
|
||||
<motion.div
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
variants={fadeInRight}
|
||||
className="bg-white rounded-lg shadow-premium overflow-hidden hover:shadow-premium-hover transition-all duration-500 transform hover:-translate-y-2 snap-start w-[calc(80vw-1rem)] flex-shrink-0 sm:w-auto"
|
||||
whileHover={{ scale: 1.02 }}
|
||||
>
|
||||
<div className="p-4 md:p-6 text-center">
|
||||
<div className="mb-4">
|
||||
<h3 className="text-2xl font-bold text-[#8B4513] mb-2 text-gradient">
|
||||
World Chocolate Day
|
||||
</h3>
|
||||
<p className="text-gray-600">
|
||||
Celebrating the art of chocolate making
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-gradient-to-br from-amber-100 to-orange-100 rounded-lg p-4 shadow-premium">
|
||||
<div className="text-4xl mb-2">🍫</div>
|
||||
<p className="text-sm text-gray-700">
|
||||
Join us in celebrating the world's favorite treat
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
)
|
||||
) : (
|
||||
posts?.slice(0, 3).map((post, index) => (
|
||||
<motion.div
|
||||
key={post.id}
|
||||
initial="initial"
|
||||
whileInView="animate"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
variants={
|
||||
index === 0
|
||||
? fadeInLeft
|
||||
: index === 1
|
||||
? fadeInUp
|
||||
: fadeInRight
|
||||
}
|
||||
className="snap-start w-[calc(80vw-1rem)] flex-shrink-0 sm:w-auto bg-white rounded-lg shadow-premium overflow-hidden hover:shadow-premium-hover transition-all duration-500 transform hover:-translate-y-2"
|
||||
whileHover={{ scale: 1.02 }}
|
||||
>
|
||||
<a
|
||||
href={post.permalink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block"
|
||||
>
|
||||
<div className="relative h-64 md:h-96">
|
||||
<Image
|
||||
src={post.mediaUrl}
|
||||
alt={post.caption || "Instagram post"}
|
||||
fill
|
||||
className="object-cover img-premium"
|
||||
draggable={false}
|
||||
quality={85}
|
||||
onError={(e) => {
|
||||
const target = e.target as HTMLImageElement;
|
||||
target.src = "/bst/bs1.svg";
|
||||
}}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/30 via-transparent to-transparent" />
|
||||
{post.mediaType === "VIDEO" && (
|
||||
<div className="absolute top-4 right-4 bg-black/50 rounded-full p-2">
|
||||
<svg
|
||||
className="w-4 h-4 text-white"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path d="M8 5v10l8-5-8-5z" />
|
||||
</svg>
|
||||
</div>
|
||||
)}
|
||||
<div className="absolute bottom-4 left-4 right-4">
|
||||
<div className="glass rounded-lg p-3 border border-white/20">
|
||||
<p className="text-sm text-gray-800 line-clamp-2">
|
||||
{post.caption?.slice(0, 100)}...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</motion.div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</Section>
|
||||
<SocialMedia />
|
||||
|
||||
{/* In the Spotlight Section */}
|
||||
<Section background="white">
|
||||
@ -785,7 +447,6 @@ export default function Home() {
|
||||
animate={{ x: `-${spotlightIndex * 152}px` }}
|
||||
transition={{ type: "spring", stiffness: 80, damping: 18 }}
|
||||
>
|
||||
{/* Create 12 tiles (3 sets of 4 logos) */}
|
||||
{Array(12)
|
||||
.fill(0)
|
||||
.map((_, i) => {
|
||||
@ -795,7 +456,10 @@ export default function Home() {
|
||||
<motion.div
|
||||
key={i}
|
||||
className="w-24 h-24 md:w-32 md:h-32 lg:w-36 lg:h-36 bg-white rounded-full flex items-center justify-center shadow-premium hover:shadow-premium-hover flex-shrink-0 transition-all duration-300"
|
||||
style={{ boxShadow: "0 2px 12px 0 rgba(60,42,33,0.10)" }}
|
||||
style={{
|
||||
boxShadow: "0 4px 20px 0 rgba(60,42,33,0.15)", // Increased blur and opacity
|
||||
margin: "8px", // Added margin to give space for shadow
|
||||
}}
|
||||
whileHover={{
|
||||
scale: 1.1,
|
||||
rotate: 5,
|
||||
|
||||
Reference in New Issue
Block a user