---
title: Hero
description: Landing page hero with title, lede, and actions
visibility: guest
draft: false
---

# Hero

A landing page hero section with title, lede, actions, and optional aside content.

## Basic Usage

:::preview{title="Default hero"}
<x-wirekit::hero>
    <x-slot:title>Build faster with WireKit.</x-slot:title>
    <x-slot:lede>Free, open-source UI components for Laravel Livewire.</x-slot:lede>
    <x-slot:actions>
        <x-wirekit::button>Get Started</x-wirekit::button>
    </x-slot:actions>
</x-wirekit::hero>
:::

## With Eyebrow

:::preview{title="Hero with eyebrow badge"}
<x-wirekit::hero>
    <x-slot:eyebrow><x-wirekit::badge>Open Source</x-wirekit::badge></x-slot:eyebrow>
    <x-slot:title>UI components for Laravel.</x-slot:title>
    <x-slot:lede>Styled with Tailwind CSS v4 and Alpine.js.</x-slot:lede>
    <x-slot:actions>
        <x-wirekit::button>Docs</x-wirekit::button>
        <x-wirekit::button intent="neutral" surface="outline">GitHub</x-wirekit::button>
    </x-slot:actions>
</x-wirekit::hero>
:::

## Dark Variant

On `variant="dark"` heroes, pair the call-to-action button with `intent="neutral" surface="filled"` so the button reads as a high-contrast pill against the dark surface. The default `intent="primary"` button uses the accent color, which works on light backgrounds but may collide with the dark hero's foreground tokens depending on theme — neutral-filled is the safe default for dark sections.

:::preview{title="Dark hero section"}
<x-wirekit::hero variant="dark">
    <x-slot:title>Ship faster, ship better.</x-slot:title>
    <x-slot:lede>Production-ready components out of the box.</x-slot:lede>
    <x-slot:actions>
        <x-wirekit::button intent="neutral" surface="filled">Get Started</x-wirekit::button>
    </x-slot:actions>
</x-wirekit::hero>
:::

## Accent Variant

:::preview{title="Accent-colored hero"}
<x-wirekit::hero variant="accent">
    <x-slot:title>Ready to launch?</x-slot:title>
    <x-slot:lede>Everything you need in one library.</x-slot:lede>
</x-wirekit::hero>
:::

## Layouts

The `layout` prop controls how the copy column and the optional `aside` slot share the available width. Four layouts are available:

| Layout | When to use | Behavior |
| --- | --- | --- |
| `balanced` (default) | Standard product hero with a copy column and a media/code aside | 50/50 split at `lg+`, stacked below |
| `lead` | Long-form copy where the headline + lede dominate over the aside | 60/40 split (copy: `flex-[3]`, aside: `flex-[2]`) at `lg+` |
| `centered` | Marketing hero without an aside, or when you want the copy on top with a centered narrow column | Single column, max-w container-md, copy stays `text-center` at every breakpoint |
| `stacked` | Showcase pages where copy + media should always be full-width and vertically stacked | Both columns `w-full`, column flow at every breakpoint |

:::preview{title="Centered hero (no aside, narrow column)"}
<x-wirekit::hero layout="centered">
    <x-slot:eyebrow><x-wirekit::badge>v1.3</x-wirekit::badge></x-slot:eyebrow>
    <x-slot:title>The fastest way to ship a Laravel UI.</x-slot:title>
    <x-slot:lede>One package, a full component library, full theming. Click the button below to get started.</x-slot:lede>
    <x-slot:actions>
        <x-wirekit::button>Get Started</x-wirekit::button>
        <x-wirekit::button intent="neutral" surface="outline">View on GitHub</x-wirekit::button>
    </x-slot:actions>
</x-wirekit::hero>
:::

:::preview{title="Lead hero — copy gets the larger share"}
<x-wirekit::hero layout="lead">
    <x-slot:title>Built for Livewire teams.</x-slot:title>
    <x-slot:lede>Pair WireKit with Livewire 4 for instant interactivity, server-driven validation, and zero JavaScript build steps in your day-to-day work.</x-slot:lede>
    <x-slot:actions>
        <x-wirekit::button>Open the docs</x-wirekit::button>
    </x-slot:actions>
    <x-slot:aside>
        <x-wirekit::card>
            <x-wirekit::card.body>Aside content keeps its 40% column.</x-wirekit::card.body>
        </x-wirekit::card>
    </x-slot:aside>
