feat: Revamped design - improved dark mode visibility, mobile UX fixes, updated trust signals
This commit is contained in:
+74
-33
@@ -4,26 +4,34 @@ import { Icons } from './landing/constants';
|
||||
|
||||
const services = [
|
||||
{
|
||||
title: "Commercial and Residential Repair and Diagnostics",
|
||||
desc: "Leak detection & shingle replacement in record time. We identify micro-fractures invisible to the naked eye.",
|
||||
title: "Commercial & Residential Repair and Diagnostics",
|
||||
desc: "Leak detection & shingle replacement in record time. We identify micro-fractures invisible to the naked eye using drone-captured LiDAR scans and AI-powered thermal analysis.",
|
||||
icon: Icons.Home,
|
||||
color: "from-blue-400 to-blue-600",
|
||||
glow: "shadow-blue-500/20"
|
||||
glow: "shadow-blue-500/20",
|
||||
badge: "Licensed",
|
||||
badgeClass: "permit-stamp--verified",
|
||||
badgeIcon: "\u2713",
|
||||
stat: "2,847",
|
||||
statLabel: "Properties Inspected",
|
||||
},
|
||||
// Commercial Development Removed as per request
|
||||
{
|
||||
title: "Lead & Data Solutions",
|
||||
desc: "Advanced lead scoring and real time storm tracking alerts. Know where the damage is before the phone rings. Powered by intelligent data models and predictive algorithms, we direct your reps and marketing into high-impact zones; where probability, urgency and opportunity align.",
|
||||
desc: "Advanced lead scoring and real-time storm tracking alerts. Know where the damage is before the phone rings. We direct your reps and marketing into high-impact zones where probability, urgency and opportunity align.",
|
||||
icon: Icons.Chart,
|
||||
color: "from-purple-400 to-indigo-600",
|
||||
glow: "shadow-purple-500/20"
|
||||
glow: "shadow-purple-500/20",
|
||||
badge: "Certified",
|
||||
badgeClass: "permit-stamp--accent",
|
||||
badgeIcon: "\u25B9",
|
||||
stat: "96%",
|
||||
statLabel: "Lead Accuracy",
|
||||
}
|
||||
];
|
||||
|
||||
const Services = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Simple Tilt Logic
|
||||
const handleMouseMove = (e) => {
|
||||
const card = e.currentTarget;
|
||||
const rect = card.getBoundingClientRect();
|
||||
@@ -31,11 +39,8 @@ const Services = () => {
|
||||
const y = e.clientY - rect.top;
|
||||
const centerX = rect.width / 2;
|
||||
const centerY = rect.height / 2;
|
||||
|
||||
// Rotation calc (Max 5deg)
|
||||
const rotateX = ((y - centerY) / centerY) * -5;
|
||||
const rotateY = ((x - centerX) / centerX) * 5;
|
||||
|
||||
const rotateX = ((y - centerY) / centerY) * -4;
|
||||
const rotateY = ((x - centerX) / centerX) * 4;
|
||||
card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(1.02)`;
|
||||
};
|
||||
|
||||
@@ -44,52 +49,88 @@ const Services = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="py-24 bg-white relative overflow-hidden dark:bg-black/40">
|
||||
<div className="absolute inset-0 opacity-5 bg-grid-pattern bg-[length:40px_40px]"></div>
|
||||
<section className="py-24 bg-zinc-100 dark:bg-zinc-900 relative overflow-hidden">
|
||||
<div className="absolute inset-0 blueprint-grid-fine opacity-25"></div>
|
||||
|
||||
<div className="container mx-auto px-4 relative z-10">
|
||||
<div className="max-w-5xl mx-auto px-6 relative z-10">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-slate-900 dark:text-white font-heading text-4xl font-bold">Our Core Services</h2>
|
||||
<p className="text-gray-500 mt-4 max-w-2xl mx-auto font-light">Leveraging military-grade technology for civilian roofing applications.</p>
|
||||
<span className="permit-stamp permit-stamp--accent mb-6 inline-flex">▷ Core Operations</span>
|
||||
<h2 className="text-3xl md:text-5xl font-black text-zinc-900 dark:text-white mb-4 mt-4 tracking-tight">What We Do Best</h2>
|
||||
<p className="text-zinc-500 dark:text-zinc-400 max-w-2xl mx-auto">Military-grade technology applied to civilian roofing. Two pillars, one platform.</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-4xl mx-auto">
|
||||
<div className="grid md:grid-cols-2 gap-8">
|
||||
{services.map((service, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
onMouseMove={handleMouseMove}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
className="group p-8 rounded-2xl border border-gray-100 dark:border-white/10 bg-white/80 dark:bg-white/5 backdrop-blur-sm shadow-xl transition-all duration-200 ease-out cursor-pointer relative overflow-hidden"
|
||||
className="group relative p-8 rounded-2xl border border-zinc-200 dark:border-white/10 bg-white dark:bg-white/[0.04] hover:bg-zinc-50 dark:hover:bg-white/[0.07] backdrop-blur-sm transition-all duration-200 cursor-pointer overflow-hidden shadow-xl dark:shadow-[0_20px_60px_rgba(0,0,0,0.4)]"
|
||||
style={{ transformStyle: 'preserve-3d', transition: 'transform 0.1s ease-out' }}
|
||||
>
|
||||
{/* Gradient Glow on Hover */}
|
||||
<div className={`absolute -inset-0.5 bg-gradient-to-br ${service.color} opacity-0 group-hover:opacity-20 blur-xl transition-opacity duration-300 pointer-events-none`}></div>
|
||||
{/* Measurement ticks — top */}
|
||||
<div className="measure-ticks measure-ticks-top absolute top-0 left-4 right-4 h-3"></div>
|
||||
|
||||
{/* Gradient glow on hover */}
|
||||
<div className={`absolute -inset-0.5 bg-gradient-to-br ${service.color} opacity-0 group-hover:opacity-15 blur-xl transition-opacity duration-300 pointer-events-none`}></div>
|
||||
|
||||
<div className="relative z-10 flex flex-col h-full">
|
||||
<div className={`w-16 h-16 mb-6 rounded-xl flex items-center justify-center text-white bg-gradient-to-br ${service.color} shadow-lg ${service.glow} transform group-hover:scale-110 transition-transform duration-300`}>
|
||||
<div className="w-8 h-8 flex items-center justify-center">
|
||||
<service.icon />
|
||||
{/* Top row: Icon + Service number */}
|
||||
<div className="flex items-start justify-between mb-6 mt-1">
|
||||
<div className={`w-14 h-14 rounded-xl flex items-center justify-center text-white bg-gradient-to-br ${service.color} shadow-lg ${service.glow} group-hover:scale-110 transition-transform duration-300`}>
|
||||
<div className="w-7 h-7 flex items-center justify-center">
|
||||
<service.icon />
|
||||
</div>
|
||||
</div>
|
||||
<span className="font-mono text-[11px] font-bold text-zinc-300 dark:text-white/15 tracking-wider">0{idx + 1}</span>
|
||||
</div>
|
||||
|
||||
<h3 className="text-2xl font-heading font-bold text-slate-900 dark:text-white mb-3 group-hover:text-transparent group-hover:bg-clip-text group-hover:bg-gradient-to-r group-hover:from-blue-600 group-hover:to-cyan-500 dark:group-hover:from-blue-400 dark:group-hover:to-cyan-400 transition-all duration-300">
|
||||
<h3 className="text-xl font-bold text-zinc-900 dark:text-white mb-3 leading-snug">
|
||||
{service.title}
|
||||
</h3>
|
||||
|
||||
<p className="text-gray-600 dark:text-gray-400 text-sm leading-relaxed mb-8 flex-grow">
|
||||
<p className="text-zinc-500 dark:text-zinc-400 text-sm leading-relaxed mb-6 flex-grow">
|
||||
{service.desc}
|
||||
</p>
|
||||
|
||||
<div
|
||||
onClick={(e) => { e.stopPropagation(); navigate('/login'); }}
|
||||
className="pt-6 border-t border-gray-100 dark:border-white/10 flex items-center justify-between mt-auto group-hover:border-cyan/20 transition-colors cursor-pointer"
|
||||
>
|
||||
<span className="text-xs font-bold text-gray-400 uppercase tracking-wider group-hover:text-cyan transition-colors">Explore Solution</span>
|
||||
<div className="w-8 h-8 rounded-full border border-gray-200 dark:border-white/20 text-gray-400 flex items-center justify-center transform group-hover:rotate-45 group-hover:border-cyan group-hover:text-cyan transition-all duration-300">
|
||||
↗
|
||||
{/* Inline stat */}
|
||||
<div className="flex items-baseline gap-2 mb-6">
|
||||
<span className="font-mono text-2xl font-bold text-zinc-900 dark:text-white tracking-tight">{service.stat}</span>
|
||||
<span className="text-xs text-zinc-500 font-medium uppercase tracking-wider">{service.statLabel}</span>
|
||||
</div>
|
||||
|
||||
{/* Footer row: Permit stamp + CTA */}
|
||||
<div className="pt-4 border-t border-zinc-100 dark:border-white/5 flex items-center justify-between mt-auto">
|
||||
<span className={`permit-stamp ${service.badgeClass}`}>{service.badgeIcon} {service.badge}</span>
|
||||
<div
|
||||
onClick={(e) => { e.stopPropagation(); navigate('/login'); }}
|
||||
className="flex items-center gap-2 text-xs font-bold text-zinc-500 uppercase tracking-wider group-hover:text-blue-400 transition-colors"
|
||||
>
|
||||
Explore
|
||||
<div className="w-6 h-6 rounded-full border border-zinc-300 dark:border-white/10 flex items-center justify-center group-hover:border-blue-400/30 group-hover:rotate-45 transition-all duration-300 text-[10px]">
|
||||
↗
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Measurement ticks — bottom */}
|
||||
<div className="measure-ticks absolute bottom-0 left-4 right-4 h-3"></div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Trust signals strip */}
|
||||
<div className="mt-12 flex flex-wrap items-center justify-center gap-x-8 gap-y-3 text-zinc-500">
|
||||
{[
|
||||
{ label: "AI-Powered Analysis", icon: "◉" },
|
||||
{ label: "15-Min Turnaround", icon: "◉" },
|
||||
{ label: "Drone-Powered Inspections", icon: "◉" },
|
||||
{ label: "Insurance-Ready Reports", icon: "◉" },
|
||||
].map((item, i) => (
|
||||
<div key={i} className="flex items-center gap-2 text-xs font-mono uppercase tracking-wider">
|
||||
<span className="text-blue-500/60 text-[6px]">{item.icon}</span>
|
||||
<span>{item.label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user