/** * SERVICES PAGE — FULL REDESIGN * * Matches the reference design layout while strictly following * Finjineers' locked design system (tokens, fonts, colors, animations). * * Sections: * 1. Hero — "OUR SERVICES" * 2. Services Grid — Tabbed bento grid * 3. Case Studies — Portfolio showcase (3 projects) * 4. Mid-Page CTA — "Have a Great Idea?" (imported from Homepage) * 5. Our Expertise — Auto-cycling domain chips + phone mockup * 6. Why Finjineers + Testimonials * 7. How We Work — 6-step process * 8. Consultation CTA Banner * 9. Tech Stack (bento layout) * 10. Final CTA — "Got a Project in Mind?" + "What Happens Next?" */ import { useRef, useState, useEffect } from "react"; import { motion, AnimatePresence, useInView } from "motion/react"; import { Link } from "react-router"; import teamImage from "figma:asset/22939b40b7751694b6fa87efec01230693a8f8ec.webp"; import whyImage from "figma:asset/ca905b480448e1b9c983f73e7a177d02d9eeffd4.webp"; import founderImage from "figma:asset/founder_haseeb.webp"; import founderTransparentImage from "figma:asset/founder_transparent.webp"; import serviceHeroImage from "figma:asset/service_feature_graphic.webp"; import { ArrowRight, ArrowUpRight, Calendar, Star, Linkedin, Mail, } from "lucide-react"; import { typography, spacing, layout, backgrounds, borders, transitions, colors, } from "@/app/utils/design-tokens"; import { easing, duration } from "@/app/utils/animations"; import { Button } from "@/app/components/ui/shared/Buttons"; import { ImageWithFallback } from "@/app/components/figma/ImageWithFallback"; import { optimizeUnsplashUrl, optimizeForSize } from "@/app/utils/image-utils"; import { useDocumentMeta } from "@/app/hooks/useDocumentMeta"; import { MidPageCTA } from "@/app/components/shared/MidPageCTA"; import { SectionHeader, GradientText } from "@/app/components/shared/SectionHeader"; import { TechStackSection } from "@/app/components/shared/TechStackSection"; import { externalUrls, contact, socialLinks } from "@/app/config/site"; import { startupsData, businessData, caseStudies, expertiseDomains, servicesTestimonials as testimonials, whyStatRows, workModels, whatHappensNext, } from "@/app/data/services"; import { FinalCTASection } from "@/app/components/shared/FinalCTASection"; // ============================================================================ // SECTION: HERO // ============================================================================ function ServicesHero() { const ref = useRef(null); const isInView = useInView(ref, { once: true }); return (
{/* Background glow */}

What We Offer

Our{" "} Services

We craft enterprise-grade mobile and web applications that drive growth, delight users, and scale with your ambition. From concept to launch and beyond.

); } // ============================================================================ // SECTION: SERVICES GRID // ============================================================================ // — Detail card component (title + arrow + description) function DetailCard({ title, description, delay: delayMs, isInView, }: { title: string; description: string; delay: number; isInView: boolean; }) { return (

{title}

{description}

); } // — Link-list card component (stacked items with arrows) function LinkListCard({ items, delay: delayMs, isInView, }: { items: string[]; delay: number; isInView: boolean; }) { return ( {items.map((item, i) => (
{item}
))}
); } // Tab data imported from @/app/data/services function ServicesGrid() { const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: "-100px" }); const [activeTab, setActiveTab] = useState<"startups" | "business">("startups"); const data = activeTab === "startups" ? startupsData : businessData; return (
{/* Background */}
{/* Section Title */} {/* Bento Grid */}
{/* ── Row 1: Tabs + Description | Featured Card ── */} {/* Tabs + Description (spans 2 cols) */} {/* Tab Buttons */}
{/* Description */}

{data.description}

{/* Featured Card (right column, row 1-2 on lg) */}

{data.featured.title}

{data.featured.description}

