Your favourite go-to field.
One live WebGL surface, copy-paste ready, doing the work a hero photo and a badge usually split between them.
67 live fields · zero dependencies · reduced-motion safe
- Ships as
- one file
- Pointer
- bends the rays
- Fallback
- CSS floor
Solar Beacon
Same two-column anatomy as `split-beacon` — claim and CTAs on the left, a glass ledger of proof on the right — built on `solar-fan` instead, the catalogue's one light-ground, pointer-bent field. Two buttons instead of one this time: the field itself is warm and busy enough to carry a second, quieter call to action without the page feeling over-stuffed.
Built to prove the anatomy survives an inverted contract: every other Sections piece inks light text over a dark field with `--field-ink`; this one inks dark text over a pale field with `--field-ink-warm`, the same fixed, theme-independent pairing running in reverse.
Install
No installation needed — self-contained, paste-in code.
Usage
Drop it straight into a page.
import { SolarFanField } from "./SolarFanField";
export default function Example() {
return (
<header className="relative isolate min-h-[36rem] overflow-hidden flex items-center">
<div className="absolute inset-0 -z-10">
<SolarFanField guardSelector="#solar-beacon-copy" />
</div>
<div id="solar-beacon-copy" className="mx-auto max-w-xl px-8 text-left text-[#33251c]">
<h1 className="text-5xl font-medium tracking-tight">
Your favourite go-to field.
</h1>
<p className="mt-4 text-lg opacity-80">
One live WebGL surface, copy-paste ready, doing the work a hero
photo and a badge usually split between them.
</p>
<div className="mt-8 flex gap-3">
<a href="#" className="rounded-xl bg-[#c9502a] px-5 py-3 text-white">
See it work
</a>
<a href="#" className="rounded-xl border border-black/10 bg-white/50 px-5 py-3 backdrop-blur">
Browse the catalogue
</a>
</div>
</div>
</header>
);
}Component
The real source, exactly as it ships — multiple files, kept together.
import Link from "next/link";
import type { CategoryDef, CreationCard } from "@/lib/iris";
import { SolarFanField } from "../visuals/backgrounds";
/**
* The real `solar-beacon` section, full scale. Left-aligned claim and two
* calls to action over a live field, a short glass ledger of proof floating
* on the right — the two-column, text-plus-panel anatomy an agency hero
* usually spends a badge, a nav bar and a product screenshot building.
* Here the field itself is the product shot: `solar-fan` is a live,
* pointer-bent piece from this same catalogue, not a static image.
*
* The only Sections piece built on a light-ground field instead of one of
* the five vivid dark ones, so it inks with `--field-ink-warm` /
* `--field-glass-warm` rather than `--field-ink` / `--field-glass`.
*/
export function SolarBeacon({
category,
creation,
}: {
category: CategoryDef;
creation: CreationCard;
}) {
return (
<header className="iris-hero iris-hero--field iris-section-hero--solar relative isolate [overflow:clip] mt-[calc(-3.5rem_-_1px)] min-h-[min(82vh,760px)] flex flex-col justify-center [padding-block:calc(clamp(3rem,8vh,6rem)+3.5rem)_clamp(3rem,8vh,6rem)]">
<div className="absolute inset-0 z-[-1] overflow-hidden bg-[color:var(--iris-bg)]" aria-hidden="true">
<div className="absolute inset-0 [mask-image:linear-gradient(180deg,#000_0_64%,transparent_99%)] [-webkit-mask-image:linear-gradient(180deg,#000_0_64%,transparent_99%)] data-[enter=right]:[animation:iris-field-enter-right_560ms_cubic-bezier(0.16,1,0.3,1)_both] data-[enter=left]:[animation:iris-field-enter-left_560ms_cubic-bezier(0.16,1,0.3,1)_both] motion-reduce:[animation:none]">
<SolarFanField guardSelector=".iris-section-hero--solar .iris-hero__inner" />
</div>
</div>
<div className="iris-shell iris-hero__inner flex flex-row flex-wrap items-center justify-between gap-[clamp(2rem,5vw,4rem)] text-left relative">
<div className="flex flex-col items-start flex-[1_1_26rem] min-w-0">
<p className="flex flex-wrap items-center gap-[0.4rem] text-[length:0.8125rem] text-[color:var(--field-ink-warm-dim)] [&_a]:text-inherit [&_a:hover]:text-[color:var(--field-ink-warm)]">
<Link href="/iris">Iris</Link>
<span aria-hidden="true">/</span>
<Link href={`/iris/${category.slug}`}>{category.label}</Link>
<span aria-hidden="true">/</span>
<span>{creation.title}</span>
</p>
<h1 className="font-[family-name:var(--font-iris-display)] font-normal text-[length:clamp(2.25rem,1.3rem+4vw,4.25rem)] leading-[1.05] tracking-[-0.02em] max-w-[15ch] text-balance text-[color:var(--field-ink-warm)]">
Your favourite{" "}
<span className="text-[color:var(--iris-accent-bright)]">go-to field</span>.
</h1>
<p className="mt-4 max-w-[38ch] text-[length:1.0625rem] text-[color:var(--field-ink-warm-dim)]">
One live WebGL surface, copy-paste ready, doing the work a hero
photo and a badge usually split between them.
</p>
<div className="mt-8 flex flex-wrap gap-3">
<Link href={`/iris/${category.slug}/${creation.slug}#detail`} className="inline-flex items-center justify-center gap-[0.4rem] py-[0.8rem] px-5 rounded-[var(--iris-radius-sm)] border border-transparent text-[length:0.9375rem] font-medium leading-none whitespace-nowrap cursor-pointer transition-[background-color,border-color,color] duration-[120ms] ease-[ease] disabled:opacity-35 disabled:cursor-default disabled:pointer-events-none bg-[color:var(--iris-accent)] text-[color:var(--iris-accent-ink)] hover:bg-[color:var(--iris-accent-hover)]">
See it work
</Link>
<Link href="/iris/backgrounds" className="inline-flex items-center justify-center gap-[0.4rem] py-[0.8rem] px-5 rounded-[var(--iris-radius-sm)] border border-[color:var(--field-glass-warm-border)] text-[length:0.9375rem] font-medium leading-none whitespace-nowrap cursor-pointer transition-[background-color,border-color,color] duration-[120ms] ease-[ease] text-[color:var(--field-ink-warm)] bg-[color:var(--field-glass-warm)] [backdrop-filter:blur(14px)] [-webkit-backdrop-filter:blur(14px)] hover:bg-[color:var(--field-glass-warm-opaque)]">
Browse the catalogue
</Link>
</div>
<p className="mt-5 text-[length:0.8125rem] text-[color:var(--field-ink-warm-dim)]">
67 live fields · zero dependencies · reduced-motion safe
</p>
</div>
<dl className="flex-[0_1_18rem] flex flex-col gap-3 py-6 px-[1.75rem] rounded-[var(--iris-radius)] border border-[var(--field-glass-warm-border)] bg-[var(--field-glass-warm)] [backdrop-filter:blur(14px)_saturate(1.2)] [-webkit-backdrop-filter:blur(14px)_saturate(1.2)] [@media(prefers-reduced-transparency:reduce)]:[backdrop-filter:none] [@media(prefers-reduced-transparency:reduce)]:[-webkit-backdrop-filter:none] [@media(prefers-reduced-transparency:reduce)]:bg-[var(--field-glass-warm-opaque)]">
<div className="flex items-baseline justify-between gap-4 text-[length:0.9375rem]">
<dt className="text-[color:var(--field-ink-warm-dim)]">Ships as</dt>
<dd className="font-medium text-[color:var(--field-ink-warm)]">one file</dd>
</div>
<div className="flex items-baseline justify-between gap-4 text-[length:0.9375rem]">
<dt className="text-[color:var(--field-ink-warm-dim)]">Pointer</dt>
<dd className="font-medium text-[color:var(--field-ink-warm)]">bends the rays</dd>
</div>
<div className="flex items-baseline justify-between gap-4 text-[length:0.9375rem]">
<dt className="text-[color:var(--field-ink-warm-dim)]">Fallback</dt>
<dd className="font-medium text-[color:var(--field-ink-warm)]">CSS floor</dd>
</div>
</dl>
</div>
</header>
);
}