"use client"; import { useCallback, useEffect, useMemo, useState } from "react"; import { Anchor, ArrowRight, Clock, Cloud, Package, Shapes, Sparkles, Zap } from "lucide-react"; import Link from "next/link"; import type { Collection, IconEntry } from "@/lib/icons"; import { loadIconsManifest } from "@/lib/icons-manifest"; import { IconCard } from "@/components/icons/icon-card"; import { IconGrid } from "@/components/icons/icon-grid"; import { IconDetail } from "@/components/icons/icon-detail"; /** Inline AWS logo - text inherits currentColor, arrow stays orange */ function AwsLogo({ className }: { className?: string }) { return ( ); } /** Hand-picked popular brand slugs */ const POPULAR_SLUGS = [ "google", "apple", "github", "microsoft", "amazon", "meta", "netflix", "spotify", "discord", "slack", "figma", "notion", "stripe", "vercel", "docker", "react", "nextdotjs", "typescript", "tailwindcss", "nodejs", "python", "rust", "openai", "claude", "firebase", "supabase", "postgresql", "mongodb", "redis", "linux", "aws", "cloudflare", "digitalocean", "github-copilot", "visual-studio-code", "chrome", "firefox", "safari", "android", "swift", ]; /** Hand-picked popular AWS slugs */ const POPULAR_AWS_SLUGS = [ "aws-aws-lambda", "aws-amazon-ec2", "aws-amazon-s3", "aws-amazon-rds", "aws-amazon-dynamodb", "aws-amazon-cloudfront", "aws-amazon-api-gateway", "aws-amazon-sqs", "aws-amazon-sns", "aws-amazon-bedrock", "aws-amazon-ecs", "aws-amazon-eks", "aws-aws-fargate", "aws-amazon-cognito", "aws-amazon-cloudwatch", "aws-aws-iam-identity-center", "aws-amazon-route-53", "aws-amazon-elasticache", "aws-aws-step-functions", "aws-amazon-kinesis", "aws-aws-cloudformation", "aws-amazon-sagemaker", "aws-aws-app-runner", "aws-amazon-eventbridge", ]; /** Hand-picked popular Azure slugs */ const POPULAR_AZURE_SLUGS = [ "azure-virtual-machines", "azure-app-services", "azure-sql-database", "azure-cosmos-db", "azure-kubernetes-service-aks", "azure-functions", "azure-storage-accounts", "azure-active-directory", "azure-devops", "azure-api-management-services", "azure-key-vaults", "azure-cognitive-services", "azure-load-balancers", "azure-virtual-networks", "azure-container-apps", "azure-application-gateways", "azure-azure-sql", "azure-monitor", "azure-azure-cache-for-redis", "azure-event-hubs", "azure-service-bus", "azure-logic-apps", "azure-bot-services", "azure-cdn-profiles", ]; /** Hand-picked popular GCP slugs */ const POPULAR_GCP_SLUGS = [ "gcp-compute-engine", "gcp-cloud-storage", "gcp-bigquery", "gcp-cloud-functions", "gcp-cloud-run", "gcp-google-kubernetes-engine", "gcp-cloud-sql", "gcp-app-engine", "gcp-cloud-cdn", "gcp-cloud-build", "gcp-pubsub", "gcp-cloud-spanner", "gcp-vertexai", "gcp-cloud-armor", "gcp-artifact-registry", "gcp-cloud-dns", "gcp-firestore", "gcp-memorystore", "gcp-cloud-monitoring", "gcp-cloud-logging", "gcp-secret-manager", "gcp-identity-and-access-management", "gcp-cloud-load-balancing", "gcp-apigee-api-platform", ]; /** Hand-picked popular Kubernetes slugs */ const POPULAR_K8S_SLUGS = [ "k8s-deployment", "k8s-pod", "k8s-service", "k8s-ingress", "k8s-configmap", "k8s-secret", "k8s-daemonset", "k8s-statefulset", "k8s-cronjob", "k8s-namespace", "k8s-node", "k8s-persistentvolume", "k8s-api-server", "k8s-etcd-cluster", "k8s-horizontalpodautoscaler", "k8s-replicaset", "k8s-serviceaccount", "k8s-storageclass", "k8s-controller-manager", "k8s-clusterrole", ]; const COLLECTION_LABELS: Record = { brands: { label: "Brand Icons", description: "Logos and brand marks" }, aws: { label: "AWS Architecture", description: "AWS service and resource icons (2026-Q1)" }, azure: { label: "Azure Services", description: "Microsoft Azure service icons (2026-Q1)" }, gcp: { label: "Google Cloud", description: "Google Cloud Platform icons (2026-Q1)" }, k8s: { label: "Kubernetes", description: "Official Kubernetes architecture icons" }, }; const ALL_SLIDES = [ { badge: "Open Source", badgeIcon: Sparkles, title: "6,030+ SVG Icons. Search. Copy. Ship.", description: "Search, copy, and ship brand icons in seconds. Free, open-source, and community-driven.", cta: { label: "Get Started", href: "/extensions" }, ctaSecondary: { label: "Submit an Icon", href: "/submit" }, gradient: "from-orange-50/50 via-background to-orange-50/30 dark:from-orange-950/20 dark:via-background dark:to-orange-950/10", accent: "border-orange-200/50 bg-orange-50/80 text-orange-600 dark:border-orange-500/20 dark:bg-orange-500/10 dark:text-orange-400", blob: "bg-orange-400/10 dark:bg-orange-500/5", collection: "brands" as const, floatSlugs: POPULAR_SLUGS, }, { badge: "npm install thesvg", badgeIcon: Package, title: "One Package, Every Brand", description: "Tree-shakeable, typed, dual ESM/CJS. Import any icon with zero config.", cta: { label: "View on npm", href: "https://www.npmjs.com/package/thesvg" }, ctaSecondary: { label: "Extensions", href: "/extensions" }, gradient: "from-blue-50/50 via-background to-blue-50/30 dark:from-blue-950/20 dark:via-background dark:to-blue-950/10", accent: "border-blue-200/50 bg-blue-50/80 text-blue-600 dark:border-blue-500/20 dark:bg-blue-500/10 dark:text-blue-400", blob: "bg-blue-400/10 dark:bg-blue-500/5", collection: "brands" as const, floatSlugs: POPULAR_SLUGS, }, { badge: "Copy & Ship", badgeIcon: Zap, title: "SVG, JSX, CDN, or Download", description: "Every format you need. Copy raw SVG, grab a CDN link, or download files. Dark mode variants included.", cta: { label: "Browse Icons", href: "/" }, ctaSecondary: { label: "Extensions", href: "/extensions" }, gradient: "from-emerald-50/50 via-background to-emerald-50/30 dark:from-emerald-950/20 dark:via-background dark:to-emerald-950/10", accent: "border-emerald-200/50 bg-emerald-50/80 text-emerald-600 dark:border-emerald-500/20 dark:bg-emerald-500/10 dark:text-emerald-400", blob: "bg-emerald-400/10 dark:bg-emerald-500/5", collection: "brands" as const, floatSlugs: POPULAR_SLUGS, }, { badge: "AWS Architecture", badgeIcon: Cloud, title: "Every AWS Icon for Your Diagrams", description: "300+ service icons, 400+ resource icons, and category icons. Browse, copy, and use in architecture diagrams instantly.", cta: { label: "Browse Services", href: "#popular" }, ctaSecondary: { label: "All Categories", href: "#categories" }, gradient: "from-[#232f3e]/5 via-background to-[#ff9900]/5 dark:from-[#232f3e]/30 dark:via-background dark:to-[#ff9900]/10", accent: "border-[#ff9900]/30 bg-[#ff9900]/10 text-[#c47b12] dark:border-[#ff9900]/30 dark:bg-[#ff9900]/15 dark:text-[#ff9900]", blob: "bg-[#ff9900]/10 dark:bg-[#ff9900]/5", collection: "aws" as const, floatSlugs: POPULAR_AWS_SLUGS, }, { badge: "2026-Q1 Release", badgeIcon: Package, title: "Official AWS Architecture Icons", description: "Unmodified SVGs from the official AWS icon set. Updated quarterly. Services, resources, categories, and groups.", cta: { label: "Browse All", href: "#all" }, ctaSecondary: { label: "View License", href: "https://aws.amazon.com/architecture/icons/" }, gradient: "from-[#ff9900]/5 via-background to-[#232f3e]/5 dark:from-[#ff9900]/10 dark:via-background dark:to-[#232f3e]/20", accent: "border-[#232f3e]/20 bg-[#232f3e]/10 text-[#232f3e] dark:border-[#ff9900]/20 dark:bg-[#ff9900]/10 dark:text-[#ff9900]", blob: "bg-[#232f3e]/10 dark:bg-[#232f3e]/5", collection: "aws" as const, floatSlugs: POPULAR_AWS_SLUGS, }, { badge: "Microsoft Azure", badgeIcon: Cloud, title: "626 Azure Service Icons", description: "Every Azure service icon for your architecture diagrams. VMs, App Services, SQL, Cosmos DB, and more. Free to use.", cta: { label: "Browse Services", href: "#popular" }, ctaSecondary: { label: "All Categories", href: "#categories" }, gradient: "from-[#0078d4]/5 via-background to-[#0078d4]/5 dark:from-[#0078d4]/20 dark:via-background dark:to-[#0078d4]/10", accent: "border-[#0078d4]/30 bg-[#0078d4]/10 text-[#0078d4] dark:border-[#0078d4]/30 dark:bg-[#0078d4]/15 dark:text-[#3ba0e6]", blob: "bg-[#0078d4]/10 dark:bg-[#0078d4]/5", collection: "azure" as const, floatSlugs: POPULAR_AZURE_SLUGS, }, { badge: "2026-Q1 Release", badgeIcon: Package, title: "Official Azure Architecture Icons", description: "29 categories of Microsoft Azure service icons. Compute, Networking, Databases, AI, Security, and more.", cta: { label: "Browse All", href: "#all" }, ctaSecondary: { label: "View License", href: "https://learn.microsoft.com/en-us/azure/architecture/icons/" }, gradient: "from-[#0078d4]/5 via-background to-[#50e6ff]/5 dark:from-[#0078d4]/15 dark:via-background dark:to-[#50e6ff]/10", accent: "border-[#50e6ff]/30 bg-[#50e6ff]/10 text-[#0078d4] dark:border-[#50e6ff]/20 dark:bg-[#50e6ff]/10 dark:text-[#50e6ff]", blob: "bg-[#50e6ff]/10 dark:bg-[#50e6ff]/5", collection: "azure" as const, floatSlugs: POPULAR_AZURE_SLUGS, }, { badge: "Google Cloud", badgeIcon: Cloud, title: "214 GCP Service Icons", description: "Google Cloud Platform icons for architecture diagrams. Compute Engine, BigQuery, Cloud Run, GKE, and all GCP services.", cta: { label: "Browse Services", href: "#popular" }, ctaSecondary: { label: "All Categories", href: "#categories" }, gradient: "from-[#4285f4]/5 via-background to-[#34a853]/5 dark:from-[#4285f4]/20 dark:via-background dark:to-[#34a853]/10", accent: "border-[#4285f4]/30 bg-[#4285f4]/10 text-[#4285f4] dark:border-[#4285f4]/30 dark:bg-[#4285f4]/15 dark:text-[#6aa5f8]", blob: "bg-[#4285f4]/10 dark:bg-[#4285f4]/5", collection: "gcp" as const, floatSlugs: POPULAR_GCP_SLUGS, }, { badge: "Apache 2.0 License", badgeIcon: Package, title: "Official Google Cloud Icons", description: "Free GCP icons under Apache 2.0. Auto-categorized into Compute, Storage, AI, Networking, and more.", cta: { label: "Browse All", href: "#all" }, ctaSecondary: { label: "View License", href: "https://cloud.google.com/icons" }, gradient: "from-[#ea4335]/5 via-background to-[#fbbc05]/5 dark:from-[#ea4335]/10 dark:via-background dark:to-[#fbbc05]/10", accent: "border-[#34a853]/30 bg-[#34a853]/10 text-[#34a853] dark:border-[#34a853]/20 dark:bg-[#34a853]/10 dark:text-[#34a853]", blob: "bg-[#34a853]/10 dark:bg-[#34a853]/5", collection: "gcp" as const, floatSlugs: POPULAR_GCP_SLUGS, }, { badge: "Kubernetes", badgeIcon: Anchor, title: "38 Official Kubernetes Icons", description: "Pods, Deployments, Services, Ingress, ConfigMaps, and more. The full CNCF Kubernetes icon set for your architecture diagrams.", cta: { label: "Browse Icons", href: "#popular" }, ctaSecondary: { label: "All Resources", href: "#categories" }, gradient: "from-[#326ce5]/5 via-background to-[#326ce5]/5 dark:from-[#326ce5]/20 dark:via-background dark:to-[#326ce5]/10", accent: "border-[#326ce5]/30 bg-[#326ce5]/10 text-[#326ce5] dark:border-[#326ce5]/30 dark:bg-[#326ce5]/15 dark:text-[#5b8eef]", blob: "bg-[#326ce5]/10 dark:bg-[#326ce5]/5", collection: "k8s" as const, floatSlugs: POPULAR_K8S_SLUGS, }, { badge: "Apache 2.0 License", badgeIcon: Package, title: "CNCF Kubernetes Architecture Icons", description: "Official icons from the Kubernetes project. Free under Apache 2.0. Use in docs, diagrams, and presentations.", cta: { label: "Browse All", href: "#all" }, ctaSecondary: { label: "View License", href: "https://github.com/kubernetes/community/tree/master/icons" }, gradient: "from-[#326ce5]/5 via-background to-[#ffffff]/5 dark:from-[#326ce5]/15 dark:via-background dark:to-[#326ce5]/10", accent: "border-[#326ce5]/20 bg-[#326ce5]/10 text-[#326ce5] dark:border-[#326ce5]/20 dark:bg-[#326ce5]/10 dark:text-[#5b8eef]", blob: "bg-[#326ce5]/10 dark:bg-[#326ce5]/5", collection: "k8s" as const, floatSlugs: POPULAR_K8S_SLUGS, }, ]; const SLIDE_DURATION = 6000; interface HomeHeroProps { categoryCounts: { name: string; count: number }[]; count: number; recentIcons: IconEntry[]; collections: { name: Collection; count: number }[]; defaultCollection?: Collection; onSelectIcon: (icon: IconEntry) => void; onCategorySelect: (category: string) => void; onCollectionSelect: (collection: string) => void; } export function HomeHero({ categoryCounts: _categoryCounts, count, recentIcons, collections, defaultCollection, onCategorySelect, onCollectionSelect, }: HomeHeroProps) { // Lazy-load the full icons manifest for decorative elements (floating icons, // popular grids, category rows). The hero carousel content renders immediately; // icons appear progressively as the manifest loads. const [icons, setIcons] = useState([]); useEffect(() => { loadIconsManifest() .then(setIcons) .catch(() => { // Decorative elements are non-critical; silently ignore load failures }); }, []); const [currentSlide, setCurrentSlide] = useState(0); const [isPaused, setIsPaused] = useState(false); const [selectedIcon, setSelectedIcon] = useState(null); const [activeCollection, setActiveCollection] = useState(defaultCollection ?? "brands"); // Filter slides by active collection const collectionSlides = useMemo( () => ALL_SLIDES.filter((s) => s.collection === activeCollection), [activeCollection] ); // Reset slide when collection changes useEffect(() => { setCurrentSlide(0); }, [activeCollection]); // Auto-rotate carousel through collection slides useEffect(() => { if (isPaused || collectionSlides.length <= 1) return; const timer = setInterval(() => { setCurrentSlide((prev) => (prev + 1) % collectionSlides.length); }, SLIDE_DURATION); return () => clearInterval(timer); }, [isPaused, collectionSlides.length]); const handleSelectIcon = useCallback((icon: IconEntry) => { setSelectedIcon(icon); }, []); // Filter icons by active collection const collectionIcons = useMemo( () => icons.filter((i) => i.collection === activeCollection), [icons, activeCollection] ); // Popular icons per collection const popularIcons = useMemo(() => { const slugMap: Record = { brands: POPULAR_SLUGS, aws: POPULAR_AWS_SLUGS, azure: POPULAR_AZURE_SLUGS, gcp: POPULAR_GCP_SLUGS, k8s: POPULAR_K8S_SLUGS, }; const slugs = slugMap[activeCollection] ?? POPULAR_SLUGS; return slugs .map((slug) => icons.find((i) => i.slug === slug)) .filter(Boolean) as IconEntry[]; }, [icons, activeCollection]); // Categories for active collection const topCategories = useMemo(() => { const counts = new Map(); for (const icon of collectionIcons) { for (const c of icon.categories) { counts.set(c, (counts.get(c) || 0) + 1); } } return [...counts.entries()] .map(([name, count]) => ({ name, count })) .sort((a, b) => b.count - a.count) .slice(0, 8); }, [collectionIcons]); // Recently added for active collection const collectionRecentIcons = useMemo(() => { if (activeCollection === "brands") return recentIcons; return [...collectionIcons] .filter((i) => i.dateAdded) .sort((a, b) => (b.dateAdded as string).localeCompare(a.dateAdded as string)) .slice(0, 12); }, [activeCollection, collectionIcons, recentIcons]); const fallbackSlide = ALL_SLIDES[0]; const slide = collectionSlides.length > 0 ? collectionSlides[currentSlide % collectionSlides.length] : fallbackSlide; const BadgeIcon = slide.badgeIcon; // Pick 6 floating icons matching the current slide's collection const floatingIcons = useMemo(() => { const activeSlide = collectionSlides.length > 0 ? collectionSlides[currentSlide % collectionSlides.length] : fallbackSlide; const slugs = activeSlide.floatSlugs.slice(0, 6); return slugs .map((s) => icons.find((i) => i.slug === s)) .filter(Boolean) as IconEntry[]; }, [icons, currentSlide, collectionSlides, fallbackSlide]); // Predefined positions for floating icons (scattered, not grid) const FLOAT_POSITIONS = [ { top: "8%", right: "5%", size: "h-10 w-10", delay: "0s", opacity: "opacity-25" }, { top: "20%", right: "18%", size: "h-8 w-8", delay: "0.8s", opacity: "opacity-20" }, { top: "55%", right: "3%", size: "h-9 w-9", delay: "1.6s", opacity: "opacity-15" }, { top: "40%", right: "22%", size: "h-7 w-7", delay: "2.4s", opacity: "opacity-20" }, { top: "70%", right: "15%", size: "h-11 w-11", delay: "0.4s", opacity: "opacity-15" }, { top: "15%", right: "30%", size: "h-6 w-6", delay: "1.2s", opacity: "opacity-10" }, ]; return (
{/* Hero carousel - lifted card with depth */}
{/* Bottom shadow layer for lifted effect */}
setIsPaused(true)} onMouseLeave={() => setIsPaused(false)} > {/* Top highlight edge */}
{/* Min-height reserves space so rotating slide titles/descriptions of different lengths don't trigger Cumulative Layout Shift. Sized to the longest expected slide content. */}
{/* Slide content with fade */}
{slide.badge === "Open Source" ? `${count.toLocaleString()}+ icons` : slide.badge}

