# Hero 03 - Digital Agency Hero Section

> High-impact digital agency hero section with cinematic background video, bold typography, brand driven headline, and clear CTA, perfect for creative studios and performance-focused marketing websites.

A shadcn/ui block from the [@shadcn-space](https://shadcnspace.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/shadcn-space/hero-03).

- Page, with a live preview: https://shadcn.exchange/r/shadcn-space/hero-03
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/shadcn-space/hero-03-light-1b4b1af97ac4d485.png
- Registry item: https://shadcnspace.com/r/hero-03.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://shadcnspace.com/r/hero-03.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `lucide-react`, `motion`
- Registry items: `dropdown-menu`

## Files

### `src/components/shadcn-space/blocks/hero-03/page.tsx`

```tsx
import HeroPage from "@/components/shadcn-space/blocks/hero-03/index";

const Page = () => {
  return (
    <HeroPage />
  );
};

export default Page;
```

### `src/components/shadcn-space/blocks/hero-03/hero.tsx`

```tsx
"use client";

import { useRef } from "react";
import { ArrowUpRight } from "lucide-react";
import { motion, useInView } from "motion/react";

const HeroSection: React.FC = () => {
  const sectionRef = useRef<HTMLElement>(null);
  const isInView = useInView(sectionRef, { once: true, amount: 0.1 });

  return (
    <section
      ref={sectionRef}
      className="relative flex items-end text-white bg-black h-full min-h-screen overflow-hidden"
    >
      {/* Background Video */}
      <video
        className="absolute top-0 left-0 w-full h-full object-cover"
        loop
        autoPlay
        muted
        playsInline
      >
        <source
          src="https://images.shadcnspace.com/assets/video/hero05-banner-video.mp4"
          type="video/mp4"
        />
      </video>

      {/* Overlay to improve text readability */}
      <div className="absolute inset-0 bg-black/50"></div>

      {/* Content */}
      <div className="relative z-10 mx-auto max-w-7xl px-4 xl:px-16">
        <div className="flex flex-col gap-4 sm:gap-6 py-10 sm:py-16">
          <div className="flex items-start gap-2.5 md:gap-4">
            <div className="w-10 h-10 sm:w-11 sm:h-11 shrink-0">
              <motion.img
                src={
                  "https://images.shadcnspace.com/assets/svgs/primary-leaf.svg"
                }
                alt="icon"
                width={44}
                height={44}
                animate={{ rotate: 360 }}
                transition={{ duration: 4, repeat: Infinity, ease: "linear" }}
              />
            </div>
            <p className="sm:text-base text-sm sm:leading-6 leading-5 font-normal text-white sm:max-w-sm">
              We create <span className="text-teal-400">high-performing</span>{" "}
              digital designs that elevate brands and enhance conversions.
            </p>
          </div>
          <motion.div
            initial={{ opacity: 0, y: 32 }}
            animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 32 }}
            transition={{ duration: 0.3, ease: "easeInOut", delay: 0.2 }}
            className="flex sm:flex-row flex-col items-start lg:items-baseline gap-4"
          >
            <h1 className="text-4xl sm:text-5xl md:text-7xl lg:text-8xl xl:text-9xl leading-10 lg:leading-32 font-bold">
              SHADCN®SPACE
            </h1>
            <div>
              <div className="bg-teal-400 rounded-full p-1 pl-8">
                <div className="lg:p-3 p-2 bg-white text-black rounded-full">
                  <ArrowUpRight size={24} />
                </div>
              </div>
            </div>
          </motion.div>
        </div>
      </div>
    </section>
  );
};

export default HeroSection;
```

### `src/components/shadcn-space/blocks/hero-03/navbar.tsx`

```tsx
"use client";

import { useEffect, useState, useRef } from "react";
import NavLink from "@/components/shadcn-space/blocks/hero-03/navlink";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Equal, X } from "lucide-react";
import { cn } from "@/lib/utils";
import { motion, useInView, AnimatePresence } from "motion/react";

type navData = {
  title: string;
  href: string;
};

type NavbarProps = {
  navigationData: navData[];
};

const Header = ({ navigationData }: NavbarProps) => {
  const [menuOpen, setMenuOpen] = useState(false);
  const [sticky, setSticky] = useState(false);
  const headerRef = useRef<HTMLElement>(null);
  const isInView = useInView(headerRef, { once: true, amount: 0.1 });

  const handleScroll = () => {
    setSticky(window.scrollY >= 80);
  };

  useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);

  return (
    <header
      ref={headerRef}
      className={cn(
        "sticky top-0 z-50 w-full border-t-4 border-teal-400 transition-all duration-500 ease-in-out h-20 flex items-center",
        "before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-0 before:bg-teal-400 before:transition-all before:duration-500 before:ease-in-out",
        sticky && "before:h-full"
      )}
    >
      <motion.nav
        initial={{ opacity: 0, y: -32 }}
        animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: -32 }}
        transition={{ duration: 0.7, ease: "easeInOut" }}
        className={cn(
          "relative mx-auto max-w-7xl px-4 xl:px-16 flex item-center justify-between w-full"
        )}
      >
        <a href="#">
          <img
            src="https://images.shadcnspace.com/assets/logo/shadcnspace-logo-white.svg"
            alt="brand logo"
            width={147}
            height={40}
          />
        </a>
        <div>
          <AnimatePresence>
            {menuOpen && (
              <motion.div
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                exit={{ opacity: 0 }}
                onClick={() => setMenuOpen(false)}
                className="fixed inset-0 z-40 bg-black/40 backdrop-blur-sm"
              />
            )}
          </AnimatePresence>
            <DropdownMenu open={menuOpen} onOpenChange={setMenuOpen}>
              {/* Trigger */}
              <DropdownMenuTrigger className="bg-white text-black flex items-center justify-center rounded-full sm:h-12 sm:w-12 h-10 w-10 p-2.5 sm:p-4 outline-none cursor-pointer">
                <Equal size={16} />
              </DropdownMenuTrigger>
              {/* Content */}
              <DropdownMenuContent
                align="end"
                sideOffset={20}
                className="min-w-xs sm:min-w-sm bg-background py-8 px-6 shadow-lg rounded-3xl border-none -mt-16"
              >
                <div className="flex flex-col gap-6">
                  {/* Header */}
                  <div className="flex items-center justify-between">
                    <p className="text-lg font-medium text-foreground">Menu</p>
                    <button
                      onClick={() => setMenuOpen(false)}
                      className="text-muted-foreground hover:text-foreground cursor-pointer"
                    >
                      <X size={20} />
                    </button>
                  </div>
                  <hr className="border-border" />
                  {/* Navigation */}
                  <ul className="flex flex-col gap-4 pb-4">
                    {navigationData.map((menuItem, index) => (
                      <NavLink key={index} item={menuItem} />
                    ))}
                  </ul>
                  {/* Contact */}
                  <div className="flex flex-col">
                    <a
                      href="tel:+1-212-456-7890"
                      className="text-lg font-normal leading-7 text-muted-foreground w-fit hover:text-primary"
                    >
                      +1-212-456-7890
                    </a>
                    <a
                      href="mailto:info@wrappixel.com"
                      className="text-2xl font-semibold leading-8 text-foreground w-fit"
                    >
                      info@wrappixel.com
                    </a>
                  </div>
                </div>
              </DropdownMenuContent>
            </DropdownMenu>
        </div>
      </motion.nav>
    </header>
  );
};

export default Header;
```

### `src/components/shadcn-space/blocks/hero-03/navlink.tsx`

```tsx
import { cn } from "@/lib/utils";

export type NavLinkItem = {
  title: string;
  href: string;
  isActive?: boolean;
};

export interface NavLinkProps {
  item: NavLinkItem;
  onClick?: () => void;
}

const NavLink: React.FC<NavLinkProps> = ({ item, }) => {
  const { title, href, isActive } = item;

  return (
    <li className={cn(`group flex items-center transition-all duration-500 ease-in-out w-fit`,
      isActive ? "gap-3" : "gap-0 hover:gap-3"
    )}>
      <div
        className={cn(
          "overflow-hidden transition-all duration-500 ease-in-out",
          isActive ? "max-w-6 opacity-100" : "max-w-0 opacity-0 group-hover:max-w-6 group-hover:opacity-100",
        )}
      >
        <img
          src="https://images.shadcnspace.com/assets/svgs/primary-leaf.svg"
          alt="icon"
          height={20}
          width={20}
          className="animate-spin"
        />
      </div>
      <a
        href={href}
        className="text-foreground text-2xl sm:text-4xl sm:leading-10 leading-8 font-semibold"
      >
        {title}
      </a>
    </li>
  );
};

export default NavLink;
```

### `src/components/shadcn-space/blocks/hero-03/index.tsx`

```tsx
import Navbar from "@/components/shadcn-space/blocks/hero-03/navbar";
import { NavLinkItem } from "@/components/shadcn-space/blocks/hero-03/navlink";
import HeroSection from "@/components/shadcn-space/blocks/hero-03/hero";

const HeroPage = () => {
  const navigationData: NavLinkItem[] = [
    { title: "Home", href: "#", isActive: true },
    { title: "Properties", href: "#", isActive: false },
    { title: "Blog", href: "#", isActive: false },
    { title: "Contact", href: "#", isActive: false },
    { title: "Docs", href: "#", isActive: false },
  ];
  return (
    <>
      <Navbar navigationData={navigationData} />
      <main className="-mt-20">
        <HeroSection />
      </main>
    </>
  );
};

export default HeroPage;
```
