From 00f78f53d780df501ab7978373260b84646321d2 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 10 Apr 2026 15:01:33 -0400 Subject: [PATCH] feat(i18n): wire services page and sub-components to translations Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/(frontend)/[locale]/services/page.tsx | 162 +++--------------- src/components/sections/services/AILayer.tsx | 15 +- .../sections/services/ServicesCTA.tsx | 15 +- .../sections/services/ServicesHero.tsx | 12 +- 4 files changed, 46 insertions(+), 158 deletions(-) diff --git a/src/app/(frontend)/[locale]/services/page.tsx b/src/app/(frontend)/[locale]/services/page.tsx index 19c7328..07d0035 100644 --- a/src/app/(frontend)/[locale]/services/page.tsx +++ b/src/app/(frontend)/[locale]/services/page.tsx @@ -36,136 +36,6 @@ export async function generateMetadata({ params }: PageProps): Promise }; } -// ─── Service data ────────────────────────────────────────────────────────────── - -export const SERVICE_PILLARS = [ - { - id: 'design-development', - numeral: '01', - title: 'Web Design & Development', - description: - 'Your website shouldn\'t look like everyone else\'s — and it shouldn\'t be built like everyone else\'s either. We design and build custom websites and web applications from a blank canvas, crafting every layout, every interaction, and every page with intention. The result is fast, search-engine-friendly, and built to grow with your business. Whether you need a marketing site that converts, a web application your team relies on, or an e-commerce platform that scales — we build it from scratch, and we build it to last.', - background: 'bg-surface' as const, - features: [ - { - icon: 'Palette', - title: 'Custom Design', - description: - 'Every layout, component, and interaction is designed for your brand. No themes, no templates, no shortcuts.', - }, - { - icon: 'Globe', - title: 'Web Applications', - description: - 'Modern, responsive applications built with the latest technologies — fast, reliable, and ready to scale.', - }, - { - icon: 'ShoppingCart', - title: 'E-Commerce', - description: - 'Custom storefronts, checkout flows, and multi-currency platforms built for serious online retail.', - }, - { - icon: 'Zap', - title: 'Performance & SEO', - description: - 'Fast load times, clean code, and search engine optimization built into the foundation — not bolted on after.', - }, - ], - }, - { - id: 'custom-systems', - numeral: '02', - title: 'Software & Platforms', - description: - 'Off-the-shelf software makes assumptions about how your business works. We don\'t. When spreadsheets and generic tools stop cutting it, we build the exact system your team needs — designed around your workflow, not someone else\'s. From CRMs tailored to your sales process, to management platforms that replace three different subscriptions, to integrations that connect your existing tools — everything we build is yours, fully documented, and built to last.', - background: 'bg-surface-low' as const, - features: [ - { - icon: 'Database', - title: 'CRM & Management Tools', - description: - 'Relationship and pipeline management built around how your team actually works — not how a generic platform thinks you should.', - }, - { - icon: 'Code2', - title: 'Custom Software', - description: - 'From booking platforms to internal tools to full SaaS products — purpose-built for your business.', - }, - { - icon: 'GitBranch', - title: 'Integrations & APIs', - description: - 'We connect your existing tools and build the bridges between systems so everything works together.', - }, - { - icon: 'Wrench', - title: 'Dashboards & Automation', - description: - 'Admin panels, reporting tools, and workflow automation that give your team an unfair advantage.', - }, - ], - }, - { - id: 'infrastructure', - numeral: '03', - title: 'Hosting & Infrastructure', - description: - 'Your website and software need a home — and we think you should own it. We set up and manage dedicated servers, email, cloud storage, and all the infrastructure your business runs on. No shared hosting, no mysterious third-party dependencies. You know where your data lives, who has access, and that someone is watching the dashboard around the clock.', - background: 'bg-surface' as const, - features: [ - { - icon: 'Server', - title: 'Dedicated Hosting', - description: - 'Private servers managed for your business — no shared hosting, no noisy neighbors, no surprises.', - }, - { - icon: 'Shield', - title: 'Your Data, Your Control', - description: - 'You own your data and know exactly where it lives. Full access, full transparency, no lock-in.', - }, - { - icon: 'Lock', - title: 'Security & Protection', - description: - 'Serious security, proactive monitoring, and protection built into your infrastructure from day one.', - }, - { - icon: 'Settings', - title: 'Monitoring & Support', - description: - 'Proactive monitoring, regular updates, and ongoing support so you never have to worry about uptime.', - }, - ], - }, -] as const; - -// ─── AI Layer data ───────────────────────────────────────────────────────────── - -export const AI_CAPABILITIES = [ - { - id: 'ai-teammate', - title: 'AI Teammate', - description: - 'An AI assistant built into your workflow — automates repetitive tasks, surfaces the info your team needs, and connects your tools.', - }, - { - id: 'customer-facing-ai', - title: 'Customer-Facing AI', - description: - 'Smart features for your customers — intelligent search, personalized recommendations, and conversational interfaces that work around the clock.', - }, - { - id: 'data-intelligence', - title: 'Data Intelligence', - description: - 'AI that helps you understand your data — automated reports, trend spotting, and insights you can actually act on.', - }, -] as const; - // ─── Page ────────────────────────────────────────────────────────────────────── type Props = { @@ -176,19 +46,37 @@ export default async function ServicesPage({ params }: Props) { const { locale } = await params; setRequestLocale(locale); + const t = await getTranslations({ locale, namespace: 'servicesPage' }) + + const backgrounds = ['bg-surface', 'bg-surface-low', 'bg-surface'] as const + const pillars = [0, 1, 2].map((i) => ({ + id: t(`pillars.${i}.id`), + numeral: t(`pillars.${i}.numeral`), + title: t(`pillars.${i}.title`), + description: t(`pillars.${i}.description`), + background: backgrounds[i], + features: [0, 1, 2, 3].map((j) => ({ + icon: t(`pillars.${i}.features.${j}.icon`), + title: t(`pillars.${i}.features.${j}.title`), + description: t(`pillars.${i}.features.${j}.description`), + })), + })) + + const aiCapabilities = [0, 1, 2].map((i) => ({ + id: t(`ai.capabilities.${i}.id`), + title: t(`ai.capabilities.${i}.title`), + description: t(`ai.capabilities.${i}.description`), + })) + return (
- {SERVICE_PILLARS.map((pillar, index) => ( - + {pillars.map((pillar, index) => ( + ))} - +
diff --git a/src/components/sections/services/AILayer.tsx b/src/components/sections/services/AILayer.tsx index 7d63a66..503bcd2 100644 --- a/src/components/sections/services/AILayer.tsx +++ b/src/components/sections/services/AILayer.tsx @@ -1,6 +1,7 @@ 'use client'; import { motion } from 'framer-motion'; +import { useTranslations } from 'next-intl'; import { Users, MessageCircle, BarChart3 } from 'lucide-react'; import { cn } from '@/lib/utils'; import { @@ -115,6 +116,7 @@ function AICapabilityCard({ capability }: { capability: AiCapability }) { // ─── Component ───────────────────────────────────────────────────────────────── export default function AILayer({ capabilities }: AILayerProps) { + const t = useTranslations('servicesPage.ai') return (
- Intelligent Layer + {t('eyebrow')} {/* Heading */} @@ -146,7 +148,7 @@ export default function AILayer({ capabilities }: AILayerProps) { variants={revealVariants} className="font-serif font-semibold tracking-headline text-white text-4xl md:text-5xl max-w-2xl leading-[1.1]" > - AI Built Into Everything + {t('title')} {/* Vertical line */} @@ -163,7 +165,7 @@ export default function AILayer({ capabilities }: AILayerProps) { className="font-serif italic text-xl leading-relaxed max-w-xl" style={{ color: 'rgba(255,255,255,0.75)' }} > - Your platform, made smarter. + {t('subtitle')} {/* Context paragraph */} @@ -172,10 +174,7 @@ export default function AILayer({ capabilities }: AILayerProps) { className="mt-5 text-[0.9375rem] leading-relaxed max-w-2xl" style={{ color: 'rgba(255,255,255,0.5)' }} > - We integrate AI directly into the websites and software we build - for you. Not as a buzzword or an add-on — as practical features - that save your team time and give your customers a better - experience. + {t('description')} @@ -201,7 +200,7 @@ export default function AILayer({ capabilities }: AILayerProps) { className="mt-10 text-center text-xs uppercase tracking-widest" style={{ color: 'rgba(255,255,255,0.25)' }} > - Every AI feature is tailored to your business — your data stays on your servers + {t('bottomNote')} diff --git a/src/components/sections/services/ServicesCTA.tsx b/src/components/sections/services/ServicesCTA.tsx index efa4bde..198580b 100644 --- a/src/components/sections/services/ServicesCTA.tsx +++ b/src/components/sections/services/ServicesCTA.tsx @@ -1,6 +1,7 @@ 'use client'; import { motion } from 'framer-motion'; +import { useTranslations } from 'next-intl'; import { ArrowRight } from 'lucide-react'; import { cn } from '@/lib/utils'; import { @@ -27,6 +28,7 @@ const decorLineVariants = { // ─── Component ───────────────────────────────────────────────────────────────── export default function ServicesCTA() { + const t = useTranslations('servicesPage.cta') return (
- Let's Talk + {t('eyebrow')} {/* Heading */}

- Ready to get started? + {t('title')}

{/* Subtitle */}

- Walk through a few questions and we'll put together a project - brief tailored to you — no commitment required, just clarity. + {t('subtitle')}

@@ -118,14 +119,14 @@ export default function ServicesCTA() { size="lg" arrow > - Start Your Project + {t('primary')} @@ -133,7 +134,7 @@ export default function ServicesCTA() { {/* Reassurance */}

- No commitment required — just a conversation about what's possible. + {t('reassurance')}

diff --git a/src/components/sections/services/ServicesHero.tsx b/src/components/sections/services/ServicesHero.tsx index 126d46d..3f43422 100644 --- a/src/components/sections/services/ServicesHero.tsx +++ b/src/components/sections/services/ServicesHero.tsx @@ -1,6 +1,7 @@ 'use client'; import { motion } from 'framer-motion'; +import { useTranslations } from 'next-intl'; import { staggerContainer, revealVariants, viewportOnce } from '@/lib/animations'; // ─── Animation variants ──────────────────────────────────────────────────────── @@ -45,6 +46,7 @@ const ruleVariants = { // ─── Component ───────────────────────────────────────────────────────────────── export default function ServicesHero() { + const t = useTranslations('servicesPage.hero') return (
- Our Services + {t('eyebrow')} {/* Headline */} @@ -70,8 +72,8 @@ export default function ServicesHero() { variants={headlineVariants} className="font-serif font-semibold tracking-headline text-on-surface text-5xl md:text-6xl lg:text-7xl max-w-4xl leading-[1.05]" > - Everything your business{' '} - needs online. + {t('title')}{' '} + {t('titleAccent')} {/* Subtitle */} @@ -79,9 +81,7 @@ export default function ServicesHero() { variants={subtitleVariants} className="mt-6 text-lg text-outline leading-relaxed max-w-2xl" > - We design custom websites, build purpose-built software, and manage - the infrastructure behind it all — one team, one standard of - quality, nothing outsourced. + {t('subtitle')} {/* Decorative rule */}