# HeroSection

> Full-bleed hero shell with min-height, alignment, and background variants.

- Status: stable
- Group: marketing
- Page: https://www.digitaltableteur.com/design-system/components/hero-section
- Contract: https://www.digitaltableteur.com/contracts/v1/HeroSection.contract.json

## When to use

HeroSection is the layout shell under heroes: a full-bleed section with min-height, align/justify, and background/backgroundImage variants, rendering whatever children you pass (HomeHero builds on it). Use it when a bespoke hero needs the shell but not Hero's fixed content model. Pass ariaLabel when the section needs its own landmark name.

## When not to use

The contract records no forbidden uses.

## Look-alikes

The contract names no look-alike with a deciding condition.

## Props

| Prop | Type | Default | Description | Required |
| --- | --- | --- | --- | --- |
| `children` | `ReactNode` | none | Hero content. | Yes |
| `background` | `"image" \| "transparent" \| "solid" \| "gradient"` | `transparent` | Background style variant. Defaults to `transparent`. | No |
| `backgroundImage` | `string` | none | Background image URL (only used when background="image") | No |
| `minHeight` | `"auto" \| "hero" \| "screen" \| "half"` | `hero` | Minimum height of the hero section. Defaults to `hero` (75vh); `screen` is 100vh, `half` 50vh, `auto` none. | No |
| `align` | `"center" \| "start" \| "end"` | `center` | Horizontal (cross-axis) alignment of the content. The root is a flex column, so this maps to items-*. Defaults to `center`. | No |
| `justify` | `"center" \| "start" \| "end"` | `center` | Vertical (main-axis) alignment of the content within the min-height. The root is a flex column, so this maps to justify-*. Defaults to `center`. | No |
| `className` | `string` | none | Custom className for styling extensions. | No |
| `as` | `"symbol" \| "object" \| "image" \| "form" \| "slot" \| "style" \| "title" \| "button" \| "search" \| "article" \| "dialog" \| "figure" \| "img" \| "link" \| "main" \| "menu" \| "menuitem" \| "option" \| "switch" \| "table" \| "text" \| "time" \| "div" \| "section" \| "aside" \| "li" \| "a" \| "abbr" \| "address" \| "area" \| "audio" \| "b" \| "base" \| "bdi" \| "bdo" \| "big" \| "blockquote" \| "body" \| "br" \| "canvas" \| "caption" \| "center" \| "cite" \| "code" \| "col" \| "colgroup" \| "data" \| "datalist" \| "dd" \| "del" \| "details" \| "dfn" \| "dl" \| "dt" \| "em" \| "embed" \| "fieldset" \| "figcaption" \| "footer" \| "h1" \| "h2" \| "h3" \| "h4" \| "h5" \| "h6" \| "head" \| "header" \| "hgroup" \| "hr" \| "html" \| "i" \| "iframe" \| "input" \| "ins" \| "kbd" \| "keygen" \| "label" \| "legend" \| "map" \| "mark" \| "meta" \| "meter" \| "nav" \| "noindex" \| "noscript" \| "ol" \| "optgroup" \| "output" \| "p" \| "param" \| "picture" \| "pre" \| "progress" \| "q" \| "rp" \| "rt" \| "ruby" \| "s" \| "samp" \| "script" \| "select" \| "small" \| "source" \| "span" \| "strong" \| "sub" \| "summary" \| "sup" \| "template" \| "tbody" \| "td" \| "textarea" \| "tfoot" \| "th" \| "thead" \| "tr" \| "track" \| "u" \| "ul" \| "var" \| "video" \| "wbr" \| "webview" \| "svg" \| "animate" \| "animateMotion" \| "animateTransform" \| "circle" \| "clipPath" \| "defs" \| "desc" \| "ellipse" \| "feBlend" \| "feColorMatrix" \| "feComponentTransfer" \| "feComposite" \| "feConvolveMatrix" \| "feDiffuseLighting" \| "feDisplacementMap" \| "feDistantLight" \| "feDropShadow" \| "feFlood" \| "feFuncA" \| "feFuncB" \| "feFuncG" \| "feFuncR" \| "feGaussianBlur" \| "feImage" \| "feMerge" \| "feMergeNode" \| "feMorphology" \| "feOffset" \| "fePointLight" \| "feSpecularLighting" \| "feSpotLight" \| "feTile" \| "feTurbulence" \| "filter" \| "foreignObject" \| "g" \| "line" \| "linearGradient" \| "marker" \| "mask" \| "metadata" \| "mpath" \| "path" \| "pattern" \| "polygon" \| "polyline" \| "radialGradient" \| "rect" \| "set" \| "stop" \| "textPath" \| "tspan" \| "use" \| "view"` | `section` | Semantic HTML element to render as. Defaults to `section`. Typed as any React ElementType, so the values list is every JSX intrinsic; only section-level elements (section, header, div) make sense here. | No |
| `ariaLabel` | `string` | none | ARIA label for accessibility. | No |

## Variants

