"use client" import { AnimatePresence, motion, useMotionValue, useSpring } from "motion/react" import { useEffect, useRef, useState } from "react" import { ArrowUpRightIcon } from "lucide-react" import { cn } from "@/lib/utils" import type { TemplateProps } from "../../lib/types" import { TImage } from "../shared/media" import { Counter, Marquee, Reveal, RevealWords, ScrollWords, ease } from "../shared/motion" import { TemplateShell } from "../shared/shell" import { agentur, type AgenturData } from "./definition" import { fonts } from "./fonts" const em = "italic text-t-accent" const container = "mx-auto w-full max-w-[1500px] px-5 md:px-10" const display = "font-t-display font-extrabold tracking-[-0.05em]" const GLYPHS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ#%&*+" // Buchstaben würfeln kurz durcheinander und rasten dann ein function Scramble({ text, className }: { text: string; className?: string }) { const [output, setOutput] = useState(text) const timer = useRef | null>(null) useEffect(() => () => { if (timer.current) clearInterval(timer.current) }, []) function run() { if (timer.current) clearInterval(timer.current) let frame = 0 timer.current = setInterval(() => { frame += 1 setOutput( text .split("") .map((char, i) => (char === " " || i < frame / 2 ? char : GLYPHS[(i * 7 + frame * 3) % GLYPHS.length])) .join("") ) if (frame / 2 >= text.length && timer.current) clearInterval(timer.current) }, 30) } return ( {output} ) } export function AgenturTemplate({ content }: TemplateProps) { const { brand, hero, clients, work, manifest, services, numbers, team, contact } = content.data const show = (key: string) => !content.hidden.includes(key) const [cursor, setCursor] = useState(null) const x = useMotionValue(-100) const y = useMotionValue(-100) const springX = useSpring(x, { stiffness: 500, damping: 40 }) const springY = useSpring(y, { stiffness: 500, damping: 40 }) useEffect(() => { const move = (event: PointerEvent) => { x.set(event.clientX) y.set(event.clientY) } window.addEventListener("pointermove", move) return () => window.removeEventListener("pointermove", move) }, [x, y]) return ( {cursor}

{hero.text}

{brand.tagline} · {brand.city}

{show("clients") && (
{clients.items.map((client, i) => ( {client.name} ))}
)}
{work.items.map((project, i) => (
setCursor("Ansehen")} onMouseLeave={() => setCursor(null)} className="sticky overflow-hidden rounded-[2rem] p-6 text-white md:p-10" style={{ top: `${6 + i * 1.5}rem`, background: project.color || "var(--t-surface)" }} >

{project.category} · {project.year}

{project.title}

{project.text}

Case ansehen
))}
{show("manifest") && (
)} {show("services") && } {show("numbers") && (
{numbers.items.map((item, i) => (
{item.suffix}
{item.label}
))}
)} {show("team") && (
{team.members.map((member, i) => (
setCursor("Hallo!")} onMouseLeave={() => setCursor(null)}>

{member.name}

{member.role}

))}
)}

{contact.text}

setCursor("Schreiben")} onMouseLeave={() => setCursor(null)} className={cn(display, "group relative mt-10 inline-block text-[clamp(2rem,6vw,5.5rem)] text-t-accent")} > {brand.email}

{brand.name} · {brand.city}

) } function Services({ services }: { services: AgenturData["services"] }) { const [active, setActive] = useState(null) return (
    setActive(null)}> {services.items.map((item, i) => (
  • setActive(i)} className="border-b border-t-fg/15">
    0{i + 1} {item.title} {(active === i || active === null) && ( {item.text} )}
  • ))}
) }