{/* Featured Link Items */}
{data.featuredLinks.map((link) => (
{link}
))}
{/* ── Row 2: First two detail cards ── */} {data.grid.slice(0, 2).map((item, i) => item.type === "detail" ? ( ) : ( ) )} {/* ── Row 3: Links + 2 detail cards ── */} {data.grid.slice(2, 5).map((item, i) => item.type === "detail" ? ( ) : ( ) )} {/* ── Row 4: Last 3 detail cards ── */} {data.grid.slice(5, 8).map((item, i) => item.type === "detail" ? ( ) : ( ) )}
); } // ============================================================================ // SECTION: CASE STUDIES // ============================================================================ // Case studies imported from @/app/data/services function CaseStudies() { const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: "-100px" }); return (
{/* Header */} {/* Case Study Cards */}
{caseStudies.map((study, i) => (
{/* Image */}
{/* Content */}
{study.category}

{study.title}

{study.description}

{/* Stats */}
{study.stats.map((stat) => (
{stat.value}
{stat.label}
))}
Explore Full Portfolio
))}
); } // ============================================================================ // SECTION: OUR EXPERTISE // ============================================================================ // Expertise domains imported from @/app/data/services function OurExpertise() { const ref = useRef(null); const chipsCardRef = useRef(null); const leftColumnRef = useRef(null); const isInView = useInView(ref, { once: true, margin: "-100px" }); const [activeIndex, setActiveIndex] = useState(4); // Start on Social Media const [chipsCardHeight, setChipsCardHeight] = useState(0); const [leftColumnHeight, setLeftColumnHeight] = useState(0); // Measure chips card height and full left column height useEffect(() => { const measure = () => { if (chipsCardRef.current) { setChipsCardHeight(chipsCardRef.current.offsetHeight); } if (leftColumnRef.current) { setLeftColumnHeight(leftColumnRef.current.offsetHeight); } }; measure(); window.addEventListener("resize", measure); return () => window.removeEventListener("resize", measure); }, []); // Auto-cycle through domains randomly useEffect(() => { const interval = setInterval(() => { setActiveIndex((prev) => { let next: number; do { next = Math.floor(Math.random() * expertiseDomains.length); } while (next === prev); return next; }); }, 3000); return () => clearInterval(interval); }, []); const activeDomain = expertiseDomains[activeIndex]; return (
{/* Subtle background glow */}
{/* ── Left Column: Title + Chips ── */} {/* Header */} {/* Chips Card */}
{expertiseDomains.map((domain, i) => { const Icon = domain.icon; const isActive = i === activeIndex; return ( {domain.name} ); })}
{/* ── Right Column: Phone Mockup ── */} {/* Clipping container — height further refined for optimal visibility balance */}
0 ? `${leftColumnHeight + 125}px` : "500px" }} > {/* Wide colored background card — matches chips card height exactly */} 0 ? `${chipsCardHeight}px` : "60%" }} animate={{ backgroundColor: activeDomain.accent }} transition={{ duration: 0.5, ease: "easeInOut" }} /> {/* Industry Shot — centered, original width but revealing much more height */}
); } // ============================================================================ // SECTION: WHY FINJINEERS + TESTIMONIALS // ============================================================================ // ── Large Circular Progress with text inside ── function CircularStatCard({ value, label, percentage, isInView, delay = 0, }: { value: string; label: string; percentage: number; isInView: boolean; delay?: number; }) { const size = 160; const strokeW = 6; const radius = (size - strokeW) / 2 - 8; const circumference = 2 * Math.PI * radius; const strokeDashoffset = circumference - (percentage / 100) * circumference; const gradId = `arcG-${percentage}-${delay}`; return (
{/* Track */} {/* Animated arc */} {/* Text inside the circle */}
{value} {label}
); } // whyStatRows imported from @/app/data/services // testimonials imported from @/app/data/services (as servicesTestimonials) function WhyFinjineers() { const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: "-100px" }); return (
{/* ── Section Title ── */} {/* ── 2-Column Stats Layout ── */}
{/* Left — Team Photo */}
{/* Right — Paired Stats (circular left + rect right) with vertical connectors */} {/* Vertical interlinking spine — runs behind all rows */}
{whyStatRows.map((row, rowIdx) => (
{/* Row */} {/* Left — Circular card */}
{/* Right — Rectangular card */}
{row.rect.value} {row.rect.label}
{/* Vertical connector bridge between rows */} {rowIdx < whyStatRows.length - 1 && (
{/* Connector node */} {/* Left arm */}
{/* Center diamond */}
{/* Right arm */}
)}
))}
{/* ── Testimonials — 2-col: title left, scrolling cards right ── */}
{/* Left — Title + Clutch CTA */}

Our Clients Are Our
Best Ambassadors

{/* Right — Infinite scrolling testimonial cards */} {/* Fade masks top & bottom */}
{/* Scrolling track */}
{/* Duplicate list for seamless loop */} {[...testimonials, ...testimonials].map((t, i) => (
{/* Author row */}
{t.role} {t.flag}
{t.name}
{/* Quote */}

“{t.quote}”

))}
); } // ============================================================================ // SECTION: HOW DO WE WORK // ============================================================================ // workModels imported from @/app/data/services function HowWeWork() { const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: "-100px" }); return (
{/* Header */} {/* Two model cards */}
{workModels.map((model, i) => ( {/* Badge */} {model.badge && (
{model.badge.emoji} {model.badge.text}
)}
{/* Title */}

{model.title}

{/* Description */}

{model.description}

{/* Points heading */}

{model.heading}

{/* Bullet list */}
    {model.points.map((pt) => (
  • {pt}
  • ))}
))}
); } // ============================================================================ // SECTION: DON'T KNOW WHAT TO CHOOSE? CTA // ============================================================================ function ConsultationCTA() { const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: "-80px" }); return (
{/* Pill-shaped card — dark glassmorphic theme */}
{/* Subtle orange glow top-left */}
{/* Left — Title + brand CTA */}

Don't Know What
To Choose?

{/* Center — Person info */}

Muhammad Haseeb

Founder & AI Consultant
at Finjineers

{/* Right — Floating character */}
{/* Glow behind character */}
Muhammad Haseeb — Founder & AI Consultant
); } // TechStack — now uses shared TechStackSection component from @/app/components/shared/TechStackSection // ============================================================================ // SECTION: FINAL CTA — GOT A PROJECT IN MIND? (Form + What Happens Next) // ============================================================================ // whatHappensNext imported from @/app/data/services // FinalCTA now uses shared FinalCTASection from @/app/components/shared/FinalCTASection // ============================================================================ // PAGE EXPORT // ============================================================================ export function Services() { useDocumentMeta({ title: "Services", description: "Explore Finjineers' full-service mobile app development: strategy, UI/UX design, React Native, Flutter, iOS, Android, backend, DevOps, and post-launch support.", }); return (
{/* 1. Hero */} {/* 2. Services Grid */} {/* 4. Case Studies */} {/* 5. Mid-Page CTA */} {/* 6. Our Expertise */} {/* 7. Why Finjineers + Testimonials */} {/* 8. How We Work */} {/* 9. Consultation CTA Banner */} {/* 10. Tech Stack */} {/* 12. Final CTA */}
); }