Text Animation
Animated text effects for hero sections and landing pages. Gradient and shimmer are pure CSS. Word rotate and the typing effect use small JS hooks but render their full text server-side, so they still work without JavaScript and search engines see real text.
Gradient text
Text filled with a gradient that sweeps from end to end. Pure CSS, no hook required. Set the font size and weight with the class attr.
Change the colors with color_from and color_to, and the sweep time with duration.
Shimmer text
Muted text with a band of light passing over it, the classic "✨ Introducing ..." pill treatment. Pure CSS. Control the speed with duration.
Word rotate
Cycles through a list of words with a smooth roll-up transition. Requires the PetalWordRotate hook from the petal_components JS bundle, and the id attr is required. The first word is rendered server-side, so there's no layout jump and crawlers see a complete sentence.
Typing effect
Types text out character by character with a blinking caret. Requires the PetalTypingEffect hook from the petal_components JS bundle, and the id attr is required. The full text is rendered server-side and replayed on mount, so it reads fine without JavaScript and stays visible to search engines. Set loop to delete and retype forever.
Properties
gradient_text
attr :color_from, :string, default: "#ffaa40", doc: "start color of the gradient"
attr :color_to, :string, default: "#9c40ff", doc: "end color of the gradient"
attr :duration, :string, default: "8s", doc: "time for one full gradient sweep"
attr :class, :any, default: nil, doc: "extra classes (set font size/weight here)"
attr :rest, :global
slot :inner_block, required: true
shimmer_text
attr :duration, :string, default: "2.5s", doc: "time for one full shimmer pass"
attr :class, :any, default: nil, doc: "extra classes (set font size/weight here)"
attr :rest, :global
slot :inner_block, required: true
word_rotate
attr :id, :string, required: true
attr :words, :list, required: true, doc: "the words to cycle through"
attr :interval, :integer, default: 2500, doc: "milliseconds each word stays on screen"
attr :class, :any, default: nil, doc: "extra classes (set font size/weight here)"
attr :rest, :global
typing_effect
attr :id, :string, required: true
attr :text, :string, required: true, doc: "the text to type out"
attr :speed, :integer, default: 60, doc: "milliseconds per character"
attr :start_delay, :integer, default: 0, doc: "milliseconds to wait before typing starts"
attr :loop, :boolean, default: false, doc: "delete the text and type it again, forever"
attr :cursor, :boolean, default: true, doc: "show a blinking caret"
attr :class, :any, default: nil, doc: "extra classes (set font size/weight here)"
attr :rest, :global