import React, { useRef, useState, useEffect, useCallback } from "react"; import { motion, useInView, AnimatePresence } from "motion/react"; import { ArrowRight, Star, Mail, Linkedin, Paperclip, ChevronLeft, ChevronRight, Play, } from "lucide-react"; import { colors, typography, spacing, layout, } from "@/app/utils/design-tokens"; import { easing, duration } from "@/app/utils/animations"; import { Button } from "../components/ui/shared/Buttons"; import { ImageWithFallback } from "../components/figma/ImageWithFallback"; import { optimizeUnsplashUrl, optimizeForSize } from "../utils/image-utils"; import { useDocumentMeta } from "../hooks/useDocumentMeta"; import { externalUrls, socialLinks } from "../config/site"; import { SectionHeader, GradientText } from "../components/shared/SectionHeader"; import { FinalCTASection } from "../components/shared/FinalCTASection"; import { AnimatedSection } from "../components/shared/AnimatedSection"; import { specialistStats, industries, clientBreakdown, whyWorkWithUs, testimonials, heroReviews, aboutWhatHappensNext, } from "../data/about"; // Data arrays imported from @/app/data/about.ts // Tech stack imported from @/app/data/tech-stack.tsx // ============================================================================ // MAIN COMPONENT // ============================================================================ export function About() { useDocumentMeta({ title: "About", description: "Meet the Finjineers team — a 100% in-house team of mobile app developers, designers, and strategists building world-class apps for startups and enterprises.", }); return (
); } // ============================================================================ // 1. HERO SECTION — About Us // ============================================================================ function HeroSection() { const ref = useRef(null); const isInView = useInView(ref, { once: true }); return (
{/* Background glow */}
{/* Left — Copy */} About us

About Us

We are a premium mobile app development agency founded by ex-Google and ex-Facebook engineers. We combine Silicon Valley engineering standards with world-class design to build apps that startups and SaaS founders love.

{/* Right — Review Ticket Carousel */}
); } // ============================================================================ // REVIEW TICKET CAROUSEL — used in Hero // ============================================================================ function StarRating({ rating }: { rating: string }) { const numRating = parseFloat(rating); const fullStars = Math.floor(numRating); const hasHalf = numRating % 1 >= 0.5; return ( {Array.from({ length: 5 }).map((_, i) => ( ))} ); } function ReviewTicketCarousel() { const [current, setCurrent] = useState(0); const [direction, setDirection] = useState(1); const total = heroReviews.length; const ticketRef = useRef(null); const goTo = useCallback( (next: number) => { setDirection(next > current ? 1 : -1); setCurrent(next); }, [current] ); const goNext = useCallback(() => { goTo((current + 1) % total); }, [current, total, goTo]); const goPrev = useCallback(() => { goTo((current - 1 + total) % total); }, [current, total, goTo]); // Auto-scroll every 4 seconds — pauses when off-screen useEffect(() => { const el = ticketRef.current; if (!el) return; let timer: ReturnType | null = null; const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { timer = setInterval(goNext, 4000); } else if (timer) { clearInterval(timer); timer = null; } }, { threshold: 0.1 } ); observer.observe(el); return () => { observer.disconnect(); if (timer) clearInterval(timer); }; }, [goNext]); const review = heroReviews[current]; const variants = { enter: (dir: number) => ({ x: dir > 0 ? 80 : -80, opacity: 0 }), center: { x: 0, opacity: 1 }, exit: (dir: number) => ({ x: dir > 0 ? -80 : 80, opacity: 0 }), }; return (
{/* Ticket Card */}
{/* Top perforation dots */}
{Array.from({ length: 16 }).map((_, i) => (
))}
{/* Left — Quote & Date */}
The Review

“{review.quote}”