- Allowed `align` values: `center`, `end`, `start` (default `center`).
- Available backgrounds: `image`, `transparent`, `solid`, `gradient` (default `transparent`).
- Allowed `minHeight` values: `auto`, `hero`, `screen`, `half` (default `hero`).
- Allowed `justify` values: `center`, `start`, `end` (default `center`).
- Allowed `as` values: `symbol`, `object`, `image`, `form`, `slot`, `style`, `title`, `button`, `search`, `article`, `dialog`, `figure`, `img`, `link`, `main`, `menu`, `menuitem`, `option`, `switch`, `table`, `text`, `time`, `div`, `section`, `aside`, `li`, `a`, `abbr`, `address`, `area`, `audio`, `b`, `base`, `bdi`, `bdo`, `big`, `blockquote`, `body`, `br`, `canvas`, `caption`, `center`, `cite`, `code`, `col`, `colgroup`, `data`, `datalist`, `dd`, `del`, `details`, `dfn`, `dl`, `dt`, `em`, `embed`, `fieldset`, `figcaption`, `footer`, `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `head`, `header`, `hgroup`, `hr`, `html`, `i`, `iframe`, `input`, `ins`, `kbd`, `keygen`, `label`, `legend`, `map`, `mark`, `meta`, `meter`, `nav`, `noindex`, `noscript`, `ol`, `optgroup`, `output`, `p`, `param`, `picture`, `pre`, `progress`, `q`, `rp`, `rt`, `ruby`, `s`, `samp`, `script`, `select`, `small`, `source`, `span`, `strong`, `sub`, `summary`, `sup`, `template`, `tbody`, `td`, `textarea`, `tfoot`, `th`, `thead`, `tr`, `track`, `u`, `ul`, `var`, `video`, `wbr`, `webview`, `svg`, `animate`, `animateMotion`, `animateTransform`, `circle`, `clipPath`, `defs`, `desc`, `ellipse`, `feBlend`, `feColorMatrix`, `feComponentTransfer`, `feComposite`, `feConvolveMatrix`, `feDiffuseLighting`, `feDisplacementMap`, `feDistantLight`, `feDropShadow`, `feFlood`, `feFuncA`, `feFuncB`, `feFuncG`, `feFuncR`, `feGaussianBlur`, `feImage`, `feMerge`, `feMergeNode`, `feMorphology`, `feOffset`, `fePointLight`, `feSpecularLighting`, `feSpotLight`, `feTile`, `feTurbulence`, `filter`, `foreignObject`, `g`, `line`, `linearGradient`, `marker`, `mask`, `metadata`, `mpath`, `path`, `pattern`, `polygon`, `polyline`, `radialGradient`, `rect`, `set`, `stop`, `textPath`, `tspan`, `use`, `view` (default `section`).

## Invalid combinations

- MUST NOT: When `backgroundImage` is set and `background` is one of `gradient`, `solid`, `transparent`, then do not set `backgroundImage`. `backgroundImage` only renders when background="image"; with any other background it is silently dropped.
- MUST NOT: When `backgroundImage` is set and `background` is not set, then also set `background`. `background` defaults to "transparent", which drops `backgroundImage`. Set background="image".

## Keyboard

The contract records no keyboard interaction.

## Rules

Every item under When not to use is a MUST NOT. MUST and SHOULD follow RFC 2119.

| Level | Rule | How it is checked |
| --- | --- | --- |
| MUST NOT | When `backgroundImage` is set and `background` is one of `gradient`, `solid`, `transparent`, then do not set `backgroundImage`. `backgroundImage` only renders when background="image"; with any other background it is silently dropped. | Checked by the MCP tool validate_component_usage (rule `hero-background-image-needs-image-mode`). Also enforced in code: HeroSection.tsx: hasBackgroundImage = background === "image" && backgroundImage. |
| MUST NOT | When `backgroundImage` is set and `background` is not set, then also set `background`. `background` defaults to "transparent", which drops `backgroundImage`. Set background="image". | Checked by the MCP tool validate_component_usage (rule `hero-background-image-default-mode`). Also enforced in code: HeroSection.tsx: background defaults to "transparent". |
| MUST | Required stories produce no axe violations at the configured severity. | Automated by `npm run test:stories:matrix:ci`. WCAG 2.5.8. |
| MUST | The accessibility tree (role, name, state) matches the committed snapshot for every required story. | Automated by `npm run test:stories:matrix:ci`. WCAG 1.3.1, 4.1.2. |
| MUST | The component remains legible and operable under a real browser forced-colors: active pass. | Automated by `npm run test:stories:hc`. |
| MUST | A human completed an end-to-end accessibility review of this component. | Manual review, last on 2026-11-04. |
| MUST NOT | Maintainers: Do not bypass design tokens or skip forced-colors verification at beta. | Release review; not machine-checked. |

## Install and import

- In-repo only. HeroSection is not exported from `@digitaltableteur/react`, so there is no public import path.

## Links

- Machine-readable contract (Design System Contract 1.0): https://www.digitaltableteur.com/contracts/v1/HeroSection.contract.json
- Markdown version of this page: https://www.digitaltableteur.com/design-system/components/hero-section.md
- Component index as JSON: https://www.digitaltableteur.com/design-system/components.json
- All components: https://www.digitaltableteur.com/design-system/components
- Source: The implementation lives in a private repository. This page, its Markdown twin and the contract are generated from it at build time and are the public source of truth.