{slide.title}

{slide.description}

{slide.cta.href.startsWith("http") ? ( {slide.cta.label} ) : ( {slide.cta.label} )} {slide.ctaSecondary.label}
{/* Decorative blobs */}
{/* Floating scattered icons */}
{floatingIcons.map((icon, i) => { const pos = FLOAT_POSITIONS[i]; return (
); })}
{/* Thin glowing progress dots */}
{collectionSlides.map((_, i) => ( ))}
{/* Collection tabs */} {collections.length > 1 && (
{collections.map((col) => { const info = COLLECTION_LABELS[col.name]; const isActive = activeCollection === col.name; return ( ); })}
)} {/* Popular icons */}

{activeCollection === "aws" ? "Popular AWS Services" : activeCollection === "azure" ? "Popular Azure Services" : activeCollection === "gcp" ? "Popular GCP Services" : "Popular"}

{popularIcons.map((icon) => ( ))}
{/* Recently Added */} {collectionRecentIcons.length > 0 && (

Recently Added

{collectionRecentIcons.map((icon) => ( ))}
)} {/* Browse by category */}

Browse by Category

{topCategories.map((cat) => ( ))}
{/* All Icons - with infinite scroll */}

{activeCollection === "brands" ? "All Icons" : `All ${COLLECTION_LABELS[activeCollection]?.label ?? activeCollection} Icons`}

{collectionIcons.length.toLocaleString()}
{/* Cloud provider attributions */} {activeCollection === "aws" && (

AWS Architecture Icons provided under CC-BY-ND 2.0. Amazon Web Services and all related marks are trademarks of Amazon.com, Inc.

)} {activeCollection === "azure" && (

Microsoft Azure icons provided under MIT license. Microsoft Azure and all related marks are trademarks of Microsoft Corporation.

)} {activeCollection === "gcp" && (

Google Cloud icons provided under Apache 2.0 license. Google Cloud and all related marks are trademarks of Google LLC.

)} {/* Detail modal */} setSelectedIcon(null)} />
); }