"use client"; import { ReactNode } from "react"; import Image from "next/image"; import { motion, Variants } from "framer-motion"; import { C } from "./palette"; export { C }; const viewport = { once: true, amount: 0.2 } as const; /* Shared smooth easing — a soft, premium ease-out curve reused across reveals. */ const smoothEase = [0.22, 1, 0.36, 1] as const; /* stagger container variants */ export const stagger: Variants = { hidden: {}, show: { transition: { staggerChildren: 0.11, delayChildren: 0.06 } }, }; export const riseItem: Variants = { hidden: { opacity: 0, y: 34, scale: 0.96 }, show: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.7, ease: smoothEase }, }, }; /* ------- Section ------- */ type SectionProps = { id: string; children: ReactNode; variant?: "cream" | "deep" | "night" | "plain"; className?: string; }; export function Section({ id, children, variant = "deep", className = "" }: SectionProps) { const bg = variant === "cream" ? "bg-cream text-[#0a0a0a]" : variant === "night" ? "bg-night text-white" : variant === "plain" ? "bg-[#120a1f] text-white" : "bg-deep text-white"; return (
{children}
); } /* ------- Reveal (fade/slide up on scroll) ------- */ export function Reveal({ children, className = "", delay = 0, y = 26, }: { children: ReactNode; className?: string; delay?: number; y?: number; }) { return ( {children} ); } /* ------- Group (stagger children that use riseItem) ------- */ export function Group({ children, className = "", }: { children: ReactNode; className?: string; }) { return ( {children} ); } /* ------- Pill ------- */ export function Pill({ children, bg = C.pink, text = "#fff", }: { children: ReactNode; bg?: string; text?: string; }) { return ( {children} ); } /* ------- Card (scroll-reveal + neobrutalist hover) ------- */ export function Card({ children, bg = "#fff", text = "#0a0a0a", className = "", rounded = "rounded-2xl", delay = 0, group = false, }: { children: ReactNode; bg?: string; text?: string; className?: string; rounded?: string; delay?: number; /** set true when rendered inside a so stagger drives the entrance */ group?: boolean; }) { const entrance = group ? { variants: riseItem } : { initial: { opacity: 0, y: 30, scale: 0.96 }, whileInView: { opacity: 1, y: 0, scale: 1 }, viewport, transition: { duration: 0.7, ease: smoothEase, delay }, }; return ( {children} ); } /* ------- Chip ------- */ export function Chip({ children, bg = C.lime, text = "#0a0a0a", delay = 0, }: { children: ReactNode; bg?: string; text?: string; delay?: number; }) { return ( {children} ); } /* ------- Heading (self-animating) ------- */ export function Heading({ children, className = "", }: { children: ReactNode; className?: string; }) { return ( {children} ); } /* LytsUp wordmark */ export function Logo({ className = "" }: { className?: string }) { return ( LytsUp ); }