395 lines
17 KiB
TypeScript
395 lines
17 KiB
TypeScript
"use client";
|
|
|
|
import { useRef } from "react";
|
|
import { motion } from "framer-motion";
|
|
import Image from "next/image";
|
|
|
|
interface MenuItemProps {
|
|
name: string;
|
|
desc: string;
|
|
tag: string;
|
|
type: "green" | "gold" | "orange";
|
|
img: string;
|
|
}
|
|
|
|
const LotusOrnament = () => (
|
|
<svg className="w-16 h-8 text-[#bc9e65] opacity-90 mb-1" viewBox="0 0 120 40" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
|
{/* Center Petal */}
|
|
<path d="M 60,5 C 55,18 57,32 60,35 C 63,32 65,18 60,5 Z" fill="currentColor" fillOpacity="0.1" />
|
|
{/* Left Petal */}
|
|
<path d="M 60,18 C 45,20 44,32 60,35" />
|
|
{/* Right Petal */}
|
|
<path d="M 60,18 C 75,20 76,32 60,35" />
|
|
{/* Left scroll wing */}
|
|
<path d="M 45,30 C 30,30 25,20 35,15 C 42,12 48,22 38,28 C 35,30 30,26 32,22" />
|
|
{/* Right scroll wing */}
|
|
<path d="M 75,30 C 90,30 95,20 85,15 C 78,12 72,22 82,28 C 85,30 90,26 88,22" />
|
|
<circle cx="60" cy="35" r="2" fill="currentColor" />
|
|
</svg>
|
|
);
|
|
|
|
const TitleDivider = () => (
|
|
<div className="flex items-center gap-4 w-full max-w-[280px] justify-center my-3">
|
|
<div className="h-[1px] flex-1 bg-gradient-to-r from-transparent via-[#d8c396]/60 to-[#d8c396]" />
|
|
<svg className="w-6 h-4 text-[#bc9e65] opacity-90" viewBox="0 0 40 20" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
|
<path d="M 20,4 C 18,10 12,14 20,17 C 28,14 22,10 20,4 Z" fill="currentColor" fillOpacity="0.1" />
|
|
<path d="M 12,14 C 4,14 2,10 8,8 C 12,7 15,11 12,14" />
|
|
<path d="M 28,14 C 36,14 38,10 32,8 C 28,7 25,11 28,14" />
|
|
</svg>
|
|
<div className="h-[1px] flex-1 bg-gradient-to-l from-transparent via-[#d8c396]/60 to-[#d8c396]" />
|
|
</div>
|
|
);
|
|
|
|
const MiniOrnament = () => (
|
|
<svg className="w-6 h-5 text-[#bc9e65] opacity-75 mt-3" viewBox="0 0 30 20" fill="none" stroke="currentColor" strokeWidth="1.2">
|
|
<path d="M 15,3 C 13,8 14,14 15,16 C 16,14 17,8 15,3 Z" fill="currentColor" fillOpacity="0.1" />
|
|
<path d="M 15,8 C 9,10 9,15 15,16" />
|
|
<path d="M 15,8 C 21,10 21,15 15,16" />
|
|
</svg>
|
|
);
|
|
|
|
const BoardCornerDecor = ({ position }: { position: "tl" | "tr" | "bl" | "br" }) => {
|
|
const styles = {
|
|
tl: "top-4 left-4 rotate-0",
|
|
tr: "top-4 right-4 -scale-x-100",
|
|
bl: "bottom-4 left-4 -scale-y-100",
|
|
br: "bottom-4 right-4 scale-[-1]"
|
|
};
|
|
return (
|
|
<svg
|
|
className={`absolute ${styles[position]} w-10 h-10 md:w-12 md:h-12 text-[#bc9e65]/60 pointer-events-none z-10`}
|
|
viewBox="0 0 50 50"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="1.2"
|
|
>
|
|
<path d="M 2,12 C 2,6 6,2 12,2 L 30,2" />
|
|
<path d="M 12,2 C 6,2 2,6 2,12 L 2,30" />
|
|
<path d="M 6,18 C 6,12 12,6 18,6 L 24,6" />
|
|
<path d="M 18,6 C 12,6 6,12 6,18 L 6,24" />
|
|
<path d="M 4,4 C 8,8 8,8 12,12 C 14,14 16,13 16,10 C 16,7 13,8 11,11" />
|
|
<circle cx="16" cy="16" r="1.5" fill="currentColor" />
|
|
</svg>
|
|
);
|
|
};
|
|
|
|
const CategoryPill = ({ tag, type }: { tag: string; type: "green" | "gold" | "orange" }) => {
|
|
const styles = {
|
|
green: {
|
|
bg: "bg-[#e8f5e9]/95 text-[#1b5e20] border-[#a5d6a7]/70",
|
|
icon: "✓"
|
|
},
|
|
gold: {
|
|
bg: "bg-[#fff8e1]/95 text-[#b78103] border-[#ffe082]/70",
|
|
icon: "★"
|
|
},
|
|
orange: {
|
|
bg: "bg-[#fbe9e7]/95 text-[#c62828] border-[#ffab91]/70",
|
|
icon: "●"
|
|
}
|
|
};
|
|
const style = styles[type];
|
|
return (
|
|
<span className={`inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full border text-sm font-sans font-bold uppercase tracking-wider shadow-sm flex-shrink-0 ${style.bg}`}>
|
|
<span className="text-base leading-none font-extrabold">{style.icon}</span>
|
|
{tag}
|
|
</span>
|
|
);
|
|
};
|
|
|
|
const MenuItemCard = ({ name, desc, tag, type, img, index }: MenuItemProps & { index: number }) => (
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true, margin: "-50px" }}
|
|
transition={{ duration: 0.5, delay: (index % 5) * 0.08, ease: "easeOut" }}
|
|
whileHover={{ y: -2, scale: 1.01 }}
|
|
className="group relative bg-[#fdfcf9] border border-[#d8c396]/45 rounded-none p-4 pl-22 pr-4 min-h-[96px] shadow-[0_4px_12px_rgba(10,74,43,0.03)] hover:shadow-[0_8px_20px_rgba(10,74,43,0.07)] hover:border-[#bc9e65] flex flex-col justify-center select-text overflow-visible"
|
|
>
|
|
{/* Inner decorative inset line */}
|
|
<div className="absolute inset-1.5 border border-[#d8c396]/20 pointer-events-none" />
|
|
|
|
{/* Classic inset corner notched borders using background-matching circular masks with hover support */}
|
|
<div className="absolute -top-[1px] -left-[1px] w-3.5 h-3.5 bg-[#fbfaf5] rounded-br-full border-r border-b border-[#d8c396]/45 group-hover:border-[#bc9e65] z-20 pointer-events-none transition-colors duration-300" />
|
|
<div className="absolute -top-[1px] -right-[1px] w-3.5 h-3.5 bg-[#fbfaf5] rounded-bl-full border-l border-b border-[#d8c396]/45 group-hover:border-[#bc9e65] z-20 pointer-events-none transition-colors duration-300" />
|
|
<div className="absolute -bottom-[1px] -left-[1px] w-3.5 h-3.5 bg-[#fbfaf5] rounded-tr-full border-r border-t border-[#d8c396]/45 group-hover:border-[#bc9e65] z-20 pointer-events-none transition-colors duration-300" />
|
|
<div className="absolute -bottom-[1px] -right-[1px] w-3.5 h-3.5 bg-[#fbfaf5] rounded-tl-full border-l border-t border-[#d8c396]/45 group-hover:border-[#bc9e65] z-20 pointer-events-none transition-colors duration-300" />
|
|
|
|
{/* Protruding traditional brass thali container */}
|
|
<div className="absolute -left-6 top-1/2 -translate-y-1/2 w-20 h-20 sm:w-[86px] sm:h-[86px] rounded-full p-1.5 bg-gradient-to-br from-[#bc9e65] via-[#fcfaf2] to-[#aa771c] shadow-lg flex-shrink-0 z-10 flex items-center justify-center">
|
|
{/* Inner Rim of the Plate */}
|
|
<div className="w-full h-full rounded-full p-[3px] bg-[#0c5030] relative overflow-hidden flex items-center justify-center">
|
|
{/* Green Banana Leaf Inner Liner */}
|
|
<div className="absolute inset-0 bg-gradient-to-br from-[#388e3c] to-[#1b5e20] opacity-95" />
|
|
|
|
{/* Food Image */}
|
|
<div className="w-full h-full rounded-full overflow-hidden relative z-10">
|
|
<Image
|
|
src={img}
|
|
alt={name}
|
|
fill
|
|
sizes="80px"
|
|
className="object-cover transition-transform duration-500 group-hover:scale-112"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Content Section */}
|
|
<div className="relative z-10 flex flex-col gap-1 w-full pl-2">
|
|
{/* Name and Pill Badge */}
|
|
<div className="flex items-start justify-between gap-3 w-full">
|
|
<h3 className="font-serif text-lg sm:text-[15.5px] font-bold text-[#0a4a2b] tracking-wider uppercase transition-colors duration-300 group-hover:text-[#bc9e65]">
|
|
{name}
|
|
</h3>
|
|
<CategoryPill tag={tag} type={type} />
|
|
</div>
|
|
|
|
{/* Description */}
|
|
<p className="font-sans text-base sm:text-base text-stone-550 leading-relaxed max-w-[95%]">
|
|
{desc}
|
|
</p>
|
|
</div>
|
|
</motion.div>
|
|
);
|
|
|
|
export default function MenuPreview() {
|
|
const sectionRef = useRef<HTMLDivElement>(null);
|
|
|
|
const leftColumnItems: MenuItemProps[] = [
|
|
{
|
|
name: "ONION RAVA DOSA",
|
|
desc: "Crispy semolina crepe with onions, herbs & spices.",
|
|
tag: "RAVA SPL",
|
|
type: "green",
|
|
img: "/images/masala_dosa_luxury.png"
|
|
},
|
|
{
|
|
name: "IDLI SAMBAR (2 PCS)",
|
|
desc: "Steamed fluffy rice & lentil cakes with hot sambar.",
|
|
tag: "TIFFIN SPL",
|
|
type: "gold",
|
|
img: "/images/my_dosa_place_food.png"
|
|
},
|
|
{
|
|
name: "MYSORE MASALA DOSA",
|
|
desc: "Rice crepe spread with spicy chutney & potato masala.",
|
|
tag: "CLASSIC",
|
|
type: "orange",
|
|
img: "/images/masala_dosa_luxury.png"
|
|
},
|
|
{
|
|
name: "RAVA MASALA DOSA",
|
|
desc: "Crispy semolina crepe filled with spiced potato masala.",
|
|
tag: "RAVA SPL",
|
|
type: "green",
|
|
img: "/images/masala_dosa_luxury.png"
|
|
},
|
|
{
|
|
name: "PURI BHAJI (3 PCS)",
|
|
desc: "Golden fluffy deep-fried puris with flavorful potato bhaji.",
|
|
tag: "TIFFIN SPL",
|
|
type: "gold",
|
|
img: "/images/royal_dining_experience.png"
|
|
}
|
|
];
|
|
|
|
const rightColumnItems: MenuItemProps[] = [
|
|
{
|
|
name: "MASALA DOSA",
|
|
desc: "Crispy thin rice & lentil crepe stuffed with potato masala.",
|
|
tag: "CLASSIC",
|
|
type: "orange",
|
|
img: "/images/masala_dosa_luxury.png"
|
|
},
|
|
{
|
|
name: "ONION RAVA MASALA DOSA",
|
|
desc: "Semolina crepe with onions and spiced potato filling.",
|
|
tag: "RAVA SPL",
|
|
type: "green",
|
|
img: "/images/masala_dosa_luxury.png"
|
|
},
|
|
{
|
|
name: "MEDU VADA (2 PCS)",
|
|
desc: "Deep fried crispy lentil donuts served with sambar & chutney.",
|
|
tag: "TIFFIN SPL",
|
|
type: "gold",
|
|
img: "/images/south_indian_thali_luxury.png"
|
|
},
|
|
{
|
|
name: "PAPER ROAST DOSA",
|
|
desc: "Extra large, paper-thin, crispy dosa served hot.",
|
|
tag: "CLASSIC",
|
|
type: "orange",
|
|
img: "/images/masala_dosa_luxury.png"
|
|
},
|
|
{
|
|
name: "RAVA PLAIN DOSA",
|
|
desc: "Crispy semolina crepe served with chutney & sambar.",
|
|
tag: "RAVA SPL",
|
|
type: "green",
|
|
img: "/images/masala_dosa_luxury.png"
|
|
}
|
|
];
|
|
|
|
return (
|
|
<section
|
|
ref={sectionRef}
|
|
id="menu"
|
|
className="relative min-h-screen py-24 md:py-32 px-6 sm:px-12 md:px-24 overflow-hidden select-none"
|
|
>
|
|
{/* Traditional Background Image containing pre-composed sketches, leaves, and brass pots */}
|
|
<Image
|
|
src="/images/home/menu/our-menu-bg.webp"
|
|
alt="Traditional South Indian Menu Background"
|
|
fill
|
|
priority
|
|
className="object-fill pointer-events-none select-none z-0"
|
|
/>
|
|
|
|
{/* Traditional Temple Borders */}
|
|
<div className="absolute top-0 left-0 w-full h-[6px] bg-gradient-to-r from-gold-dark via-gold-light to-gold-dark opacity-30 z-10" />
|
|
|
|
<div className="max-w-[1300px] mx-auto relative z-10">
|
|
|
|
{/* Header Elements */}
|
|
<div className="mb-14 flex flex-col items-center text-center">
|
|
<LotusOrnament />
|
|
|
|
<h2 className="font-serif text-4xl sm:text-5xl lg:text-6xl font-bold tracking-wider text-[#0a4a2b] uppercase">
|
|
Our Menu
|
|
</h2>
|
|
|
|
<TitleDivider />
|
|
|
|
<p className="font-sans text-sm sm:text-lg text-stone-700 max-w-2xl mt-4 leading-relaxed tracking-wider italic font-semibold">
|
|
Explore a wide variety of authentic South Indian vegetarian dishes,<br className="hidden sm:inline" />
|
|
crafted with traditional recipes and the finest ingredients.
|
|
</p>
|
|
|
|
<MiniOrnament />
|
|
</div>
|
|
|
|
{/* Menu Board Container */}
|
|
<div className="bg-[#fbfaf5]/95 border border-[#d8c396]/60 rounded-3xl p-6 sm:p-10 md:p-14 shadow-2xl relative backdrop-blur-xs">
|
|
|
|
{/* Inner border line overlay */}
|
|
<div className="absolute inset-2 border border-[#d8c396]/35 rounded-2xl pointer-events-none" />
|
|
|
|
{/* Corner decorative scrolls */}
|
|
<BoardCornerDecor position="tl" />
|
|
<BoardCornerDecor position="tr" />
|
|
<BoardCornerDecor position="bl" />
|
|
<BoardCornerDecor position="br" />
|
|
|
|
{/* Banner Badge - Dosa Specialties */}
|
|
<div className="flex justify-center mb-12 relative z-20">
|
|
<div className="relative inline-flex items-center justify-center select-none">
|
|
{/* Left Scroll */}
|
|
<svg className="w-8 h-4 text-[#bc9e65] mr-2 hidden sm:block" viewBox="0 0 30 15" fill="currentColor">
|
|
<path d="M 0,7.5 C 5,7.5 15,3 15,3 C 15,3 12,7.5 25,7.5 L 30,7.5 C 28,9 25,12 15,12 C 5,12 0,7.5 0,7.5 Z" />
|
|
</svg>
|
|
|
|
<div className="bg-[#0a4a2b] border border-[#d8c396]/80 px-8 py-2.5 rounded-full z-10 font-serif font-bold text-sm sm:text-base tracking-[0.25em] text-[#fcfaf2] uppercase shadow-lg flex items-center gap-3">
|
|
<span className="text-[#d8c396] text-sm opacity-75">✦</span>
|
|
Dosa Specialties
|
|
<span className="text-[#d8c396] text-sm opacity-75">✦</span>
|
|
</div>
|
|
|
|
{/* Right Scroll */}
|
|
<svg className="w-8 h-4 text-[#bc9e65] ml-2 hidden sm:block scale-x-[-1]" viewBox="0 0 30 15" fill="currentColor">
|
|
<path d="M 0,7.5 C 5,7.5 15,3 15,3 C 15,3 12,7.5 25,7.5 L 30,7.5 C 28,9 25,12 15,12 C 5,12 0,7.5 0,7.5 Z" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 2-Column Menu Layout grid */}
|
|
<div className="relative grid grid-cols-1 md:grid-cols-2 gap-x-14 gap-y-6 z-10 md:px-4">
|
|
|
|
{/* Vertical separator in the center (Desktop only) */}
|
|
<div className="hidden md:flex absolute left-1/2 top-4 bottom-4 w-[1px] flex-col items-center justify-between -translate-x-1/2 pointer-events-none z-15">
|
|
<div className="w-[1px] flex-1 border-l border-dashed border-[#d8c396]/55" />
|
|
<svg className="w-4 h-8 text-[#bc9e65] my-2 opacity-70" viewBox="0 0 20 40" fill="none" stroke="currentColor" strokeWidth="1.5">
|
|
<circle cx="10" cy="20" r="3" fill="currentColor" />
|
|
<path d="M 10,5 L 10,14" />
|
|
<path d="M 10,26 L 10,35" />
|
|
<path d="M 6,10 C 10,12 10,12 14,10" />
|
|
<path d="M 6,30 C 10,28 10,28 14,30" />
|
|
</svg>
|
|
<div className="w-[1px] flex-1 border-l border-dashed border-[#d8c396]/55" />
|
|
</div>
|
|
|
|
{/* Left Column Item Cards */}
|
|
<div className="flex flex-col gap-6 pl-2 pr-2 md:pl-4">
|
|
{leftColumnItems.map((item, index) => (
|
|
<MenuItemCard key={index} {...item} index={index} />
|
|
))}
|
|
</div>
|
|
|
|
{/* Right Column Item Cards */}
|
|
<div className="flex flex-col gap-6 pl-2 pr-2 md:pr-4">
|
|
{rightColumnItems.map((item, index) => (
|
|
<MenuItemCard key={index} {...item} index={index} />
|
|
))}
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{/* Bottom Section Core Pillars Feature Bar */}
|
|
<BottomFeatures />
|
|
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
const BottomFeatures = () => (
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-6 md:gap-0 mt-16 bg-[#faf8f2]/95 border border-[#d8c396]/45 rounded-2xl p-6 shadow-lg max-w-4xl mx-auto z-10 relative divide-y md:divide-y-0 md:divide-x divide-[#d8c396]/25 select-text">
|
|
{/* Feature 1 */}
|
|
<div className="flex items-center gap-3.5 justify-center px-4 py-3 md:py-0">
|
|
<div className="w-10 h-10 rounded-full bg-[#188754]/8 flex items-center justify-center text-[#bc9e65] flex-shrink-0">
|
|
<Image src="/images/home/menu/icons/menu-pure-veg.webp" alt="100% Vegetarian" width={24} height={24} className="object-contain" />
|
|
</div>
|
|
<div className="text-left">
|
|
<h5 className="font-sans text-base sm:text-base font-bold text-stone-850 tracking-wider uppercase">100% Vegetarian</h5>
|
|
<p className="font-sans text-sm sm:text-base text-stone-500 mt-0.5">Pure Veg. Good Food</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Feature 2 */}
|
|
<div className="flex items-center gap-3.5 justify-center px-4 py-3 md:py-0">
|
|
<div className="w-10 h-10 rounded-full bg-[#188754]/8 flex items-center justify-center text-[#bc9e65] flex-shrink-0">
|
|
<Image src="/images/home/menu/icons/menu-authentic.webp" alt="Authentic Recipes" width={24} height={24} className="object-contain" />
|
|
</div>
|
|
<div className="text-left">
|
|
<h5 className="font-sans text-base sm:text-base font-bold text-stone-850 tracking-wider uppercase">Authentic Recipes</h5>
|
|
<p className="font-sans text-sm sm:text-base text-stone-500 mt-0.5">Traditional Taste</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Feature 3 */}
|
|
<div className="flex items-center gap-3.5 justify-center px-4 py-3 md:py-0">
|
|
<div className="w-10 h-10 rounded-full bg-[#188754]/8 flex items-center justify-center text-[#bc9e65] flex-shrink-0">
|
|
<Image src="/images/home/menu/icons/menu-ingredients.webp" alt="Finest Ingredients" width={24} height={24} className="object-contain" />
|
|
</div>
|
|
<div className="text-left">
|
|
<h5 className="font-sans text-base sm:text-base font-bold text-stone-850 tracking-wider uppercase">Finest Ingredients</h5>
|
|
<p className="font-sans text-sm sm:text-base text-stone-500 mt-0.5">Always Fresh</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Feature 4 */}
|
|
<div className="flex items-center gap-3.5 justify-center px-4 py-3 md:py-0">
|
|
<div className="w-10 h-10 rounded-full bg-[#188754]/8 flex items-center justify-center text-[#bc9e65] flex-shrink-0">
|
|
<Image src="/images/home/menu/icons/menu-love.webp" alt="Made With Love" width={24} height={24} className="object-contain" />
|
|
</div>
|
|
<div className="text-left">
|
|
<h5 className="font-sans text-base sm:text-base font-bold text-stone-850 tracking-wider uppercase">Made With Love</h5>
|
|
<p className="font-sans text-sm sm:text-base text-stone-500 mt-0.5">For You</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|