"use client";
import { motion, useReducedMotion } from "motion/react";
type LetterFlowProps = {
text: string;
className?: string;
/** Seconds between one letter and the next. */
stagger?: number;
/** Play only the first time it scrolls into view. */
once?: boolean;
};
/* LetterFlow: letters rise out from under an invisible line, tilting upright as they land, in one flowing wave. */
export function LetterFlow({ text, className = "", stagger = 0.025, once = true }: LetterFlowProps) {
const reduce = useReducedMotion();
if (reduce) return {text};
const words = text.split(" ");
// Each letter's place in the whole text, so the wave carries on across words.
const starts = words.map((_, w) => words.slice(0, w).join("").length);
return (
{text}
{words.map((word, w) => (
{/* Each word clips its own letters and never breaks across lines. */}
{[...word].map((ch, i) => (
({
y: 0,
rotate: 0,
transition: { type: "spring", stiffness: 260, damping: 24, delay: k * stagger },
}),
}}
>
{ch}
))}
{w < words.length - 1 && " "}
))}
);
}