Skip to content

IrisSectionsGlow Beacon

Two flat layers, zero GPU.

No canvas, no shader, no pointer listener — a radial gradient and a repeating mask, tuned pixel-for-pixel against a real screenshot. The lightest field in the catalogue.

two flat layers · zero dependencies · no WebGL required

Ships as
two divs
Motion
none — held
Fallback
not needed
field

Glow Beacon

Same two-column anatomy as `solar-beacon` — claim and CTAs on the left, a glass ledger of proof on the right — built on `striped-glow` instead, the catalogue's other light-ground field and its only one with no WebGL underneath at all.

The ledger says so plainly rather than reusing solar-beacon's facts: where that one bends its rays to the pointer and falls back to a CSS floor if WebGL is missing, this field has no pointer to bend and nothing to fall back from — a radial gradient and a repeating mask were always going to render, on anything.

  • background
  • two-column
  • proof
  • glass
  • light-ground
  • static
Family
field
Status
Available
Licence
Free

Install

No installation needed — self-contained, paste-in code.

Usage

Drop it straight into a page.

example.tsx
import { StripedGlowField } from "./StripedGlowField";

export default function Example() {
  return (
    <header className="relative isolate min-h-[36rem] overflow-hidden flex items-center">
      <div className="absolute inset-0 -z-10">
        <StripedGlowField />
      </div>
      <div className="mx-auto max-w-xl px-8 text-left text-[#33251c]">
        <h1 className="text-5xl font-medium tracking-tight">
          Two flat layers, <span className="text-[#c9502a]">zero GPU</span>.
        </h1>
        <p className="mt-4 text-lg opacity-80">
          No canvas, no shader, no pointer listener — a radial gradient and
          a repeating mask, tuned pixel-for-pixel against a real screenshot.
        </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 { StripedGlowField } from "../visuals/backgrounds";

/**
 * The real `glow-beacon` section, full scale. Same two-column anatomy as
 * `solar-beacon` — claim and CTAs on the left, a glass ledger of proof on
 * the right — built on `striped-glow` instead, the catalogue's other
 * light-ground field and its only fully static one.
 *
 * The ledger states that plainly rather than reusing solar-beacon's facts:
 * where that one bends its rays to the pointer and falls back to a CSS
 * floor if WebGL is missing, this field has no pointer to bend and nothing
 * to fall back from — it never needed WebGL in the first place.
 */
export function GlowBeacon({
  category,
  creation,
}: {
  category: CategoryDef;
  creation: CreationCard;
}) {
  return (
    <header className="iris-hero iris-hero--field 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]">
          <StripedGlowField />
        </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-[16ch] text-balance text-[color:var(--field-ink-warm)]">
            Two flat layers,{" "}
            <span className="text-[color:var(--iris-accent-bright)]">zero GPU</span>.
          </h1>
          <p className="mt-4 max-w-[40ch] text-[length:1.0625rem] text-[color:var(--field-ink-warm-dim)]">
            No canvas, no shader, no pointer listener — a radial gradient and
            a repeating mask, tuned pixel-for-pixel against a real
            screenshot. The lightest field in the catalogue.
          </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)]">
            two flat layers · zero dependencies · no WebGL required
          </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)]">two divs</dd>
          </div>
          <div className="flex items-baseline justify-between gap-4 text-[length:0.9375rem]">
            <dt className="text-[color:var(--field-ink-warm-dim)]">Motion</dt>
            <dd className="font-medium text-[color:var(--field-ink-warm)]">none — held</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)]">not needed</dd>
          </div>
        </dl>
      </div>
    </header>
  );
}

More sections

Start with a background.

The backgrounds are the most finished corner of the catalogue. Take one and drop it under your own copy.

Browse backgrounds