Aurora Hero
A full-bleed hero with a slow aurora of blurred colour blobs drifting behind balanced display type. Pure CSS — no canvas, no JS.
- conic-gradient
- filter: blur
- text-wrap: balance
Source
A single self-contained .astro component. It uses Prism's design tokens (--spectrum-*, --ink…) with sensible fallbacks, so it renders even outside this site.
---
export const meta = {
title: "Aurora Hero",
tags: ["hero", "gradient", "css-only"],
description:
"A full-bleed hero with a slow aurora of blurred colour blobs drifting behind balanced display type. Pure CSS — no canvas, no JS.",
tech: ["conic-gradient", "filter: blur", "text-wrap: balance"],
height: 560,
};
---
<section class="aurora-hero">
<div class="aurora" aria-hidden="true">
<span class="blob b1"></span>
<span class="blob b2"></span>
<span class="blob b3"></span>
</div>
<div class="aurora-hero__content">
<p class="kicker">Now in private beta</p>
<h1>Ship interfaces that feel <em>alive.</em></h1>
<p class="sub">A design engine for teams who care about the last 10%. Motion, colour and type that respond to every interaction.</p>
<div class="actions">
<a href="#" class="a-btn a-btn--solid">Get early access</a>
<a href="#" class="a-btn a-btn--ghost">Watch the film →</a>
</div>
</div>
</section>
<style>
.aurora-hero {
position: relative; min-height: 560px; display: grid; place-items: center;
padding: 4rem 1.5rem; overflow: hidden; isolation: isolate;
background: var(--bg, #0e0f1a); color: var(--ink, #f2f2f7); text-align: center;
}
.aurora { position: absolute; inset: -20%; z-index: -1; filter: blur(70px) saturate(1.3); }
.blob { position: absolute; width: 45vmax; height: 45vmax; border-radius: 50%; opacity: 0.7; mix-blend-mode: screen; }
.b1 { background: var(--spectrum-1, #8b5cf6); top: -10%; left: -5%; animation: drift1 18s ease-in-out infinite; }
.b2 { background: var(--spectrum-3, #45d3e8); top: 10%; right: -10%; animation: drift2 22s ease-in-out infinite; }
.b3 { background: var(--spectrum-5, #fbbf24); bottom: -20%; left: 30%; animation: drift3 26s ease-in-out infinite; }
@keyframes drift1 { 50% { transform: translate(20%, 15%) scale(1.2); } }
@keyframes drift2 { 50% { transform: translate(-15%, 20%) scale(1.1); } }
@keyframes drift3 { 50% { transform: translate(10%, -20%) scale(1.25); } }
.aurora-hero__content { max-width: 44rem; display: grid; gap: 1.1rem; justify-items: center; }
.kicker {
font-size: 0.8rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
padding: 0.4rem 0.9rem; border-radius: 999px; color: var(--ink, #fff);
border: 1px solid color-mix(in oklab, currentColor 25%, transparent);
background: color-mix(in oklab, currentColor 8%, transparent);
}
.aurora-hero h1 {
font-size: clamp(2.4rem, 1.6rem + 4vw, 4.6rem); line-height: 1.02;
letter-spacing: -0.03em; text-wrap: balance; margin: 0;
}
.aurora-hero h1 em {
font-style: normal;
background: linear-gradient(100deg, var(--spectrum-1, #8b5cf6), var(--spectrum-3, #45d3e8), var(--spectrum-5, #fbbf24));
-webkit-background-clip: text; background-clip: text; color: transparent;
}
.sub { font-size: 1.15rem; line-height: 1.5; color: var(--ink-muted, #b7b9c9); max-width: 40ch; }
.actions { display: flex; flex-wrap: wrap; gap: 0.8rem; justify-content: center; margin-top: 0.5rem; }
.a-btn { padding: 0.8rem 1.4rem; border-radius: 999px; font-weight: 600; text-decoration: none; transition: transform 0.2s cubic-bezier(0.34,1.56,0.64,1); }
.a-btn:hover { transform: translateY(-2px); }
.a-btn--solid { background: #fff; color: #111; }
.a-btn--ghost { color: var(--ink, #fff); border: 1px solid color-mix(in oklab, currentColor 30%, transparent); }
@media (prefers-reduced-motion: reduce) { .blob { animation: none; } }
</style>