Innovations
heroes /

AI Summit Hero (Glass Pill Nav + Speaker Mosaic)

Deep purple conference hero. Translucent glass-pill nav across the top with chip-icon logo, link cluster, and gradient Register CTA. Left: oversized sans-serif headline + intro paragraph + gradient Learn More button. Right: staggered 5-tile speaker portrait mosaic with rounded corners and subtle ring outlines. Built for AI / tech / conference / event landing pages.

Preview

Source

tsx
import { Cpu } from "lucide-react";

interface NavItem {
  label: string;
  href: string;
}

interface PortraitTile {
  src: string;
  alt: string;
}

export interface AiSummitHeroProps {
  brand?: string;
  navItems?: NavItem[];
  registerCta?: { label: string; href: string };
  headlinePart1?: string;
  headlinePart2?: string;
  body?: string;
  primaryCta?: { label: string; href: string };
  /** Speaker portraits. All tiles render at the same 3:4 portrait aspect; the two marquee columns are evenly split from this list. */
  portraits?: PortraitTile[];
  /** Deep purple background. */
  bgColor?: string;
  /** Brighter purple used for accent glow + CTA gradient. */
  accentColor?: string;
  /** Seconds for one full marquee loop. Lower = faster scroll. Default 50. */
  marqueeDurationSec?: number;
}

const DEFAULT_PORTRAITS: PortraitTile[] = [
  {
    src: "https://images.unsplash.com/photo-1531123897727-8f129e1688ce?w=900&h=1200&fit=crop&crop=faces",
    alt: "Speaker portrait with dramatic red and blue lighting on orange backdrop",
  },
  {
    src: "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=900&h=1200&fit=crop&crop=faces",
    alt: "Smiling speaker portrait in pink turtleneck against teal backdrop",
  },
  {
    src: "https://images.unsplash.com/photo-1525134479668-1bee5c7c6845?w=900&h=1200&fit=crop&crop=faces",
    alt: "Speaker portrait wearing a black cap against orange backdrop",
  },
  {
    src: "https://images.unsplash.com/photo-1488426862026-3ee34a7d66df?w=900&h=1200&fit=crop&crop=faces",
    alt: "Speaker portrait in red knit sweater",
  },
  {
    src: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=900&h=1200&fit=crop&crop=faces",
    alt: "Speaker portrait on teal backdrop",
  },
  {
    src: "https://images.unsplash.com/photo-1544005313-94ddf0286df2?w=900&h=1200&fit=crop&crop=faces",
    alt: "Speaker portrait — woman with curly hair",
  },
  {
    src: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=900&h=1200&fit=crop&crop=faces",
    alt: "Speaker portrait — bearded man",
  },
  {
    src: "https://images.unsplash.com/photo-1539571696357-5a69c17a67c6?w=900&h=1200&fit=crop&crop=faces",
    alt: "Speaker portrait — man in glasses",
  },
];

