bg images updated

This commit is contained in:
Selvi 2026-07-21 17:57:12 +05:30
parent 4c5ce6a1bf
commit 44f0134a49
45 changed files with 222 additions and 200 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/images/card.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

@ -348,7 +348,7 @@ export default function AboutPage() {
</AnimatedSection> </AnimatedSection>
{/* Cards Grid */} {/* Cards Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 w-full mb-20 relative"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 w-full mb-20 relative">
{/* Decorators between cards */} {/* Decorators between cards */}
<div className="hidden lg:block absolute left-1/4 top-1/2 -translate-y-1/2 -ml-2 z-30"> <div className="hidden lg:block absolute left-1/4 top-1/2 -translate-y-1/2 -ml-2 z-30">
<div className="w-3 h-3 rotate-45 border border-[#bc9e65] bg-[#0a2e1f]" /> <div className="w-3 h-3 rotate-45 border border-[#bc9e65] bg-[#0a2e1f]" />
@ -361,28 +361,33 @@ export default function AboutPage() {
</div> </div>
{values.map((v, i) => ( {values.map((v, i) => (
<AnimatedSection key={v.label} variant="fadeUp" delay={i * 0.1}> <AnimatedSection key={v.label} variant="fadeUp" delay={i * 0.1} className="h-full">
<div className="relative group bg-[#0a2e1f] border border-[#bc9e65] rounded-t-[50px] rounded-b-xl px-6 py-12 flex flex-col items-center text-center shadow-[0_10px_30px_rgba(0,0,0,0.5)] transition-transform duration-300 hover:-translate-y-2 h-full z-20"> <div className="relative group px-6 py-12 flex flex-col items-center justify-center text-center transition-transform duration-300 hover:-translate-y-2 h-full min-h-[380px] sm:min-h-[400px] z-20">
{/* Scalloped top inner border approximation */} {/* Card Background Image (Expanded horizontally to make the visible border wider) */}
<div className="absolute inset-2 border border-[#bc9e65]/30 rounded-t-[42px] rounded-b-lg pointer-events-none" /> <div className="absolute -inset-x-4 sm:-inset-x-6 -inset-y-2 z-0 pointer-events-none">
<Image
{/* Gold Circular Icon */} src="/images/card.png"
<div className="w-[84px] h-[84px] rounded-full border-[2px] border-[#bc9e65] bg-gradient-to-br from-[#bc9e65]/20 to-transparent flex items-center justify-center text-[#bc9e65] mb-8 relative shadow-[0_0_15px_rgba(188,158,101,0.2)]"> alt="Card Frame"
<div className="absolute inset-1.5 border border-[#bc9e65]/50 rounded-full" /> fill
{v.icon} sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 25vw"
className="object-fill"
/>
</div> </div>
<h3 className="font-serif text-white text-xl uppercase tracking-widest mb-4"> {/* Content (Constrained width to stay inside borders) */}
{v.label} <div className="relative z-10 flex flex-col items-center w-full px-2 sm:px-10">
</h3> {/* Gold Circular Icon */}
{/* <div className="flex justify-center mb-5"> <div className="w-[84px] h-[84px] rounded-full flex items-center justify-center text-[#bc9e65] mb-6 relative">
<svg className="w-4 h-4 text-[#bc9e65]" viewBox="0 0 30 20" fill="currentColor"> {v.icon}
<path d="M 15,3 C 13,8 14,14 15,16 C 16,14 17,8 15,3 Z" /> </div>
</svg>
</div> */} <h3 className="font-serif text-white text-base uppercase tracking-widest mb-3">
<p className="font-sans text-stone-200 text-sm leading-relaxed px-2"> {v.label}
{v.desc} </h3>
</p> <p className="font-sans text-stone-200 text-sm leading-relaxed max-w-[85%] md:max-w-[55%] lg:max-w-[85%] mx-auto">
{v.desc}
</p>
</div>
</div> </div>
</AnimatedSection> </AnimatedSection>
))} ))}
@ -445,7 +450,7 @@ export default function AboutPage() {
*/} */}
<div className="relative w-full bg-[#fdfaf4] overflow-hidden"> <div className="relative w-full bg-[#fdfaf4] overflow-hidden">
<div className="absolute inset-0 z-0 pointer-events-none select-none"> <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 opacity-60 mix-blend-multiply" /> <Image src="/images/about/bg/testimonial-bg.webp" alt="" fill className="object-cover object-center opacity-60 mix-blend-multiply" />
</div> </div>
<div className="relative z-10 max-w-6xl mx-auto px-6 py-20 sm:py-24 text-center"> <div className="relative z-10 max-w-6xl mx-auto px-6 py-20 sm:py-24 text-center">
@ -457,7 +462,7 @@ export default function AboutPage() {
</svg> </svg>
</div> </div>
<p className="font-sans text-[11px] tracking-[0.3em] text-[#8a6c3a] uppercase font-bold mb-3"> <p className="font-sans text-[11px] tracking-[0.3em] text-[#bc9e65] uppercase font-bold mb-3">
Words of Love Words of Love
</p> </p>
<h2 className="font-serif text-4xl sm:text-5xl text-[#1a3a25] tracking-wider mb-2"> <h2 className="font-serif text-4xl sm:text-5xl text-[#1a3a25] tracking-wider mb-2">
@ -730,7 +735,7 @@ export default function AboutPage() {
<div className="w-12 h-[1.5px] bg-gradient-to-l from-transparent to-[#bc9e65]" /> <div className="w-12 h-[1.5px] bg-gradient-to-l from-transparent to-[#bc9e65]" />
</div> </div>
<p className="font-sans text-[11px] tracking-[0.3em] text-[#8a6c3a] uppercase font-bold mb-4"> <p className="font-sans text-[11px] tracking-[0.3em] text-[#bc9e65] uppercase font-bold mb-4">
Come Dine With Us Come Dine With Us
</p> </p>
@ -738,7 +743,7 @@ export default function AboutPage() {
EXPERIENCE THE TASTE OF EXPERIENCE THE TASTE OF
</h2> </h2>
<h2 className="font-serif text-4xl sm:text-6xl lg:text-[90px] text-transparent bg-clip-text bg-gradient-to-b from-[#d9b876] to-[#8a6c3a] tracking-widest leading-none mb-6 drop-shadow-sm font-bold" style={{ textShadow: "0px 4px 15px rgba(188,158,101,0.3)" }}> <h2 className="font-serif text-4xl sm:text-6xl lg:text-[90px] text-transparent bg-clip-text bg-gradient-to-b from-[#d9b876] to-[#bc9e65] tracking-widest leading-none mb-6 drop-shadow-sm font-bold" style={{ textShadow: "0px 4px 15px rgba(188,158,101,0.3)" }}>
TRADITION TRADITION
</h2> </h2>
@ -760,7 +765,7 @@ export default function AboutPage() {
}} }}
> >
{/* Inner subtle border effect */} {/* Inner subtle border effect */}
<div className="absolute inset-[3px] border border-[#8a6c3a]/30 pointer-events-none" style={{ <div className="absolute inset-[3px] border border-[#bc9e65]/30 pointer-events-none" style={{
clipPath: "polygon(9px 0, calc(100% - 9px) 0, 100% 9px, 100% calc(100% - 9px), calc(100% - 9px) 100%, 9px 100%, 0 calc(100% - 9px), 0 9px)" clipPath: "polygon(9px 0, calc(100% - 9px) 0, 100% 9px, 100% calc(100% - 9px), calc(100% - 9px) 100%, 9px 100%, 0 calc(100% - 9px), 0 9px)"
}} /> }} />

View File

@ -36,65 +36,65 @@ export default function BlogPage() {
</div> </div>
<div className="max-w-6xl mx-auto px-6 py-12 lg:py-20 relative z-10"> <div className="max-w-6xl 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"> <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) => ( {BLOG_POSTS.map((post, index) => (
<AnimatedSection key={post.id} variant="fadeUp" delay={index * 0.1}> <AnimatedSection key={post.id} variant="fadeUp" delay={index * 0.1}>
<div <div
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" 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"
> >
{/* Image Container with fade out */} {/* Image Container with fade out */}
<div className="relative w-full aspect-[4/3] overflow-hidden border-b-1 border-[#0a4a2b]"> <div className="relative w-full aspect-[4/3] overflow-hidden border-b-1 border-[#0a4a2b]">
<Image <Image
src={post.cardImage || post.image} src={post.cardImage || post.image}
alt={post.title} alt={post.title}
fill fill
sizes="(max-width: 768px) 100vw, 30vw" sizes="(max-width: 768px) 100vw, 30vw"
className="object-cover group-hover:scale-105 transition-transform duration-700" 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 */} {/* Gradient fade to match background */}
<div className="absolute bottom-4 left-5 z-20 bg-[#0a4a2b] rounded-md px-3 py-1.5 shadow-md"> <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" />
<span className="font-sans text-[10px] font-extrabold tracking-widest text-[#fff] uppercase">
{post.id === 1 ? "Recipes" : post.id === 2 ? "Ingredients" : "Behind The Scenes"} {/* Floating Tag */}
</span> <div className="absolute bottom-0 right-0 z-20 bg-[#0a4a2b] rounded-tl-xl px-4 py-1.5 shadow-md border-t border-l border-[#0a4a2b]">
<span className="font-sans text-[10px] font-extrabold tracking-widest text-[#fff] uppercase">
{post.id === 1 ? "Recipes" : post.id === 2 ? "Ingredients" : "Behind The Scenes"}
</span>
</div>
</div>
{/* 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-[#bc9e65] 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}
</span>
{/* Expanding line */}
<div className="flex-1 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>
</div> </div>
</div> </AnimatedSection>
))}
{/* Card Body */} </div>
<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}
</span>
{/* Expanding line */}
<div className="flex-1 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>
</div>
</AnimatedSection>
))}
</div>
</div> </div>
</div> </div>
</SubpageLayout> </SubpageLayout>

