Light Rays
Soft swaying rays of light for hero and section backgrounds.
pnpm dlx @glinui/cli@latest add light-raysSee every login before it becomes an incident
Risk scoring on each sign in, device trust checks and one click session revocation from a single audit trail.
Works with
- Vercel
- GitHub
- Cloudflare
- Astro
Installation
pnpm dlx @glinui/cli@latest add light-raysCredits. Adapted from Magic UI (MIT, (c) Magic UI). Web Animations instead of motion, seeded rays, token colors, reduced motion levels, offscreen pause and RTL mirroring. Attribution details.
Prefer the package?
Usage
Place the component as the first child of a relative parent and keep it behind content (use -z-10 or DOM order). Recommended intensity is 0.5 or lower behind body text so contrast stays at WCAG AA.
Large blur radii are expensive to paint. Count is capped at 24 and only the rays carry will-change.
Variants
Soft rays, crisp rays and another seed for a different layout.
import { LightRays } from "@glinui/ui"
export function Variants() { return ( <div data-glin-theme="dark" className="grid w-full gap-3 sm:grid-cols-3"> <div className="relative isolate flex h-44 items-end overflow-hidden rounded-xl bg-[var(--surface-0)] p-3"> <LightRays intensity={0.45} /> <span className="relative z-10 rounded-full bg-black/70 px-2.5 py-1 text-xs font-medium text-white">Soft</span> </div> <div className="relative isolate flex h-44 items-end overflow-hidden rounded-xl bg-[var(--surface-0)] p-3"> <LightRays variant="crisp" count={5} intensity={0.45} /> <span className="relative z-10 rounded-full bg-black/70 px-2.5 py-1 text-xs font-medium text-white">Crisp</span> </div> <div className="relative isolate flex h-44 items-end overflow-hidden rounded-xl bg-[var(--surface-0)] p-3"> <LightRays seed={4} count={9} blur={40} intensity={0.45} /> <span className="relative z-10 rounded-full bg-black/70 px-2.5 py-1 text-xs font-medium text-white">Seed 4</span> </div> </div> )}Behind a sign in card
Rays at intensity 0.45 or lower keep body text above AA contrast.
import { LightRays, Button, Heading, Input, Label, Text } from "@glinui/ui"
export function SignIn() { return ( <section data-glin-theme="dark" className="relative isolate flex min-h-[26rem] w-full items-center justify-center overflow-hidden rounded-xl bg-[var(--surface-0)] px-4 py-10"> <LightRays intensity={0.4} /> <form className="relative z-10 flex w-full max-w-sm flex-col gap-4 rounded-2xl border border-[var(--line-soft)] bg-[var(--surface-1)] p-6 text-left [box-shadow:var(--shadow-lg)]"> <div className="flex flex-col gap-1"> <Heading level={2} size="sm">Sign in to Northwind</Heading> <Text size="sm" variant="muted">Use your work email to continue.</Text> </div> <div className="flex flex-col gap-1.5"> <Label htmlFor="email">Work email</Label> <Input id="email" type="email" autoComplete="email" placeholder="you@company.com" /> </div> <div className="flex flex-col gap-1.5"> <Label htmlFor="password">Password</Label> <Input id="password" type="password" autoComplete="current-password" placeholder="At least 12 characters" /> </div> <Button type="submit" className="w-full">Continue</Button> </form> </section> )}Accessibility
- Purely decorative: aria-hidden and pointer-events none, never focusable.
- Keep intensity at 0.5 or lower behind text; verify AA contrast on your own background.
- No information is carried by the rays.
ARIA Attributes
- `aria-hidden="true"` on the root
Reduced Motion
At motion level full the rays sway with WAAPI. With prefers-reduced-motion or data-glin-motion none or subtle, the rays render as a static frame with no animation. Animations also pause offscreen and in background tabs.
Affected properties
opacitytransformAPI Reference
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
count | number | No | 7 | Number of rays, capped at 24. |
color | string | No | var(--color-accent) | Any CSS color or token. |
variant | "soft" | "crisp" | No | soft | Soft uses a 24px blur, crisp uses 6px. An explicit blur wins. |
blur | number | No | - | Blur radius in px. |
speed | number | No | 14 | Seconds per sway cycle. |
length | string | No | 120% | CSS length of each ray. |
intensity | number | No | 0.35 | Overall strength from 0 to 1. |
seed | number | No | 1 | Seed for the deterministic layout. |
Source
Import directly from the package or browse the source on GitHub. Click any file to view it.
Import
import { LightRays } from "@glinui/ui"Dependencies
@glinui/ui@glinui/motionclass-variance-authorityGenerated API Snapshot
Beta
Generated API Snapshot
BetaAuto-extracted from TypeScript source in packages/ui/src/components/light-rays.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.
Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata
Primary Props Type
LightRaysProps
LightRaysProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
blur | number | No | - | Blur radius in px. Defaults to 24 (soft) or 6 (crisp). |
color | string | No | "var(--color-accent)" | Any CSS color. Defaults to the accent token. |
count | number | No | 7 | Number of rays, capped at 24. |
intensity | number | No | 0.35 | Overall strength from 0 to 1. Keep at or below 0.5 behind text. |
length | string | No | "120%" | CSS length of each ray, for example "70%" or "28rem". |
seed | number | No | 1 | Seed for the deterministic ray layout. |
speed | number | No | 14 | Seconds for one sway cycle. |
variant | "soft" | "crisp" | No | "soft" | Variant option from lightRaysVariants. |