export default function AiSummitHero({
  brand = "AI SUMMIT",
  navItems = [
    { label: "Sessions", href: "#sessions" },
    { label: "Speakers", href: "#speakers" },
    { label: "Ticket Options", href: "#tickets" },
    { label: "FAQ", href: "#faq" },
  ],
  registerCta = { label: "Register Your Ticket", href: "#register" },
  headlinePart1 = "AI Horizons:",
  headlinePart2 = "Shaping the Future of Intelligence",
  body = "Join us at AI Tech Summit, the premier global event where industry leaders, innovators, and visionaries converge to explore the transformative power of artificial intelligence.",
  primaryCta = { label: "Learn More", href: "#learn-more" },
  portraits = DEFAULT_PORTRAITS,
  bgColor = "#3B1361",
  accentColor = "#A93AFF",
  marqueeDurationSec = 50,
}: AiSummitHeroProps) {
  const col1 = portraits.filter((_, i) => i % 2 === 0);
  const col2 = portraits.filter((_, i) => i % 2 === 1);
  const col1Loop = [...col1, ...col1];
  const col2Loop = [...col2, ...col2];

  return (
    <section
      className="ai-summit-hero relative isolate h-screen min-h-[760px] overflow-hidden font-sans text-white"
      style={{
        background: `radial-gradient(120% 90% at 90% 10%, ${accentColor}22, transparent 55%), radial-gradient(120% 90% at 10% 100%, ${accentColor}1f, transparent 60%), linear-gradient(160deg, ${bgColor} 0%, #1F0A36 100%)`,
      }}
    >
      {/* Soft accent glows */}
      <div
        aria-hidden
        className="pointer-events-none absolute -left-32 bottom-0 z-0 h-[420px] w-[420px] rounded-full opacity-50 blur-3xl"
        style={{ background: accentColor }}
      />
      <div
        aria-hidden
        className="pointer-events-none absolute right-1/3 -top-24 z-0 h-[320px] w-[320px] rounded-full opacity-30 blur-3xl"
        style={{ background: "#FF7A2D" }}
      />

      {/* PORTRAIT MARQUEES — absolute, anchored to right edge, full section height */}
      <div className="pointer-events-none absolute inset-y-0 right-0 z-10 hidden w-[48%] gap-3 px-4 sm:gap-4 lg:flex lg:px-8 xl:w-[46%]">
        {/* Column 1 — scrolling DOWN */}
        <div className="relative flex-1 overflow-hidden">
          <div
            className="flex flex-col gap-3 will-change-transform sm:gap-4"
            style={{
              animation: `aiSummitDown ${marqueeDurationSec}s linear infinite`,
            }}
          >
            {col1Loop.map((p, i) => (
              <PortraitFrame key={`c1-${i}`} img={p} />
            ))}
          </div>
        </div>
        {/* Column 2 — scrolling UP */}
        <div className="relative flex-1 overflow-hidden">
          <div
            className="flex flex-col gap-3 will-change-transform sm:gap-4"
            style={{
              animation: `aiSummitUp ${marqueeDurationSec}s linear infinite`,
            }}
          >
            {col2Loop.map((p, i) => (
              <PortraitFrame key={`c2-${i}`} img={p} />
            ))}
          </div>
        </div>
      </div>

      {/* FOREGROUND: nav + copy */}
      <div className="relative z-20 mx-auto flex h-full max-w-7xl flex-col px-4 sm:px-6 lg:px-8">
        {/* GLASS PILL NAV */}
        <nav className="mt-6 flex items-center justify-between gap-4 rounded-full border border-white/15 bg-white/10 px-4 py-2 backdrop-blur-md sm:px-5 sm:py-3">
          <a href="/" className="flex items-center gap-2 pl-1">
            <Cpu className="h-6 w-6" strokeWidth={1.5} />
            <span className="text-sm font-semibold tracking-[0.18em] sm:text-base">
              {brand}
            </span>
          </a>
          <div className="hidden items-center gap-8 md:flex">
            {navItems.map((item) => (
              <a
                key={item.label}
                href={item.href}
                className="text-sm font-medium text-white/85 transition-colors hover:text-white"
              >
                {item.label}
              </a>
            ))}
          </div>
          <a
            href={registerCta.href}
            className="rounded-full px-4 py-2 text-xs font-semibold transition-all hover:-translate-y-0.5 sm:px-6 sm:py-2.5 sm:text-sm"
            style={{
              background: `linear-gradient(135deg, ${accentColor} 0%, #6B1FB7 100%)`,
              boxShadow: `0 8px 24px ${accentColor}55`,
            }}
          >
            {registerCta.label}
          </a>
        </nav>

        {/* COPY BLOCK — vertically centered in remaining space */}
        <div className="flex flex-1 items-center py-10 lg:py-16">
          <div className="max-w-xl lg:max-w-[44%]">
            <h1 className="text-[44px] font-bold leading-[1.05] tracking-tight sm:text-5xl lg:text-6xl">
              {headlinePart1}
              <br />
              {headlinePart2}
            </h1>
            <p className="mt-7 max-w-md text-base leading-relaxed text-white/75">
              {body}
            </p>
            <a
              href={primaryCta.href}
              className="mt-10 inline-flex items-center rounded-full px-9 py-3.5 text-sm font-semibold transition-all hover:-translate-y-0.5"
              style={{
                background: `linear-gradient(135deg, ${accentColor} 0%, #6B1FB7 100%)`,
                boxShadow: `0 12px 32px ${accentColor}66`,
              }}
            >
              {primaryCta.label}
            </a>
          </div>
        </div>
      </div>

      <style>{`
        @keyframes aiSummitUp {
          from { transform: translateY(0); }
          to { transform: translateY(-50%); }
        }
        @keyframes aiSummitDown {
          from { transform: translateY(-50%); }
          to { transform: translateY(0); }
        }
        @media (prefers-reduced-motion: reduce) {
          .ai-summit-hero [style*="aiSummitUp"],
          .ai-summit-hero [style*="aiSummitDown"] {
            animation: none !important;
          }
        }
      `}</style>
    </section>
  );
}

