A closing call-to-action band lit by moving caustics: sunlight through water, glass or silk, with prism dispersion, a pointer that focuses the light, and a glass button that ripples when pressed.

  • shader
  • webgl
  • cta
  • button
  • caustics
  • light
  • ripple
Preset

Installation

Pro — coming soon

The source and installation instructions for this item ship with Kagadmodyaa Pro.

Usage

Use it like any other component. Choose a theme with preset; any prop you pass as well overrides the preset.

import { LumenCta } from '@/components/effects/lumen-cta/lumen-cta'

// 1. The closing band of a landing page. It fills its parent, or takes a height.
export function Closing() {
  return (
    <section className="px-4 pb-10">
      <LumenCta
        preset="Lagoon"
        height={380}
        headline="Let your next launch catch the light."
        subline="Everything you need to ship a page people remember."
        primaryLabel="Start for free"
        primaryHref="/signup"
        secondaryLabel="Talk to sales"
        secondaryHref="/contact"
      />
    </section>
  )
}

// 2. A click handler instead of a link: pressing the primary button also sends a ripple across the band.
export function Waitlist() {
  return <LumenCta preset="Prism" align="center" primaryLabel="Join the waitlist" onClick={() => setOpen(true)} />
}

// 3. Your own colours. Text turns light or dark by itself; force it with textMode.
export function Branded() {
  return <LumenCta background="#1b0f3a" light="#ffe9a8" accent="#8a5bff" medium="glass" dispersion={0.8} />
}

// Presets: Lagoon, Prism, Dawn, Glacier (a light band with dark text), Noir. Any prop you pass overrides the preset.
// The stage above is <LumenCtaShowcase />, also exported: the band at the bottom of a faux landing page.
<LumenCta preset="Prism" medium={"water"} />

Presets

  • Lagoon
  • Prism
  • Dawn
  • Glacier
  • Noir

Props

NameTypeDefaultDescription
preset'Lagoon' | 'Prism' | 'Dawn' | 'Glacier' | 'Noir'none (the defaults below)A named theme. Any prop you pass as well overrides the preset’s value.
medium'water' | 'glass' | 'silk''water'What the light passes through: water ripples (every direction), faceted glass (a crystalline lattice) or silk (long folds with one grain).
scalenumber1Size of the caustic cells. Small is a fine web, large is broad pools. Range 0.5 to 2.2.
sharpnessnumber0.550 is a soft glow, 1 is hairline filaments. Range 0 to 1.
speednumber1How fast the light drifts. 0 freezes it. Range 0 to 2.
dispersionnumber0.3Chromatic dispersion: rainbow fringes at the brightest lines, as through a prism. Range 0 to 1.
intensitynumber1Strength of the caustic light. Range 0 to 1.5.
sweepnumber0.6A slow band of extra light that travels across the surface. 0 turns it off. Range 0 to 1.
focusnumber1How strongly the pointer acts as a lens: light focuses and brightens around it and the lines bend. Past 1 a bright ring forms. Range 0 to 2.
tintnumber0.6How much of the accent colour tints the surface, the haze and the shafts of light. Range 0 to 1.
ripplenumber1How strongly pressing the primary button sends a ripple of refracted light across the band. Range 0 to 2.
backgroundstring'#052f38'The colour of the surface between the light. Also the page colour of the stage while it loads. A hex colour.
lightstring'#b4fbf0'The colour of the caustic lines, the rim light and the glow of the primary button. A hex colour.
accentstring'#17b8b0'The soft skirt around each line, the volumetric haze and the shafts of light. A hex colour.
grainnumber0.35Fine film grain. It also dithers the gradients, so there is no banding. Range 0 to 1.
textMode'auto' | 'light' | 'dark''auto'auto picks white or ink from the surface's lightness. Force light or dark if you change the colours.
align'left' | 'center''left'Where the text sits. The light comes in from the opposite side.
heightnumber380Minimum height of the band in the stage. Stacked content on narrow screens can make it taller. Range 240 to 560 px.
headline'Let your next launch catch the light.' | 'Make the last section the best one.' | 'Ready when you are.' | 'Turn curious visitors into customers.''Let your next launch catch the light.'The headline, an <h2>.
subline'Everything you need to ship a page people remember, ready when you are.' | 'Join thousands of teams who ship faster, with fewer meetings.' | 'No credit card, no setup call. Be live before lunch.''Everything you need to ship a page people remember, ready when you are.'The line under the headline.
primaryLabel'Start for free' | 'Get started' | 'Book a demo' | 'Join the waitlist''Start for free'Label of the primary button (also pass primaryHref or onClick).
secondaryLabel'Talk to sales' | 'See pricing' | 'Take a tour''Talk to sales'Label of the secondary button. Leave it out in code for a single button.
classNamestring—Extra class on the root element. The effect fills its parent: give the parent a height.
styleCSSProperties—Inline style on the root element.

Behaviour

  • The light is real caustics, not noise: the shader builds a height field from travelling waves and finds where the surface bunches the rays up, which is where a pool floor shows its bright web. Cusps blaze, long folds stay faint, and the whole web slowly rearranges. Dispersion splits the light into a true spectrum at the brightest lines.
  • The pointer is a lens. Light focuses and brightens around the cursor, and the lines bend around it; push Pointer focus past 1 and a bright ring forms. On touch, pressing and dragging does the same. When the pointer leaves, the lens fades out.
  • Pressing the primary button, with a mouse, a finger or Enter and Space, sends a ripple across the band from where you pressed. The ripple refracts the whole web as it passes.
  • The primary button is a glass pill drawn into the light: it magnifies the caustics beneath it, and a lit rim wraps it wherever a bright line runs into its edge, strongest on the side facing the light. The label is ordinary text on top, so it stays crisp, selectable and accessible. The secondary button is a quiet glass outline with a faint rim.
  • Text stays legible in every frame: the light is turned down behind the text block, a soft scrim backs it up, and the sub-line is a solid colour chosen for at least 4.5:1 contrast. Text colour follows the surface (white on dark looks, ink on the light Glacier look); set Text colour to force one.
  • On a narrow band the buttons stack and fill the width. Left-aligned text sits on the calm side; the light comes in from the opposite corner.
  • It pauses while off screen and in a background tab, lowers its resolution automatically if frames run slow, and draws one composed still frame under prefers-reduced-motion (no ripple). Without WebGL, and before the first frame, you see a poster: the same colours as a gradient with a faint caustic web made from an SVG filter.

See all effects