import React, { useState, useEffect, useRef } from 'react';
import {
Building2,
BarChart3,
Users,
Layers,
Zap,
CheckCircle2,
ArrowRight,
Menu,
X,
ChevronDown,
Mail,
PieChart,
ShieldCheck,
Smartphone,
Bot,
Eye,
Share2,
Clock,
MapPin,
FileText,
MessageSquare,
Send,
Download
} from 'lucide-react';
/* --- CUSTOM CSS FOR ANIMATIONS & THEME --- */
const customStyles = `
@keyframes float {
0% { transform: translateY(0px); }
50% { transform: translateY(-20px); }
100% { transform: translateY(0px); }
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-float { animation: float 6s ease-in-out infinite; }
.fade-in-section {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
will-change: opacity, visibility;
}
.fade-in-section.is-visible {
opacity: 1;
transform: none;
}
/* LIGHT THEME GLASS CARD (Solid Tints, No Gradients) */
.glass-card {
background: rgba(255, 255, 255, 0.85); /* More opaque, solid feel */
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(179, 58, 58, 0.2);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.05);
}
/* DARK THEME GLASS CARD */
.glass-card-dark {
background: rgba(46, 46, 46, 0.9); /* Solid dark */
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3);
}
/* SOLID COLORS - NO GRADIENTS */
.text-highlight {
color: #B33A3A; /* Solid Brick Red */
}
.bg-primary {
background-color: #B33A3A;
}
/* --- SOLID GLASS BUTTON STYLES --- */
.brikly-btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
/* Solid Transparent Base - No Gradient */
background-color: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(46, 46, 46, 0.2);
color: #2E2E2E;
font-weight: 700;
padding: 14px 40px;
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.5px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
cursor: pointer;
font-family: ui-sans-serif, system-ui, sans-serif;
position: relative;
overflow: hidden;
}
/* Hover State - Solid Color Shift */
.brikly-btn:hover {
transform: translateY(-2px);
background-color: rgba(255, 255, 255, 0.3);
border-color: #B33A3A;
color: #B33A3A;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
/* Primary Button Variant (Solid Red) */
.brikly-btn.primary {
color: #FFFFFF;
background-color: #B33A3A; /* Solid Red */
border: 1px solid #B33A3A;
}
.brikly-btn.primary:hover {
background-color: #962e2e; /* Darker Red on Hover */
border-color: #962e2e;
color: #FFFFFF;
box-shadow: 0 10px 30px rgba(179, 58, 58, 0.3);
}
/* Active: Press Down */
.brikly-btn:active {
transform: translateY(1px);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
/* Inventory Grid Animations */
.unit-box {
transition: all 0.3s ease;
}
.unit-box:hover {
transform: scale(1.1);
z-index: 10;
box-shadow: 0 10px 20px rgba(0,0,0,0.15);
}
/* Chat Animation */
.chat-bubble {
animation: popIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
opacity: 0;
transform: scale(0.9) translateY(10px);
}
@keyframes popIn {
to { opacity: 1; transform: scale(1) translateY(0); }
}
.typing-dot {
animation: typing 1.4s infinite ease-in-out both;
}
.typing-dot:nth-child(1) { animation-delay: -0.32s; }
.typing-dot:nth-child(2) { animation-delay: -0.16s; }
@keyframes typing {
0%, 80%, 100% { transform: scale(0); }
40% { transform: scale(1); }
}
`;
/* --- REUSABLE COMPONENTS --- */
const useOnScreen = (ref) => {
const [isIntersecting, setIntersecting] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => setIntersecting(entry.isIntersecting),
{ threshold: 0.1 }
);
if (ref.current) observer.observe(ref.current);
return () => { if (ref.current) observer.unobserve(ref.current); };
}, [ref]);
return isIntersecting;
};
const FadeInSection = ({ children, className = "" }) => {
const ref = useRef(null);
const isVisible = useOnScreen(ref);
return (
{children}
);
};
const Button = ({ children, primary = false, className = "", onClick, ...props }) => {
return (
{children}
);
};
/* --- FORM MODAL COMPONENT --- */
const ConsultationModal = ({ isOpen, onClose }) => {
const [formData, setFormData] = useState({
name: '',
phone: '',
email: '',
project: ''
});
if (!isOpen) return null;
const handleSubmit = (e) => {
e.preventDefault();
// Construct Mailto Link
const subject = `New Consultation Request from ${formData.name}`;
const body = `Name: ${formData.name}%0D%0APhone: ${formData.phone}%0D%0AEmail: ${formData.email}%0D%0AProject Interest: ${formData.project}%0D%0A%0D%0ASent from Brikly Website.`;
window.location.href = `mailto:vivek.baseinfr@gmail.com?subject=${subject}&body=${body}`;
// Optional: Close modal after delay
setTimeout(() => {
onClose();
alert("Opening your email client to send the request!");
}, 500);
};
return (
{/* Backdrop */}
{/* Modal Content */}
Book Consultation
Get expert advice on implementing Brikly.
);
};
/* --- INTERACTIVE CITY BUILDER COMPONENT (THREE.JS) --- */
const Hero3D = () => {
const mountRef = useRef(null);
useEffect(() => {
const script = document.createElement('script');
script.src = "https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js";
script.async = true;
script.onload = () => {
if (!window.THREE || !mountRef.current) return;
const THREE = window.THREE;
// --- SCENE SETUP ---
const scene = new THREE.Scene();
scene.fog = new THREE.Fog(0xF5F5F5, 10, 60);
scene.background = new THREE.Color(0xF5F5F5);
const camera = new THREE.PerspectiveCamera(75, mountRef.current.clientWidth / mountRef.current.clientHeight, 0.1, 1000);
camera.position.set(0, 12, 18);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.setSize(mountRef.current.clientWidth, mountRef.current.clientHeight);
renderer.setPixelRatio(window.devicePixelRatio);
mountRef.current.appendChild(renderer.domElement);
// --- LIGHTING ---
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); // Increased ambient for solid color visibility
scene.add(ambientLight);
// Solid White Light for true colors
const dirLight = new THREE.DirectionalLight(0xffffff, 1.0);
dirLight.position.set(20, 40, 20);
dirLight.castShadow = true;
scene.add(dirLight);
const redLight = new THREE.PointLight(0xB33A3A, 1, 40); // Soft fill light
redLight.position.set(-10, 5, -10);
scene.add(redLight);
// --- INSTANCED MESH (SOLID RED BRICKS) ---
const geometry = new THREE.BoxGeometry(0.8, 1, 0.8);
// Move pivot to bottom so scaling happens upwards
geometry.translate(0, 0.5, 0);
// Solid Opaque Material, No Glass, No Gradient
const material = new THREE.MeshStandardMaterial({
color: 0xB33A3A, // Solid Brick Red
roughness: 0.6, // Matte finish like real brick
metalness: 0.1, // Slight sheen
flatShading: true, // Enhances the solid/low-poly look
});
const gridSize = 40;
const count = gridSize * gridSize;
const mesh = new THREE.InstancedMesh(geometry, material, count);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
// Initialize Matrix
const dummy = new THREE.Object3D();
const instanceScales = new Float32Array(count).fill(0.1); // Start flat
// Initial Layout
let i = 0;
for (let x = -gridSize / 2; x < gridSize / 2; x++) {
for (let z = -gridSize / 2; z < gridSize / 2; z++) {
dummy.position.set(x, 0, z);
dummy.scale.set(1, 0.1, 1); // Flat initially
dummy.updateMatrix();
mesh.setMatrixAt(i++, dummy.matrix);
}
}
mesh.instanceMatrix.needsUpdate = true;
// --- MOUSE INTERACTION SETUP ---
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2(9999, 9999);
const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
const onMouseMove = (event) => {
const rect = mountRef.current.getBoundingClientRect();
mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
};
window.addEventListener('mousemove', onMouseMove);
// --- ANIMATION LOOP ---
const animate = () => {
requestAnimationFrame(animate);
raycaster.setFromCamera(mouse, camera);
const target = new THREE.Vector3();
raycaster.ray.intersectPlane(plane, target);
let idx = 0;
for (let x = -gridSize / 2; x < gridSize / 2; x++) {
for (let z = -gridSize / 2; z < gridSize / 2; z++) {
// Logic: Distance from mouse determines target height
const dx = x - (target ? target.x : 999);
const dz = z - (target ? target.z : 999);
const dist = Math.sqrt(dx*dx + dz*dz);
// "City" building effect
let targetHeight = 0.1; // Ground level
if (dist < 6) {
// The closer, the taller. Max height around 6 units.
targetHeight = Math.max(0.1, (6 - dist) + Math.random() * 0.5);
}
// Smooth Lerp
instanceScales[idx] += (targetHeight - instanceScales[idx]) * 0.1;
dummy.position.set(x, 0, z);
dummy.scale.set(1, instanceScales[idx], 1);
dummy.updateMatrix();
mesh.setMatrixAt(idx, dummy.matrix);
idx++;
}
}
mesh.instanceMatrix.needsUpdate = true;
renderer.render(scene, camera);
};
animate();
// Handle Resize
const handleResize = () => {
if (!mountRef.current) return;
camera.aspect = mountRef.current.clientWidth / mountRef.current.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(mountRef.current.clientWidth, mountRef.current.clientHeight);
};
window.addEventListener('resize', handleResize);
// Cleanup
return () => {
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('resize', handleResize);
if (mountRef.current) mountRef.current.removeChild(renderer.domElement);
};
};
document.body.appendChild(script);
return () => {
if(document.body.contains(script)) document.body.removeChild(script);
}
}, []);
return
;
};
/* --- MAIN APP COMPONENT --- */
export default function App() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [isAnnual, setIsAnnual] = useState(true);
const [isModalOpen, setIsModalOpen] = useState(false);
// Chat Bot Animation State
const [chatMessages, setChatMessages] = useState([]);
const [isTyping, setIsTyping] = useState(false);
const chatContainerRef = useRef(null);
// Chat Sequence Data
const chatSequence = [
{ type: 'user', text: "Show me park facing plots, North facing.", delay: 1000 },
{ type: 'bot', text: "I found 3 premium units matching your criteria:\n• Plot A-12 (1500 sqft)\n• Plot B-05 (1800 sqft)\n• Plot C-09 (1200 sqft)", delay: 2000 },
{ type: 'user', text: "What is the price of A-12?", delay: 4000 },
{ type: 'bot', text: "The base price for Unit A-12 is ₹75 Lakhs.", delay: 5000 },
{ type: 'user', text: "Send me the total costing.", delay: 7000 },
{ type: 'bot', text: "Generating Cost Sheet... 📄", isCostSheet: true, delay: 8500 }
];
useEffect(() => {
let timeoutIds = [];
let startTime = 0;
const runChatSequence = () => {
setChatMessages([]); // Reset
chatSequence.forEach((msg, index) => {
// Show typing indicator before bot messages
if (msg.type === 'bot') {
const typingDelay = msg.delay - 1000;
const tId1 = setTimeout(() => setIsTyping(true), typingDelay);
timeoutIds.push(tId1);
}
const tId2 = setTimeout(() => {
setIsTyping(false);
setChatMessages(prev => [...prev, msg]);
// Scroll to bottom
if (chatContainerRef.current) {
chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
}
}, msg.delay);
timeoutIds.push(tId2);
});
// Loop the animation
const totalDuration = chatSequence[chatSequence.length - 1].delay + 4000;
const loopId = setTimeout(runChatSequence, totalDuration);
timeoutIds.push(loopId);
};
// Start observer to trigger animation only when visible could be added here
// For now, just run it
runChatSequence();
return () => timeoutIds.forEach(clearTimeout);
}, []);
// Pricing Data based on provided document
const pricingData = [
{
title: "Starter",
target: "Small Developers",
priceMonthly: 5000,
priceAnnual: 4150, // ~17% off
features: [
"5 Users",
"500 Leads",
"3 Active Projects",
"2 GB Storage",
"Basic Dashboard",
"1 Landing Page"
],
notIncluded: ["Bot Assistant", "Adv. Analytics"],
color: "from-[#B33A3A] to-[#D4AF37]" // Brick to Gold
},
{
title: "Professional",
target: "Mid-size Developers",
priceMonthly: 15000,
priceAnnual: 12450,
popular: true,
features: [
"20 Users",
"2,000 Leads",
"10 Active Projects",
"10 GB Storage",
"Adv. Inventory & Costing",
"Bot Assistant (Basic)",
"50 Email Automations"
],
notIncluded: ["White-labeling"],
color: "from-[#B33A3A] to-[#2E2E2E]" // Brick to Charcoal
},
{
title: "Enterprise",
target: "Large Developers",
priceMonthly: 50000,
priceAnnual: 41500,
features: [
"Unlimited Users",
"Unlimited Leads",
"Unlimited Projects",
"50 GB Storage",
"Full AI Bot Assistant",
"Priority Support",
"White-label Option"
],
notIncluded: [],
color: "from-[#2E2E2E] to-[#D4AF37]" // Charcoal to Gold
}
];
const modules = [
{ name: "Landing Page Builder", price: "₹1,000", icon: },
{ name: "Inventory & Costing", price: "₹2,500", icon: },
{ name: "Marketing Collateral", price: "₹2,000", icon: },
{ name: "Bot Assistant", price: "₹2,000", icon: },
{ name: "Email Automation", price: "₹1,500", icon: },
{ name: "Advanced Analytics", price: "₹3,000", icon: },
];
return (
{/* Modal */}
setIsModalOpen(false)} />
{/* --- NAVIGATION --- */ }
Brikly
setIsModalOpen(true)}>Get Started
setIsMenuOpen(!isMenuOpen)}
className="inline-flex items-center p-2 w-10 h-10 justify-center text-sm rounded-lg md:hidden hover:bg-[#2E2E2E]/5 text-[#2E2E2E] focus:outline-none"
>
{isMenuOpen ? : }
{['Features', 'Modules', 'Pricing', 'Resources'].map((item) => (
{item}
))}
{/* --- HERO SECTION WITH INTERACTIVE CITY BUILDER BACKGROUND --- */ }
{/* 3D Scene Container */}
{/* Tagline Badge */}
Brikly 2.0 is now live with AI Reports
Build Deals,
{/* Removed gradient here - solid color used */}
Brick by Brick.
The modular SaaS CRM tailored for real estate developers. Manage inventory, orchestrate broker networks, and close deals with solid precision.
setIsModalOpen(true)}>Start Free Trial
setIsModalOpen(true)}>
Watch Demo
{/* --- STATS SECTION --- */}
{[
{ label: "Leads Processed", value: "10M+" },
{ label: "Active Projects", value: "500+" },
{ label: "Brokers Managed", value: "25k" },
{ label: "Uptime", value: "99.9%" },
].map((stat, i) => (
{stat.value}
{stat.label}
))}
{/* --- INVENTORY MODULE SECTION --- */}
Smart Inventory Command
Your Digital Stockyard.
Forget Excel sheets. Visualize your entire project inventory in a real-time interactive grid. Block units, update cost sheets instantly, and prevent double-booking.
{[
"Real-time Available/Sold/Blocked status",
"One-click Unit Blocking from Mobile",
"Dynamic Cost Sheet Generation",
"Inventory History Logs"
].map((item, i) => (
{item}
))}
setIsModalOpen(true)}>Explore Inventory Module
Tower A - Floor 5
Residential Phase 1
{/* Interactive Unit Grid Visualization */}
{Array.from({ length: 12 }).map((_, i) => {
// Simulating different unit statuses
let statusColor = "bg-green-50 border-green-200 text-green-700"; // Available
let statusLabel = "₹1.2Cr";
if ([2, 5, 9].includes(i)) {
statusColor = "bg-red-50 border-red-200 text-red-700 opacity-60"; // Sold
statusLabel = "SOLD";
} else if ([1, 7].includes(i)) {
statusColor = "bg-yellow-50 border-yellow-200 text-yellow-700"; // Blocked
statusLabel = "Blocked";
}
return (
50{i+1}
{statusLabel}
View
)
})}
Total Valuation
₹ 42.5 Cr
{/* --- MARKETING TRACKING SECTION --- */}
Marketing Intelligence
Stop guessing — start knowing.
Get real-time insights when clients view your brochure, cost sheet, or walkthrough video. Follow up smarter, close faster.
Instant Sharing
Share brochures & price lists with a single click.
Time Tracking
See how long they spent viewing the page.
setIsModalOpen(true)}>Track Client Engagement Now
{/* Decorative Glow */}
{/* Activity Items */}
{[
{ user: "Rajesh Kumar", action: "opened", file: "Tower B Brochure", time: "Just now", icon:
, color: "text-blue-400" },
{ user: "Amit Shah", action: "downloaded", file: "Cost Sheet", time: "5 mins ago", icon:
, color: "text-green-400" },
{ user: "Priya Singh", action: "viewed", file: "Walkthrough Video", time: "12 mins ago", icon:
, color: "text-[#D4AF37]" }
].map((activity, idx) => (
{activity.user.charAt(0)}
{activity.user} {activity.action} {activity.file}
Mumbai, India
{activity.time}
))}
{/* Floating Notification Toast Simulation */}
New Interaction
Client opened Quote #202
{/* --- NEW: AI SALES ASSISTANT (CHAT BOT) SECTION --- */}
{/* Left: Text Content */}
AI Sales Assistant
Your 24/7 Sales Powerhouse.
Handle thousands of lead queries instantly. From checking inventory availability to generating complex cost sheets, the Brikly AI Bot does it all via WhatsApp or Web Chat.
setIsModalOpen(true)}>Try AI Demo
{/* Right: Phone Simulator with Live Chat */}
{/* Phone Bezel */}
{/* Screen */}
{/* Status Bar */}
{/* Chat Header */}
{/* Chat Area */}
Today
{/* Messages Loop */}
{chatMessages.map((msg, i) => (
{msg.isCostSheet ? (
Cost Sheet Generated
Base Price: ₹75.00 L
GST (5%): ₹3.75 L
PLC: ₹2.00 L
Total: ₹80.75 L
Download PDF
) : (
{msg.text}
)}
))}
{/* Typing Indicator */}
{isTyping && (
)}
{/* Chat Input Area (Visual Only) */}
{/* --- MODULAR ARCHITECTURE SECTION --- */}
Why pay for what you don't use?
Brikly uses a unique modular pricing model. Start with the base plan and enable only the powerful modules your business actually needs.
{modules.map((mod, idx) => (
{mod.icon}
{mod.price}/mo
{mod.name}
Activate this module to unlock advanced capabilities specific to your workflow. Disable anytime.
))}
{/* --- FEATURES GRID (Charcoal Background for Contrast) --- */}
Complete Control over
Real Estate Sales
{[
{ title: "Smart Inventory", desc: "Visualize unit availability, cost sheets, and block inventory in real-time.", icon:
},
{ title: "Broker Network", desc: "Onboard channel partners, track their leads, and automate commission payouts.", icon:
},
{ title: "Automated Nurturing", desc: "Send WhatsApp, Email, and SMS blasts automatically based on lead stage.", icon:
}
].map((feat, i) => (
))}
Lead Pipeline
Export CSV
{[1,2,3,4].map((n) => (
{n===1 ? 'Booked' : 'Follow Up'}
))}
{/* --- PRICING --- */}
Simple, Transparent Pricing
Choose the base plan that fits your scale. Add modules as you grow.
{/* Toggle */}
setIsAnnual(false)}
className={`px-6 py-2 rounded-full text-sm font-medium transition-all ${!isAnnual ? 'bg-[#2E2E2E] text-white shadow-lg' : 'text-[#2E2E2E]/50 hover:text-[#2E2E2E]'}`}
>
Monthly
setIsAnnual(true)}
className={`px-6 py-2 rounded-full text-sm font-medium transition-all flex items-center gap-2 ${isAnnual ? 'bg-[#2E2E2E] text-white shadow-lg' : 'text-[#2E2E2E]/50 hover:text-[#2E2E2E]'}`}
>
Annual -17%
{pricingData.map((plan, idx) => (
{plan.popular && (
Most Popular
)}
{/* Changed from gradient to solid */}
{plan.title}
{plan.target}
₹{(isAnnual ? plan.priceAnnual : plan.priceMonthly).toLocaleString()}
/mo
{isAnnual &&
Billed ₹{(plan.priceAnnual * 12).toLocaleString()} yearly
}
{plan.features.map((feature, fIdx) => (
{feature}
))}
{plan.notIncluded.map((feature, fIdx) => (
{feature}
))}
setIsModalOpen(true)}>
{plan.title === 'Enterprise' ? 'Contact Sales' : 'Start Free Trial'}
+ Pay-per-module pricing
))}
{/* --- CTA SECTION (UPDATED: Force Dark Background & Modal Trigger) --- */}
{/* Added direct bg color */}
Ready to close more deals?
Join 500+ developers using Brikly to streamline their sales.
No credit card required for the 14-day trial.
setIsModalOpen(true)}>Get Started Now
setIsModalOpen(true)}>Book Consultation
{/* --- FOOTER --- */}
);
}