Skip to content
Sign in
MarketingHero ASCIIMenu

Hero ASCIIPro

A hero with the product screenshot set in ASCII beside the headline. When it scrolls into view it resolves, once, from characters into the real screenshot.

ProA product screenshot set in ASCII beside the headline, resolving into the real screenshot once it scrolls into view.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/hero-ascii

Usage

tsx
import { HeroAscii } from "@/components/ui/chatcn/pro/hero-ascii"

<HeroAscii
  title="Meetings, written down while they happen."
  src="/shots/notes.png"
  darkSrc="/shots/notes-dark.png"
  alt="The notes for a pricing review"
  url="app.example.com/meetings"
/>

The screenshot waits as ASCII until half of it is on screen, then resolves row by row into the picture, once. The character density follows the width the shot first appears at (about one character per 8 px) and then holds, so a resize mid reveal never rebuilds the grid. It sits in a browser frame with your url, or bare with frame={false}. Pass darkSrc and the shot follows the theme: the reveal plays once with the matching screenshot, and a later theme switch crossfades to the other one without playing it again. Serve the screenshot from your own domain or with CORS, at 2x its display size.

Every section is full width with a 16 px gutter on phones and 32 px from 768 px, content capped at 1200 px. Layout follows the section's own width through a container query, not the viewport, so a section in a narrow column lays out like a phone.

Examples

Bare frame and error

The shot on the start side without a frame in coarse characters, and the error state.

ProThe shot on the start side without a frame in coarse characters, and the error state.

Props

PropTypeNotes
titleReactNodeRequired. One idea; it balances over two or three lines
descriptionReactNodeThe paragraph under or beside the headline
actionsReactNodeButtons or links under the paragraph
src, altstringRequired. alt is what screen readers hear
darkSrcstringThe shot in your dark theme. Shown wherever the hero sits on a dark surface
aspectRationumber | "16:10"Default 16:10
frame, urlBrowser frame and its URL. Default on
durationnumberReveal length in ms. Default 2600
thresholdnumberShare visible before it plays. Default 0.5
columnsnumberCharacters across. Default from the width, 48 to 128
imageSide"start" | "end"Default end
onRevealed() => voidOnce, when the screenshot shows

Keyboard

KeyAction
TabReaches your actions. The screenshot takes no focus

Accessibility

  • The section is labelled by its headline. Heroes use an h1, other sections an h2; render one hero per page.
  • The characters are aria-hidden; the real screenshot with your alt is always in the page.
  • Under forced-colors: active the screenshot shows at once.

Motion

  • Rows resolve top to bottom over 2.6 s, once per page view.
  • Under reduced motion the ASCII crossfades into the screenshot.
  • With darkSrc, a theme switch after the reveal crossfades the shot in 200 ms instead of replaying it.