Components Border Beam

Petal Pro is the full SaaS app this is built for

Auth, billing, admin, and Claude Code integration included. One purchase, unlimited projects.

Petal Pro

Border Beam

An animated beam of light that travels the border of its container - the quiet way to draw the eye to a card, a CTA or an auth form. It's pure CSS (an offset-path animation), so there's no JavaScript and nothing to register. The wrapper is a proper panel now, so your content goes straight inside.
Basic Border Beam

Wrap your content and you get the panel plus a single beam on the default warm gradient.

Default border beam

heex
Custom Colors

Set color_from and color_to for the gradient, and duration for how long a full lap takes.

Cyan beam

heex
Beam with Content

There's no z-index dance - drop a full call-to-action straight inside the panel.

Ready when you are

Clone the repo, run the generators, ship by the weekend.

heex
Pricing Cards

The classic use: run a beam around the plan you want people to pick, and leave the others plain.

Pro
$99/mo
heex
Glow and Multiple Beams

glow swaps the sharp head for a soft comet that tolerates long size values. beams runs several evenly spaced around the border, and easing="spring" gives a single beam a springy settle at the seam.

glow

beams=3

heex
Newsletter Signup

A subtle beam turns a plain signup box into something worth stopping for.

Join the list

One email a week. No noise.

heex
Properties
elixir
          
  attr :color_from, :string, default: "#ffaa40", doc: "start color of the beam gradient"
  attr :color_to, :string, default: "#9c40ff", doc: "end color of the beam gradient"
  attr :duration, :string, default: "8s", doc: "time the beam takes to travel the full border once"
  attr :delay, :string, default: "0s", doc: "phase offset for the beam (a head start)"
  attr :size, :string, default: "150px", doc: "length of the beam, and how widely it swings through corners"
  attr :border_radius, :string, default: nil, doc: "container radius; follows the theme radius when unset"
  attr :border_width, :string, default: "1px", doc: "width of the border the beam runs along"
  attr :beams, :integer, default: 1, doc: "number of beams, evenly phased around the border"
  attr :reverse, :boolean, default: false, doc: "run the beam anticlockwise"
  attr :initial_offset, :integer, default: nil, doc: "shift the lap seam (0-100, % from the top-left)"
  attr :glow, :boolean, default: false, doc: "soft symmetric comet instead of a sharp head; tolerates long sizes"
  attr :easing, :string, default: "linear", values: ["linear", "ease-in-out", "spring"]
  attr :class, :any, default: nil
  attr :rest, :global

  slot :inner_block