feature/coming_soon #3

Merged
hardik merged 4 commits from feature/coming_soon into main 2025-12-06 19:35:57 +05:30
12 changed files with 1000 additions and 94 deletions
Showing only changes of commit 2f79c22280 - Show all commits

Binary file not shown.

View File

@ -1,12 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Vite + React + TS</title>
</head>
<body>
<title>The Kalawati</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</body>
</html>

View File

@ -16,7 +16,8 @@
"@mui/material": "^7.3.2",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react-intersection-observer": "^9.16.0"
"react-intersection-observer": "^9.16.0",
"react-router-dom": "^7.8.2"
},
"devDependencies": {
"@eslint/js": "^9.33.0",

View File

@ -1,18 +1,23 @@
// import { useState } from 'react'
// import reactLogo from './assets/react.svg'
// import viteLogo from '/vite.svg'
import './App.css'
// import VintageComingSoon from './comingsoon/comingsoon'
import VintageComingSoonPage from './comingsoon/comingsoon'
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import "./App.css";
import VintageComingSoonPage from "./comingsoon/comingsoon";
import DarkProductShowcase from "./product/product";
// import OtherPage from "./pages/OtherPage"; // example if you add more pages
function App() {
// const [count, setCount] = useState(0)
return (
<Router>
<Routes>
{/* Default route */}
<Route path="/" element={<VintageComingSoonPage />} />
<VintageComingSoonPage />
{/* Example extra routes */}
<Route path="/home" element={<DarkProductShowcase />} />
{/* <Route path="/about" element={<AboutPage />} /> */}
{/* <Route path="/contact" element={<ContactPage />} /> */}
</Routes>
</Router>
);
}
export default App
export default App;

BIN
src/assets/bag1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

BIN
src/assets/bag2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
src/assets/group1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
src/assets/solo1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
src/assets/solo2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

View File

@ -7,6 +7,12 @@ import TwitterIcon from '@mui/icons-material/Twitter';
import EmailIcon from '@mui/icons-material/Email';
import { keyframes } from '@emotion/react';
import { styled } from '@mui/system';
import image1 from '../assets/group1.jpg'
import image2 from '../assets/solo1.jpg'
import image3 from '../assets/solo2.jpg'
import image4 from '../assets/bag1.jpg'
import image5 from '../assets/bag2.jpg'
// Color palette inspired by Indian heritage
const colors = {
@ -57,6 +63,60 @@ const scrollReveal = keyframes`
to { opacity: 1; transform: translateY(0); }
`;
const shimmer = keyframes`
0% { background-position: -200px 0; }
100% { background-position: calc(200px + 100%) 0; }
`;
const textGlow = keyframes`
0% { text-shadow: 0 0 5px rgba(212, 160, 23, 0.3); }
50% { text-shadow: 0 0 15px rgba(212, 160, 23, 0.6); }
100% { text-shadow: 0 0 5px rgba(212, 160, 23, 0.3); }
`;
const borderFlow = keyframes`
0% { border-color: ${colors.accent}; }
33% { border-color: ${colors.secondary}; }
66% { border-color: ${colors.border}; }
100% { border-color: ${colors.accent}; }
`;
const typewriter = keyframes`
from { width: 0; }
to { width: 100%; }
`;
const fadeInLeft = keyframes`
from { opacity: 0; transform: translateX(-50px); }
to { opacity: 1; transform: translateX(0); }
`;
const fadeInRight = keyframes`
from { opacity: 0; transform: translateX(50px); }
to { opacity: 1; transform: translateX(0); }
`;
const bounce = keyframes`
0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
40% { transform: translateY(-15px); }
60% { transform: translateY(-7px); }
`;
const flipIn = keyframes`
0% { transform: perspective(400px) rotateY(90deg); opacity: 0; }
100% { transform: perspective(400px) rotateY(0deg); opacity: 1; }
`;
const zoomIn = keyframes`
from { transform: scale(0.95); opacity: 0; }
to { transform: scale(1); opacity: 1; }
`;
const spinSlow = keyframes`
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
`;
// Styled components
const VintageBox = styled(Box)({
position: 'relative',
@ -158,6 +218,35 @@ const AnimatedSection = styled(Box)({
animation: `${scrollReveal} 1s forwards`,
});
const GlowingText = styled(Typography)({
animation: `${textGlow} 3s ease-in-out infinite`,
});
const BorderFlowBox = styled(Box)({
border: `1px solid ${colors.accent}`,
animation: `${borderFlow} 6s infinite linear`,
});
const TypewriterText = styled(Typography)({
overflow: 'hidden',
whiteSpace: 'nowrap',
margin: '0 auto',
animation: `${typewriter} 4s steps(40, end)`,
});
const BounceBox = styled(Box)({
animation: `${bounce} 2s infinite`,
});
const FlipInBox = styled(Box)({
animation: `${flipIn} 1s forwards`,
transformOrigin: 'center',
});
const ZoomInBox = styled(Box)({
animation: `${zoomIn} 1s forwards`,
});
// Kalawati story sections with updated Pexels images
const storyChapters = [
{
@ -165,42 +254,42 @@ const storyChapters = [
title: 'Where Curiosity Met Craft',
content:
'Fresh out of fashion school, I found myself drawn to looms, dye pits, and village homes. I organized workshops to listen, learn, and share space with artisans, forging a bond between design, community, and culture.',
image: 'https://images.pexels.com/photos/28382914/pexels-photo-28382914.jpeg?auto=compress&cs=tinysrgb&w=500',
image: `${image1}`,
},
{
year: '2020',
title: 'A Name Was Born',
content:
'During the pandemic, I launched a campaign to highlight artisans hit by lockdowns. The Kalawati was born—named after women who hold culture in their palms and creativity in their hearts.',
image: 'https://images.pexels.com/photos/31308739/pexels-photo-31308739.jpeg?auto=compress&cs=tinysrgb&w=500',
image: `${image2}`,
},
{
year: '2021',
title: 'Strengthening the Circle',
content:
'I spent the year mapping artisan strengths, connecting traditional skills to modern demand, and building trust for a long-term vision of community and craft.',
image: 'https://images.pexels.com/photos/3772504/pexels-photo-3772504.jpeg?auto=compress&cs=tinysrgb&w=500',
image: `${image3}`,
},
{
year: '2022',
title: 'Systems That Serve People',
content:
'Through the JSW Foundation Fellowship, I built systems blending business and empathy—brand building for rural women, value chain development, and sustainable income pathways.',
image: 'https://images.pexels.com/photos/163064/pexels-photo-163064.jpeg?auto=compress&cs=tinysrgb&w=500',
image: `${image4}`,
},
{
year: '2023',
title: 'Quiet Creation',
content:
'Working with artisan clusters, we prototyped collections with handloom, embroidery, and natural dyes—crafting stories you could wear.',
image: 'https://images.pexels.com/photos/145939/pexels-photo-145939.jpeg?auto=compress&cs=tinysrgb&w=500',
image: `${image1}`,
},
{
year: '2024',
title: 'Kalawati Arrives',
content:
'The Kalawati opens its doors as a brand and movement, offering ethically made handcrafted apparel and decor. Join us to co-create, support heritage, and connect to roots.',
image: 'https://images.pexels.com/photos/774859/pexels-photo-774859.jpeg?auto=compress&cs=tinysrgb&w=500',
image: `${image5}`,
},
];
@ -209,22 +298,22 @@ const processSteps = [
{
title: 'Design Inspiration',
description: 'Drawing from traditional Indian motifs and contemporary aesthetics',
image: 'https://images.pexels.com/photos/28382914/pexels-photo-28382914.jpeg?auto=compress&cs=tinysrgb&w=500',
image: `${image4}`,
},
{
title: 'Material Selection',
description: 'Choosing the finest natural fibers and dyes',
image: 'https://images.pexels.com/photos/145939/pexels-photo-145939.jpeg?auto=compress&cs=tinysrgb&w=500',
image: `${image5}`,
},
{
title: 'Artisan Crafting',
description: 'Skilled hands weaving stories into fabric',
image: 'https://images.pexels.com/photos/163064/pexels-photo-163064.jpeg?auto=compress&cs=tinysrgb&w=500',
image: `${image4}`,
},
{
title: 'Quality Assurance',
description: 'Meticulous inspection ensuring perfection',
image: 'https://images.pexels.com/photos/3772504/pexels-photo-3772504.jpeg?auto=compress&cs=tinysrgb&w=500',
image: `${image5}`,
},
];
@ -287,10 +376,12 @@ export const VintageComingSoonPage: React.FC = () => {
const handleSubscribe = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
if (email && email.includes('@')) {
console.log('Subscribed with email:', email);
setSubscribed(true);
setEmail('');
setTimeout(() => setSubscribed(false), 3000);
}
};
return (
@ -310,6 +401,39 @@ export const VintageComingSoonPage: React.FC = () => {
}}
/>
{/* Animated decorative elements */}
<Box
sx={{
position: 'fixed',
top: '10%',
right: '5%',
width: '100px',
height: '100px',
backgroundImage: `linear-gradient(90deg, ${colors.accent}20, ${colors.secondary}30, ${colors.accent}20)`,
backgroundSize: '200px 100px',
borderRadius: '50%',
animation: `${shimmer} 2s infinite linear, ${spinSlow} 20s infinite linear`,
zIndex: 0,
opacity: 0.3,
}}
/>
<Box
sx={{
position: 'fixed',
bottom: '15%',
left: '5%',
width: '80px',
height: '80px',
backgroundImage: `linear-gradient(90deg, ${colors.secondary}20, ${colors.accent}30, ${colors.secondary}20)`,
backgroundSize: '200px 100px',
borderRadius: '50%',
animation: `${shimmer} 3s infinite linear, ${spinSlow} 25s infinite linear reverse`,
zIndex: 0,
opacity: 0.3,
}}
/>
{/* Parallax background elements */}
<Box
sx={{
@ -318,14 +442,18 @@ export const VintageComingSoonPage: React.FC = () => {
right: '5%',
width: '200px',
height: '200px',
backgroundImage: 'url(https://images.pexels.com/photos/28382914/pexels-photo-28382914.jpeg?auto=compress&cs=tinysrgb&w=500)',
// backgroundColor: 'black',
backgroundSize: 'cover',
backgroundPosition: 'center',
opacity: 0.1,
zIndex: 0,
transform: `rotate(${scrollPosition * 0.02}deg)`,
transition: 'transform 0.3s ease-out',
borderRadius: '50%', // makes it circular
overflow: 'hidden', // ensures image stays inside the circle
}}
/>
<Box
sx={{
position: 'fixed',
@ -333,15 +461,19 @@ export const VintageComingSoonPage: React.FC = () => {
left: '5%',
width: '150px',
height: '150px',
backgroundImage: 'url(https://images.pexels.com/photos/145939/pexels-photo-145939.jpeg?auto=compress&cs=tinysrgb&w=500)',
// backgroundColor: 'black',
backgroundSize: 'cover',
backgroundPosition: 'center',
opacity: 0.1,
zIndex: 0,
transform: `rotate(${-scrollPosition * 0.03}deg)`,
transition: 'transform 0.3s ease-out',
borderRadius: '50%', // circular shape
overflow: 'hidden', // ensures the image fits inside the circle
}}
/>
<Container maxWidth="lg" sx={{ position: 'relative', zIndex: 1, py: 6 }} ref={containerRef}>
{/* Header */}
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: `1px solid ${colors.border}`, py: 4, mb: 4 }}>
@ -361,6 +493,7 @@ export const VintageComingSoonPage: React.FC = () => {
</AnimatedSection>
<AnimatedSection ref={heroRef} style={{ animationDelay: heroInView ? '0.2s' : '0s' }}>
<Box sx={{ display: 'flex', gap: 2 }}>
<BounceBox>
<IconButton
href="https://instagram.com"
target="_blank"
@ -368,6 +501,8 @@ export const VintageComingSoonPage: React.FC = () => {
>
<InstagramIcon />
</IconButton>
</BounceBox>
<BounceBox sx={{ animationDelay: '0.1s' }}>
<IconButton
href="https://facebook.com"
target="_blank"
@ -375,6 +510,8 @@ export const VintageComingSoonPage: React.FC = () => {
>
<FacebookIcon />
</IconButton>
</BounceBox>
<BounceBox sx={{ animationDelay: '0.2s' }}>
<IconButton
href="https://twitter.com"
target="_blank"
@ -382,6 +519,7 @@ export const VintageComingSoonPage: React.FC = () => {
>
<TwitterIcon />
</IconButton>
</BounceBox>
</Box>
</AnimatedSection>
</Box>
@ -450,7 +588,7 @@ export const VintageComingSoonPage: React.FC = () => {
flex: 1,
}}
>
<Typography
<GlowingText
variant="h1"
sx={{
fontWeight: 300,
@ -462,7 +600,7 @@ export const VintageComingSoonPage: React.FC = () => {
}}
>
<span style={{ fontWeight: 400, color: colors.dark }}>A Journey</span> Woven with Stories, People & Purpose
</Typography>
</GlowingText>
<Typography
variant="h5"
sx={{
@ -544,7 +682,7 @@ export const VintageComingSoonPage: React.FC = () => {
{/* Email Subscription */}
<Box>
<Box sx={{ display: 'flex', gap: 3, mb: 3, flexDirection: { xs: 'column', sm: 'row' } }}>
<BorderFlowBox sx={{ display: 'flex', gap: 3, mb: 3, flexDirection: { xs: 'column', sm: 'row' }, p: '1px', borderRadius: '0' }}>
<input
type="email"
value={email}
@ -555,7 +693,7 @@ export const VintageComingSoonPage: React.FC = () => {
flex: 1,
padding: '16px 24px',
borderRadius: '0',
border: `1px solid ${colors.border}`,
border: 'none',
fontSize: '16px',
outline: 'none',
background: colors.paper,
@ -579,7 +717,7 @@ export const VintageComingSoonPage: React.FC = () => {
>
Notify Me
</VintagePulseButton>
</Box>
</BorderFlowBox>
{subscribed && (
<Typography
sx={{
@ -613,7 +751,7 @@ export const VintageComingSoonPage: React.FC = () => {
'&::before': {
content: '""',
position: 'absolute',
top: 0,
top: "20%",
left: '50%',
transform: 'translateX(-50%)',
width: '1px',
@ -788,9 +926,10 @@ export const VintageComingSoonPage: React.FC = () => {
'&:hover': {
transform: 'translateY(-5px)',
},
height: '100%',
}}
>
<VintageImageFrame
<FlipInBox
sx={{
height: '200px',
width: '100%',
@ -799,7 +938,6 @@ export const VintageComingSoonPage: React.FC = () => {
backgroundPosition: 'center',
mb: 3,
filter: 'sepia(0.2) contrast(1.05)',
animation: `${scaleIn} 1s ease`,
}}
/>
<Typography variant="h6" sx={{ fontWeight: 400, color: colors.ink, mb: 2, fontFamily: '"Playfair Display", serif' }}>
@ -847,6 +985,7 @@ export const VintageComingSoonPage: React.FC = () => {
Join our journey to weave stories, empower artisans, and celebrate Indian heritage. Be the first to experience our handcrafted collections.
</Typography>
<Box sx={{ display: 'flex', justifyContent: 'center', gap: 3, mb: 4 }}>
<BounceBox>
<IconButton
href="https://instagram.com"
target="_blank"
@ -854,6 +993,8 @@ export const VintageComingSoonPage: React.FC = () => {
>
<InstagramIcon />
</IconButton>
</BounceBox>
<BounceBox sx={{ animationDelay: '0.1s' }}>
<IconButton
href="https://facebook.com"
target="_blank"
@ -861,6 +1002,8 @@ export const VintageComingSoonPage: React.FC = () => {
>
<FacebookIcon />
</IconButton>
</BounceBox>
<BounceBox sx={{ animationDelay: '0.2s' }}>
<IconButton
href="https://twitter.com"
target="_blank"
@ -868,12 +1011,15 @@ export const VintageComingSoonPage: React.FC = () => {
>
<TwitterIcon />
</IconButton>
</BounceBox>
<BounceBox sx={{ animationDelay: '0.3s' }}>
<IconButton
href="mailto:contact@thekalawati.com"
sx={{ color: colors.secondary, '&:hover': { color: colors.accent, transform: 'scale(1.1)' }, transition: 'all 0.3s ease' }}
>
<EmailIcon />
</IconButton>
</BounceBox>
</Box>
<Typography
variant="caption"

708
src/product/product.tsx Normal file
View File

@ -0,0 +1,708 @@
import React, { useState } from 'react';
import { Box, Typography, Button, Container, IconButton, Grid, Card, Chip, CardMedia } from '@mui/material';
import { useInView } from 'react-intersection-observer';
import InstagramIcon from '@mui/icons-material/Instagram';
import FacebookIcon from '@mui/icons-material/Facebook';
import TwitterIcon from '@mui/icons-material/Twitter';
import EmailIcon from '@mui/icons-material/Email';
import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder';
import VisibilityIcon from '@mui/icons-material/Visibility';
import { keyframes } from '@emotion/react';
import { styled } from '@mui/system';
import image1 from '../assets/group1.jpg'
import image2 from '../assets/solo1.jpg'
import image3 from '../assets/solo2.jpg'
import image4 from '../assets/bag1.jpg'
import image5 from '../assets/bag2.jpg'
// Lighter color palette for product showcase
const colors = {
lightBase: '#F8F7F4', // Very light cream
lightPaper: '#FFFFFF', // White
lightInk: '#3E3E3E', // Dark gray for text
accent: '#C19A6B', // Muted gold
secondary: '#8E7D6D', // Muted taupe
highlight: '#E8D9C7', // Light sand
border: '#D1C6B5', // Light tan border
dark: '#5C4B3A', // Dark brown for contrast
};
// Smooth animations
const fadeIn = keyframes`
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
`;
const scaleIn = keyframes`
from { transform: scale(0.95); opacity: 0; }
to { transform: scale(1); opacity: 1; }
`;
const float = keyframes`
0% { transform: translateY(0px); }
50% { transform: translateY(-8px); }
100% { transform: translateY(0px); }
`;
const drawUnderline = keyframes`
0% { width: 0; }
100% { width: 100%; }
`;
const smoothPulse = keyframes`
0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(193, 154, 107, 0.3); }
70% { transform: scale(1.01); box-shadow: 0 0 0 8px rgba(193, 154, 107, 0); }
100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(193, 154, 107, 0); }
`;
// Styled components
const LightVintageBox = styled(Box)({
position: 'relative',
backgroundColor: colors.lightBase,
'&::before': {
content: '""',
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
background: `url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%235C4B3A' fill-opacity='0.05' fill-rule='evenodd'/%3E%3C/svg%3E")`,
opacity: 0.1,
zIndex: 0,
},
});
const LightVintageButton = styled(Button)({
position: 'relative',
overflow: 'hidden',
border: `1px solid ${colors.border}`,
color: colors.lightInk,
backgroundColor: colors.lightPaper,
fontWeight: 400,
letterSpacing: '0.5px',
textTransform: 'uppercase',
padding: '10px 22px',
borderRadius: '2px',
transition: 'all 0.3s ease',
boxShadow: '0 2px 8px rgba(0,0,0,0.05)',
'&:hover': {
backgroundColor: colors.highlight,
color: colors.dark,
borderColor: colors.accent,
transform: 'translateY(-2px)',
boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
},
'&::after': {
content: '""',
position: 'absolute',
bottom: 0,
left: 0,
width: '100%',
height: '1px',
backgroundColor: colors.accent,
transform: 'scaleX(0)',
transformOrigin: 'right',
transition: 'transform 0.3s ease',
},
'&:hover::after': {
transform: 'scaleX(1)',
transformOrigin: 'left',
},
});
const LightVintagePulseButton = styled(LightVintageButton)({
animation: `${smoothPulse} 3s infinite`,
'&:hover': {
animation: 'none',
},
});
const LightVintageUnderline = styled(Box)({
position: 'relative',
display: 'inline-block',
'&::after': {
content: '""',
position: 'absolute',
bottom: '-4px',
left: 0,
width: '0',
height: '1.5px',
backgroundColor: colors.accent,
animation: `${drawUnderline} 1.2s forwards`,
animationDelay: '0.3s',
},
});
const AnimatedSection = styled(Box)({
opacity: 0,
transform: 'translateY(20px)',
animation: `${fadeIn} 0.8s forwards`,
});
// Product data
const products = [
{
id: 1,
name: 'Handwoven Silk Saree',
price: '₹12,999',
description: 'Traditional Banarasi silk with zari work',
image: `${image5}`,
category: 'Clothing',
tags: ['Handmade', 'Premium'],
},
{
id: 2,
name: 'Block Print Cotton Kurta',
price: '₹3,499',
description: 'Hand-block printed with natural dyes',
image: `${image4}`,
category: 'Clothing',
tags: ['Eco-friendly', 'Handmade'],
},
{
id: 3,
name: 'Brass Pooja Thali',
price: '₹2,899',
description: 'Handcrafted brass prayer set with intricate designs',
image: `${image4}`,
category: 'Home Decor',
tags: ['Ritual', 'Handcrafted'],
},
{
id: 4,
name: 'Embroidered Jutti',
price: '₹1,899',
description: 'Traditional Punjabi footwear with phulkari work',
image: `${image5}`,
category: 'Footwear',
tags: ['Handmade', 'Comfort'],
},
{
id: 5,
name: 'Handloom Cushion Covers',
price: '₹1,299',
description: 'Set of 2 handwoven cushion covers',
image: `${image4}`,
category: 'Home Decor',
tags: ['Handmade', 'Set'],
},
{
id: 6,
name: 'Silver Tribal Jewelry Set',
price: '₹5,999',
description: 'Traditional tribal necklace and earrings set',
image: `${image5}`,
category: 'Jewelry',
tags: ['Handcrafted', 'Silver'],
},
];
const categories = [
{ name: 'All', value: 'all' },
{ name: 'Clothing', value: 'Clothing' },
{ name: 'Home Decor', value: 'Home Decor' },
{ name: 'Jewelry', value: 'Jewelry' },
{ name: 'Footwear', value: 'Footwear' },
];
export const LightProductShowcase: React.FC = () => {
const [selectedCategory, setSelectedCategory] = useState('all');
const [hoveredProduct, setHoveredProduct] = useState<number | null>(null);
// Intersection Observer for scroll animations
const [heroRef, heroInView] = useInView({ threshold: 0.1, triggerOnce: true });
const [productsRef, productsInView] = useInView({ threshold: 0.1, triggerOnce: true });
const [footerRef, footerInView] = useInView({ threshold: 0.1, triggerOnce: true });
const filteredProducts = selectedCategory === 'all'
? products
: products.filter(product => product.category === selectedCategory);
return (
<LightVintageBox sx={{ minHeight: '100vh', color: colors.lightInk, overflow: 'hidden', position: 'relative' }}>
{/* Paper texture overlay */}
<Box
sx={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
backgroundImage:
'url("data:image/svg+xml,%3Csvg width=\'600\' height=\'600\' viewBox=\'0 0 600 600\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cfilter id=\'noiseFilter\'%3E%3CfeTurbulence type=\'fractalNoise\' baseFrequency=\'0.65\' numOctaves=\'3\' stitchTiles=\'stitch\'/%3E%3C/filter%3E%3Crect width=\'100%25\' height=\'100%25\' filter=\'url(%23noiseFilter)\' opacity=\'0.03\'/%3E%3C/svg%3E")',
opacity: 0.3,
zIndex: 0,
}}
/>
{/* Animated decorative elements */}
<Box
sx={{
position: 'fixed',
top: '15%',
right: '5%',
width: '80px',
height: '80px',
background: `linear-gradient(135deg, ${colors.accent}15, ${colors.secondary}20, ${colors.accent}15)`,
borderRadius: '50%',
animation: `${float} 8s ease-in-out infinite`,
zIndex: 0,
opacity: 0.4,
}}
/>
<Box
sx={{
position: 'fixed',
bottom: '20%',
left: '5%',
width: '60px',
height: '60px',
background: `linear-gradient(135deg, ${colors.secondary}15, ${colors.accent}20, ${colors.secondary}15)`,
borderRadius: '50%',
animation: `${float} 7s ease-in-out infinite reverse`,
zIndex: 0,
opacity: 0.4,
}}
/>
<Container maxWidth="lg" sx={{ position: 'relative', zIndex: 1, py: 5 }}>
{/* Header */}
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: `1px solid ${colors.border}`, py: 3, mb: 4 }}>
<AnimatedSection ref={heroRef} style={{ animationDelay: heroInView ? '0.1s' : '0s' }}>
<Typography
variant="h3"
sx={{
fontWeight: 500,
color: colors.lightInk,
letterSpacing: '2px',
fontFamily: '"Playfair Display", serif',
}}
>
<LightVintageUnderline>The Kalawati Collection</LightVintageUnderline>
</Typography>
</AnimatedSection>
<AnimatedSection ref={heroRef} style={{ animationDelay: heroInView ? '0.2s' : '0s' }}>
<Box sx={{ display: 'flex', gap: 1 }}>
<IconButton
href="https://instagram.com"
target="_blank"
sx={{
color: colors.secondary,
'&:hover': { color: colors.accent, transform: 'scale(1.1)' },
transition: 'all 0.3s ease'
}}
>
<InstagramIcon />
</IconButton>
<IconButton
href="https://facebook.com"
target="_blank"
sx={{
color: colors.secondary,
'&:hover': { color: colors.accent, transform: 'scale(1.1)' },
transition: 'all 0.3s ease'
}}
>
<FacebookIcon />
</IconButton>
<IconButton
href="https://twitter.com"
target="_blank"
sx={{
color: colors.secondary,
'&:hover': { color: colors.accent, transform: 'scale(1.1)' },
transition: 'all 0.3s ease'
}}
>
<TwitterIcon />
</IconButton>
</Box>
</AnimatedSection>
</Box>
{/* Hero Section */}
<Box
sx={{
display: 'flex',
flexDirection: { xs: 'column', md: 'row' },
alignItems: 'center',
gap: 6,
py: 6,
minHeight: '50vh',
}}
>
<AnimatedSection
ref={heroRef}
style={{
animationDelay: heroInView ? '0.3s' : '0s',
flex: 1,
}}
>
<Box
sx={{
height: { xs: '350px', md: '450px' },
backgroundImage: `url(${image2})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
borderRadius: '4px',
boxShadow: '0 4px 20px rgba(0,0,0,0.08)',
animation: `${scaleIn} 1s ease`,
}}
/>
</AnimatedSection>
<AnimatedSection
ref={heroRef}
style={{
animationDelay: heroInView ? '0.4s' : '0s',
flex: 1,
}}
>
<Typography
variant="h3"
sx={{
fontWeight: 300,
mb: 3,
fontSize: { xs: '2.2rem', md: '2.8rem' },
lineHeight: 1.3,
color: colors.lightInk,
fontFamily: '"Playfair Display", serif',
}}
>
<span style={{ fontWeight: 400, color: colors.dark }}>Timeless</span> Craftsmanship, Modern Elegance
</Typography>
<Typography
variant="h6"
sx={{
mb: 4,
color: colors.secondary,
fontWeight: 300,
fontStyle: 'italic',
fontFamily: '"Cormorant Garamond", serif',
pl: 3,
position: 'relative',
'&::before': {
content: '""',
position: 'absolute',
left: 0,
top: 0,
height: '100%',
width: '2px',
background: colors.accent,
},
}}
>
Each piece tells a story of tradition, skill, and the hands that crafted it with love and dedication.
</Typography>
<LightVintagePulseButton
variant="contained"
sx={{
px: 4,
py: 1.5,
fontWeight: 300,
fontFamily: '"Cormorant Garamond", serif',
letterSpacing: '1.5px',
color: colors.lightInk,
'&:hover': { background: colors.highlight },
}}
>
Explore Collection
</LightVintagePulseButton>
</AnimatedSection>
</Box>
{/* Category Filter */}
<Box sx={{ my: 6, textAlign: 'center' }}>
<AnimatedSection style={{ animationDelay: '0.1s' }}>
<Typography
variant="h5"
sx={{
mb: 3,
fontWeight: 300,
color: colors.lightInk,
fontFamily: '"Playfair Display", serif',
}}
>
Browse Categories
</Typography>
</AnimatedSection>
<Box sx={{ display: 'flex', justifyContent: 'center', flexWrap: 'wrap', gap: 1.5, mb: 5 }}>
{categories.map((category) => (
<Chip
key={category.value}
label={category.name}
onClick={() => setSelectedCategory(category.value)}
variant={selectedCategory === category.value ? "filled" : "outlined"}
sx={{
color: selectedCategory === category.value ? colors.lightPaper : colors.lightInk,
backgroundColor: selectedCategory === category.value ? colors.accent : 'transparent',
borderColor: colors.border,
fontFamily: '"Cormorant Garamond", serif',
fontSize: '1rem',
padding: '8px 16px',
'&:hover': {
backgroundColor: selectedCategory === category.value ? colors.accent : colors.highlight,
},
}}
/>
))}
</Box>
</Box>
{/* Products Grid */}
<Box ref={productsRef} sx={{ my: 8 }}>
<Grid container spacing={3}>
{filteredProducts.map((product, index) => (
<Grid key={product.id}>
<AnimatedSection
style={{
animationDelay: productsInView ? `${index * 0.1}s` : '0s',
}}
>
<Card
sx={{
background: colors.lightPaper,
border: `1px solid ${colors.border}`,
borderRadius: '4px',
overflow: 'hidden',
transition: 'all 0.3s ease',
height: '100%',
display: 'flex',
flexDirection: 'column',
boxShadow: '0 4px 12px rgba(0,0,0,0.05)',
'&:hover': {
transform: 'translateY(-4px)',
boxShadow: `0 8px 24px rgba(0,0,0,0.1)`,
},
}}
onMouseEnter={() => setHoveredProduct(product.id)}
onMouseLeave={() => setHoveredProduct(null)}
>
<Box sx={{ position: 'relative', overflow: 'hidden' }}>
<CardMedia
component="img"
height="300"
image={product.image}
alt={product.name}
sx={{
transition: 'all 0.5s ease',
transform: hoveredProduct === product.id ? 'scale(1.05)' : 'scale(1)',
filter: 'brightness(0.98)',
}}
/>
<Box
sx={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
background: `linear-gradient(to bottom, transparent 0%, ${colors.lightBase} 100%)`,
opacity: hoveredProduct === product.id ? 0.8 : 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
gap: 2,
transition: 'all 0.3s ease',
}}
>
<IconButton sx={{ color: colors.lightInk, background: `${colors.lightPaper}`, '&:hover': { background: colors.accent, color: colors.lightPaper } }}>
<FavoriteBorderIcon />
</IconButton>
<IconButton sx={{ color: colors.lightInk, background: `${colors.lightPaper}`, '&:hover': { background: colors.accent, color: colors.lightPaper } }}>
<ShoppingCartIcon />
</IconButton>
<IconButton sx={{ color: colors.lightInk, background: `${colors.lightPaper}`, '&:hover': { background: colors.accent, color: colors.lightPaper } }}>
<VisibilityIcon />
</IconButton>
</Box>
<Box sx={{ position: 'absolute', top: 10, right: 10 }}>
{product.tags.map((tag, i) => (
<Chip
key={i}
label={tag}
size="small"
sx={{
background: colors.accent,
color: colors.lightPaper,
fontSize: '0.7rem',
height: '22px',
mb: 0.5,
display: 'block',
}}
/>
))}
</Box>
</Box>
<Box sx={{ p: 2.5, flexGrow: 1, display: 'flex', flexDirection: 'column' }}>
<Typography
variant="h6"
sx={{
fontWeight: 400,
color: colors.lightInk,
fontFamily: '"Playfair Display", serif',
mb: 1,
}}
>
{product.name}
</Typography>
<Typography
variant="body2"
sx={{
color: colors.secondary,
fontFamily: '"Cormorant Garamond", serif',
mb: 2,
flexGrow: 1,
fontSize: '0.95rem',
}}
>
{product.description}
</Typography>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Typography
variant="h6"
sx={{
color: colors.accent,
fontFamily: '"Playfair Display", serif',
}}
>
{product.price}
</Typography>
<LightVintageButton size="small">
Add to Cart
</LightVintageButton>
</Box>
</Box>
</Card>
</AnimatedSection>
</Grid>
))}
</Grid>
</Box>
{/* Call to Action */}
<Box sx={{ my: 8, py: 8, textAlign: 'center', background: colors.highlight, borderRadius: '4px' }}>
<Container maxWidth="md">
<AnimatedSection style={{ animationDelay: '0.1s' }}>
<Typography
variant="h4"
sx={{
mb: 3,
fontWeight: 300,
color: colors.lightInk,
fontFamily: '"Playfair Display", serif',
}}
>
Join Our Artisan Community
</Typography>
</AnimatedSection>
<AnimatedSection style={{ animationDelay: '0.2s' }}>
<Typography
variant="body1"
sx={{
color: colors.secondary,
mb: 5,
fontSize: '1.05rem',
fontFamily: '"Cormorant Garamond", serif',
lineHeight: 1.7,
}}
>
By purchasing our products, you're not just buying beautiful handcrafted items—you're supporting traditional artisans and helping preserve India's rich cultural heritage for future generations.
</Typography>
</AnimatedSection>
<AnimatedSection style={{ animationDelay: '0.3s' }}>
<LightVintagePulseButton
variant="contained"
sx={{
px: 5,
py: 1.5,
fontWeight: 300,
fontFamily: '"Cormorant Garamond", serif',
letterSpacing: '1.5px',
color: colors.lightInk,
'&:hover': { background: colors.highlight },
}}
>
Discover Our Story
</LightVintagePulseButton>
</AnimatedSection>
</Container>
</Box>
{/* Footer */}
<Box ref={footerRef} sx={{ py: 5, textAlign: 'center', borderTop: `1px solid ${colors.border}` }}>
<AnimatedSection style={{ animationDelay: footerInView ? '0.1s' : '0s' }}>
<Typography
variant="h6"
sx={{
mb: 2,
fontWeight: 300,
color: colors.lightInk,
letterSpacing: '3px',
fontFamily: '"Playfair Display", serif',
textTransform: 'uppercase',
}}
>
Handcrafted Heritage
</Typography>
<Typography
variant="body2"
sx={{
color: colors.secondary,
mb: 3,
maxWidth: '600px',
margin: '0 auto',
fontSize: '0.95rem',
fontFamily: '"Cormorant Garamond", serif',
lineHeight: 1.6,
}}
>
Each piece tells a story of India's rich heritage and skilled artisanship.
</Typography>
<Box sx={{ display: 'flex', justifyContent: 'center', gap: 2, mb: 3 }}>
<IconButton
href="https://instagram.com"
target="_blank"
sx={{ color: colors.secondary, '&:hover': { color: colors.accent, transform: 'scale(1.1)' }, transition: 'all 0.3s ease' }}
>
<InstagramIcon />
</IconButton>
<IconButton
href="https://facebook.com"
target="_blank"
sx={{ color: colors.secondary, '&:hover': { color: colors.accent, transform: 'scale(1.1)' }, transition: 'all 0.3s ease' }}
>
<FacebookIcon />
</IconButton>
<IconButton
href="https://twitter.com"
target="_blank"
sx={{ color: colors.secondary, '&:hover': { color: colors.accent, transform: 'scale(1.1)' }, transition: 'all 0.3s ease' }}
>
<TwitterIcon />
</IconButton>
<IconButton
href="mailto:contact@thekalawati.com"
sx={{ color: colors.secondary, '&:hover': { color: colors.accent, transform: 'scale(1.1)' }, transition: 'all 0.3s ease' }}
>
<EmailIcon />
</IconButton>
</Box>
<Typography
variant="caption"
sx={{ color: colors.secondary, opacity: 0.7, fontSize: '0.8rem', fontFamily: '"Cormorant Garamond", serif' }}
>
© {new Date().getFullYear()} Handcrafted Heritage. All rights reserved.
</Typography>
</AnimatedSection>
</Box>
</Container>
</LightVintageBox>
);
};
export default LightProductShowcase;

View File

@ -1731,6 +1731,13 @@ __metadata:
languageName: node
linkType: hard
"cookie@npm:^1.0.1":
version: 1.0.2
resolution: "cookie@npm:1.0.2"
checksum: 10c0/fd25fe79e8fbcfcaf6aa61cd081c55d144eeeba755206c058682257cb38c4bd6795c6620de3f064c740695bb65b7949ebb1db7a95e4636efb8357a335ad3f54b
languageName: node
linkType: hard
"cosmiconfig@npm:^7.0.0":
version: 7.1.0
resolution: "cosmiconfig@npm:7.1.0"
@ -3771,6 +3778,34 @@ __metadata:
languageName: node
linkType: hard
"react-router-dom@npm:^7.8.2":
version: 7.8.2
resolution: "react-router-dom@npm:7.8.2"
dependencies:
react-router: "npm:7.8.2"
peerDependencies:
react: ">=18"
react-dom: ">=18"
checksum: 10c0/b285182ffa1b26df5025f6e7952edca066928d5688d3447b02e4a7e699ca16941e8a42ecad65ab505914e27fed04a2023c92ae3ebf838226b4381a2e3a69ae01
languageName: node
linkType: hard
"react-router@npm:7.8.2":
version: 7.8.2
resolution: "react-router@npm:7.8.2"
dependencies:
cookie: "npm:^1.0.1"
set-cookie-parser: "npm:^2.6.0"
peerDependencies:
react: ">=18"
react-dom: ">=18"
peerDependenciesMeta:
react-dom:
optional: true
checksum: 10c0/e3122c2949bcad5e9c990cfb88e9cbd139e5a2a5c1d29664732623907a488634c0ddbf673d07af8f113d418f66270c174f014de8b885996722f431d09f5734be
languageName: node
linkType: hard
"react-transition-group@npm:^4.4.5":
version: 4.4.5
resolution: "react-transition-group@npm:4.4.5"
@ -4049,6 +4084,13 @@ __metadata:
languageName: node
linkType: hard
"set-cookie-parser@npm:^2.6.0":
version: 2.7.1
resolution: "set-cookie-parser@npm:2.7.1"
checksum: 10c0/060c198c4c92547ac15988256f445eae523f57f2ceefeccf52d30d75dedf6bff22b9c26f756bd44e8e560d44ff4ab2130b178bd2e52ef5571bf7be3bd7632d9a
languageName: node
linkType: hard
"set-function-length@npm:^1.2.2":
version: 1.2.2
resolution: "set-function-length@npm:1.2.2"
@ -4393,6 +4435,7 @@ __metadata:
react: "npm:^19.1.1"
react-dom: "npm:^19.1.1"
react-intersection-observer: "npm:^9.16.0"
react-router-dom: "npm:^7.8.2"
typescript: "npm:~5.8.3"
typescript-eslint: "npm:^8.39.1"
vite: "npm:^7.1.2"