Split Hero with Terminal Card

About this block

Split Hero with Terminal CardPRO

Fullscreen split hero with content left and realistic terminal/CLI card right over inset background video

Hero101: Split Hero with Terminal Card

Fullscreen split hero: heading, description, and CTAs on the left, a realistic dark-themed terminal window on the right whose command/output lines type themselves in on load, all layered over an inset background video panel.

Upgrade to Pro

Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.

Upgrade Now

Installation

Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.

Radix flavor

bash
npx shadcn add "https://ui.beste.co/r/hero101?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://ui.beste.co/r-base/hero101?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/hero101.tsx and its dependencies: the badge and button shadcn/ui primitives.

Quick start

The installed file exports hero101Demo alongside the block: the exact props behind the preview above. Spread it to get a working hero in one line.

tsx
import { Hero101, hero101Demo } from "@/components/beste/block/hero101";

export default function Page() {
  return <Hero101 {...hero101Demo} />;
}

Then replace the demo with your own props. Written out, the same setup looks like this:

tsx
import { Hero101 } from "@/components/beste/block/hero101";

export default function Page() {
  return (
    <Hero101
      badge={{ label: "Developer First", variant: "secondary" }}
      heading="Deploy in seconds, not hours"
      description="One command to go from local to global."
      buttons={[
        { label: "Get Started", href: "/signup", variant: "default" },
        { label: "Read Docs", href: "/docs", variant: "outline" },
      ]}
      backgroundMedia={{ type: "video", src: "/videos/hero.mp4" }}
      terminalTitle="Terminal — zsh"
      terminalLines={[
        { type: "command", text: "npx create-app my-project" },
        { type: "output", text: "Installing dependencies..." },
        { type: "success", text: "✓ Project created successfully" },
      ]}
    />
  );
}

Props

PropTypeDefaultDescription
badgeBadge–Pill shown above the heading
headingstring–Main headline
descriptionstring–Supporting copy under the heading
buttonsButtonItem[][]CTA buttons under the description
backgroundMediaBackgroundMedia–Video or image behind the whole section
terminalLinesTerminalLine[][]Lines rendered inside the terminal card, in order
terminalTitlestring"Terminal"Text centered in the terminal's title bar
invertColorbooleantrueLight-on-dark treatment (white text, black overlay) vs. dark-on-light
classNamestring–Extra classes for the outer <section>
ts
type Badge = { label: string; variant?: "default" | "secondary" | "outline" };
type ButtonItem = { label: string; href: string; variant?: "default" | "outline" };
type BackgroundMedia = { type: "image" | "video"; src: string; alt?: string };
type TerminalLine = { type: "command" | "output" | "success" | "comment"; text: string };

Behavior notes

  • The terminal card is a fixed dark surface (bg-gray-950) that ignores invertColor; only the hero's own text and the background overlay respond to that prop.
  • Each terminalLines entry types itself in via a CSS keyframe (hero101-type), animating max-width from 0 to 600px over 0.6s with a steps(40, end) timing function so the text reveals character-by-character rather than fading. Lines are staggered 0.8s apart (delay = index * 0.8), so the whole block plays out sequentially on mount, not on scroll or hover.
  • type: "command" lines are prefixed with a green $ and rendered in light gray; output lines are dimmer gray; success lines render in emerald; comment lines are the dimmest gray. Colors are fixed per type, not configurable per line.
  • After the last configured line finishes typing, a blinking cursor block (animate-pulse) fades in via a second keyframe (hero101-fadein) timed to start exactly when the last line's animation would complete (terminalLines.length * 0.8), simulating a live, ready-for-input prompt.
  • The video/image background is inset on all sides (inset-x-6 top-6 bottom-6, wider on lg) rather than full-bleed, matching the panel treatment used across this hero set.

More Hero blocks

View all Hero
PRO

hero84

Split Hero with Edge-to-Edge Media

PRO

hero91

Split Hero with Feature List Panel

PRO

hero102

Split Hero with Timeline Steps

Get Pro access