function PortraitFrame({ img }: { img: PortraitTile }) {
  return (
    <div className="relative aspect-[3/4] w-full shrink-0 overflow-hidden rounded-2xl bg-white/5 shadow-lg ring-1 ring-white/10">
      <img
        src={img.src}
        alt={img.alt}
        loading="eager"
        decoding="async"
        className="absolute inset-0 h-full w-full object-cover"
      />
    </div>
  );
}
Claude Code Instructions

CLI Install

npx innovations add ai-summit-hero

Where to use it

Use for AI conferences, tech summits, speaker-led events — anywhere the speaker lineup IS the marketing. In Astro: --- import AiSummitHero from '../components/innovations/heroes/ai-summit-hero'; --- <AiSummitHero /> In Next.js (app/page.tsx): import AiSummitHero from '@/components/innovations/heroes/ai-summit-hero'; No client:* required — server-renderable, no hooks. CUSTOMIZATION: <AiSummitHero brand="AI SUMMIT" navItems={[ { label: "Sessions", href: "#sessions" }, { label: "Speakers", href: "#speakers" }, { label: "Ticket Options", href: "#tickets" }, { label: "FAQ", href: "#faq" }, ]} registerCta={{ label: "Register Your Ticket", href: "#register" }} headlinePart1="AI Horizons:" headlinePart2="Shaping the Future of Intelligence" body="..." primaryCta={{ label: "Learn More", href: "#learn-more" }} portraits={[ { src: "/speakers/1.jpg", alt: "..." }, // col1-top (tall 3:4) { src: "/speakers/2.jpg", alt: "..." }, // col1-bottom (square) { src: "/speakers/3.jpg", alt: "..." }, // col2-top (wide 4:3) { src: "/speakers/4.jpg", alt: "..." }, // col2-middle (tall 3:4) { src: "/speakers/5.jpg", alt: "..." }, // col2-bottom (wide 4:3) ]} bgColor="#3B1361" accentColor="#A93AFF" /> PORTRAIT TILES: 5 photos in a 2-col mosaic. Column 2 is offset down ~16px (sm:64px) to create the staggered feel. The asymmetric aspect ratios are intentional — keep tall portraits at 3:4 and crop strips at 4:3. PALETTE: deep purple (#3B1361) + accent magenta (#A93AFF) + warm orange glow. Both bgColor and accentColor are exposed as props for easy rebrand. Headline is white, body is white/75, all CTAs use a magenta→indigo gradient. NAV: floating glass-pill (border-white/15, bg-white/5, backdrop-blur-md). On mobile the link cluster hides; only the logo + Register CTA remain.