</x-wirekit::hero>
:::

:::preview{title="Stacked hero — copy and aside both full-width"}
<x-wirekit::hero layout="stacked">
    <x-slot:title>One library, every surface.</x-slot:title>
    <x-slot:lede>Use WireKit for both your app shell and your marketing pages.</x-slot:lede>
    <x-slot:aside>
        <x-wirekit::feature-grid cols="1 sm:3">
            <x-wirekit::feature icon="bolt" title="Fast">Compositor-only animations and tree-shakeable bundles ship the smallest possible runtime to your users.</x-wirekit::feature>
            <x-wirekit::feature icon="shield" title="Safe">WCAG 2.1 AA contrast on every preset, focus management out of the box, and a hard tested keyboard contract.</x-wirekit::feature>
            <x-wirekit::feature icon="sparkles" title="Polished">Carefully tuned micro-interactions, dark-mode parity, and a curated motion system that respects reduced-motion.</x-wirekit::feature>
        </x-wirekit::feature-grid>
    </x-slot:aside>
</x-wirekit::hero>
:::

::: tip
Even with `layout="centered"`, an `aside` slot is preserved — it renders below the copy in column flow. If you want the centered look without an aside, simply omit the slot.
:::

## Gradients

`<x-wirekit::hero>` ships one built-in gradient prop and supports three orthogonal customization techniques on top of it. Pick by intent:

| Intent | Tool | Detail |
| --- | --- | --- |
| Subtle corner emphasis ("depth without color change") | `gradient` prop | Single token-aware overlay; works on every variant |
| Headline-only color wash | `bg-clip-text` on a `<span>` | Token-stop gradient runs through the glyphs only |
| Full-bleed custom background | wrapper-level `background` inline style | Replace the variant entirely |
| Per-variant overlay tweak | CSS scope on `.wk-hero` + variant data-attr | Override the overlay shape per variant |

### 1. `gradient` prop — built-in overlay

The optional `gradient` prop adds a soft diagonal overlay on top of the variant background — `to-black/20` on light variants, `to-white/30` on dark / accent. It emphasizes the bottom-right corner without changing text contrast (every variant + overlay pair is WCAG AA against the slot text colors).

The overlay direction is fixed (`bg-gradient-to-br` = top-left → bottom-right). The color adapts to the variant — light variants darken, dark / accent lighten. The 20-30% alpha keeps the overlay subtle enough that the variant background color reads through clearly.

:::preview{title="Default variant + gradient" wide}
<x-wirekit::hero size="sm" gradient>
    <x-slot:title>Subtle depth, default variant.</x-slot:title>
    <x-slot:lede>The `gradient` prop adds a soft `to-black/20` overlay on the default light surface.</x-slot:lede>
</x-wirekit::hero>
:::

:::preview{title="Dark variant + gradient" wide}
<x-wirekit::hero size="sm" variant="dark" gradient>
    <x-slot:title>Subtle depth, dark variant.</x-slot:title>
    <x-slot:lede>On dark variants the overlay flips to `to-white/30` so the bottom-right corner reads brighter, not darker.</x-slot:lede>
</x-wirekit::hero>
:::

:::preview{title="Accent variant + gradient" wide}
<x-wirekit::hero size="sm" variant="accent" gradient>
    <x-slot:title>Same overlay, accent variant.</x-slot:title>
    <x-slot:lede>Accent surfaces inherit the dark-style `to-white/30` overlay because the accent color is bright enough that a darker bottom-right would muddy the contrast.</x-slot:lede>
</x-wirekit::hero>
:::

:::preview{title="Muted variant + gradient" wide}
<x-wirekit::hero size="sm" variant="muted" gradient>
    <x-slot:title>Muted variant — the most subtle pairing.</x-slot:title>
    <x-slot:lede>Muted backgrounds are gentle by design; the gradient adds the lightest possible depth cue without competing with the lede text.</x-slot:lede>
