inner pages updated

This commit is contained in:
Selvi 2026-07-16 21:32:16 +05:30
parent 857a840059
commit 6b6682a9a9
90 changed files with 1625 additions and 499 deletions

2
package-lock.json generated
View File

@ -1727,7 +1727,6 @@
"version": "19.2.17",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
"integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
"dev": true,
"license": "MIT",
"dependencies": {
"csstype": "^3.2.2"
@ -3017,7 +3016,6 @@
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
"dev": true,
"license": "MIT"
},
"node_modules/damerau-levenshtein": {

BIN
public/images/about.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

View File

@ -1,33 +1,331 @@
"use client";
import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import Image from "next/image";
import Link from "next/link";
import SubpageLayout from "@/components/SubpageLayout";
import RestaurantStory from "@/components/RestaurantStory";
import ChefShowcase from "@/components/ChefShowcase";
import InnerBanner from "@/components/InnerBanner";
import AnimatedSection from "@/components/AnimatedSection";
import TestimonialSlider from "@/components/TestimonialSlider";
/* ─── FAQ Data ─────────────────────────────────────── */
const faqs = [
{
q: "Do you offer vegan options?",
a: "Yes! We have a wide range of delicious vegan dishes made with the finest ingredients.",
},
{
q: "Where do you source your ingredients?",
a: "We partner with local and trusted suppliers to bring you the freshest, highest-quality South Indian ingredients every day.",
},
{
q: "Do you provide catering services?",
a: "Absolutely! We offer full catering for private events, corporate gatherings, weddings, and celebrations. Contact us to discuss your needs.",
},
{
q: "What are your opening hours?",
a: "MonThu: 4pm10pm · FriSun: 11am10pm",
},
];
/* ─── Values Data ───────────────────────────────────── */
const values = [
{
label: "Quality",
desc: "Every dish crafted with the finest ingredients.",
icon: (
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-10 h-10">
<path d="M24 4l5.5 11.2L42 17l-9 8.8 2.1 12.4L24 32.4 12.9 38.2 15 25.8 6 17l12.5-1.8z" />
</svg>
),
},
{
label: "Sustainability",
desc: "Our thinking practices support responsible.",
icon: (
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-10 h-10">
<path d="M24 6c0 0-14 8-14 20a14 14 0 0028 0C38 14 24 6 24 6z" />
<path d="M24 20v16M18 30l6-6 6 6" />
</svg>
),
},
{
label: "Passion",
desc: "Dedication and love poured into every recipe.",
icon: (
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-10 h-10">
<path d="M24 38s-14-8.5-14-18a8 8 0 0114-5.3A8 8 0 0138 20c0 9.5-14 18-14 18z" />
</svg>
),
},
{
label: "Community",
desc: "Building bonds and bringing people together.",
icon: (
<svg viewBox="0 0 48 48" fill="none" stroke="currentColor" strokeWidth="1.5" className="w-10 h-10">
<circle cx="18" cy="18" r="6" />
<circle cx="30" cy="18" r="6" />
<path d="M6 40c0-6.6 5.4-12 12-12h12c6.6 0 12 5.4 12 12" />
</svg>
),
},
];
/* ─── Page ──────────────────────────────────────────── */
export default function AboutPage() {
/* single controlled index — only 1 FAQ open at a time */
const [openFaq, setOpenFaq] = useState<number | null>(0);
return (
<SubpageLayout>
<div className="flex flex-col gap-2">
{/* Subpage Header Banner */}
<div className="text-center pt-12 pb-6 max-w-2xl mx-auto px-6 relative z-10 select-text">
<div className="flex items-center gap-3 justify-center mb-2">
<span className="text-[#bc9e65] text-xs"></span>
<span className="font-sans text-[10px] tracking-[0.3em] text-[#bc9e65] font-extrabold uppercase">
ABOUT OUR HOUSE
</span>
<span className="text-[#bc9e65] text-xs"></span>
</div>
<h1 className="font-serif text-3xl sm:text-4xl lg:text-[42px] font-bold text-white tracking-wider leading-tight uppercase">
Our Legacy & <span className="text-[#bc9e65]">Passion</span>
</h1>
<div className="w-24 h-[1px] bg-gradient-to-r from-transparent via-[#bc9e65] to-transparent mx-auto mt-4" />
{/* ── Inner Banner ── */}
<InnerBanner pageName="About" />
{/*
SECTION 1 Welcome (sandstone bg)
*/}
<div className="relative w-full">
<div className="absolute inset-0 z-0 pointer-events-none select-none">
<Image src="/images/story_bg.png" alt="" fill priority className="object-cover object-center" />
</div>
{/* Core sections */}
<RestaurantStory />
<ChefShowcase />
<div className="relative z-10 max-w-6xl mx-auto px-6 py-16 sm:py-20">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 lg:gap-16 items-center">
{/* Text */}
<AnimatedSection variant="fadeLeft" delay={0.1}>
<div className="select-text">
<p className="font-sans text-[11px] tracking-[0.3em] text-[#8a6c3a] uppercase font-bold mb-3">
Welcome to
</p>
<h1 className="font-serif text-4xl sm:text-5xl lg:text-[52px] text-[#1a3a25] leading-tight mb-6">
My Dosa Place
</h1>
<div className="w-16 h-[1.5px] bg-[#bc9e65] mb-6" />
<p className="font-sans text-[#4a3c28] text-sm sm:text-base leading-relaxed tracking-wide mb-4">
Nestled in the heart of Waterloo, My Dosa Place is a celebration of authentic South Indian cuisine where every dish tells a story rooted in tradition, love, and the finest ingredients.
</p>
<p className="font-sans text-[#4a3c28] text-sm sm:text-base leading-relaxed tracking-wide mb-4">
From our crispy, golden dosas to rich, aromatic curries, each recipe has been carefully crafted to honour the culinary heritage of South India. We believe that great food brings people together, and that every meal should be an experience to remember.
</p>
<p className="font-sans text-[#4a3c28] text-sm sm:text-base leading-relaxed tracking-wide mb-8">
Our doors are open to families, friends, and anyone seeking a warm and cozy dining experience, from the streets of Waterloo all the way to South Indian flavours.
</p>
<Link
href="/contact"
className="inline-flex items-center gap-2 px-8 py-3.5 bg-[#1a3a25] hover:bg-[#8a6c3a] text-white font-sans font-bold text-[10px] tracking-widest uppercase transition-all duration-300 shadow-md hover:shadow-lg rounded-sm mt-2"
>
Contact Us <span className="text-sm leading-none"></span>
</Link>
</div>
</AnimatedSection>
{/* Photo */}
<AnimatedSection variant="fadeRight" delay={0.2}>
<div className="relative flex justify-center lg:justify-end items-center">
<div className="relative shadow-2xl border-4 border-white/60 rounded-sm inline-flex">
<Image
src="/images/about.png"
alt="My Dosa Place exterior"
width={600}
height={800}
className="w-full h-auto object-contain max-w-[500px]"
/>
</div>
{/* <div className="absolute -bottom-4 -right-4 w-24 h-24 pointer-events-none opacity-60 select-none hidden lg:block">
<Image src="/images/menu_leaf_right.png" alt="" fill className="object-contain" />
</div> */}
</div>
</AnimatedSection>
</div>
</div>
</div>
{/*
SECTION 2 Our Values (dark green bg)
*/}
<div className="relative w-full bg-[#04120a]">
<div className="absolute inset-0 pointer-events-none select-none">
<Image src="/images/category_bg.jpg" alt="" fill className="object-cover object-center" />
</div>
<div className="absolute inset-0 bg-[#040d08]/70 pointer-events-none" />
<div className="relative z-10 max-w-6xl mx-auto px-6 py-20 sm:py-24 text-center">
<AnimatedSection variant="fadeUp" delay={0}>
<h2 className="font-serif text-3xl sm:text-[40px] text-[#e8dcb5] tracking-wider mb-20">
Our Values
</h2>
</AnimatedSection>
<div className="grid grid-cols-1 md:grid-cols-4 gap-8 sm:gap-0">
{values.map((v, i) => (
<AnimatedSection key={v.label} variant="fadeUp" delay={i * 0.12}>
<div
className={`flex flex-col items-center text-center group ${i !== values.length - 1 ? 'md:border-r border-[#bc9e65]/20' : ''
} px-4 sm:px-8`}
>
<div className="relative flex items-center justify-center mb-6">
{/* subtle glow behind icon */}
<div className="absolute inset-0 bg-[#163823] rounded-full blur-[20px] scale-[1.5] opacity-50 group-hover:opacity-80 transition-opacity duration-300"></div>
<div className="relative z-10 text-[#bc9e65] group-hover:scale-110 transition-transform duration-300">
{v.icon}
</div>
</div>
<h3 className="font-serif text-[#bc9e65] text-lg mb-3 tracking-wide">{v.label}</h3>
<p className="font-sans text-[#e8dcb5]/70 text-[11px] uppercase tracking-widest leading-[1.8]">{v.desc}</p>
</div>
</AnimatedSection>
))}
</div>
</div>
</div>
{/*
SECTION 2.5 Testimonials (sandstone bg)
*/}
<div className="relative w-full">
<div className="absolute inset-0 z-0 pointer-events-none select-none">
<Image src="/images/story_bg.png" alt="" fill className="object-cover object-center" />
</div>
<div className="absolute inset-0 bg-[#f5e9d0]/40 pointer-events-none" />
<div className="relative z-10 max-w-6xl mx-auto px-6 py-16 sm:py-20 text-center">
<AnimatedSection variant="fadeUp">
<p className="font-sans text-[11px] tracking-[0.3em] text-[#8a6c3a] uppercase font-bold mb-3">
Words of Love
</p>
<h2 className="font-serif text-3xl sm:text-4xl text-[#1a3a25] tracking-wider mb-3">
What Our Guests Say
</h2>
<div className="w-16 h-[1.5px] bg-[#bc9e65] mx-auto mb-14" />
</AnimatedSection>
<TestimonialSlider />
</div>
</div>
{/*
SECTION 3 FAQ (full-width split layout)
LEFT: dark green bg + accordion
RIGHT: interior photo full height
*/}
<div className="w-full flex flex-col lg:flex-row" style={{ minHeight: "420px" }}>
{/* ── LEFT: dark green panel ── */}
<div className="relative flex-1 bg-[#071a0e]">
{/* subtle bg texture */}
<div className="absolute inset-0 pointer-events-none">
<Image src="/images/category_bg.jpg" alt="" fill className="object-cover object-center" />
</div>
<div className="absolute inset-0 bg-[#050f08]/65 pointer-events-none" />
{/* gold border right edge only on desktop, bottom edge on mobile */}
<div className="absolute top-0 right-0 bottom-0 w-px bg-[#bc9e65]/30 hidden lg:block" />
<div className="relative z-10 px-8 sm:px-12 lg:px-16 py-12 lg:py-16">
<AnimatedSection variant="fadeLeft" delay={0.1}>
<h2 className="font-serif text-3xl sm:text-4xl text-white tracking-wide mb-8">
Frequently Asked Questions
</h2>
{/* FAQ accordion */}
<div className="space-y-2">
{faqs.map((f, i) => {
const isOpen = openFaq === i;
return (
<div
key={i}
className={`border border-[#bc9e65]/25 cursor-pointer transition-colors duration-300 rounded-sm overflow-hidden ${isOpen ? "bg-[#0a2012]" : "bg-[#091810] hover:bg-[#0c2016]"
}`}
onClick={() => setOpenFaq(isOpen ? null : i)}
>
{/* question row */}
<div className="flex items-center justify-between px-5 py-4 gap-4">
<span className={`font-sans text-sm tracking-wide transition-colors duration-300 ${isOpen ? "text-white" : "text-stone-300"
}`}>
{f.q}
</span>
<motion.span
animate={{ rotate: isOpen ? 45 : 0 }}
transition={{ duration: 0.25, ease: "easeInOut" }}
className="text-[#bc9e65] text-2xl leading-none shrink-0 font-light select-none"
>
+
</motion.span>
</div>
{/* answer — smooth height animation */}
<AnimatePresence initial={false}>
{isOpen && (
<motion.div
key="answer"
initial={{ height: 0, opacity: 0 }}
animate={{ height: "auto", opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.35, ease: [0.25, 0.1, 0.25, 1] }}
style={{ overflow: "hidden" }}
>
<p className="font-sans text-stone-300 text-sm leading-relaxed px-5 pb-5 tracking-wide">
{f.a}
</p>
</motion.div>
)}
</AnimatePresence>
</div>
);
})}
</div>
</AnimatedSection>
</div>
</div>
{/* ── RIGHT: photo full height ── */}
<div className="relative w-full lg:w-[42%] min-h-[280px] lg:min-h-0">
<Image
src="/images/my_dosa_place_interior.png"
alt="My Dosa Place interior"
fill
className="object-cover object-center"
/>
{/* warm dark fade on the left edge blending into green panel */}
<div className="absolute inset-0 bg-gradient-to-r from-[#050f08]/50 via-transparent to-transparent" />
</div>
</div>
{/*
SECTION 4 CTA (sandstone bg)
*/}
<div className="relative w-full">
<div className="absolute inset-0 z-0 pointer-events-none select-none">
<Image src="/images/menu_bg_traditional.png" alt="" fill className="object-cover object-center" />
</div>
<div className="absolute inset-0 bg-[#f5e9d0]/30 pointer-events-none" />
<div className="relative z-10 max-w-3xl mx-auto px-6 py-20 sm:py-24 text-center">
<AnimatedSection variant="scaleUp" delay={0}>
<p className="font-sans text-[11px] tracking-[0.3em] text-[#8a6c3a] uppercase font-bold mb-4">
Come Dine With Us
</p>
<h2 className="font-serif text-3xl sm:text-4xl lg:text-5xl text-[#1a3a25] tracking-wide leading-tight mb-4">
Experience the Taste of Tradition
</h2>
<div className="w-16 h-[1.5px] bg-[#bc9e65] mx-auto mb-6" />
<p className="font-sans text-[#4a3c28] text-sm sm:text-base leading-relaxed tracking-wide mb-10 max-w-xl mx-auto">
Visit us or order online and let every bite take you on a journey of authentic South Indian flavors.
</p>
<Link
href="/reservation"
className="inline-flex items-center gap-3 px-10 py-4 bg-[#1a3a25] hover:bg-[#0c2419] text-[#bc9e65] font-sans font-bold text-sm tracking-widest uppercase transition-all duration-300 shadow-lg hover:shadow-xl rounded-sm"
>
Reserve a Table
</Link>
</AnimatedSection>
</div>
</div>
</SubpageLayout>
);
}

View File

@ -0,0 +1,58 @@
import { fallbackGoogleReviews } from '@/lib/reviewUtils';
export const dynamic = 'force-static';
const SERPAPI_URL = 'https://serpapi.com/search.json?engine=google_maps_reviews&hl=en';
async function fetchGoogleReviews(apiKey, placeId) {
if (!apiKey || !placeId) {
throw new Error('Missing SERPAPI_KEY or SERPAPI_PLACE_ID');
}
const url = `${SERPAPI_URL}&api_key=${encodeURIComponent(apiKey)}&place_id=${encodeURIComponent(placeId)}`;
const response = await fetch(url);
if (!response.ok) {
const body = await response.text().catch(() => '');
throw new Error(`SerpAPI request failed ${response.status} ${response.statusText}: ${body}`);
}
const data = await response.json();
if (data.error) {
throw new Error(data.error.message || data.error);
}
if (!Array.isArray(data.reviews)) {
throw new Error('SerpAPI returned no reviews array');
}
return data.reviews;
}
export async function GET() {
const apiKey = process.env.SERPAPI_KEY;
const placeId = process.env.SERPAPI_PLACE_ID;
try {
const reviews = await fetchGoogleReviews(apiKey, placeId);
return new Response(JSON.stringify({ reviews, total: reviews.length }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
console.error('Reviews API error:', error);
return new Response(
JSON.stringify({
reviews: fallbackGoogleReviews,
total: fallbackGoogleReviews.length,
fallback: true,
error: error.message,
}),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
}
);
}
}

View File

@ -0,0 +1,234 @@
import Image from "next/image";
import Link from "next/link";
import { notFound } from "next/navigation";
import SubpageLayout from "@/components/SubpageLayout";
import { BLOG_POSTS } from "@/utils/blogData";
import InnerBanner from "@/components/InnerBanner";
import AnimatedSection from "@/components/AnimatedSection";
export function generateStaticParams() {
return BLOG_POSTS.map((post) => ({
slug: post.slug,
}));
}
export default async function BlogPostPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const post = BLOG_POSTS.find((p) => p.slug === slug);
if (!post) {
notFound();
}
// Split content into paragraphs for custom structural rendering
const paragraphs = post.content.split('\n\n').filter(p => p.trim() !== '');
const firstParagraph = paragraphs[0] || "";
const remainingParagraphs = paragraphs.slice(1) || [];
return (
<SubpageLayout>
{/* Inner Banner */}
<InnerBanner pageName="Blog Details" />
<div className="w-full bg-[#fbfaf4] relative z-10">
<div className="max-w-7xl mx-auto px-6 py-12 lg:py-20 flex flex-col lg:flex-row gap-12">
{/* ── MAIN CONTENT (Left) ── */}
<div className="flex-1 lg:max-w-[800px] w-full">
{/* Big Featured Image */}
<AnimatedSection variant="scaleUp" delay={0}>
<div className="relative w-full h-[500px] rounded-2xl overflow-hidden shadow-lg mb-10 border border-[#e8e0ce]">
<Image
src={post.image}
alt={post.title}
fill
priority
className="object-cover"
/>
</div>
</AnimatedSection>
{/* Post Header / Meta */}
<AnimatedSection variant="fadeUp" delay={0.15}>
<div className="mb-8">
<div className="flex items-center gap-3 font-sans text-[11px] tracking-widest text-[#8a6c3a] uppercase font-bold mb-4">
<span>{post.date}</span>
<span className="w-1.5 h-1.5 rounded-full bg-[#bc9e65]" />
<span>BY {post.author}</span>
</div>
<h1 className="font-serif text-3xl sm:text-4xl lg:text-[44px] font-bold text-[#1a3a25] tracking-wide leading-tight mb-6">
{post.title}
</h1>
</div>
</AnimatedSection>
{/* Content Body */}
<AnimatedSection variant="fadeUp" delay={0.25}>
<div className="prose prose-stone max-w-none prose-p:font-sans prose-p:text-stone-700 prose-p:leading-[1.8] prose-p:text-[15px] prose-p:mb-6">
{/* First Paragraph */}
<p className="text-lg text-stone-800 leading-relaxed font-medium">
{firstParagraph}
</p>
{/* Blockquote using theme style */}
<blockquote className="my-10 relative bg-[#f5efe0] border-l-4 border-[#1a3a25] px-8 py-6 rounded-r-xl shadow-sm">
<svg className="absolute top-4 left-4 w-8 h-8 text-[#bc9e65]/20 transform -translate-x-2 -translate-y-2" fill="currentColor" viewBox="0 0 32 32">
<path d="M10 8c-3.3 0-6 2.7-6 6v10h10V14H8c0-1.1.9-2 2-2h4V8h-4zm14 0c-3.3 0-6 2.7-6 6v10h10V14h-6c0-1.1.9-2 2-2h4V8h-4z"/>
</svg>
<p className="font-serif text-xl sm:text-2xl italic text-[#1a3a25] leading-snug relative z-10 m-0">
"Tradition is not the worship of ashes, but the preservation of fire. Our recipes are a testament to this philosophy."
</p>
</blockquote>
{/* Remaining Paragraphs */}
{remainingParagraphs.map((p, idx) => (
<p key={idx}>{p}</p>
))}
{/* List with related icons */}
<h3 className="font-serif text-2xl text-[#1a3a25] mt-12 mb-6 font-bold">Key Elements of Our Heritage</h3>
<ul className="space-y-4 mb-10 pl-0">
<li className="flex items-start gap-4">
<div className="mt-1 flex-shrink-0 w-8 h-8 rounded-full bg-[#f5efe0] flex items-center justify-center text-[#8a6c3a] shadow-sm border border-[#e8e0ce]">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z"/></svg>
</div>
<div>
<strong className="block text-[#1a3a25] font-sans font-bold">Authentic Spices</strong>
<span className="text-stone-600 font-sans text-sm">Sourced directly from the lush hills of Kerala, ensuring unmatched aroma and flavor.</span>
</div>
</li>
<li className="flex items-start gap-4">
<div className="mt-1 flex-shrink-0 w-8 h-8 rounded-full bg-[#f5efe0] flex items-center justify-center text-[#8a6c3a] shadow-sm border border-[#e8e0ce]">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
</div>
<div>
<strong className="block text-[#1a3a25] font-sans font-bold">Time-Honored Techniques</strong>
<span className="text-stone-600 font-sans text-sm">Slow-cooking processes that have been passed down through generations.</span>
</div>
</li>
<li className="flex items-start gap-4">
<div className="mt-1 flex-shrink-0 w-8 h-8 rounded-full bg-[#f5efe0] flex items-center justify-center text-[#8a6c3a] shadow-sm border border-[#e8e0ce]">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/></svg>
</div>
<div>
<strong className="block text-[#1a3a25] font-sans font-bold">Cooked with Love</strong>
<span className="text-stone-600 font-sans text-sm">Every dish is prepared with the same care and devotion as a home-cooked meal.</span>
</div>
</li>
</ul>
{/* 2 Images per row */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6 my-12">
<div className="relative w-full aspect-[4/3] rounded-xl overflow-hidden shadow-md">
<Image src="/images/chettinad_interior.png" alt="Kitchen Prep" fill className="object-cover" />
</div>
<div className="relative w-full aspect-[4/3] rounded-xl overflow-hidden shadow-md">
<Image src="/images/chef_cooking.png" alt="Chef Cooking" fill className="object-cover object-top" />
</div>
</div>
{/* Title, Paragraph and FAQ */}
<h3 className="font-serif text-3xl text-[#1a3a25] mt-12 mb-4 font-bold">Common Inquiries</h3>
<p className="mb-8">
We often receive questions about our traditional cooking methods and ingredient sourcing. Here are some of the most frequently asked questions from our guests who want to dive deeper into our culinary heritage.
</p>
<div className="space-y-4 mb-16">
{[
{ q: "Do you use artificial colors in your curries?", a: "Never. The vibrant colors of our dishes come purely from natural ingredients like turmeric, Kashmiri chili, and fresh herbs." },
{ q: "Is your dosa batter gluten-free?", a: "Yes, our traditional dosa batter is made entirely from rice and lentils, making it naturally gluten-free." },
{ q: "How spicy is the authentic Chettinad preparation?", a: "It carries a robust, earthy heat from black pepper and dry red chilies. However, we can adjust the spice level to accommodate your palate upon request." }
].map((faq, idx) => (
<div key={idx} className="bg-white border border-[#e8e0ce] p-6 rounded-xl shadow-sm">
<h4 className="font-sans font-bold text-[#1a3a25] text-[15px] mb-2 flex items-start gap-2">
<span className="text-[#8a6c3a]">Q.</span> {faq.q}
</h4>
<p className="font-sans text-stone-600 text-sm m-0 pl-6">
{faq.a}
</p>
</div>
))}
</div>
{/* Back to page button */}
<div className="border-t border-[#e8e0ce] pt-10 mt-10 text-center sm:text-left">
<Link
href="/blog"
className="inline-flex items-center justify-center gap-3 bg-[#1a3a25] hover:bg-[#8a6c3a] text-white px-8 py-4 rounded-full font-sans text-xs font-bold tracking-widest uppercase transition-all duration-300 shadow-md hover:shadow-lg"
>
<span className="text-[14px]"></span> Back to Blogs
</Link>
</div>
</div>
</AnimatedSection>
</div>
{/* ── RIGHT SIDEBAR ── */}
<AnimatedSection variant="fadeRight" delay={0.3} className="w-full lg:w-[350px] shrink-0">
<div className="w-full lg:w-[350px] shrink-0">
<div className="sticky top-24 bg-[#f5efe0] rounded-2xl p-6 lg:p-8 border border-[#e8e0ce] shadow-sm">
<h4 className="font-serif text-2xl text-[#1a3a25] font-bold mb-6 flex items-center gap-3">
<span className="w-8 h-[2px] bg-[#bc9e65]" />
Related Posts
</h4>
<div className="flex flex-col gap-6">
{BLOG_POSTS.filter(p => p.id !== post.id).slice(0, 3).map(related => (
<Link key={related.id} href={`/blog/${related.slug}`} className="group flex flex-col gap-3">
<div className="relative w-full aspect-video rounded-xl overflow-hidden shadow-sm">
<Image
src={related.image}
alt={related.title}
fill
className="object-cover group-hover:scale-105 transition-transform duration-700"
/>
</div>
<div>
<div className="text-[10px] text-[#8a6c3a] font-bold tracking-widest uppercase mb-1 font-sans">
{related.date}
</div>
<h5 className="font-serif text-[15px] leading-snug font-bold text-[#1a3a25] group-hover:text-[#bc9e65] transition-colors">
{related.title}
</h5>
</div>
</Link>
))}
</div>
{/* Contact CTA Banner */}
<div className="mt-10 relative rounded-xl overflow-hidden shadow-lg border border-[#bc9e65]/30 bg-[#272f27] min-h-[240px] flex flex-col items-center justify-center text-center p-8">
{/* Content */}
<div className="relative z-10 flex flex-col items-center gap-4">
{/* Gold icon */}
<div className="w-12 h-12 rounded-full border border-[#bc9e65]/60 flex items-center justify-center text-[#bc9e65] mb-1">
<svg className="w-6 h-6" fill="none" stroke="currentColor" strokeWidth="1.5" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 002.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 01-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 00-1.091-.852H4.5A2.25 2.25 0 002.25 4.5v2.25z" />
</svg>
</div>
<h5 className="font-serif text-xl text-white tracking-wide leading-tight">
Reserve a Table
</h5>
<p className="font-sans text-stone-300 text-xs leading-relaxed max-w-[200px]">
Ready to experience authentic South Indian flavors? Visit us or get in touch.
</p>
<Link
href="/reservation"
className="mt-2 inline-flex items-center gap-2 bg-[#bc9e65] hover:bg-white text-[#061810] font-bold text-[10px] tracking-widest uppercase px-6 py-3 rounded-md transition-all duration-300 shadow-md hover:shadow-lg"
>
Reserve your table <span className="text-sm leading-none"></span>
</Link>
</div>
</div>
</div>
</div>
</AnimatedSection>
</div>
</div>
</SubpageLayout>
);
}

View File

@ -1,7 +1,11 @@
"use client";
import Image from "next/image";
import Link from "next/link";
import SubpageLayout from "@/components/SubpageLayout";
import { BLOG_POSTS } from "@/utils/blogData";
import InnerBanner from "@/components/InnerBanner";
import AnimatedSection from "@/components/AnimatedSection";
const CornerOrnaments = () => (
<>
@ -20,115 +24,78 @@ const CornerOrnaments = () => (
</>
);
const BLOG_POSTS = [
{
id: 1,
title: "The Art of Fermenting Dosa Batter: A 24-Hour Ritual",
desc: "Discover the traditional science and family secrets behind cultivating the perfect sourness and crispiness for our signature stone-ground dosas.",
date: "JULY 15, 2026",
image: "/images/masala_dosa_luxury.png",
author: "Chef Sundaram Iyer",
},
{
id: 2,
title: "Secret Spices of Chettinad Cookery",
desc: "Unveiling the delicate proportions of kalpasi (stone flower), star anise, and freshly crushed peppercorns that define our royal spice blends.",
date: "JUNE 28, 2026",
image: "/images/category_curries.jpg",
author: "My Dosa Place Culinary Team",
},
{
id: 3,
title: "Why Brass Cookware Remains King in Heritage Dining",
desc: "How slow-heating copper and brass vessels preserve the vital nutrients and aroma of our house-cooked lentil sambar and vegetable poriyals.",
date: "MAY 12, 2026",
image: "/images/south_indian_thali_luxury.png",
author: "Heritage Preservation Society",
},
];
export default function BlogPage() {
return (
<SubpageLayout>
{/* Background elements */}
<div className="absolute inset-0 z-0 pointer-events-none select-none opacity-40">
<Image
src="/images/category_bg.jpg"
alt="Backdrop"
fill
priority
className="object-cover object-center"
/>
</div>
<InnerBanner pageName="Blog" />
<div className="max-w-5xl mx-auto px-6 py-12 relative z-10">
{/* Subpage Header Banner */}
<div className="text-center pb-14 max-w-2xl mx-auto select-text">
<div className="flex items-center gap-3 justify-center mb-2">
<span className="text-[#bc9e65] text-xs"></span>
<span className="font-sans text-[10px] tracking-[0.3em] text-[#bc9e65] font-extrabold uppercase">
CULINARY CHRONICLES
</span>
<span className="text-[#bc9e65] text-xs"></span>
</div>
<h1 className="font-serif text-3xl sm:text-4xl lg:text-[42px] font-bold text-white tracking-wider leading-tight uppercase">
Spices & <span className="text-[#bc9e65]">Stories</span>
</h1>
<div className="w-24 h-[1px] bg-gradient-to-r from-transparent via-[#bc9e65] to-transparent mx-auto mt-4" />
<div className="w-full bg-[#f5efe0] relative z-10">
{/* Subtle background texture */}
<div className="absolute inset-0 pointer-events-none select-none">
<Image src="/images/story_bg.png" alt="" fill className="object-cover" />
</div>
{/* Blog Posts Grid */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 w-full">
{BLOG_POSTS.map((post) => (
<div className="max-w-5xl mx-auto px-6 py-12 lg:py-20 relative z-10">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 w-full max-w-7xl mx-auto">
{BLOG_POSTS.map((post, index) => (
<AnimatedSection key={post.id} variant="fadeUp" delay={index * 0.1}>
<div
key={post.id}
className="relative bg-gradient-to-br from-[#0c2419]/90 via-[#06120c]/95 to-[#040b07]/98 border border-[#bc9e65]/40 p-5 rounded-none shadow-2xl flex flex-col group overflow-visible transition-all duration-300 hover:-translate-y-1"
className="relative bg-[#fbfaf4] rounded-xl border border-[#e8e0ce] flex flex-col group overflow-hidden shadow-sm hover:shadow-xl transition-all duration-300 hover:-translate-y-1"
>
{/* Corner leaves and border outline */}
<div className="absolute inset-1.5 border border-[#bc9e65]/15 pointer-events-none" />
<CornerOrnaments />
{/* Image Frame */}
<div className="relative w-full aspect-[4/3] border border-[#bc9e65]/35 overflow-hidden mb-4 bg-[#06120c] shadow-md z-10"
style={{
clipPath: "polygon(50% 0%, 100% 20%, 100% 100%, 0% 100%, 0% 20%)"
}}
>
{/* Image Container with fade out */}
<div className="relative w-full aspect-[4/3] overflow-hidden border-b-1 border-[#0a4a2b]">
<Image
src={post.image}
alt={post.title}
fill
sizes="(max-width: 768px) 100vw, 30vw"
className="object-cover group-hover:scale-105 transition-transform duration-[1.5s]"
className="object-cover group-hover:scale-105 transition-transform duration-700"
/>
{/* Gradient fade to match background */}
<div className="absolute bottom-0 left-0 right-0 h-32 bg-gradient-to-t from-[#fbfaf4] via-[#fbfaf4]50 to-transparent z-10 pointer-events-none" />
{/* Floating Tag */}
<div className="absolute bottom-4 left-5 z-20 bg-[#0a4a2b] rounded-md px-3 py-1.5 shadow-md">
<span className="font-sans text-[10px] font-extrabold tracking-widest text-[#bc9e65] uppercase">
{post.id === 1 ? "Recipes" : post.id === 2 ? "Ingredients" : "Behind The Scenes"}
</span>
</div>
</div>
{/* Meta */}
<div className="flex items-center justify-between font-sans text-[9px] tracking-wider text-[#bc9e65] uppercase font-bold mb-2 z-10">
<span>{post.date}</span>
<span>BY {post.author}</span>
{/* Card Body */}
<div className="flex flex-col flex-1 p-5 pt-3 relative z-10">
<Link href={`/blog/${post.slug}`} className="mb-3 block">
<h3 className="font-serif text-[22px] leading-tight font-medium text-[#1a3a25] transition-colors duration-300 hover:text-[#8a6c3a] line-clamp-2">
{post.title}
</h3>
</Link>
<p className="font-sans text-stone-600 text-[13px] leading-relaxed mb-6 flex-1">
{post.desc}
</p>
{/* Footer Row */}
<div className="flex items-center text-stone-500 font-sans text-[11px] mt-auto">
<span className="flex-shrink-0">
{post.date} {Math.max(2, Math.ceil(post.content.length / 400))} min read
</span>
{/* Expanding line */}
<div className="flex-1 h-[1px] bg-[#d8c396]/60 mx-3" />
<Link
href={`/blog/${post.slug}`}
className="flex-shrink-0 text-[#0a4a2b] hover:text-[#bc9e65] transition-colors flex items-center gap-1 group/btn font-bold text-[13px]"
>
Read More <span className="transition-transform group-hover/btn:translate-x-1 text-lg leading-none"></span>
</Link>
</div>
</div>
{/* Details */}
<h3 className="font-serif text-sm lg:text-[15px] font-bold text-white tracking-wider uppercase mb-2 group-hover:text-[#bc9e65] transition-colors duration-300 z-10 min-h-[44px]">
{post.title}
</h3>
<p className="font-sans text-stone-300 text-[11px] leading-relaxed tracking-wider mb-6 flex-1 z-10">
{post.desc}
</p>
{/* Read button */}
<button
className="clickable self-start font-sans font-bold text-[9px] tracking-[0.2em] text-[#bc9e65] uppercase hover:text-white transition-colors duration-300 z-10 flex items-center gap-1.5"
onClick={() => alert(`Enjoying "${post.title}"? Full recipe chronicles coming soon to Waterloo!`)}
>
READ MORE <span className="text-[10px] group-hover:translate-x-1 transition-transform duration-300"></span>
</button>
</div>
</AnimatedSection>
))}
</div>
</div>
</div>
</SubpageLayout>
);

View File

@ -2,7 +2,10 @@
import { useState } from "react";
import Image from "next/image";
import { Phone, Mail, MapPin, Clock, UtensilsCrossed, ShoppingBag, Truck, ChefHat } from "lucide-react";
import SubpageLayout from "@/components/SubpageLayout";
import InnerBanner from "@/components/InnerBanner";
import AnimatedSection from "@/components/AnimatedSection";
const CornerOrnaments = () => (
<>
@ -22,7 +25,7 @@ const CornerOrnaments = () => (
);
export default function ContactPage() {
const [formData, setFormData] = useState({ name: "", email: "", msg: "" });
const [formData, setFormData] = useState({ name: "", email: "", phone: "", subject: "", msg: "" });
const [submitted, setSubmitted] = useState(false);
const handleSubmit = (e: React.FormEvent) => {
@ -31,177 +34,274 @@ export default function ContactPage() {
setSubmitted(true);
setTimeout(() => {
setSubmitted(false);
setFormData({ name: "", email: "", msg: "" });
setFormData({ name: "", email: "", phone: "", subject: "", msg: "" });
}, 5000);
}
};
return (
<SubpageLayout>
<div className="absolute inset-0 z-0 pointer-events-none select-none opacity-40">
<Image
src="/images/category_bg.jpg"
alt="Backdrop"
fill
priority
className="object-cover object-center"
/>
</div>
<div className="max-w-5xl mx-auto px-6 py-12 relative z-10">
{/* ── Inner Banner ── */}
<InnerBanner pageName="Contact" />
{/* Header */}
<div className="text-center pb-12 max-w-2xl mx-auto select-text">
<div className="flex items-center gap-3 justify-center mb-2">
<span className="text-[#bc9e65] text-xs"></span>
<span className="font-sans text-[10px] tracking-[0.3em] text-[#bc9e65] font-extrabold uppercase">
GET IN TOUCH
</span>
<span className="text-[#bc9e65] text-xs"></span>
</div>
<h1 className="font-serif text-3xl sm:text-4xl lg:text-[42px] font-bold text-white tracking-wider leading-tight uppercase">
Connect With <span className="text-[#bc9e65]">Us</span>
</h1>
<div className="w-24 h-[1px] bg-gradient-to-r from-transparent via-[#bc9e65] to-transparent mx-auto mt-4" />
{/* ── TOP SECTION: Sandstone bg — Info + Form ── */}
<div className="relative w-full">
{/* Sandstone bg image */}
<div className="absolute inset-0 z-0 pointer-events-none select-none">
<Image
src="/images/story_bg.png"
alt="Background"
fill
priority
className="object-cover object-center"
/>
</div>
{/* 2-Column Info & Form */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 items-stretch mt-4">
<div className="relative z-10 max-w-6xl mx-auto px-6 py-16">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 lg:gap-20 items-start">
{/* Column 1: Info */}
<div className="relative bg-gradient-to-br from-[#0c2419]/90 via-[#06120c]/95 to-[#040b07]/98 border border-[#bc9e65]/40 p-8 flex flex-col justify-between group overflow-visible shadow-2xl">
<div className="absolute inset-1.5 border border-[#bc9e65]/15 pointer-events-none" />
<CornerOrnaments />
{/* Left Column: Info */}
<AnimatedSection variant="fadeLeft" delay={0.1}>
<div className="select-text pt-4">
<h2 className="font-serif text-3xl sm:text-4xl text-[#1a3a25] tracking-wider mb-10">
Get in Touch
</h2>
<div className="select-text relative z-10">
<h3 className="font-serif text-lg font-bold text-white tracking-wider uppercase mb-4">
THE DINING COURT
</h3>
<div className="space-y-6">
<div>
<h4 className="font-sans text-[10px] sm:text-[11px] tracking-widest text-[#bc9e65] uppercase font-bold mb-1">
OUR HAVEN
</h4>
<p className="font-sans text-stone-300 text-xs leading-relaxed tracking-wider">
123 Erb Street West,<br />
Waterloo, ON N2L 1T4
</p>
<div className="space-y-8">
{/* Phone */}
<div className="flex items-start gap-5 group">
<div className="w-12 h-12 rounded-full bg-[#0c2419]/10 border border-[#0c2419]/30 flex items-center justify-center text-[#1a3a25] group-hover:bg-[#0c2419] group-hover:text-[#bc9e65] transition-colors duration-300 shadow-sm shrink-0">
<Phone strokeWidth={1.5} className="w-5 h-5" />
</div>
<div className="pt-1">
<h4 className="font-serif text-[#1a3a25] text-base tracking-wide font-medium mb-1">Phone</h4>
<p className="font-sans text-[#3a2e1e] text-sm tracking-wider">+1 (519) 888-7459</p>
</div>
</div>
<div>
<h4 className="font-sans text-[10px] sm:text-[11px] tracking-widest text-[#bc9e65] uppercase font-bold mb-1">
HEAR OUR VOICE
</h4>
<p className="font-sans text-stone-300 text-xs leading-relaxed tracking-wider">
Direct Line: (519) 555-0199<br />
Royal Inquiries: concierge@mydosaplace.ca
</p>
{/* Email */}
<div className="flex items-start gap-5 group">
<div className="w-12 h-12 rounded-full bg-[#0c2419]/10 border border-[#0c2419]/30 flex items-center justify-center text-[#1a3a25] group-hover:bg-[#0c2419] group-hover:text-[#bc9e65] transition-colors duration-300 shadow-sm shrink-0">
<Mail strokeWidth={1.5} className="w-5 h-5" />
</div>
<div className="pt-1">
<h4 className="font-serif text-[#1a3a25] text-base tracking-wide font-medium mb-1">Email</h4>
<p className="font-sans text-[#3a2e1e] text-sm tracking-wider">mydosaplacewaterloo@gmail.com</p>
</div>
</div>
<div>
<h4 className="font-sans text-[10px] sm:text-[11px] tracking-widest text-[#bc9e65] uppercase font-bold mb-1">
TIMINGS OF THE COURT
</h4>
<p className="font-sans text-stone-300 text-xs leading-relaxed tracking-wider">
Lunch Service: 11:30 AM 3:00 PM<br />
Dinner Service: 5:30 PM 10:30 PM<br />
<span className="text-[#bc9e65] font-semibold mt-1 block">Closed on Tuesdays for spice curing.</span>
</p>
{/* Location */}
<div className="flex items-start gap-5 group">
<div className="w-12 h-12 rounded-full bg-[#0c2419]/10 border border-[#0c2419]/30 flex items-center justify-center text-[#1a3a25] group-hover:bg-[#0c2419] group-hover:text-[#bc9e65] transition-colors duration-300 shadow-sm shrink-0">
<MapPin strokeWidth={1.5} className="w-5 h-5" />
</div>
<div className="pt-1">
<h4 className="font-serif text-[#1a3a25] text-base tracking-wide font-medium mb-1">Location</h4>
<p className="font-sans text-[#3a2e1e] text-sm tracking-wider leading-relaxed uppercase">
922 Erb St. W Unit C3#3,<br />
Waterloo, ON N2T 0C9,<br />
Canada
</p>
</div>
</div>
{/* Opening Hours */}
<div className="flex items-start gap-5 group">
<div className="w-12 h-12 rounded-full bg-[#0c2419]/10 border border-[#0c2419]/30 flex items-center justify-center text-[#1a3a25] group-hover:bg-[#0c2419] group-hover:text-[#bc9e65] transition-colors duration-300 shadow-sm shrink-0">
<Clock strokeWidth={1.5} className="w-5 h-5" />
</div>
<div className="pt-1">
<h4 className="font-serif text-[#1a3a25] text-base tracking-wide font-medium mb-1">Opening Hours</h4>
<p className="font-sans text-[#3a2e1e] text-sm tracking-wider leading-relaxed">
Mon - Thu: 4pm10pm<br />
Fri - Sun: 11am10pm
</p>
</div>
</div>
</div>
</div>
</AnimatedSection>
{/* Banner bottom */}
<div className="border-t border-[#bc9e65]/20 pt-6 mt-8 relative z-10">
<span className="font-serif text-[10px] tracking-[0.2em] text-[#bc9e65]/80 uppercase block text-center">
HOSPITALITY SERVED WITH SOUL
</span>
</div>
</div>
{/* Right Column: Form — Dark green theme card */}
<AnimatedSection variant="fadeRight" delay={0.2}>
<div className="relative bg-gradient-to-br from-[#0c2419]/95 via-[#06120c]/98 to-[#040b07] border border-[#bc9e65]/40 p-8 sm:p-10 group overflow-visible shadow-2xl">
<div className="absolute inset-1.5 border border-[#bc9e65]/15 pointer-events-none" />
<CornerOrnaments />
{/* Column 2: Form */}
<div className="relative bg-gradient-to-br from-[#0c2419]/90 via-[#06120c]/95 to-[#040b07]/98 border border-[#bc9e65]/40 p-8 group overflow-visible shadow-2xl">
<div className="absolute inset-1.5 border border-[#bc9e65]/15 pointer-events-none" />
<CornerOrnaments />
<div className="relative z-10 h-full flex flex-col justify-between">
<div>
<h3 className="font-serif text-lg font-bold text-white tracking-wider uppercase mb-5">
WRITE A NOTE
</h3>
<div className="relative z-10">
<h3 className="font-serif text-2xl text-[#bc9e65] mb-8">Send Us a Message</h3>
{submitted ? (
<div className="flex flex-col items-center justify-center py-10 text-center animate-pulse">
<svg className="w-10 h-10 text-[#bc9e65] mb-4" viewBox="0 0 24 24" fill="currentColor">
<div className="flex flex-col items-center justify-center py-12 text-center animate-pulse min-h-[350px]">
<svg className="w-12 h-12 text-[#bc9e65] mb-4" viewBox="0 0 24 24" fill="currentColor">
<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z" />
</svg>
<h4 className="font-serif text-white tracking-wider uppercase text-sm mb-2">
INQUIRY SENT
</h4>
<p className="font-sans text-stone-300 text-[11px] leading-relaxed max-w-[260px] mx-auto tracking-wider">
Thank you for contacting the court. Our hospitality concierge will respond within a single sun cycle.
<h4 className="font-serif text-white tracking-wider uppercase text-base mb-2">MESSAGE SENT</h4>
<p className="font-sans text-stone-300 text-sm leading-relaxed max-w-[280px] mx-auto tracking-wider">
Thank you for contacting us. We will get back to you shortly.
</p>
</div>
) : (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block font-sans text-[9px] tracking-widest text-[#bc9e65] uppercase font-bold mb-1">
YOUR NAME
</label>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<input
type="text"
required
className="w-full bg-[#06120c]/60 border border-[#bc9e65]/35 p-2 text-xs font-sans text-white focus:outline-none focus:border-[#bc9e65] transition-colors rounded-none placeholder-stone-600"
placeholder="Enter your name"
className="w-full bg-transparent border border-[#bc9e65]/30 p-3 text-sm font-sans text-white focus:outline-none focus:border-[#bc9e65] transition-colors rounded-none placeholder-stone-500"
placeholder="Your Name"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
/>
</div>
<div>
<label className="block font-sans text-[9px] tracking-widest text-[#bc9e65] uppercase font-bold mb-1">
EMAIL ADRESS
</label>
<input
type="email"
required
className="w-full bg-[#06120c]/60 border border-[#bc9e65]/35 p-2 text-xs font-sans text-white focus:outline-none focus:border-[#bc9e65] transition-colors rounded-none placeholder-stone-600"
placeholder="concierge@example.com"
className="w-full bg-transparent border border-[#bc9e65]/30 p-3 text-sm font-sans text-white focus:outline-none focus:border-[#bc9e65] transition-colors rounded-none placeholder-stone-500"
placeholder="Your Email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
/>
</div>
<div>
<label className="block font-sans text-[9px] tracking-widest text-[#bc9e65] uppercase font-bold mb-1">
MESSAGE TO THE COURT
</label>
<textarea
rows={4}
required
className="w-full bg-[#06120c]/60 border border-[#bc9e65]/35 p-2 text-xs font-sans text-white focus:outline-none focus:border-[#bc9e65] transition-colors rounded-none resize-none placeholder-stone-600"
placeholder="Tell us what's on your mind..."
value={formData.msg}
onChange={(e) => setFormData({ ...formData, msg: e.target.value })}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<input
type="tel"
className="w-full bg-transparent border border-[#bc9e65]/30 p-3 text-sm font-sans text-white focus:outline-none focus:border-[#bc9e65] transition-colors rounded-none placeholder-stone-500"
placeholder="Phone Number"
value={formData.phone}
onChange={(e) => setFormData({ ...formData, phone: e.target.value })}
/>
<input
type="text"
className="w-full bg-transparent border border-[#bc9e65]/30 p-3 text-sm font-sans text-white focus:outline-none focus:border-[#bc9e65] transition-colors rounded-none placeholder-stone-500"
placeholder="Subject"
value={formData.subject}
onChange={(e) => setFormData({ ...formData, subject: e.target.value })}
/>
</div>
<textarea
rows={5}
required
className="w-full bg-transparent border border-[#bc9e65]/30 p-3 text-sm font-sans text-white focus:outline-none focus:border-[#bc9e65] transition-colors rounded-none resize-none placeholder-stone-500"
placeholder="Your Message"
value={formData.msg}
onChange={(e) => setFormData({ ...formData, msg: e.target.value })}
/>
<button
type="submit"
className="clickable w-full py-2.5 border border-[#bc9e65]/50 hover:border-[#bc9e65] bg-transparent text-[#bc9e65] hover:bg-[#bc9e65] hover:text-[#06120c] font-sans font-bold text-[9px] tracking-widest uppercase transition-all duration-300 shadow-md"
className="clickable w-full py-3.5 bg-gradient-to-r from-[#bc9e65] to-[#d4b872] hover:from-[#c5a975] hover:to-[#dfc585] text-[#06120c] font-sans font-bold text-sm tracking-wider transition-all duration-300 shadow-md rounded-sm mt-1"
>
SEND INQUIRY
Send Message
</button>
</form>
)}
</div>
</div>
</div>
</AnimatedSection>
</div>
</div>
</div>
{/* ── MAP SECTION: Sandstone bg ── */}
<div className="relative w-full">
{/* Sandstone bg image */}
<div className="absolute inset-0 z-0 pointer-events-none select-none">
<Image
src="/images/story_bg.png"
alt="Background"
fill
className="object-cover object-center"
/>
</div>
<div className="relative z-10 px-6 py-20">
<AnimatedSection variant="scaleUp" delay={0}>
<div className="relative w-full h-[400px] border border-[#bc9e65]/40 shadow-2xl overflow-hidden group rounded-sm max-w-6xl mx-auto">
<iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2387.597603633402!2d-80.5796577!3d43.4438744!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x882bf755b6dfbef5%3A0x21184d424ab8bf6f!2sMy%20Dosa%20Place%20(%20South%20Indian%20Pure%20VEG)!5e1!3m2!1sen!2sin!4v1784207213128!5m2!1sen!2sin"
width="100%"
height="100%"
style={{ border: 0, filter: "grayscale(40%) sepia(10%) opacity(0.85)" }}
allowFullScreen={false}
loading="lazy"
referrerPolicy="no-referrer-when-downgrade"
className="absolute inset-0 transition-all duration-700 group-hover:filter-none group-hover:opacity-100"
></iframe>
{/* Floating info card */}
<div className="absolute inset-0 flex items-center justify-center p-4 pointer-events-none">
<div className="bg-[#0c2419] border border-[#bc9e65]/40 p-6 sm:p-8 shadow-2xl max-w-xs w-full pointer-events-auto rounded-sm">
<h3 className="font-serif text-white text-xl mb-3 tracking-wide">My Dosa Place</h3>
<p className="font-sans text-stone-300 text-sm leading-relaxed tracking-wider mb-5 uppercase">
922 Erb Street West,<br />
Waterloo, ON N2T 0C9
</p>
<a
href="https://www.google.com/maps?gs_lcrp=EgZjaHJvbWUqBwgAEAAYgAQyBwgAEAAYgAQyDAgBEC4YJxivARjHATIGCAIQRRg5MgcIAxAAGIAEMgcIBBAAGIAEMgYIBRBFGDwyBggGEEUYPDIGCAcQRRg90gEIMzc1MGowajeoAgCwAgA&um=1&ie=UTF-8&fb=1&gl=in&sa=X&geocode=KfW-37ZV9yuIMW-_uEpCTRgh&daddr=922+Erb+St.+W+Unit+C3%233,+Waterloo,+ON+N2T+0C9,+Canada"
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-2 text-[#bc9e65] hover:text-white font-sans text-xs tracking-widest uppercase transition-colors group/link"
>
Get Directions
<span className="transform group-hover/link:translate-x-1 transition-transform"></span>
</a>
</div>
</div>
</div>
</AnimatedSection>
</div>
</div>
{/* ── BOTTOM FEATURES: Full-width dark green ── */}
{/* <div className="relative max-w-7xl mx-auto w-[calc(100%-3rem)] bg-[#061810] rounded-2xl mb-16 border border-[#bc9e65]/30 overflow-hidden shadow-2xl">
<div className="absolute inset-0 pointer-events-none select-none opacity-60">
<Image
src="/images/footer_bg.png"
alt=""
fill
className="object-cover object-center"
/>
</div>
<div className="relative z-10 max-w-6xl mx-auto px-6 py-10">
<div className="grid grid-cols-2 md:grid-cols-4 gap-8">
<div className="flex flex-col items-center text-center px-4 group">
<div className="w-14 h-14 mb-4 text-[#bc9e65] group-hover:scale-110 transition-transform duration-300">
<UtensilsCrossed strokeWidth={1} className="w-full h-full" />
</div>
<h4 className="font-serif text-white text-lg mb-2">Dine In</h4>
<p className="font-sans text-stone-400 text-xs tracking-wider">A warm and cozy experience</p>
</div>
<div className="flex flex-col items-center text-center px-4 group">
<div className="w-14 h-14 mb-4 text-[#bc9e65] group-hover:scale-110 transition-transform duration-300">
<ShoppingBag strokeWidth={1} className="w-full h-full" />
</div>
<h4 className="font-serif text-white text-lg mb-2">Takeaway</h4>
<p className="font-sans text-stone-400 text-xs tracking-wider">Fast &amp; convenient pick-up</p>
</div>
<div className="flex flex-col items-center text-center px-4 group">
<div className="w-14 h-14 mb-4 text-[#bc9e65] group-hover:scale-110 transition-transform duration-300">
<Truck strokeWidth={1} className="w-full h-full" />
</div>
<h4 className="font-serif text-white text-lg mb-2">Delivery</h4>
<p className="font-sans text-stone-400 text-xs tracking-wider">Bringing flavor to your door</p>
</div>
<div className="flex flex-col items-center text-center px-4 group">
<div className="w-14 h-14 mb-4 text-[#bc9e65] group-hover:scale-110 transition-transform duration-300">
<ChefHat strokeWidth={1} className="w-full h-full" />
</div>
<h4 className="font-serif text-white text-lg mb-2">Catering</h4>
<p className="font-sans text-stone-400 text-xs tracking-wider">Perfect for your special events</p>
</div>
</div>
</div>
</div> */}
</SubpageLayout>
);
}

View File

@ -1,32 +1,18 @@
"use client";
import SubpageLayout from "@/components/SubpageLayout";
import CulinaryCategories from "@/components/CulinaryCategories";
import MenuPreview from "@/components/MenuPreview";
import InnerBanner from "@/components/InnerBanner";
import MenuPageContent from "@/components/MenuPageContent";
export default function MenuPage() {
return (
<SubpageLayout>
<div className="flex flex-col gap-2">
<div className="flex flex-col">
{/* Subpage Header Banner */}
<div className="text-center pt-12 pb-6 max-w-2xl mx-auto px-6 relative z-10 select-text">
<div className="flex items-center gap-3 justify-center mb-2">
<span className="text-[#bc9e65] text-xs"></span>
<span className="font-sans text-[10px] tracking-[0.3em] text-[#bc9e65] font-extrabold uppercase">
THE ROYAL BANQUET
</span>
<span className="text-[#bc9e65] text-xs"></span>
</div>
<h1 className="font-serif text-3xl sm:text-4xl lg:text-[42px] font-bold text-white tracking-wider leading-tight uppercase">
Feast <span className="text-[#bc9e65]">Menu</span>
</h1>
<div className="w-24 h-[1px] bg-gradient-to-r from-transparent via-[#bc9e65] to-transparent mx-auto mt-4" />
</div>
{/* Inner Banner */}
<InnerBanner pageName="Menu" />
{/* Core sections */}
<CulinaryCategories />
<MenuPreview />
<MenuPageContent />
</div>
</SubpageLayout>
);

View File

@ -48,7 +48,7 @@ export default function ReservationPage() {
/>
</div>
<div className="max-w-[500px] mx-auto px-6 py-12 relative z-10">
<div className="max-w-[500px] mx-auto px-6 pt-[140px] pb-[100px] sm:pt-[160px] sm:pb-[120px] relative z-10 min-h-screen flex flex-col justify-center">
{/* Header */}
<div className="text-center pb-10 select-text">

View File

@ -0,0 +1,60 @@
"use client";
import { motion } from "framer-motion";
import { ReactNode } from "react";
type AnimationVariant = "fadeUp" | "fadeIn" | "fadeLeft" | "fadeRight" | "scaleUp";
interface AnimatedSectionProps {
children: ReactNode;
className?: string;
variant?: AnimationVariant;
delay?: number;
duration?: number;
once?: boolean;
}
const variants = {
fadeUp: {
hidden: { opacity: 0, y: 48 },
visible: { opacity: 1, y: 0 },
},
fadeIn: {
hidden: { opacity: 0 },
visible: { opacity: 1 },
},
fadeLeft: {
hidden: { opacity: 0, x: -48 },
visible: { opacity: 1, x: 0 },
},
fadeRight: {
hidden: { opacity: 0, x: 48 },
visible: { opacity: 1, x: 0 },
},
scaleUp: {
hidden: { opacity: 0, scale: 0.92 },
visible: { opacity: 1, scale: 1 },
},
};
export default function AnimatedSection({
children,
className,
variant = "fadeUp",
delay = 0,
duration = 0.6,
once = true,
}: AnimatedSectionProps) {
return (
<motion.div
className={className}
initial="hidden"
whileInView="visible"
viewport={{ once, margin: "-80px" }}
variants={variants[variant]}
transition={{ duration, delay, ease: [0.25, 0.1, 0.25, 1] }}
>
{children}
</motion.div>
);
}

View File

@ -131,7 +131,7 @@ export default function ChefShowcase() {
{/* Backdrop Chef Showcase Background Image */}
<div className="absolute inset-0 z-0 pointer-events-none select-none">
<Image
src="/images/chef_bg.jpg"
src="/images/home/chef/chef-bg.webp"
alt="Chef Showcase Background"
fill
priority
@ -162,9 +162,9 @@ export default function ChefShowcase() {
<h2 className="font-serif text-4xl sm:text-5xl lg:text-6xl font-bold tracking-wider text-white uppercase leading-tight mb-4 select-text">
CHEF <br />
SUNDARAM <br />
Mendia <br />
<span className="text-[#bc9e65] flex items-center justify-center lg:justify-start gap-3">
IYER
Juxef
<svg className="w-7 h-7 text-[#bc9e65]/80 inline-block" 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" />
<path d="M 15,8 C 9,10 9,15 15,16" />
@ -180,7 +180,7 @@ export default function ChefShowcase() {
<StoryLotusDivider />
<p className="font-sans text-xs sm:text-sm text-stone-200 leading-relaxed tracking-wider max-w-xl mb-8">
With three decades of culinary devotion, Chef Sundaram Iyer has traversed the villages of Tamil Nadu, uncovering regional temple recipes and masterfully blending heritage masalas. He believes that true gastronomy is a spiritual act, uniting soil, tradition, and warm wood fire.
With three decades of culinary devotion, Chef Mendia Juxef has traversed the villages of Tamil Nadu, uncovering regional temple recipes and masterfully blending heritage masalas. He believes that true gastronomy is a spiritual act, uniting soil, tradition, and warm wood fire.
</p>
{/* Cursive Signature */}
@ -189,7 +189,7 @@ export default function ChefShowcase() {
className="text-[#bc9e65] text-3xl md:text-4xl pointer-events-none select-none"
style={{ fontFamily: '"Playball", "Great Vibes", "Brush Script MT", cursive' }}
>
Sundaram Iyer
Mendia Juxef
</span>
</div>
@ -221,8 +221,8 @@ export default function ChefShowcase() {
{/* Portrait Image */}
<Image
src="/images/chef_cooking.jpg"
alt="Chef Sundaram Iyer Cooking with Fire"
src="/images/home/chef/chef-right-img.webp"
alt="Chef Mendia Juxef Cooking with Fire"
fill
priority
sizes="(max-width: 768px) 100vw, 35vw"
@ -251,43 +251,28 @@ export default function ChefShowcase() {
{/* Feature 1: Authentic Recipes */}
<div className="flex flex-col items-center text-center px-4 py-3 md:py-0 select-text">
<svg className="w-7 h-7 text-[#bc9e65] mb-2.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M4 10h16c0 5-2.5 8-8 8s-8-3-8-8z" />
<path d="M12 4v4" />
<path d="M6 8h12" />
<path d="M2 10h20" />
</svg>
<Image src="/images/home/chef/icons/chef-authentic.webp" alt="Authentic Recipes" width={45} height={45} className="object-contain mb-2.5" />
<h5 className="font-serif text-[11px] sm:text-xs font-bold text-[#bc9e65] tracking-wider uppercase mb-1">Authentic Recipes</h5>
<p className="font-sans text-[10px] sm:text-[11px] text-stone-300 leading-relaxed max-w-[150px] mx-auto">Traditional recipes passed down through generations.</p>
</div>
{/* Feature 2: Pure Vegetarian */}
<div className="flex flex-col items-center text-center px-4 py-3 md:py-0 select-text">
<svg className="w-7 h-7 text-[#bc9e65] mb-2.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<circle cx="12" cy="12" r="10" />
<path d="M12 18V12" />
<path d="M12 12C12 10 14 9 16 9" />
<path d="M12 14C12 12 10 11 8 11" />
</svg>
<Image src="/images/home/chef/icons/chef-pure-veg.webp" alt="Pure Vegetarian" width={45} height={45} className="object-contain mb-2.5" />
<h5 className="font-serif text-[11px] sm:text-xs font-bold text-[#bc9e65] tracking-wider uppercase mb-1">Pure Vegetarian</h5>
<p className="font-sans text-[10px] sm:text-[11px] text-stone-300 leading-relaxed max-w-[150px] mx-auto">100% pure veg, made with the finest natural ingredients.</p>
</div>
{/* Feature 3: Wood Fire Cooking */}
<div className="flex flex-col items-center text-center px-4 py-3 md:py-0 select-text">
<svg className="w-7 h-7 text-[#bc9e65] mb-2.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 3z" />
</svg>
<Image src="/images/home/chef/icons/chef-wood.webp" alt="Wood Fire Cooking" width={45} height={45} className="object-contain mb-2.5" />
<h5 className="font-serif text-[11px] sm:text-xs font-bold text-[#bc9e65] tracking-wider uppercase mb-1">Wood Fire Cooking</h5>
<p className="font-sans text-[10px] sm:text-[11px] text-stone-300 leading-relaxed max-w-[150px] mx-auto">Infused with the aroma of wood fire and heritage.</p>
</div>
{/* Feature 4: Cooked With Love */}
<div className="flex flex-col items-center text-center px-4 py-3 md:py-0 select-text">
<svg className="w-7 h-7 text-[#bc9e65] mb-2.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<circle cx="12" cy="12" r="10" />
<path d="M12 16.5s-4-2.5-4-4.5c0-1.2.8-2 2-2 1 0 1.5.5 2 1 .5-.5 1-1 2-1 1.2 0 2 .8 2 2 0 2-4 4.5-4 4.5z" fill="currentColor" fillOpacity="0.1" />
</svg>
<Image src="/images/home/chef/icons/chef-love.webp" alt="Cooked With Love" width={45} height={45} className="object-contain mb-2.5" />
<h5 className="font-serif text-[11px] sm:text-xs font-bold text-[#bc9e65] tracking-wider uppercase mb-1">Cooked With Love</h5>
<p className="font-sans text-[10px] sm:text-[11px] text-stone-300 leading-relaxed max-w-[150px] mx-auto">Every dish is prepared with care, devotion & warmth.</p>
</div>

View File

@ -5,61 +5,61 @@ import Image from "next/image";
// Custom Gold Category Icons (SVG Paths)
const LeafThaliIcon = () => (
<svg className="w-4.5 h-4.5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M17 2H7C5.9 2 5 2.9 5 4v16c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-5 18c-1.7 0-3-1.3-3-3s1.3-3 3-3 3 1.3 3 3-1.3 3-3 3zm0-8c-1.7 0-3-1.3-3-3s1.3-3 3-3 3 1.3 3 3-1.3 3-3 3z" />
</svg>
);
const BiryaniRiceIcon = () => (
<svg className="w-4.5 h-4.5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C7 2 3 5 3 9c0 2.2 1.3 4.2 3.3 5.4C6.1 15 6 15.5 6 16c0 2.2 2.7 4 6 4s6-1.8 6-4c0-.5-.1-1-.3-1.6 2-1.2 3.3-3.2 3.3-5.4 0-4-4-7-9-7zm0 10c-3.3 0-6-1.8-6-4s2.7-4 6-4 6 1.8 6 4-2.7 4-6 4z" />
</svg>
);
const TiffinsDosasIcon = () => (
<svg className="w-4.5 h-4.5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 3c-4.97 0-9 4.03-9 9 0 2.12.74 4.07 1.97 5.61L17.61 5.03C16.07 3.74 14.12 3 12 3zm5.66 3.44L5.03 17.61C6.48 19.06 8.57 20 11 20c4.97 0 9-4.03 9-9 0-2.43-.94-4.52-2.34-5.96z" />
</svg>
);
const CurriesGraviesIcon = () => (
<svg className="w-4.5 h-4.5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M22 11h-2.1c-.5-3.3-3.1-5.9-6.4-6.4V2.5C13.5 2.2 13 2 12 2s-1.5.2-1.5.5V4.6C7.2 5.1 4.6 7.7 4.1 11H2c-.6 0-1 .4-1 1s.4 1 1 1h2.1c.5 3.3 3.1 5.9 6.4 6.4v2.1c0 .3.5.5 1.5.5s1.5-.2 1.5-.5v-2.1c3.3-.5 5.9-3.1 6.4-6.4H22c.6 0 1-.4 1-1s-.4-1-1-1z" />
</svg>
);
const SweetsDessertsIcon = () => (
<svg className="w-4.5 h-4.5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zm1-14.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0 5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0 5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z" />
</svg>
);
const BeveragesIcon = () => (
<svg className="w-4.5 h-4.5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M2 21h18v-2H2v2zM20 8h-2V5h2v3zm-4-3H4v10c0 2.21 1.79 4 4 4h8c2.21 0 4-1.79 4-4V5h-4zm2 10c0 1.1-.9 2-2 2H8c-1.1 0-2-.9-2-2V7h12v8z" />
</svg>
);
const TandoorSpecialsIcon = () => (
<svg className="w-4.5 h-4.5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C7.03 2 3 6.03 3 11c0 3.7 2.24 6.89 5.5 8.24V21c0 .55.45 1 1 1h5c.55 0 1-.45 1-1v-1.76c3.26-1.35 5.5-4.54 5.5-8.24 0-4.97-4.03-9-9-9zm3 10H9v-2h6v2z" />
</svg>
);
const SeafoodDelightsIcon = () => (
<svg className="w-4.5 h-4.5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 14.5c0 .83-.67 1.5-1.5 1.5s-1.5-.67-1.5-1.5.67-1.5 1.5-1.5 1.5.67 1.5 1.5zm-1.5-3.5c-.55 0-1-.45-1-1V8c0-.55.45-1 1-1s1 .45 1 1v4c0 .55-.45 1-1 1z" />
</svg>
);
const ChefSpecialsIcon = () => (
<svg className="w-4.5 h-4.5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 3c-4.97 0-9 4.03-9 9 0 2.12.74 4.07 1.97 5.61L17.61 5.03C16.07 3.74 14.12 3 12 3zm0 15c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6z" />
</svg>
);
const BanquetMenusIcon = () => (
<svg className="w-4.5 h-4.5 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z" />
</svg>
);
@ -92,76 +92,76 @@ const ROW1_CATEGORIES = [
title: "Traditional Thali",
subtitle: "FEATURED",
desc: "A wholesome spread of authentic South Indian flavors served the traditional way.",
image: "/images/south_indian_thali_luxury.png",
image: "/images/home/culinary-categories/left-single-card-Traditional-Thali.webp",
icon: LeafThaliIcon,
isDouble: true,
},
{
id: "biryani",
title: "Biryani & Rice",
desc: "Aromatic, flavorful & slow-cooked to perfection.",
image: "/images/category_biryani.jpg",
icon: BiryaniRiceIcon,
},
{
id: "dosas",
title: "Tiffins & Dosas",
desc: "Crisp, soft & made fresh for a perfect start.",
image: "/images/masala_dosa_luxury.png",
id: "dosa",
title: "Crispy Dosas",
desc: "Golden, crisp and served with fresh chutneys.",
image: "/images/home/culinary-categories/right-side-dosa.webp",
icon: TiffinsDosasIcon,
},
{
id: "curries",
title: "Curries & Gravies",
desc: "Rich, flavorful & inspired by regional classics.",
image: "/images/category_curries.jpg",
icon: CurriesGraviesIcon,
id: "uthappam",
title: "Soft Uthappam",
desc: "Thick, soft pancakes topped with fresh ingredients.",
image: "/images/home/culinary-categories/right-side-utthappam.webp",
icon: TiffinsDosasIcon,
},
{
id: "vada",
title: "Crispy Vada",
desc: "Golden fried lentil donuts, crispy outside and soft inside.",
image: "/images/home/culinary-categories/right-side-vada.webp",
icon: TiffinsDosasIcon,
},
];
const ROW2_CATEGORIES = [
{
id: "sweets",
title: "Sweets & Desserts",
desc: "Traditional sweets crafted to end your meal beautifully.",
image: "/images/category_sweets.jpg",
icon: SweetsDessertsIcon,
},
{
id: "beverages",
title: "Beverages",
desc: "Refreshing & traditional drinks to complement every meal.",
image: "/images/category_beverages.jpg",
icon: BeveragesIcon,
},
{
id: "tandoor",
title: "Tandoor Specials",
desc: "Fire-grilled delights with bold spices and irresistible aroma.",
image: "/images/category_tandoor.jpg",
icon: TandoorSpecialsIcon,
},
{
id: "seafood",
title: "Seafood Delights",
desc: "Coastal flavors cooked with authenticity and passion.",
image: "/images/category_seafood.jpg",
icon: SeafoodDelightsIcon,
},
{
id: "chef_specials",
title: "Chef's Specials",
desc: "Handpicked creations by our master chef, just for you.",
image: "/images/category_chef_specials.jpg",
id: "appetizer",
title: "Appetizers",
desc: "Perfect starters to begin your culinary journey.",
image: "/images/home/culinary-categories/bottom-appetizer.webp",
icon: ChefSpecialsIcon,
},
{
id: "banquet",
title: "Banquet Menus",
desc: "Curated menus for weddings, events & celebrations.",
image: "/images/category_banquet.jpg",
id: "tiffin",
title: "Tiffins",
desc: "Authentic quick bites full of traditional flavors.",
image: "/images/home/culinary-categories/bottom-tiffin.webp",
icon: TiffinsDosasIcon,
},
{
id: "rice",
title: "Rice Bowls",
desc: "Aromatic and flavorful rice specialties.",
image: "/images/home/culinary-categories/bottom-rice.webp",
icon: BiryaniRiceIcon,
},
{
id: "breads",
title: "Indian Breads",
desc: "Soft, warm breads fresh from our tandoor.",
image: "/images/home/culinary-categories/bottom-breads.webp",
icon: TandoorSpecialsIcon,
},
{
id: "combo",
title: "Combos",
desc: "Carefully curated combinations for a complete meal.",
image: "/images/home/culinary-categories/bottom-combo.webp",
icon: BanquetMenusIcon,
},
{
id: "dessert",
title: "Desserts & Beverages",
desc: "Sweet endings and refreshing traditional drinks.",
image: "/images/home/culinary-categories/bottom-dessert-beverages.webp",
icon: SweetsDessertsIcon,
},
];
export default function CulinaryCategories() {
@ -171,7 +171,7 @@ export default function CulinaryCategories() {
{/* Background Graphic Template Layer */}
<div className="absolute inset-0 z-0 pointer-events-none select-none">
<Image
src="/images/category_bg.jpg"
src="/images/home/culinary-categories/our-culinary-categories.webp"
alt="Categories Backdrop"
fill
priority
@ -233,9 +233,9 @@ export default function CulinaryCategories() {
<CornerOrnaments />
{/* Gold Category Badge at top center of card with interactive outer ring */}
<div className="absolute -top-4 left-1/2 -translate-x-1/2 w-8 h-8 rounded-full bg-[#06120c] border border-[#bc9e65]/60 flex items-center justify-center shadow-lg z-20 select-none">
<div className="absolute -top-6 left-1/2 -translate-x-1/2 w-12 h-12 rounded-full bg-[#06120c] border border-[#bc9e65]/60 flex items-center justify-center shadow-lg z-20 select-none">
{/* Rotating Outer Dashed Mandala Ring on Hover */}
<div className="absolute w-11 h-11 rounded-full border border-dashed border-[#bc9e65]/35 group-hover:rotate-[45deg] transition-transform duration-1000 z-10 pointer-events-none" />
<div className="absolute w-16 h-16 rounded-full border border-dashed border-[#bc9e65]/35 group-hover:rotate-[45deg] transition-transform duration-1000 z-10 pointer-events-none" />
<Icon />
</div>
@ -300,8 +300,8 @@ export default function CulinaryCategories() {
<CornerOrnaments />
{/* Gold Category Badge with rotating outer dashed border */}
<div className="absolute -top-4 left-1/2 -translate-x-1/2 w-8 h-8 rounded-full bg-[#06120c] border border-[#bc9e65]/60 flex items-center justify-center shadow-lg z-20 select-none">
<div className="absolute w-11 h-11 rounded-full border border-dashed border-[#bc9e65]/35 group-hover:rotate-[45deg] transition-transform duration-1000 z-10 pointer-events-none" />
<div className="absolute -top-6 left-1/2 -translate-x-1/2 w-12 h-12 rounded-full bg-[#06120c] border border-[#bc9e65]/60 flex items-center justify-center shadow-lg z-20 select-none">
<div className="absolute w-16 h-16 rounded-full border border-dashed border-[#bc9e65]/35 group-hover:rotate-[45deg] transition-transform duration-1000 z-10 pointer-events-none" />
<Icon />
</div>
@ -361,8 +361,8 @@ export default function CulinaryCategories() {
<CornerOrnaments />
{/* Gold Category Badge with rotating outer dashed border */}
<div className="absolute -top-4 left-1/2 -translate-x-1/2 w-8 h-8 rounded-full bg-[#06120c] border border-[#bc9e65]/60 flex items-center justify-center shadow-lg z-20 select-none">
<div className="absolute w-11 h-11 rounded-full border border-dashed border-[#bc9e65]/35 group-hover:rotate-[45deg] transition-transform duration-1000 z-10 pointer-events-none" />
<div className="absolute -top-6 left-1/2 -translate-x-1/2 w-12 h-12 rounded-full bg-[#06120c] border border-[#bc9e65]/60 flex items-center justify-center shadow-lg z-20 select-none">
<div className="absolute w-16 h-16 rounded-full border border-dashed border-[#bc9e65]/35 group-hover:rotate-[45deg] transition-transform duration-1000 z-10 pointer-events-none" />
<Icon />
</div>

View File

@ -383,17 +383,17 @@ export default function EntranceExperience({ onProgress }: { onProgress?: (progr
<div className="absolute top-2 left-2 right-2 bottom-2 border border-gold/15 pointer-events-none rounded-[22px]" />
<span className="font-sans text-[#188754] text-[10px] sm:text-[11px] tracking-[0.4em] uppercase font-bold block mb-2.5 text-center mt-1">
P U R E V E G E T A R I A N F E A S T
AUTHENTIC SOUTH INDIAN · PURE VEGETARIAN
</span>
<h3 className="font-serif text-[#188754] text-xl sm:text-2xl tracking-[0.15em] uppercase font-bold mb-3 text-center">
A Royal Banquet
A Royal Banquet in the Heart of Waterloo
</h3>
<div className="w-24 h-[1px] bg-gradient-to-r from-transparent via-[#d8c396] to-transparent mx-auto mb-4" />
<p className="font-sans text-xs sm:text-[13px] text-stone-800 leading-relaxed tracking-wider font-medium text-justify">
Your table is set. Experience a royal banquet served on fresh banana leaves, where crispy ghee-roasted dosas, steaming lentil sambar, and hand-ground chutneys await you.
A tradition older than memory. The table is set for a royal banquet on fresh banana leavesdosas roasted in pure ghee to a crisp, golden perfection, slow-simmered sambar, and chutneys hand-ground fresh every morning. Served exactly as it was meant to be. 100% pure vegetarian.
</p>
</motion.div>
)}

View File

@ -4,36 +4,20 @@ import { useState } from "react";
import { motion } from "framer-motion";
import Image from "next/image";
// Custom Ornate Gold Category SVG Icons
const RoyalFeastsIcon = () => (
<svg className="w-5 h-5 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M12 21c4.5-3.5 6-7.5 6-10.5C18 7.5 15.5 6 12 10 8.5 6 6 7.5 6 10.5c0 3 1.5 7 6 10.5z" />
<path d="M12 10V21" />
<path d="M12 14c-1.5-1-3-1.5-4.5-1" strokeLinecap="round" />
<path d="M12 14c1.5-1 3-1.5 4.5-1" strokeLinecap="round" />
</svg>
<Image src="/images/home/royal/icons/royal-feast.webp" alt="Royal Feasts" width={28} height={28} className="object-contain" />
);
const HeritageDinnersIcon = () => (
<svg className="w-5 h-5 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M3 21h18M5 21V10l7-5 7 5v11M9 21v-4a3 3 0 0 1 6 0v4M12 3v2" strokeLinecap="round" />
<circle cx="12" cy="11" r="1.5" stroke="currentColor" fill="currentColor" fillOpacity="0.2" />
</svg>
<Image src="/images/home/royal/icons/heritage-dinner.webp" alt="Heritage Dinners" width={28} height={28} className="object-contain" />
);
const PrivateGatheringsIcon = () => (
<svg className="w-5 h-5 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" strokeLinecap="round" strokeLinejoin="round" />
<path d="M9 8h6M12 8v8" strokeLinecap="round" />
</svg>
<Image src="/images/home/royal/icons/private-gatherings.webp" alt="Private Gatherings" width={28} height={28} className="object-contain" />
);
const KudumbaDiningIcon = () => (
<svg className="w-5 h-5 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M3 10h18M5 10v9M19 10v9M8 6h8M12 3v3" strokeLinecap="round" />
<circle cx="9" cy="14" r="1" fill="currentColor" />
<circle cx="15" cy="14" r="1" fill="currentColor" />
</svg>
<Image src="/images/home/royal/icons/kudumba-dining.webp" alt="Kudumba Dining" width={28} height={28} className="object-contain" />
);
export default function EventsAccordion() {
@ -44,33 +28,33 @@ export default function EventsAccordion() {
title: "Royal Feasts",
tamilTitle: "கல்யாண விருந்து",
subtitle: "WEDDING BANQUETS",
desc: "A grand imperial feast served to celebrate auspicious marital unions. Traditional multi-course menus served on fresh organic banana leaves with royal silver chalices.",
desc: "Our South Indian catering service in Waterloo brings the same authentic flavours to your celebrations—whether it's a wedding, family gathering, or corporate event. Enjoy traditional multi-course menus with the option of classic banana leaf-style presentation for a truly authentic South Indian dining experience. ",
icon: RoyalFeastsIcon,
bgImage: "/images/royal_dining_experience.png",
bgImage: "/images/home/royal/cards/royal-feast.webp",
},
{
title: "Heritage Dinners",
tamilTitle: "ஆயுள் விருந்து",
subtitle: "ANNIVERSARIES & MILESTONES",
desc: "Honor milestones and life chapters. Our ancestral dining rooms provide an intimate, warm-lit atmosphere with traditional music ensembles and customized menus.",
desc: "Celebrate life's biggest moments with a truly memorable dinner venue in Waterloo. Our heritage dining experience honors milestones and family chapters in an intimate, warm-lit setting designed for meaningful gatherings.",
icon: HeritageDinnersIcon,
bgImage: "/images/my_dosa_place_interior.png",
bgImage: "/images/home/royal/cards/heritage-dinner.webp",
},
{
title: "Private Gatherings",
tamilTitle: "சபை கூட்டங்கள்",
subtitle: "CORPORATE COLLABORATIONS",
desc: "Host partners and executives in private boardrooms crafted from vintage rosewood. Pair high-level meetings with gourmet curated South Indian starters.",
desc: "Looking for a distinctive corporate event venue in Waterloo? Host partners and executives in our private boardroom venue, crafted from vintage rosewood for a refined, professional setting. Our executive dining venue is designed for high-level meetings, client presentations, and business discussions — paired seamlessly with gourmet South Indian catering. From strategic sessions to celebratory close-outs, our private meeting space with catering brings substance and style together.",
icon: PrivateGatheringsIcon,
bgImage: "/images/chettinad_interior.png",
bgImage: "/images/home/royal/cards/private-gatherings.webp",
},
{
title: "Kudumba Dining",
tamilTitle: "குடும்ப விருந்து",
subtitle: "GRAND FAMILY REUNIONS",
desc: "Experience a South Indian heritage reunion, complete with traditional brass servers and folklore music.",
desc: "Bring the whole family together at Waterloo's most authentic family reunion venue. Our Kudumba Dining experience recreates a true South Indian heritage reunion, complete with traditional brass servers and live folklore music that brings generations closer.",
icon: KudumbaDiningIcon,
bgImage: "/images/south_indian_welcome.png",
bgImage: "/images/home/royal/cards/kudumba-dining.webp",
},
];
@ -78,7 +62,7 @@ export default function EventsAccordion() {
<section id="events" className="relative min-h-screen py-24 px-6 md:px-12 flex flex-col justify-center overflow-hidden bg-[#fdfcf7]">
{/* Background Decorative Layer 1: Pillars setting in soft focus */}
<div className="absolute inset-0 bg-[url('/images/chettinad_interior.png')] bg-cover bg-center opacity-[0.06] pointer-events-none select-none z-0" />
<div className="absolute inset-0 bg-[url('/images/home/royal/royal-assemblies-bg.webp')] bg-cover bg-center opacity-[0.06] pointer-events-none select-none z-0" />
{/* Background Decorative Layer 2: Parchment Overlay */}
<div className="absolute inset-0 bg-[url('/images/sanctuary_bg.png')] bg-cover bg-center pointer-events-none select-none z-0 opacity-80 mix-blend-multiply" />

View File

@ -21,7 +21,7 @@ export default function Footer() {
{/* Consolidated Mockup Background Layer */}
<div className="absolute inset-0 z-0 pointer-events-none select-none">
<Image
src="/images/footer_bg.png"
src="/images/home/footer/footer-bg.webp"
alt="Footer Backdrop"
fill
priority
@ -62,14 +62,14 @@ export default function Footer() {
<div className="flex items-start gap-2.5 max-w-sm text-left">
<span className="text-[#bc9e65] text-xl font-bold leading-none mt-0.5 pointer-events-none select-none"></span>
<p className="font-sans text-xs text-stone-300 leading-relaxed tracking-wider select-text">
Waterloo's premier destination for authentic, pure vegetarian South Indian flavors. Crispy ghee-roasted dosas, steaming lentil sambar, and home-ground chutneys crafted with devotion.
Waterloo's premier 100% pure vegetarian restaurant, serving authentic dosa in Waterloo. Enjoy crispy ghee roast dosa, lentil sambar, and home-ground chutneys made fresh daily using time-honoured recipes.
</p>
</div>
{/* Circular outline social links */}
<div className="flex gap-4 items-center mt-2">
<a
href="https://www.instagram.com"
href="#"
target="_blank"
rel="noopener noreferrer"
className="clickable w-8 h-8 rounded-full border border-[#bc9e65]/30 flex items-center justify-center text-[#bc9e65] hover:text-white hover:border-[#bc9e65] transition-all duration-300"
@ -77,7 +77,7 @@ export default function Footer() {
<Instagram size={13} />
</a>
<a
href="https://www.facebook.com"
href="#"
target="_blank"
rel="noopener noreferrer"
className="clickable w-8 h-8 rounded-full border border-[#bc9e65]/30 flex items-center justify-center text-[#bc9e65] hover:text-white hover:border-[#bc9e65] transition-all duration-300"
@ -85,7 +85,7 @@ export default function Footer() {
<Facebook size={13} />
</a>
<a
href="https://www.google.com"
href="#"
target="_blank"
rel="noopener noreferrer"
className="clickable w-8 h-8 rounded-full border border-[#bc9e65]/30 flex items-center justify-center text-[#bc9e65] hover:text-white hover:border-[#bc9e65] font-sans font-bold text-xs transition-all duration-300"
@ -234,7 +234,7 @@ export default function Footer() {
<div className="w-9 h-9 rounded-full border border-[#bc9e65]/35 flex items-center justify-center text-[#bc9e65] flex-shrink-0">
<Mail size={13} />
</div>
<span className="select-text">info@mydosaplace.com</span>
<span className="select-text">mydosaplacewaterloo@gmail.com</span>
</div>
</div>
</div>

View File

@ -0,0 +1,54 @@
import Image from "next/image";
import Link from "next/link";
interface InnerBannerProps {
pageName: string;
}
export default function InnerBanner({ pageName }: InnerBannerProps) {
return (
<div className="relative w-full h-[320px] sm:h-[450px] flex items-center justify-center overflow-hidden">
{/* Background Image */}
<div className="absolute inset-0 z-0">
<Image
src="/images/inner-banner.png"
alt={`${pageName} banner`}
fill
priority
className="object-cover object-[center_-300px]"
/>
</div>
{/* Decorative top & bottom gold lines */}
<div className="absolute top-0 left-0 right-0 h-[2px] bg-gradient-to-r from-transparent via-[#bc9e65]/60 to-transparent z-20" />
<div className="absolute bottom-0 left-0 right-0 h-[2px] bg-gradient-to-r from-transparent via-[#bc9e65]/60 to-transparent z-20" />
{/* Content */}
<div className="relative z-20 flex flex-col items-center text-center px-6">
{/* Breadcrumb */}
<div className="flex items-center gap-2 mb-4">
<Link
href="/"
className="font-sans text-[11px] sm:text-xs tracking-[0.2em] text-[#bc9e65]/80 hover:text-[#bc9e65] uppercase transition-colors duration-200"
>
Home
</Link>
<span className="text-[#bc9e65]/50 text-xs select-none"></span>
<span className="font-sans text-[11px] sm:text-xs tracking-[0.2em] text-[#1a3a25] uppercase">
{pageName}
</span>
</div>
{/* Page Name */}
<h1 className="font-serif text-3xl sm:text-4xl lg:text-5xl text-[#1a3a25] tracking-wider leading-tight">
{pageName}
</h1>
{/* Gold divider */}
<div className="mt-5 w-20 h-[1.5px] bg-gradient-to-r from-transparent via-[#bc9e65] to-transparent" />
</div>
</div>
);
}

View File

@ -0,0 +1,247 @@
"use client";
import { motion } from "framer-motion";
import Image from "next/image";
import { useState } from "react";
import AnimatedSection from "@/components/AnimatedSection";
const TABS = [
{ id: "all", label: "ALL ITEMS", noIcon: true },
{ id: "dosa", label: "DOSA", active: true },
{ id: "idli", label: "IDLI" },
{ id: "vada", label: "VADA" },
{ id: "uttapam", label: "UTTAPAM" },
{ id: "tiffin", label: "TIFFIN" },
{ id: "rice", label: "RICE" },
{ id: "curry", label: "CURRY" },
{ id: "beverages", label: "BEVERAGES" }
];
const MENU_ITEMS = [
{
id: 1,
name: "ONION RAVA DOSA",
desc: "Crispy semolina crepe with onions, herbs & spices.",
price: "$9.99",
tag: "RAVA SPL",
bg: "light",
},
{
id: 2,
name: "MASALA DOSA",
desc: "Crispy thin rice & lentil crepe stuffed with potato masala.",
price: "$8.99",
tag: "CLASSIC",
bg: "light",
},
{
id: 3,
name: "IDLI SAMBAR (2 PCS)",
desc: "Steamed fluffy rice & lentil cakes with hot sambar.",
price: "$6.49",
tag: "TIFFIN SPL",
bg: "green",
},
{
id: 4,
name: "ONION RAVA MASALA DOSA",
desc: "Semolina crepe with onions and spiced potato filling.",
price: "$9.49",
tag: "RAVA SPL",
bg: "light",
},
{
id: 5,
name: "MYSORE MASALA",
desc: "Rice crepe spread with spicy chutney & potato masala.",
price: "$9.49",
tag: "CLASSIC",
bg: "dark",
},
{
id: 6,
name: "MEDU VADA (2 PCS)",
desc: "Deep fried crispy lentil donuts served with sambar & chutney.",
price: "$6.49",
tag: "TIFFIN SPL",
bg: "light",
},
{
id: 7,
name: "PAPER ROAST DOSA",
desc: "Extra large, paper-thin, crispy dosa served hot.",
price: "$10.49",
tag: "CLASSIC",
bg: "light",
},
{
id: 8,
name: "RAVA MASALA DOSA",
desc: "Crispy semolina crepe filled with spiced potato masala.",
price: "$9.49",
tag: "RAVA SPL",
bg: "light",
}
];
export default function MenuPageContent() {
const [activeTab, setActiveTab] = useState("dosa");
return (
<div className="bg-[#faf7f2] font-sans pb-24 text-stone-800">
{/* Header Section */}
<div className="relative pt-24 px-6 flex flex-col items-center text-center overflow-hidden">
{/* Background Sketch (using a subtle pattern or existing image if available, else CSS) */}
<div className="absolute inset-0 opacity-10 pointer-events-none" style={{ backgroundImage: 'url("/images/home/menu/our-menu-bg.webp")', backgroundSize: 'cover', backgroundPosition: 'center top' }}></div>
</div>
{/* Section Title */}
<div className="flex flex-col items-center mb-10">
<div className="flex items-center gap-6">
<span className="text-[#bc9e65]"></span>
<h2 className="font-serif text-3xl font-bold text-[#0f3f26] uppercase tracking-widest">DOSA SPECIALTIES</h2>
<span className="text-[#bc9e65] scale-x-[-1]"></span>
</div>
<div className="flex items-center gap-3 mt-3 text-sm font-semibold tracking-wide text-stone-600">
<span className="w-8 h-[1px] bg-[#bc9e65]/60"></span>
Crispy <span className="text-[#bc9e65] text-xs"></span> Flavorful <span className="text-[#bc9e65] text-xs"></span> Authentic
<span className="w-8 h-[1px] bg-[#bc9e65]/60"></span>
</div>
</div>
{/* Tabs */}
<AnimatedSection variant="fadeUp" delay={0}>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mb-16 relative z-10">
<div className="flex items-center gap-2 overflow-x-auto pb-6 hide-scrollbar justify-start md:justify-center items-end">
{TABS.map((tab) => {
const isActive = activeTab === tab.id;
const isAllItems = tab.id === "all";
if (isAllItems) {
return (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`relative flex items-center gap-3 px-6 rounded-[20px] whitespace-nowrap transition-all duration-300 font-serif font-bold text-xs uppercase tracking-wider
${isActive
? "bg-[#0a4a2b] text-white border-[3px] border-[#bc9e65] py-2.5 shadow-[0_4px_15px_rgba(188,158,101,0.3)] z-10"
: "bg-[#0a4a2b] text-white border-[3px] border-transparent py-2.5 hover:bg-[#073820]"
}`}
>
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<rect x="3" y="3" width="7" height="7" rx="1.5" />
<rect x="14" y="3" width="7" height="7" rx="1.5" />
<rect x="14" y="14" width="7" height="7" rx="1.5" />
<rect x="3" y="14" width="7" height="7" rx="1.5" />
</svg>
{tab.label}
{isActive && (
<div className="absolute -bottom-[6px] left-1/2 -translate-x-1/2 w-2.5 h-2.5 bg-[#bc9e65] rotate-45 z-20"></div>
)}
</button>
);
}
return (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`relative flex items-center gap-3 px-2 whitespace-nowrap transition-all duration-300 font-serif font-bold text-[11px] uppercase tracking-wider rounded-[20px]
${isActive
? "bg-[#0a4a2b] text-white border-[3px] border-[#bc9e65] py-2 shadow-[0_4px_15px_rgba(188,158,101,0.3)] z-10"
: "bg-[#fdfcf9] text-[#0f3f26] border border-[#eaddc4] py-2.5 hover:bg-white hover:shadow-md"
}`}
>
<div className={`w-8 h-8 flex items-center justify-center rounded-full ${isActive ? 'opacity-100' : 'opacity-90'}`}>
<Image src="/images/menu/tab-icon.png" alt="" width={38} height={38} className="object-contain drop-shadow-sm" />
</div>
{tab.label}
{/* Gold Diamond for Active Tab */}
{isActive && (
<div className="absolute -bottom-[6px] left-1/2 -translate-x-1/2 w-2.5 h-2.5 bg-[#bc9e65] rotate-45 z-20"></div>
)}
</button>
)
})}
</div>
</div>
</AnimatedSection>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
{/* Card Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{MENU_ITEMS.map((item, index) => (
<AnimatedSection key={item.id} variant="fadeUp" delay={index * 0.08}>
<div
className="relative rounded-3xl overflow-hidden shadow-lg group transition-all duration-500 hover:-translate-y-1 hover:shadow-2xl border bg-white text-stone-800 border-stone-200 hover:bg-[#0a4a2b] hover:border-[#0a4a2b]"
>
{/* Image Section */}
<div className="relative h-30 w-full bg-[#111]">
<Image
src="/images/menu/card-img.png"
alt={item.name}
fill
className="object-cover transition-transform duration-700 group-hover:scale-105"
/>
{/* Curve Overlay */}
<div className="absolute top-0 right-0 w-20 h-20 bg-transparent pointer-events-none">
<svg viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg" className="absolute w-full h-full top-0 right-0 scale-x-[1] scale-y-[1] text-white group-hover:text-[#0a4a2b] transition-colors duration-500">
<path d="M100,0 V100 C100,44.77 55.23,0 0,0 H100 Z" fill="currentColor" />
</svg>
</div>
{/* Floating Icon */}
<div className="absolute -bottom-6 left-6 w-14 h-14 rounded-full flex items-center justify-center shadow-lg border-3 z-10 bg-[#fdfcf9] border-[#eaddc4] group-hover:border-[#bc9e65] transition-colors duration-500">
<Image src="/images/menu/card-icon.png" alt="icon" width={38} height={38} className="object-contain" />
</div>
</div>
{/* Content Section */}
<div className="pt-10 pb-6 px-6 relative">
<h3 className="font-serif text-lg font-bold tracking-wider mb-2 pr-6 text-[#0f3f26] group-hover:text-white transition-colors duration-500">
{item.name}
</h3>
{/* Little Leaf / Accent */}
<div className="absolute top-10 right-6 text-[#188754] group-hover:text-[#bc9e65] transition-colors duration-500">
🌿
</div>
<p className="text-[11px] font-sans mb-6 min-h-[32px] leading-relaxed text-stone-500 group-hover:text-stone-300 transition-colors duration-500">
{item.desc}
</p>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<span className="font-serif text-lg font-bold text-[#0f3f26] group-hover:text-white transition-colors duration-500">
{item.price}
</span>
<span className={`text-[8px] font-bold uppercase tracking-wider px-2 py-1 rounded-full flex items-center gap-1 border transition-colors duration-500
${item.tag.includes('RAVA') ? 'bg-[#e8f5e9] text-[#1b5e20] border-[#a5d6a7]/70 group-hover:bg-white/20 group-hover:text-white group-hover:border-white/30' :
item.tag.includes('CLASSIC') ? 'bg-[#fbe9e7] text-[#c62828] border-[#ffab91]/70 group-hover:bg-white/20 group-hover:text-white group-hover:border-white/30' :
'bg-[#fff8e1] text-[#b78103] border-[#ffe082]/70 group-hover:bg-white/20 group-hover:text-white group-hover:border-white/30'}`}
>
<span className="text-[10px] leading-none">
{item.tag.includes('RAVA') ? '✓' : item.tag.includes('CLASSIC') ? '●' : '★'}
</span>
{item.tag}
</span>
</div>
<button className="w-6 h-6 rounded-full flex items-center justify-center font-bold text-sm transition-all hover:scale-110 bg-[#0f3f26] text-white group-hover:bg-[#bc9e65] group-hover:text-[#0a4a2b]">
+
</button>
</div>
</div>
</div>
</AnimatedSection>
))}
</div>
</div>
</div>
);
}

View File

@ -240,7 +240,7 @@ export default function MenuPreview() {
>
{/* Traditional Background Image containing pre-composed sketches, leaves, and brass pots */}
<Image
src="/images/menu_bg_traditional.png"
src="/images/home/menu/our-menu-bg.webp"
alt="Traditional South Indian Menu Background"
fill
priority
@ -350,12 +350,7 @@ const BottomFeatures = () => (
{/* 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">
<svg className="w-5 h-5 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<circle cx="12" cy="12" r="10" />
<path d="M12 18V12" />
<path d="M12 12C12 10 14 9 16 9" />
<path d="M12 14C12 12 10 11 8 11" />
</svg>
<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-[10px] sm:text-[11px] font-bold text-stone-850 tracking-wider uppercase">100% Vegetarian</h5>
@ -366,12 +361,7 @@ const BottomFeatures = () => (
{/* 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">
<svg className="w-5 h-5 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M4 10h16c0 5-2.5 8-8 8s-8-3-8-8z" />
<path d="M12 4v4" />
<path d="M6 8h12" />
<path d="M2 10h20" />
</svg>
<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-[10px] sm:text-[11px] font-bold text-stone-850 tracking-wider uppercase">Authentic Recipes</h5>
@ -382,12 +372,7 @@ const BottomFeatures = () => (
{/* 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">
<svg className="w-5 h-5 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M12 20V4" />
<path d="M12 7c4 0 6 2 6 5s-2 3-6 3" />
<path d="M12 11c-4 0-6 2-6 5s2 3 6 3" />
<path d="M12 15c4 0 6-2 6-5s-2-2-6-2" />
</svg>
<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-[10px] sm:text-[11px] font-bold text-stone-850 tracking-wider uppercase">Finest Ingredients</h5>
@ -398,10 +383,7 @@ const BottomFeatures = () => (
{/* 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">
<svg className="w-5 h-5 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<circle cx="12" cy="12" r="10" />
<path d="M12 16.5s-4-2.5-4-4.5c0-1.2.8-2 2-2 1 0 1.5.5 2 1 .5-.5 1-1 2-1 1.2 0 2 .8 2 2 0 2-4 4.5-4 4.5z" fill="currentColor" fillOpacity="0.1" />
</svg>
<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-[10px] sm:text-[11px] font-bold text-stone-850 tracking-wider uppercase">Made With Love</h5>

View File

@ -26,7 +26,7 @@ export default function RestaurantStory() {
<section id="story" className="relative py-24 md:py-32 px-6 sm:px-12 md:px-24 overflow-hidden select-none">
{/* Traditional Background Image containing pre-composed sketches and mandalas */}
<Image
src="/images/story_bg.png"
src="/images/home/our-story/our-story-bg.webp"
alt="Traditional South Indian Story Background"
fill
priority
@ -57,8 +57,8 @@ export default function RestaurantStory() {
{/* Main Headline */}
<h2 className="font-serif text-3xl sm:text-4xl lg:text-5xl font-bold tracking-wider text-[#0a4a2b] leading-tight uppercase">
A Tradition Served<br />
<span className="text-[#0a4a2b] font-extrabold block mt-1">With Love</span>
South Indian Recipes,<br />
<span className="text-[#0a4a2b] font-extrabold block mt-1">Made the Traditional Way</span>
</h2>
{/* Traditional Gold Divider */}
@ -66,7 +66,7 @@ export default function RestaurantStory() {
{/* Paragraph Narrative */}
<p className="font-sans text-xs sm:text-sm lg:text-[15px] text-stone-700 leading-relaxed max-w-xl text-center tracking-wider mb-2 italic font-semibold">
At My Dosa Place, food is more than just a meal, it's a tradition passed down through generations. From authentic recipes to warm hospitality, we bring the true essence of South India to your table.
At My Dosa Place, every recipe carries the memory of a South Indian kitchenpassed from hand to hand, kitchen to kitchen, and generation to generation. Nestled in the heart of Waterloo, we've created a home for those who grew up with these flavours and an introduction for those experiencing them for the first time.
</p>
{/* Traditional Bottom Gold Divider */}
@ -83,13 +83,8 @@ export default function RestaurantStory() {
transition={{ duration: 0.5, delay: 0.1, ease: "easeOut" }}
className="flex flex-col items-center text-center group select-text"
>
<div className="w-14 h-14 rounded-full border border-[#d8c396] flex items-center justify-center mb-3 bg-[#fcfaf2]/70 shadow-sm transition-transform duration-300 group-hover:scale-110 pointer-events-none select-none">
<svg className="w-6 h-6 text-[#188754]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="12" r="10" />
<path d="M12 18V12" />
<path d="M12 12C12 10 14 9 16 9" />
<path d="M12 14C12 12 10 11 8 11" />
</svg>
<div className="w-14 h-14 rounded-full border border-[#d8c396] flex items-center justify-center mb-3 bg-[#fcfaf2]/70 shadow-sm transition-transform duration-300 group-hover:scale-110 pointer-events-none select-none overflow-hidden">
<Image src="/images/home/our-story/icons/pure-veg.webp" alt="100% Pure Veg" width={32} height={32} className="object-contain" />
</div>
<h4 className="font-serif text-[11px] sm:text-xs font-bold text-[#0a4a2b] tracking-wider uppercase mb-1.5">
100% Pure Veg
@ -107,13 +102,8 @@ export default function RestaurantStory() {
transition={{ duration: 0.5, delay: 0.2, ease: "easeOut" }}
className="flex flex-col items-center text-center group select-text"
>
<div className="w-14 h-14 rounded-full border border-[#d8c396] flex items-center justify-center mb-3 bg-[#fcfaf2]/70 shadow-sm transition-transform duration-300 group-hover:scale-110 pointer-events-none select-none">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8">
<path d="M4 10h16c0 5-2.5 8-8 8s-8-3-8-8z" />
<path d="M12 4v4" />
<path d="M6 8h12" />
<path d="M2 10h20" />
</svg>
<div className="w-14 h-14 rounded-full border border-[#d8c396] flex items-center justify-center mb-3 bg-[#fcfaf2]/70 shadow-sm transition-transform duration-300 group-hover:scale-110 pointer-events-none select-none overflow-hidden">
<Image src="/images/home/our-story/icons/authentic.webp" alt="Authentic Recipes" width={32} height={32} className="object-contain" />
</div>
<h4 className="font-serif text-[11px] sm:text-xs font-bold text-[#0a4a2b] tracking-wider uppercase mb-1.5">
Authentic Recipes
@ -131,13 +121,8 @@ export default function RestaurantStory() {
transition={{ duration: 0.5, delay: 0.3, ease: "easeOut" }}
className="flex flex-col items-center text-center group select-text"
>
<div className="w-14 h-14 rounded-full border border-[#d8c396] flex items-center justify-center mb-3 bg-[#fcfaf2]/70 shadow-sm transition-transform duration-300 group-hover:scale-110 pointer-events-none select-none">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8">
<path d="M12 20V4" />
<path d="M12 7c4 0 6 2 6 5s-2 3-6 3" />
<path d="M12 11c-4 0-6 2-6 5s2 3 6 3" />
<path d="M12 15c4 0 6-2 6-5s-2-2-6-2" />
</svg>
<div className="w-14 h-14 rounded-full border border-[#d8c396] flex items-center justify-center mb-3 bg-[#fcfaf2]/70 shadow-sm transition-transform duration-300 group-hover:scale-110 pointer-events-none select-none overflow-hidden">
<Image src="/images/home/our-story/icons/hospitality.webp" alt="Warm Hospitality" width={32} height={32} className="object-contain" />
</div>
<h4 className="font-serif text-[11px] sm:text-xs font-bold text-[#0a4a2b] tracking-wider uppercase mb-1.5">
Warm Hospitality
@ -155,11 +140,8 @@ export default function RestaurantStory() {
transition={{ duration: 0.5, delay: 0.4, ease: "easeOut" }}
className="flex flex-col items-center text-center group select-text"
>
<div className="w-14 h-14 rounded-full border border-[#d8c396] flex items-center justify-center mb-3 bg-[#fcfaf2]/70 shadow-sm transition-transform duration-300 group-hover:scale-110 pointer-events-none select-none">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8">
<circle cx="12" cy="12" r="10" />
<path d="M12 16.5s-4-2.5-4-4.5c0-1.2.8-2 2-2 1 0 1.5.5 2 1 .5-.5 1-1 2-1 1.2 0 2 .8 2 2 0 2-4 4.5-4 4.5z" fill="currentColor" fillOpacity="0.1" />
</svg>
<div className="w-14 h-14 rounded-full border border-[#d8c396] flex items-center justify-center mb-3 bg-[#fcfaf2]/70 shadow-sm transition-transform duration-300 group-hover:scale-110 pointer-events-none select-none overflow-hidden">
<Image src="/images/home/our-story/icons/love.webp" alt="Made With Love" width={32} height={32} className="object-contain" />
</div>
<h4 className="font-serif text-[11px] sm:text-xs font-bold text-[#0a4a2b] tracking-wider uppercase mb-1.5">
Made With Love
@ -184,7 +166,7 @@ export default function RestaurantStory() {
{/* Crop-extracted story thali arch image */}
<div className="w-[340px] h-[340px] sm:w-[480px] sm:h-[480px] md:w-[500px] md:h-[500px] relative pointer-events-none select-none">
<Image
src="/images/story_arch.png"
src="/images/home/our-story/our-story-right-img.webp"
alt="My Dosa Place Traditional Dining Feast"
fill
sizes="(max-width: 1024px) 100vw, 46vw"

View File

@ -96,7 +96,7 @@ export default function SpatialSanctuary() {
<div className="w-screen h-screen flex-shrink-0 relative flex flex-col justify-center px-6 sm:px-12 md:px-16 pt-12 pb-20 overflow-hidden bg-[#fdfcf7]">
{/* Parchment background image for Slide 1 */}
<Image
src="/images/sanctuary_bg.png"
src="/images/home/culinary-heritage/our-culinary-heritage-bg-1.webp"
alt="Traditional South Indian Sanctuary Background"
fill
priority
@ -158,9 +158,7 @@ export default function SpatialSanctuary() {
{/* Card 1: Recipes */}
<div className="bg-[#fcfaf2]/70 border border-[#d8c396]/45 rounded-xl shadow-sm p-4 flex flex-col items-center text-center group">
<svg className="w-6 h-6 text-[#bc9e65] mb-2" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" strokeLinecap="round" />
</svg>
<Image src="/images/home/culinary-heritage/icons/culinary-heritage.webp" alt="Heritage Recipes" width={32} height={32} className="object-contain mb-2" />
<h5 className="font-serif text-[10px] sm:text-[11px] font-bold text-[#0a4a2b] tracking-wider uppercase mb-1">
Heritage Recipes
</h5>
@ -171,9 +169,7 @@ export default function SpatialSanctuary() {
{/* Card 2: Ghee */}
<div className="bg-[#fcfaf2]/70 border border-[#d8c396]/45 rounded-xl shadow-sm p-4 flex flex-col items-center text-center group">
<svg className="w-6 h-6 text-[#bc9e65] mb-2" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M12 3v18M3 12h18M12 3a9 9 0 009 9M12 3a9 9 0 01-9 9M12 21a9 9 0 009-9M12 21a9 9 0 01-9-9" strokeLinecap="round" />
</svg>
<Image src="/images/home/culinary-heritage/icons/culinary-pure.webp" alt="Pure A2 Ghee" width={32} height={32} className="object-contain mb-2" />
<h5 className="font-serif text-[10px] sm:text-[11px] font-bold text-[#0a4a2b] tracking-wider uppercase mb-1">
Pure A2 Ghee
</h5>
@ -184,10 +180,7 @@ export default function SpatialSanctuary() {
{/* Card 3: Dosa */}
<div className="bg-[#fcfaf2]/70 border border-[#d8c396]/45 rounded-xl shadow-sm p-4 flex flex-col items-center text-center group">
<svg className="w-6 h-6 text-[#bc9e65] mb-2" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<circle cx="12" cy="12" r="10" />
<path d="M8 12a4 4 0 108 0" strokeLinecap="round" />
</svg>
<Image src="/images/home/culinary-heritage/icons/culinary-dosa.webp" alt="Artisanal Dosa" width={32} height={32} className="object-contain mb-2" />
<h5 className="font-serif text-[10px] sm:text-[11px] font-bold text-[#0a4a2b] tracking-wider uppercase mb-1">
Artisanal Dosa
</h5>
@ -198,9 +191,7 @@ export default function SpatialSanctuary() {
{/* Card 4: Feasts */}
<div className="bg-[#fcfaf2]/70 border border-[#d8c396]/45 rounded-xl shadow-sm p-4 flex flex-col items-center text-center group">
<svg className="w-6 h-6 text-[#bc9e65] mb-2" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
</svg>
<Image src="/images/home/culinary-heritage/icons/culinary-feast.webp" alt="Imperial Feasts" width={32} height={32} className="object-contain mb-2" />
<h5 className="font-serif text-[10px] sm:text-[11px] font-bold text-[#0a4a2b] tracking-wider uppercase mb-1">
Imperial Feasts
</h5>
@ -217,7 +208,7 @@ export default function SpatialSanctuary() {
<div className="w-full lg:w-[46%] flex justify-center lg:justify-end relative select-none pointer-events-none">
<div className="w-[320px] h-[320px] sm:w-[460px] sm:h-[460px] md:w-[480px] md:h-[480px] relative">
<Image
src="/images/sanctuary_arch.png"
src="/images/home/culinary-heritage/our-culinary-heritage-right.webp"
alt="My Dosa Place Spatial Dining Sanctuary"
fill
sizes="(max-width: 1024px) 100vw, 46vw"
@ -234,7 +225,7 @@ export default function SpatialSanctuary() {
<div className="h-screen flex-shrink-0 w-max flex items-center px-8 sm:px-12 md:px-16 relative bg-[#fdfcf7] py-12 select-none z-10">
{/* Parchment background image for Bento Grid */}
<Image
src="/images/sanctuary_bg.png"
src="/images/home/culinary-heritage/our-culinary-heritage-bg-2.webp"
alt="Traditional South Indian Sanctuary Background"
fill
className="object-fill pointer-events-none select-none z-0"
@ -269,7 +260,7 @@ export default function SpatialSanctuary() {
{/* Card 2: Row 2, Col 1 - Breakfast Classics Image Card */}
<div className="row-span-1 col-span-1 w-full h-full relative rounded-2xl overflow-hidden border border-[#d8c396]/60 shadow-sm group bg-[#0a4a2b]/10">
<Image
src="/images/masala_dosa_luxury.png"
src="/images/home/culinary-heritage/cards/crispy-ghee-roast.webp"
alt="Breakfast Classics"
fill
sizes="240px"
@ -311,7 +302,7 @@ export default function SpatialSanctuary() {
{/* Right image section */}
<div className="w-full sm:w-[50%] h-[150px] sm:h-full relative overflow-hidden">
<Image
src="/images/south_indian_thali_luxury.png"
src="/images/home/culinary-heritage/cards/royal-feast.webp"
alt="Royal Feast Thali"
fill
sizes="480px"
@ -338,7 +329,7 @@ export default function SpatialSanctuary() {
{/* Card 5: Row 2, Col 3 - South Indian Feast Image Card */}
<div className="row-span-1 col-span-1 w-full h-full relative rounded-2xl overflow-hidden border border-[#d8c396]/60 shadow-sm group bg-[#0a4a2b]/10">
<Image
src="/images/south_indian_thali_luxury.png"
src="/images/home/culinary-heritage/cards/heirloom.webp"
alt="South Indian Feast"
fill
sizes="240px"
@ -378,7 +369,7 @@ export default function SpatialSanctuary() {
{/* Card 7: Row 2, Col 4 - Dosa Perfection Image Card */}
<div className="row-span-1 col-span-1 w-full h-full relative rounded-2xl overflow-hidden border border-[#d8c396]/60 shadow-sm group bg-[#0a4a2b]/10">
<Image
src="/images/masala_dosa_luxury.png"
src="/images/home/culinary-heritage/cards/ghee-roast.webp"
alt="Dosa Perfection"
fill
sizes="240px"
@ -398,7 +389,7 @@ export default function SpatialSanctuary() {
{/* Card 8: Row 1, Col 5 - Chef's Specials Image Card */}
<div className="row-span-1 col-span-1 w-full h-full relative rounded-2xl overflow-hidden border border-[#d8c396]/60 shadow-sm group bg-[#0a4a2b]/10">
<Image
src="/images/my_dosa_place_food_royal.png"
src="/images/home/culinary-heritage/cards/seasonal-creations.webp"
alt="Chef's Specials"
fill
sizes="240px"
@ -446,7 +437,7 @@ export default function SpatialSanctuary() {
{/* Card 11: Row 2, Col 6 - Curry Court Image Card */}
<div className="row-span-1 col-span-1 w-full h-full relative rounded-2xl overflow-hidden border border-[#d8c396]/60 shadow-sm group bg-[#0a4a2b]/10">
<Image
src="/images/my_dosa_place_food_traditional.png"
src="/images/home/culinary-heritage/cards/smoked.webp"
alt="Curry Court"
fill
sizes="240px"
@ -480,7 +471,7 @@ export default function SpatialSanctuary() {
{/* Card 13: Row 2, Col 7 - Beverage Bar Image Card */}
<div className="row-span-1 col-span-1 w-full h-full relative rounded-2xl overflow-hidden border border-[#d8c396]/60 shadow-sm group bg-[#0a4a2b]/10">
<Image
src="/images/menu_brass_pot.png"
src="/images/home/culinary-heritage/cards/nectar.webp"
alt="Beverage Bar"
fill
sizes="240px"

View File

@ -25,7 +25,7 @@ export default function SubpageLayout({ children }: { children: React.ReactNode
{/* Lenis Scroll syncing with GSAP triggers */}
<SmoothScroll>
<div className="pt-24 min-h-screen flex flex-col justify-between">
<div className="flex flex-col justify-between">
<div className="flex-1 w-full relative z-10">
{children}
</div>

View File

@ -0,0 +1,134 @@
"use client";
import { useState, useEffect, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { formatReviewsForHome } from "@/lib/reviewUtils";
export default function TestimonialSlider() {
const [current, setCurrent] = useState(0);
const [animating, setAnimating] = useState(false);
const [reviews, setReviews] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [expanded, setExpanded] = useState(false);
useEffect(() => {
async function loadReviews() {
try {
const res = await fetch("/api/reviews");
const data = await res.json().catch(() => ({}));
const reviews = Array.isArray(data.reviews) ? data.reviews : [];
setReviews(formatReviewsForHome(reviews));
} catch (error) {
console.error("Reviews fetch failed:", error);
} finally {
setLoading(false);
}
}
loadReviews();
}, []);
const displayReviews = reviews;
const goTo = useCallback(
(index: number) => {
if (animating || displayReviews.length === 0) return;
setAnimating(true);
setExpanded(false); // Reset expanded on slide change
setTimeout(() => {
setCurrent(index);
setAnimating(false);
}, 300);
},
[animating, displayReviews.length]
);
const prev = () => goTo((current - 1 + displayReviews.length) % displayReviews.length);
const next = useCallback(() => goTo((current + 1) % displayReviews.length), [current, displayReviews.length, goTo]);
// Auto-slider logic
useEffect(() => {
if (expanded) return; // Pause if user is reading a long review
const timer = setInterval(next, 5000);
return () => clearInterval(timer);
}, [next, expanded]);
if (loading) {
return <div className="py-20 text-[#bc9e65] text-sm animate-pulse">Loading Google reviews...</div>;
}
if (!displayReviews.length) {
return <div className="py-20 text-[#bc9e65] text-sm">No reviews available at this time.</div>;
}
const review = displayReviews[current % displayReviews.length];
const maxChars = 150;
const isLong = review.text.length > maxChars;
const displayText = expanded ? review.text : (isLong ? `${review.text.substring(0, maxChars)}...` : review.text);
return (
<div className="w-full max-w-3xl mx-auto relative group">
<AnimatePresence mode="wait">
<motion.div
key={current}
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
transition={{ duration: 0.3 }}
className="bg-white/40 border border-[#bc9e65]/30 p-8 sm:p-12 shadow-sm rounded-xl relative"
>
{/* Quote Icon */}
<svg className="absolute w-10 h-10 text-[#bc9e65]/20 top-6 left-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M14.017 21v-7.391c0-5.704 3.731-9.57 8.983-10.609l.995 2.151c-2.432.917-3.995 3.638-3.995 5.849h4v10h-9.983zm-14.017 0v-7.391c0-5.704 3.748-9.57 9-10.609l.996 2.151c-2.433.917-3.996 3.638-3.996 5.849h3.983v10h-9.983z" />
</svg>
{/* Stars */}
<div className="flex justify-center gap-1 mb-6 text-[#bc9e65]">
{[...Array(review.rating)].map((_, i) => (
<svg key={i} className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
</svg>
))}
</div>
<p className="font-sans text-[#4a3c28] text-base sm:text-lg leading-relaxed italic mb-4 min-h-[100px]">
"{displayText}"
{isLong && (
<button
onClick={() => setExpanded(!expanded)}
className="ml-2 text-[#bc9e65] hover:text-[#8a6c3a] font-bold text-xs uppercase tracking-wider transition-colors inline-block"
>
{expanded ? "Read Less" : "Read More"}
</button>
)}
</p>
<div className="w-8 h-px bg-[#bc9e65]/50 mx-auto mb-4" />
<h4 className="font-serif text-[#1a3a25] tracking-widest uppercase text-sm font-bold">
{review.name}
</h4>
<span className="text-[10px] uppercase tracking-widest text-[#8a6c3a] mt-1 block">
{review.role}
</span>
</motion.div>
</AnimatePresence>
{/* Navigation Controls */}
<div className="flex items-center justify-center gap-6 mt-8">
<button onClick={prev} className="p-2 text-[#8a6c3a] hover:text-[#1a3a25] transition-colors">
<svg className="w-5 h-5" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"></polyline></svg>
</button>
<div className="flex items-center gap-2">
{displayReviews.map((_, i) => (
<button
key={i}
onClick={() => goTo(i)}
className={`w-2 h-2 rounded-full transition-all duration-300 ${i === current ? 'bg-[#1a3a25] w-6' : 'bg-[#bc9e65]/40 hover:bg-[#bc9e65]'}`}
/>
))}
</div>
<button onClick={next} className="p-2 text-[#8a6c3a] hover:text-[#1a3a25] transition-colors">
<svg className="w-5 h-5" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"></polyline></svg>
</button>
</div>
</div>
);
}

34
src/lib/reviewUtils.ts Normal file
View File

@ -0,0 +1,34 @@
export const fallbackGoogleReviews = [
{
author_name: "Ayesha K.",
text: "The best Dosa I've had in Waterloo! Reminds me of home. The flavors are absolutely authentic and the service is wonderful.",
rating: 5,
author_title: "Local Guide",
},
{
author_name: "Marcus T.",
text: "A true culinary journey. The spices are perfectly balanced, the ambiance is stunning, and every dish tells a beautiful story. The attention to detail in every aspect of the meal is astounding. Highly recommended for anyone looking to explore the rich tapestry of Indian cuisine in a warm and welcoming environment.",
rating: 5,
author_title: "Food Critic",
},
{
author_name: "Priya R.",
text: "My go-to place for authentic South Indian comfort food. Their filter coffee and masala dosa are unmatched in the city.",
rating: 5,
author_title: "Regular Customer",
},
];
export function formatReviewsForHome(reviews: any[]) {
if (!Array.isArray(reviews)) return [];
return reviews.map((r) => {
let text = r.snippet || r.text || '';
return {
name: r.author_name || 'Guest',
text: text,
rating: r.rating || 5,
role: r.author_title || 'Reviewer',
initials: (r.author_name || 'G').charAt(0).toUpperCase()
};
});
}

32
src/utils/blogData.ts Normal file
View File

@ -0,0 +1,32 @@
export const BLOG_POSTS = [
{
id: 1,
slug: "art-of-fermenting-dosa-batter",
title: "The Art of Fermenting Dosa Batter: A 24-Hour Ritual",
desc: "Discover the traditional science and family secrets behind cultivating the perfect sourness and crispiness for our signature stone-ground dosas.",
date: "JULY 15, 2026",
image: "/images/masala_dosa_luxury.png",
author: "Chef Mendia Juxef",
content: "Fermentation is the soul of a perfect dosa. It transforms a simple mixture of rice and lentils into a complex, tangy, and airy batter. At My Dosa Place, our 24-hour ritual involves careful temperature control, precise proportions of wild fermentation, and a lot of patience.\n\nThe result? A dosa that is crisp on the outside, porous on the inside, and packed with flavor that transports you straight to the streets of South India. We source the finest rice and urad dal, soaking them for hours before stone-grinding them to the perfect consistency. This batter is then left to ferment naturally, allowing the wild yeasts to work their magic and develop that signature sour tang that makes our dosas unforgettable."
},
{
id: 2,
slug: "secret-spices-of-chettinad-cookery",
title: "Secret Spices of Chettinad Cookery",
desc: "Unveiling the delicate proportions of kalpasi (stone flower), star anise, and freshly crushed peppercorns that define our royal spice blends.",
date: "JUNE 28, 2026",
image: "/images/category_curries.jpg",
author: "My Dosa Place Culinary Team",
content: "Chettinad cuisine is renowned for its bold and complex flavors, achieved through a masterful blending of spices. Key ingredients like kalpasi (stone flower) impart a unique, earthy aroma, while star anise adds a touch of sweetness. Freshly crushed peppercorns provide the signature heat.\n\nBy roasting and grinding these spices in-house, we ensure every dish captures the authentic, royal essence of Chettinad cookery. The secret lies not just in the ingredients, but in the precise ratios and the traditional roasting techniques passed down through generations. Each spice blend is a carefully guarded secret, ensuring that every bite of our Chettinad curries is a journey into culinary royalty."
},
{
id: 3,
slug: "why-brass-cookware-remains-king",
title: "Why Brass Cookware Remains King in Heritage Dining",
desc: "How slow-heating copper and brass vessels preserve the vital nutrients and aroma of our house-cooked lentil sambar and vegetable poriyals.",
date: "MAY 12, 2026",
image: "/images/south_indian_thali_luxury.png",
author: "Heritage Preservation Society",
content: "In our modern kitchens, the wisdom of the past still reigns supreme. Cooking in traditional brass and copper vessels is more than just a nod to heritage; it's a culinary technique that enhances the flavor and nutritional value of our food.\n\nThe slow, even heating of these metals ensures that our sambar and poriyals simmer gently, allowing the spices to meld perfectly and the aromas to flourish without losing their vital nutrients. Beyond functionality, these vessels bring an aesthetic richness to the dining experience, connecting us to the culinary traditions of our ancestors and reminding us that true flavor takes time."
},
];