1135 lines
46 KiB
React
1135 lines
46 KiB
React
import React, { useEffect, useState } from 'react';
|
||
import { ArrowLeft, Clock, Calendar, Share2, ArrowRight, Mail, CheckCircle2, Copy, Check, Send, Tag } from 'lucide-react';
|
||
import { assetUrl } from '../lib/assetUrl';
|
||
|
||
const normalizeTags = (rawTags) => {
|
||
if (!rawTags) return [];
|
||
if (Array.isArray(rawTags)) return rawTags.map(t => String(t).trim()).filter(Boolean);
|
||
if (typeof rawTags === 'string') {
|
||
try {
|
||
const parsed = JSON.parse(rawTags);
|
||
if (Array.isArray(parsed)) return parsed.map(t => String(t).trim()).filter(Boolean);
|
||
} catch {}
|
||
return rawTags.split(',').map(t => t.trim()).filter(Boolean);
|
||
}
|
||
return [];
|
||
};
|
||
|
||
export default function BlogDetailPage({ blog, allBlogs = [], isMobile, onNavigate, onSelectBlog }) {
|
||
const [newsletterEmail, setNewsletterEmail] = useState('');
|
||
const [newsletterSubmitted, setNewsletterSubmitted] = useState(false);
|
||
const [copied, setCopied] = useState(false);
|
||
|
||
useEffect(() => {
|
||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||
}, [blog?.id || blog?.slug]);
|
||
|
||
useEffect(() => {
|
||
if (!blog) return;
|
||
|
||
const prevTitle = document.title;
|
||
const pageTitle = blog.metaTitle || `${blog.title} | Cavin Infotech`;
|
||
document.title = pageTitle;
|
||
|
||
const metaDesc = blog.metaDescription || blog.excerpt || '';
|
||
const tagList = normalizeTags(blog.tags);
|
||
const metaKeywords = blog.keywords || tagList.join(', ');
|
||
|
||
const setMetaTag = (name, content, attr = 'name') => {
|
||
if (!content) return;
|
||
let el = document.querySelector(`meta[${attr}="${name}"]`);
|
||
if (!el) {
|
||
el = document.createElement('meta');
|
||
el.setAttribute(attr, name);
|
||
document.head.appendChild(el);
|
||
}
|
||
el.setAttribute('content', content);
|
||
};
|
||
|
||
setMetaTag('description', metaDesc);
|
||
setMetaTag('keywords', metaKeywords);
|
||
setMetaTag('og:title', pageTitle, 'property');
|
||
setMetaTag('og:description', metaDesc, 'property');
|
||
setMetaTag('og:type', 'article', 'property');
|
||
setMetaTag('og:url', window.location.href, 'property');
|
||
if (blog.ogImage || blog.coverImage || blog.image) {
|
||
setMetaTag('og:image', assetUrl(blog.ogImage || blog.coverImage || blog.image), 'property');
|
||
}
|
||
setMetaTag('twitter:card', 'summary_large_image');
|
||
setMetaTag('twitter:title', pageTitle);
|
||
setMetaTag('twitter:description', metaDesc);
|
||
|
||
let canonical = document.querySelector('link[rel="canonical"]');
|
||
if (!canonical) {
|
||
canonical = document.createElement('link');
|
||
canonical.setAttribute('rel', 'canonical');
|
||
document.head.appendChild(canonical);
|
||
}
|
||
canonical.setAttribute('href', blog.canonicalURL || window.location.href);
|
||
|
||
let scriptTag = document.getElementById('json-ld-article-schema');
|
||
if (!scriptTag) {
|
||
scriptTag = document.createElement('script');
|
||
scriptTag.id = 'json-ld-article-schema';
|
||
scriptTag.type = 'application/ld+json';
|
||
document.head.appendChild(scriptTag);
|
||
}
|
||
const jsonLdData = {
|
||
'@context': 'https://schema.org',
|
||
'@type': 'BlogPosting',
|
||
'headline': blog.title,
|
||
'description': metaDesc,
|
||
'image': assetUrl(blog.ogImage || blog.coverImage || blog.image || '/assets/cavin_logo.svg'),
|
||
'datePublished': blog.publishDate || blog.date || new Date().toISOString(),
|
||
'author': {
|
||
'@type': 'Person',
|
||
'name': blog.author || 'Cavin Infotech',
|
||
'jobTitle': blog.authorDesignation || ''
|
||
},
|
||
'publisher': {
|
||
'@type': 'Organization',
|
||
'name': 'Cavin Infotech',
|
||
'logo': {
|
||
'@type': 'ImageObject',
|
||
'url': window.location.origin + assetUrl('/assets/cavin_logo.svg')
|
||
}
|
||
},
|
||
'mainEntityOfPage': {
|
||
'@type': 'WebPage',
|
||
'@id': blog.canonicalURL || window.location.href
|
||
},
|
||
'keywords': metaKeywords
|
||
};
|
||
scriptTag.textContent = JSON.stringify(jsonLdData);
|
||
|
||
return () => {
|
||
document.title = prevTitle;
|
||
if (scriptTag) scriptTag.remove();
|
||
};
|
||
}, [blog]);
|
||
|
||
if (!blog) {
|
||
return (
|
||
<div style={{
|
||
background: '#020611',
|
||
color: '#ffffff',
|
||
minHeight: '100vh',
|
||
paddingTop: '8rem',
|
||
textAlign: 'center',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
alignItems: 'center',
|
||
justifyContent: 'center'
|
||
}}>
|
||
<h2 style={{ fontSize: '2rem', fontWeight: 700, marginBottom: '1rem' }}>Article Not Found</h2>
|
||
<p style={{ color: '#94a3b8', marginBottom: '2rem' }}>The requested publication could not be loaded.</p>
|
||
<button
|
||
onClick={() => onNavigate('Blogs')}
|
||
style={{
|
||
background: 'linear-gradient(135deg, #ffaa00 0%, #ff8800 100%)',
|
||
color: '#000000',
|
||
border: 'none',
|
||
padding: '0.8rem 2rem',
|
||
borderRadius: '50px',
|
||
fontWeight: 700,
|
||
cursor: 'pointer',
|
||
boxShadow: '0 4px 20px rgba(255, 170, 0, 0.3)'
|
||
}}
|
||
>
|
||
Return to Blogs
|
||
</button>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
const bgPatternUrl = assetUrl('/assets/Background pattern About Us Hero section.svg');
|
||
const spotlightUrl = assetUrl('/assets/Spotlight vector.svg');
|
||
|
||
const authorName = (typeof blog.authorName === 'string' && blog.authorName.trim())
|
||
? blog.authorName.trim()
|
||
: (typeof blog.author === 'string' && blog.author.trim()
|
||
? blog.author.trim()
|
||
: (blog.author?.firstname ? `${blog.author.firstname} ${blog.author.lastname || ''}`.trim() : 'Cavin Editorial Team'));
|
||
const authorRole = typeof blog.authorDesignation === 'string' ? blog.authorDesignation : 'Chief AI Architect & Head of Data Engineering';
|
||
const authorAvatar = '/assets/arvindh_agentic_ai.jpg';
|
||
const relatedArticles = allBlogs.filter(b => b.id !== blog.id).slice(0, 2);
|
||
|
||
const handleNewsletterSubmit = (e) => {
|
||
e.preventDefault();
|
||
if (newsletterEmail) {
|
||
setNewsletterSubmitted(true);
|
||
setTimeout(() => {
|
||
setNewsletterSubmitted(false);
|
||
setNewsletterEmail('');
|
||
}, 5000);
|
||
}
|
||
};
|
||
|
||
const handleCopyLink = () => {
|
||
navigator.clipboard.writeText(window.location.href);
|
||
setCopied(true);
|
||
setTimeout(() => setCopied(false), 2500);
|
||
};
|
||
|
||
const handleSocialShare = (platform) => {
|
||
const url = encodeURIComponent(window.location.href);
|
||
const text = encodeURIComponent(blog.title);
|
||
let shareUrl = '';
|
||
if (platform === 'twitter') {
|
||
shareUrl = `https://twitter.com/intent/tweet?url=${url}&text=${text}`;
|
||
} else if (platform === 'facebook') {
|
||
shareUrl = `https://www.facebook.com/sharer/sharer.php?u=${url}`;
|
||
} else if (platform === 'linkedin') {
|
||
shareUrl = `https://www.linkedin.com/sharing/share-offsite/?url=${url}`;
|
||
}
|
||
if (shareUrl) window.open(shareUrl, '_blank', 'noopener,noreferrer');
|
||
};
|
||
|
||
return (
|
||
<div style={{
|
||
background: '#020611',
|
||
color: '#ffffff',
|
||
minHeight: '100vh',
|
||
position: 'relative',
|
||
overflow: 'hidden',
|
||
paddingTop: isMobile ? '5.5rem' : '7rem',
|
||
paddingBottom: '6rem'
|
||
}}>
|
||
{/* Background Pattern SVG Overlay - Fixed Hero Height Only */}
|
||
<div
|
||
style={{
|
||
position: 'absolute',
|
||
top: 0,
|
||
left: 0,
|
||
right: 0,
|
||
height: isMobile ? '450px' : '580px',
|
||
backgroundImage: `url('${bgPatternUrl}')`,
|
||
backgroundSize: 'cover',
|
||
backgroundPosition: 'center top',
|
||
opacity: 0.85,
|
||
pointerEvents: 'none',
|
||
zIndex: 0,
|
||
WebkitMaskImage: 'linear-gradient(to bottom, rgba(0,0,0,1) 60%, rgba(0,0,0,0) 100%)',
|
||
maskImage: 'linear-gradient(to bottom, rgba(0,0,0,1) 60%, rgba(0,0,0,0) 100%)',
|
||
}}
|
||
/>
|
||
|
||
{/* Spotlight Vector SVG at Top-Left Corner - Fixed Hero Height Only */}
|
||
<div
|
||
style={{
|
||
position: 'absolute',
|
||
top: 0,
|
||
left: 0,
|
||
width: isMobile ? '100%' : '85%',
|
||
height: isMobile ? '450px' : '580px',
|
||
maxWidth: '1250px',
|
||
backgroundImage: `url('${spotlightUrl}')`,
|
||
backgroundSize: 'contain',
|
||
backgroundRepeat: 'no-repeat',
|
||
backgroundPosition: 'top left',
|
||
pointerEvents: 'none',
|
||
zIndex: 1,
|
||
mixBlendMode: 'screen',
|
||
opacity: 0.85,
|
||
WebkitMaskImage: 'linear-gradient(to bottom, rgba(0,0,0,1) 60%, rgba(0,0,0,0) 100%)',
|
||
maskImage: 'linear-gradient(to bottom, rgba(0,0,0,1) 60%, rgba(0,0,0,0) 100%)',
|
||
}}
|
||
/>
|
||
|
||
{/* Main Content Container */}
|
||
<div style={{
|
||
position: 'relative',
|
||
zIndex: 2,
|
||
maxWidth: '1140px',
|
||
margin: '0 auto',
|
||
padding: isMobile ? '0 1.25rem' : '0 2.5rem'
|
||
}}>
|
||
|
||
{/* Top Breadcrumbs & Back Button */}
|
||
<div style={{
|
||
display: 'flex',
|
||
justifyContent: 'space-between',
|
||
alignItems: 'center',
|
||
marginBottom: '2rem',
|
||
flexWrap: 'wrap',
|
||
gap: '1rem'
|
||
}}>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', fontSize: '0.85rem', color: '#64748b' }}>
|
||
<span style={{ cursor: 'pointer', transition: 'color 0.2s' }} onClick={() => onNavigate('Home')}>Home</span>
|
||
<span>/</span>
|
||
<span style={{ cursor: 'pointer', transition: 'color 0.2s' }} onClick={() => onNavigate('Blogs')}>Blogs</span>
|
||
<span>/</span>
|
||
<span style={{ color: '#38bdf8', fontWeight: 600, maxWidth: isMobile ? '160px' : '320px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
||
{blog.title}
|
||
</span>
|
||
</div>
|
||
|
||
<button
|
||
onClick={() => onNavigate('Blogs')}
|
||
style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '0.45rem',
|
||
background: 'rgba(255, 255, 255, 0.05)',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
color: '#ffffff',
|
||
padding: '0.45rem 1.1rem',
|
||
borderRadius: '50px',
|
||
fontSize: '0.82rem',
|
||
fontWeight: 600,
|
||
cursor: 'pointer',
|
||
transition: 'all 0.2s ease'
|
||
}}
|
||
onMouseEnter={e => { e.currentTarget.style.borderColor = '#38bdf8'; e.currentTarget.style.color = '#38bdf8'; }}
|
||
onMouseLeave={e => { e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.12)'; e.currentTarget.style.color = '#ffffff'; }}
|
||
>
|
||
<ArrowLeft size={14} /> Back to Blogs
|
||
</button>
|
||
</div>
|
||
|
||
{/* HERO DESIGN SECTION */}
|
||
<div style={{ marginBottom: '1.75rem' }}>
|
||
{/* Combined Category & Read Time Pill Badge */}
|
||
<div style={{ marginBottom: '1.25rem' }}>
|
||
<div style={{
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
gap: '0.65rem',
|
||
background: 'rgba(56, 189, 248, 0.08)',
|
||
border: '1px solid rgba(56, 189, 248, 0.45)',
|
||
borderRadius: '50px',
|
||
padding: '0.35rem 1rem',
|
||
boxShadow: '0 2px 14px rgba(56, 189, 248, 0.12)'
|
||
}}>
|
||
<span style={{
|
||
color: '#38bdf8',
|
||
fontSize: '0.8rem',
|
||
fontWeight: 600,
|
||
letterSpacing: '0.02em'
|
||
}}>
|
||
{blog.category || 'Leadership'}
|
||
</span>
|
||
<span style={{ color: 'rgba(255, 255, 255, 0.3)', fontSize: '0.75rem' }}>•</span>
|
||
<span style={{
|
||
color: '#7dd3fc',
|
||
fontSize: '0.8rem',
|
||
fontWeight: 500
|
||
}}>
|
||
{blog.readTime || '8 min read'}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Title */}
|
||
<h1 style={{
|
||
fontSize: isMobile ? '2.1rem' : '3.1rem',
|
||
fontWeight: 700,
|
||
color: '#ffffff',
|
||
lineHeight: 1.22,
|
||
letterSpacing: '-0.02em',
|
||
marginBottom: '1rem'
|
||
}}>
|
||
{blog.title}
|
||
</h1>
|
||
|
||
{/* Subtitle / Excerpt */}
|
||
{(blog.subtitle || blog.excerpt) && (
|
||
<p style={{
|
||
fontSize: isMobile ? '1.02rem' : '1.15rem',
|
||
color: '#94a3b8',
|
||
lineHeight: 1.6,
|
||
maxWidth: '860px',
|
||
marginBottom: '2.5rem',
|
||
fontWeight: 400
|
||
}}>
|
||
{blog.subtitle || blog.excerpt}
|
||
</p>
|
||
)}
|
||
</div>
|
||
|
||
{/* HERO FEATURED IMAGE */}
|
||
{(blog.image || blog.coverImage || blog.ogImage) && (
|
||
<div style={{
|
||
width: '100%',
|
||
height: isMobile ? '250px' : '520px',
|
||
borderRadius: '20px',
|
||
overflow: 'hidden',
|
||
position: 'relative',
|
||
marginBottom: '1.75rem',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
boxShadow: '0 25px 60px rgba(0, 0, 0, 0.75)'
|
||
}}>
|
||
<img
|
||
src={assetUrl(blog.image || blog.coverImage || blog.ogImage)}
|
||
alt={blog.title}
|
||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||
onError={(e) => {
|
||
const titleLower = (blog.title || '').toLowerCase();
|
||
const catLower = (blog.category || '').toLowerCase();
|
||
let fallback = '/assets/arvindh_agentic_ai.jpg';
|
||
if (titleLower.includes('llm')) fallback = '/assets/arvindh_llm_financial.jpg';
|
||
else if (titleLower.includes('supply chain')) fallback = '/assets/arvindh_supply_chain.jpg';
|
||
else if (titleLower.includes('prodmax')) fallback = '/assets/prodmax_dashboard.png';
|
||
else if (titleLower.includes('vr') || titleLower.includes('incidents')) fallback = '/assets/whyus_vr_man.jpg';
|
||
else if (titleLower.includes('scada') || titleLower.includes('plc') || titleLower.includes('speed vs')) fallback = '/assets/arvindh_agentic_ai.jpg';
|
||
else if (catLower.includes('ai')) fallback = '/assets/arvindh_agentic_ai.jpg';
|
||
const resolvedFallback = assetUrl(fallback);
|
||
if (e.currentTarget.src !== resolvedFallback) {
|
||
e.currentTarget.src = resolvedFallback;
|
||
}
|
||
}}
|
||
/>
|
||
</div>
|
||
)}
|
||
|
||
{/* METADATA & ACTION BAR UNDER FEATURED IMAGE */}
|
||
<div style={{
|
||
display: 'flex',
|
||
justifyContent: 'space-between',
|
||
alignItems: 'center',
|
||
marginBottom: '3.5rem',
|
||
flexWrap: 'wrap',
|
||
gap: '1.5rem',
|
||
paddingTop: '0.5rem',
|
||
paddingBottom: '1.5rem',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.08)'
|
||
}}>
|
||
{/* Written by & Published on */}
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: isMobile ? '1.75rem' : '3.5rem', flexWrap: 'wrap' }}>
|
||
<div>
|
||
<div style={{ fontSize: '0.78rem', color: '#94a3b8', marginBottom: '0.2rem', fontWeight: 500 }}>
|
||
Written by
|
||
</div>
|
||
<div style={{ fontSize: '0.98rem', color: '#ffffff', fontWeight: 700 }}>
|
||
{authorName}
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div style={{ fontSize: '0.78rem', color: '#94a3b8', marginBottom: '0.2rem', fontWeight: 500 }}>
|
||
Published on
|
||
</div>
|
||
<div style={{ fontSize: '0.98rem', color: '#ffffff', fontWeight: 700 }}>
|
||
{blog.date || '11 Jul 2026'}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Social Share & Action Icons */}
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.65rem', flexWrap: 'wrap' }}>
|
||
<button
|
||
onClick={handleCopyLink}
|
||
style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '0.45rem',
|
||
background: 'rgba(255, 255, 255, 0.05)',
|
||
border: '1px solid rgba(255, 255, 255, 0.15)',
|
||
color: '#ffffff',
|
||
padding: '0.5rem 0.95rem',
|
||
borderRadius: '8px',
|
||
fontSize: '0.82rem',
|
||
fontWeight: 500,
|
||
cursor: 'pointer',
|
||
transition: 'all 0.2s ease'
|
||
}}
|
||
onMouseEnter={e => { e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.3)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.08)'; }}
|
||
onMouseLeave={e => { e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.15)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.05)'; }}
|
||
>
|
||
{copied ? <Check size={14} style={{ color: '#10b981' }} /> : <Copy size={14} />}
|
||
{copied ? 'Copied!' : 'Copy link'}
|
||
</button>
|
||
|
||
{/* X / Twitter */}
|
||
<button
|
||
onClick={() => handleSocialShare('twitter')}
|
||
title="Share on X"
|
||
style={{
|
||
width: '36px',
|
||
height: '36px',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
background: 'rgba(255, 255, 255, 0.05)',
|
||
border: '1px solid rgba(255, 255, 255, 0.15)',
|
||
borderRadius: '8px',
|
||
color: '#ffffff',
|
||
fontSize: '0.85rem',
|
||
fontWeight: 700,
|
||
cursor: 'pointer',
|
||
transition: 'all 0.2s ease'
|
||
}}
|
||
onMouseEnter={e => { e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.3)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.08)'; }}
|
||
onMouseLeave={e => { e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.15)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.05)'; }}
|
||
>
|
||
𝕏
|
||
</button>
|
||
|
||
{/* Facebook */}
|
||
<button
|
||
onClick={() => handleSocialShare('facebook')}
|
||
title="Share on Facebook"
|
||
style={{
|
||
width: '36px',
|
||
height: '36px',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
background: 'rgba(255, 255, 255, 0.05)',
|
||
border: '1px solid rgba(255, 255, 255, 0.15)',
|
||
borderRadius: '8px',
|
||
color: '#ffffff',
|
||
cursor: 'pointer',
|
||
transition: 'all 0.2s ease'
|
||
}}
|
||
onMouseEnter={e => { e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.3)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.08)'; }}
|
||
onMouseLeave={e => { e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.15)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.05)'; }}
|
||
>
|
||
<svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>
|
||
</svg>
|
||
</button>
|
||
|
||
{/* LinkedIn */}
|
||
<button
|
||
onClick={() => handleSocialShare('linkedin')}
|
||
title="Share on LinkedIn"
|
||
style={{
|
||
width: '36px',
|
||
height: '36px',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
background: 'rgba(255, 255, 255, 0.05)',
|
||
border: '1px solid rgba(255, 255, 255, 0.15)',
|
||
borderRadius: '8px',
|
||
color: '#ffffff',
|
||
cursor: 'pointer',
|
||
transition: 'all 0.2s ease'
|
||
}}
|
||
onMouseEnter={e => { e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.3)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.08)'; }}
|
||
onMouseLeave={e => { e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.15)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.05)'; }}
|
||
>
|
||
<svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M19 3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14m-.5 15.5v-5.3a3.26 3.26 0 0 0-3.26-3.26c-.85 0-1.84.52-2.28 1.3v-1.11h-2.79v8.37h2.79v-4.93c0-0.77.62-1.4 1.39-1.4a1.4 1.4 0 0 1 1.4 1.4v4.93h2.75M6.46 10.9v8.37H9.25V10.9H6.46M7.86 6.74a1.65 1.65 0 0 0-1.66 1.66 1.66 1.66 0 0 0 1.66 1.65c.92 0 1.66-.74 1.66-1.65a1.65 1.65 0 0 0-1.66-1.66z"/>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* TWO COLUMN ARTICLE CONTENT LAYOUT */}
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: isMobile ? '1fr' : '1fr 320px',
|
||
gap: '3.5rem',
|
||
alignItems: 'start',
|
||
marginBottom: '5rem'
|
||
}}>
|
||
|
||
{/* MAIN ARTICLE COLUMN */}
|
||
<div>
|
||
{/* Lead Excerpt Quote Block */}
|
||
{blog.excerpt && (
|
||
<div style={{
|
||
background: 'linear-gradient(135deg, rgba(27, 54, 93, 0.3) 0%, rgba(13, 17, 26, 0.75) 100%)',
|
||
borderLeft: '4px solid #1b365d',
|
||
borderRadius: '0 16px 16px 0',
|
||
padding: isMobile ? '1.25rem 1.5rem' : '1.75rem 2rem',
|
||
color: '#ffffff',
|
||
fontSize: '1.15rem',
|
||
lineHeight: 1.65,
|
||
fontWeight: 500,
|
||
marginBottom: '2.5rem',
|
||
fontStyle: 'italic',
|
||
boxShadow: '0 10px 30px rgba(0,0,0,0.4)'
|
||
}}>
|
||
"{blog.excerpt}"
|
||
</div>
|
||
)}
|
||
|
||
{/* Article Content Body */}
|
||
<div style={{
|
||
color: '#cbd5e1',
|
||
fontSize: '1.05rem',
|
||
lineHeight: 1.85,
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: '1.5rem'
|
||
}}>
|
||
{(blog.content || blog.excerpt || '')
|
||
.replace(/(!\[.*?\]\(.*?\))/g, '\n\n$1\n\n')
|
||
.split(/\n\s*\n/)
|
||
.map(b => b.trim())
|
||
.filter(Boolean)
|
||
.map((block, idx) => {
|
||
if (block.startsWith('# ')) {
|
||
return (
|
||
<h1 key={idx} style={{
|
||
fontSize: isMobile ? '1.8rem' : '2.2rem',
|
||
fontWeight: 800,
|
||
color: '#ffffff',
|
||
marginTop: '2rem',
|
||
marginBottom: '0.75rem',
|
||
letterSpacing: '-0.02em',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.12)',
|
||
paddingBottom: '0.75rem'
|
||
}}>
|
||
{block.replace('# ', '')}
|
||
</h1>
|
||
);
|
||
}
|
||
if (block.startsWith('## ')) {
|
||
return (
|
||
<h2 key={idx} style={{
|
||
fontSize: isMobile ? '1.5rem' : '1.75rem',
|
||
fontWeight: 700,
|
||
color: '#ffffff',
|
||
marginTop: '1.75rem',
|
||
marginBottom: '0.5rem',
|
||
letterSpacing: '-0.01em',
|
||
borderBottom: '1px solid rgba(255, 255, 255, 0.08)',
|
||
paddingBottom: '0.65rem'
|
||
}}>
|
||
{block.replace('## ', '')}
|
||
</h2>
|
||
);
|
||
}
|
||
if (block.startsWith('### ')) {
|
||
return (
|
||
<h3 key={idx} style={{
|
||
fontSize: '1.35rem',
|
||
fontWeight: 700,
|
||
color: '#38bdf8',
|
||
marginTop: '1.35rem',
|
||
marginBottom: '0.35rem'
|
||
}}>
|
||
{block.replace('### ', '')}
|
||
</h3>
|
||
);
|
||
}
|
||
if (block.startsWith('#### ')) {
|
||
return (
|
||
<h4 key={idx} style={{
|
||
fontSize: '1.15rem',
|
||
fontWeight: 600,
|
||
color: '#7dd3fc',
|
||
marginTop: '1.1rem',
|
||
marginBottom: '0.3rem'
|
||
}}>
|
||
{block.replace('#### ', '')}
|
||
</h4>
|
||
);
|
||
}
|
||
if (block.startsWith('> ')) {
|
||
return (
|
||
<blockquote key={idx} style={{
|
||
borderLeft: '4px solid #38bdf8',
|
||
background: 'rgba(56, 189, 248, 0.05)',
|
||
margin: '1rem 0',
|
||
padding: '1rem 1.5rem',
|
||
borderRadius: '0 12px 12px 0',
|
||
fontStyle: 'italic',
|
||
color: '#e2e8f0'
|
||
}}>
|
||
{block.replace('> ', '')}
|
||
</blockquote>
|
||
);
|
||
}
|
||
if (block.startsWith('- ') || block.startsWith('* ')) {
|
||
const items = block.split('\n');
|
||
return (
|
||
<ul key={idx} style={{ paddingLeft: '0.5rem', margin: '0.5rem 0', display: 'flex', flexDirection: 'column', gap: '0.6rem' }}>
|
||
{items.map((item, itemIdx) => {
|
||
const itemText = item.replace(/^[-*]\s+/, '');
|
||
return (
|
||
<li key={itemIdx} style={{ display: 'flex', alignItems: 'flex-start', gap: '0.75rem', listStyle: 'none' }}>
|
||
<CheckCircle2 size={18} style={{ color: '#38bdf8', marginTop: '0.25rem', flexShrink: 0 }} />
|
||
<span>{itemText}</span>
|
||
</li>
|
||
);
|
||
})}
|
||
</ul>
|
||
);
|
||
}
|
||
if (/^\d+\.\s/.test(block)) {
|
||
const items = block.split('\n');
|
||
return (
|
||
<ol key={idx} style={{ paddingLeft: '1.25rem', margin: '0.5rem 0', display: 'flex', flexDirection: 'column', gap: '0.6rem' }}>
|
||
{items.map((item, itemIdx) => {
|
||
const itemText = item.replace(/^\d+\.\s+/, '');
|
||
return (
|
||
<li key={itemIdx} style={{ color: '#cbd5e1' }}>
|
||
<span>{itemText}</span>
|
||
</li>
|
||
);
|
||
})}
|
||
</ol>
|
||
);
|
||
}
|
||
const mdImgMatch = block.match(/!\[(.*?)\]\((.*?)\)/);
|
||
const htmlImgMatch = block.match(/<img[^>]+src=["']([^"']+)["'][^>]*>/i);
|
||
if (mdImgMatch || htmlImgMatch) {
|
||
const caption = mdImgMatch ? (mdImgMatch[1] ? mdImgMatch[1].trim() : '') : '';
|
||
const rawImgUrl = mdImgMatch ? mdImgMatch[2] : htmlImgMatch[1];
|
||
const resolvedSrc = assetUrl(rawImgUrl);
|
||
const isFilename = caption && /\.(jpg|jpeg|png|gif|webp|svg|bmp)$/i.test(caption);
|
||
const displayCaption = caption && !isFilename ? caption : null;
|
||
|
||
return (
|
||
<figure key={idx} style={{ margin: '2rem 0', width: '100%' }}>
|
||
<img
|
||
src={resolvedSrc}
|
||
alt={displayCaption || 'Blog content image'}
|
||
style={{
|
||
width: '100%',
|
||
maxHeight: '520px',
|
||
objectFit: 'cover',
|
||
borderRadius: '18px',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
boxShadow: '0 15px 35px rgba(0,0,0,0.5)'
|
||
}}
|
||
onError={(e) => {
|
||
if (rawImgUrl && rawImgUrl.includes('/uploads/')) {
|
||
const uploadPath = rawImgUrl.substring(rawImgUrl.indexOf('/uploads/'));
|
||
const fallback = assetUrl(uploadPath);
|
||
if (e.currentTarget.src !== fallback) {
|
||
e.currentTarget.src = fallback;
|
||
}
|
||
}
|
||
}}
|
||
/>
|
||
{displayCaption && (
|
||
<figcaption style={{
|
||
fontSize: '0.85rem',
|
||
color: '#94a3b8',
|
||
marginTop: '0.6rem',
|
||
textAlign: 'center',
|
||
fontStyle: 'italic'
|
||
}}>
|
||
{displayCaption}
|
||
</figcaption>
|
||
)}
|
||
</figure>
|
||
);
|
||
}
|
||
return <p key={idx} style={{ margin: 0 }}>{block}</p>;
|
||
})}
|
||
</div>
|
||
|
||
{/* TAG BADGES SECTION */}
|
||
{normalizeTags(blog.tags).length > 0 && (
|
||
<div style={{
|
||
marginTop: '2.5rem',
|
||
paddingTop: '1.5rem',
|
||
borderTop: '1px solid rgba(255, 255, 255, 0.08)',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '0.75rem',
|
||
flexWrap: 'wrap'
|
||
}}>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', color: '#94a3b8', fontSize: '0.85rem', fontWeight: 600 }}>
|
||
<Tag size={15} style={{ color: '#38bdf8' }} /> Tags:
|
||
</div>
|
||
{normalizeTags(blog.tags).map((tag, tagIdx) => (
|
||
<span
|
||
key={tagIdx}
|
||
style={{
|
||
background: 'rgba(56, 189, 248, 0.08)',
|
||
border: '1px solid rgba(56, 189, 248, 0.25)',
|
||
color: '#38bdf8',
|
||
padding: '0.3rem 0.85rem',
|
||
borderRadius: '50px',
|
||
fontSize: '0.8rem',
|
||
fontWeight: 500,
|
||
letterSpacing: '0.01em',
|
||
transition: 'all 0.2s ease',
|
||
cursor: 'pointer'
|
||
}}
|
||
onMouseEnter={e => {
|
||
e.currentTarget.style.background = 'rgba(56, 189, 248, 0.18)';
|
||
e.currentTarget.style.borderColor = 'rgba(56, 189, 248, 0.5)';
|
||
}}
|
||
onMouseLeave={e => {
|
||
e.currentTarget.style.background = 'rgba(56, 189, 248, 0.08)';
|
||
e.currentTarget.style.borderColor = 'rgba(56, 189, 248, 0.25)';
|
||
}}
|
||
>
|
||
#{tag}
|
||
</span>
|
||
))}
|
||
</div>
|
||
)}
|
||
|
||
{/* AUTHOR SECTION - MATCHING MOCKUP DESIGN EXACTLY */}
|
||
<div style={{
|
||
borderLeft: '1.5px solid #ffffff',
|
||
paddingLeft: '1.75rem',
|
||
marginTop: '4rem',
|
||
marginBottom: '2rem'
|
||
}}>
|
||
{/* Italic Author Bio Paragraph */}
|
||
<p style={{
|
||
fontStyle: 'italic',
|
||
color: '#ffffff',
|
||
fontSize: isMobile ? '1.02rem' : '1.12rem',
|
||
lineHeight: 1.7,
|
||
fontWeight: 400,
|
||
margin: 0
|
||
}}>
|
||
{blog.authorBio || `${authorName} is ${authorRole} at CAVIN INFOTECH FZE, a Dubai-based technology company delivering AR/VR experiences, AI solutions, and digital transformation for real estate and enterprises across the UAE and beyond. Connect with us to explore a smarter way to sell.`}
|
||
</p>
|
||
|
||
{/* Author Profile Row */}
|
||
<div style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '0.85rem',
|
||
marginTop: '1.75rem'
|
||
}}>
|
||
<img
|
||
src={assetUrl(blog.authorAvatar || authorAvatar)}
|
||
alt={authorName}
|
||
style={{
|
||
width: '44px',
|
||
height: '44px',
|
||
borderRadius: '50%',
|
||
objectFit: 'cover',
|
||
border: '1px solid rgba(255, 255, 255, 0.2)',
|
||
flexShrink: 0
|
||
}}
|
||
/>
|
||
<div>
|
||
<div style={{ fontSize: '0.98rem', fontWeight: 700, color: '#ffffff', lineHeight: 1.3 }}>
|
||
{authorName}
|
||
</div>
|
||
<div style={{ fontSize: '0.85rem', color: '#94a3b8', fontWeight: 400, marginTop: '0.15rem' }}>
|
||
{authorRole}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* RIGHT SIDEBAR */}
|
||
<div style={{
|
||
position: isMobile ? 'relative' : 'sticky',
|
||
top: '100px'
|
||
}}>
|
||
{/* Weekly Newsletter Subscription Card */}
|
||
<div style={{
|
||
background: '#0d111a',
|
||
border: '1px solid rgba(255, 255, 255, 0.08)',
|
||
borderRadius: '20px',
|
||
padding: '2.25rem 1.75rem',
|
||
boxShadow: '0 20px 50px rgba(0, 0, 0, 0.6)',
|
||
position: 'relative',
|
||
overflow: 'hidden'
|
||
}}>
|
||
{/* Paperplane Icon Container */}
|
||
<div style={{
|
||
width: '44px',
|
||
height: '44px',
|
||
borderRadius: '12px',
|
||
background: 'rgba(255, 255, 255, 0.03)',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
color: '#ffffff',
|
||
marginBottom: '1.5rem'
|
||
}}>
|
||
<Send size={18} style={{ transform: 'rotate(-25deg)', transformOrigin: 'center' }} />
|
||
</div>
|
||
|
||
{/* Title */}
|
||
<h3 style={{
|
||
fontSize: '1.25rem',
|
||
fontWeight: 700,
|
||
color: '#ffffff',
|
||
marginBottom: '0.65rem',
|
||
letterSpacing: '-0.01em'
|
||
}}>
|
||
Weekly newsletter
|
||
</h3>
|
||
|
||
{/* Description */}
|
||
<p style={{
|
||
fontSize: '0.92rem',
|
||
color: '#94a3b8',
|
||
lineHeight: 1.55,
|
||
marginBottom: '1.5rem'
|
||
}}>
|
||
No spam. Just the latest releases and tips, interesting articles, and exclusive interviews in your inbox every week.
|
||
</p>
|
||
|
||
{!newsletterSubmitted ? (
|
||
<form onSubmit={handleNewsletterSubmit} style={{ display: 'flex', flexDirection: 'column' }}>
|
||
{/* Email Input */}
|
||
<input
|
||
type="email"
|
||
required
|
||
placeholder="Enter your email"
|
||
value={newsletterEmail}
|
||
onChange={(e) => setNewsletterEmail(e.target.value)}
|
||
style={{
|
||
width: '100%',
|
||
background: 'rgba(255, 255, 255, 0.03)',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
borderRadius: '10px',
|
||
padding: '0.8rem 1rem',
|
||
color: '#ffffff',
|
||
fontSize: '0.92rem',
|
||
outline: 'none',
|
||
boxSizing: 'border-box',
|
||
transition: 'border-color 0.2s ease'
|
||
}}
|
||
onFocus={e => e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.3)'}
|
||
onBlur={e => e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.12)'}
|
||
/>
|
||
|
||
{/* Privacy Policy text */}
|
||
<div style={{
|
||
fontSize: '0.82rem',
|
||
color: '#64748b',
|
||
marginTop: '0.55rem',
|
||
marginBottom: '1.5rem'
|
||
}}>
|
||
Read about our <a href="#privacy" onClick={(e) => e.preventDefault()} style={{ color: '#94a3b8', textDecoration: 'underline', cursor: 'pointer' }}>privacy policy</a>.
|
||
</div>
|
||
|
||
{/* Subscribe Button */}
|
||
<button
|
||
type="submit"
|
||
style={{
|
||
width: '100%',
|
||
background: 'linear-gradient(180deg, #1b365d 0%, #132847 100%)',
|
||
border: '1px solid rgba(255, 255, 255, 0.08)',
|
||
color: '#ffffff',
|
||
padding: '0.85rem 1.25rem',
|
||
borderRadius: '50px',
|
||
fontSize: '0.98rem',
|
||
fontWeight: 700,
|
||
cursor: 'pointer',
|
||
boxShadow: '0 4px 20px rgba(0, 0, 0, 0.4)',
|
||
transition: 'all 0.25s ease'
|
||
}}
|
||
onMouseEnter={e => {
|
||
e.currentTarget.style.background = 'linear-gradient(180deg, #224373 0%, #173259 100%)';
|
||
e.currentTarget.style.transform = 'translateY(-1px)';
|
||
}}
|
||
onMouseLeave={e => {
|
||
e.currentTarget.style.background = 'linear-gradient(180deg, #1b365d 0%, #132847 100%)';
|
||
e.currentTarget.style.transform = 'translateY(0)';
|
||
}}
|
||
>
|
||
Subscribe
|
||
</button>
|
||
</form>
|
||
) : (
|
||
<div style={{
|
||
background: 'rgba(16, 185, 129, 0.15)',
|
||
border: '1px solid rgba(16, 185, 129, 0.3)',
|
||
padding: '1rem',
|
||
borderRadius: '12px',
|
||
color: '#34d399',
|
||
fontSize: '0.88rem',
|
||
textAlign: 'center',
|
||
fontWeight: 600
|
||
}}>
|
||
✓ Thanks for subscribing! Check your inbox for confirmation.
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
{/* BOTTOM "FROM THE BLOG" SECTION - MATCHING MOCKUP DESIGN */}
|
||
{relatedArticles.length > 0 && (
|
||
<div style={{ paddingTop: '4.5rem', borderTop: '1px solid rgba(255, 255, 255, 0.08)' }}>
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: isMobile ? '1fr' : '300px 1fr',
|
||
gap: isMobile ? '2.5rem' : '3.5rem',
|
||
alignItems: 'start'
|
||
}}>
|
||
{/* Left Column Header & CTA */}
|
||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
||
<span style={{
|
||
color: '#ffaa00',
|
||
fontSize: '0.85rem',
|
||
fontWeight: 700,
|
||
letterSpacing: '0.02em',
|
||
marginBottom: '0.6rem'
|
||
}}>
|
||
Latest
|
||
</span>
|
||
|
||
<h2 style={{
|
||
fontSize: '2.4rem',
|
||
fontWeight: 800,
|
||
color: '#ffffff',
|
||
lineHeight: 1.2,
|
||
letterSpacing: '-0.02em',
|
||
margin: '0 0 0.85rem 0'
|
||
}}>
|
||
From the blog
|
||
</h2>
|
||
|
||
<p style={{
|
||
color: '#94a3b8',
|
||
fontSize: '0.92rem',
|
||
lineHeight: 1.55,
|
||
margin: '0 0 2rem 0',
|
||
maxWidth: '260px'
|
||
}}>
|
||
The latest industry news, interviews, technologies, and resources.
|
||
</p>
|
||
|
||
<button
|
||
onClick={() => onNavigate('Home')}
|
||
style={{
|
||
background: '#091b33',
|
||
border: '1px solid rgba(255, 255, 255, 0.15)',
|
||
color: '#ffffff',
|
||
padding: '0.75rem 1.6rem',
|
||
borderRadius: '50px',
|
||
fontSize: '0.9rem',
|
||
fontWeight: 700,
|
||
cursor: 'pointer',
|
||
transition: 'all 0.25s ease',
|
||
marginBottom: '2.5rem',
|
||
boxShadow: '0 4px 15px rgba(0, 0, 0, 0.4)'
|
||
}}
|
||
onMouseEnter={e => {
|
||
e.currentTarget.style.background = '#0e2646';
|
||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.3)';
|
||
}}
|
||
onMouseLeave={e => {
|
||
e.currentTarget.style.background = '#091b33';
|
||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.15)';
|
||
}}
|
||
>
|
||
View All Posts
|
||
</button>
|
||
|
||
{/* Chevron Navigation Indicator */}
|
||
<div style={{
|
||
width: '36px',
|
||
height: '36px',
|
||
borderRadius: '50%',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
color: '#ffffff',
|
||
fontSize: '1.2rem',
|
||
cursor: 'pointer',
|
||
opacity: 0.8
|
||
}}>
|
||
<ArrowRight size={18} />
|
||
</div>
|
||
</div>
|
||
|
||
{/* Right Column Blog Cards */}
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: isMobile ? '1fr' : 'repeat(2, minmax(0, 1fr))',
|
||
gap: '1.25rem'
|
||
}}>
|
||
{relatedArticles.map((rel, i) => (
|
||
<div
|
||
key={i}
|
||
onClick={() => { if (onSelectBlog) onSelectBlog(rel); }}
|
||
style={{
|
||
height: '440px',
|
||
borderRadius: '18px',
|
||
overflow: 'hidden',
|
||
position: 'relative',
|
||
cursor: 'pointer',
|
||
border: '1px solid rgba(255, 255, 255, 0.12)',
|
||
boxShadow: '0 12px 35px rgba(0, 0, 0, 0.5)',
|
||
transition: 'all 0.35s cubic-bezier(0.4, 0, 0.2, 1)'
|
||
}}
|
||
onMouseEnter={e => {
|
||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.3)';
|
||
e.currentTarget.style.transform = 'translateY(-6px)';
|
||
e.currentTarget.style.boxShadow = '0 18px 45px rgba(0, 0, 0, 0.7)';
|
||
}}
|
||
onMouseLeave={e => {
|
||
e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.12)';
|
||
e.currentTarget.style.transform = 'translateY(0)';
|
||
e.currentTarget.style.boxShadow = '0 12px 35px rgba(0, 0, 0, 0.5)';
|
||
}}
|
||
>
|
||
{/* Full-bleed card image */}
|
||
<img
|
||
src={assetUrl(rel.image)}
|
||
alt={rel.title}
|
||
style={{
|
||
position: 'absolute',
|
||
inset: 0,
|
||
width: '100%',
|
||
height: '100%',
|
||
objectFit: 'cover',
|
||
display: 'block'
|
||
}}
|
||
/>
|
||
|
||
{/* Dark bottom panel */}
|
||
<div style={{
|
||
position: 'absolute',
|
||
bottom: 0,
|
||
left: 0,
|
||
right: 0,
|
||
padding: '1.25rem 1.25rem 1.15rem',
|
||
background: 'rgba(8, 14, 26, 0.88)',
|
||
backdropFilter: 'blur(16px)',
|
||
WebkitBackdropFilter: 'blur(16px)',
|
||
borderTop: '1px solid rgba(255, 255, 255, 0.08)'
|
||
}}>
|
||
<span style={{
|
||
fontSize: '0.68rem',
|
||
fontWeight: 700,
|
||
textTransform: 'uppercase',
|
||
color: '#94a3b8',
|
||
letterSpacing: '0.08em',
|
||
display: 'block'
|
||
}}>
|
||
{(rel.category || 'ARTICLE').toUpperCase()}
|
||
</span>
|
||
<h3 style={{
|
||
fontSize: '0.98rem',
|
||
fontWeight: 700,
|
||
color: '#ffffff',
|
||
margin: '0.35rem 0 0.75rem 0',
|
||
lineHeight: 1.4,
|
||
display: '-webkit-box',
|
||
WebkitLineClamp: 2,
|
||
WebkitBoxOrient: 'vertical',
|
||
overflow: 'hidden'
|
||
}}>
|
||
{rel.title}
|
||
</h3>
|
||
<div style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '0.35rem',
|
||
color: '#ffffff',
|
||
fontSize: '0.85rem',
|
||
fontWeight: 700
|
||
}}>
|
||
Read Blog <ArrowRight size={14} style={{ color: '#ffffff' }} />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|