</x-wirekit::hero>
:::

### 2. Gradient on the headline text (`bg-clip-text`)

For a different shape of visual emphasis, run the gradient ACROSS the headline text instead of behind the section. Wrap the focal word in a `<span>` with `background-clip: text` and a `linear-gradient` background:

:::preview{title="Token-stop gradient on a focal word"}
<x-wirekit::hero variant="muted">
    <x-slot:title>
        Build <span style="background: linear-gradient(to right, var(--color-wk-accent), var(--color-wk-success), var(--color-wk-warning)); -webkit-background-clip: text; background-clip: text; color: transparent;">faster</span> with WireKit.
    </x-slot:title>
    <x-slot:lede>Wrap the focal word in an inline span with `background-clip: text`. The rest of the title stays at native color for contrast.</x-slot:lede>
</x-wirekit::hero>
:::

:::preview{title="Accent-to-danger sweep"}
<x-wirekit::hero variant="default">
    <x-slot:title>
        From <span style="background: linear-gradient(to right, var(--color-wk-accent), var(--color-wk-danger)); -webkit-background-clip: text; background-clip: text; color: transparent;">spark</span> to ship.
    </x-slot:title>
    <x-slot:lede>Two-stop gradients work just as well — the right color pair tells a small story (here: accent = exciting, danger = urgent).</x-slot:lede>
</x-wirekit::hero>
:::

:::preview{title="Subtle accent + text-muted blend"}
<x-wirekit::hero variant="default">
    <x-slot:title>
        The <span style="background: linear-gradient(to right, var(--color-wk-accent), var(--color-wk-text-muted)); -webkit-background-clip: text; background-clip: text; color: transparent;">quiet</span> way to add emphasis.
    </x-slot:title>
    <x-slot:lede>When the brand voice is calm, pair accent with `text-muted` for a near-invisible gradient that still reads as intentional design.</x-slot:lede>
</x-wirekit::hero>
:::

The pattern works on every variant. Pick gradient stops from the active theme tokens (`--color-wk-accent`, `--color-wk-success`, `--color-wk-warning`, `--color-wk-danger`, `--color-wk-text-muted`) so the gradient adapts to dark mode automatically. For static stops (e.g. brand-locked palettes), use raw hex values instead — they won't follow the theme switcher.

### 3. Full-bleed custom background

When the built-in overlay isn't enough — animated gradients, multi-stop radial backgrounds, image overlays — replace the variant background entirely by setting `style="..."` on the hero. The component still renders its slots, paddings, and overlay layers; only the surface color changes:

:::preview{title="Radial brand gradient — custom background"}
<x-wirekit::hero style="background: radial-gradient(ellipse at top right, color-mix(in srgb, var(--color-wk-accent) 25%, transparent), transparent 60%), var(--color-wk-bg);">
    <x-slot:title>Radial brand gradient.</x-slot:title>
    <x-slot:lede>Inline `style` overrides the variant background. `color-mix` keeps the color theme-aware; the second layer falls back to `--color-wk-bg` so the rest of the surface stays themed.</x-slot:lede>
</x-wirekit::hero>
:::

:::preview{title="Conic gradient — multi-stop palette"}
<x-wirekit::hero style="background: conic-gradient(from 200deg at 70% 50%, color-mix(in oklab, #74B9FF 18%, transparent), color-mix(in oklab, #A29BFE 16%, transparent), color-mix(in oklab, #FD79A8 14%, transparent), color-mix(in oklab, #FAB1A0 12%, transparent), color-mix(in oklab, #74B9FF 18%, transparent)), var(--color-wk-bg);">
    <x-slot:title>Conic gradient pulled toward the right side.</x-slot:title>
    <x-slot:lede>Conic gradients work especially well as hero backdrops — the rotation center gives the eye a focal anchor. This sweep uses a sky → lavender → pink → coral palette mixed with the surface at low alpha so it reads as a soft atmospheric backdrop, not a saturated billboard.</x-slot:lede>
</x-wirekit::hero>
:::

### Customizing the built-in overlay shape

The `gradient` prop's overlay sits at `.absolute.inset-0.bg-gradient-to-br` inside the hero. To customize its direction / opacity / color stops, target the `.wk-hero[data-gradient="true"] .bg-gradient-to-br` selector in your app CSS:

```css
/* Override the gradient overlay to be a left-to-right wash instead */
.wk-hero[data-gradient="true"] > .bg-gradient-to-br {
    background-image: linear-gradient(
        to right,
        transparent 0%,
        color-mix(in srgb, var(--color-wk-accent) 12%, transparent) 100%
    );
}
```

Keep contrast ratios in mind — anything stronger than 30% alpha is likely to push slot text below WCAG AA on at least one of the four variants. Test with `prefers-color-scheme: dark` AND `light`.

### Choosing between the techniques

- **`gradient` prop**: default choice for marketing landing pages. Subtle, theme-aware, no setup.
- **`bg-clip-text`**: when the goal is to draw attention to a specific WORD in the headline (call-to-action, brand verb, product name).
- **Custom background**: when the hero is the page's primary visual identity (product launch pages, brand showcase) and the built-in overlay isn't expressive enough.
- **Stack them**: all three techniques can coexist. Custom background + `gradient` prop + `bg-clip-text` headline is a valid combination — the overlay sits ABOVE the custom background but BELOW the slot content, so the headline gradient stays on top.

To customize the section-level overlay itself (different angle, different stops, different color), target the absolute-positioned `.bg-gradient-to-br` overlay with your own CSS, or wrap the hero in a parent that establishes its own background-gradient.

## Responsive considerations

The hero's vertical padding adapts to the viewport. The `size` prop names the **`sm+` (tablet and up)** tier; the mobile viewport (< sm breakpoint, typically < 640 px) drops one tier so the section doesn't overshoot small screens:

| `size` | Mobile (< sm) | sm+ |
|--------|---------------|-----|
| `sm`   | `--space-wk-section-sm` (3 rem) | `--space-wk-section-sm` (3 rem) |
| `md`   | `--space-wk-section-sm` (3 rem) | `--space-wk-section-md` (5 rem) |
| `lg`   | `--space-wk-section-md` (5 rem) | `--space-wk-section-lg` (7 rem) |