{review.date}
{/* Right — Ratings */}
{/* Overall */}
{review.overall}
{/* Detail Scores */}
{[ { label: "Quality:", value: review.quality }, { label: "Schedule:", value: review.schedule }, { label: "Cost:", value: review.cost }, { label: "Willing to refer:", value: review.willingToRefer }, ].map((item) => (
{item.label} {item.value}
))}
{/* Bottom perforation dots */} {/* Navigation Arrows + Dots */}
{/* Slide dots */}
{heroReviews.map((_, i) => (
{/* Arrows */}
); } // 3. TECHNOLOGY STACK — Uses shared TechStackSection from @/app/components/shared/TechStackSection // ============================================================================ // 4. 50+ IN-HOUSE SPECIALISTS // ============================================================================ function SpecialistsSection() { return ( {(isInView) => (
{/* Left — Heading */}

50+ In-House
Specialists

{/* Right — Stat Cards (2×2 grid, bounding-box style) */}
{specialistStats.map((stat, i) => ( {/* Bounding-box card */}
{/* Corner & midpoint handles */} {[ "top-0 left-0 -translate-x-1/2 -translate-y-1/2", "top-0 right-0 translate-x-1/2 -translate-y-1/2", "bottom-0 left-0 -translate-x-1/2 translate-y-1/2", "bottom-0 right-0 translate-x-1/2 translate-y-1/2", "top-0 left-1/2 -translate-x-1/2 -translate-y-1/2", "bottom-0 left-1/2 -translate-x-1/2 translate-y-1/2", "top-1/2 left-0 -translate-x-1/2 -translate-y-1/2", "top-1/2 right-0 translate-x-1/2 -translate-y-1/2", ].map((pos, hi) => (
))} {/* Value */}
{stat.value}
{/* Label */}
{stat.label}
))}
)} ); } // ============================================================================ // ANIMATED BAR CHART — used in Industries section // ============================================================================ const yAxisLabels = [0, 10, 20, 30, 40, 50]; const CHART_HEIGHT = 200; const Y_LABEL_W = 36; function AnimatedBarChart({ data, maxPercentage, isInView, }: { data: typeof clientBreakdown; maxPercentage: number; isInView: boolean; }) { const [animKey, setAnimKey] = useState(0); const chartRef = useRef(null); // Use a local IntersectionObserver to pause/resume the replay interval // when the chart scrolls out of view (isInView from parent is once:true // and never resets, so the interval would run forever otherwise) useEffect(() => { if (!isInView) return; const el = chartRef.current; if (!el) return; let interval: ReturnType | null = null; const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { interval = setInterval(() => { setAnimKey((k) => k + 1); }, 5000); } else if (interval) { clearInterval(interval); interval = null; } }, { threshold: 0.1 } ); observer.observe(el); return () => { observer.disconnect(); if (interval) clearInterval(interval); }; }, [isInView]); return (
`${d.label.replace('\n', ' ')} ${d.percentage}%`).join(', ')}`}> {/* Chart area wrapper */}
{/* Plot area — fixed height, all elements positioned relative to this */}
{/* Grid lines — positioned absolutely within plot area */} {yAxisLabels.map((val) => { const bottomPx = (val / 50) * CHART_HEIGHT; return (
{/* Y-axis label — positioned to the left of the plot */} {val}% {/* Horizontal grid line */}
); })} {/* Bars — aligned exactly to the bottom edge (0-line) */}
{data.map((client, i) => { const barH = (client.percentage / 50) * CHART_HEIGHT; return (
{/* Percentage label above bar */} {client.percentage}% {/* Bar — grows upward from the 0-line */}
{/* Shimmer / glow effect */}
); })}
{/* X-axis labels — below chart, aligned with bars */}
{data.map((client) => (

{client.label}

))}
); } // ============================================================================ // 5. INDUSTRIES // ============================================================================ function IndustriesSection() { const maxPercentage = Math.max(...clientBreakdown.map((c) => c.percentage)); return ( {(isInView) => (
{/* Left — Title + Industry List */}

Industries

{industries.map((industry, i) => ( / {industry} ))}
{/* Right — Our Clients Bar Chart */}

Our clients

)}
); } // ============================================================================ // 6. WHY WORK WITH FINJINEERS // ============================================================================ function WhyWorkWithUsSection() { return ( {(isInView) => (
{/* Left — Heading (spans 2 cols) */}

Why Work
With Finjineers

{/* Right — Feature Cards (spans 3 cols) */}
{whyWorkWithUs.map((item, i) => (
{String(i + 1).padStart(2, "0")}

{item.title}

{item.description}

))}
)}
); } // ============================================================================ // 7. TESTIMONIALS — Clients Are Saying // ============================================================================ function TestimonialsSection() { const [current, setCurrent] = useState(0); const [direction, setDirection] = useState(1); const [isPlaying, setIsPlaying] = useState(false); const goTo = (index: number) => { setDirection(index > current ? 1 : -1); setCurrent(index); setIsPlaying(false); }; const slideVariants = { enter: (d: number) => ({ opacity: 0, x: d > 0 ? 60 : -60 }), center: { opacity: 1, x: 0 }, exit: (d: number) => ({ opacity: 0, x: d > 0 ? -60 : 60 }), }; const t = testimonials[current]; return ( {(isInView) => ( {/* Ticket wrapper */}
{/* Top perforation dots */}