l8components

Hero

Landing hero with animated headline, glowing background and call-to-action buttons.

l8components 1.0 is here

Buildbeautifulproducts,faster.

One design system for every product team. Accessible components, ready-made blocks and motion that feels right, all built on shadcn/ui.

Installation

npx shadcn@latest add @l8/hero

Usage

import { HeroBlock } from '@/components/blocks/hero';

export default function Page() {
  return <HeroBlock />;
}

Source

components/blocks/hero.tsx
"use client"

import Link from "next/link"
import { motion } from "motion/react"
import { ArrowRightIcon, SparklesIcon } from "lucide-react"

import { Badge } from "@/components/ui/badge"
import { buttonVariants } from "@/components/ui/button"

const words = ["Build", "beautiful", "products,", "faster."]

export function HeroBlock() {
  return (
    <section className="@container relative isolate overflow-hidden px-6 py-20 @2xl:py-28">
      <Glow />
      <div className="mx-auto flex max-w-3xl flex-col items-center text-center">
        <motion.div
          initial={{ opacity: 0, scale: 0.9 }}
          animate={{ opacity: 1, scale: 1 }}
          transition={{ duration: 0.5 }}
        >
          <Badge variant="outline" className="gap-1.5 rounded-full bg-background/60 px-3 py-1 backdrop-blur">
            <SparklesIcon className="text-primary" />
            l8components 1.0 is here
          </Badge>
        </motion.div>
        <h1 className="mt-6 text-4xl font-semibold tracking-tight text-balance @2xl:text-6xl">
          {words.map((word, i) => (
            <motion.span
              key={word}
              className="inline-block pr-[0.25em]"
              initial={{ opacity: 0, y: 24, filter: "blur(8px)" }}
              animate={{ opacity: 1, y: 0, filter: "blur(0px)" }}
              transition={{ duration: 0.6, delay: 0.15 + i * 0.1, ease: [0.22, 1, 0.36, 1] }}
            >
              {i === 1 ? (
                <span className="text-primary">
                  {word}
                </span>
              ) : (
                word
              )}
            </motion.span>
          ))}
        </h1>
        <motion.p
          className="mt-5 max-w-xl text-base text-muted-foreground @2xl:text-lg"
          initial={{ opacity: 0, y: 12 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.6, delay: 0.6 }}
        >
          One design system for every product team. Accessible components, ready-made
          blocks and motion that feels right, all built on shadcn/ui.
        </motion.p>
        <motion.div
          className="mt-8 flex flex-wrap justify-center gap-3"
          initial={{ opacity: 0, y: 12 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.6, delay: 0.75 }}
        >
          <Link href="/docs/components/button" className={buttonVariants({ size: "lg", className: "rounded-full px-5" })}>
            Browse components
            <ArrowRightIcon data-icon="inline-end" />
          </Link>
          <Link
            href="/docs/blocks/hero"
            className={buttonVariants({ size: "lg", variant: "outline", className: "rounded-full px-5" })}
          >
            Explore blocks
          </Link>
        </motion.div>
      </div>
    </section>
  )
}

function Glow() {
  return (
    <div aria-hidden className="pointer-events-none absolute inset-0 -z-10">
      <motion.div
        className="absolute top-[-20%] left-1/2 size-[36rem] -translate-x-1/2 rounded-full bg-primary/10 blur-3xl"
        animate={{ scale: [1, 1.15, 1], opacity: [0.6, 1, 0.6] }}
        transition={{ duration: 8, repeat: Infinity, ease: "easeInOut" }}
      />
      <motion.div
        className="absolute top-1/3 left-[10%] size-72 rounded-full bg-primary/5 blur-3xl"
        animate={{ x: [0, 40, 0], y: [0, -20, 0] }}
        transition={{ duration: 10, repeat: Infinity, ease: "easeInOut" }}
      />
      <motion.div
        className="absolute top-1/2 right-[10%] size-64 rounded-full bg-foreground/5 blur-3xl"
        animate={{ x: [0, -30, 0], y: [0, 30, 0] }}
        transition={{ duration: 12, repeat: Infinity, ease: "easeInOut" }}
      />
      <div className="absolute inset-0 bg-[radial-gradient(circle_at_center,var(--border)_1px,transparent_1px)] mask-[radial-gradient(ellipse_at_center,black,transparent_70%)] bg-size-[24px_24px]" />
    </div>
  )
}

On this page