All Taste components
Gradient heroes
Midnight glow hero
An always-dark opening section with glowing colour fields rising on the right and an early-access email form on the left.
always dark · 4 glowing fields · side veil · email capture · avatar proof
Private betaNow with database branching
Every pull request gets its own production.
Kiln spins up a full copy of your stack for each branch — database, queues and all — and tears it down when you merge.
AKRMJSLP
Joined by 4,800 platform teamsimport { ArrowRight } from "lucide-react";
/* Always dark: uses the brand/neutral scales, so it stays dark in light mode too.
Add once to globals.css:
@keyframes glow-1 { to { transform: translate(-16%, 20%) scale(1.1); } }
@keyframes glow-2 { to { transform: translate(20%, 14%) scale(.86); } }
@keyframes glow-3 { to { transform: translate(-22%, -18%) scale(1.14); } }
@keyframes glow-core { from { transform: scale(.8); opacity: .6; } to { transform: translate(-30%, 40%) scale(1.15); opacity: 1; } }
*/
const field = "absolute aspect-square rounded-full will-change-transform motion-reduce:animate-none";
export function HeroMidnight() {
return (
<section aria-labelledby="midnight-title" className="relative isolate overflow-hidden bg-neutral-950 px-5 pb-24 pt-5 font-sans text-neutral-50 sm:px-10">
<div aria-hidden className="absolute inset-0 -z-10 overflow-hidden animate-fade motion-reduce:animate-none">
<span className={field + " -right-[10%] -top-[36%] w-[max(54%,380px)] bg-[radial-gradient(closest-side,color-mix(in_srgb,var(--tst-brand-500)_78%,transparent),transparent)] animate-[glow-1_20s_ease-in-out_infinite_alternate]"} />
<span className={field + " right-[16%] top-[4%] w-[max(38%,280px)] bg-[radial-gradient(closest-side,color-mix(in_srgb,var(--tst-info-500)_60%,transparent),transparent)] animate-[glow-2_26s_ease-in-out_infinite_alternate]"} />
<span className={field + " -right-[16%] top-[34%] w-[max(42%,300px)] bg-[radial-gradient(closest-side,color-mix(in_srgb,var(--tst-danger-500)_46%,transparent),transparent)] animate-[glow-3_23s_ease-in-out_infinite_alternate]"} />
<span className={field + " -top-[4%] right-[12%] w-[max(16%,130px)] bg-[radial-gradient(closest-side,color-mix(in_srgb,var(--tst-brand-200)_70%,transparent),transparent)] animate-[glow-core_9s_ease-in-out_infinite_alternate]"} />
</div>
{/* Veil: copy sits on near-black, the glow lives on the right */}
<div aria-hidden className="absolute inset-0 -z-10 bg-[linear-gradient(180deg,transparent,color-mix(in_srgb,var(--tst-neutral-950)_70%,transparent)_40%,var(--tst-neutral-950)_85%)] md:bg-[linear-gradient(100deg,var(--tst-neutral-950)_22%,color-mix(in_srgb,var(--tst-neutral-950)_50%,transparent)_52%,transparent_78%)]" />
<nav aria-label="Main" className="mx-auto mb-16 flex max-w-[1080px] items-center justify-between gap-4 sm:mb-24">
<a href="/" className="flex items-center gap-2 text-[15px] font-semibold">
<span className="size-[22px] rounded-sm bg-gradient-to-br from-brand-300 to-brand-500" /> Kiln
</a>
<div className="hidden gap-6 text-[13.5px] text-neutral-400 sm:flex">
{["Product", "Changelog", "Pricing", "Docs"].map((l) => <a key={l} href="#" className="hover:text-neutral-50">{l}</a>)}
</div>
<a href="/access" className="inline-flex h-8 items-center rounded bg-neutral-50 px-3 text-[13px] font-medium text-neutral-950 hover:bg-neutral-200">Get access</a>
</nav>
<div className="mx-auto flex max-w-[1080px] flex-col items-start gap-5">
<a href="/changelog" className="inline-flex items-center gap-2 rounded-full border border-neutral-800 bg-neutral-900/70 py-0.5 pl-0.5 pr-3 text-[12.5px] text-neutral-300 animate-rise motion-reduce:animate-none">
<span className="rounded-full bg-brand-400/20 px-2 py-0.5 text-xs font-medium text-brand-200">Private beta</span>
Now with database branching <ArrowRight className="size-3.5" aria-hidden />
</a>
<h1 id="midnight-title" className="max-w-[13ch] text-balance text-4xl font-medium leading-[1.02] tracking-[-0.04em] sm:text-6xl lg:text-7xl animate-rise [animation-delay:80ms] motion-reduce:animate-none">
Every pull request gets its own production.
</h1>
<p className="max-w-[500px] text-pretty text-base leading-relaxed text-neutral-400 sm:text-lg animate-rise [animation-delay:160ms] motion-reduce:animate-none">
Kiln spins up a full copy of your stack for each branch — database, queues and all — and tears it down when you merge.
</p>
<form className="flex w-full max-w-[460px] flex-wrap gap-2 animate-rise [animation-delay:240ms] motion-reduce:animate-none" onSubmit={(e) => e.preventDefault()}>
<label htmlFor="midnight-email" className="sr-only">Work email</label>
<input id="midnight-email" type="email" autoComplete="email" placeholder="you@company.com"
className="h-11 min-w-0 flex-[1_1_220px] rounded border border-neutral-700 bg-neutral-900/80 px-3 text-neutral-50 outline-none placeholder:text-neutral-500 focus:border-brand-400 focus:ring-[3px] focus:ring-brand-400/30" />
<button type="submit" className="h-11 rounded bg-neutral-50 px-5 font-medium text-neutral-950 hover:bg-neutral-200 active:scale-[.97]">Get early access</button>
</form>
<div className="mt-2 flex items-center gap-3 text-[13px] text-neutral-400">
<div className="flex">
{["AK", "RM", "JS", "LP"].map((a, i) => (
<span key={a} className={"grid size-7 place-items-center rounded-full border-2 border-neutral-950 bg-neutral-800 text-[11px] font-medium text-neutral-200" + (i ? " -ml-2" : "")}>{a}</span>
))}
</div>
Joined by 4,800 platform teams
</div>
</div>
</section>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.