l8components

Features

Bento grid of feature cards that reveal on scroll and lift on hover.

Why l8components

Everything a product team needs

60+ components

Every shadcn/ui primitive, themed for our brand and documented with live examples.

Accessible

Keyboard, focus and screen readers handled by Base UI.

Themeable

One set of CSS variables drives every color and radius.

Dark mode

Light and dark out of the box, no extra work.

Copy & own

Install with the shadcn CLI. The code lives in your repo.

Motion built in

Blocks ship with tasteful animations that respect reduced-motion settings.

Installation

npx shadcn@latest add @l8/features

Usage

import { FeaturesBlock } from '@/components/blocks/features';

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

Source

components/blocks/features.tsx
"use client"

import { motion } from "motion/react"
import {
  AccessibilityIcon,
  BlocksIcon,
  MoonStarIcon,
  PaletteIcon,
  WandSparklesIcon,
  ZapIcon,
  type LucideIcon,
} from "lucide-react"

import { Reveal } from "@/components/motion"

const features: { icon: LucideIcon; title: string; text: string; className?: string }[] = [
  {
    icon: BlocksIcon,
    title: "60+ components",
    text: "Every shadcn/ui primitive, themed for our brand and documented with live examples.",
    className: "@xl:col-span-2",
  },
  { icon: AccessibilityIcon, title: "Accessible", text: "Keyboard, focus and screen readers handled by Base UI." },
  { icon: PaletteIcon, title: "Themeable", text: "One set of CSS variables drives every color and radius." },
  { icon: MoonStarIcon, title: "Dark mode", text: "Light and dark out of the box, no extra work." },
  { icon: ZapIcon, title: "Copy & own", text: "Install with the shadcn CLI. The code lives in your repo." },
  {
    icon: WandSparklesIcon,
    title: "Motion built in",
    text: "Blocks ship with tasteful animations that respect reduced-motion settings.",
    className: "@xl:col-span-3",
  },
]

export function FeaturesBlock() {
  return (
    <section className="@container px-6 py-16">
      <Reveal className="mx-auto max-w-2xl text-center">
        <p className="text-sm font-medium text-primary">Why l8components</p>
        <h2 className="mt-2 text-3xl font-semibold tracking-tight text-balance">
          Everything a product team needs
        </h2>
      </Reveal>
      <div className="mx-auto mt-10 grid max-w-5xl gap-4 @xl:grid-cols-3">
        {features.map((f, i) => (
          <Reveal key={f.title} delay={i * 0.06} className={f.className}>
            <motion.div
              whileHover={{ y: -4 }}
              transition={{ type: "spring", stiffness: 300, damping: 20 }}
              className="group relative h-full overflow-hidden rounded-xl border bg-card p-6"
            >
              <div className="absolute -top-16 -right-16 size-40 rounded-full bg-primary/0 blur-2xl transition-colors duration-500 group-hover:bg-primary/10" />
              <div className="flex size-10 items-center justify-center rounded-xl border bg-muted">
                <f.icon className="size-5" />
              </div>
              <h3 className="mt-4 font-medium">{f.title}</h3>
              <p className="mt-1 text-sm text-muted-foreground">{f.text}</p>
            </motion.div>
          </Reveal>
        ))}
      </div>
    </section>
  )
}

On this page