Skip to content

IrisSectionsHalo Beacon

One word, held in light.

A wordmark this size usually needs a badge and a second button to feel finished. The ring already did that work.

See it workNo sign-up, no card
field

Halo Beacon

A single wide-tracked line sits dead centre inside the ring's own light, the way a product shot leans a wordmark against a glowing loop instead of a plain field. One line of support copy, one button, one small caption underneath it — the three-tier close a lot of shots reach for, kept honest here because the button is real.

Built to prove the catalogue's field and hero-anatomy pieces compose freely: swap `HaloRingField` for any other background and the anatomy holds.

  • background
  • one-column
  • centered
  • wordmark
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 { HaloRingField } from "./HaloRingField";

export default function Example() {
  return (
    <header className="relative isolate min-h-[36rem] overflow-hidden bg-black flex flex-col items-center justify-center text-center">
      <div className="absolute inset-0 -z-10">
        <HaloRingField guardSelector="#halo-beacon-copy" />
      </div>
      <div id="halo-beacon-copy" className="mx-auto max-w-xl px-8 text-[#f5f5f5]">
        <h1 className="text-5xl font-medium tracking-wide">
          One word, <span className="text-[#a78bfa]">held in light</span>.
        </h1>
        <p className="mt-4 opacity-80">
          A wordmark this size usually needs a badge and a second button to
          feel finished. The ring already did that work.
        </p>
        <div className="mt-8 flex flex-col items-center gap-2">
          <a href="#" className="rounded-xl bg-[#7c3aed] px-5 py-3 text-white">
            See it work
          </a>
          <span className="text-sm opacity-70">No sign-up, no card</span>
        </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 { HaloRingField } from "../visuals/backgrounds";

/**
 * The real `halo-beacon` section, full scale. A wide, wide-tracked wordmark
 * sits inside the ring's own glow instead of over a plain field — no card,
 * no pill, the loop doing the work a logo mark usually does. One line of
 * support copy, one button, one small caption under it —
 * the three-tier close a lot of product shots reach for, kept honest here
 * because there is a real button underneath instead of a live account gate.
 */
export function HaloBeacon({
  category,
  creation,
}: {
  category: CategoryDef;
  creation: CreationCard;
}) {
  return (
    <header className="iris-hero iris-hero--field iris-section-hero--halo 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]">
          <HaloRingField guardSelector=".iris-section-hero--halo .iris-hero__inner" />
        </div>
      </div>

      <div className="iris-shell iris-hero__inner flex flex-col items-center relative text-center">
        <p className="flex flex-wrap items-center gap-[0.4rem] text-[length:0.8125rem] text-[var(--field-ink-dim)] [text-shadow:0_1px_10px_oklch(0.12_0.02_264_/_0.55)] [&_a]:text-inherit [&_a:hover]:text-[color:var(--field-ink)]">
          <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.5rem,1.5rem+4.4vw,5rem)] leading-[1.02] max-w-[20ch] tracking-[0.03em] text-balance text-[color:var(--field-ink)] [text-shadow:0_1px_12px_oklch(0.12_0.02_264_/_0.55)]">
          One word,{" "}
          <span className="text-[color:var(--iris-accent-bright)]">held in light</span>.
        </h1>
        <p className="mt-4 max-w-[38ch] text-[color:var(--field-ink-dim)] [text-shadow:0_1px_10px_oklch(0.1_0.02_240_/_0.55)]">
          A wordmark this size usually needs a badge and a second button to
          feel finished. The ring already did that work.
        </p>
        <div className="mt-9 flex flex-wrap justify-center flex-col gap-[0.6rem]">
          <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>
          <span className="text-[length:0.8125rem] text-[color:var(--field-ink-dim)] [text-shadow:0_1px_8px_oklch(0.1_0.02_240_/_0.5)]">
            No sign-up, no card
          </span>
        </div>
      </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