Components · Layout and structure

Hero

The opening surface of a route. A tinted card with a Founders Grotesk display headline, an Inter Tight body, and one or two buttons. Six accents, all opening on the canvas weight — the layering rule is the whole reason this component exists.

Documentedby Derek Fidler

Capital

You’re prequalified for a cash advance starting from 500.000 kr

Whether you want to grow, evolve, or just maintain — get access to the funding that you deserve. Money in your account in 5–8 business days.

Overview

A Hero introduces a route. It carries one short eyebrow, one display headline, one or two lines of body, and at most two buttons. The component is large on purpose — it earns the quietness of every page below it. Each Hero opens on background.accent.<hue>.subtlest per the layering rule; nested cards inside the Hero (a CTA tile, a preview frame) step up to subtler, never down.

Open on subtlest, never on subtler

The Capital landing in Figma fills with the literal orange.300 (#fed2a9), which is the subtler weight. We diverge: every Hero in the product opens on the canvas weight (subtlest). That keeps the layering rule consistent across surfaces — if the Hero opens on subtler, every nested card needs to climb to subtle, and the contrast steps stop reading.

Anatomy

Four parts, stacked centered by default. The eyebrow + title group sits 56 px above the action row; the eyebrow itself sits 20 px above the title.

Capital

Anatomy in one example

Eyebrow, title, body, action — each on the centerline, each separated by a deliberate gap.

  1. Eyebrow

    Inter Tight Semibold 20 / 24 in text.accent.<hue> (the 900 step of the same accent ramp). One short label — a product name, a section, an announcement.

  2. Title

    Founders Grotesk X Condensed Bold, ALL CAPS, fluid 40 → 64 px (lg) or 32 → 48 px (md). The display family is hard-restricted to two roles: page H1s and the single hero metric per page. This is one of them.

  3. Description

    Inter Tight Regular 18 / 24 in text.secondary. Caps at 600 px wide on the centered variant and 75 ch on the left-aligned variant.

  4. Actions

    One primary button, optionally a secondary. 16 px gap between them, 56 px gap between the action row and the text stack. Trailing arrow_outward glyph on the primary when the action navigates somewhere.

Accents

Six accents, each opening on the canvas weight of its hue. The eyebrow inks in text.accent.<hue> (the 900 step) so it stays inside the same ramp the surface came from. Pick one accent per route and stick to it — the Hero sets the temperature for everything below.

Welcome back

Today's settlement is on its way

Funds for transactions captured before 22:00 CET land in your account by 09:00 CET tomorrow.

New for May

Refunds you can preview before issuing

See exactly what the customer will receive — line item, fee, currency — before the refund leaves your account.

Capital

You're prequalified for a cash advance

Whether you want to grow, evolve, or just maintain — get access to the funding you deserve.

Loyalty

Reward your regulars without a punch card

Drop a digital pass into Apple Wallet on every fifth transaction. No app, no signup, no friction.

Insights

Where did your weekday revenue come from?

Break down sales by hour, channel, and product so you can staff and stock for the patterns the data already knows.

Black Friday

Higher limits, lower fees, all weekend long

We're staffing the surge so you can run your busiest day of the year without thinking about us.

Alignment

Centered is the default — every part stacks on the centerline, the body caps at 600 px, the action sits dead-center. Left-aligned is for product surfaces where the Hero shares the page with secondary content (settings landings, dashboard headers).

Centered

The default — title, body, action all stacked on the centerline

Use the centered Hero on a marketing-style landing where the eye lands on the headline first. Capital, Loyalty, Insights — surfaces that introduce a product.

Left-aligned

Use a left rail when the Hero shares the page with secondary content

Settings landings, dashboard headers, anything where the Hero is the lead but not the only thing on the page. The body wraps to ~75 ch instead of 600 px.

Actions

None, one, or two — never three. Two actions is the ceiling, and the second one should be a soft escape (Read more, See examples, Skip for now), not a comparable primary.

No action

Hero without a button — when the page itself is the action

The Hero introduces a workspace, and everything below it is the next step. A button would compete with the actual surface.

One action

Hero with a single primary action — the most common case

A clear next step. Pair with an Inter Tight Semibold label and an arrow_outward glyph.

Two actions

Hero with a primary plus a secondary

Use sparingly. The second action should be a soft escape — Read more, See examples, Skip for now — never a comparable primary.

With media

When the Hero introduces a feature whose result lives elsewhere — a sample offer, a preview frame, an in-product screenshot — pair the text rail with a media slot to the right. The media slot steps to subtler so it reads as a card on the canvas surface.

Capital

Apply in three minutes, decision in five

A short form, a soft credit check, and an offer in your inbox. No paperwork, no in-person review.

Sample offer

500.000 kr

  • Repayment term12 months
  • Effective rate7,2 %
  • Funded5–8 days

Behavior

  • One Hero per route. The Hero is the route's opening; two of them is two routes. If you find yourself wanting a second Hero, you probably want a Section.
  • Sits in a 8 px gutter. The Hero card has a 8 px corner radius and lives inside an 8 px outer gutter so all four rounded corners are visible against the canvas. The gutter is part of the component, not the page.
  • Title fluid, body fixed. The display title scales with clamp() from 40 px on mobile to 64 px on desktop (lg). The body stays at a fixed 18 / 24 — no design system uses fluid type in body copy.
  • Stay inside one hue. The Hero's accent picks the ramp; text.accent.<hue> is the only ink the eyebrow can take. Don't paint the eyebrow blue on a green Hero — the accent system collapses if hues mix.
  • Inverse is for moments. The pure-black Hero (the inverse accent) is the loudest the system gets. Use it for announcements that need to feel like an interruption — Black Friday, an outage post-mortem, a policy change. Once per quarter, not once per page.

Accessibility

  • The title is the page's H1. Render the title as <h1> — one per page. Subsequent sections inside the page step from h2down. Don't wrap the Hero title in a styled span — assistive tech relies on the heading element, not the visual weight.
  • Eyebrow is decorative, not a heading. Set the eyebrow as a <p>; it's styling, not structure. Screen readers announce it as part of the visual context, not as a separate landmark.
  • Contrast:every accent ships text that meets WCAG AA on its surface — the inverse Hero gives 21 : 1, the yellow gives 11 : 1, orange 13 : 1. Don't override the ink with a custom colour without re-checking against the surface.
  • Focus order: Tab walks through the action buttons in DOM order; the eyebrow / title / description carry no focus targets. Skip-link your way past the Hero on long routes by anchoring main immediately after.
  • Reduced motion: the Hero has no entrance animation by default. If the surrounding page brings one, respect prefers-reduced-motion: reduce and present the Hero in place.

Code

The component takes one accent, one title, optional eyebrow / description / actions / media. The accent picks both the surface and the eyebrow ink — never set them separately.

tsx

import { Hero, Button } from "@flatpay-dk/ui";
import ArrowOutwardIcon from "@mui/icons-material/ArrowOutwardOutlined";

// Centered, single primary action — the Capital landing pattern
<Hero
  accent="orange"
  eyebrow="Capital"
  title="You're prequalified for a cash advance starting from 500.000 kr"
  description="Whether you want to grow, evolve, or just maintain — get access to the funding that you deserve."
  actions={
    <Button
      size="md"
      variant="primary"
      trailingIcon={<ArrowOutwardIcon />}
    >
      View offers
    </Button>
  }
/>

// Left-aligned, two actions — settings landing
<Hero
  accent="natural"
  align="left"
  eyebrow="Settings"
  title="Make Flatpay yours"
  description="Trading hours, currency defaults, receipt copy — every customer-facing setting that isn't a price."
  actions={
    <>
      <Button size="md" variant="primary">Continue setup</Button>
      <Button size="md" variant="tertiary">Skip for now</Button>
    </>
  }
/>

// With media — Hero text on the left, sample offer card on the right
<Hero
  accent="green"
  align="left"
  size="md"
  eyebrow="Capital"
  title="Apply in three minutes, decision in five"
  description="A short form, a soft credit check, and an offer in your inbox."
  actions={<Button variant="primary">Start the application</Button>}
  media={<SampleOfferCard />}
/>

Best practices

Hero misuse is loud. The questions below catch the common ones before they ship.

Capital

Open on the canvas weight

Subtlest is the layering rule's starting point.

Do

Open on subtlest. The Hero is the canvas — every nested card or panel can step up from here.

Capital

Wrong weight

Filled with orange.300 (subtler) instead of orange.subtlest.

Don't

Don't open on subtler. If the Hero is already a 'card on canvas', a nested card has nowhere to step up to.

Insights

One hue, top to bottom

Surface, eyebrow, focus ring — same accent ramp, different weights.

Do

Stay inside one hue. The eyebrow inherits the same accent ramp as the surface.

Insights

Hue mismatch

Green eyebrow on a purple surface — neither owns the ramp.

Don't

Don't blend hues — eyebrow in green on a purple Hero collapses the accent system.

Capital

One decision, one button

When two actions appear, the second is a soft escape — never another primary.

Do

One primary action, optionally one secondary. The Hero is one decision — keep the surface that decisive.

Capital

Three primaries, no decision

Three buttons with equal weight; the Hero's job is undone.

Don't

Don't stack three primaries. The user has no idea which one to take, and the page below loses its priority.

Props

PropTypeDefaultDescription
titleReactNodeDisplay headline. Set as <h1> in Founders Grotesk X Condensed Bold, ALL CAPS, fluid 40 → 64 px (lg) or 32 → 48 px (md).
eyebrowstringOptional small label above the title. Inter Tight Semibold 20/24 in text.accent.<hue>.
descriptionReactNodeBody copy below the title. Inter Tight Regular 18/24 in text.secondary. Caps at 600 px (centered) or 75 ch (left).
actionsReactNodeAction slot — typically one or two Buttons. 16 px gap; the second action should be a soft escape, never a comparable primary.
accent"yellow" | "green" | "orange" | "purple" | "natural" | "inverse""natural"Background accent. Each accent opens on background.accent.<hue>.subtlest and inks the eyebrow in text.accent.<hue>.
align"center" | "left""center"Title alignment. Centered for marketing-style landings; left-aligned when the Hero shares a page with secondary content.
size"md" | "lg""lg"Title size token. lg fluid 40 → 64 px, md fluid 32 → 48 px. Use md inside dense product surfaces.
mediaReactNodeOptional right-side media slot — a sample offer card, a preview frame, an in-product screenshot. The slot steps to subtler.