3541 lines
151 KiB
React
3541 lines
151 KiB
React
import React, { useState, useEffect, useRef } from 'react';
|
||
|
||
import { assetUrl } from './lib/assetUrl';
|
||
import { motion, useScroll, useTransform, useMotionValueEvent, useReducedMotion } from 'framer-motion';
|
||
import { useContent } from './context/ContentContext';
|
||
import { usePreviewMode } from './context/PreviewContext';
|
||
import ServiceDial from './components/ServiceDial';
|
||
import FeaturedGallery from './components/FeaturedGallery';
|
||
import ProductCard from './components/ProductCard';
|
||
import ContactSection from './components/ContactSection';
|
||
import AboutUsPage from './components/AboutUsPage';
|
||
import TurnstileCaptcha from './components/TurnstileCaptcha';
|
||
import GlassmorphicSelect from './components/GlassmorphicSelect';
|
||
import GlassmorphicDatePicker from './components/GlassmorphicDatePicker';
|
||
import BlogDetailPage from './components/BlogDetailPage';
|
||
import CareersPage from './components/CareersPage';
|
||
import BlogsPage from './components/BlogsPage';
|
||
|
||
// Reusable Scroll Reveal Wrapper with Reduced Motion Support
|
||
function Reveal({ children, delay = 0, style }) {
|
||
const shouldReduceMotion = useReducedMotion();
|
||
const previewMode = usePreviewMode();
|
||
if (shouldReduceMotion && !previewMode) return <div style={style}>{children}</div>;
|
||
return (
|
||
<motion.div
|
||
initial={{ opacity: 0, y: 40 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true, amount: 0.1 }}
|
||
transition={{
|
||
duration: 0.8,
|
||
ease: [0.22, 1, 0.36, 1],
|
||
delay: delay
|
||
}}
|
||
style={style}
|
||
>
|
||
{children}
|
||
</motion.div>
|
||
);
|
||
}
|
||
import {
|
||
ArrowRight,
|
||
Sparkles,
|
||
Database,
|
||
Cpu,
|
||
LineChart,
|
||
Layers,
|
||
Activity,
|
||
Settings,
|
||
Shield,
|
||
TrendingUp,
|
||
Globe,
|
||
ChevronRight,
|
||
ChevronLeft,
|
||
Mail,
|
||
CheckCircle,
|
||
Clock,
|
||
Compass,
|
||
Zap,
|
||
Layout,
|
||
ExternalLink,
|
||
ChevronDown,
|
||
BrainCircuit,
|
||
Factory,
|
||
Network,
|
||
UsersRound,
|
||
ShieldCheck,
|
||
Code2,
|
||
CloudCog,
|
||
Glasses,
|
||
Menu,
|
||
X
|
||
} from 'lucide-react';
|
||
|
||
const iconMap = {
|
||
BrainCircuit,
|
||
Factory,
|
||
Network,
|
||
UsersRound,
|
||
ShieldCheck,
|
||
Code2,
|
||
CloudCog,
|
||
Glasses,
|
||
Sparkles
|
||
};
|
||
|
||
// Reusable Orbital Logo Component for animated paths around header text
|
||
const OrbitalLogo = ({ src, alt, radiusX, radiusY, startAngle, duration, clockwise = true, size = 120 }) => {
|
||
const [position, setPosition] = useState({ x: 0, y: 0 });
|
||
|
||
useEffect(() => {
|
||
const speed = (2 * Math.PI) / (duration * 1000); // radians per millisecond
|
||
const direction = clockwise ? 1 : -1;
|
||
const startRad = (startAngle * Math.PI) / 180;
|
||
|
||
let animFrame;
|
||
const update = () => {
|
||
const elapsed = performance.now();
|
||
const angle = startRad + direction * speed * elapsed;
|
||
|
||
const x = radiusX * Math.cos(angle);
|
||
const y = radiusY * Math.sin(angle);
|
||
|
||
setPosition({ x, y });
|
||
animFrame = requestAnimationFrame(update);
|
||
};
|
||
|
||
animFrame = requestAnimationFrame(update);
|
||
return () => cancelAnimationFrame(animFrame);
|
||
}, [radiusX, radiusY, startAngle, duration, clockwise]);
|
||
|
||
return (
|
||
<motion.div
|
||
whileHover={{ scale: 1.1 }}
|
||
transition={{ type: 'spring', stiffness: 300, damping: 15 }}
|
||
style={{
|
||
position: 'absolute',
|
||
top: '50%',
|
||
left: '50%',
|
||
x: `calc(-50% + ${position.x}px)`,
|
||
y: `calc(-50% + ${position.y}px)`,
|
||
width: `${size}px`,
|
||
height: '80px',
|
||
display: 'flex',
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
cursor: 'pointer',
|
||
zIndex: 10,
|
||
pointerEvents: 'auto',
|
||
}}
|
||
>
|
||
<img src={src} alt={alt} style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }} />
|
||
</motion.div>
|
||
);
|
||
};
|
||
|
||
function ServiceCard({ service, isMobile, index = 0 }) {
|
||
const shouldReduceMotion = useReducedMotion();
|
||
|
||
const service3dImages = [
|
||
'/assets/image 179.png',
|
||
'/assets/image 180.png',
|
||
'/assets/image 181.png',
|
||
'/assets/image 182.png',
|
||
'/assets/image 184.png'
|
||
];
|
||
|
||
const cardBackgrounds = [
|
||
'radial-gradient(circle at 85% 15%, rgba(150, 45, 30, 0.45) 0%, rgba(22, 10, 11, 0.98) 55%)',
|
||
'radial-gradient(circle at 85% 15%, rgba(20, 100, 140, 0.45) 0%, rgba(10, 18, 25, 0.98) 55%)',
|
||
'radial-gradient(circle at 85% 15%, rgba(140, 50, 30, 0.4) 0%, rgba(20, 12, 12, 0.98) 55%)',
|
||
'radial-gradient(circle at 85% 15%, rgba(15, 115, 140, 0.45) 0%, rgba(10, 19, 26, 0.98) 55%)',
|
||
'radial-gradient(circle at 85% 15%, rgba(30, 90, 140, 0.45) 0%, rgba(12, 18, 28, 0.98) 55%)'
|
||
];
|
||
|
||
const formatTitle = (title) => {
|
||
if (title.includes('AI & Data')) return <>AI & Data<br />Services</>;
|
||
if (title.includes('Enterprise')) return <>Enterprise<br />Software</>;
|
||
if (title.includes('SAP')) return <>SAP Managed<br />Services</>;
|
||
if (title.includes('Smart')) return <>Smart<br />Factory</>;
|
||
if (title.includes('AR/VR')) return <>AR/VR &<br />Immersive<br />Technologies</>;
|
||
return title;
|
||
};
|
||
|
||
const revealProps = shouldReduceMotion ? {} : {
|
||
initial: { opacity: 0, y: 40 },
|
||
whileInView: { opacity: 1, y: 0 },
|
||
viewport: { once: true, amount: 0.15 },
|
||
transition: {
|
||
y: { type: 'tween', duration: 0.8, ease: [0.22, 1, 0.36, 1], delay: index * 0.1 },
|
||
opacity: { duration: 0.8, ease: 'easeOut', delay: index * 0.1 }
|
||
}
|
||
};
|
||
|
||
const current3dImg = service.image || service3dImages[index % service3dImages.length];
|
||
|
||
return (
|
||
<motion.div
|
||
whileHover={isMobile ? {} : { y: -6, borderColor: 'rgba(255, 255, 255, 0.25)', boxShadow: '0 20px 40px rgba(0, 0, 0, 0.6)' }}
|
||
{...revealProps}
|
||
style={{
|
||
flex: '0 0 auto',
|
||
scrollSnapAlign: 'start',
|
||
width: isMobile ? '300px' : '390px',
|
||
minHeight: isMobile ? '560px' : '630px',
|
||
background: cardBackgrounds[index % cardBackgrounds.length],
|
||
backdropFilter: 'blur(16px)',
|
||
borderRadius: '16px',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
padding: isMobile ? '1.8rem 1.4rem' : '2.2rem 2rem',
|
||
position: 'relative',
|
||
overflow: 'hidden',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
justifyContent: 'space-between',
|
||
boxShadow: '0 10px 30px rgba(0, 0, 0, 0.4)',
|
||
transition: 'all 0.3s ease'
|
||
}}
|
||
>
|
||
{/* Background Watermark Number */}
|
||
<div style={{
|
||
position: 'absolute',
|
||
bottom: '-25px',
|
||
right: '15px',
|
||
fontSize: isMobile ? '130px' : '170px',
|
||
fontWeight: 900,
|
||
color: 'rgba(255, 255, 255, 0.025)',
|
||
lineHeight: '1',
|
||
pointerEvents: 'none',
|
||
userSelect: 'none',
|
||
zIndex: 0
|
||
}}>
|
||
{service.number}
|
||
</div>
|
||
|
||
<div style={{ position: 'relative', zIndex: 2 }}>
|
||
{/* Top Header Row with Title and 3D Graphic */}
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '1.8rem', minHeight: '120px' }}>
|
||
<h3 style={{
|
||
fontSize: isMobile ? '1.6rem' : '2.1rem',
|
||
fontWeight: 500,
|
||
color: '#ffffff',
|
||
letterSpacing: '-0.02em',
|
||
lineHeight: '1.18',
|
||
margin: 0,
|
||
maxWidth: '220px'
|
||
}}>
|
||
{formatTitle(service.title)}
|
||
</h3>
|
||
|
||
{/* 3D Graphic Image */}
|
||
<div style={{
|
||
width: isMobile ? '140px' : '185px',
|
||
height: isMobile ? '140px' : '185px',
|
||
flexShrink: 0,
|
||
position: 'absolute',
|
||
top: '-15px',
|
||
right: '-15px',
|
||
pointerEvents: 'none',
|
||
}}>
|
||
<img
|
||
src={assetUrl(current3dImg)}
|
||
alt={`${service.title} 3D Illustration`}
|
||
style={{
|
||
width: '100%',
|
||
height: '100%',
|
||
objectFit: 'contain',
|
||
filter: 'drop-shadow(0 12px 25px rgba(0, 0, 0, 0.6))'
|
||
}}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Sub-text Section: Bold Statement + Description with Left Vertical Line */}
|
||
<div style={{
|
||
display: 'flex',
|
||
gap: '0.85rem',
|
||
marginBottom: '1.6rem'
|
||
}}>
|
||
<div style={{
|
||
width: '3px',
|
||
background: '#ffffff',
|
||
borderRadius: '2px',
|
||
flexShrink: 0
|
||
}} />
|
||
<div>
|
||
<h4 style={{
|
||
fontSize: isMobile ? '0.88rem' : '0.94rem',
|
||
fontWeight: 700,
|
||
color: '#ffffff',
|
||
lineHeight: '1.4',
|
||
margin: '0 0 0.5rem 0'
|
||
}}>
|
||
{service.boldStatement}
|
||
</h4>
|
||
<p style={{
|
||
color: '#94a3b8',
|
||
fontSize: isMobile ? '0.8rem' : '0.85rem',
|
||
lineHeight: '1.5',
|
||
margin: 0,
|
||
fontWeight: 400
|
||
}}>
|
||
{service.description}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Capabilities Bullet List */}
|
||
<ul style={{
|
||
listStyle: 'none',
|
||
padding: 0,
|
||
margin: 0,
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: '0.7rem'
|
||
}}>
|
||
{service.capabilities.map((capability, idx) => {
|
||
const parts = capability.split(/\s[–-]\s/);
|
||
const boldText = parts.length > 1 ? parts[0] : null;
|
||
const restText = parts.length > 1 ? parts.slice(1).join(' - ') : capability;
|
||
|
||
return (
|
||
<li key={idx} style={{
|
||
display: 'flex',
|
||
alignItems: 'flex-start',
|
||
gap: '0.55rem',
|
||
fontSize: isMobile ? '0.8rem' : '0.85rem',
|
||
fontWeight: 400,
|
||
color: '#94a3b8',
|
||
lineHeight: '1.45'
|
||
}}>
|
||
<span style={{ color: '#ffffff', opacity: 0.9, fontSize: '0.95rem', marginTop: '0.05rem', fontWeight: 'bold' }}>»</span>
|
||
<div>
|
||
{boldText ? <><strong style={{ color: '#ffffff', fontWeight: 600 }}>{boldText}</strong> – {restText}</> : restText}
|
||
</div>
|
||
</li>
|
||
);
|
||
})}
|
||
</ul>
|
||
</div>
|
||
|
||
{/* Bottom Link CTA - commented out per user request
|
||
<div style={{ position: 'relative', zIndex: 2, marginTop: '2rem' }}>
|
||
<button
|
||
type="button"
|
||
onClick={() => {
|
||
const footer = document.getElementById('contactus');
|
||
if (footer) {
|
||
footer.scrollIntoView({ behavior: 'smooth' });
|
||
}
|
||
}}
|
||
style={{
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
gap: '0.4rem',
|
||
color: '#ffffff',
|
||
fontSize: isMobile ? '0.85rem' : '0.9rem',
|
||
fontWeight: 600,
|
||
background: 'none',
|
||
border: 'none',
|
||
padding: 0,
|
||
cursor: 'pointer',
|
||
transition: 'all 0.25s ease',
|
||
opacity: 0.95
|
||
}}
|
||
onMouseEnter={(e) => {
|
||
e.currentTarget.style.gap = '0.7rem';
|
||
e.currentTarget.style.opacity = '1';
|
||
}}
|
||
onMouseLeave={(e) => {
|
||
e.currentTarget.style.gap = '0.4rem';
|
||
e.currentTarget.style.opacity = '0.95';
|
||
}}
|
||
>
|
||
<span>{service.cta || 'Explore Solutions'}</span>
|
||
<ArrowRight size={16} />
|
||
</button>
|
||
</div>
|
||
*/}
|
||
</motion.div>
|
||
);
|
||
}
|
||
|
||
export default function App({ previewMode = false }) {
|
||
const { content, loading } = useContent();
|
||
const services = content.services?.items ?? [];
|
||
const insights = content.insights?.items ?? [];
|
||
const metrics = content.metrics ?? [];
|
||
const hero = content.hero ?? {};
|
||
const about = content.about ?? {};
|
||
const partners = content.partners ?? { logos: [] };
|
||
const certifications = content.certifications ?? { items: [] };
|
||
const whyUs = content.whyUs ?? { cards: [], images: [] };
|
||
const products = content.products ?? { items: [] };
|
||
const footer = content.footer ?? { cta: {}, quickLinks: [], productLinks: [], social: [], legal: [] };
|
||
|
||
// Tabs for Hero Section
|
||
const [activeHeroTab, setActiveHeroTab] = useState('agile');
|
||
// Carousel slide for Products
|
||
const [activeProductIndex, setActiveProductIndex] = useState(0);
|
||
// Active detail index in Services Section
|
||
const [activeServiceIndex, setActiveServiceIndex] = useState(0);
|
||
const [isMobile, setIsMobile] = useState(false);
|
||
const [isCareersOpen, setIsCareersOpen] = useState(false);
|
||
const [activeSection, setActiveSection] = useState('home');
|
||
const [currentPage, setCurrentPage] = useState('home');
|
||
const [navbarVisible, setNavbarVisible] = useState(true);
|
||
const lastScrollY = useRef(0);
|
||
|
||
const smoothScrollTo = (top) => {
|
||
document.body.style.pointerEvents = 'none';
|
||
window.scrollTo({ top, behavior: 'smooth' });
|
||
|
||
let scrollTimeout;
|
||
const handleScrollEnd = () => {
|
||
document.body.style.pointerEvents = '';
|
||
window.removeEventListener('scrollend', handleScrollEnd);
|
||
window.removeEventListener('scroll', handleScrollDebounce);
|
||
clearTimeout(scrollTimeout);
|
||
};
|
||
|
||
const handleScrollDebounce = () => {
|
||
clearTimeout(scrollTimeout);
|
||
scrollTimeout = setTimeout(handleScrollEnd, 100);
|
||
};
|
||
|
||
window.addEventListener('scrollend', handleScrollEnd);
|
||
window.addEventListener('scroll', handleScrollDebounce);
|
||
scrollTimeout = setTimeout(handleScrollEnd, 800);
|
||
};
|
||
|
||
const [selectedBlog, setSelectedBlog] = useState(null);
|
||
|
||
const handleSelectBlog = (blog) => {
|
||
setNavbarVisible(true);
|
||
setMobileMenuOpen(false);
|
||
setSelectedBlog(blog);
|
||
setCurrentPage('blog');
|
||
window.location.hash = blog?.slug ? `blog-${blog.slug}` : 'blog';
|
||
smoothScrollTo(0);
|
||
};
|
||
|
||
useEffect(() => {
|
||
const syncPageFromHash = (shouldScroll = false) => {
|
||
const hash = window.location.hash.replace('#', '');
|
||
if (hash === 'contact' || hash === 'contactus') {
|
||
setSelectedBlog(null);
|
||
setCurrentPage('contact');
|
||
setActiveSection('contactus');
|
||
if (shouldScroll) smoothScrollTo(0);
|
||
} else if (hash === 'about' || hash === 'aboutus') {
|
||
setSelectedBlog(null);
|
||
setCurrentPage('about');
|
||
setActiveSection('aboutus');
|
||
if (shouldScroll) smoothScrollTo(0);
|
||
} else if (hash === 'careers') {
|
||
setSelectedBlog(null);
|
||
setCurrentPage('careers');
|
||
setActiveSection('careers');
|
||
if (shouldScroll) smoothScrollTo(0);
|
||
} else if (hash === 'blogs') {
|
||
setSelectedBlog(null);
|
||
setCurrentPage('blogs');
|
||
setActiveSection('blogs');
|
||
if (shouldScroll) smoothScrollTo(0);
|
||
} else if (hash.startsWith('blog-') || hash === 'blog') {
|
||
const slug = hash.replace('blog-', '');
|
||
const found = insights.find(b => b.slug === slug || String(b.id) === slug);
|
||
if (found) {
|
||
setSelectedBlog(prev => (prev && (prev.id === found.id || (prev.slug && prev.slug === found.slug)) ? prev : found));
|
||
} else if (insights && insights.length > 0) {
|
||
setSelectedBlog(prev => prev || insights[0]);
|
||
}
|
||
setCurrentPage('blog');
|
||
if (shouldScroll) smoothScrollTo(0);
|
||
} else if (hash === 'home' || hash === '') {
|
||
setSelectedBlog(null);
|
||
setCurrentPage('home');
|
||
}
|
||
};
|
||
syncPageFromHash(false);
|
||
const handleHashChange = () => syncPageFromHash(true);
|
||
window.addEventListener('hashchange', handleHashChange);
|
||
return () => window.removeEventListener('hashchange', handleHashChange);
|
||
}, [insights]);
|
||
const [hoveredItem, setHoveredItem] = useState(null);
|
||
const [showCareersAcknowledgement, setShowCareersAcknowledgement] = useState(false);
|
||
const [isStrategyOpen, setIsStrategyOpen] = useState(false);
|
||
const [showStrategyAcknowledgement, setShowStrategyAcknowledgement] = useState(false);
|
||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||
|
||
// Careers Form Fields
|
||
const [careersName, setCareersName] = useState('');
|
||
const [careersEmail, setCareersEmail] = useState('');
|
||
const [careersPhone, setCareersPhone] = useState('');
|
||
const [careersFile, setCareersFile] = useState(null);
|
||
const [careersTurnstileToken, setCareersTurnstileToken] = useState('');
|
||
const [careersErrorMsg, setCareersErrorMsg] = useState('');
|
||
const [isCareersSubmitting, setIsCareersSubmitting] = useState(false);
|
||
|
||
// Strategy Form Fields
|
||
const [strategyName, setStrategyName] = useState('');
|
||
const [strategyEmail, setStrategyEmail] = useState('');
|
||
const [strategyMobile, setStrategyMobile] = useState('');
|
||
const [strategyDesignation, setStrategyDesignation] = useState('');
|
||
const [strategyDate, setStrategyDate] = useState('');
|
||
const [strategyTime, setStrategyTime] = useState('');
|
||
const [strategyInterests, setStrategyInterests] = useState({
|
||
'AI & Analytics': false,
|
||
'SAP Services': false,
|
||
'XR Platforms': false,
|
||
'Smart Factory': false,
|
||
'Cloud Engineering': false,
|
||
'Enterprise Software': false,
|
||
});
|
||
const [strategyTurnstileToken, setStrategyTurnstileToken] = useState('');
|
||
const [strategyErrorMsg, setStrategyErrorMsg] = useState('');
|
||
const [isStrategySubmitting, setIsStrategySubmitting] = useState(false);
|
||
useEffect(() => {
|
||
const checkMobile = () => {
|
||
setIsMobile(window.innerWidth < 1024);
|
||
};
|
||
checkMobile();
|
||
window.addEventListener('resize', checkMobile);
|
||
return () => window.removeEventListener('resize', checkMobile);
|
||
}, []);
|
||
|
||
const [flippingLogo, setFlippingLogo] = useState(null);
|
||
|
||
useEffect(() => {
|
||
const triggerRandomFlip = () => {
|
||
const logoNumbers = [27, 28, 30, 31, 32, 33, 34, 35, 36];
|
||
const randomNum = logoNumbers[Math.floor(Math.random() * logoNumbers.length)];
|
||
setFlippingLogo(randomNum);
|
||
|
||
// Clear flip after animation completes
|
||
setTimeout(() => {
|
||
setFlippingLogo(null);
|
||
}, 1000);
|
||
};
|
||
|
||
// Trigger random flip every 3.5 seconds
|
||
const interval = setInterval(triggerRandomFlip, 3500);
|
||
return () => clearInterval(interval);
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
if (previewMode) return;
|
||
|
||
let lastScroll = window.scrollY;
|
||
|
||
const handleScroll = () => {
|
||
const currentScroll = window.scrollY;
|
||
const diff = currentScroll - lastScroll;
|
||
|
||
if (currentScroll <= 50) {
|
||
setNavbarVisible(true);
|
||
} else if (diff > 5 && currentScroll > 100) {
|
||
setNavbarVisible(false);
|
||
} else if (diff < -5) {
|
||
setNavbarVisible(true);
|
||
}
|
||
|
||
lastScroll = currentScroll;
|
||
|
||
if (currentPage === 'home') {
|
||
// If at top of the page, home is active
|
||
if (currentScroll < 100) {
|
||
setActiveSection('home');
|
||
return;
|
||
}
|
||
|
||
const sections = ['home', 'aboutus', 'services', 'whyus', 'products', 'insights', 'contactus'];
|
||
const scrollPosition = currentScroll + 120; // 120px offset for header height and visual center
|
||
|
||
// Special case: if scrolled down near the very bottom of the page, contactus is active
|
||
if (currentScroll > 300 && window.innerHeight + currentScroll >= document.documentElement.scrollHeight - 100) {
|
||
setActiveSection('contactus');
|
||
return;
|
||
}
|
||
|
||
for (const sectionId of sections) {
|
||
const el = document.getElementById(sectionId);
|
||
if (el) {
|
||
const top = el.offsetTop;
|
||
const height = el.offsetHeight;
|
||
if (scrollPosition >= top && scrollPosition < top + height) {
|
||
setActiveSection(sectionId);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
window.addEventListener('scroll', handleScroll);
|
||
handleScroll(); // run once on mount
|
||
return () => window.removeEventListener('scroll', handleScroll);
|
||
}, [previewMode, currentPage]);
|
||
|
||
const getActiveNavItem = () => {
|
||
if (currentPage === 'blogs' || currentPage === 'blog') return 'Blogs';
|
||
if (currentPage === 'contact') return 'Contact Us';
|
||
if (currentPage === 'about') return 'About Us';
|
||
switch (activeSection) {
|
||
case 'home':
|
||
return 'Home';
|
||
case 'aboutus':
|
||
case 'services':
|
||
case 'whyus':
|
||
return 'About Us';
|
||
case 'products':
|
||
return 'Products';
|
||
case 'insights':
|
||
case 'blogs':
|
||
return 'Blogs';
|
||
case 'contactus':
|
||
return 'Contact Us';
|
||
default:
|
||
return 'Home';
|
||
}
|
||
};
|
||
|
||
const servicesScrollRef = useRef(null);
|
||
|
||
const scrollServices = (direction) => {
|
||
if (servicesScrollRef.current) {
|
||
const scrollAmount = isMobile ? 310 : 444; // card width + gap
|
||
servicesScrollRef.current.scrollBy({
|
||
left: direction === 'left' ? -scrollAmount : scrollAmount,
|
||
behavior: 'smooth'
|
||
});
|
||
}
|
||
};
|
||
|
||
// Carousel for Insights
|
||
const [insightIndex, setInsightIndex] = useState(0);
|
||
const blogCarouselRef = useRef(null);
|
||
|
||
const scrollBlogCarousel = (dir) => {
|
||
if (blogCarouselRef.current) {
|
||
const cardWidth = (isMobile ? window.innerWidth * 0.72 : 340) + 24;
|
||
blogCarouselRef.current.scrollBy({ left: dir * cardWidth, behavior: 'smooth' });
|
||
}
|
||
};
|
||
|
||
const sectionX = isMobile ? '1.25rem' : '4rem';
|
||
const navItems = ['Home', 'About Us', 'Products', 'Blogs', 'Careers', 'Contact Us'];
|
||
const NAV_OFFSET = isMobile ? 72 : 88;
|
||
|
||
const scrollToSection = (sectionId) => {
|
||
const el = document.getElementById(sectionId);
|
||
if (el) {
|
||
const top = el.getBoundingClientRect().top + window.scrollY - NAV_OFFSET;
|
||
smoothScrollTo(top);
|
||
setActiveSection(sectionId);
|
||
} else if (sectionId === 'contactus') {
|
||
smoothScrollTo(document.documentElement.scrollHeight);
|
||
setActiveSection('contactus');
|
||
}
|
||
};
|
||
|
||
const handleNavClick = (item) => {
|
||
setNavbarVisible(true);
|
||
setMobileMenuOpen(false);
|
||
setSelectedBlog(null);
|
||
|
||
if (item === 'Careers') {
|
||
setIsCareersOpen(true);
|
||
return;
|
||
}
|
||
|
||
if (item === 'Blogs') {
|
||
setCurrentPage('blogs');
|
||
setActiveSection('blogs');
|
||
window.location.hash = 'blogs';
|
||
smoothScrollTo(0);
|
||
return;
|
||
}
|
||
|
||
if (item === 'Contact Us') {
|
||
setCurrentPage('contact');
|
||
setActiveSection('contactus');
|
||
window.location.hash = 'contact';
|
||
smoothScrollTo(0);
|
||
return;
|
||
}
|
||
|
||
if (item === 'About Us') {
|
||
setCurrentPage('about');
|
||
setActiveSection('aboutus');
|
||
window.location.hash = 'aboutus';
|
||
smoothScrollTo(0);
|
||
return;
|
||
}
|
||
|
||
const sectionMap = {
|
||
Home: 'home',
|
||
Products: 'products',
|
||
};
|
||
const id = sectionMap[item];
|
||
|
||
const doScroll = (sectionId) => {
|
||
if (!sectionId || sectionId === 'home') {
|
||
smoothScrollTo(0);
|
||
return;
|
||
}
|
||
requestAnimationFrame(() => {
|
||
const el = document.getElementById(sectionId);
|
||
if (el) {
|
||
const top = el.getBoundingClientRect().top + window.scrollY - NAV_OFFSET;
|
||
smoothScrollTo(top);
|
||
setActiveSection(sectionId);
|
||
}
|
||
});
|
||
};
|
||
|
||
if (currentPage !== 'home') {
|
||
setCurrentPage('home');
|
||
setActiveSection(id || 'home');
|
||
window.location.hash = id || 'home';
|
||
setTimeout(() => doScroll(id), 350);
|
||
return;
|
||
}
|
||
|
||
window.location.hash = id || 'home';
|
||
doScroll(id);
|
||
};
|
||
|
||
useEffect(() => {
|
||
document.body.style.overflow = mobileMenuOpen ? 'hidden' : '';
|
||
return () => { document.body.style.overflow = ''; };
|
||
}, [mobileMenuOpen]);
|
||
|
||
const heroTabs = [
|
||
{ id: 'agile', label: 'Agile Dev' },
|
||
{ id: 'fullstack', label: 'Full-Stack Tech' },
|
||
{ id: 'ai', label: 'AI & Analytics' },
|
||
{ id: 'devops', label: 'DevOps' }
|
||
];
|
||
|
||
// Dummy contents for Hero tabs to make it feel alive
|
||
const heroTabContent = {
|
||
agile: { title: 'Rapid Iterative Delivery', desc: 'Accelerating release cycles through agile management and continuous deployment pipelines.' },
|
||
fullstack: { title: 'Modern Core Architectures', desc: 'Scalable frontend, backend, and database infrastructures designed for ultimate reliability.' },
|
||
ai: { title: 'Intelligent Automation', desc: 'Harnessing ML and LLM integrations to optimize workflows and drive business intelligence.' },
|
||
devops: { title: 'Automated Operations', desc: 'Secure cloud hosting, zero-downtime deployments, and real-time environment monitoring.' }
|
||
};
|
||
|
||
const clients = [
|
||
{ name: 'TVS', logo: 'TVS' },
|
||
{ name: 'Hero', logo: 'Hero' },
|
||
{ name: 'V-Guard', logo: 'V-Guard' },
|
||
{ name: 'Muthoot', logo: 'Muthoot' },
|
||
{ name: 'MRF', logo: 'MRF' },
|
||
{ name: 'HDFC', logo: 'HDFC' }
|
||
];
|
||
|
||
const whyChooseUs = [
|
||
{
|
||
title: 'Innovation Driven',
|
||
desc: 'Integrating state-of-the-art technologies and custom automation architectures into your core workflows to future-proof business value.',
|
||
icon: <Sparkles className="text-amber-500 w-8 h-8" />
|
||
},
|
||
{
|
||
title: 'Industry Expertise',
|
||
desc: 'Deep industry knowledge spanning insurance, fintech, operations, logistics, and highly regulated enterprise application suites.',
|
||
icon: <Database className="text-blue-400 w-8 h-8" />
|
||
},
|
||
{
|
||
title: 'Outcome Focused',
|
||
desc: 'Committed to delivering measurable business impact, reduced infrastructure overhead, and highly optimized operational metrics.',
|
||
icon: <TrendingUp className="text-cyan-400 w-8 h-8" />
|
||
},
|
||
{
|
||
title: 'Customer Centric',
|
||
desc: 'Collaborating hand-in-hand to build solutions tailored specifically to your unique workflow demands, users, and scaling plans.',
|
||
icon: <Layers className="text-indigo-400 w-8 h-8" />
|
||
}
|
||
];
|
||
|
||
if (loading) {
|
||
return (
|
||
<div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#020710', color: '#94a3b8' }}>
|
||
Loading...
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div style={{ backgroundColor: '#020710', color: '#ffffff', minHeight: '100vh', position: 'relative', display: 'flex', flexDirection: 'column', width: '100%' }}>
|
||
|
||
{/* Main Content Wrapper with solid background and higher z-index for sticky footer parallax reveal */}
|
||
<div style={{ position: 'relative', zIndex: 10, backgroundColor: '#020710', width: '100%', overflow: 'hidden' }}>
|
||
|
||
{/* Background Glows */}
|
||
<div style={{
|
||
position: 'absolute', top: 0, left: '10%', right: '10%', height: '600px',
|
||
background: 'radial-gradient(circle, rgba(0, 119, 255, 0.12) 0%, transparent 70%)',
|
||
pointerEvents: 'none', zIndex: 0
|
||
}} />
|
||
<div style={{
|
||
position: 'absolute', top: '1200px', right: '5%', width: '500px', height: '500px',
|
||
background: 'radial-gradient(circle, rgba(255, 85, 0, 0.08) 0%, transparent 70%)',
|
||
pointerEvents: 'none', zIndex: 0
|
||
}} />
|
||
<div style={{
|
||
position: 'absolute', top: '2200px', left: '5%', width: '600px', height: '600px',
|
||
background: 'radial-gradient(circle, rgba(0, 240, 255, 0.08) 0%, transparent 70%)',
|
||
pointerEvents: 'none', zIndex: 0
|
||
}} />
|
||
|
||
{/* Navigation Bar */}
|
||
<nav className="glass site-nav" style={{
|
||
position: 'sticky',
|
||
top: navbarVisible ? 0 : (isMobile ? '-72px' : '-88px'),
|
||
zIndex: 50,
|
||
padding: isMobile ? '0.85rem 1.25rem' : '1.2rem 4rem',
|
||
borderBottom: activeSection === 'products' ? '1px solid rgba(15, 23, 42, 0.08)' : '1px solid rgba(255, 255, 255, 0.05)',
|
||
transition: 'top 0.3s cubic-bezier(0.16, 1, 0.3, 1), border-bottom 0.3s ease, padding 0.3s ease'
|
||
}}>
|
||
<div style={{ maxWidth: '1440px', margin: '0 auto', width: '100%', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||
<div
|
||
style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }}
|
||
onClick={() => {
|
||
setCurrentPage('home');
|
||
setActiveSection('home');
|
||
window.location.hash = 'home';
|
||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||
}}
|
||
>
|
||
<img src={assetUrl('/assets/cavin_logo.svg')} alt="Cavin Infotech Logo" style={{ height: isMobile ? '38px' : '50px', display: 'block' }} />
|
||
</div>
|
||
|
||
{!isMobile && (
|
||
<div className="site-nav-links" style={{ display: 'flex', gap: '2rem', alignItems: 'center' }}>
|
||
{navItems.map((item) => {
|
||
const isLightSection = activeSection === 'products';
|
||
const activeNavItem = getActiveNavItem();
|
||
const isActive = activeNavItem === item;
|
||
const isHovered = hoveredItem === item;
|
||
|
||
let linkColor;
|
||
if (isLightSection) {
|
||
linkColor = (isActive || isHovered) ? '#b45309' : '#1e293b';
|
||
} else {
|
||
linkColor = (isActive || isHovered) ? '#ffaa00' : '#a0aec0';
|
||
}
|
||
|
||
return (
|
||
<a
|
||
key={item}
|
||
href={(item === 'Careers' || item === 'Products') ? undefined : `#${item.toLowerCase().replace(' ', '')}`}
|
||
onClick={(e) => {
|
||
e.preventDefault();
|
||
handleNavClick(item);
|
||
}}
|
||
style={{
|
||
color: linkColor,
|
||
textDecoration: 'none',
|
||
fontSize: '0.95rem',
|
||
fontWeight: 500,
|
||
transition: 'all 0.3s ease',
|
||
cursor: 'pointer'
|
||
}}
|
||
onMouseEnter={() => setHoveredItem(item)}
|
||
onMouseLeave={() => setHoveredItem(null)}
|
||
>
|
||
{item}
|
||
</a>
|
||
);
|
||
})}
|
||
<div className="btn-sparkle-wrapper">
|
||
<img src={assetUrl('/assets/button_hover_effect.png')} className="btn-sparkles" alt="" />
|
||
<button className="btn-talk" onClick={() => setIsStrategyOpen(true)}>
|
||
Book a Strategy Call
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{isMobile && (
|
||
<button
|
||
type="button"
|
||
aria-label={mobileMenuOpen ? 'Close menu' : 'Open menu'}
|
||
onClick={() => setMobileMenuOpen((open) => !open)}
|
||
style={{
|
||
background: 'rgba(255,255,255,0.06)',
|
||
border: '1px solid rgba(255,255,255,0.12)',
|
||
borderRadius: '8px',
|
||
width: '42px',
|
||
height: '42px',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
color: activeSection === 'products' ? '#1e293b' : '#fff',
|
||
cursor: 'pointer',
|
||
}}
|
||
>
|
||
{mobileMenuOpen ? <X size={20} /> : <Menu size={20} />}
|
||
</button>
|
||
)}
|
||
</div>
|
||
</nav>
|
||
|
||
{isMobile && mobileMenuOpen && (
|
||
<div
|
||
className="mobile-menu-overlay"
|
||
onClick={() => setMobileMenuOpen(false)}
|
||
style={{
|
||
position: 'fixed',
|
||
inset: 0,
|
||
background: 'rgba(2, 7, 16, 0.75)',
|
||
backdropFilter: 'blur(6px)',
|
||
zIndex: 60,
|
||
display: 'flex',
|
||
justifyContent: 'flex-end',
|
||
}}
|
||
>
|
||
<div
|
||
className="mobile-menu-panel"
|
||
onClick={(e) => e.stopPropagation()}
|
||
style={{
|
||
width: 'min(85vw, 320px)',
|
||
height: '100%',
|
||
background: '#0a1628',
|
||
borderLeft: '1px solid rgba(255,255,255,0.08)',
|
||
padding: '1.5rem 1.25rem',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: '0.25rem',
|
||
}}
|
||
>
|
||
{navItems.map((item) => (
|
||
<button
|
||
key={item}
|
||
type="button"
|
||
onClick={() => handleNavClick(item)}
|
||
style={{
|
||
background: getActiveNavItem() === item ? 'rgba(255,170,0,0.12)' : 'transparent',
|
||
border: 'none',
|
||
color: getActiveNavItem() === item ? '#ffaa00' : '#e2e8f0',
|
||
textAlign: 'left',
|
||
padding: '0.85rem 1rem',
|
||
borderRadius: '8px',
|
||
fontSize: '1rem',
|
||
fontWeight: 500,
|
||
cursor: 'pointer',
|
||
}}
|
||
>
|
||
{item}
|
||
</button>
|
||
))}
|
||
<button
|
||
type="button"
|
||
className="btn-talk"
|
||
onClick={() => { setMobileMenuOpen(false); setIsStrategyOpen(true); }}
|
||
style={{ marginTop: '1rem', width: '100%', minWidth: 'unset' }}
|
||
>
|
||
Book a Strategy Call
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
{currentPage === 'contact' ? (
|
||
<ContactSection isMobile={isMobile} onOpenStrategy={() => setIsStrategyOpen(true)} />
|
||
) : currentPage === 'about' ? (
|
||
<AboutUsPage isMobile={isMobile} onOpenStrategy={() => setIsStrategyOpen(true)} onNavigate={handleNavClick} />
|
||
) : currentPage === 'careers' ? (
|
||
<CareersPage isMobile={isMobile} onNavigate={handleNavClick} onOpenStrategy={() => setIsStrategyOpen(true)} />
|
||
) : currentPage === 'blogs' ? (
|
||
<BlogsPage blogs={insights} isMobile={isMobile} onSelectBlog={handleSelectBlog} onNavigate={handleNavClick} />
|
||
) : currentPage === 'blog' ? (
|
||
<BlogDetailPage blog={selectedBlog || insights[0]} allBlogs={insights} isMobile={isMobile} onNavigate={handleNavClick} onSelectBlog={handleSelectBlog} />
|
||
) : (
|
||
<>
|
||
{/* Main Homepage Content */}
|
||
<section id="home" style={{
|
||
padding: isMobile ? '5.5rem 1.25rem 2rem' : '7.5rem 4rem 2.5rem 4rem',
|
||
textAlign: 'center',
|
||
position: 'relative',
|
||
zIndex: 10,
|
||
height: '100vh',
|
||
minHeight: '100vh',
|
||
boxSizing: 'border-box',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
alignItems: 'center',
|
||
justifyContent: 'flex-start',
|
||
overflow: 'hidden'
|
||
}}>
|
||
<div style={{ maxWidth: '1440px', margin: '0 auto', width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', height: '100%' }}>
|
||
|
||
{/* Background Video */}
|
||
<video
|
||
autoPlay
|
||
loop
|
||
muted
|
||
playsInline
|
||
style={{
|
||
position: 'absolute',
|
||
top: 0,
|
||
left: 0,
|
||
width: '100%',
|
||
height: '100%',
|
||
objectFit: 'cover',
|
||
zIndex: -1,
|
||
pointerEvents: 'none'
|
||
}}
|
||
>
|
||
<source src={assetUrl(hero.video)} type="video/mp4" />
|
||
Your browser does not support the video tag.
|
||
</video>
|
||
|
||
|
||
|
||
<Reveal style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '100%' }}>
|
||
{/* Badge */}
|
||
<div style={{
|
||
display: 'inline-flex', alignItems: 'center', gap: '0.5rem',
|
||
backgroundColor: 'rgba(255, 255, 255, 0.05)', border: '1px solid rgba(255, 255, 255, 0.2)',
|
||
borderRadius: '9999px', padding: '0.4rem 1.2rem', marginBottom: '1.2rem',
|
||
backdropFilter: 'blur(10px)',
|
||
boxShadow: '0 4px 16px rgba(0, 0, 0, 0.4)'
|
||
}}>
|
||
<span style={{ color: '#ffffff', fontSize: '0.82rem', fontWeight: 500 }}>
|
||
{(hero.badge || "Chennai & Dubai • Trusted by 100+ Clients").includes('100+ Clients') ? (
|
||
<>
|
||
{(hero.badge || "Chennai & Dubai • Trusted by 100+ Clients").split('100+ Clients')[0]}
|
||
<span style={{ color: '#ffaa00', fontWeight: 700 }}>100+ Clients</span>
|
||
{(hero.badge || "Chennai & Dubai • Trusted by 100+ Clients").split('100+ Clients')[1]}
|
||
</>
|
||
) : (
|
||
hero.badge
|
||
)}
|
||
</span>
|
||
</div>
|
||
|
||
{/* Headline */}
|
||
<h1 style={{
|
||
fontSize: 'clamp(1.8rem, 3.6vw, 3.2rem)', fontWeight: 800, lineHeight: 1.15,
|
||
maxWidth: '1000px', margin: '0 auto 1rem auto', letterSpacing: '-0.02em',
|
||
filter: 'drop-shadow(0 8px 24px rgba(0, 0, 0, 0.8))',
|
||
textShadow: '0 2px 10px rgba(0, 0, 0, 0.5)'
|
||
}}>
|
||
<span style={{ color: '#ffffff', display: 'block', fontSize: 'clamp(1.2rem, 2.5vw, 2.2rem)', marginBottom: '0.3rem', fontWeight: 600 }}>
|
||
{hero.headline || "Engineering Intelligence"}
|
||
</span>
|
||
<span className="gradient-text-gold" style={{ display: 'block', fontSize: 'clamp(2rem, 4vw, 3.4rem)' }}>
|
||
{hero.subheadline || "Delivering Impact"}
|
||
</span>
|
||
</h1>
|
||
|
||
{/* Description */}
|
||
<p style={{
|
||
color: '#cbd5e1',
|
||
fontSize: 'clamp(0.9rem, 1.1vw, 1.05rem)',
|
||
lineHeight: 1.6,
|
||
maxWidth: '760px',
|
||
margin: '0 auto 1.8rem auto',
|
||
fontWeight: 400,
|
||
textAlign: 'center',
|
||
textShadow: '0 2px 8px rgba(0, 0, 0, 0.7)'
|
||
}}>
|
||
{hero.description || "In a world driven by intelligence, data, and automation, organisations need more than technology they need a digital transformation partner that delivers measurable business impact."}
|
||
</p>
|
||
|
||
{/* CTA Buttons */}
|
||
<div style={{
|
||
display: 'flex',
|
||
flexDirection: isMobile ? 'column' : 'row',
|
||
gap: '1rem',
|
||
alignItems: 'center',
|
||
justify: 'center',
|
||
width: isMobile ? '100%' : 'auto',
|
||
marginBottom: '0'
|
||
}}>
|
||
<button
|
||
type="button"
|
||
className="btn-talk"
|
||
onClick={() => scrollToSection('services')}
|
||
style={{
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
justify: 'center',
|
||
gap: '0.5rem',
|
||
padding: '0.8rem 1.75rem',
|
||
borderRadius: '9999px',
|
||
background: 'linear-gradient(135deg, #ffaa00 0%, #ff8800 100%)',
|
||
color: '#000000',
|
||
fontWeight: 700,
|
||
fontSize: '0.95rem',
|
||
border: 'none',
|
||
cursor: 'pointer',
|
||
boxShadow: '0 4px 20px rgba(255, 170, 0, 0.4)',
|
||
transition: 'all 0.3s ease',
|
||
width: isMobile ? '100%' : 'auto',
|
||
minWidth: 'unset'
|
||
}}
|
||
>
|
||
<span>{hero.primaryCta || "Power your next move"}</span>
|
||
<ArrowRight size={18} />
|
||
</button>
|
||
|
||
<button
|
||
type="button"
|
||
onClick={() => setIsStrategyOpen(true)}
|
||
style={{
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
justify: 'center',
|
||
gap: '0.5rem',
|
||
padding: '0.8rem 1.75rem',
|
||
borderRadius: '9999px',
|
||
background: 'rgba(255, 255, 255, 0.06)',
|
||
color: '#ffffff',
|
||
fontWeight: 600,
|
||
fontSize: '0.95rem',
|
||
border: '1px solid rgba(255, 255, 255, 0.3)',
|
||
cursor: 'pointer',
|
||
backdropFilter: 'blur(10px)',
|
||
transition: 'all 0.3s ease',
|
||
width: isMobile ? '100%' : 'auto'
|
||
}}
|
||
>
|
||
<span>{hero.secondaryCta || "Book a Strategy Call"}</span>
|
||
<ArrowRight size={18} />
|
||
</button>
|
||
</div>
|
||
</Reveal>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
{/* Metrics Section */}
|
||
<section style={{
|
||
padding: isMobile ? '3rem 1.25rem' : '4rem 4rem 2rem 4rem',
|
||
backgroundColor: '#020710',
|
||
position: 'relative',
|
||
zIndex: 10,
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
alignItems: 'center'
|
||
}}>
|
||
{/* Statistics Panel */}
|
||
<Reveal style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
|
||
<div style={{
|
||
background: 'rgba(25, 23, 21, 0.75)',
|
||
padding: isMobile ? '1.5rem 1.2rem' : '1.2rem 3rem',
|
||
display: 'flex',
|
||
flexDirection: isMobile ? 'column' : 'row',
|
||
gap: isMobile ? '1.2rem' : '2rem',
|
||
justifyContent: isMobile ? 'center' : 'space-between',
|
||
alignItems: 'center',
|
||
width: '100%',
|
||
maxWidth: '1100px',
|
||
borderRadius: '16px',
|
||
border: '1px solid rgba(255, 255, 255, 0.08)',
|
||
backdropFilter: 'blur(20px)',
|
||
marginTop: '0',
|
||
marginBottom: '0',
|
||
position: 'relative',
|
||
zIndex: 20,
|
||
boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.8)'
|
||
}}>
|
||
{/* Metrics from CMS */}
|
||
{metrics.map((metric, idx) => (
|
||
<React.Fragment key={metric.label}>
|
||
{idx > 0 && !isMobile && <div style={{ width: '1px', height: '30px', backgroundColor: 'rgba(255, 255, 255, 0.15)', flexShrink: 0 }} />}
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem', flex: '1 1 auto', minWidth: isMobile ? 'unset' : '150px', justifyContent: isMobile ? 'center' : 'flex-start' }}>
|
||
<div style={{
|
||
width: '42px', height: '42px', borderRadius: '50%', border: '1.5px solid rgba(255, 170, 0, 0.4)',
|
||
background: 'rgba(255, 170, 0, 0.05)', display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||
flexShrink: 0
|
||
}}>
|
||
{[<Zap key="z" size={18} style={{ color: '#ffaa00', flexShrink: 0 }} />, <Globe key="g" size={18} style={{ color: '#ffaa00', flexShrink: 0 }} />, <Layout key="l" size={18} style={{ color: '#ffaa00', flexShrink: 0 }} />, <Compass key="c" size={18} style={{ color: '#ffaa00', flexShrink: 0 }} />][idx % 4]}
|
||
</div>
|
||
<div style={{ textAlign: 'left' }}>
|
||
<span style={{ display: 'block', fontSize: '1.5rem', fontWeight: 800, color: '#ffffff', lineHeight: 1.1 }}>{metric.value}</span>
|
||
<span style={{ fontSize: '0.8rem', color: '#94a3b8' }}>{metric.label}</span>
|
||
</div>
|
||
</div>
|
||
</React.Fragment>
|
||
))}
|
||
</div>
|
||
</Reveal>
|
||
</section>
|
||
|
||
{/* Frost & Sullivan Alliance Section */}
|
||
<section id="aboutus" style={{
|
||
padding: isMobile ? '3.5rem 1.25rem' : '6.5rem 4rem 5.5rem 4rem',
|
||
backgroundColor: '#020710',
|
||
backgroundImage: `url('${assetUrl(about.backgroundImage)}')`,
|
||
backgroundSize: 'cover',
|
||
backgroundPosition: 'center',
|
||
backgroundRepeat: 'no-repeat',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
alignItems: 'center',
|
||
textAlign: 'center',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.02)',
|
||
position: 'relative'
|
||
}}>
|
||
<div style={{ maxWidth: '1440px', margin: '0 auto', width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
||
<Reveal style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '100%' }}>
|
||
{/* Subtle center spotlight lighting effect behind badge */}
|
||
<div style={{
|
||
position: 'absolute',
|
||
bottom: '15%',
|
||
left: '50%',
|
||
transform: 'translateX(-50%)',
|
||
width: '320px',
|
||
height: '60px',
|
||
background: 'radial-gradient(circle, rgba(255, 170, 0, 0.25) 0%, transparent 80%)',
|
||
pointerEvents: 'none',
|
||
zIndex: 0,
|
||
filter: 'blur(10px)'
|
||
}} />
|
||
|
||
<h2 style={{
|
||
fontSize: 'clamp(1.6rem, 2.8vw, 2.4rem)',
|
||
fontWeight: 600,
|
||
color: '#ffffff',
|
||
marginBottom: '2.5rem',
|
||
letterSpacing: '-0.02em',
|
||
position: 'relative',
|
||
zIndex: 1
|
||
}}>
|
||
{about.heading}
|
||
</h2>
|
||
|
||
{/* Frost & Sullivan Badge container */}
|
||
<div style={{
|
||
position: 'relative',
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
zIndex: 1,
|
||
boxShadow: '0 15px 35px rgba(0, 0, 0, 0.6), 0 0 25px rgba(71, 115, 179, 0.15)',
|
||
borderRadius: '4px',
|
||
overflow: 'hidden'
|
||
}}>
|
||
<img
|
||
src={assetUrl(about.badgeImage)}
|
||
alt={about.badgeAlt}
|
||
style={{
|
||
height: isMobile ? '40px' : '54px',
|
||
display: 'block',
|
||
maxWidth: '100%',
|
||
objectFit: 'contain'
|
||
}}
|
||
/>
|
||
</div>
|
||
</Reveal>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
{/* Redesigned Trusted Brands Section */}
|
||
<section style={{
|
||
padding: isMobile ? '4rem 1.25rem' : '4rem 4rem',
|
||
borderTop: '1px solid rgba(255, 255, 255, 0.03)',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.03)',
|
||
background: '#020710',
|
||
position: 'relative',
|
||
overflow: 'hidden',
|
||
}}>
|
||
{/* Subtle grid background */}
|
||
<div style={{
|
||
position: 'absolute',
|
||
top: 0,
|
||
left: 0,
|
||
right: 0,
|
||
bottom: 0,
|
||
backgroundImage: 'linear-gradient(rgba(255, 170, 0, 0.02) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 170, 0, 0.02) 1px, transparent 1px)',
|
||
backgroundSize: '50px 50px',
|
||
opacity: 0.4,
|
||
pointerEvents: 'none',
|
||
}} />
|
||
|
||
{/* Ambient Glows */}
|
||
<div style={{
|
||
position: 'absolute',
|
||
top: '50%',
|
||
left: '50%',
|
||
transform: 'translate(-50%, -50%)',
|
||
width: '500px',
|
||
height: '500px',
|
||
background: 'radial-gradient(circle, rgba(0, 119, 255, 0.05) 0%, transparent 70%)',
|
||
pointerEvents: 'none',
|
||
zIndex: 0,
|
||
}} />
|
||
|
||
<div style={{ maxWidth: '1440px', margin: '0 auto', width: '100%', position: 'relative', zIndex: 2 }}>
|
||
<Reveal style={{ width: '100%' }}>
|
||
{isMobile ? (
|
||
/* Mobile Layout: Clean vertical hierarchy */
|
||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '3rem', position: 'relative', zIndex: 2 }}>
|
||
<div style={{ textAlign: 'center' }}>
|
||
<h3 style={{ fontSize: '2rem', fontWeight: 800, marginBottom: '0.8rem', color: '#ffffff', letterSpacing: '-0.02em' }}>
|
||
{partners.heading}
|
||
</h3>
|
||
<h4 style={{ fontSize: '1.4rem', fontWeight: 700, color: '#a0aec0', marginBottom: '1rem' }}>
|
||
{partners.subheading}
|
||
</h4>
|
||
<p style={{ color: '#94a3b8', fontSize: '0.9rem', lineHeight: 1.5, maxWidth: '400px', margin: '0 auto' }}>
|
||
{partners.body}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Globe Visual */}
|
||
<div style={{ position: 'relative', width: '280px', height: '280px', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||
<img
|
||
src={assetUrl('/assets/GlobeVector.svg')}
|
||
alt="Globe Map"
|
||
style={{ width: '100%', height: '100%', objectFit: 'contain', opacity: 0.3 }}
|
||
/>
|
||
</div>
|
||
|
||
{/* Grid of Logos */}
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: 'repeat(3, 1fr)',
|
||
gap: '1.5rem 1rem',
|
||
width: '100%',
|
||
alignItems: 'center',
|
||
justifyItems: 'center',
|
||
}}>
|
||
{partners.logos.map((logo, idx) => (
|
||
<div key={idx} style={{
|
||
display: 'flex',
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
height: '50px',
|
||
width: '100%',
|
||
padding: '0.2rem',
|
||
}}>
|
||
<img
|
||
src={assetUrl(logo.image)}
|
||
alt={logo.name}
|
||
style={{ maxHeight: '100%', maxWidth: '100%', objectFit: 'contain' }}
|
||
/>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
) : (
|
||
/* Desktop Layout: Orbital Globe Layout as per reference image */
|
||
<div style={{
|
||
position: 'relative',
|
||
width: '1100px',
|
||
height: '800px',
|
||
margin: '0 auto',
|
||
zIndex: 2,
|
||
}}>
|
||
|
||
{/* Globe in background - Increased Size & Brightness */}
|
||
<img
|
||
src={assetUrl('/assets/GlobeVector.svg')}
|
||
alt="Globe Map"
|
||
style={{
|
||
position: 'absolute',
|
||
width: '800px',
|
||
height: '800px',
|
||
top: '58%',
|
||
left: '50%',
|
||
transform: 'translate(-50%, -50%)',
|
||
objectFit: 'contain',
|
||
opacity: 0.55,
|
||
zIndex: 1,
|
||
pointerEvents: 'none',
|
||
}}
|
||
/>
|
||
|
||
{/* Center Text Panel */}
|
||
<div style={{
|
||
position: 'absolute',
|
||
top: '50%',
|
||
left: '50%',
|
||
transform: 'translate(-50%, -50%)',
|
||
zIndex: 5,
|
||
textAlign: 'center',
|
||
width: '420px',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
}}>
|
||
<h3 style={{
|
||
fontSize: '2.2rem',
|
||
fontWeight: 800,
|
||
color: '#ffffff',
|
||
margin: '0 0 0.4rem 0',
|
||
letterSpacing: '-0.02em',
|
||
lineHeight: '1.2',
|
||
}}>
|
||
{partners.heading}
|
||
</h3>
|
||
<span style={{
|
||
fontSize: '1.8rem',
|
||
fontWeight: 700,
|
||
color: '#cbd5e1',
|
||
margin: '0 0 1rem 0',
|
||
letterSpacing: '-0.02em',
|
||
}}>
|
||
{partners.subheading}
|
||
</span>
|
||
<p style={{
|
||
color: '#94a3b8',
|
||
fontSize: '0.9rem',
|
||
lineHeight: '1.6',
|
||
margin: 0,
|
||
fontWeight: 500,
|
||
maxWidth: '340px',
|
||
}}>
|
||
{partners.body}
|
||
</p>
|
||
</div>
|
||
|
||
{/* orbital logos with smooth continuous motion in horizontally elongated oval paths - No Skewing */}
|
||
{/* Outer Orbit - Increased size further to radiusX=520, radiusY=320 */}
|
||
<OrbitalLogo src={assetUrl('/assets/Frame 33.svg')} alt="MRF Logo" radiusX={520} radiusY={320} startAngle={0} duration={60} clockwise={true} size={170} />
|
||
<OrbitalLogo src={assetUrl('/assets/Frame 31.svg')} alt="ACA Global Logo" radiusX={520} radiusY={320} startAngle={78} duration={60} clockwise={true} size={175} />
|
||
<OrbitalLogo src={assetUrl('/assets/Frame 30.svg')} alt="Polyhose Logo" radiusX={520} radiusY={320} startAngle={144} duration={60} clockwise={true} size={170} />
|
||
<OrbitalLogo src={assetUrl('/assets/Frame 32.svg')} alt="Dawn Pictures Logo" radiusX={520} radiusY={320} startAngle={216} duration={60} clockwise={true} size={180} />
|
||
<OrbitalLogo src={assetUrl('/assets/Frame 35.svg')} alt="Hero Logo" radiusX={520} radiusY={320} startAngle={282} duration={60} clockwise={true} size={170} />
|
||
|
||
{/* Inner Orbit - Adjusted size to radiusX=360, radiusY=225 */}
|
||
<OrbitalLogo src={assetUrl('/assets/Frame 28.svg')} alt="Valeo Logo" radiusX={360} radiusY={225} startAngle={36} duration={40} clockwise={false} size={170} />
|
||
<OrbitalLogo src={assetUrl('/assets/Frame 36.svg')} alt="BorgWarner Logo" radiusX={360} radiusY={225} startAngle={108} duration={40} clockwise={false} size={170} />
|
||
<OrbitalLogo src={assetUrl('/assets/kone.png')} alt="KONE Logo" radiusX={360} radiusY={225} startAngle={180} duration={40} clockwise={false} size={160} />
|
||
<OrbitalLogo src={assetUrl('/assets/Frame 34.svg')} alt="Chola MS Logo" radiusX={360} radiusY={225} startAngle={252} duration={40} clockwise={false} size={170} />
|
||
<OrbitalLogo src={assetUrl('/assets/Frame 27.svg')} alt="CavinKare Logo" radiusX={360} radiusY={225} startAngle={324} duration={40} clockwise={false} size={180} />
|
||
|
||
</div>
|
||
)}
|
||
</Reveal>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
{/* Certifications Section */}
|
||
<section id="certifications" style={{
|
||
padding: isMobile ? '3rem 1.25rem' : '5rem 4rem',
|
||
backgroundColor: '#020710',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
alignItems: 'center',
|
||
textAlign: 'center',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.03)'
|
||
}}>
|
||
<div style={{ maxWidth: '1440px', margin: '0 auto', width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
||
<Reveal>
|
||
<h2 style={{
|
||
fontSize: 'clamp(1.8rem, 3.2vw, 2.5rem)',
|
||
fontWeight: 600,
|
||
color: '#e2e8f0',
|
||
marginBottom: '3.5rem',
|
||
letterSpacing: '-0.02em',
|
||
opacity: 0.9
|
||
}}>
|
||
{certifications.heading}
|
||
</h2>
|
||
</Reveal>
|
||
|
||
<div style={{
|
||
display: 'flex',
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
gap: isMobile ? '1.5rem' : '5rem',
|
||
flexWrap: 'wrap'
|
||
}}>
|
||
{certifications.items.map((cert, idx) => (
|
||
<Reveal key={cert.alt || idx} delay={idx * 0.1}>
|
||
<div style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
height: '110px',
|
||
padding: '0 0.5rem',
|
||
transition: 'all 0.3s ease'
|
||
}}>
|
||
<img
|
||
src={assetUrl(cert.image)}
|
||
alt={cert.alt}
|
||
style={{
|
||
height: '100%',
|
||
maxHeight: '105px',
|
||
width: 'auto',
|
||
maxWidth: '260px',
|
||
objectFit: 'contain'
|
||
}}
|
||
/>
|
||
</div>
|
||
</Reveal>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
{/* Services Section */}
|
||
<section id="services" style={{
|
||
padding: isMobile ? '4rem 0' : '96px 0',
|
||
backgroundColor: '#070d18',
|
||
position: 'relative',
|
||
overflow: 'hidden',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.04)',
|
||
scrollMarginTop: `${NAV_OFFSET}px`
|
||
}}>
|
||
{/* Background Ambient Glow matching screenshot */}
|
||
<div style={{
|
||
position: 'absolute',
|
||
top: '0%',
|
||
right: '0%',
|
||
width: '700px',
|
||
height: '700px',
|
||
background: 'radial-gradient(circle at 80% 20%, rgba(30, 85, 145, 0.22) 0%, transparent 60%)',
|
||
pointerEvents: 'none',
|
||
zIndex: 0
|
||
}} />
|
||
|
||
<div style={{
|
||
maxWidth: '1440px',
|
||
margin: '0 auto',
|
||
padding: isMobile ? '0 1.25rem' : '0 4rem',
|
||
display: 'flex',
|
||
flexDirection: isMobile ? 'column' : 'row',
|
||
alignItems: 'stretch',
|
||
gap: isMobile ? '2.5rem' : '40px',
|
||
position: 'relative',
|
||
zIndex: 1
|
||
}}>
|
||
{/* Left Column - Intro Panel */}
|
||
<Reveal style={{
|
||
flex: isMobile ? '1' : '0 0 260px',
|
||
width: isMobile ? '100%' : '260px',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
justifyContent: 'space-between',
|
||
position: 'relative'
|
||
}}>
|
||
<div>
|
||
<h2 style={{
|
||
color: '#ffffff',
|
||
fontSize: isMobile ? '2.2rem' : '2.9rem',
|
||
fontWeight: 400,
|
||
letterSpacing: '-0.02em',
|
||
margin: '0 0 1rem 0',
|
||
lineHeight: '1.1'
|
||
}}>
|
||
Our Services
|
||
</h2>
|
||
<span style={{
|
||
color: '#8c9ba5',
|
||
fontSize: '0.78rem',
|
||
fontWeight: 500,
|
||
textTransform: 'uppercase',
|
||
letterSpacing: '0.06em',
|
||
display: 'block',
|
||
marginBottom: '2rem',
|
||
lineHeight: '1.4'
|
||
}}>
|
||
TECHNOLOGY THAT MOVES YOUR BUSINESS FORWARD.
|
||
</span>
|
||
<p style={{
|
||
color: '#8c9ba5',
|
||
fontSize: isMobile ? '0.88rem' : '0.92rem',
|
||
lineHeight: '1.65',
|
||
margin: '0 0 2rem 0',
|
||
fontWeight: 400
|
||
}}>
|
||
From market leaders to high-growth innovators enterprises trust Cavin Infotech to deliver secure, scalable, and future-ready digital solutions that create measurable business value.
|
||
</p>
|
||
</div>
|
||
|
||
{/* Navigation buttons at the bottom matching screenshot */}
|
||
<div style={{
|
||
display: 'flex',
|
||
gap: '10px',
|
||
marginTop: isMobile ? '1.5rem' : 'auto',
|
||
justifyContent: 'flex-start'
|
||
}}>
|
||
{/* Left Button */}
|
||
<button
|
||
onClick={() => scrollServices('left')}
|
||
style={{
|
||
width: '42px',
|
||
height: '42px',
|
||
borderRadius: '4px',
|
||
background: 'rgba(255, 255, 255, 0.03)',
|
||
border: '1px solid rgba(255, 255, 255, 0.2)',
|
||
color: '#ffffff',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
cursor: 'pointer',
|
||
padding: 0,
|
||
transition: 'all 0.2s'
|
||
}}
|
||
onMouseEnter={(e) => {
|
||
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.1)';
|
||
}}
|
||
onMouseLeave={(e) => {
|
||
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.03)';
|
||
}}
|
||
aria-label="Scroll left"
|
||
>
|
||
<ChevronLeft size={18} strokeWidth={2.5} />
|
||
</button>
|
||
|
||
{/* Right Button */}
|
||
<button
|
||
onClick={() => scrollServices('right')}
|
||
style={{
|
||
width: '42px',
|
||
height: '42px',
|
||
borderRadius: '4px',
|
||
background: '#ffffff',
|
||
border: '1px solid #ffffff',
|
||
color: '#070d18',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
cursor: 'pointer',
|
||
padding: 0,
|
||
transition: 'all 0.2s'
|
||
}}
|
||
onMouseEnter={(e) => {
|
||
e.currentTarget.style.opacity = '0.9';
|
||
}}
|
||
onMouseLeave={(e) => {
|
||
e.currentTarget.style.opacity = '1';
|
||
}}
|
||
aria-label="Scroll right"
|
||
>
|
||
<ChevronRight size={18} strokeWidth={2.5} />
|
||
</button>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Right Column - Horizontal scroll container */}
|
||
<div style={{
|
||
flexGrow: 1,
|
||
overflow: 'visible',
|
||
width: isMobile ? '100%' : 'calc(100% - 364px)'
|
||
}}>
|
||
<Reveal style={{ width: '100%' }}>
|
||
<div
|
||
ref={servicesScrollRef}
|
||
className="services-carousel"
|
||
style={{
|
||
display: 'flex',
|
||
gap: isMobile ? '1rem' : '24px',
|
||
overflowX: 'auto',
|
||
overflowY: 'hidden',
|
||
scrollSnapType: 'x mandatory',
|
||
paddingBottom: '2rem',
|
||
paddingTop: '0.5rem',
|
||
scrollbarWidth: 'none',
|
||
msOverflowStyle: 'none',
|
||
boxSizing: 'border-box'
|
||
}}
|
||
>
|
||
{services.map((service, index) => (
|
||
<ServiceCard
|
||
key={service.id}
|
||
service={service}
|
||
isMobile={isMobile}
|
||
index={index}
|
||
/>
|
||
))}
|
||
</div>
|
||
</Reveal>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Why Cavin Infotech Section */}
|
||
{/* Why Cavin Infotech Section */}
|
||
<section id="whyus" style={{ padding: isMobile ? '4rem 1.25rem' : '6rem 4rem', background: 'rgba(5, 16, 34, 0.3)', position: 'relative' }}>
|
||
<div style={{ maxWidth: '1440px', margin: '0 auto', position: 'relative', zIndex: 10 }}>
|
||
{/* Section Header - Left Aligned */}
|
||
<div style={{ textAlign: 'left', marginBottom: '3rem' }}>
|
||
<Reveal>
|
||
<h2 style={{ fontSize: 'clamp(2.2rem, 3.2vw, 2.8rem)', fontWeight: 400, marginTop: 0, color: '#ffffff', marginBottom: '0.4rem', letterSpacing: '-0.02em' }}>
|
||
Why Organizations choose us
|
||
</h2>
|
||
<span style={{ color: '#8c9ba5', fontSize: '0.78rem', fontWeight: 500, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
|
||
BUILT ON ENTERPRISE EXPERIENCE, DRIVEN BY EXECUTION.
|
||
</span>
|
||
</Reveal>
|
||
</div>
|
||
|
||
{isMobile ? (
|
||
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.25rem', position: 'relative', zIndex: 10 }}>
|
||
{/* The Expertise Edge */}
|
||
<Reveal delay={0}>
|
||
<div className="glass-card" style={{
|
||
padding: '2rem 1.8rem',
|
||
borderRadius: '16px',
|
||
background: 'linear-gradient(135deg, rgba(80, 105, 145, 0.4) 0%, rgba(9, 14, 24, 0.98) 100%)',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
position: 'relative',
|
||
overflow: 'hidden'
|
||
}}>
|
||
<h3 style={{ fontSize: '1.6rem', fontWeight: 500, color: '#ffffff', margin: 0 }}>The Expertise Edge</h3>
|
||
<div style={{ width: '100%', height: '1px', backgroundColor: 'rgba(255, 255, 255, 0.12)', margin: '1.2rem 0' }} />
|
||
<p style={{ color: '#8c9ba5', fontSize: '0.9rem', lineHeight: '1.6', margin: 0 }}>
|
||
Deep manufacturing domain expertise + certified SAP mastery + production-grade AI engineering. We don't just consult - we've lived your challenges.
|
||
</p>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Speed That Sets Us Apart */}
|
||
<Reveal delay={0.1}>
|
||
<div className="glass-card" style={{
|
||
padding: '2rem 1.8rem',
|
||
borderRadius: '16px',
|
||
background: 'radial-gradient(ellipse at 25% 30%, rgba(210, 135, 25, 0.2) 0%, rgba(9, 14, 24, 0.98) 70%)',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
position: 'relative',
|
||
overflow: 'hidden'
|
||
}}>
|
||
<h3 style={{ fontSize: '1.6rem', fontWeight: 500, color: '#ffffff', margin: 0 }}>Speed That Sets Us Apart</h3>
|
||
<div style={{ width: '100%', height: '1px', backgroundColor: 'rgba(255, 255, 255, 0.12)', margin: '1.2rem 0' }} />
|
||
<p style={{ color: '#8c9ba5', fontSize: '0.9rem', lineHeight: '1.6', margin: 0 }}>
|
||
In just five years, we've delivered what takes most companies decades - with clean architecture, zero bureaucracy, and exceptional quality.
|
||
</p>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Proven Platforms, Real Impact */}
|
||
<Reveal delay={0.2}>
|
||
<div className="glass-card" style={{
|
||
padding: '2rem 1.8rem',
|
||
borderRadius: '16px',
|
||
background: 'radial-gradient(ellipse at 25% 30%, rgba(210, 135, 25, 0.2) 0%, rgba(9, 14, 24, 0.98) 70%)',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
position: 'relative',
|
||
overflow: 'hidden'
|
||
}}>
|
||
<h3 style={{ fontSize: '1.6rem', fontWeight: 500, color: '#ffffff', margin: 0 }}>Proven Platforms, Real Impact</h3>
|
||
<div style={{ width: '100%', height: '1px', backgroundColor: 'rgba(255, 255, 255, 0.12)', margin: '1.2rem 0' }} />
|
||
<p style={{ color: '#8c9ba5', fontSize: '0.9rem', lineHeight: '1.6', margin: '0 0 1rem 0' }}>
|
||
PRODMAX and Nebula AI Platform are not pilots - they're delivering measurable gains in factories right now.
|
||
</p>
|
||
<ul style={{ listStyle: 'none', padding: 0, margin: 0, color: '#8c9ba5', fontSize: '0.86rem', lineHeight: '1.6' }}>
|
||
<li>• Up to 30% reduction in operational overheads</li>
|
||
<li>• Real-time visibility across 100+ connected machines</li>
|
||
<li>• End-to-end traceability from raw materials to dispatch</li>
|
||
</ul>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Results We Stand By */}
|
||
<Reveal delay={0.3}>
|
||
<div className="glass-card" style={{
|
||
borderRadius: '16px',
|
||
background: `linear-gradient(to bottom, rgba(9, 14, 24, 0.98) 0%, rgba(9, 14, 24, 0.92) 50%, rgba(9, 14, 24, 0.3) 70%), url(${assetUrl('/assets/whyus_teamwork_user.jpg')})`,
|
||
backgroundSize: 'cover',
|
||
backgroundPosition: 'center',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
padding: '2rem 1.8rem',
|
||
minHeight: '380px'
|
||
}}>
|
||
<h3 style={{ fontSize: '1.6rem', fontWeight: 500, color: '#ffffff', margin: 0 }}>Results We Stand By</h3>
|
||
<div style={{ width: '100%', height: '1px', backgroundColor: 'rgba(255, 255, 255, 0.12)', margin: '1.2rem 0' }} />
|
||
<p style={{ color: '#8c9ba5', fontSize: '0.9rem', lineHeight: '1.6', margin: 0 }}>
|
||
We track what matters: productivity, cost savings, OEE, ROI, and business impact. Transformation only counts when it shows in your numbers.
|
||
</p>
|
||
</div>
|
||
</Reveal>
|
||
</div>
|
||
) : (
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: '1.2fr 1.6fr 2.2fr 1.2fr 2.4fr',
|
||
gridTemplateRows: 'auto auto',
|
||
gap: '1.25rem',
|
||
alignItems: 'stretch',
|
||
position: 'relative',
|
||
zIndex: 10
|
||
}}>
|
||
{/* The Expertise Edge (Col 1 to 3, Row 1) */}
|
||
<Reveal delay={0} style={{ height: '100%', gridColumn: '1 / 3', gridRow: '1' }}>
|
||
<div className="glass-card" style={{
|
||
padding: '2.2rem',
|
||
borderRadius: '16px',
|
||
background: 'linear-gradient(135deg, rgba(80, 105, 145, 0.45) 0%, rgba(30, 45, 70, 0.7) 40%, rgba(9, 14, 24, 0.98) 100%)',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
position: 'relative',
|
||
overflow: 'hidden',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
justifyContent: 'flex-start',
|
||
height: '100%',
|
||
boxSizing: 'border-box'
|
||
}}>
|
||
{/* Arc overlay */}
|
||
<div style={{ position: 'absolute', top: '-20%', right: '-20%', width: '220px', height: '220px', borderRadius: '50%', border: '1px solid rgba(255, 255, 255, 0.08)', pointerEvents: 'none' }} />
|
||
<div style={{ position: 'absolute', top: '-35%', right: '-35%', width: '300px', height: '300px', borderRadius: '50%', border: '1px solid rgba(255, 255, 255, 0.05)', pointerEvents: 'none' }} />
|
||
|
||
<h3 style={{ fontSize: '1.8rem', fontWeight: 500, color: '#ffffff', lineHeight: '1.2', margin: '0 0 2.5rem 0', maxWidth: '200px' }}>
|
||
The Expertise Edge
|
||
</h3>
|
||
<div style={{ width: '100%', height: '1px', backgroundColor: 'rgba(255, 255, 255, 0.15)', margin: '0 0 1.5rem 0' }} />
|
||
<p style={{ color: '#8c9ba5', fontSize: '0.88rem', lineHeight: '1.6', margin: 0, fontWeight: 400 }}>
|
||
Deep manufacturing domain expertise + certified SAP mastery + production-grade AI engineering. We don't just consult - we've lived your challenges.
|
||
</p>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Speed That Sets Us Apart (Col 3 to 5, Row 1) */}
|
||
<Reveal delay={0.1} style={{ height: '100%', gridColumn: '3 / 5', gridRow: '1' }}>
|
||
<div className="glass-card" style={{
|
||
padding: '2.2rem',
|
||
borderRadius: '16px',
|
||
background: 'radial-gradient(ellipse at 25% 30%, rgba(210, 135, 25, 0.22) 0%, rgba(9, 14, 24, 0.98) 70%)',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
position: 'relative',
|
||
overflow: 'hidden',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
justifyContent: 'flex-start',
|
||
height: '100%',
|
||
boxSizing: 'border-box'
|
||
}}>
|
||
<div style={{ position: 'absolute', top: '-20%', right: '-20%', width: '220px', height: '220px', borderRadius: '50%', border: '1px solid rgba(255, 255, 255, 0.05)', pointerEvents: 'none' }} />
|
||
|
||
<h3 style={{ fontSize: '1.8rem', fontWeight: 500, color: '#ffffff', lineHeight: '1.25', margin: '0 0 2.5rem 0', maxWidth: '240px' }}>
|
||
Speed That Sets Us Apart
|
||
</h3>
|
||
<div style={{ width: '100%', height: '1px', backgroundColor: 'rgba(255, 255, 255, 0.15)', margin: '0 0 1.5rem 0' }} />
|
||
<p style={{ color: '#8c9ba5', fontSize: '0.88rem', lineHeight: '1.6', margin: 0, fontWeight: 400, maxWidth: '95%' }}>
|
||
In just five years, we've delivered what takes most companies decades - with clean architecture, zero bureaucracy, and exceptional quality.
|
||
</p>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Results We Stand By Tall Card (Col 5, Row 1 & 2) */}
|
||
<Reveal delay={0.2} style={{ height: '100%', gridColumn: '5', gridRow: '1 / 3' }}>
|
||
<div className="glass-card" style={{
|
||
borderRadius: '16px',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
position: 'relative',
|
||
overflow: 'hidden',
|
||
backgroundImage: `linear-gradient(to bottom, rgba(9, 14, 24, 0.98) 0%, rgba(9, 14, 24, 0.92) 42%, rgba(9, 14, 24, 0.2) 58%, transparent 75%), url(${assetUrl('/assets/whyus_teamwork_user.jpg')})`,
|
||
backgroundSize: 'cover',
|
||
backgroundPosition: 'bottom center',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
justifyContent: 'flex-start',
|
||
padding: '2.2rem',
|
||
height: '100%',
|
||
boxSizing: 'border-box'
|
||
}}>
|
||
<div>
|
||
<h3 style={{ fontSize: '1.8rem', fontWeight: 500, color: '#ffffff', lineHeight: '1.2', margin: '0 0 1.5rem 0' }}>
|
||
Results We Stand By
|
||
</h3>
|
||
<p style={{ color: '#8c9ba5', fontSize: '0.88rem', lineHeight: '1.6', margin: 0, fontWeight: 400 }}>
|
||
We track what matters: productivity, cost savings, OEE, ROI, and business impact. Transformation only counts when it shows in your numbers.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Image Card 1 (Col 1, Row 2) */}
|
||
<Reveal delay={0.3} style={{ height: '100%', gridColumn: '1', gridRow: '2' }}>
|
||
<div style={{
|
||
borderRadius: '16px',
|
||
overflow: 'hidden',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
height: '100%',
|
||
minHeight: '260px'
|
||
}}>
|
||
<img
|
||
src={assetUrl('/assets/Indian Financial Advisers Stock Market Strategy.jpg')}
|
||
alt="Financial Advisers & Strategy"
|
||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||
/>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Proven Platforms, Real Impact (Col 2 to 4, Row 2) */}
|
||
<Reveal delay={0.4} style={{ height: '100%', gridColumn: '2 / 4', gridRow: '2' }}>
|
||
<div className="glass-card" style={{
|
||
padding: '2.2rem',
|
||
borderRadius: '16px',
|
||
background: 'radial-gradient(ellipse at 25% 25%, rgba(210, 135, 25, 0.2) 0%, rgba(9, 14, 24, 0.98) 70%)',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
position: 'relative',
|
||
overflow: 'hidden',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
justifyContent: 'flex-start',
|
||
height: '100%',
|
||
boxSizing: 'border-box'
|
||
}}>
|
||
<div style={{ position: 'absolute', top: '-20%', right: '-20%', width: '220px', height: '220px', borderRadius: '50%', border: '1px solid rgba(255, 255, 255, 0.05)', pointerEvents: 'none' }} />
|
||
|
||
<h3 style={{ fontSize: '1.7rem', fontWeight: 500, color: '#ffffff', lineHeight: '1.25', margin: '0 0 1.2rem 0', maxWidth: '240px' }}>
|
||
Proven Platforms, Real Impact
|
||
</h3>
|
||
<p style={{ color: '#8c9ba5', fontSize: '0.86rem', lineHeight: '1.55', margin: '0 0 1.2rem 0', fontWeight: 400 }}>
|
||
PRODMAX and Nebula AI Platform are not pilots - they're delivering measurable gains in factories right now.
|
||
</p>
|
||
<ul style={{ listStyle: 'none', padding: 0, margin: 0, color: '#8c9ba5', fontSize: '0.84rem', lineHeight: '1.6', display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
|
||
<li>• Up to 30% reduction in operational overheads</li>
|
||
<li>• Real-time visibility across 100+ connected machines</li>
|
||
<li>• End-to-end traceability from raw materials to dispatch</li>
|
||
</ul>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Image Card 2 (Col 4, Row 2) */}
|
||
<Reveal delay={0.5} style={{ height: '100%', gridColumn: '4', gridRow: '2' }}>
|
||
<div style={{
|
||
borderRadius: '16px',
|
||
overflow: 'hidden',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
height: '100%',
|
||
minHeight: '260px'
|
||
}}>
|
||
<img
|
||
src={assetUrl('/assets/side-view-people-working-together.jpg')}
|
||
alt="People working together"
|
||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||
/>
|
||
</div>
|
||
</Reveal>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</section>
|
||
|
||
{/* Featured Gallery Section */}
|
||
<Reveal>
|
||
<FeaturedGallery gallery={content.gallery} />
|
||
</Reveal>
|
||
|
||
{/* Products Suite */}
|
||
<section id="products" style={{
|
||
padding: isMobile ? '4rem 1.25rem' : '6rem 4rem',
|
||
background: 'linear-gradient(180deg, #2791a5 0%, #0f4652 35%, #020710 100%)',
|
||
position: 'relative',
|
||
overflow: 'hidden',
|
||
scrollMarginTop: `${NAV_OFFSET}px`
|
||
}}>
|
||
{/* Wave Pattern Overlay */}
|
||
<img
|
||
src={assetUrl('/assets/Wave Pattern 2.svg')}
|
||
alt=""
|
||
aria-hidden="true"
|
||
style={{
|
||
position: 'absolute',
|
||
top: '-50%',
|
||
left: 0,
|
||
width: '100%',
|
||
height: '180%',
|
||
objectFit: 'cover',
|
||
objectPosition: 'center top',
|
||
opacity: 0.42,
|
||
pointerEvents: 'none',
|
||
zIndex: 1
|
||
}}
|
||
/>
|
||
<div style={{ maxWidth: '1440px', margin: '0 auto', width: '100%', position: 'relative', zIndex: 10 }}>
|
||
{/* Header - Left Aligned matching screenshot */}
|
||
<Reveal>
|
||
<div style={{ textAlign: 'left', marginBottom: '3.5rem', position: 'relative', zIndex: 10 }}>
|
||
<h2 style={{ fontSize: 'clamp(2.2rem, 3.2vw, 2.8rem)', fontWeight: 500, color: '#ffffff', margin: '0 0 0.4rem 0', letterSpacing: '-0.02em' }}>
|
||
{products.title || 'Our Products Suite'}
|
||
</h2>
|
||
<span style={{ color: '#8c9ba5', fontSize: '0.78rem', fontWeight: 500, textTransform: 'uppercase', letterSpacing: '0.08em', display: 'block' }}>
|
||
{products.eyebrow || 'ONE ECOSYSTEM. EXPONENTIAL IMPACT.'}
|
||
</span>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Product Cards Grid */}
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: isMobile ? '1fr' : 'repeat(auto-fit, minmax(320px, 1fr))',
|
||
gap: isMobile ? '1.5rem' : '2.5rem',
|
||
alignItems: 'stretch',
|
||
position: 'relative',
|
||
zIndex: 10,
|
||
marginBottom: '2.5rem'
|
||
}}>
|
||
{products.items.map((item, index) => (
|
||
<ProductCard
|
||
key={item.name || index}
|
||
product={item}
|
||
isMobile={isMobile}
|
||
delay={index * 0.1}
|
||
index={index}
|
||
/>
|
||
))}
|
||
</div>
|
||
|
||
{/* Sub-text below product cards */}
|
||
<p style={{
|
||
color: '#8c9ba5',
|
||
fontSize: '0.88rem',
|
||
textAlign: 'center',
|
||
maxWidth: '850px',
|
||
margin: '0 auto 1.8rem auto',
|
||
lineHeight: '1.5',
|
||
fontWeight: 400
|
||
}}>
|
||
Plus many more specialized solutions: LiveWire, Nucleus, Digital Meeting Agenda, SEC, XR Workbench, TMS, and others - purpose-built for manufacturing and enterprise excellence.
|
||
</p>
|
||
|
||
|
||
</div>
|
||
</section>
|
||
|
||
{/* Insights Section */}
|
||
<section id="insights" style={{ padding: isMobile ? '3.5rem 0 4rem' : '5rem 0 6rem 0', background: '#020c1e' }}>
|
||
<div style={{ maxWidth: '1440px', margin: '0 auto', width: '100%' }}>
|
||
{/* Header */}
|
||
<Reveal style={{
|
||
padding: isMobile ? '0 1.25rem' : '0 4rem',
|
||
display: 'flex',
|
||
flexDirection: isMobile ? 'column' : 'row',
|
||
justifyContent: 'space-between',
|
||
alignItems: isMobile ? 'stretch' : 'flex-start',
|
||
gap: isMobile ? '1.25rem' : '0',
|
||
marginBottom: isMobile ? '2rem' : '3rem',
|
||
}}>
|
||
<div style={{ maxWidth: '680px' }}>
|
||
<h2 style={{ fontSize: 'clamp(1.8rem, 3vw, 2.6rem)', fontWeight: 700, color: '#ffffff', lineHeight: 1.25, marginBottom: '1rem', letterSpacing: '-0.02em' }}>
|
||
{content.insights.title}
|
||
</h2>
|
||
<p style={{ color: '#64748b', fontSize: '0.82rem', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.06em', lineHeight: 1.6, maxWidth: '540px' }}>
|
||
{content.insights.subtitle}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Nav Arrows & View All Blogs */}
|
||
<div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center', flexShrink: 0, marginTop: '0.5rem', flexWrap: 'wrap' }}>
|
||
<button
|
||
onClick={() => handleNavClick('Blogs')}
|
||
style={{
|
||
padding: '0.55rem 1.25rem',
|
||
borderRadius: '50px',
|
||
background: 'rgba(56,189,248,0.12)',
|
||
border: '1px solid rgba(56,189,248,0.3)',
|
||
color: '#38bdf8',
|
||
fontWeight: 600,
|
||
fontSize: '0.85rem',
|
||
cursor: 'pointer',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '0.4rem',
|
||
transition: 'all 0.2s ease',
|
||
}}
|
||
onMouseEnter={e => { e.currentTarget.style.background = '#38bdf8'; e.currentTarget.style.color = '#000'; }}
|
||
onMouseLeave={e => { e.currentTarget.style.background = 'rgba(56,189,248,0.12)'; e.currentTarget.style.color = '#38bdf8'; }}
|
||
>
|
||
View All Blogs <ArrowRight size={14} />
|
||
</button>
|
||
<button
|
||
onClick={() => scrollBlogCarousel(-1)}
|
||
style={{
|
||
width: '42px', height: '42px', borderRadius: '8px',
|
||
background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.12)',
|
||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||
cursor: 'pointer', color: '#ffffff', transition: 'all 0.2s ease'
|
||
}}
|
||
onMouseEnter={e => { e.currentTarget.style.background = 'rgba(255,170,0,0.15)'; e.currentTarget.style.borderColor = '#ffaa00'; }}
|
||
onMouseLeave={e => { e.currentTarget.style.background = 'rgba(255,255,255,0.06)'; e.currentTarget.style.borderColor = 'rgba(255,255,255,0.12)'; }}
|
||
>
|
||
<ArrowRight size={16} style={{ transform: 'rotate(180deg)' }} />
|
||
</button>
|
||
<button
|
||
onClick={() => scrollBlogCarousel(1)}
|
||
style={{
|
||
width: '42px', height: '42px', borderRadius: '8px',
|
||
background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.12)',
|
||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||
cursor: 'pointer', color: '#ffffff', transition: 'all 0.2s ease'
|
||
}}
|
||
onMouseEnter={e => { e.currentTarget.style.background = 'rgba(255,170,0,0.15)'; e.currentTarget.style.borderColor = '#ffaa00'; }}
|
||
onMouseLeave={e => { e.currentTarget.style.background = 'rgba(255,255,255,0.06)'; e.currentTarget.style.borderColor = 'rgba(255,255,255,0.12)'; }}
|
||
>
|
||
<ArrowRight size={16} />
|
||
</button>
|
||
</div>
|
||
</Reveal>
|
||
|
||
{/* Carousel Container */}
|
||
<Reveal style={{ width: '100%' }}>
|
||
<div
|
||
ref={blogCarouselRef}
|
||
style={{
|
||
display: 'flex',
|
||
gap: '1.5rem',
|
||
overflowX: 'auto',
|
||
overflowY: 'hidden',
|
||
scrollSnapType: 'x mandatory',
|
||
scrollPaddingLeft: isMobile ? '1.25rem' : '4rem',
|
||
paddingLeft: isMobile ? '1.25rem' : '4rem',
|
||
paddingRight: isMobile ? '1.25rem' : '4rem',
|
||
paddingBottom: '1.5rem',
|
||
paddingTop: '0.5rem',
|
||
scrollbarWidth: 'none',
|
||
msOverflowStyle: 'none',
|
||
boxSizing: 'border-box',
|
||
}}
|
||
className="blog-carousel"
|
||
>
|
||
{insights.map((insight, idx) => (
|
||
<Reveal
|
||
key={idx}
|
||
delay={idx * 0.1}
|
||
style={{
|
||
flex: isMobile ? '0 0 72vw' : '0 0 340px',
|
||
minWidth: isMobile ? '72vw' : '340px',
|
||
height: '420px',
|
||
scrollSnapAlign: 'start',
|
||
flexShrink: 0,
|
||
}}
|
||
>
|
||
<div
|
||
className="blog-card"
|
||
onClick={() => handleSelectBlog(insight)}
|
||
style={{
|
||
width: '100%',
|
||
height: '100%',
|
||
borderRadius: '14px',
|
||
overflow: 'hidden',
|
||
position: 'relative',
|
||
cursor: 'pointer',
|
||
border: '1px solid rgba(255,255,255,0.08)',
|
||
transition: 'all 0.35s cubic-bezier(0.4,0,0.2,1)',
|
||
boxShadow: '0 4px 30px rgba(0,0,0,0.5)',
|
||
}}
|
||
onMouseEnter={e => {
|
||
e.currentTarget.style.borderColor = 'rgba(255,170,0,0.35)';
|
||
e.currentTarget.style.boxShadow = '0 16px 48px rgba(255,170,0,0.12)';
|
||
e.currentTarget.style.transform = 'translateY(-5px)';
|
||
}}
|
||
onMouseLeave={e => {
|
||
e.currentTarget.style.borderColor = 'rgba(255,255,255,0.08)';
|
||
e.currentTarget.style.boxShadow = '0 4px 30px rgba(0,0,0,0.5)';
|
||
e.currentTarget.style.transform = 'translateY(0)';
|
||
}}
|
||
>
|
||
{/* Full-bleed image */}
|
||
<img
|
||
src={assetUrl(insight.image)}
|
||
alt={insight.title}
|
||
className="blog-card-img"
|
||
style={{
|
||
position: 'absolute', inset: 0,
|
||
width: '100%', height: '100%',
|
||
objectFit: 'cover', objectPosition: 'center top',
|
||
display: 'block',
|
||
transition: 'transform 0.6s ease',
|
||
}}
|
||
/>
|
||
|
||
{/* Subtle top gradient so image top isn't too harsh */}
|
||
<div style={{
|
||
position: 'absolute', inset: 0,
|
||
background: 'linear-gradient(to bottom, rgba(0,0,0,0.0) 30%, rgba(0,0,0,0.25) 60%, rgba(0,0,0,0.0) 100%)',
|
||
pointerEvents: 'none',
|
||
}} />
|
||
|
||
{/* Frosted glass panel — pinned to bottom */}
|
||
<div style={{
|
||
position: 'absolute', bottom: 0, left: 0, right: 0,
|
||
padding: '1.3rem 1.2rem 1.2rem 1.2rem',
|
||
display: 'flex', flexDirection: 'column', gap: '0.5rem',
|
||
background: 'rgba(8, 14, 32, 0.55)',
|
||
backdropFilter: 'blur(14px)',
|
||
WebkitBackdropFilter: 'blur(14px)',
|
||
borderTop: '1px solid rgba(255, 255, 255, 0.08)',
|
||
}}>
|
||
{/* Category */}
|
||
<span style={{
|
||
fontSize: '0.63rem', fontWeight: 700,
|
||
textTransform: 'uppercase', letterSpacing: '0.13em',
|
||
color: '#64748b',
|
||
}}>
|
||
{insight.category}
|
||
</span>
|
||
|
||
{/* Title */}
|
||
<h3 style={{
|
||
fontSize: '0.97rem', fontWeight: 700, color: '#f1f5f9',
|
||
lineHeight: 1.4, margin: 0,
|
||
display: '-webkit-box', WebkitLineClamp: 2,
|
||
WebkitBoxOrient: 'vertical', overflow: 'hidden',
|
||
}}>
|
||
{insight.title}
|
||
</h3>
|
||
|
||
{/* Read Blog */}
|
||
<div
|
||
className="blog-read-more"
|
||
style={{
|
||
marginTop: '0.2rem',
|
||
display: 'flex', alignItems: 'center', gap: '0.35rem',
|
||
color: '#cbd5e1', fontSize: '0.82rem', fontWeight: 600,
|
||
transition: 'color 0.2s ease',
|
||
}}
|
||
>
|
||
Read Blog <ArrowRight size={14} style={{ color: '#ffaa00' }} />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Reveal>
|
||
))}
|
||
</div>
|
||
</Reveal>
|
||
</div>
|
||
</section>
|
||
|
||
</>
|
||
)}
|
||
|
||
{/* Brand Logo Divider Section */}
|
||
<section style={{
|
||
background: '#020c1e',
|
||
position: 'relative',
|
||
zIndex: 10,
|
||
overflow: 'hidden',
|
||
display: 'flex',
|
||
justifyContent: 'center',
|
||
alignItems: 'flex-end',
|
||
padding: '4rem 0 0 0',
|
||
}}>
|
||
<img
|
||
src={assetUrl('/assets/Citpl footer.svg')}
|
||
alt="Cavin Infotech Logo Divider"
|
||
style={{
|
||
width: '100%',
|
||
height: 'auto',
|
||
display: 'block',
|
||
}}
|
||
/>
|
||
</section>
|
||
</div> {/* Close Content Wrapper */}
|
||
|
||
{/* Sticky Parallax Reveal Footer */}
|
||
<footer id="footer" style={{
|
||
position: 'sticky',
|
||
bottom: 0,
|
||
zIndex: 1,
|
||
background: 'linear-gradient(180deg, #ffffff 0%, #dde6f5 100%)',
|
||
padding: isMobile ? '3rem 0' : '4rem 0',
|
||
color: '#1e293b',
|
||
width: '100%',
|
||
scrollMarginTop: `${NAV_OFFSET}px`,
|
||
}}>
|
||
|
||
{/* Footer Container Padded Content */}
|
||
<div style={{ maxWidth: '1440px', margin: '0 auto', width: '100%', padding: `0 ${sectionX}` }}>
|
||
|
||
{/* CTA Banner Section */}
|
||
{isMobile ? (
|
||
<Reveal>
|
||
<div style={{
|
||
background: 'linear-gradient(135deg, #092244 0%, #05162d 100%)',
|
||
borderRadius: '20px',
|
||
padding: '2.2rem 1.6rem',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: '1.2rem',
|
||
marginBottom: '2.5rem',
|
||
position: 'relative',
|
||
overflow: 'hidden',
|
||
boxShadow: '0 20px 40px rgba(0,0,0,0.25)',
|
||
border: '1px solid rgba(255, 255, 255, 0.08)'
|
||
}}>
|
||
<div>
|
||
<h2 style={{ fontSize: '1.65rem', fontWeight: 600, color: '#ffffff', lineHeight: 1.25, marginBottom: '0.8rem', letterSpacing: '-0.02em' }}>
|
||
Let's Build What's Next -<br />Together.
|
||
</h2>
|
||
<p style={{ fontSize: '0.82rem', fontWeight: 500, lineHeight: 1.55, color: '#cbd5e1', marginBottom: '1.8rem', textTransform: 'uppercase', letterSpacing: '0.06em' }}>
|
||
{footer.cta.body}
|
||
</p>
|
||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.9rem' }}>
|
||
<button
|
||
onClick={() => scrollToSection('contactus')}
|
||
style={{
|
||
background: 'linear-gradient(135deg, #d6802e 0%, #ba6a20 100%)',
|
||
border: 'none',
|
||
boxShadow: '0 8px 25px rgba(214, 128, 46, 0.35)',
|
||
color: '#ffffff',
|
||
padding: '0.85rem 1.6rem',
|
||
borderRadius: '50px',
|
||
fontSize: '0.88rem',
|
||
fontWeight: 600,
|
||
cursor: 'pointer',
|
||
width: '100%',
|
||
textAlign: 'center'
|
||
}}
|
||
>
|
||
{footer.cta.primaryButton}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Reveal>
|
||
) : (
|
||
/* Desktop Banner */
|
||
<Reveal>
|
||
<div style={{ position: 'relative', width: '100%', marginBottom: '3.5rem' }}>
|
||
<img
|
||
src={assetUrl(footer.cta.image)}
|
||
alt="CTA Banner"
|
||
style={{
|
||
width: '100%',
|
||
height: 'auto',
|
||
display: 'block',
|
||
}}
|
||
/>
|
||
{/* Overlay text and buttons matching screenshot */}
|
||
<div style={{
|
||
position: 'absolute',
|
||
left: '5.5%',
|
||
top: '50%',
|
||
transform: 'translateY(-50%)',
|
||
width: '56%',
|
||
zIndex: 2,
|
||
}}>
|
||
<h2 style={{
|
||
fontSize: 'clamp(1.5rem, 2.5vw, 2.4rem)',
|
||
fontWeight: 500,
|
||
color: '#ffffff',
|
||
lineHeight: 1.2,
|
||
marginBottom: '1rem',
|
||
letterSpacing: '-0.02em'
|
||
}}>
|
||
Let's Build What's Next -<br />Together.
|
||
</h2>
|
||
<p style={{
|
||
fontSize: 'clamp(0.72rem, 1vw, 0.9rem)',
|
||
fontWeight: 500,
|
||
lineHeight: 1.55,
|
||
color: '#cbd5e1',
|
||
marginBottom: '2.2rem',
|
||
textTransform: 'uppercase',
|
||
letterSpacing: '0.06em',
|
||
maxWidth: '92%'
|
||
}}>
|
||
{footer.cta.body}
|
||
</p>
|
||
<div style={{ display: 'flex', gap: '1rem', alignItems: 'center', flexWrap: 'wrap' }}>
|
||
<button
|
||
onClick={() => scrollToSection('contactus')}
|
||
style={{
|
||
background: 'linear-gradient(135deg, #d6802e 0%, #ba6a20 100%)',
|
||
border: 'none',
|
||
boxShadow: '0 8px 25px rgba(214, 128, 46, 0.35)',
|
||
color: '#ffffff',
|
||
padding: '0.85rem 1.8rem',
|
||
borderRadius: '50px',
|
||
fontSize: 'clamp(0.75rem, 0.95vw, 0.88rem)',
|
||
fontWeight: 600,
|
||
cursor: 'pointer',
|
||
transition: 'all 0.25s ease',
|
||
}}
|
||
onMouseEnter={e => {
|
||
e.currentTarget.style.transform = 'translateY(-2px)';
|
||
e.currentTarget.style.boxShadow = '0 12px 30px rgba(214, 128, 46, 0.5)';
|
||
}}
|
||
onMouseLeave={e => {
|
||
e.currentTarget.style.transform = 'translateY(0)';
|
||
e.currentTarget.style.boxShadow = '0 8px 25px rgba(214, 128, 46, 0.35)';
|
||
}}
|
||
>
|
||
{footer.cta.primaryButton}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Reveal>
|
||
)}
|
||
|
||
{/* Links Grid */}
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: isMobile ? '1fr 1fr' : '180px 180px 1fr',
|
||
gap: isMobile ? '2rem 1.5rem' : '1.25rem',
|
||
paddingBottom: isMobile ? '2rem' : '2.5rem',
|
||
borderBottom: '1px solid rgba(30,41,59,0.12)',
|
||
marginBottom: '1.5rem',
|
||
}}>
|
||
{/* Quick Links */}
|
||
<div>
|
||
<h5 style={{ fontSize: '0.75rem', fontWeight: 800, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#1e293b', marginBottom: '1rem' }}>Quick Links</h5>
|
||
<ul style={{ listStyle: 'none', display: 'flex', flexDirection: 'column', gap: '0.45rem', padding: 0, margin: 0 }}>
|
||
<li>
|
||
<a href="#home" onClick={e => {
|
||
e.preventDefault();
|
||
scrollToSection('home');
|
||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
||
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>Home</a>
|
||
</li>
|
||
<li>
|
||
<a href="#aboutus" onClick={e => {
|
||
e.preventDefault();
|
||
handleNavClick('About Us');
|
||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
||
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>About Us</a>
|
||
</li>
|
||
<li>
|
||
<a href="#services" onClick={e => {
|
||
e.preventDefault();
|
||
if (currentPage !== 'home') {
|
||
setCurrentPage('home');
|
||
setTimeout(() => scrollToSection('services'), 300);
|
||
} else {
|
||
scrollToSection('services');
|
||
}
|
||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
||
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>Our Services</a>
|
||
</li>
|
||
<li>
|
||
<a href="#contactus" onClick={e => {
|
||
e.preventDefault();
|
||
handleNavClick('Contact Us');
|
||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
||
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>Contact Us</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
|
||
{/* Products */}
|
||
<div>
|
||
<h5 style={{ fontSize: '0.75rem', fontWeight: 800, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#1e293b', marginBottom: '1rem' }}>Products</h5>
|
||
<ul style={{ listStyle: 'none', display: 'flex', flexDirection: 'column', gap: '0.45rem', padding: 0, margin: 0 }}>
|
||
{(footer.productLinks && footer.productLinks.length ? footer.productLinks.map(p => p.label) : ['Nebula AI Platform', 'Prodmax', 'Budgie']).map(l => (
|
||
<li key={l}><a href="#products" onClick={e => {
|
||
e.preventDefault();
|
||
if (currentPage !== 'home') {
|
||
setCurrentPage('home');
|
||
setTimeout(() => scrollToSection('products'), 300);
|
||
} else {
|
||
scrollToSection('products');
|
||
}
|
||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.85rem', transition: 'color 0.2s' }}
|
||
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>{l}</a></li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
|
||
{/* Social Links Column */}
|
||
<div style={{ gridColumn: isMobile ? 'span 2' : 'auto' }}>
|
||
<h5 style={{ fontSize: '0.75rem', fontWeight: 800, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#1e40af', marginBottom: '1rem' }}>Social Links</h5>
|
||
<div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center', flexWrap: 'wrap' }}>
|
||
{(footer.social && footer.social.length ? footer.social : [
|
||
{ platform: 'Facebook', url: 'https://www.facebook.com/cavininfotech1' },
|
||
{ platform: 'X', url: 'https://x.com/cavin_infotech' },
|
||
{ platform: 'Instagram', url: 'https://www.instagram.com/cavin_infotech' },
|
||
{ platform: 'LinkedIn', url: 'https://www.linkedin.com/company/cavin-infotech/' },
|
||
{ platform: 'YouTube', url: 'https://youtube.com/@cavin_infotech' }
|
||
]).map(({ platform, url }) => {
|
||
const paths = {
|
||
Facebook: 'M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z',
|
||
Instagram: 'M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.051.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 1 0 0 12.324 6.162 6.162 0 0 0 0-12.324zM12 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm6.406-11.845a1.44 1.44 0 1 0 0 2.881 1.44 1.44 0 0 0 0-2.881z',
|
||
LinkedIn: 'M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z',
|
||
X: 'M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z',
|
||
YouTube: 'M23.498 6.163a3.003 3.003 0 0 0-2.11-2.11C19.53 3.545 12 3.545 12 3.545s-7.53 0-9.388.508a3.003 3.003 0 0 0-2.11 2.11C0 8.017 0 12 0 12s0 3.983.502 5.837a3.003 3.003 0 0 0 2.11 2.11c1.858.508 9.388.508 9.388.508s7.53 0 9.388-.508a3.003 3.003 0 0 0 2.11-2.11C24 15.983 24 12 24 12s0-3.983-.502-5.837zM9.545 15.568V8.432L15.818 12l-6.273 3.568z'
|
||
};
|
||
const d = paths[platform] || paths.Facebook;
|
||
|
||
return (
|
||
<a key={platform} href={url || '#'} target="_blank" rel="noopener noreferrer" aria-label={platform}
|
||
style={{
|
||
width: '36px', height: '36px', borderRadius: '50%',
|
||
background: 'rgba(30,41,59,0.08)', border: '1px solid rgba(30,41,59,0.12)',
|
||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||
transition: 'all 0.2s ease', color: '#475569',
|
||
}}
|
||
onMouseEnter={e => { e.currentTarget.style.background = '#1e40af'; e.currentTarget.style.color = '#fff'; e.currentTarget.style.borderColor = '#1e40af'; }}
|
||
onMouseLeave={e => { e.currentTarget.style.background = 'rgba(30,41,59,0.08)'; e.currentTarget.style.color = '#475569'; e.currentTarget.style.borderColor = 'rgba(30,41,59,0.12)'; }}
|
||
>
|
||
<svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor" stroke="none">
|
||
<path d={d} />
|
||
</svg>
|
||
</a>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Legal / Copyright Bottom Bar */}
|
||
<div style={{
|
||
display: 'flex',
|
||
flexDirection: isMobile ? 'column' : 'row',
|
||
alignItems: isMobile ? 'flex-start' : 'center',
|
||
justifyContent: 'space-between',
|
||
gap: isMobile ? '0.75rem' : '1.5rem',
|
||
fontSize: '0.82rem',
|
||
color: '#475569',
|
||
}}>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem', flexWrap: 'wrap' }}>
|
||
<a href="#" style={{ color: '#475569', textDecoration: 'none', fontWeight: 500, transition: 'color 0.2s' }}
|
||
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>Privacy Policy</a>
|
||
<span style={{ color: '#cbd5e1' }}>•</span>
|
||
<a href="#" style={{ color: '#475569', textDecoration: 'none', fontWeight: 500, transition: 'color 0.2s' }}
|
||
onMouseEnter={e => e.currentTarget.style.color = '#1e40af'}
|
||
onMouseLeave={e => e.currentTarget.style.color = '#475569'}>Terms & Conditions</a>
|
||
</div>
|
||
<span style={{ fontSize: '0.78rem', color: '#64748b' }}>
|
||
Copyrights reserved to CAVIN INFOTECH
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</footer >
|
||
|
||
{/* Careers Modal Popup */ }
|
||
{
|
||
isCareersOpen && !previewMode && (
|
||
<div style={{
|
||
position: 'fixed',
|
||
inset: 0,
|
||
backgroundColor: 'rgba(2, 7, 16, 0.85)',
|
||
backdropFilter: 'blur(10px)',
|
||
zIndex: 100,
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
padding: isMobile ? '1rem' : '1.5rem',
|
||
overflowY: 'auto',
|
||
}}>
|
||
<div style={{
|
||
position: 'relative',
|
||
borderRadius: '24px',
|
||
border: '1px solid rgba(255, 255, 255, 0.1)',
|
||
background: 'rgba(5, 11, 24, 0.95)',
|
||
backdropFilter: 'blur(20px)',
|
||
WebkitBackdropFilter: 'blur(20px)',
|
||
overflow: 'hidden',
|
||
boxShadow: '0 30px 70px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.08)',
|
||
display: 'grid',
|
||
gridTemplateColumns: isMobile ? '1fr' : '38% 62%',
|
||
minHeight: '520px',
|
||
width: '100%',
|
||
maxWidth: '920px',
|
||
color: '#ffffff',
|
||
}}>
|
||
|
||
{/* Close Button */}
|
||
<button
|
||
onClick={() => {
|
||
setIsCareersOpen(false);
|
||
setShowCareersAcknowledgement(false);
|
||
setCareersTurnstileToken('');
|
||
setCareersErrorMsg('');
|
||
}}
|
||
style={{
|
||
position: 'absolute',
|
||
top: '1.25rem',
|
||
right: '1.25rem',
|
||
background: 'none',
|
||
border: 'none',
|
||
color: '#94a3b8',
|
||
cursor: 'pointer',
|
||
fontSize: '1.5rem',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
transition: 'color 0.2s',
|
||
zIndex: 10,
|
||
}}
|
||
onMouseEnter={e => e.currentTarget.style.color = '#38bdf8'}
|
||
onMouseLeave={e => e.currentTarget.style.color = '#94a3b8'}
|
||
>
|
||
×
|
||
</button>
|
||
|
||
{/* LEFT SIDE: "Join Our Team" Info */}
|
||
<div
|
||
style={{
|
||
position: 'relative',
|
||
zIndex: 1,
|
||
padding: isMobile ? '2.5rem 1.5rem' : '3.5rem 3rem',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
justifyContent: 'flex-start',
|
||
background: 'radial-gradient(circle at top left, rgba(3, 135, 218, 0.25) 0%, rgba(2, 7, 16, 0.4) 100%)',
|
||
borderRight: isMobile ? 'none' : '1px solid rgba(255, 255, 255, 0.08)',
|
||
borderBottom: isMobile ? '1px solid rgba(255, 255, 255, 0.08)' : 'none',
|
||
overflow: 'hidden'
|
||
}}
|
||
>
|
||
{/* Blur asset overlay on left section */}
|
||
<img
|
||
src={assetUrl('/assets/C0ntact form blur.svg')}
|
||
alt=""
|
||
style={{
|
||
position: 'absolute',
|
||
top: '-20%',
|
||
left: '-20%',
|
||
width: '140%',
|
||
height: '140%',
|
||
objectFit: 'cover',
|
||
opacity: 0.7,
|
||
pointerEvents: 'none',
|
||
zIndex: 0
|
||
}}
|
||
/>
|
||
|
||
<div style={{ position: 'relative', zIndex: 1 }}>
|
||
<h3 style={{
|
||
fontSize: isMobile ? '1.5rem' : '1.85rem',
|
||
fontWeight: 700,
|
||
color: '#ffffff',
|
||
marginBottom: '2rem',
|
||
letterSpacing: '-0.01em'
|
||
}}>
|
||
Join Our Team
|
||
</h3>
|
||
|
||
<ul style={{
|
||
listStyle: 'none',
|
||
padding: 0,
|
||
margin: 0,
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: '1.25rem'
|
||
}}>
|
||
{[
|
||
'Work on Challenging Projects',
|
||
'Collaborative Global Team',
|
||
'Continuous Growth & Learning',
|
||
'Competitive Compensation'
|
||
].map((item, idx) => (
|
||
<li
|
||
key={idx}
|
||
style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '0.85rem',
|
||
color: '#e2e8f0',
|
||
fontSize: isMobile ? '0.95rem' : '1.05rem',
|
||
fontWeight: 500
|
||
}}
|
||
>
|
||
<span style={{
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
width: '20px',
|
||
height: '20px',
|
||
color: '#ffffff'
|
||
}}>
|
||
✓
|
||
</span>
|
||
<span>{item}</span>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
{/* RIGHT SIDE: Careers Form */}
|
||
<div
|
||
style={{
|
||
position: 'relative',
|
||
zIndex: 1,
|
||
padding: isMobile ? '2.5rem 1.5rem' : '3.5rem 3.5rem',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
justifyContent: 'center',
|
||
background: 'rgba(2, 7, 16, 0.4)'
|
||
}}
|
||
>
|
||
{!showCareersAcknowledgement ? (
|
||
<form
|
||
onSubmit={async (e) => {
|
||
e.preventDefault();
|
||
if (!careersName.trim() || !careersEmail.trim() || !careersPhone.trim()) {
|
||
setCareersErrorMsg('Please fill in Name, Email, and Phone fields.');
|
||
return;
|
||
}
|
||
if (!careersFile) {
|
||
setCareersErrorMsg('Please upload your resume file.');
|
||
return;
|
||
}
|
||
if (!careersTurnstileToken) {
|
||
setCareersErrorMsg('Please complete the Cloudflare Turnstile security verification.');
|
||
return;
|
||
}
|
||
|
||
setIsCareersSubmitting(true);
|
||
setCareersErrorMsg('');
|
||
|
||
try {
|
||
const uploadData = new FormData();
|
||
uploadData.append('type', 'careers');
|
||
uploadData.append('name', careersName);
|
||
uploadData.append('email', careersEmail);
|
||
uploadData.append('phone', careersPhone);
|
||
if (careersFile) {
|
||
uploadData.append('resume', careersFile);
|
||
uploadData.append('resumeName', careersFile.name);
|
||
}
|
||
uploadData.append('message', `New Careers Application from ${careersName}`);
|
||
uploadData.append('turnstileToken', careersTurnstileToken);
|
||
|
||
let response = await fetch('/api/contact', {
|
||
method: 'POST',
|
||
body: uploadData
|
||
});
|
||
|
||
if (!response.ok) {
|
||
response = await fetch('/api/send', {
|
||
method: 'POST',
|
||
body: uploadData
|
||
});
|
||
}
|
||
|
||
const resData = await response.json().catch(() => ({}));
|
||
|
||
if (response.ok && resData.success) {
|
||
setShowCareersAcknowledgement(true);
|
||
} else {
|
||
setShowCareersAcknowledgement(true);
|
||
}
|
||
} catch (err) {
|
||
console.error('Error sending application:', err);
|
||
setShowCareersAcknowledgement(true);
|
||
} finally {
|
||
setIsCareersSubmitting(false);
|
||
}
|
||
}}
|
||
style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}
|
||
>
|
||
{careersErrorMsg && (
|
||
<div style={{
|
||
padding: '0.75rem 1rem',
|
||
background: 'rgba(239, 68, 68, 0.15)',
|
||
border: '1px solid rgba(239, 68, 68, 0.4)',
|
||
borderRadius: '8px',
|
||
color: '#fca5a5',
|
||
fontSize: '0.88rem'
|
||
}}>
|
||
{careersErrorMsg}
|
||
</div>
|
||
)}
|
||
|
||
{/* Name Input */}
|
||
<div style={{ position: 'relative' }}>
|
||
<input
|
||
type="text"
|
||
required
|
||
value={careersName}
|
||
onChange={e => {
|
||
setCareersName(e.target.value);
|
||
if (careersErrorMsg) setCareersErrorMsg('');
|
||
}}
|
||
placeholder="Name"
|
||
style={{
|
||
width: '100%',
|
||
background: 'transparent',
|
||
border: 'none',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.25)',
|
||
color: '#ffffff',
|
||
fontSize: '0.98rem',
|
||
padding: '0.6rem 0',
|
||
outline: 'none',
|
||
transition: 'border-color 0.3s ease',
|
||
}}
|
||
onFocus={e => e.currentTarget.style.borderBottomColor = '#38bdf8'}
|
||
onBlur={e => e.currentTarget.style.borderBottomColor = 'rgba(255, 255, 255, 0.25)'}
|
||
/>
|
||
</div>
|
||
|
||
{/* Email Input */}
|
||
<div style={{ position: 'relative' }}>
|
||
<input
|
||
type="email"
|
||
required
|
||
value={careersEmail}
|
||
onChange={e => {
|
||
setCareersEmail(e.target.value);
|
||
if (careersErrorMsg) setCareersErrorMsg('');
|
||
}}
|
||
placeholder="Email"
|
||
style={{
|
||
width: '100%',
|
||
background: 'transparent',
|
||
border: 'none',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.25)',
|
||
color: '#ffffff',
|
||
fontSize: '0.98rem',
|
||
padding: '0.6rem 0',
|
||
outline: 'none',
|
||
transition: 'border-color 0.3s ease',
|
||
}}
|
||
onFocus={e => e.currentTarget.style.borderBottomColor = '#38bdf8'}
|
||
onBlur={e => e.currentTarget.style.borderBottomColor = 'rgba(255, 255, 255, 0.25)'}
|
||
/>
|
||
</div>
|
||
|
||
{/* Phone Input */}
|
||
<div style={{ position: 'relative' }}>
|
||
<input
|
||
type="tel"
|
||
required
|
||
value={careersPhone}
|
||
onChange={e => {
|
||
setCareersPhone(e.target.value);
|
||
if (careersErrorMsg) setCareersErrorMsg('');
|
||
}}
|
||
placeholder="Phone"
|
||
style={{
|
||
width: '100%',
|
||
background: 'transparent',
|
||
border: 'none',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.25)',
|
||
color: '#ffffff',
|
||
fontSize: '0.98rem',
|
||
padding: '0.6rem 0',
|
||
outline: 'none',
|
||
transition: 'border-color 0.3s ease',
|
||
}}
|
||
onFocus={e => e.currentTarget.style.borderBottomColor = '#38bdf8'}
|
||
onBlur={e => e.currentTarget.style.borderBottomColor = 'rgba(255, 255, 255, 0.25)'}
|
||
/>
|
||
</div>
|
||
|
||
{/* File Attachment Input */}
|
||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem', marginTop: '0.5rem' }}>
|
||
<div style={{
|
||
position: 'relative',
|
||
border: '2px dashed rgba(255, 255, 255, 0.15)',
|
||
borderRadius: '12px',
|
||
padding: '1.5rem',
|
||
textAlign: 'center',
|
||
background: 'rgba(255, 255, 255, 0.01)',
|
||
cursor: 'pointer',
|
||
transition: 'all 0.3s ease',
|
||
}}
|
||
onMouseEnter={e => {
|
||
e.currentTarget.style.borderColor = '#38bdf8';
|
||
e.currentTarget.style.background = 'rgba(56, 189, 248, 0.05)';
|
||
}}
|
||
onMouseLeave={e => {
|
||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.15)';
|
||
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.01)';
|
||
}}
|
||
>
|
||
<input
|
||
type="file"
|
||
required
|
||
accept=".pdf,.doc,.docx"
|
||
style={{
|
||
position: 'absolute',
|
||
inset: 0,
|
||
width: '100%',
|
||
height: '100%',
|
||
opacity: 0,
|
||
cursor: 'pointer',
|
||
}}
|
||
onChange={e => {
|
||
const file = e.target.files[0];
|
||
setCareersFile(file);
|
||
if (careersErrorMsg) setCareersErrorMsg('');
|
||
const fileName = file?.name;
|
||
const labelEl = document.getElementById('file-upload-label');
|
||
if (labelEl && fileName) {
|
||
labelEl.textContent = fileName;
|
||
}
|
||
}}
|
||
/>
|
||
<span id="file-upload-label" style={{ fontSize: '0.88rem', color: '#cbd5e1', fontWeight: 500 }}>
|
||
Click to upload your Resume (.pdf, .doc, .docx)
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Cloudflare Turnstile Captcha */}
|
||
<TurnstileCaptcha
|
||
onVerify={token => {
|
||
setCareersTurnstileToken(token);
|
||
if (careersErrorMsg) setCareersErrorMsg('');
|
||
}}
|
||
onExpire={() => setCareersTurnstileToken('')}
|
||
/>
|
||
|
||
{/* Submit Button */}
|
||
<button
|
||
type="submit"
|
||
disabled={isCareersSubmitting}
|
||
style={{
|
||
marginTop: '1rem',
|
||
width: '100%',
|
||
background: '#ffffff',
|
||
color: '#020710',
|
||
border: 'none',
|
||
padding: '0.95rem 1.5rem',
|
||
borderRadius: '50px',
|
||
fontSize: '1.05rem',
|
||
fontWeight: 700,
|
||
cursor: isCareersSubmitting ? 'not-allowed' : 'pointer',
|
||
boxShadow: '0 10px 25px rgba(255, 255, 255, 0.15)',
|
||
transition: 'all 0.3s ease',
|
||
}}
|
||
onMouseEnter={e => {
|
||
if (!isCareersSubmitting) {
|
||
e.currentTarget.style.transform = 'translateY(-2px)';
|
||
e.currentTarget.style.boxShadow = '0 15px 35px rgba(255, 255, 255, 0.3)';
|
||
}
|
||
}}
|
||
onMouseLeave={e => {
|
||
if (!isCareersSubmitting) {
|
||
e.currentTarget.style.transform = 'translateY(0)';
|
||
e.currentTarget.style.boxShadow = '0 10px 25px rgba(255, 255, 255, 0.15)';
|
||
}
|
||
}}
|
||
>
|
||
{isCareersSubmitting ? 'Submitting...' : 'Submit Application'}
|
||
</button>
|
||
</form>
|
||
) : (
|
||
/* Acknowledgement Panel */
|
||
<div style={{ textAlign: 'center', padding: '1rem 0' }}>
|
||
<div style={{
|
||
width: '56px',
|
||
height: '56px',
|
||
borderRadius: '50%',
|
||
background: 'rgba(16, 185, 129, 0.2)',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
margin: '0 auto 1.25rem auto',
|
||
color: '#34d399'
|
||
}}>
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#34d399" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
|
||
<polyline points="20 6 9 17 4 12" />
|
||
</svg>
|
||
</div>
|
||
<h3 style={{
|
||
fontSize: '1.5rem',
|
||
fontWeight: 700,
|
||
marginBottom: '1rem',
|
||
color: '#ffffff',
|
||
letterSpacing: '-0.02em',
|
||
}}>
|
||
Application Received!
|
||
</h3>
|
||
<p style={{
|
||
fontSize: '0.9rem',
|
||
color: '#cbd5e1',
|
||
lineHeight: '1.6',
|
||
marginBottom: '2rem',
|
||
}}>
|
||
Thank you for applying to Cavin Infotech. We have received your resume and details successfully. Our recruitment team will review your application and contact you if your qualifications match our current needs.
|
||
</p>
|
||
<button
|
||
onClick={() => {
|
||
setIsCareersOpen(false);
|
||
setShowCareersAcknowledgement(false);
|
||
setCareersName('');
|
||
setCareersEmail('');
|
||
setCareersPhone('');
|
||
setCareersFile(null);
|
||
setCareersTurnstileToken('');
|
||
}}
|
||
style={{
|
||
background: 'transparent',
|
||
border: '1px solid rgba(255, 255, 255, 0.3)',
|
||
color: '#ffffff',
|
||
padding: '0.6rem 2rem',
|
||
borderRadius: '50px',
|
||
fontSize: '0.88rem',
|
||
fontWeight: 600,
|
||
cursor: 'pointer',
|
||
}}
|
||
>
|
||
Close Window
|
||
</button>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
{/* Book a Strategy Call Modal Popup */ }
|
||
{
|
||
isStrategyOpen && !previewMode && (
|
||
<div style={{
|
||
position: 'fixed',
|
||
inset: 0,
|
||
backgroundColor: 'rgba(2, 7, 16, 0.85)',
|
||
backdropFilter: 'blur(10px)',
|
||
zIndex: 100,
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
padding: isMobile ? '1rem' : '1.5rem',
|
||
overflowY: 'auto',
|
||
}}>
|
||
<div style={{
|
||
position: 'relative',
|
||
borderRadius: '24px',
|
||
border: '1px solid rgba(255, 255, 255, 0.1)',
|
||
background: 'rgba(5, 11, 24, 0.95)',
|
||
backdropFilter: 'blur(20px)',
|
||
WebkitBackdropFilter: 'blur(20px)',
|
||
overflow: 'hidden',
|
||
boxShadow: '0 30px 70px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.08)',
|
||
display: 'grid',
|
||
gridTemplateColumns: isMobile ? '1fr' : '38% 62%',
|
||
minHeight: '520px',
|
||
width: '100%',
|
||
maxWidth: '920px',
|
||
color: '#ffffff',
|
||
}}>
|
||
|
||
{/* Close Button */}
|
||
<button
|
||
onClick={() => {
|
||
setIsStrategyOpen(false);
|
||
setShowStrategyAcknowledgement(false);
|
||
setStrategyTurnstileToken('');
|
||
setStrategyErrorMsg('');
|
||
}}
|
||
style={{
|
||
position: 'absolute',
|
||
top: '1.25rem',
|
||
right: '1.25rem',
|
||
background: 'none',
|
||
border: 'none',
|
||
color: '#94a3b8',
|
||
cursor: 'pointer',
|
||
fontSize: '1.5rem',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
transition: 'color 0.2s',
|
||
zIndex: 10,
|
||
}}
|
||
onMouseEnter={e => e.currentTarget.style.color = '#38bdf8'}
|
||
onMouseLeave={e => e.currentTarget.style.color = '#94a3b8'}
|
||
>
|
||
×
|
||
</button>
|
||
|
||
{/* LEFT SIDE: "How We Can Help?" Info */}
|
||
<div
|
||
style={{
|
||
position: 'relative',
|
||
zIndex: 1,
|
||
padding: isMobile ? '2.5rem 1.5rem' : '3.5rem 3rem',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
justifyContent: 'flex-start',
|
||
background: 'radial-gradient(circle at top left, rgba(3, 135, 218, 0.25) 0%, rgba(2, 7, 16, 0.4) 100%)',
|
||
borderRight: isMobile ? 'none' : '1px solid rgba(255, 255, 255, 0.08)',
|
||
borderBottom: isMobile ? '1px solid rgba(255, 255, 255, 0.08)' : 'none',
|
||
overflow: 'hidden'
|
||
}}
|
||
>
|
||
{/* Blur asset overlay on left section */}
|
||
<img
|
||
src={assetUrl('/assets/C0ntact form blur.svg')}
|
||
alt=""
|
||
style={{
|
||
position: 'absolute',
|
||
top: '-20%',
|
||
left: '-20%',
|
||
width: '140%',
|
||
height: '140%',
|
||
objectFit: 'cover',
|
||
opacity: 0.7,
|
||
pointerEvents: 'none',
|
||
zIndex: 0
|
||
}}
|
||
/>
|
||
|
||
<div style={{ position: 'relative', zIndex: 1 }}>
|
||
<h3 style={{
|
||
fontSize: isMobile ? '1.5rem' : '1.85rem',
|
||
fontWeight: 700,
|
||
color: '#ffffff',
|
||
marginBottom: '2rem',
|
||
letterSpacing: '-0.01em'
|
||
}}>
|
||
How We Can Help?
|
||
</h3>
|
||
|
||
<ul style={{
|
||
listStyle: 'none',
|
||
padding: 0,
|
||
margin: 0,
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: '1.25rem'
|
||
}}>
|
||
{[
|
||
'Tailored Strategy Session',
|
||
'Expert Guidance',
|
||
'Technical Architecture Review',
|
||
'Value-Added Partnership'
|
||
].map((item, idx) => (
|
||
<li
|
||
key={idx}
|
||
style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '0.85rem',
|
||
color: '#e2e8f0',
|
||
fontSize: isMobile ? '0.95rem' : '1.05rem',
|
||
fontWeight: 500
|
||
}}
|
||
>
|
||
<span style={{
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
width: '20px',
|
||
height: '20px',
|
||
color: '#ffffff'
|
||
}}>
|
||
✓
|
||
</span>
|
||
<span>{item}</span>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
{/* RIGHT SIDE: Strategy call Form */}
|
||
<div
|
||
style={{
|
||
position: 'relative',
|
||
zIndex: 1,
|
||
padding: isMobile ? '2.5rem 1.5rem' : '3.5rem 3.5rem',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
justifyContent: 'center',
|
||
background: 'rgba(2, 7, 16, 0.4)'
|
||
}}
|
||
>
|
||
{!showStrategyAcknowledgement ? (
|
||
<form
|
||
onSubmit={async (e) => {
|
||
e.preventDefault();
|
||
if (!strategyName.trim() || !strategyEmail.trim() || !strategyMobile.trim() || !strategyDesignation.trim() || !strategyDate.trim() || !strategyTime.trim()) {
|
||
setStrategyErrorMsg('Please fill in all required fields including Date and Time Slot.');
|
||
return;
|
||
}
|
||
if (!strategyTurnstileToken) {
|
||
setStrategyErrorMsg('Please complete the Cloudflare Turnstile security verification.');
|
||
return;
|
||
}
|
||
|
||
setIsStrategySubmitting(true);
|
||
setStrategyErrorMsg('');
|
||
|
||
const selectedInterests = Object.keys(strategyInterests).filter(key => strategyInterests[key]).join(', ');
|
||
const formattedDateTime = `${strategyDate} (${strategyTime})`;
|
||
|
||
try {
|
||
let response = await fetch('/api/contact', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
type: 'strategy',
|
||
name: strategyName,
|
||
email: strategyEmail,
|
||
phone: strategyMobile,
|
||
designation: strategyDesignation,
|
||
dateTime: formattedDateTime,
|
||
interests: selectedInterests || 'General Consultation',
|
||
message: `New Strategy Call Request from ${strategyName}`,
|
||
turnstileToken: strategyTurnstileToken
|
||
})
|
||
});
|
||
|
||
if (!response.ok) {
|
||
response = await fetch('/api/send', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
type: 'strategy',
|
||
name: strategyName,
|
||
email: strategyEmail,
|
||
phone: strategyMobile,
|
||
designation: strategyDesignation,
|
||
dateTime: formattedDateTime,
|
||
interests: selectedInterests || 'General Consultation',
|
||
message: `New Strategy Call Request from ${strategyName}`,
|
||
turnstileToken: strategyTurnstileToken
|
||
})
|
||
});
|
||
}
|
||
|
||
const resData = await response.json().catch(() => ({}));
|
||
|
||
if (response.ok && resData.success) {
|
||
setShowStrategyAcknowledgement(true);
|
||
} else {
|
||
setShowStrategyAcknowledgement(true);
|
||
}
|
||
} catch (err) {
|
||
console.error('Error scheduling strategy session:', err);
|
||
setShowStrategyAcknowledgement(true);
|
||
} finally {
|
||
setIsStrategySubmitting(false);
|
||
}
|
||
}}
|
||
style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}
|
||
>
|
||
{strategyErrorMsg && (
|
||
<div style={{
|
||
padding: '0.75rem 1rem',
|
||
background: 'rgba(239, 68, 68, 0.15)',
|
||
border: '1px solid rgba(239, 68, 68, 0.4)',
|
||
borderRadius: '8px',
|
||
color: '#fca5a5',
|
||
fontSize: '0.88rem'
|
||
}}>
|
||
{strategyErrorMsg}
|
||
</div>
|
||
)}
|
||
|
||
{/* Name & Email Group */}
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr',
|
||
gap: '1.5rem'
|
||
}}>
|
||
<div style={{ position: 'relative' }}>
|
||
<input
|
||
type="text"
|
||
required
|
||
value={strategyName}
|
||
onChange={e => {
|
||
setStrategyName(e.target.value);
|
||
if (strategyErrorMsg) setStrategyErrorMsg('');
|
||
}}
|
||
placeholder="Name"
|
||
style={{
|
||
width: '100%',
|
||
background: 'transparent',
|
||
border: 'none',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.25)',
|
||
color: '#ffffff',
|
||
fontSize: '0.98rem',
|
||
padding: '0.5rem 0',
|
||
outline: 'none',
|
||
transition: 'border-color 0.3s ease',
|
||
}}
|
||
onFocus={e => e.currentTarget.style.borderBottomColor = '#38bdf8'}
|
||
onBlur={e => e.currentTarget.style.borderBottomColor = 'rgba(255, 255, 255, 0.25)'}
|
||
/>
|
||
</div>
|
||
|
||
<div style={{ position: 'relative' }}>
|
||
<input
|
||
type="email"
|
||
required
|
||
value={strategyEmail}
|
||
onChange={e => {
|
||
setStrategyEmail(e.target.value);
|
||
if (strategyErrorMsg) setStrategyErrorMsg('');
|
||
}}
|
||
placeholder="Email"
|
||
style={{
|
||
width: '100%',
|
||
background: 'transparent',
|
||
border: 'none',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.25)',
|
||
color: '#ffffff',
|
||
fontSize: '0.98rem',
|
||
padding: '0.5rem 0',
|
||
outline: 'none',
|
||
transition: 'border-color 0.3s ease',
|
||
}}
|
||
onFocus={e => e.currentTarget.style.borderBottomColor = '#38bdf8'}
|
||
onBlur={e => e.currentTarget.style.borderBottomColor = 'rgba(255, 255, 255, 0.25)'}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Phone & Designation Group */}
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr',
|
||
gap: '1.5rem'
|
||
}}>
|
||
<div style={{ position: 'relative' }}>
|
||
<input
|
||
type="tel"
|
||
required
|
||
value={strategyMobile}
|
||
onChange={e => {
|
||
setStrategyMobile(e.target.value);
|
||
if (strategyErrorMsg) setStrategyErrorMsg('');
|
||
}}
|
||
placeholder="Mobile"
|
||
style={{
|
||
width: '100%',
|
||
background: 'transparent',
|
||
border: 'none',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.25)',
|
||
color: '#ffffff',
|
||
fontSize: '0.98rem',
|
||
padding: '0.5rem 0',
|
||
outline: 'none',
|
||
transition: 'border-color 0.3s ease',
|
||
}}
|
||
onFocus={e => e.currentTarget.style.borderBottomColor = '#38bdf8'}
|
||
onBlur={e => e.currentTarget.style.borderBottomColor = 'rgba(255, 255, 255, 0.25)'}
|
||
/>
|
||
</div>
|
||
|
||
<div style={{ position: 'relative' }}>
|
||
<input
|
||
type="text"
|
||
required
|
||
value={strategyDesignation}
|
||
onChange={e => {
|
||
setStrategyDesignation(e.target.value);
|
||
if (strategyErrorMsg) setStrategyErrorMsg('');
|
||
}}
|
||
placeholder="Designation"
|
||
style={{
|
||
width: '100%',
|
||
background: 'transparent',
|
||
border: 'none',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.25)',
|
||
color: '#ffffff',
|
||
fontSize: '0.98rem',
|
||
padding: '0.5rem 0',
|
||
outline: 'none',
|
||
transition: 'border-color 0.3s ease',
|
||
}}
|
||
onFocus={e => e.currentTarget.style.borderBottomColor = '#38bdf8'}
|
||
onBlur={e => e.currentTarget.style.borderBottomColor = 'rgba(255, 255, 255, 0.25)'}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Date & Time Slot (Glassmorphic Custom Controls) */}
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr',
|
||
gap: '1.5rem'
|
||
}}>
|
||
{/* Glassmorphic Date Picker */}
|
||
<div style={{ position: 'relative' }}>
|
||
<GlassmorphicDatePicker
|
||
value={strategyDate}
|
||
onChange={(newDate) => {
|
||
setStrategyDate(newDate);
|
||
if (strategyErrorMsg) setStrategyErrorMsg('');
|
||
}}
|
||
placeholder="Preferred Date"
|
||
/>
|
||
</div>
|
||
|
||
{/* Glassmorphic Time Slot Select */}
|
||
<div style={{ position: 'relative' }}>
|
||
<GlassmorphicSelect
|
||
value={strategyTime}
|
||
onChange={(newTime) => {
|
||
setStrategyTime(newTime);
|
||
if (strategyErrorMsg) setStrategyErrorMsg('');
|
||
}}
|
||
placeholder="Preferred Time Slot"
|
||
options={[
|
||
{ value: '09:00 AM - 10:00 AM', label: '09:00 AM - 10:00 AM' },
|
||
{ value: '10:00 AM - 11:00 AM', label: '10:00 AM - 11:00 AM' },
|
||
{ value: '11:00 AM - 12:00 PM', label: '11:00 AM - 12:00 PM' },
|
||
{ value: '02:00 PM - 03:00 PM', label: '02:00 PM - 03:00 PM' },
|
||
{ value: '03:00 PM - 04:00 PM', label: '03:00 PM - 04:00 PM' },
|
||
{ value: '04:00 PM - 05:00 PM', label: '04:00 PM - 05:00 PM' },
|
||
{ value: '05:00 PM - 06:00 PM', label: '05:00 PM - 06:00 PM' }
|
||
]}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Areas of Interest Checkboxes */}
|
||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
|
||
<label style={{ fontSize: '0.78rem', fontWeight: 600, color: '#e2e8f0', textTransform: 'uppercase', letterSpacing: '0.05em' }}>Areas of Interest</label>
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: '1fr 1fr',
|
||
gap: '0.5rem',
|
||
background: 'rgba(255, 255, 255, 0.01)',
|
||
border: '1px solid rgba(255, 255, 255, 0.05)',
|
||
borderRadius: '10px',
|
||
padding: '0.75rem',
|
||
}}>
|
||
{[
|
||
'AI & Analytics',
|
||
'SAP Services',
|
||
'XR Platforms',
|
||
'Smart Factory',
|
||
'Cloud Engineering',
|
||
'Enterprise Software'
|
||
].map((interest) => (
|
||
<label key={interest} style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '0.5rem',
|
||
fontSize: '0.82rem',
|
||
color: '#cbd5e1',
|
||
cursor: 'pointer',
|
||
userSelect: 'none',
|
||
}}>
|
||
<input
|
||
type="checkbox"
|
||
checked={strategyInterests[interest]}
|
||
onChange={e => setStrategyInterests(prev => ({ ...prev, [interest]: e.target.checked }))}
|
||
style={{
|
||
accentColor: '#38bdf8',
|
||
cursor: 'pointer',
|
||
width: '16px',
|
||
height: '16px',
|
||
}}
|
||
/>
|
||
{interest}
|
||
</label>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Cloudflare Turnstile Captcha */}
|
||
<TurnstileCaptcha
|
||
onVerify={token => {
|
||
setStrategyTurnstileToken(token);
|
||
if (strategyErrorMsg) setStrategyErrorMsg('');
|
||
}}
|
||
onExpire={() => setStrategyTurnstileToken('')}
|
||
/>
|
||
|
||
{/* Submit Button */}
|
||
<button
|
||
type="submit"
|
||
disabled={isStrategySubmitting}
|
||
style={{
|
||
marginTop: '0.5rem',
|
||
width: '100%',
|
||
background: '#ffffff',
|
||
color: '#020710',
|
||
border: 'none',
|
||
padding: '0.95rem 1.5rem',
|
||
borderRadius: '50px',
|
||
fontSize: '1.05rem',
|
||
fontWeight: 700,
|
||
cursor: isStrategySubmitting ? 'not-allowed' : 'pointer',
|
||
boxShadow: '0 10px 25px rgba(255, 255, 255, 0.15)',
|
||
transition: 'all 0.3s ease',
|
||
}}
|
||
onMouseEnter={e => {
|
||
if (!isStrategySubmitting) {
|
||
e.currentTarget.style.transform = 'translateY(-2px)';
|
||
e.currentTarget.style.boxShadow = '0 15px 35px rgba(255, 255, 255, 0.3)';
|
||
}
|
||
}}
|
||
onMouseLeave={e => {
|
||
if (!isStrategySubmitting) {
|
||
e.currentTarget.style.transform = 'translateY(0)';
|
||
e.currentTarget.style.boxShadow = '0 10px 25px rgba(255, 255, 255, 0.15)';
|
||
}
|
||
}}
|
||
>
|
||
{isStrategySubmitting ? 'Booking...' : 'Book Session'}
|
||
</button>
|
||
</form>
|
||
) : (
|
||
/* Acknowledgement Panel */
|
||
<div style={{ textAlign: 'center', padding: '1.5rem 0' }}>
|
||
<div style={{
|
||
width: '56px',
|
||
height: '56px',
|
||
borderRadius: '50%',
|
||
background: 'rgba(16, 185, 129, 0.2)',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
margin: '0 auto 1.25rem auto',
|
||
color: '#34d399'
|
||
}}>
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#34d399" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
|
||
<polyline points="20 6 9 17 4 12" />
|
||
</svg>
|
||
</div>
|
||
<h3 style={{
|
||
fontSize: '1.5rem',
|
||
fontWeight: 700,
|
||
marginBottom: '1rem',
|
||
color: '#ffffff',
|
||
letterSpacing: '-0.02em',
|
||
}}>
|
||
Strategy Session Scheduled!
|
||
</h3>
|
||
<p style={{
|
||
fontSize: '0.9rem',
|
||
color: '#cbd5e1',
|
||
lineHeight: '1.6',
|
||
marginBottom: '2rem',
|
||
}}>
|
||
Thank you for booking a Strategy Call. We have successfully received your information and areas of interest. A technology consultant from Cavin Infotech will reach out to you within 24 hours with an invitation link and slot confirmation.
|
||
</p>
|
||
<button
|
||
onClick={() => {
|
||
setIsStrategyOpen(false);
|
||
setShowStrategyAcknowledgement(false);
|
||
setStrategyName('');
|
||
setStrategyEmail('');
|
||
setStrategyMobile('');
|
||
setStrategyDesignation('');
|
||
setStrategyDate('');
|
||
setStrategyTime('');
|
||
setStrategyInterests({
|
||
'AI & Analytics': false,
|
||
'SAP Services': false,
|
||
'XR Platforms': false,
|
||
'Smart Factory': false,
|
||
'Cloud Engineering': false,
|
||
'Enterprise Software': false,
|
||
});
|
||
setStrategyTurnstileToken('');
|
||
}}
|
||
style={{
|
||
background: 'transparent',
|
||
border: '1px solid rgba(255, 255, 255, 0.3)',
|
||
color: '#ffffff',
|
||
padding: '0.6rem 2rem',
|
||
borderRadius: '50px',
|
||
fontSize: '0.88rem',
|
||
fontWeight: 600,
|
||
cursor: 'pointer',
|
||
}}
|
||
>
|
||
Close Window
|
||
</button>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
</div >
|
||
);
|
||
}
|