The values above show the bundled defaults; override `--space-wk-section-{sm,md,lg}` in your `app.css` `:root {}` block to customize the scale globally. See [Theming → Responsive token overrides](../theming.md#responsive-token-overrides) for the advanced pattern that flips the tokens themselves per viewport.

The three tiers side-by-side:

The hero sections below use `variant="muted"` so the vertical padding boundary is visible against the surrounding page background — on the default white surface the padding is invisible.

:::preview{title="Hero size — sm / md / lg" wide}
<x-wirekit::hero size="sm" variant="muted">
    <x-slot:eyebrow><x-wirekit::badge intent="accent">size sm</x-wirekit::badge></x-slot:eyebrow>
    <x-slot:title>Tight</x-slot:title>
    <x-slot:lede>3 rem vertical padding on every viewport.</x-slot:lede>
</x-wirekit::hero>

<x-wirekit::hero size="md" variant="muted">
    <x-slot:eyebrow><x-wirekit::badge intent="accent">size md</x-wirekit::badge></x-slot:eyebrow>
    <x-slot:title>Balanced</x-slot:title>
    <x-slot:lede>3 rem on mobile, 5 rem on sm+.</x-slot:lede>
</x-wirekit::hero>

<x-wirekit::hero size="lg" variant="muted">
    <x-slot:eyebrow><x-wirekit::badge intent="accent">size lg</x-wirekit::badge></x-slot:eyebrow>
    <x-slot:title>Roomy</x-slot:title>
    <x-slot:lede>5 rem on mobile, 7 rem on sm+. The marketing-default.</x-slot:lede>
</x-wirekit::hero>
:::

### Tight mobile padding for `size="lg"`

Dark-variant heroes with `size="lg"` carry 5 rem of bottom padding on mobile viewports. Combined with a gradient overlay on a near-black background, that band reads as a visible dead-zone below the content on iPhone-class viewports (390 px wide). The opt-in `tightOnMobile` prop drops mobile to `--space-wk-section-sm` (3 rem) while preserving the desktop `--space-wk-section-lg` (7 rem) tier — you keep the visually heaviest desktop spacing without the mobile overshoot.

:::preview{title="Hero size=lg with tightOnMobile" wide}
<x-wirekit::hero size="lg" tightOnMobile variant="dark" gradient>
    <x-slot:eyebrow><x-wirekit::badge>tight mobile</x-wirekit::badge></x-slot:eyebrow>
    <x-slot:title>Compact below, roomy above</x-slot:title>
    <x-slot:lede>3 rem on mobile, 7 rem on sm+. Set the prop on any dark hero that hosts a code-block or screenshot in its aside slot.</x-slot:lede>
    <x-slot:actions>
        <x-wirekit::button intent="neutral" surface="filled">Get started</x-wirekit::button>
    </x-slot:actions>
</x-wirekit::hero>
:::

### Gradient overlay containment

When `gradient` is set, the overlay is anchored to the inner content wrapper (max-w-xl) — NOT the outer `<section>`. This keeps the depth-cue at the visible content corner instead of bleeding into the section's vertical-padding band, which on mobile under `variant="dark"` previously showed a large empty dark area below content. The overlay carries `pointer-events-none` so it never intercepts clicks on the action buttons it visually covers.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `variant` | string | `'default'` | Visual variant: `default`, `dark`, `accent`, `muted` |
| `gradient` | bool | `false` | Add a soft `to-black/10` gradient overlay on top of the variant background. Subtle by design — emphasizes the bottom-right corner without affecting text contrast (verified against WCAG AA on every variant). To customize: target the absolute-positioned `.bg-gradient-to-br` overlay with your own CSS, or wrap the hero in a parent that establishes its own gradient |
| `layout` | string | `'balanced'` | Column layout: `balanced` (50/50), `lead` (60/40), `centered` (single column, max-w-md), `stacked` (full-width column flow) |
| `asideWidth` | string\|null | `null` | Refines the copy:aside ratio under `layout="balanced"`. Five values: `1/3`, `2/5`, `1/2` (matches default), `3/5`, `2/3`. Throws on any non-balanced layout (debug) or is silently ignored (production). |
| `size` | `sm` \| `md` \| `lg` | `lg` | Vertical-rhythm tier. Reads `--space-wk-section-{size}` tokens. Mobile viewport (< sm breakpoint) automatically drops one tier — `lg` becomes `md` on mobile — so the section never overshoots a small viewport. `sm` is uniform across viewports. |
| `tightOnMobile` | bool | `false` | When `true`, drop an additional tier on mobile viewports for `size="lg"` heroes — mobile resolves to `--space-wk-section-sm` (3 rem) instead of `--space-wk-section-md` (5 rem) while desktop stays at `--space-wk-section-lg` (7 rem). Useful for dark-variant heroes with gradient overlays on narrow viewports where 5 rem of mobile padding reads as a visible dead-zone. No-op for `size="sm"` and `size="md"` (mobile already runs at the tightest tier). |
| `scope` | string\|null | `null` | Scoped personalization name |

## Slots

| Slot | Description |
| --- | --- |
| `eyebrow` | Small text/badge above the title |
| `title` | Main hero heading (h1) |
| `lede` | Subtitle paragraph |
| `actions` | CTA buttons |
| `aside` | Side content (image, code block, etc.) |

## Keyboard Interaction

This component is a layout wrapper. Keyboard interaction is delegated to its children.

## Pitfalls

- **Don't combine `layout="centered"` with a left-aligned aside.** Centered layout pins lede + actions to center alignment at every breakpoint; a side-aside renders below copy by design — overriding it breaks responsive flow.

## Design Tokens

| Token | Used for |
| --- | --- |
| `--space-wk-section-lg` | Vertical padding |
| `--font-wk-heading-weight` | Title weight |
| `--font-wk-heading-2xl` | Title size |
| `--color-wk-bg-inverse` | Dark variant background |
| `--color-wk-accent` | Accent variant background |

## Usage & Conventions

> **Prop conventions** — this component uses one or more of the shared semantic prop names (`intent` / `variant` / `tone` / `surface`). See [Prop naming conventions](/extending/prop-naming-conventions) for the canonical vocabulary, alias matrix, and decision tree.
