"use client"; /** * PillMark — the brand imagotype as a living system. * * Reconstructs the 4-bar capsule grid (violet→blue gradient bar / ink bar + * blue square / emerald bar) as inline SVG so each pill can be animated * independently: it assembles on mount, then breathes. Used at hero scale and * as a compact mark in dividers / footer. * * Decorative by default (aria-hidden). Pass `title` to expose it as an image. */ import { useEffect, useRef } from "react"; import { gsap } from "gsap"; type Props = { className?: string; /** Animate assembly on mount (hero). */ animate?: boolean; /** Continuous breathing after assembly. */ breathe?: boolean; title?: string; }; export default function PillMark({ className = "", animate = false, breathe = false, title, }: Props) { const ref = useRef(null); useEffect(() => { const el = ref.current; if (!el) return; if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; const ctx = gsap.context(() => { const bars = gsap.utils.toArray(".pillmark__bar"); if (animate) { gsap.set(bars, { transformOrigin: "center center" }); gsap.from(bars, { scaleX: 0, scaleY: 0.2, opacity: 0, duration: 1.1, ease: "elastic.out(1, 0.75)", stagger: { each: 0.09, from: "start" }, delay: 0.2, }); } if (breathe) { bars.forEach((bar, i) => { gsap.to(bar, { y: i % 2 === 0 ? "+=6" : "-=6", duration: 2.6 + i * 0.25, ease: "sine.inOut", repeat: -1, yoyo: true, delay: 1.2 + i * 0.1, }); }); } }, el); return () => ctx.revert(); }, [animate, breathe]); return ( {title ? {title} : null} {/* top: full-width violet→blue gradient capsule */} {/* middle row: ink wide capsule + blue square capsule */} {/* bottom: full-width emerald capsule */} ); }