"use client" import { useRef } from "react" import { cn } from "@/lib/utils" const GLYPHS = "!<>-_\\/[]{}=+*^?#01" const DURATION_MS = 420 /** Link whose label decodes itself on hover, like terminal output. */ export function ScrambleLink({ href, children, className, onClick, }: { href: string children: string className?: string onClick?: () => void }) { const textRef = useRef(null) const frameRef = useRef(0) const scramble = () => { const el = textRef.current if (!el || window.matchMedia("(prefers-reduced-motion: reduce)").matches) return cancelAnimationFrame(frameRef.current) const start = performance.now() const tick = (now: number) => { const progress = Math.min((now - start) / DURATION_MS, 1) const revealed = Math.floor(progress * children.length) el.textContent = children .split("") .map((char, index) => index < revealed || char === " " ? char : GLYPHS[Math.floor(Math.random() * GLYPHS.length)] ) .join("") if (progress < 1) frameRef.current = requestAnimationFrame(tick) } frameRef.current = requestAnimationFrame(tick) } return ( {/* Fixed width per character so the scramble never shifts the layout */} ) }