<!DOCTYPE html> <html lang="en" class="scroll-smooth"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SEO Tags --> <title>Muscle House Gym | Gym in Gangarampur, West Bengal</title> <meta name="description" content="Join Muscle House Gym in Gangarampur, West Bengal. Affordable gym membership starting at ₹700/month with strength training, muscle building, fat-loss and fitness guidance."> <meta name="keywords" content="Muscle House Gym Gangarampur, Gym in Gangarampur, Best gym in Gangarampur, Muscle House Gym West Bengal, Gym near Gangarampur, মাসল হাউস জিম"> <!-- Open Graph for Social Sharing --> <meta property="og:title" content="Muscle House Gym | Gangarampur"> <meta property="og:description" content="Premium fitness destination in Gangarampur. Train Hard. Stay Consistent. Get Stronger."> <meta property="og:type" content="website"> <!-- Fonts --> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Oswald:wght@400;500;600;700&display=swap" rel="stylesheet"> <!-- Tailwind CSS --> <script src="https://cdn.tailwindcss.com"></script> <script> tailwind.config = { theme: { extend: { colors: { brand: { red: '#dc2626', // Strong Red dark: '#0a0a0a', // Deep Black gray: '#171717', // Dark Gray for cards light: '#f5f5f5' // Off-white for text } }, fontFamily: { sans: ['Inter', 'sans-serif'], heading: ['Oswald', 'sans-serif'], bengali: ['Inter', 'sans-serif'] // Fallback, modern browsers handle unicode well }, animation: { 'fade-in-up': 'fadeInUp 0.8s ease-out forwards', }, keyframes: { fadeInUp: { '0%': { opacity: '0', transform: 'translateY(20px)' }, '100%': { opacity: '1', transform: 'translateY(0)' }, } } } } } </script> <style> /* Custom scrollbar for premium feel */ ::-webkit-scrollbar { width: 10px; } ::-webkit-scrollbar-track { background: #0a0a0a; } ::-webkit-scrollbar-thumb { background: #333; border-radius: 5px; } ::-webkit-scrollbar-thumb:hover { background: #dc2626; } body { background-color: #0a0a0a; color: #f5f5f5; } /* Utility for fade-in animations on scroll */ .reveal { opacity: 0; transform: translateY(30px); transition: all 0.8s ease-out; } .reveal.active { opacity: 1; transform: translateY(0); } /* Gradient Text Utility */ .text-gradient { background: linear-gradient(to right, #ffffff, #a3a3a3); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .bg-pattern { background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%231f2937' fill-opacity='0.2'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); } </style> <!-- React & ReactDOM --> <script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script> <!-- Babel for JSX --> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> </head> <body class="antialiased overflow-x-hidden"> <div id="root"></div> <script type="text/babel"> const { useState, useEffect, useRef } = React; // Reusable SVG Icons const Icons = { Menu: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>, X: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>, MapPin: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>, Phone: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>, Clock: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>, CheckCircle: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/></svg>, Dumbbell: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14.4 14.4 9.6 9.6"/><path d="M18.65 21.35a2.12 2.12 0 0 1-2.99 0L2.65 8.35a2.12 2.12 0 0 1 0-2.99l1.4-1.4a2.12 2.12 0 0 1 2.99 0l12.99 12.99a2.12 2.12 0 0 1 0 2.99z"/><path d="m21.5 21.5-1.4-1.4"/><path d="M3.9 3.9 2.5 2.5"/><path d="M6.4 17.6 5 19"/><path d="m17.6 6.4 1.4-1.4"/></svg>, Flame: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" 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 2.5z"/></svg>, TrendingUp: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg>, Activity: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>, Facebook: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"/></svg>, ChevronRight: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m9 18 6-6-6-6"/></svg>, CreditCard: () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect width="20" height="14" x="2" y="5" rx="2"/><line x1="2" x2="22" y1="10" y2="10"/></svg> }; // Hook for scroll animation const useScrollReveal = () => { useEffect(() => { const reveals = document.querySelectorAll('.reveal'); const revealOnScroll = () => { const windowHeight = window.innerHeight; const elementVisible = 100; reveals.forEach((reveal) => { const elementTop = reveal.getBoundingClientRect().top; if (elementTop < windowHeight - elementVisible) { reveal.classList.add('active'); } }); }; window.addEventListener('scroll', revealOnScroll); revealOnScroll(); // Trigger on load return () => window.removeEventListener('scroll', revealOnScroll); }, []); }; // Helper to get Gym Status based on IST const getGymStatus = () => { const options = { timeZone: 'Asia/Kolkata', hour12: false, hour: 'numeric', minute: 'numeric', weekday: 'short' }; const now = new Date(); const timeString = now.toLocaleTimeString('en-US', options); // Handle edge case where toLocaleTimeString doesn't return weekday in some browsers easily const istDate = new Date(now.toLocaleString("en-US", {timeZone: "Asia/Kolkata"})); const day = istDate.getDay(); // 0 (Sun) to 6 (Sat) const hour = istDate.getHours(); const minute = istDate.getMinutes(); const time = hour + minute / 60; if (day === 0) return { isOpen: false, text: "CLOSED NOW", class: "bg-red-900/50 text-red-400 border-red-500" }; // Sunday let openTime = 6.0; // 6:00 AM let closeTime = 22.0; // 10:00 PM if (day === 4) { // Thursday openTime = 6.5; // 6:30 AM } if (time >= openTime && time < closeTime) { return { isOpen: true, text: "OPEN NOW • CLOSES 10:00 PM", class: "bg-green-900/50 text-green-400 border-green-500" }; } else { let nextOpen = "6:00 AM"; if (day === 3) nextOpen = "6:30 AM"; // Wed night -> Thu morning if (day === 6) nextOpen = "Monday 6:00 AM"; // Sat night -> Sun closed -> Mon morning return { isOpen: false, text: `CLOSED NOW • OPENS ${nextOpen}`, class: "bg-gray-800 text-gray-400 border-gray-600" }; } }; const Navbar = () => { const [isScrolled, setIsScrolled] = useState(false); const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); useEffect(() => { const handleScroll = () => { setIsScrolled(window.scrollY > 50); }; window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, []); const navLinks = [ { name: 'Home', href: '#home' }, { name: 'About', href: '#about' }, { name: 'Membership', href: '#membership' }, { name: 'Services', href: '#services' }, { name: 'Gallery', href: '#gallery' }, { name: 'Contact', href: '#contact' }, ]; return ( <nav className={`fixed w-full z-50 transition-all duration-300 ${isScrolled ? 'bg-brand-dark/90 backdrop-blur-md border-b border-brand-gray py-3' : 'bg-transparent py-5'}`}> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="flex justify-between items-center"> {/* Logo */} <a href="#" className="flex flex-col items-start group"> <span className="font-heading font-bold text-2xl tracking-wider text-white uppercase group-hover:text-brand-red transition-colors">Muscle House</span> <span className="font-bengali text-xs text-gray-400 tracking-widest">মাসল হাউস জিম</span> </a> {/* Desktop Nav */} <div className="hidden md:flex items-center space-x-8"> {navLinks.map((link) => ( <a key={link.name} href={link.href} className="text-sm font-medium text-gray-300 hover:text-white transition-colors uppercase tracking-wide"> {link.name} </a> ))} <a href="#contact" className="bg-brand-red hover:bg-red-700 text-white px-6 py-2 rounded-sm font-heading font-semibold tracking-wider transition-all transform hover:scale-105 uppercase"> Join Now </a> </div> {/* Mobile Menu Button */} <div className="md:hidden"> <button onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)} className="text-gray-300 hover:text-white"> {isMobileMenuOpen ? <Icons.X /> : <Icons.Menu />} </button> </div> </div> </div> {/* Mobile Menu */} {isMobileMenuOpen && ( <div className="md:hidden absolute top-full left-0 w-full bg-brand-dark/95 backdrop-blur-lg border-b border-brand-gray"> <div className="px-4 pt-2 pb-6 space-y-1 flex flex-col"> {navLinks.map((link) => ( <a key={link.name} href={link.href} onClick={() => setIsMobileMenuOpen(false)} className="block px-3 py-3 text-base font-medium text-gray-300 hover:text-white hover:bg-brand-gray rounded-sm uppercase tracking-wide" > {link.name} </a> ))} <a href="#contact" onClick={() => setIsMobileMenuOpen(false)} className="mt-4 text-center bg-brand-red text-white px-6 py-3 rounded-sm font-heading font-semibold tracking-wider uppercase block"> Join Now </a> </div> </div> )} </nav> ); }; const Hero = () => { const [status, setStatus] = useState(getGymStatus()); useEffect(() => { // Update status every minute const interval = setInterval(() => setStatus(getGymStatus()), 60000); return () => clearInterval(interval); }, []); return ( <section id="home" className="relative h-screen flex items-center justify-center pt-20"> {/* Background Image with Overlay */} <div className="absolute inset-0 z-0"> <img src="https://images.unsplash.com/photo-1534438327276-14e5300c3a48?q=80&w=2000&auto=format&fit=crop" alt="Muscle House Gym Environment" className="w-full h-full object-cover" /> <div className="absolute inset-0 bg-gradient-to-r from-brand-dark via-brand-dark/80 to-transparent"></div> <div className="absolute inset-0 bg-gradient-to-t from-brand-dark via-transparent to-brand-dark/30"></div> </div> <div className="relative z-10 w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-left"> <div className="max-w-3xl animate-fade-in-up"> {/* Status Badge */} <div className={`inline-flex items-center space-x-2 px-3 py-1 rounded-full border text-xs font-semibold tracking-wider mb-6 ${status.class}`}> <span className={`w-2 h-2 rounded-full ${status.isOpen ? 'bg-green-400 animate-pulse' : 'bg-gray-400'}`}></span> <span>{status.text}</span> </div> <h1 className="font-heading font-bold text-5xl sm:text-7xl lg:text-8xl leading-tight text-white mb-2 uppercase"> Build Your Body.<br/> <span className="text-brand-red">Build Your Confidence.</span> </h1> <h2 className="font-bengali text-2xl sm:text-3xl text-gray-400 mb-6 tracking-wider"> মাসল হাউস জিম </h2> <p className="text-lg sm:text-xl text-gray-300 mb-10 max-w-2xl leading-relaxed"> Train harder. Get stronger. Become the best version of yourself at Muscle House Gym. </p> <div className="flex flex-col sm:flex-row gap-4"> <a href="#membership" className="inline-flex justify-center items-center bg-brand-red hover:bg-red-700 text-white px-8 py-4 rounded-sm font-heading font-bold text-lg tracking-wider uppercase transition-all transform hover:-translate-y-1"> Join Now <Icons.ChevronRight /> </a> <a href="tel:07363037887" className="inline-flex justify-center items-center bg-transparent border-2 border-white hover:bg-white hover:text-brand-dark text-white px-8 py-4 rounded-sm font-heading font-bold text-lg tracking-wider uppercase transition-all"> <span className="mr-2"><Icons.Phone /></span> Call Us </a> </div> </div> </div> </section> ); }; const QuickInfo = () => { const info = [ { icon: <Icons.CreditCard />, title: "Membership", desc: "Starting at ₹700/month" }, { icon: <Icons.MapPin />, title: "Location", desc: "Gangarampur, West Bengal" }, { icon: <Icons.Clock />, title: "Opening Hours", desc: "6:00 AM – 10:00 PM" }, { icon: <Icons.Phone />, title: "Contact", desc: "073630 37887", link: "tel:07363037887" }, ]; return ( <div className="bg-brand-dark relative z-20 border-b border-