defuss-shadcn / Website / Landing Page / hero
HeroBLK
Badge, headline, description and CTAs - a centered copy block; pair it with the Product Showcase below when you want a video.
On this page (7)
§Default
Copy-only block; the title steps up to 60px at wide container widths.
§Split with media
data-variant='split': copy beside a picture - two columns once the hero is 40rem wide, stacked below that. An announcement pill (.mk-hero-pill) sits above the title.
§Background image
data-variant='image': a full-bleed photo (.mk-hero-bg) behind the copy; a dark scrim keeps the white text readable on any picture.
§Glow
data-variant='glow': a soft light in the theme's primary and chart colors over a grid that fades out; the title fades into the page. With social proof (.mk-hero-proof) below the actions.
§Signup
data-align='start' with an inline email form (.mk-hero-form) - Input + Button on one row once there is room - and a note below it.
§With the product
.mk-hero-stage: the product under the copy - a framed screenshot with a deep shadow whose bottom edge fades into the page.
§CSS view file
/* -- Hero (marketing) --------------------------------------------- Centered headline + description + CTAs. Copy-only by design - pair it with the Product Showcase block for video. Layout switches on container width, not viewport - the block renders correctly inside a preview box. */@layer components { .mk-hero { container: mk-hero / inline-size; display: flex; flex-direction: column; gap: 3rem; width: 100%; max-width: 80rem; margin-inline: auto; padding-inline: 1.25rem; } .mk-hero-copy { display: flex; flex-direction: column; align-items: center; gap: 1rem; width: 100%; max-width: 48rem; margin-inline: auto; text-align: center; } .mk-hero-badge { border: 1px solid var(--border); background: var(--background); border-radius: 9999px; padding: 0.125rem 0.5rem; font-size: 0.75rem; font-weight: 500; } .mk-hero-title { margin: 0; font-size: 2.25rem; font-weight: 500; line-height: 1.1; letter-spacing: -0.025em; text-wrap: balance; } .mk-hero-desc { margin: 0; max-width: 36rem; color: var(--muted-foreground); font-size: 1.125rem; text-wrap: pretty; } .mk-hero-actions { display: flex; flex-direction: column; gap: 0.5rem; width: 100%; } /* the section itself is the query container - a container cannot query itself, so responsive rules target the copy child (descendant) */ @container mk-hero (min-width: 30rem) { .mk-hero-title { font-size: 3.75rem; } .mk-hero-actions { flex-direction: row; width: fit-content; } } /* -- variants ------------------------------------------------- */ /* start-aligned copy (a hero beside a sidebar, a docs landing) */ .mk-hero[data-align="start"] .mk-hero-copy { align-items: flex-start; margin-inline: 0; text-align: start; } /* an announcement pill above the title: a link with a chip and an arrow */ .mk-hero-pill { display: inline-flex; align-items: center; gap: 0.5rem; max-width: 100%; padding: 0.25rem 0.75rem 0.25rem 0.25rem; border: 1px solid var(--border); border-radius: 999px; background: color-mix(in oklch, var(--background) 80%, transparent); color: var(--foreground); font-size: 0.8125rem; font-weight: 500; text-decoration: none; text-align: start; transition: border-color 150ms ease; & .badge { flex: none; border-radius: 999px; } & svg { flex: none; width: 0.875rem; height: 0.875rem; transition: translate 150ms ease; } &:hover { border-color: color-mix(in oklch, var(--foreground) 30%, var(--border)); } &:hover svg { translate: 0.125rem 0; } &:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; } } /* split: the copy beside a picture or video (auto-fit: stacks when narrow) */ .mk-hero[data-variant="split"] { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); align-items: center; gap: 2.5rem 3rem; & .mk-hero-copy { align-items: flex-start; margin: 0; text-align: start; } & .mk-hero-title { font-size: clamp(2.25rem, 5.5cqi, 3.5rem); } } .mk-hero-media { position: relative; margin: 0; aspect-ratio: 4 / 3; overflow: hidden; border-radius: var(--radius-xl); background: var(--muted); & :is(img, video) { display: block; width: 100%; height: 100%; object-fit: cover; } } /* image: a full-bleed photo behind the copy, a scrim keeps it readable */ .mk-hero[data-variant="image"] { position: relative; isolation: isolate; overflow: hidden; padding: 6rem 1.5rem; border-radius: var(--radius-xl); color: #fff; &::before { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(to top, oklch(0.15 0.02 260 / 0.85), oklch(0.15 0.02 260 / 0.35)); } & .mk-hero-bg { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; } & .mk-hero-desc { color: oklch(1 0 0 / 0.82); } & .mk-hero-badge { border-color: oklch(1 0 0 / 0.3); background: oklch(1 0 0 / 0.12); color: #fff; backdrop-filter: blur(6px); } & .btn[data-variant="outline"] { border-color: oklch(1 0 0 / 0.4); background: transparent; color: #fff; } } /* glow: a soft brand light over a fading grid; the title fades into the page */ .mk-hero[data-variant="glow"] { position: relative; isolation: isolate; padding-block: 5rem 3rem; &::before, &::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; } &::before { /* the chart palette, not --primary: a near-black primary would smudge */ background: radial-gradient(28% 40% at 50% 8%, color-mix(in oklch, var(--chart-1) 30%, transparent), transparent), radial-gradient(22% 32% at 70% 30%, color-mix(in oklch, var(--chart-2) 26%, transparent), transparent), radial-gradient(22% 32% at 30% 34%, color-mix(in oklch, var(--chart-3) 22%, transparent), transparent); filter: blur(24px); } &::after { background-image: linear-gradient(color-mix(in oklch, var(--foreground) 7%, transparent) 1px, transparent 1px), linear-gradient(90deg, color-mix(in oklch, var(--foreground) 7%, transparent) 1px, transparent 1px); background-size: 40px 40px; mask-image: radial-gradient(60% 55% at 50% 30%, #000, transparent 75%); } & .mk-hero-title { background: linear-gradient(180deg, var(--foreground) 40%, color-mix(in oklch, var(--foreground) 55%, transparent)); -webkit-background-clip: text; background-clip: text; color: transparent; } } /* signup: an inline email form under the copy */ .mk-hero-form { display: flex; flex-direction: column; gap: 0.5rem; width: 100%; max-width: 28rem; & .input { flex: 1; min-width: 0; } } .mk-hero-note { margin: 0; color: var(--muted-foreground); font-size: 0.8125rem; } /* social proof: an avatar group, stars and a line */ .mk-hero-proof { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.75rem; color: var(--muted-foreground); font-size: 0.875rem; text-align: start; & > div:last-child { display: grid; gap: 0.125rem; } & strong { color: var(--foreground); font-weight: 600; } } .mk-hero-stars { display: flex; gap: 1px; color: oklch(0.78 0.16 75); & svg { width: 0.875rem; height: 0.875rem; fill: currentColor; } } /* stage: the product under the copy - a framed screenshot with depth */ .mk-hero-stage { position: relative; width: 100%; margin: 0; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-xl); background: var(--card); box-shadow: var(--shadow-2xl); & img { display: block; width: 100%; height: auto; } /* fade the bottom edge into the page */ &::after { content: ""; position: absolute; inset: auto 0 0; height: 35%; background: linear-gradient(transparent, var(--background)); } } @container mk-hero (min-width: 30rem) { .mk-hero-form { flex-direction: row; } } /* -- Accessibility ------------------------------------------- */ @media (prefers-reduced-motion: reduce) { .mk-hero-pill, .mk-hero-pill svg { transition: none; } .mk-hero-pill:hover svg { translate: none; } } @media (forced-colors: active) { .mk-hero[data-variant="glow"] .mk-hero-title { background: none; color: CanvasText; } .mk-hero-pill { border-color: CanvasText; } }}Comments, ideas or improvements? Edit this page's source on GitHub