visual update services

This commit is contained in:
null 2026-05-25 20:03:56 -05:00
parent 9b5f9f885c
commit 07a43b9b7c
1 changed files with 92 additions and 15 deletions

View File

@ -1,6 +1,6 @@
import SEO from '@/components/SEO' import SEO from '@/components/SEO'
import { services } from '@/data/services' import { services } from '@/data/services'
import { ArrowRight, MessageCircle, Users, LifeBuoy, GraduationCap, Link as LinkIcon, Wifi, Network, Layers } from 'lucide-react' import { ArrowRight, MessageCircle, Users, LifeBuoy, GraduationCap, Link as LinkIcon, Wifi, Network, Layers, CheckCircle2, ShieldCheck, PhoneCall } from 'lucide-react'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
const serviceLd = { const serviceLd = {
@ -28,6 +28,39 @@ const iconMap = {
'network': Network, 'network': Network,
} }
const serviceAccentStyles = [
{
card: 'border-t-[3px] border-t-primary-blue hover:border-primary-blue/50',
iconWrap: 'bg-sky-50',
icon: 'text-primary-blue',
link: 'text-primary-blue hover:text-primary-navy',
},
{
card: 'border-t-[3px] border-t-teal-500 hover:border-teal-500/50',
iconWrap: 'bg-teal-50',
icon: 'text-teal-600',
link: 'text-teal-700 hover:text-primary-navy',
},
{
card: 'border-t-[3px] border-t-cyan-400 hover:border-cyan-400/60',
iconWrap: 'bg-cyan-50',
icon: 'text-cyan-600',
link: 'text-cyan-700 hover:text-primary-navy',
},
{
card: 'border-t-[3px] border-t-accent-gold hover:border-accent-gold/60',
iconWrap: 'bg-amber-50',
icon: 'text-amber-600',
link: 'text-amber-700 hover:text-primary-navy',
},
]
const serviceHighlights = [
{ label: 'Discovery first', icon: CheckCircle2 },
{ label: 'Vendor-neutral guidance', icon: ShieldCheck },
{ label: 'Deployment and support', icon: PhoneCall },
]
const Services = () => { const Services = () => {
return ( return (
<> <>
@ -39,7 +72,16 @@ const Services = () => {
/> />
{/* Hero */} {/* Hero */}
<section className="bg-primary-navy py-12 lg:py-20 text-white"> <section className="relative isolate overflow-hidden bg-primary-navy py-16 lg:py-24 text-white">
<div className="absolute inset-0 -z-10">
<img
src="/assets/hero-tech.webp"
alt="Queue North technician working inside a communications rack"
className="h-full w-full object-cover object-center"
/>
<div className="absolute inset-0 bg-primary-navy/75" />
<div className="absolute inset-0 bg-gradient-to-r from-primary-navy via-primary-navy/90 to-primary-navy/35" />
</div>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="max-w-3xl"> <div className="max-w-3xl">
<div className="inline-flex items-center gap-2 rounded-md border border-white/20 bg-white/10 px-3 py-2 text-xs font-semibold uppercase tracking-wide text-primary-cyan mb-6"> <div className="inline-flex items-center gap-2 rounded-md border border-white/20 bg-white/10 px-3 py-2 text-xs font-semibold uppercase tracking-wide text-primary-cyan mb-6">
@ -67,26 +109,61 @@ const Services = () => {
Existing Client? Get Support Existing Client? Get Support
</Link> </Link>
</div> </div>
<div className="mt-10 grid grid-cols-1 gap-3 sm:grid-cols-3">
{serviceHighlights.map((item) => {
const Icon = item.icon
return (
<div key={item.label} className="flex items-center gap-2 rounded-md border border-white/15 bg-white/10 px-3 py-2 text-sm font-semibold text-white/85">
<Icon className="h-4 w-4 text-primary-cyan" aria-hidden="true" />
{item.label}
</div>
)
})}
</div>
</div> </div>
</div> </div>
</section> </section>
{/* Services Grid */} {/* Services Grid */}
<section className="bg-background py-16 lg:py-20"> <section className="bg-background py-16 lg:py-24">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> <div className="mb-10 flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
{services.map((service) => { <div>
const Icon = iconMap[service.icon] <h2 className="text-3xl md:text-4xl font-bold text-primary-navy">Services built around the whole environment</h2>
return ( <p className="mt-3 max-w-2xl text-lg text-soft-text">
<div key={service.id} className="group flex flex-col rounded-md border border-border bg-white p-6 shadow-sm hover:shadow-md hover:border-primary-navy/30 transition-all"> Choose a starting point below, or bring us the messy version and we will map the practical path forward.
<div className="flex h-12 w-12 items-center justify-center rounded-md bg-primary-navy/10 mb-5 flex-shrink-0"> </p>
{Icon && <Icon className="h-6 w-6 text-primary-navy" aria-hidden="true" />}
</div> </div>
<h2 className="text-xl font-semibold text-primary-navy mb-3">{service.name}</h2> <Link
<p className="text-soft-text text-sm leading-relaxed flex-1 mb-6">{service.homeDesc}</p> to="/contact"
className="inline-flex h-10 items-center justify-center gap-2 rounded-md border border-primary-navy/20 px-4 text-sm font-semibold text-primary-navy hover:border-primary-blue hover:text-primary-blue transition-colors"
>
Talk through options
<ArrowRight className="h-4 w-4" aria-hidden="true" />
</Link>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{services.map((service, index) => {
const Icon = iconMap[service.icon]
const accent = serviceAccentStyles[index % serviceAccentStyles.length]
return (
<div key={service.id} className={`group flex h-full flex-col rounded-md border border-border bg-white p-6 shadow-sm hover:shadow-md transition-all ${accent.card}`}>
<div className="mb-5 flex items-center gap-4">
<div className={`flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-md ${accent.iconWrap}`}>
{Icon && <Icon className={`h-6 w-6 ${accent.icon}`} aria-hidden="true" />}
</div>
<h2 className="text-left text-xl font-semibold text-primary-navy">{service.name}</h2>
</div>
<p className="text-soft-text text-sm leading-relaxed flex-1 mb-5">{service.homeDesc}</p>
{service.idealFor?.[0] && (
<p className="mb-6 rounded-md bg-section-alt px-3 py-2 text-xs font-semibold text-primary-navy">
Best fit: {service.idealFor[0]}
</p>
)}
<Link <Link
to={`/services/${service.id}`} to={`/services/${service.id}`}
className="inline-flex items-center gap-1.5 text-sm font-semibold text-primary-navy hover:text-primary-blue transition-colors" className={`inline-flex items-center gap-1.5 text-sm font-semibold transition-colors ${accent.link}`}
aria-label={`Learn more about ${service.name}`} aria-label={`Learn more about ${service.name}`}
> >
Learn more Learn more
@ -100,18 +177,18 @@ const Services = () => {
</section> </section>
{/* CTA */} {/* CTA */}
<section className="bg-primary-navy py-14 text-white"> <section className="bg-section-alt py-16 lg:py-24">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-6"> <div className="flex flex-col gap-8 border-y border-border py-10 lg:flex-row lg:items-center lg:justify-between">
<div> <div>
<h2 className="text-3xl md:text-4xl font-bold mb-3">Not sure where to start?</h2> <h2 className="text-3xl md:text-4xl font-bold text-primary-navy mb-3">Not sure where to start?</h2>
<p className="text-white/70 max-w-2xl"> <p className="text-soft-text max-w-2xl">
Tell us about your environment and we'll cut through the options to tell you what actually fits. Tell us about your environment and we'll cut through the options to tell you what actually fits.
</p> </p>
</div> </div>
<Link <Link
to="/contact" to="/contact"
className="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-white px-6 text-sm font-semibold text-primary-navy hover:bg-section-alt transition-colors flex-shrink-0" className="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-primary-navy px-6 text-sm font-semibold text-white hover:bg-primary-navy-dark transition-colors flex-shrink-0"
> >
Get a Free Quote Get a Free Quote
<ArrowRight className="h-4 w-4" aria-hidden="true" /> <ArrowRight className="h-4 w-4" aria-hidden="true" />