Update AboutUsPage, server routes, packages, and assets
This commit is contained in:
+169
-144
@@ -8,6 +8,7 @@ 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';
|
||||
|
||||
// Reusable Scroll Reveal Wrapper with Reduced Motion Support
|
||||
function Reveal({ children, delay = 0, style }) {
|
||||
@@ -377,7 +378,9 @@ export default function App({ previewMode = false }) {
|
||||
const [activeSection, setActiveSection] = useState('home');
|
||||
const [currentPage, setCurrentPage] = useState(() => {
|
||||
const hash = typeof window !== 'undefined' ? window.location.hash : '';
|
||||
return hash === '#contact' || hash === '#contactus' ? 'contact' : 'home';
|
||||
if (hash === '#contact' || hash === '#contactus') return 'contact';
|
||||
if (hash === '#about' || hash === '#aboutus') return 'about';
|
||||
return 'home';
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -387,6 +390,10 @@ export default function App({ previewMode = false }) {
|
||||
setCurrentPage('contact');
|
||||
setActiveSection('contactus');
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
} else if (hash === '#about' || hash === '#aboutus') {
|
||||
setCurrentPage('about');
|
||||
setActiveSection('aboutus');
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
} else if (hash === '#home' || hash === '') {
|
||||
setCurrentPage('home');
|
||||
}
|
||||
@@ -481,6 +488,7 @@ export default function App({ previewMode = false }) {
|
||||
|
||||
const getActiveNavItem = () => {
|
||||
if (currentPage === 'contact') return 'Contact Us';
|
||||
if (currentPage === 'about') return 'About Us';
|
||||
switch (activeSection) {
|
||||
case 'home':
|
||||
return 'Home';
|
||||
@@ -560,6 +568,14 @@ export default function App({ previewMode = false }) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item === 'About Us') {
|
||||
setCurrentPage('about');
|
||||
setActiveSection('aboutus');
|
||||
window.location.hash = 'aboutus';
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
return;
|
||||
}
|
||||
|
||||
const sectionMap = {
|
||||
Home: 'home',
|
||||
'About Us': 'aboutus',
|
||||
@@ -820,6 +836,8 @@ export default function App({ previewMode = false }) {
|
||||
)}
|
||||
{currentPage === 'contact' ? (
|
||||
<ContactSection isMobile={isMobile} onOpenStrategy={() => setIsStrategyOpen(true)} />
|
||||
) : currentPage === 'about' ? (
|
||||
<AboutUsPage isMobile={isMobile} onOpenStrategy={() => setIsStrategyOpen(true)} onNavigate={handleNavClick} />
|
||||
) : (
|
||||
<>
|
||||
{/* Main Homepage Content */}
|
||||
@@ -1788,32 +1806,36 @@ export default function App({ previewMode = false }) {
|
||||
{/* Products Suite */}
|
||||
<section id="products" style={{
|
||||
padding: isMobile ? '4rem 1.25rem' : '6rem 4rem',
|
||||
backgroundImage: `url(${assetUrl('/assets/products_bg.svg')})`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
background: 'linear-gradient(180deg, #2791a5 0%, #0f4652 35%, #020710 100%)',
|
||||
position: 'relative',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
{/* Soft gradient from bottom to top: light bottom fading to 0 opacity at top */}
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
background: 'linear-gradient(0deg, #ffffff 0%, rgba(255, 255, 255, 0.85) 45%, rgba(255, 255, 255, 0.25) 75%, rgba(255, 255, 255, 0) 100%)',
|
||||
pointerEvents: 'none',
|
||||
zIndex: 1
|
||||
}} />
|
||||
{/* 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: 800, color: '#0f172a', margin: '0 0 0.4rem 0', letterSpacing: '-0.02em' }}>
|
||||
<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: '#64748b', fontSize: '0.78rem', fontWeight: 500, textTransform: 'uppercase', letterSpacing: '0.08em', display: 'block' }}>
|
||||
<span style={{ color: '#8c9ba5', fontSize: '0.78rem', fontWeight: 500, textTransform: 'uppercase', letterSpacing: '0.08em', display: 'block' }}>
|
||||
{products.eyebrow || 'ONE ECOSYSTEM. EXPONENTIAL IMPACT.'}
|
||||
</span>
|
||||
</div>
|
||||
@@ -1827,7 +1849,7 @@ export default function App({ previewMode = false }) {
|
||||
alignItems: 'stretch',
|
||||
position: 'relative',
|
||||
zIndex: 10,
|
||||
marginBottom: '4rem'
|
||||
marginBottom: '2.5rem'
|
||||
}}>
|
||||
{products.items.map((item, index) => (
|
||||
<ProductCard
|
||||
@@ -1839,6 +1861,56 @@ export default function App({ previewMode = false }) {
|
||||
/>
|
||||
))}
|
||||
</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>
|
||||
|
||||
{/* Bottom CTA Button */}
|
||||
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => scrollToSection('contactus')}
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: '0.6rem',
|
||||
background: 'rgba(255, 255, 255, 0.05)',
|
||||
border: '1.5px solid rgba(255, 255, 255, 0.35)',
|
||||
boxShadow: '0 8px 25px rgba(0, 0, 0, 0.3)',
|
||||
borderRadius: '50px',
|
||||
color: '#ffffff',
|
||||
padding: '0.75rem 2rem',
|
||||
fontSize: '0.92rem',
|
||||
fontWeight: 600,
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.25s ease',
|
||||
backdropFilter: 'blur(10px)'
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.12)';
|
||||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.6)';
|
||||
e.currentTarget.style.transform = 'translateY(-2px)';
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.05)';
|
||||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.35)';
|
||||
e.currentTarget.style.transform = 'translateY(0)';
|
||||
}}
|
||||
>
|
||||
<span>Explore Our Full Product Suite</span>
|
||||
<ArrowRight size={16} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -2069,20 +2141,21 @@ export default function App({ previewMode = false }) {
|
||||
<div style={{
|
||||
background: 'linear-gradient(135deg, #092244 0%, #05162d 100%)',
|
||||
borderRadius: '20px',
|
||||
padding: '2.5rem 1.8rem',
|
||||
padding: '2.2rem 1.6rem',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '2rem',
|
||||
marginBottom: '3rem',
|
||||
gap: '1.2rem',
|
||||
marginBottom: '2.5rem',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
boxShadow: '0 20px 40px rgba(0,0,0,0.2)'
|
||||
boxShadow: '0 20px 40px rgba(0,0,0,0.25)',
|
||||
border: '1px solid rgba(255, 255, 255, 0.08)'
|
||||
}}>
|
||||
<div>
|
||||
<h2 style={{ fontSize: '1.8rem', fontWeight: 500, color: '#ffffff', lineHeight: 1.2, marginBottom: '1rem', letterSpacing: '-0.02em' }}>
|
||||
<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.88rem', fontWeight: 500, lineHeight: 1.55, color: '#cbd5e1', marginBottom: '2rem', textTransform: 'uppercase', letterSpacing: '0.06em' }}>
|
||||
<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' }}>
|
||||
@@ -2098,45 +2171,14 @@ export default function App({ previewMode = false }) {
|
||||
fontSize: '0.88rem',
|
||||
fontWeight: 600,
|
||||
cursor: 'pointer',
|
||||
width: '100%',
|
||||
textAlign: 'center'
|
||||
}}
|
||||
>
|
||||
{footer.cta.primaryButton}
|
||||
</button>
|
||||
{/* Secondary button commented out per user request
|
||||
<button
|
||||
onClick={() => setIsStrategyOpen(true)}
|
||||
style={{
|
||||
background: '#e8f1f8',
|
||||
border: 'none',
|
||||
color: '#2a4a6c',
|
||||
padding: '0.85rem 1.6rem',
|
||||
borderRadius: '50px',
|
||||
fontSize: '0.88rem',
|
||||
fontWeight: 600,
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
{footer.cta.secondaryButton}
|
||||
</button>
|
||||
*/}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Phone mockup container on mobile */}
|
||||
<div style={{ width: '100%', height: '180px', position: 'relative', overflow: 'hidden', borderRadius: '12px' }}>
|
||||
<img
|
||||
src={assetUrl(footer.cta.image)}
|
||||
alt="Phone preview"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: '-20px',
|
||||
top: '-90px',
|
||||
width: '280px',
|
||||
height: 'auto',
|
||||
maxWidth: 'none',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
) : (
|
||||
@@ -2209,34 +2251,6 @@ export default function App({ previewMode = false }) {
|
||||
>
|
||||
{footer.cta.primaryButton}
|
||||
</button>
|
||||
{/* Secondary button commented out per user request
|
||||
<button
|
||||
onClick={() => setIsStrategyOpen(true)}
|
||||
style={{
|
||||
background: '#e8f1f8',
|
||||
border: 'none',
|
||||
color: '#2a4a6c',
|
||||
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.background = '#ffffff';
|
||||
e.currentTarget.style.boxShadow = '0 8px 20px rgba(0, 0, 0, 0.1)';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
e.currentTarget.style.transform = 'translateY(0)';
|
||||
e.currentTarget.style.background = '#e8f1f8';
|
||||
e.currentTarget.style.boxShadow = 'none';
|
||||
}}
|
||||
>
|
||||
{footer.cta.secondaryButton}
|
||||
</button>
|
||||
*/}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2247,20 +2261,20 @@ export default function App({ previewMode = false }) {
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: isMobile ? '1fr 1fr' : '180px 180px 1fr',
|
||||
gap: isMobile ? '1.5rem' : '1.25rem',
|
||||
paddingBottom: '2.5rem',
|
||||
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.7rem', fontWeight: 800, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#1e293b', marginBottom: '1rem' }}>Quick Links</h5>
|
||||
<ul style={{ listStyle: 'none', display: 'flex', flexDirection: 'column', gap: '0.35rem', padding: 0, margin: 0 }}>
|
||||
<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.84rem', transition: 'color 0.2s' }}
|
||||
}} 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>
|
||||
@@ -2268,7 +2282,7 @@ export default function App({ previewMode = false }) {
|
||||
<a href="#certifications" onClick={e => {
|
||||
e.preventDefault();
|
||||
scrollToSection('certifications');
|
||||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.84rem', transition: 'color 0.2s' }}
|
||||
}} 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>
|
||||
@@ -2276,7 +2290,7 @@ export default function App({ previewMode = false }) {
|
||||
<a href="#services" onClick={e => {
|
||||
e.preventDefault();
|
||||
scrollToSection('services');
|
||||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.84rem', transition: 'color 0.2s' }}
|
||||
}} 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>
|
||||
@@ -2285,72 +2299,83 @@ export default function App({ previewMode = false }) {
|
||||
|
||||
{/* Products */}
|
||||
<div>
|
||||
<h5 style={{ fontSize: '0.7rem', fontWeight: 800, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#1e293b', marginBottom: '1rem' }}>Products</h5>
|
||||
<ul style={{ listStyle: 'none', display: 'flex', flexDirection: 'column', gap: '0.35rem', padding: 0, margin: 0 }}>
|
||||
{['PRODMAX', 'Budgie HRMS', 'EVIDO'].map(l => (
|
||||
<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();
|
||||
scrollToSection('products');
|
||||
}} style={{ color: '#475569', textDecoration: 'none', fontSize: '0.84rem', transition: 'color 0.2s' }}
|
||||
}} 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.7rem', fontWeight: 800, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#1e40af', marginBottom: '1rem' }}>Social Links</h5>
|
||||
<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' }}>
|
||||
{[
|
||||
{ label: 'Facebook', d: 'M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z' },
|
||||
{ label: 'Instagram', d: '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' },
|
||||
{ label: 'LinkedIn', d: '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' },
|
||||
{ label: 'Telegram', d: 'M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.562 8.161c-.18.717-.962 4.084-1.362 5.462-.168.58-.506.772-.712.791-.45.041-.79-.297-1.225-.583-.681-.447-1.066-.723-1.727-1.158-.764-.502-.269-.778.167-1.23.114-.118 2.096-1.922 2.134-2.083.005-.02.009-.095-.036-.135-.045-.04-.112-.026-.16-.015-.069.016-1.171.745-3.305 2.186-.313.215-.596.321-.85.315-.281-.006-.822-.153-1.225-.284-.494-.16-.887-.246-.853-.518.178-.142.716-.291 1.6-.447 5.485-2.385 9.143-3.957 10.973-4.717.868-.362 1.8-.425 2.39-.425.13 0 .42.03.606.18.156.126.2.296.21.425.013.167.013.435-.008.685z' },
|
||||
{ label: 'WhatsApp', d: 'M12.008 22c-1.948 0-3.855-.522-5.504-1.508l-.395-.235-4.093 1.073 1.092-3.993-.257-.408C1.815 15.222 1.25 13.064 12.008 12c5.514 0 10.008 4.486 10.008 10S17.522 22 12.008 22zm8.487-18.49C18.232 1.257 15.258 0 12.008 0 5.394 0 .02 5.373.017 11.99c0 2.115.553 4.18 1.603 5.996L0 24l6.155-1.615c1.768.964 3.753 1.472 5.845 1.474v-.002c6.611 0 11.986-5.375 11.99-11.994.002-3.206-1.242-6.22-3.497-8.48zM17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.063 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.715 2.006-1.404.248-.69.248-1.278.173-1.402-.074-.125-.272-.199-.57-.348z' },
|
||||
{ label: 'X', d: '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' },
|
||||
{ label: 'YouTube', d: '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' },
|
||||
].map(({ label, d }) => (
|
||||
<a key={label} href="#" aria-label={label}
|
||||
style={{
|
||||
width: '34px', height: '34px', 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 style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
flexWrap: 'wrap',
|
||||
gap: '1rem',
|
||||
marginTop: '1.5rem',
|
||||
fontSize: '0.82rem',
|
||||
color: '#475569',
|
||||
}}>
|
||||
<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>
|
||||
<span style={{ color: '#cbd5e1' }}>•</span>
|
||||
<span style={{ fontSize: '0.78rem', color: '#334155' }}>
|
||||
Copyrights reserved to CAVIN INFOTECH
|
||||
</span>
|
||||
{(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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user