View File

@ -50,11 +50,11 @@ export default function ContactPage() {
{/* Sandstone bg image with pots and diyas on the bottom corners */} {/* Sandstone bg image with pots and diyas on the bottom corners */}
<div className="absolute inset-0 z-0 pointer-events-none select-none"> <div className="absolute inset-0 z-0 pointer-events-none select-none">
<Image <Image
src="/images/story_bg.png" src="/images/about/bg/contact-bg.webp"
alt="Background" alt="Background"
fill fill
priority priority
className="object-cover object-center opacity-90 mix-blend-multiply" className="object-cover object-center mix-blend-multiply"
/> />
</div> </div>
@ -80,7 +80,7 @@ export default function ContactPage() {
{/* Phone */} {/* Phone */}
<div className="flex items-center lg:items-start gap-6 group"> <div className="flex items-center lg:items-start gap-6 group">
<div className="relative w-14 h-14 flex items-center justify-center shrink-0"> <div className="relative w-12 h-15 flex items-center justify-center shrink-0">
<svg className="absolute inset-0 w-full h-full text-[#0a2e1f]" viewBox="0 0 100 100"> <svg className="absolute inset-0 w-full h-full text-[#0a2e1f]" viewBox="0 0 100 100">
<path d="M50 2 C60 2 62 10 70 12 C78 14 84 8 88 15 C92 22 86 28 88 36 C90 44 98 46 98 55 C98 64 90 66 88 74 C86 82 92 88 88 95 C84 102 78 96 70 98 C62 100 60 108 50 108 C40 108 38 100 30 98 C22 96 16 102 12 95 C8 88 14 82 12 74 C10 66 2 64 2 55 C2 46 10 44 12 36 C14 28 8 22 12 15 C16 8 22 14 30 12 C38 10 40 2 50 2 Z" fill="currentColor" stroke="#bc9e65" strokeWidth="3" /> <path d="M50 2 C60 2 62 10 70 12 C78 14 84 8 88 15 C92 22 86 28 88 36 C90 44 98 46 98 55 C98 64 90 66 88 74 C86 82 92 88 88 95 C84 102 78 96 70 98 C62 100 60 108 50 108 C40 108 38 100 30 98 C22 96 16 102 12 95 C8 88 14 82 12 74 C10 66 2 64 2 55 C2 46 10 44 12 36 C14 28 8 22 12 15 C16 8 22 14 30 12 C38 10 40 2 50 2 Z" fill="currentColor" stroke="#bc9e65" strokeWidth="3" />
</svg> </svg>
@ -97,7 +97,7 @@ export default function ContactPage() {
{/* Email */} {/* Email */}
<div className="flex items-center lg:items-start gap-6 group"> <div className="flex items-center lg:items-start gap-6 group">
<div className="relative w-14 h-14 flex items-center justify-center shrink-0"> <div className="relative w-12 h-15 flex items-center justify-center shrink-0">
<svg className="absolute inset-0 w-full h-full text-[#0a2e1f]" viewBox="0 0 100 100"> <svg className="absolute inset-0 w-full h-full text-[#0a2e1f]" viewBox="0 0 100 100">
<path d="M50 2 C60 2 62 10 70 12 C78 14 84 8 88 15 C92 22 86 28 88 36 C90 44 98 46 98 55 C98 64 90 66 88 74 C86 82 92 88 88 95 C84 102 78 96 70 98 C62 100 60 108 50 108 C40 108 38 100 30 98 C22 96 16 102 12 95 C8 88 14 82 12 74 C10 66 2 64 2 55 C2 46 10 44 12 36 C14 28 8 22 12 15 C16 8 22 14 30 12 C38 10 40 2 50 2 Z" fill="currentColor" stroke="#bc9e65" strokeWidth="3" /> <path d="M50 2 C60 2 62 10 70 12 C78 14 84 8 88 15 C92 22 86 28 88 36 C90 44 98 46 98 55 C98 64 90 66 88 74 C86 82 92 88 88 95 C84 102 78 96 70 98 C62 100 60 108 50 108 C40 108 38 100 30 98 C22 96 16 102 12 95 C8 88 14 82 12 74 C10 66 2 64 2 55 C2 46 10 44 12 36 C14 28 8 22 12 15 C16 8 22 14 30 12 C38 10 40 2 50 2 Z" fill="currentColor" stroke="#bc9e65" strokeWidth="3" />
</svg> </svg>
@ -114,7 +114,7 @@ export default function ContactPage() {
{/* Location */} {/* Location */}
<div className="flex items-center lg:items-start gap-6 group"> <div className="flex items-center lg:items-start gap-6 group">
<div className="relative w-14 h-14 flex items-center justify-center shrink-0"> <div className="relative w-12 h-15 flex items-center justify-center shrink-0">
<svg className="absolute inset-0 w-full h-full text-[#0a2e1f]" viewBox="0 0 100 100"> <svg className="absolute inset-0 w-full h-full text-[#0a2e1f]" viewBox="0 0 100 100">
<path d="M50 2 C60 2 62 10 70 12 C78 14 84 8 88 15 C92 22 86 28 88 36 C90 44 98 46 98 55 C98 64 90 66 88 74 C86 82 92 88 88 95 C84 102 78 96 70 98 C62 100 60 108 50 108 C40 108 38 100 30 98 C22 96 16 102 12 95 C8 88 14 82 12 74 C10 66 2 64 2 55 C2 46 10 44 12 36 C14 28 8 22 12 15 C16 8 22 14 30 12 C38 10 40 2 50 2 Z" fill="currentColor" stroke="#bc9e65" strokeWidth="3" /> <path d="M50 2 C60 2 62 10 70 12 C78 14 84 8 88 15 C92 22 86 28 88 36 C90 44 98 46 98 55 C98 64 90 66 88 74 C86 82 92 88 88 95 C84 102 78 96 70 98 C62 100 60 108 50 108 C40 108 38 100 30 98 C22 96 16 102 12 95 C8 88 14 82 12 74 C10 66 2 64 2 55 C2 46 10 44 12 36 C14 28 8 22 12 15 C16 8 22 14 30 12 C38 10 40 2 50 2 Z" fill="currentColor" stroke="#bc9e65" strokeWidth="3" />
</svg> </svg>
@ -303,9 +303,9 @@ export default function ContactPage() {
{/* ── OPENING HOURS + MAP ROW ── */} {/* ── OPENING HOURS + MAP ROW ── */}
<AnimatedSection variant="fadeUp" delay={0.1}> <AnimatedSection variant="fadeUp" delay={0.1}>
<div className="relative max-w-7xl mx-auto w-[calc(100%-3rem)] bg-[#0a2e1f] border border-[#bc9e65]/20 rounded-2xl mb-16 overflow-hidden shadow-2xl"> <div className="relative max-w-7xl mx-auto w-[calc(100%-3rem)] bg-[#0a2e1f] border border-[#bc9e65]/20 rounded-2xl mb-16 overflow-hidden shadow-2xl">
<div className="absolute inset-0 pointer-events-none select-none opacity-20"> <div className="absolute inset-0 pointer-events-none select-none">
<Image <Image
src="/images/footer_bg.png" src="/images/about/bg/map-bg.webp"
alt="Background" alt="Background"
fill fill
className="object-cover object-center" className="object-cover object-center"

View File

@ -26,6 +26,8 @@ export const metadata: Metadata = {
} }
}; };
import ScrollToTop from "@/components/ScrollToTop";
export default function RootLayout({ export default function RootLayout({
children, children,
}: Readonly<{ }: Readonly<{
@ -38,6 +40,7 @@ export default function RootLayout({
> >
<body className="min-h-full bg-darkbg text-foreground"> <body className="min-h-full bg-darkbg text-foreground">
{children} {children}
<ScrollToTop />
</body> </body>
</html> </html>
); );

View File

@ -3,66 +3,17 @@
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import Image from "next/image"; import Image from "next/image";
// Custom Gold Category Icons (SVG Paths) // Custom Image Icons
const LeafThaliIcon = () => ( const ThaliIcon = () => <Image src="/images/home/culinary-categories/icons/thali.png" alt="Thali" width={40} height={40} className="object-contain" />;
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor"> const DosaIcon = () => <Image src="/images/home/culinary-categories/icons/dosa.png" alt="Dosa" width={40} height={40} className="object-contain" />;
<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" /> const UthappamIcon = () => <Image src="/images/home/culinary-categories/icons/uthappam.png" alt="Uthappam" width={40} height={40} className="object-contain" />;
</svg> const VadaIcon = () => <Image src="/images/home/culinary-categories/icons/vada.png" alt="Vada" width={40} height={40} className="object-contain" />;
); const AppetizerIcon = () => <Image src="/images/home/culinary-categories/icons/appetizer.png" alt="Appetizer" width={40} height={40} className="object-contain" />;
const TiffinIcon = () => <Image src="/images/home/culinary-categories/icons/tiffin.png" alt="Tiffin" width={40} height={40} className="object-contain" />;
const BiryaniRiceIcon = () => ( const RiceIcon = () => <Image src="/images/home/culinary-categories/icons/rice.png" alt="Rice" width={40} height={40} className="object-contain" />;
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor"> const BreadsIcon = () => <Image src="/images/home/culinary-categories/icons/breads.png" alt="Breads" width={40} height={40} className="object-contain" />;
<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" /> const ComboIcon = () => <Image src="/images/home/culinary-categories/icons/combo.png" alt="Combo" width={40} height={40} className="object-contain" />;
</svg> const DessertIcon = () => <Image src="/images/home/culinary-categories/icons/dessert.png" alt="Desserts" width={40} height={40} className="object-contain" />;
);
const TiffinsDosasIcon = () => (
<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-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-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-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-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-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-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-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>
);
// Ornate Corner Leaf Ornament Vector details // Ornate Corner Leaf Ornament Vector details
const CornerOrnaments = () => ( const CornerOrnaments = () => (
@ -93,7 +44,7 @@ const ROW1_CATEGORIES = [
subtitle: "FEATURED", subtitle: "FEATURED",
desc: "A wholesome spread of authentic South Indian flavors served the traditional way.", desc: "A wholesome spread of authentic South Indian flavors served the traditional way.",
image: "/images/home/culinary-categories/left-single-card-Traditional-Thali.webp", image: "/images/home/culinary-categories/left-single-card-Traditional-Thali.webp",
icon: LeafThaliIcon, icon: ThaliIcon,
isDouble: true, isDouble: true,
}, },
{ {
@ -101,21 +52,21 @@ const ROW1_CATEGORIES = [
title: "Crispy Dosas", title: "Crispy Dosas",
desc: "Golden, crisp and served with fresh chutneys.", desc: "Golden, crisp and served with fresh chutneys.",
image: "/images/home/culinary-categories/right-side-dosa.webp", image: "/images/home/culinary-categories/right-side-dosa.webp",
icon: TiffinsDosasIcon, icon: DosaIcon,
}, },
{ {
id: "uthappam", id: "uthappam",
title: "Soft Uthappam", title: "Soft Uthappam",
desc: "Thick, soft pancakes topped with fresh ingredients.", desc: "Thick, soft pancakes topped with fresh ingredients.",
image: "/images/home/culinary-categories/right-side-utthappam.webp", image: "/images/home/culinary-categories/right-side-utthappam.webp",
icon: TiffinsDosasIcon, icon: UthappamIcon,
}, },
{ {
id: "vada", id: "vada",
title: "Crispy Vada", title: "Crispy Vada",
desc: "Golden fried lentil donuts, crispy outside and soft inside.", desc: "Golden fried lentil donuts, crispy outside and soft inside.",
image: "/images/home/culinary-categories/right-side-vada.webp", image: "/images/home/culinary-categories/right-side-vada.webp",
icon: TiffinsDosasIcon, icon: VadaIcon,
}, },
]; ];
@ -125,49 +76,49 @@ const ROW2_CATEGORIES = [
title: "Appetizers", title: "Appetizers",
desc: "Perfect starters to begin your culinary journey.", desc: "Perfect starters to begin your culinary journey.",
image: "/images/home/culinary-categories/bottom-appetizer.webp", image: "/images/home/culinary-categories/bottom-appetizer.webp",
icon: ChefSpecialsIcon, icon: AppetizerIcon,
}, },
{ {
id: "tiffin", id: "tiffin",
title: "Tiffins", title: "Tiffins",
desc: "Authentic quick bites full of traditional flavors.", desc: "Authentic quick bites full of traditional flavors.",
image: "/images/home/culinary-categories/bottom-tiffin.webp", image: "/images/home/culinary-categories/bottom-tiffin.webp",
icon: TiffinsDosasIcon, icon: TiffinIcon,
}, },
{ {
id: "rice", id: "rice",
title: "Rice Bowls", title: "Rice Bowls",
desc: "Aromatic and flavorful rice specialties.", desc: "Aromatic and flavorful rice specialties.",
image: "/images/home/culinary-categories/bottom-rice.webp", image: "/images/home/culinary-categories/bottom-rice.webp",
icon: BiryaniRiceIcon, icon: RiceIcon,
}, },
{ {
id: "breads", id: "breads",
title: "Indian Breads", title: "Indian Breads",
desc: "Soft, warm breads fresh from our tandoor.", desc: "Soft, warm breads fresh from our tandoor.",
image: "/images/home/culinary-categories/bottom-breads.webp", image: "/images/home/culinary-categories/bottom-breads.webp",
icon: TandoorSpecialsIcon, icon: BreadsIcon,
}, },
{ {
id: "combo", id: "combo",
title: "Combos", title: "Combos",
desc: "Carefully curated combinations for a complete meal.", desc: "Carefully curated combinations for a complete meal.",
image: "/images/home/culinary-categories/bottom-combo.webp", image: "/images/home/culinary-categories/bottom-combo.webp",
icon: BanquetMenusIcon, icon: ComboIcon,
}, },
{ {
id: "dessert", id: "dessert",
title: "Desserts & Beverages", title: "Desserts & Beverages",
desc: "Sweet endings and refreshing traditional drinks.", desc: "Sweet endings and refreshing traditional drinks.",
image: "/images/home/culinary-categories/bottom-dessert-beverages.webp", image: "/images/home/culinary-categories/bottom-dessert-beverages.webp",
icon: SweetsDessertsIcon, icon: DessertIcon,
}, },
]; ];
export default function CulinaryCategories() { export default function CulinaryCategories() {
return ( return (
<section id="categories" className="relative w-full py-28 px-6 sm:px-12 md:px-16 lg:px-24 overflow-hidden z-20 bg-[#06120c]"> <section id="categories" className="relative w-full py-28 px-6 sm:px-12 md:px-16 lg:px-24 overflow-hidden z-20 bg-[#06120c]">
{/* Background Graphic Template Layer */} {/* Background Graphic Template Layer */}
<div className="absolute inset-0 z-0 pointer-events-none select-none"> <div className="absolute inset-0 z-0 pointer-events-none select-none">
<Image <Image
@ -180,7 +131,7 @@ export default function CulinaryCategories() {
</div> </div>
<div className="container max-w-[1300px] mx-auto relative z-10 flex flex-col gap-14 items-center"> <div className="container max-w-[1300px] mx-auto relative z-10 flex flex-col gap-14 items-center">
{/* Title Area */} {/* Title Area */}
<div className="flex flex-col items-center text-center select-text max-w-3xl"> <div className="flex flex-col items-center text-center select-text max-w-3xl">
<div className="flex items-center gap-3 mb-3"> <div className="flex items-center gap-3 mb-3">
@ -212,7 +163,7 @@ export default function CulinaryCategories() {
{/* Categories Grid Container */} {/* Categories Grid Container */}
<div className="w-full flex flex-col gap-6"> <div className="w-full flex flex-col gap-6">
{/* Row 1 Grid: 5 columns on desktop */} {/* Row 1 Grid: 5 columns on desktop */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-6 w-full"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-6 w-full">
{ROW1_CATEGORIES.map((cat) => { {ROW1_CATEGORIES.map((cat) => {
@ -246,7 +197,7 @@ export default function CulinaryCategories() {
<div className="relative w-36 h-36 sm:w-40 sm:h-40 lg:w-36 lg:h-36 xl:w-40 xl:h-40 flex-shrink-0 z-10"> <div className="relative w-36 h-36 sm:w-40 sm:h-40 lg:w-36 lg:h-36 xl:w-40 xl:h-40 flex-shrink-0 z-10">
{/* Spin ring behind thali */} {/* Spin ring behind thali */}
<div className="absolute inset-[-6px] border border-dashed border-[#bc9e65]/25 rounded-full animate-[spin_60s_linear_infinite]" /> <div className="absolute inset-[-6px] border border-dashed border-[#bc9e65]/25 rounded-full animate-[spin_60s_linear_infinite]" />
<div className="w-full h-full rounded-full border-2 border-[#bc9e65]/40 p-1 bg-[#06120c] overflow-hidden shadow-xl relative"> <div className="w-full h-full rounded-full border-2 border-[#bc9e65]/40 p-1 bg-[#06120c] overflow-hidden shadow-xl relative">
<div className="w-full h-full rounded-full overflow-hidden relative"> <div className="w-full h-full rounded-full overflow-hidden relative">
<Image <Image
@ -273,7 +224,7 @@ export default function CulinaryCategories() {
<p className="font-sans text-stone-300 text-[11px] lg:text-xs leading-relaxed tracking-wider mb-4 max-w-[240px]"> <p className="font-sans text-stone-300 text-[11px] lg:text-xs leading-relaxed tracking-wider mb-4 max-w-[240px]">
{cat.desc} {cat.desc}
</p> </p>
<a <a
href="#menu" href="#menu"
className="clickable inline-flex items-center gap-2 font-sans font-bold text-[9px] tracking-[0.2em] text-[#bc9e65] uppercase hover:text-white transition-colors duration-300" className="clickable inline-flex items-center gap-2 font-sans font-bold text-[9px] tracking-[0.2em] text-[#bc9e65] uppercase hover:text-white transition-colors duration-300"

View File

@ -182,7 +182,7 @@ export default function EventsAccordion() {
whileInView={{ opacity: 1, y: 0 }} whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }} viewport={{ once: true }}
transition={{ duration: 0.8, delay: 0.1, ease: "easeOut" }} transition={{ duration: 0.8, delay: 0.1, ease: "easeOut" }}
className="flex flex-col lg:flex-row gap-5 h-[800px] lg:h-[460px] w-full items-stretch relative z-20" className="flex flex-col lg:flex-row gap-5 max-[400px]:h-[950px] h-[800px] lg:h-[460px] w-full items-stretch relative z-20"
> >
{events.map((event, idx) => { {events.map((event, idx) => {
const isActive = idx === activeIdx; const isActive = idx === activeIdx;

View File

@ -16,7 +16,7 @@ export default function Footer() {
}; };
return ( return (
<footer id="footer" className="relative w-full py-16 overflow-hidden z-20"> <footer id="footer" className="relative w-full pt-16 pb-10 overflow-hidden z-20">
{/* Consolidated Mockup Background Layer */} {/* Consolidated Mockup Background Layer */}
<div className="absolute inset-0 z-0 pointer-events-none select-none"> <div className="absolute inset-0 z-0 pointer-events-none select-none">
@ -25,7 +25,7 @@ export default function Footer() {
alt="Footer Backdrop" alt="Footer Backdrop"
fill fill
priority priority
className="object-cover object-center" className="object-cover object-center md:object-fill"
/> />
</div> </div>
@ -235,11 +235,11 @@ export default function Footer() {
<span className="select-text">+1 519-888-7459</span> <span className="select-text">+1 519-888-7459</span>
</div> </div>
{/* Email */} {/* Email */}
<div className="flex items-center gap-3"> <div className="flex items-start gap-3">
<div className="w-9 h-9 rounded-full border border-[#bc9e65]/35 flex items-center justify-center text-[#bc9e65] flex-shrink-0"> <div className="w-9 h-9 rounded-full border border-[#bc9e65]/35 flex items-center justify-center text-[#bc9e65] flex-shrink-0 mt-0.5">
<Mail size={13} /> <Mail size={13} />
</div> </div>
<span className="select-text">mydosaplacewaterloo@gmail.com</span> <span className="select-text break-all">mydosaplacewaterloo@gmail.com</span>
</div> </div>
</div> </div>
</div> </div>
@ -247,7 +247,7 @@ export default function Footer() {
</div> </div>
{/* Footer Bottom copyright & credits bar */} {/* Footer Bottom copyright & credits bar */}
<div className="pt-6 mt-8 flex flex-col items-center justify-center text-center gap-2 text-stone-300 font-sans text-xs tracking-[0.2em] uppercase select-text relative z-10"> <div className="mt-8 flex flex-col items-center justify-center text-center gap-2 text-stone-300 font-sans text-xs tracking-[0.2em] uppercase select-text relative z-10">
<p> <p>
© 2026 My Dosa Place. All rights reserved. | Powered by <a href="https://metatroncubesolutions.com/" target="_blank" rel="noopener noreferrer" className="hover:text-[#bc9e65] transition-colors">Metatroncube</a> © 2026 My Dosa Place. All rights reserved. | Powered by <a href="https://metatroncubesolutions.com/" target="_blank" rel="noopener noreferrer" className="hover:text-[#bc9e65] transition-colors">Metatroncube</a>
</p> </p>

View File

@ -27,7 +27,7 @@ export default function InnerBanner({ pageName, bgImage = "/images/inner-banner.
<div className="absolute bottom-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 */} {/* Content */}
<div className="relative z-20 flex flex-col items-center text-center px-6"> <div className="relative z-20 flex flex-col items-center text-center px-6 top-10">
{/* Breadcrumb */} {/* Breadcrumb */}
<div className="flex items-center gap-2.5 mb-4"> <div className="flex items-center gap-2.5 mb-4">
<Link <Link

View File

@ -17,6 +17,8 @@ const TABS = [
{ id: "rice", label: "RICE" }, { id: "rice", label: "RICE" },
{ id: "beverages", label: "BEVERAGES" }, { id: "beverages", label: "BEVERAGES" },
{ id: "weekend", label: "WEEKEND SPL" }, { id: "weekend", label: "WEEKEND SPL" },
{ id: "sides", label: "SIDES" },
{ id: "desserts", label: "DESSERTS" },
]; ];
const MENU_ITEMS = [ const MENU_ITEMS = [
@ -117,6 +119,18 @@ const MENU_ITEMS = [
{ id: 123, name: "POP / WATER", desc: "Chilled soft drink or still water.", price: "$2.99", tag: "BEVERAGES", bg: "light" }, { id: 123, name: "POP / WATER", desc: "Chilled soft drink or still water.", price: "$2.99", tag: "BEVERAGES", bg: "light" },
{ id: 124, name: "MASALA CHAI", desc: "Aromatic spiced tea brewed with ginger, cardamom & milk.", price: "$4.99", tag: "BEVERAGES", bg: "light" }, { id: 124, name: "MASALA CHAI", desc: "Aromatic spiced tea brewed with ginger, cardamom & milk.", price: "$4.99", tag: "BEVERAGES", bg: "light" },
{ id: 125, name: "FILTER COFFEE", desc: "Authentic South Indian decoction coffee with frothy milk.", price: "$4.99", tag: "BEVERAGES", bg: "dark" }, { id: 125, name: "FILTER COFFEE", desc: "Authentic South Indian decoction coffee with frothy milk.", price: "$4.99", tag: "BEVERAGES", bg: "dark" },
// ── SIDES ─────────────────────────────────────────────────────────────
{ id: 130, name: "SAMBAR", desc: "Traditional South Indian lentil and vegetable stew.", price: "$2.50", tag: "SIDES", bg: "light" },
{ id: 131, name: "PODI", desc: "Spicy and aromatic gunpowder condiment.", price: "$1.99", tag: "SIDES", bg: "light" },
{ id: 132, name: "MASALA", desc: "Flavourful spiced potato filling.", price: "$2.50", tag: "SIDES", bg: "light" },
{ id: 133, name: "EXTRA", desc: "Additional accompaniments for your meal.", price: "$1.99", tag: "SIDES", bg: "light" },
// ── DESSERTS ──────────────────────────────────────────────────────────
{ id: 140, name: "GULAB JAMUN", desc: "Soft milk dumplings immersed in rose-scented syrup.", price: "$5.99", tag: "DESSERTS", bg: "light" },
{ id: 141, name: "RASAMALAI", desc: "Spongy cottage cheese discs soaked in sweetened milk.", price: "$5.99", tag: "DESSERTS", bg: "light" },
{ id: 142, name: "PINEAPPLE KESARI", desc: "Sweet semolina pudding flavoured with pineapple chunks.", price: "$6.99", tag: "DESSERTS", bg: "light" },
{ id: 143, name: "PAYASAM", desc: "Traditional rich and creamy South Indian sweet pudding.", price: "$7.99", tag: "DESSERTS", bg: "light" },
]; ];
export default function MenuPageContent() { export default function MenuPageContent() {
@ -134,6 +148,8 @@ export default function MenuPageContent() {
rice: "RICE", rice: "RICE",
beverages: "BEVERAGES", beverages: "BEVERAGES",
weekend: "WEEKEND SPL", weekend: "WEEKEND SPL",
sides: "SIDES",
desserts: "DESSERTS",
}; };
const filteredItems = const filteredItems =

View File

@ -0,0 +1,46 @@
"use client";
import { useState, useEffect } from "react";
import { ChevronsUp } from "lucide-react";
export default function ScrollToTop() {
const [isVisible, setIsVisible] = useState(false);
// Show button when page is scrolled down
const toggleVisibility = () => {
if (window.scrollY > 300) {
setIsVisible(true);
} else {
setIsVisible(false);
}
};
const scrollToTop = () => {
window.scrollTo({
top: 0,
behavior: "smooth",
});
};
useEffect(() => {
window.addEventListener("scroll", toggleVisibility);
return () => {
window.removeEventListener("scroll", toggleVisibility);
};
}, []);
return (
<div className="fixed bottom-6 right-6 sm:bottom-8 sm:right-8 z-[100]">
<button
type="button"
onClick={scrollToTop}
className={`flex items-center justify-center w-12 h-12 rounded-full bg-[#0a2e1f] border-[1.5px] border-[#bc9e65] text-[#bc9e65] shadow-lg shadow-black/50 transition-all duration-300 hover:-translate-y-1 hover:bg-[#bc9e65] hover:text-[#0a2e1f] ${
isVisible ? "opacity-100 scale-100 translate-y-0" : "opacity-0 scale-75 translate-y-4 pointer-events-none"
}`}
aria-label="Scroll to top"
>
<ChevronsUp size={24} strokeWidth={2.5} />
</button>
</div>
);
}

View File

@ -15,7 +15,7 @@ export default function TestimonialSlider() {
try { try {
const res = await fetch("/api/reviews"); const res = await fetch("/api/reviews");
const data = await res.json().catch(() => ({})); const data = await res.json().catch(() => ({}));
if (!res.ok) { if (!res.ok) {
const errorMessage = data?.error || `${res.status} ${res.statusText}`; const errorMessage = data?.error || `${res.status} ${res.statusText}`;
console.warn('Reviews API returned non-ok response:', errorMessage); console.warn('Reviews API returned non-ok response:', errorMessage);
@ -85,19 +85,19 @@ export default function TestimonialSlider() {
animate={{ opacity: 1, scale: 1 }} animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.95 }} exit={{ opacity: 0, scale: 0.95 }}
transition={{ duration: 0.4 }} transition={{ duration: 0.4 }}
className="relative bg-[#fcf9f2] p-6 sm:p-14 rounded-2xl shadow-[0_10px_40px_rgba(0,0,0,0.08)] mx-1 sm:mx-12 mt-12 border border-[#bc9e65]/20" className="relative mx-1 sm:mx-12 mt-12 min-h-[400px] flex flex-col justify-center bg-[#fcf9f2] p-6 sm:p-14 rounded-2xl shadow-[0_10px_40px_rgba(0,0,0,0.08)] border border-[#bc9e65]/20 md:bg-[url('/images/testimonial.png')] md:bg-[length:100%_100%] md:bg-center md:bg-no-repeat md:p-20 md:border-none md:shadow-none md:bg-transparent"
> >
{/* Inner decorative border */} {/* Inner decorative border */}
<div className="absolute inset-2 border border-[#bc9e65]/40 rounded-xl pointer-events-none" /> <div className="block md:hidden absolute inset-2 border border-[#bc9e65]/40 rounded-xl pointer-events-none" />
{/* Decorative Corner accents */} {/* Decorative Corner accents */}
<div className="absolute top-2 left-2 w-4 h-4 border-t border-l border-[#bc9e65] rounded-tl-lg" /> <div className="block md:hidden absolute top-2 left-2 w-4 h-4 border-t border-l border-[#bc9e65] rounded-tl-lg" />
<div className="absolute top-2 right-2 w-4 h-4 border-t border-r border-[#bc9e65] rounded-tr-lg" /> <div className="block md:hidden absolute top-2 right-2 w-4 h-4 border-t border-r border-[#bc9e65] rounded-tr-lg" />
<div className="absolute bottom-2 left-2 w-4 h-4 border-b border-l border-[#bc9e65] rounded-bl-lg" /> <div className="block md:hidden absolute bottom-2 left-2 w-4 h-4 border-b border-l border-[#bc9e65] rounded-bl-lg" />
<div className="absolute bottom-2 right-2 w-4 h-4 border-b border-r border-[#bc9e65] rounded-br-lg" /> <div className="block md:hidden absolute bottom-2 right-2 w-4 h-4 border-b border-r border-[#bc9e65] rounded-br-lg" />
{/* Crown Crest Top Center */} {/* Crown Crest Top Center */}
<div className="absolute -top-10 left-1/2 -translate-x-1/2 w-20 h-20 bg-gradient-to-br from-[#fcf9f2] to-[#f5e9d0] rounded-full border border-[#bc9e65] flex items-center justify-center shadow-md z-10"> <div className="flex md:hidden absolute -top-10 left-1/2 -translate-x-1/2 w-20 h-20 bg-gradient-to-br from-[#fcf9f2] to-[#f5e9d0] rounded-full border border-[#bc9e65] items-center justify-center shadow-md z-10">
<div className="absolute inset-1 border border-[#bc9e65]/40 rounded-full" /> <div className="absolute inset-1 border border-[#bc9e65]/40 rounded-full" />
<svg className="w-8 h-8 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor"> <svg className="w-8 h-8 text-[#bc9e65]" viewBox="0 0 24 24" fill="currentColor">
<path d="M5 16L3 5l5.5 5L12 4l3.5 6L21 5l-2 11H5zm14 3c0 .6-.4 1-1 1H6c-.6 0-1-.4-1-1v-1h14v1z" /> <path d="M5 16L3 5l5.5 5L12 4l3.5 6L21 5l-2 11H5zm14 3c0 .6-.4 1-1 1H6c-.6 0-1-.4-1-1v-1h14v1z" />
@ -105,18 +105,18 @@ export default function TestimonialSlider() {
</div> </div>
{/* Left Quote */} {/* Left Quote */}
<div className="absolute top-16 left-6 sm:left-12 text-[#bc9e65] opacity-90"> <div className="block md:hidden absolute top-16 left-6 sm:left-12 text-[#bc9e65] opacity-90">
<span className="font-serif text-6xl leading-none"></span> <span className="font-serif text-6xl leading-none"></span>
</div> </div>
{/* Right Quote */} {/* Right Quote */}
<div className="absolute bottom-24 right-6 sm:right-12 text-[#bc9e65] opacity-90"> <div className="block md:hidden absolute bottom-24 right-6 sm:right-12 text-[#bc9e65] opacity-90">
<span className="font-serif text-6xl leading-none"></span> <span className="font-serif text-6xl leading-none"></span>
</div> </div>
<div className="relative z-10 px-8 sm:px-20 flex flex-col items-center text-center mt-2"> <div className="relative z-10 px-8 sm:px-20 flex flex-col items-center text-center mt-2">
{/* Stars */} {/* Stars */}
<div className="flex justify-center gap-1.5 mb-4 text-[#bc9e65]"> <div className="flex md:hidden justify-center gap-1.5 mb-4 text-[#bc9e65]">
{[...Array(review.rating || 5)].map((_, i) => ( {[...Array(review.rating || 5)].map((_, i) => (
<svg key={i} className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20"> <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" /> <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" />
@ -125,10 +125,10 @@ export default function TestimonialSlider() {
</div> </div>
{/* Small divider under stars */} {/* Small divider under stars */}
<div className="flex items-center gap-2 mb-8"> <div className="flex md:hidden items-center gap-2 mb-8">
<div className="w-6 h-px bg-[#bc9e65]/50" /> <div className="w-6 h-px bg-[#bc9e65]/50" />
<div className="w-1.5 h-1.5 rotate-45 bg-[#bc9e65]" /> <div className="w-1.5 h-1.5 rotate-45 bg-[#bc9e65]" />
<div className="w-6 h-px bg-[#bc9e65]/50" /> <div className="w-6 h-px bg-[#bc9e65]/50" />
</div> </div>
<p className="font-sans text-[#4a3c28] text-base sm:text-lg leading-relaxed italic mb-10 min-h-[80px]"> <p className="font-sans text-[#4a3c28] text-base sm:text-lg leading-relaxed italic mb-10 min-h-[80px]">
@ -136,7 +136,7 @@ export default function TestimonialSlider() {
{isLong && ( {isLong && (
<button <button
onClick={() => setExpanded(!expanded)} onClick={() => setExpanded(!expanded)}
className="ml-2 text-[#bc9e65] hover:text-[#8a6c3a] font-bold text-xs uppercase tracking-wider transition-colors inline-block" className="ml-2 text-[#bc9e65] hover:text-[#bc9e65] font-bold text-xs uppercase tracking-wider transition-colors inline-block"
> >
{expanded ? "Read Less" : "Read More"} {expanded ? "Read Less" : "Read More"}
</button> </button>
@ -147,13 +147,13 @@ export default function TestimonialSlider() {
<h4 className="font-serif text-[#1a3a25] tracking-widest uppercase text-base font-bold"> <h4 className="font-serif text-[#1a3a25] tracking-widest uppercase text-base font-bold">
{review.name} {review.name}
</h4> </h4>
<span className="text-[10px] uppercase tracking-widest text-[#8a6c3a] mt-1 block"> <span className="text-[10px] uppercase tracking-widest text-[#bc9e65] mt-1 block">
{review.role || "REGULAR CUSTOMER"} {review.role || "REGULAR CUSTOMER"}
</span> </span>
</div> </div>
{/* Bottom Lotus Ornament */} {/* Bottom Lotus Ornament */}
{/* <div className="absolute -bottom-4 left-1/2 -translate-x-1/2 bg-[#fcf9f2] px-3 z-10"> {/* <div className="hidden md:block absolute -bottom-4 left-1/2 -translate-x-1/2 bg-[#fcf9f2] px-3 z-10">
<svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 30 20" fill="currentColor"> <svg className="w-6 h-6 text-[#bc9e65]" viewBox="0 0 30 20" fill="currentColor">
<path d="M 15,3 C 13,8 14,14 15,16 C 16,14 17,8 15,3 Z" /> <path d="M 15,3 C 13,8 14,14 15,16 C 16,14 17,8 15,3 Z" />
</svg> </svg>
@ -163,7 +163,7 @@ export default function TestimonialSlider() {
{/* Navigation Controls */} {/* Navigation Controls */}
<div className="flex items-center justify-center gap-6 mt-8"> <div className="flex items-center justify-center gap-6 mt-8">
<button onClick={prev} className="p-2 text-[#8a6c3a] hover:text-[#1a3a25] transition-colors"> <button onClick={prev} className="p-2 text-[#bc9e65] 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> <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> </button>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@ -175,7 +175,7 @@ export default function TestimonialSlider() {
/> />
))} ))}
</div> </div>
<button onClick={next} className="p-2 text-[#8a6c3a] hover:text-[#1a3a25] transition-colors"> <button onClick={next} className="p-2 text-[#bc9e65] 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> <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> </button>
</div> </div>

View File

@ -23,12 +23,13 @@ export function formatReviewsForHome(reviews: any[]) {
if (!Array.isArray(reviews)) return []; if (!Array.isArray(reviews)) return [];
return reviews.map((r) => { return reviews.map((r) => {
let text = r.snippet || r.text || ''; let text = r.snippet || r.text || '';
let authorName = r.author_name || (r.user && r.user.name) || 'Guest';
return { return {
name: r.author_name || 'Guest', name: authorName,
text: text, text: text,
rating: r.rating || 5, rating: r.rating || 5,
role: r.author_title || 'Reviewer', role: r.author_title || (r.user && r.user.local_guide ? 'Local Guide' : 'Reviewer'),
initials: (r.author_name || 'G').charAt(0).toUpperCase() initials: authorName.charAt(0).toUpperCase()
}; };
}); });
} }

File diff suppressed because one or more lines are too long