// Homepage-only section compositions, part 2: Dining, Corporate, Reviews, // Newsletter. Depends on shared/vivaan-sections.jsx. const { Button } = window.VivaanDesignSystem_b1c8ba; const { PhotoBlock, PhotoSlideshow, HoverImageSwap, SectionLabel, EditorialHeading, BodyCopy } = window; /* ---------------------------------------------------------------------- */ /* 5. Dining */ /* ---------------------------------------------------------------------- */ function DiningSection() { const wrap = { padding: "var(--space-2xl) var(--space-xl)", backgroundColor: "var(--vivaan-cream)", display: "flex", flexDirection: "column", gap: "var(--space-xl)" }; const head = { display: "flex", flexDirection: "column", gap: 20, maxWidth: 620 }; return (
Dining From leisurely breakfasts to elegant dinners, our restaurants bring together seasonal flavours, thoughtful hospitality and memorable moments throughout the day.
); } /* ---------------------------------------------------------------------- */ /* 6. Meetings & Conferences */ /* ---------------------------------------------------------------------- */ const LAYOUTS = window.LAYOUTS; const LayoutIcon = window.LayoutIcon; function CorporateSection() { const wrap = { padding: "var(--space-2xl) var(--space-xl)", backgroundColor: "var(--color-surface-page)", display: "flex", flexDirection: "column", gap: "var(--space-xl)" }; const head = { display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 40, flexWrap: "wrap" }; const card = { display: "flex", flexDirection: "column", gap: 14, padding: "var(--space-md)", borderTop: "1px solid var(--color-border-hairline)" }; return (
Meetings & Conferences From board meetings to grand conferences, The Vivaan offers versatile venues, luxury stays and seamless event planning.
{LAYOUTS.map((l) => (
{l.name}
{l.capacity}
{l.tag}
))}
); } /* ---------------------------------------------------------------------- */ /* 7. Guest Reviews */ /* ---------------------------------------------------------------------- */ const TESTIMONIALS = window.TESTIMONIALS; function ReviewsSection() { const [active, setActive] = React.useState("Wedding"); const [index, setIndex] = React.useState(0); const list = TESTIMONIALS[active]; // Reset to the first review whenever the category tab changes. React.useEffect(() => { setIndex(0); }, [active]); // Auto-rotate through the active category's reviews, slow luxury pace. React.useEffect(() => { if (!list || list.length < 2) return; const id = setInterval(() => { setIndex((v) => (v + 1) % list.length); }, 7000); return () => clearInterval(id); }, [active, list]); const wrap = { padding: "var(--space-2xl) var(--space-xl)", backgroundColor: "var(--vivaan-black)", color: "var(--color-text-on-dark)", display: "flex", flexDirection: "column", alignItems: "center", gap: "var(--space-xl)", textAlign: "center" }; const tabs = { display: "flex", gap: "var(--space-lg)", flexWrap: "wrap", justifyContent: "center" }; const tab = (name) => ({ fontFamily: "var(--font-serif)", fontSize: 12, letterSpacing: "0.12em", textTransform: "uppercase", color: name === active ? "var(--vivaan-gold)" : "rgba(255,255,255,0.5)", background: "none", border: "none", borderBottom: name === active ? "1px solid var(--vivaan-gold)" : "1px solid transparent", paddingBottom: 8, cursor: "pointer", transition: "color 0.2s ease", }); const dot = (i) => ({ width: i === index ? 20 : 8, height: 8, borderRadius: 4, border: "none", padding: 0, backgroundColor: i === index ? "var(--vivaan-gold)" : "rgba(255,255,255,0.3)", cursor: "pointer", transition: "all 0.3s ease", }); const current = list[index]; return (
Guest Reviews
{Object.keys(TESTIMONIALS).map((k) => ( ))}

“{current.quote}”

{current.meta ? (
) : null} {list.length > 1 ? (
{list.map((_, i) => (
) : null}
); } /* ---------------------------------------------------------------------- */ /* 8. Stay Updated (newsletter) */ /* ---------------------------------------------------------------------- */ function NewsletterSection() { const [email, setEmail] = React.useState(""); const [consent, setConsent] = React.useState(false); const [sent, setSent] = React.useState(false); const wrap = { padding: "var(--space-2xl) var(--space-xl)", backgroundColor: "var(--vivaan-cream)", display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center", gap: 24 }; const inputRowClass = "newsletter-row"; const input = { flex: 1, border: "none", borderBottom: "1px solid var(--color-border-hairline)", background: "transparent", fontFamily: "var(--font-serif)", fontSize: 15, padding: "10px 0", outline: "none" }; const consentRow = { display: "flex", alignItems: "flex-start", gap: 10, maxWidth: 480, textAlign: "left" }; return (
Newsletter

Stay Updated

Be the first to receive exclusive offers, wedding inspirations, seasonal experiences and special events from The Vivaan. {sent ? (
Thank you — you're on the list.
) : (
setEmail(e.target.value)} />
)}
); } Object.assign(window, { DiningSection, LAYOUTS, CorporateSection, TESTIMONIALS, ReviewsSection, NewsletterSection });