{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry.json","name":"ui-designbycode","homepage":"https:\/\/ui.designbycode.co.za","items":[{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"activity-feed","type":"registry:block","title":"Activity Feed","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/activity-feed\/activity-feed.tsx","type":"registry:block","content":"'use client';\n\nimport React from 'react';\nimport { Card, CardHeader, CardTitle, CardContent } from '@\/components\/ui\/card';\n\ninterface EventItem {\n    time: string;\n    title: string;\n    details: string;\n    color: string;\n}\n\nconst events: EventItem[] = [\n    {\n        time: 'Just Now',\n        title: 'Version 2.0.4 Released',\n        details: 'Added 10 new blocks to the global registry seeder index.',\n        color: 'bg-primary',\n    },\n    {\n        time: '10m ago',\n        title: 'Database Migration Complete',\n        details: 'Successfully seeded 159 component manifest files.',\n        color: 'bg-chart-2',\n    },\n    {\n        time: '2h ago',\n        title: 'Theme Variables Injected',\n        details: 'CSS global variables synced with theme-slate values.',\n        color: 'bg-chart-4',\n    },\n];\n\nexport function ActivityFeed() {\n    return (\n        <Card className=\"mx-auto w-full max-w-md border-border\/50 bg-card\/30 backdrop-blur-xs\">\n            <CardHeader className=\"pb-3\">\n                <CardTitle className=\"text-base font-bold\">\n                    Activity Feed\n                <\/CardTitle>\n            <\/CardHeader>\n            <CardContent className=\"space-y-4\">\n                {events.map((event, idx) => (\n                    <div\n                        key={idx}\n                        className=\"relative flex items-start gap-3 pl-4 before:absolute before:top-2 before:bottom-0 before:left-1 before:w-[1px] before:bg-border\/30 last:before:hidden\"\n                    >\n                        <div\n                            className={`size-2.5 rounded-full ${event.color} relative -left-[17px] mt-1 shrink-0 ring-4 ring-background`}\n                        \/>\n                        <div className=\"min-w-0\">\n                            <div className=\"flex items-baseline justify-between gap-2\">\n                                <h4 className=\"truncate text-xs font-bold text-foreground\">\n                                    {event.title}\n                                <\/h4>\n                                <span className=\"shrink-0 text-[9px] text-muted-foreground\">\n                                    {event.time}\n                                <\/span>\n                            <\/div>\n                            <p className=\"mt-0.5 text-[10px] leading-relaxed text-muted-foreground\">\n                                {event.details}\n                            <\/p>\n                        <\/div>\n                    <\/div>\n                ))}\n            <\/CardContent>\n        <\/Card>\n    );\n}\n\nexport default ActivityFeed;\n"}],"meta":{"category":"activity-feed","version":"1.0.0"},"categories":["activity-feed"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"analytics-dashboard","type":"registry:block","title":"Analytics Dashboard","description":"A comprehensive, premium analytics dashboard showing statistics, performance metrics, and graphs.","author":"designbycode","dependencies":["recharts","lucide-react"],"devDependencies":[],"registryDependencies":["button","card","badge","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/analytics-dashboard\/analytics-dashboard.tsx","type":"registry:block","content":"'use client';\nimport React, { useState, useEffect } from 'react';\nimport {\n    ResponsiveContainer,\n    AreaChart,\n    Area,\n    XAxis,\n    YAxis,\n    Tooltip as ChartTooltip,\n    CartesianGrid,\n    BarChart,\n    Bar,\n} from 'recharts';\nimport {\n    Users,\n    MousePointerClick,\n    RefreshCw,\n    Calendar,\n    ArrowUpRight,\n    TrendingUp,\n    TrendingDown,\n    Activity,\n    Globe,\n    Search as SearchIcon,\n} from 'lucide-react';\nimport { Button } from '@\/components\/ui\/button';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { cn } from '@\/lib\/utils';\n\n\/\/ Mock trend history\nconst trendData = [\n    { name: 'Jan', visits: 4000, pageviews: 2400 },\n    { name: 'Feb', visits: 3000, pageviews: 1398 },\n    { name: 'Mar', visits: 2000, pageviews: 9800 },\n    { name: 'Apr', visits: 2780, pageviews: 3908 },\n    { name: 'May', visits: 1890, pageviews: 4800 },\n    { name: 'Jun', visits: 2390, pageviews: 3800 },\n    { name: 'Jul', visits: 3490, pageviews: 4300 },\n    { name: 'Aug', visits: 4200, pageviews: 5400 },\n    { name: 'Sep', visits: 3900, pageviews: 4900 },\n    { name: 'Oct', visits: 4500, pageviews: 5900 },\n    { name: 'Nov', visits: 4800, pageviews: 6500 },\n    { name: 'Dec', visits: 5400, pageviews: 7200 },\n];\n\n\/\/ Mock traffic sources\nconst sourceData = [\n    {\n        name: 'Organic Search',\n        value: 4300,\n        color: 'var(--color-chart-3)',\n    },\n    { name: 'Direct', value: 2900, color: 'var(--color-chart-2)' },\n    { name: 'Social', value: 2100, color: 'var(--color-chart-1)' },\n    {\n        name: 'Referrals',\n        value: 1400,\n        color: 'var(--color-chart-4)',\n    },\n];\n\n\/\/ Mock conversions list\nconst initialConversions = [\n    {\n        id: '1',\n        user: 'Alex Morgan',\n        email: 'alex@example.com',\n        amount: '$120.00',\n        status: 'Success',\n        time: '2 mins ago',\n    },\n    {\n        id: '2',\n        user: 'Sarah Chen',\n        email: 'sarah.c@example.com',\n        amount: '$350.00',\n        status: 'Success',\n        time: '10 mins ago',\n    },\n    {\n        id: '3',\n        user: 'Michael Scott',\n        email: 'm.scott@example.com',\n        amount: '$49.00',\n        status: 'Success',\n        time: '22 mins ago',\n    },\n    {\n        id: '4',\n        user: 'Emma Watson',\n        email: 'emma@example.com',\n        amount: '$899.00',\n        status: 'Success',\n        time: '45 mins ago',\n    },\n];\n\nexport function AnalyticsDashboard() {\n    const [isMounted, setIsMounted] = useState(false);\n    const [conversions, setConversions] = useState(initialConversions);\n    const [isRefreshing, setIsRefreshing] = useState(false);\n\n    useEffect(() => {\n        setIsMounted(true);\n    }, []);\n\n    const handleRefresh = () => {\n        setIsRefreshing(true);\n        setTimeout(() => {\n            \/\/ Add a mock random new conversion to top\n            const names = [\n                'John Doe',\n                'Linda Carter',\n                'Devon Lane',\n                'Bessie Cooper',\n            ];\n            const emails = [\n                'john@example.com',\n                'linda@example.com',\n                'devon@example.com',\n                'bessie@example.com',\n            ];\n            const amounts = ['$59.00', '$199.00', '$29.00', '$450.00'];\n\n            const randomIndex = Math.floor(Math.random() * names.length);\n\n            const newConv = {\n                id: Date.now().toString(),\n                user: names[randomIndex],\n                email: emails[randomIndex],\n                amount: amounts[randomIndex],\n                status: 'Success',\n                time: 'Just now',\n            };\n\n            setConversions((prev) => [newConv, ...prev.slice(0, 3)]);\n            setIsRefreshing(false);\n        }, 800);\n    };\n\n    return (\n        <div className=\"mx-auto flex w-full max-w-5xl flex-col gap-6 px-4 py-6\">\n            {\/* Header Control row *\/}\n            <div className=\"flex flex-col justify-between gap-4 border-b border-border\/20 pb-6 sm:flex-row sm:items-center\">\n                <div>\n                    <h2 className=\"text-2xl font-bold tracking-tight\">\n                        Analytics Overview\n                    <\/h2>\n                    <p className=\"mt-0.5 text-xs text-muted-foreground\">\n                        Real-time engagement telemetry dashboard\n                    <\/p>\n                <\/div>\n\n                <div className=\"flex items-center gap-2\">\n                    <Button\n                        variant=\"outline\"\n                        size=\"sm\"\n                        className=\"flex h-8.5 items-center gap-1.5 text-xs\"\n                    >\n                        <Calendar className=\"size-3.5\" \/>\n                        Last 12 Months\n                    <\/Button>\n                    <Button\n                        size=\"sm\"\n                        variant=\"default\"\n                        className=\"flex h-8.5 items-center gap-1.5 text-xs\"\n                        onClick={handleRefresh}\n                        disabled={isRefreshing}\n                    >\n                        <RefreshCw\n                            className={cn(\n                                'size-3.5',\n                                isRefreshing && 'animate-spin',\n                            )}\n                        \/>\n                        Refresh\n                    <\/Button>\n                <\/div>\n            <\/div>\n\n            {\/* Quick Metrics Cards *\/}\n            <div className=\"grid w-full gap-4 sm:grid-cols-3\">\n                <Card className=\"flex flex-row items-center gap-4 border border-border\/40 bg-card\/30 p-4.5 backdrop-blur-xs\">\n                    <div className=\"flex size-10 shrink-0 items-center justify-center rounded-xl bg-chart-3\/10 text-chart-3\">\n                        <Users className=\"size-5\" \/>\n                    <\/div>\n                    <div className=\"min-w-0 flex-1\">\n                        <span className=\"text-[10px] font-semibold tracking-wider text-muted-foreground uppercase\">\n                            Total Visitors\n                        <\/span>\n                        <div className=\"mt-0.5 flex items-baseline gap-2\">\n                            <span className=\"font-mono text-xl font-bold\">\n                                148,290\n                            <\/span>\n                            <span className=\"flex items-center gap-0.5 text-[10px] font-semibold text-chart-2\">\n                                <TrendingUp className=\"size-3\" \/> +12.4%\n                            <\/span>\n                        <\/div>\n                    <\/div>\n                <\/Card>\n\n                <Card className=\"flex flex-row items-center gap-4 border border-border\/40 bg-card\/30 p-4.5 backdrop-blur-xs\">\n                    <div className=\"flex size-10 shrink-0 items-center justify-center rounded-xl bg-chart-2\/10 text-chart-2\">\n                        <MousePointerClick className=\"size-5\" \/>\n                    <\/div>\n                    <div className=\"min-w-0 flex-1\">\n                        <span className=\"text-[10px] font-semibold tracking-wider text-muted-foreground uppercase\">\n                            Conversion Rate\n                        <\/span>\n                        <div className=\"mt-0.5 flex items-baseline gap-2\">\n                            <span className=\"font-mono text-xl font-bold\">\n                                3.48%\n                            <\/span>\n                            <span className=\"flex items-center gap-0.5 text-[10px] font-semibold text-chart-2\">\n                                <TrendingUp className=\"size-3\" \/> +4.2%\n                            <\/span>\n                        <\/div>\n                    <\/div>\n                <\/Card>\n\n                <Card className=\"flex flex-row items-center gap-4 border border-border\/40 bg-card\/30 p-4.5 backdrop-blur-xs\">\n                    <div className=\"flex size-10 shrink-0 items-center justify-center rounded-xl bg-destructive\/10 text-destructive\">\n                        <Activity className=\"size-5\" \/>\n                    <\/div>\n                    <div className=\"min-w-0 flex-1\">\n                        <span className=\"text-[10px] font-semibold tracking-wider text-muted-foreground uppercase\">\n                            Bounce Rate\n                        <\/span>\n                        <div className=\"mt-0.5 flex items-baseline gap-2\">\n                            <span className=\"font-mono text-xl font-bold\">\n                                42.15%\n                            <\/span>\n                            <span className=\"flex items-center gap-0.5 text-[10px] font-semibold text-destructive\">\n                                <TrendingDown className=\"size-3\" \/> -1.8%\n                            <\/span>\n                        <\/div>\n                    <\/div>\n                <\/Card>\n            <\/div>\n\n            {\/* Performance Main Chart Card *\/}\n            <Card className=\"border border-border\/40 bg-card\/30 backdrop-blur-xs\">\n                <CardHeader>\n                    <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                        <Globe className=\"size-4 text-muted-foreground\" \/>\n                        Engagement History\n                    <\/CardTitle>\n                    <CardDescription className=\"text-xs\">\n                        Comparison trends between raw visitors traffic and\n                        engaged pageviews.\n                    <\/CardDescription>\n                <\/CardHeader>\n                <CardContent className=\"h-64 pt-2\">\n                    {isMounted ? (\n                        <ResponsiveContainer width=\"100%\" height=\"100%\">\n                            <AreaChart\n                                data={trendData}\n                                margin={{\n                                    top: 0,\n                                    right: 10,\n                                    left: -20,\n                                    bottom: 0,\n                                }}\n                            >\n                                <defs>\n                                    <linearGradient\n                                        id=\"colorVisits\"\n                                        x1=\"0\"\n                                        y1=\"0\"\n                                        x2=\"0\"\n                                        y2=\"1\"\n                                    >\n                                        <stop\n                                            offset=\"5%\"\n                                            stopColor=\"var(--color-primary, #6366f1)\"\n                                            stopOpacity={0.25}\n                                        \/>\n                                        <stop\n                                            offset=\"95%\"\n                                            stopColor=\"var(--color-primary, #6366f1)\"\n                                            stopOpacity={0.0}\n                                        \/>\n                                    <\/linearGradient>\n                                    <linearGradient\n                                        id=\"colorViews\"\n                                        x1=\"0\"\n                                        y1=\"0\"\n                                        x2=\"0\"\n                                        y2=\"1\"\n                                    >\n                                        <stop\n                                            offset=\"5%\"\n                                            stopColor=\"var(--color-chart-2)\"\n                                            stopOpacity={0.2}\n                                        \/>\n                                        <stop\n                                            offset=\"95%\"\n                                            stopColor=\"var(--color-chart-2)\"\n                                            stopOpacity={0.0}\n                                        \/>\n                                    <\/linearGradient>\n                                <\/defs>\n                                <CartesianGrid\n                                    strokeDasharray=\"3 3\"\n                                    vertical={false}\n                                    stroke=\"var(--color-border, #e2e8f0)\"\n                                \/>\n                                <XAxis\n                                    dataKey=\"name\"\n                                    stroke=\"var(--color-muted-foreground, #64748b)\"\n                                    fontSize={10}\n                                    tickLine={false}\n                                    axisLine={false}\n                                \/>\n                                <YAxis\n                                    stroke=\"var(--color-muted-foreground, #64748b)\"\n                                    fontSize={10}\n                                    tickLine={false}\n                                    axisLine={false}\n                                \/>\n                                <ChartTooltip\n                                    contentStyle={{\n                                        background:\n                                            'var(--color-popover, #ffffff)',\n                                        borderColor:\n                                            'var(--color-border, #e2e8f0)',\n                                        borderRadius: '8px',\n                                        fontSize: '11px',\n                                    }}\n                                \/>\n                                <Area\n                                    type=\"monotone\"\n                                    dataKey=\"pageviews\"\n                                    stroke=\"var(--color-chart-2)\"\n                                    strokeWidth={2}\n                                    fillOpacity={1}\n                                    fill=\"url(#colorViews)\"\n                                    name=\"Pageviews\"\n                                \/>\n                                <Area\n                                    type=\"monotone\"\n                                    dataKey=\"visits\"\n                                    stroke=\"var(--color-primary, #6366f1)\"\n                                    strokeWidth={2}\n                                    fillOpacity={1}\n                                    fill=\"url(#colorVisits)\"\n                                    name=\"Unique Visitors\"\n                                \/>\n                            <\/AreaChart>\n                        <\/ResponsiveContainer>\n                    ) : (\n                        <div className=\"flex h-full w-full animate-pulse items-center justify-center rounded-lg bg-muted\/20 font-mono text-xs text-muted-foreground\">\n                            Loading chart telemetry...\n                        <\/div>\n                    )}\n                <\/CardContent>\n            <\/Card>\n\n            {\/* Split Bottom Section *\/}\n            <div className=\"grid w-full items-stretch gap-6 md:grid-cols-2\">\n                {\/* Real-time Transactions Feed *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/30 backdrop-blur-xs\">\n                    <div>\n                        <CardHeader>\n                            <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                                <SearchIcon className=\"size-4 text-muted-foreground\" \/>\n                                Real-time conversions\n                            <\/CardTitle>\n                            <CardDescription className=\"text-xs\">\n                                Live view of active user acquisitions and signup\n                                events.\n                            <\/CardDescription>\n                        <\/CardHeader>\n                        <CardContent className=\"space-y-4\">\n                            {conversions.map((conv) => (\n                                <div\n                                    key={conv.id}\n                                    className=\"flex items-center justify-between border-b border-border\/20 py-1 last:border-b-0\"\n                                >\n                                    <div className=\"flex items-center gap-3\">\n                                        <div className=\"flex size-8 items-center justify-center rounded-full bg-primary\/10 text-xs font-bold text-primary\">\n                                            {conv.user\n                                                .split(' ')\n                                                .map((n) => n[0])\n                                                .join('')}\n                                        <\/div>\n                                        <div className=\"flex min-w-0 flex-col gap-0.5\">\n                                            <span className=\"truncate text-xs font-semibold\">\n                                                {conv.user}\n                                            <\/span>\n                                            <span className=\"truncate text-[10px] text-muted-foreground\">\n                                                {conv.email}\n                                            <\/span>\n                                        <\/div>\n                                    <\/div>\n                                    <div className=\"text-right\">\n                                        <span className=\"font-mono text-xs font-bold text-primary\">\n                                            {conv.amount}\n                                        <\/span>\n                                        <span className=\"block font-mono text-[9px] text-muted-foreground\">\n                                            {conv.time}\n                                        <\/span>\n                                    <\/div>\n                                <\/div>\n                            ))}\n                        <\/CardContent>\n                    <\/div>\n                <\/Card>\n\n                {\/* Traffic Channels breakdown *\/}\n                <Card className=\"border border-border\/40 bg-card\/30 backdrop-blur-xs\">\n                    <CardHeader>\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Activity className=\"size-4 text-muted-foreground\" \/>\n                            Acquisition Channels\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Distribution of incoming visitor sessions grouped by\n                            source.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"h-56\">\n                        {isMounted ? (\n                            <ResponsiveContainer width=\"100%\" height=\"100%\">\n                                <BarChart\n                                    data={sourceData}\n                                    margin={{\n                                        top: 0,\n                                        right: 0,\n                                        left: -20,\n                                        bottom: 0,\n                                    }}\n                                >\n                                    <CartesianGrid\n                                        strokeDasharray=\"3 3\"\n                                        vertical={false}\n                                        stroke=\"var(--color-border, #e2e8f0)\"\n                                    \/>\n                                    <XAxis\n                                        dataKey=\"name\"\n                                        stroke=\"var(--color-muted-foreground, #64748b)\"\n                                        fontSize={10}\n                                        tickLine={false}\n                                        axisLine={false}\n                                    \/>\n                                    <YAxis\n                                        stroke=\"var(--color-muted-foreground, #64748b)\"\n                                        fontSize={10}\n                                        tickLine={false}\n                                        axisLine={false}\n                                    \/>\n                                    <Bar\n                                        dataKey=\"value\"\n                                        radius={[4, 4, 0, 0]}\n                                        fill=\"var(--color-primary, #6366f1)\"\n                                    \/>\n                                <\/BarChart>\n                            <\/ResponsiveContainer>\n                        ) : (\n                            <div className=\"flex h-full w-full animate-pulse items-center justify-center rounded-lg bg-muted\/20 font-mono text-xs text-muted-foreground\">\n                                Loading acquisition channels...\n                            <\/div>\n                        )}\n                    <\/CardContent>\n                <\/Card>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default AnalyticsDashboard;\n"}],"meta":{"category":"analytics-dashboard","version":"1.0.0"},"categories":["analytics-dashboard"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"booking-form","type":"registry:block","title":"Booking Form","description":"A clean and responsive booking card form layout for properties or services.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["badge","button","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/booking-form\/booking-form.tsx","type":"registry:block","content":"import {\n    Calendar as CalendarIcon,\n    Users,\n    ArrowRight,\n    Loader2,\n    Sparkles,\n    CheckCircle2,\n} from 'lucide-react';\nimport React, { useState, useMemo } from 'react';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Button } from '@\/components\/ui\/button';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardFooter,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\n\nexport function BookingForm({\n    pricePerNight = 120,\n    cleaningFee = 45,\n    serviceFee = 25,\n}: {\n    pricePerNight?: number;\n    cleaningFee?: number;\n    serviceFee?: number;\n}) {\n    const [checkIn, setCheckIn] = useState('');\n    const [checkOut, setCheckOut] = useState('');\n    const [guests, setGuests] = useState(2);\n    const [isLoading, setIsLoading] = useState(false);\n    const [isBooked, setIsBooked] = useState(false);\n\n    const nights = useMemo(() => {\n        if (!checkIn || !checkOut) {\n            return 0;\n        }\n\n        const start = new Date(checkIn);\n        const end = new Date(checkOut);\n        const diffTime = Math.abs(end.getTime() - start.getTime());\n        const diffDays = Math.ceil(diffTime \/ (1000 * 60 * 60 * 24));\n\n        return isNaN(diffDays) ? 0 : diffDays;\n    }, [checkIn, checkOut]);\n\n    const totalCost = useMemo(() => {\n        if (nights === 0) {\n            return 0;\n        }\n\n        return pricePerNight * nights + cleaningFee + serviceFee;\n    }, [nights, pricePerNight, cleaningFee, serviceFee]);\n\n    const handleSearch = (e: React.FormEvent) => {\n        e.preventDefault();\n\n        if (!checkIn || !checkOut || nights <= 0) {\n            return;\n        }\n\n        setIsLoading(true);\n        setTimeout(() => {\n            setIsLoading(false);\n            setIsBooked(true);\n        }, 1500);\n    };\n\n    const resetBooking = () => {\n        setIsBooked(false);\n        setCheckIn('');\n        setCheckOut('');\n        setGuests(2);\n    };\n\n    return (\n        <Card className=\"relative mx-auto w-full max-w-md overflow-hidden border border-border\/40 bg-card\/40 shadow-2xl backdrop-blur-md transition-all duration-300\">\n            {\/* Ambient Background Glow *\/}\n            <div className=\"pointer-events-none absolute top-0 right-0 h-36 w-36 rounded-full bg-primary\/10 blur-2xl\" \/>\n            <div className=\"pointer-events-none absolute -bottom-8 -left-8 h-36 w-36 rounded-full bg-chart-2\/5 blur-2xl\" \/>\n\n            <CardHeader className=\"relative z-10\">\n                <div className=\"flex items-center justify-between\">\n                    <div>\n                        <CardTitle className=\"font-sans text-xl font-bold\">\n                            Book Your Stay\n                        <\/CardTitle>\n                        <CardDescription className=\"mt-0.5 text-xs\">\n                            Check availability and secure your dates\n                        <\/CardDescription>\n                    <\/div>\n                    <div className=\"text-right\">\n                        <span className=\"font-sans text-xl font-extrabold text-foreground\">\n                            ${pricePerNight}\n                        <\/span>\n                        <span className=\"text-xs text-muted-foreground\">\n                            {' '}\n                            \/ night\n                        <\/span>\n                    <\/div>\n                <\/div>\n            <\/CardHeader>\n\n            <CardContent className=\"relative z-10 space-y-4\">\n                {isBooked ? (\n                    <div className=\"animate-fadeIn space-y-4 py-8 text-center\">\n                        <div className=\"mx-auto flex size-14 items-center justify-center rounded-full bg-chart-2\/10 text-chart-2 shadow-inner\">\n                            <CheckCircle2 className=\"size-8\" \/>\n                        <\/div>\n                        <div className=\"space-y-2\">\n                            <h3 className=\"font-sans text-lg font-bold text-foreground\">\n                                Dates are Available!\n                            <\/h3>\n                            <p className=\"mx-auto max-w-xs text-xs text-muted-foreground\">\n                                We have temporarily reserved your stay from{' '}\n                                <span className=\"font-semibold text-foreground\">\n                                    {checkIn}\n                                <\/span>{' '}\n                                to{' '}\n                                <span className=\"font-semibold text-foreground\">\n                                    {checkOut}\n                                <\/span>{' '}\n                                ({nights} nights) for{' '}\n                                <span className=\"font-semibold text-foreground\">\n                                    {guests} guests\n                                <\/span>\n                                .\n                            <\/p>\n                        <\/div>\n                        <div className=\"flex justify-center gap-2 pt-2\">\n                            <Button\n                                onClick={resetBooking}\n                                variant=\"outline\"\n                                size=\"sm\"\n                            >\n                                Change Dates\n                            <\/Button>\n                            <Button\n                                className=\"bg-primary font-semibold text-primary-foreground hover:bg-primary\/90\"\n                                size=\"sm\"\n                            >\n                                Proceed to Payment\n                            <\/Button>\n                        <\/div>\n                    <\/div>\n                ) : (\n                    <form onSubmit={handleSearch} className=\"space-y-4\">\n                        <div className=\"grid grid-cols-2 gap-3\">\n                            <div className=\"space-y-1\">\n                                <label className=\"flex items-center gap-1 text-[10px] font-bold tracking-wider text-muted-foreground uppercase\">\n                                    <CalendarIcon className=\"size-3 text-primary\" \/>\n                                    Check In\n                                <\/label>\n                                <input\n                                    type=\"date\"\n                                    required\n                                    min={new Date().toISOString().split('T')[0]}\n                                    value={checkIn}\n                                    onChange={(e) => setCheckIn(e.target.value)}\n                                    className=\"w-full rounded-lg border border-border\/40 bg-muted\/40 px-3 py-2 text-xs text-foreground transition-all hover:bg-muted\/60 focus:border-primary\/50 focus:outline-none\"\n                                \/>\n                            <\/div>\n                            <div className=\"space-y-1\">\n                                <label className=\"flex items-center gap-1 text-[10px] font-bold tracking-wider text-muted-foreground uppercase\">\n                                    <CalendarIcon className=\"size-3 text-primary\" \/>\n                                    Check Out\n                                <\/label>\n                                <input\n                                    type=\"date\"\n                                    required\n                                    min={\n                                        checkIn ||\n                                        new Date().toISOString().split('T')[0]\n                                    }\n                                    value={checkOut}\n                                    onChange={(e) =>\n                                        setCheckOut(e.target.value)\n                                    }\n                                    className=\"w-full rounded-lg border border-border\/40 bg-muted\/40 px-3 py-2 text-xs text-foreground transition-all hover:bg-muted\/60 focus:border-primary\/50 focus:outline-none\"\n                                \/>\n                            <\/div>\n                        <\/div>\n\n                        <div className=\"space-y-1.5\">\n                            <label className=\"flex items-center gap-1 text-[10px] font-bold tracking-wider text-muted-foreground uppercase\">\n                                <Users className=\"size-3 text-primary\" \/>\n                                Guests\n                            <\/label>\n                            <div className=\"flex items-center justify-between rounded-lg border border-border\/40 bg-muted\/20 px-3 py-1.5\">\n                                <span className=\"text-xs font-semibold\">\n                                    {guests} {guests === 1 ? 'Guest' : 'Guests'}\n                                <\/span>\n                                <div className=\"flex items-center gap-1\">\n                                    <button\n                                        type=\"button\"\n                                        onClick={() =>\n                                            setGuests(Math.max(1, guests - 1))\n                                        }\n                                        className=\"size-7 cursor-pointer rounded border border-border\/40 bg-muted\/60 text-xs font-bold select-none hover:border-border hover:bg-muted\"\n                                    >\n                                        -\n                                    <\/button>\n                                    <button\n                                        type=\"button\"\n                                        onClick={() =>\n                                            setGuests(Math.min(6, guests + 1))\n                                        }\n                                        className=\"size-7 cursor-pointer rounded border border-border\/40 bg-muted\/60 text-xs font-bold select-none hover:border-border hover:bg-muted\"\n                                    >\n                                        +\n                                    <\/button>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n\n                        <Button\n                            type=\"submit\"\n                            disabled={\n                                isLoading ||\n                                !checkIn ||\n                                !checkOut ||\n                                nights <= 0\n                            }\n                            className=\"group relative mt-2 w-full overflow-hidden bg-primary font-bold tracking-wide text-primary-foreground transition-all duration-300 hover:bg-primary\/95\"\n                        >\n                            {isLoading ? (\n                                <span className=\"flex items-center gap-2\">\n                                    <Loader2 className=\"size-4 animate-spin\" \/>\n                                    Checking Rooms...\n                                <\/span>\n                            ) : (\n                                <span className=\"flex items-center gap-1\">\n                                    Check Availability\n                                    <ArrowRight className=\"size-4 transition-transform group-hover:translate-x-1\" \/>\n                                <\/span>\n                            )}\n                        <\/Button>\n                    <\/form>\n                )}\n\n                {nights > 0 && !isBooked && (\n                    <div className=\"animate-fadeIn space-y-2.5 border-t border-border\/40 pt-4\">\n                        <h4 className=\"text-[10px] font-bold tracking-wider text-muted-foreground uppercase\">\n                            Price Details\n                        <\/h4>\n                        <div className=\"space-y-1.5\">\n                            <div className=\"flex justify-between text-xs text-muted-foreground\">\n                                <span>\n                                    ${pricePerNight} x {nights} nights\n                                <\/span>\n                                <span className=\"font-semibold text-foreground\">\n                                    ${pricePerNight * nights}\n                                <\/span>\n                            <\/div>\n                            <div className=\"flex justify-between text-xs text-muted-foreground\">\n                                <span>Cleaning fee<\/span>\n                                <span className=\"font-semibold text-foreground\">\n                                    ${cleaningFee}\n                                <\/span>\n                            <\/div>\n                            <div className=\"flex justify-between text-xs text-muted-foreground\">\n                                <span>Service fee<\/span>\n                                <span className=\"font-semibold text-foreground\">\n                                    ${serviceFee}\n                                <\/span>\n                            <\/div>\n                            <div className=\"flex justify-between border-t border-border\/20 pt-2 text-sm font-bold text-foreground\">\n                                <span className=\"flex items-center gap-1\">\n                                    Total\n                                    <Badge\n                                        variant=\"outline\"\n                                        className=\"border-primary\/20 bg-primary\/5 px-1 py-0 font-mono text-[9px] text-primary\"\n                                    >\n                                        Best Price\n                                    <\/Badge>\n                                <\/span>\n                                <span>${totalCost}<\/span>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                )}\n            <\/CardContent>\n\n            <CardFooter className=\"relative z-10 flex items-center justify-center gap-1.5 border-t border-border\/20 bg-muted\/15 px-6 py-3 text-[10px] text-muted-foreground\">\n                <Sparkles className=\"size-3.5 text-chart-4\" \/>\n                <span>Free cancellation up to 48 hours before check-in<\/span>\n            <\/CardFooter>\n        <\/Card>\n    );\n}\n\nexport default BookingForm;\n"}],"meta":{"category":"forms","version":"1.0.0"},"categories":["forms"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"buttons-gallery","type":"registry:block","title":"Buttons Gallery","description":"A showcase of various button designs including magnetic, particles, and shining effect variants.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/button-particles.json","https:\/\/ui.test\/r\/button-magnetic.json","https:\/\/ui.test\/r\/button-shine.json","https:\/\/ui.test\/r\/glow-conic.json","card","badge"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/buttons-gallery\/buttons-gallery.tsx","type":"registry:block","content":"import React from 'react';\nimport { Play, Sparkles, Move, Sun, Compass } from 'lucide-react';\nimport { ButtonParticles } from '@\/registry\/new-york\/components\/ui\/buttons\/button-particles';\nimport { ButtonMagnetic } from '@\/registry\/new-york\/components\/ui\/buttons\/button-magnetic';\nimport { ButtonShine } from '@\/registry\/new-york\/components\/ui\/buttons\/button-shine';\nimport GlowConic from '@\/registry\/new-york\/components\/ui\/glow\/glow-conic';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\nimport { Badge } from '@\/components\/ui\/badge';\n\nexport function ButtonsGallery() {\n    return (\n        <div className=\"mx-auto flex w-full max-w-5xl flex-col gap-8 px-4 py-6\">\n            <div className=\"space-y-2\">\n                <Badge\n                    variant=\"outline\"\n                    className=\"bg-primary\/5 px-3 py-1 font-mono text-xs tracking-widest text-primary uppercase\"\n                >\n                    Component Showcase\n                <\/Badge>\n                <h2 className=\"text-2xl font-bold tracking-tight\">\n                    Interactive Buttons Gallery\n                <\/h2>\n                <p className=\"text-xs text-muted-foreground\">\n                    Explore and compare different interactive button styles,\n                    micro-animations, and glow effects.\n                <\/p>\n            <\/div>\n\n            <div className=\"grid w-full gap-6 sm:grid-cols-2 lg:grid-cols-3\">\n                {\/* 1. Magnetic Button *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Move className=\"size-4 text-chart-3\" \/>\n                            Magnetic Button\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Pulls towards the cursor within active range.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex h-28 items-center justify-center\">\n                        <ButtonMagnetic className=\"h-9 bg-chart-3 px-4.5 text-xs text-primary-foreground shadow-chart-3\/10 hover:bg-chart-3\/90\">\n                            Magnetic Pull\n                        <\/ButtonMagnetic>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 2. Shine \/ Shimmer Button *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Sun className=\"size-4 text-chart-4\" \/>\n                            Shine Button\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Sleek glossy swipe reflecting across surface on\n                            hover.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex h-28 items-center justify-center\">\n                        <ButtonShine\n                            className=\"h-9 bg-chart-4 px-4.5 text-xs text-primary-foreground shadow-chart-4\/10 hover:bg-chart-4\/90\"\n                            shineColor=\"rgba(255,255,255,0.4)\"\n                        >\n                            Glossy Shimmer\n                        <\/ButtonShine>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 3. Particle Exploding Button *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Sparkles className=\"size-4 text-chart-5\" \/>\n                            Particles Button\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Spawns exploding physics particles on click.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex h-28 items-center justify-center\">\n                        <ButtonParticles className=\"h-9 bg-chart-5 px-4.5 text-xs text-primary-foreground shadow-chart-5\/10 hover:bg-chart-5\/90\">\n                            Explode Particles!\n                        <\/ButtonParticles>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 4. Conic Glowing Border Button *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Compass className=\"size-4 text-chart-2\" \/>\n                            Glow Border Button\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Button wrapped in a rotating conic glow mask.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex h-28 items-center justify-center\">\n                        <div className=\"relative h-9 w-36 overflow-hidden rounded-lg bg-border\/40\">\n                            <GlowConic\n                                style={\n                                    {\n                                        '--conic-color': 'var(--color-chart-2)',\n                                    } as React.CSSProperties\n                                }\n                            \/>\n                            <button className=\"absolute inset-px flex cursor-pointer items-center justify-center gap-1.5 rounded-[7px] bg-background text-[11px] font-semibold text-chart-2 transition-colors select-none hover:text-foreground\">\n                                <Play className=\"size-3 fill-chart-2\/20\" \/>\n                                Run System\n                            <\/button>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 5. Magnetic Icon Button *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Move className=\"size-4 text-chart-1\" \/>\n                            Magnetic Icon Variant\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Attracts cursor with subtle rotation.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex h-28 items-center justify-center\">\n                        <ButtonMagnetic className=\"flex size-10 items-center justify-center rounded-full bg-chart-1 p-0 text-primary-foreground shadow-chart-1\/10 hover:bg-chart-1\/90\">\n                            <Compass className=\"size-4\" \/>\n                        <\/ButtonMagnetic>\n                    <\/CardContent>\n                <\/Card>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default ButtonsGallery;\n"}],"meta":{"category":"galleries","version":"1.0.0"},"categories":["galleries"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"call-to-action-box","type":"registry:block","title":"Call To Action Box","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["card","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/call-to-action-box\/call-to-action-box.tsx","type":"registry:block","content":"'use client';\n\nimport React from 'react';\nimport { Sparkles } from 'lucide-react';\nimport { Card, CardContent } from '@\/components\/ui\/card';\nimport { Button } from '@\/components\/ui\/button';\n\nexport function CallToActionBox() {\n    return (\n        <Card className=\"relative w-full overflow-hidden border-border\/50 bg-linear-to-br from-primary\/10 via-card\/30 to-muted\/20 p-8 text-center backdrop-blur-xs\">\n            <div className=\"absolute top-0 right-0 h-32 w-32 rounded-full bg-primary\/5 blur-2xl\" \/>\n            <CardContent className=\"mx-auto max-w-lg space-y-4 p-0\">\n                <div className=\"mx-auto mb-2 flex size-8 animate-pulse items-center justify-center rounded-full bg-primary\/20 text-primary\">\n                    <Sparkles className=\"size-4\" \/>\n                <\/div>\n                <h3 className=\"text-xl font-black tracking-tight text-foreground md:text-2xl\">\n                    Ready to build styled components?\n                <\/h3>\n                <p className=\"text-xs leading-relaxed text-muted-foreground\">\n                    Install registry hooks and items instantly in your project.\n                    No manual files copy-pasting required.\n                <\/p>\n                <div className=\"flex flex-wrap justify-center gap-2.5 pt-2\">\n                    <Button size=\"sm\" className=\"h-9 px-4 text-xs font-bold\">\n                        Get Started\n                    <\/Button>\n                    <Button\n                        size=\"sm\"\n                        variant=\"outline\"\n                        className=\"h-9 border-border\/60 px-4 text-xs font-bold\"\n                    >\n                        View Documentation\n                    <\/Button>\n                <\/div>\n            <\/CardContent>\n        <\/Card>\n    );\n}\n\nexport default CallToActionBox;\n"}],"meta":{"category":"call-to-action-box","version":"1.0.0"},"categories":["call-to-action-box"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"canvas-gallery","type":"registry:block","title":"Canvas Gallery","description":"A beautiful presentation displaying interactive HTML Canvas art and experiments.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/pixel-canvas.json","https:\/\/ui.test\/r\/waves-three.json","card","badge","slider","switch","label"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/canvas-gallery\/canvas-gallery.tsx","type":"registry:block","content":"import React, { useState } from 'react';\nimport { Play, Pause, Layers, Sliders, Monitor } from 'lucide-react';\nimport { PixelCanvas } from '@\/registry\/new-york\/components\/ui\/canvas\/pixel-canvas';\nimport WavesThree from '@\/registry\/new-york\/components\/ui\/threejs\/waves-three';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Slider } from '@\/components\/ui\/slider';\nimport { Switch } from '@\/components\/ui\/switch';\nimport { Label } from '@\/components\/ui\/label';\n\nexport function CanvasGallery() {\n    const [opacity, setOpacity] = useState([50]);\n    const [playWaves, setPlayWaves] = useState(true);\n    const [interactivePixel, setInteractivePixel] = useState(true);\n\n    return (\n        <div className=\"mx-auto flex w-full max-w-5xl flex-col gap-8 px-4 py-6\">\n            <div className=\"space-y-2\">\n                <Badge\n                    variant=\"outline\"\n                    className=\"bg-primary\/5 px-3 py-1 font-mono text-xs tracking-widest text-primary uppercase\"\n                >\n                    Component Showcase\n                <\/Badge>\n                <h2 className=\"text-2xl font-bold tracking-tight\">\n                    Interactive Canvas Gallery\n                <\/h2>\n                <p className=\"text-xs text-muted-foreground\">\n                    Compare interactive canvas backgrounds and WebGL visuals\n                    with live configuration toggles.\n                <\/p>\n            <\/div>\n\n            {\/* Split layout *\/}\n            <div className=\"grid w-full items-stretch gap-6 md:grid-cols-2\">\n                {\/* 1. WebGL Waves (Three.js) *\/}\n                <Card className=\"relative flex min-h-[380px] flex-col justify-between overflow-hidden border border-border\/40 bg-card text-card-foreground\">\n                    {\/* Live Waves background *\/}\n                    {playWaves && (\n                        <div\n                            className=\"absolute inset-0 transition-opacity duration-300\"\n                            style={{ opacity: opacity[0] \/ 100 }}\n                        >\n                            <WavesThree \/>\n                        <\/div>\n                    )}\n\n                    {\/* Glass Control Box *\/}\n                    <div className=\"relative z-10 flex h-full flex-col justify-between bg-card\/60 p-6 backdrop-blur-xs\">\n                        <div>\n                            <div className=\"flex items-center justify-between\">\n                                <Badge\n                                    variant=\"secondary\"\n                                    className=\"rounded-full border border-chart-2\/20 bg-chart-2\/10 px-2 py-0.5 text-[10px] font-bold text-chart-2\"\n                                >\n                                    WebGL \/ ThreeJS\n                                <\/Badge>\n                                <div\n                                    className=\"cursor-pointer text-muted-foreground transition-colors hover:text-card-foreground\"\n                                    onClick={() => setPlayWaves(!playWaves)}\n                                >\n                                    {playWaves ? (\n                                        <Pause className=\"size-4\" \/>\n                                    ) : (\n                                        <Play className=\"size-4\" \/>\n                                    )}\n                                <\/div>\n                            <\/div>\n                            <h3 className=\"mt-4 font-bebas-neue! text-lg font-bold tracking-wide\">\n                                WebGL Waves Background\n                            <\/h3>\n                            <p className=\"mt-1 text-[11px] leading-relaxed text-muted-foreground\">\n                                A high-performance mathematical point grid\n                                oscillating in three-dimensional space. Great\n                                for homepage banners and premium section\n                                layouts.\n                            <\/p>\n                        <\/div>\n\n                        {\/* Control Panel *\/}\n                        <div className=\"space-y-4 border-t border-border\/50 pt-6\">\n                            <div className=\"space-y-1.5\">\n                                <div className=\"flex items-center justify-between font-mono text-[10px] text-muted-foreground\">\n                                    <span>Wave Opacity<\/span>\n                                    <span>{opacity[0]}%<\/span>\n                                <\/div>\n                                <Slider\n                                    value={opacity}\n                                    onValueChange={setOpacity}\n                                    max={100}\n                                    step={5}\n                                    className=\"w-full\"\n                                \/>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                <\/Card>\n\n                {\/* 2. Interactive Pixel Canvas *\/}\n                <Card className=\"relative flex min-h-[380px] flex-col justify-between overflow-hidden border border-border\/40 bg-card text-card-foreground\">\n                    {\/* Live Pixel canvas *\/}\n                    <PixelCanvas\n                        className={`absolute inset-0 transition-opacity duration-300 ${interactivePixel ? 'opacity-40' : 'pointer-events-none opacity-0'}`}\n                    \/>\n\n                    {\/* Glass Control Box *\/}\n                    <div className=\"relative z-10 flex h-full flex-col justify-between bg-card\/60 p-6 backdrop-blur-xs\">\n                        <div>\n                            <div className=\"flex items-center justify-between\">\n                                <Badge\n                                    variant=\"secondary\"\n                                    className=\"rounded-full border border-chart-3\/20 bg-chart-3\/10 px-2 py-0.5 text-[10px] font-bold text-chart-3\"\n                                >\n                                    HTML5 Canvas\n                                <\/Badge>\n                                <Switch\n                                    id=\"pixel-state\"\n                                    checked={interactivePixel}\n                                    onCheckedChange={setInteractivePixel}\n                                    className=\"data-[state=checked]:bg-primary\"\n                                \/>\n                            <\/div>\n                            <h3 className=\"mt-4 font-bebas-neue! text-lg font-bold tracking-wide\">\n                                Interactive Pixel Grid\n                            <\/h3>\n                            <p className=\"mt-1 text-[11px] leading-relaxed text-muted-foreground\">\n                                An HTML5 canvas grid where individual pixels\n                                light up, float, and react dynamically to mouse\n                                coordinates. Move your mouse across this card to\n                                interact.\n                            <\/p>\n                        <\/div>\n\n                        {\/* Status readout *\/}\n                        <div className=\"flex items-center justify-between rounded border border-border bg-muted\/50 p-3 font-mono text-[10px] text-muted-foreground\">\n                            <span className=\"flex items-center gap-1.5\">\n                                <span\n                                    className={`size-1.5 rounded-full ${interactivePixel ? 'animate-pulse bg-primary' : 'bg-muted'}`}\n                                \/>\n                                Status:{' '}\n                                {interactivePixel\n                                    ? 'Active (Cursor tracking)'\n                                    : 'Disabled'}\n                            <\/span>\n                            <span>Grid: 16px<\/span>\n                        <\/div>\n                    <\/div>\n                <\/Card>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default CanvasGallery;\n"}],"meta":{"category":"galleries","version":"1.0.0"},"categories":["galleries"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"cards-stats","type":"registry:block","title":"Cards Stats","description":"A collection of metric statistics cards with trends, indicator badges, and compact styling.","author":"designbycode","dependencies":["lucide-react","recharts"],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/cards-stats\/cards-stats.tsx","type":"registry:block","content":"import React from 'react';\nimport { Activity, CreditCard, DollarSign, Users } from 'lucide-react';\nimport { StatCard } from '.\/stat-card';\n\n\/\/ Mock chart data for sparklines\nconst revenueData = [\n    { value: 4000 },\n    { value: 4500 },\n    { value: 5100 },\n    { value: 4900 },\n    { value: 5300 },\n    { value: 5800 },\n    { value: 6200 },\n];\n\nconst subscriptionsData = [\n    { value: 120 },\n    { value: 140 },\n    { value: 135 },\n    { value: 160 },\n    { value: 180 },\n    { value: 175 },\n    { value: 210 },\n];\n\nconst salesData = [\n    { value: 300 },\n    { value: 320 },\n    { value: 290 },\n    { value: 350 },\n    { value: 410 },\n    { value: 380 },\n    { value: 450 },\n];\n\nconst activeUsersData = [\n    { value: 450 },\n    { value: 480 },\n    { value: 510 },\n    { value: 490 },\n    { value: 530 },\n    { value: 560 },\n    { value: 573 },\n];\n\nexport function CardsStats() {\n    return (\n        <div className=\"grid w-full gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n            <StatCard\n                title=\"Total Revenue\"\n                value=\"$45,231.89\"\n                description=\"+$8,231.89 from last month\"\n                trend={{ type: 'up', value: '20.1%' }}\n                icon={<DollarSign className=\"size-4\" \/>}\n                chartType=\"area\"\n                chartData={revenueData}\n                chartColor=\"var(--color-chart-2)\"\n            \/>\n            <StatCard\n                title=\"Subscriptions\"\n                value=\"+2,350\"\n                description=\"+180.1% from last month\"\n                trend={{ type: 'up', value: '180.1%' }}\n                icon={<CreditCard className=\"size-4\" \/>}\n                chartType=\"bar\"\n                chartData={subscriptionsData}\n                chartColor=\"var(--color-chart-3)\"\n            \/>\n            <StatCard\n                title=\"Sales\"\n                value=\"+12,234\"\n                description=\"+19% from last month\"\n                trend={{ type: 'up', value: '19%' }}\n                icon={<DollarSign className=\"size-4\" \/>}\n                chartType=\"area\"\n                chartData={salesData}\n                chartColor=\"var(--color-chart-1)\"\n            \/>\n            <StatCard\n                title=\"Active Now\"\n                value=\"+573\"\n                description=\"+201 since last hour\"\n                trend={{ type: 'up', value: '12%' }}\n                icon={<Activity className=\"size-4\" \/>}\n                chartType=\"bar\"\n                chartData={activeUsersData}\n                chartColor=\"var(--color-chart-4)\"\n            \/>\n        <\/div>\n    );\n}\nexport default CardsStats;\n"},{"path":"resources\/js\/registry\/new-york\/components\/blocks\/cards-stats\/stat-card.tsx","type":"registry:block","content":"import React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { ResponsiveContainer, AreaChart, Area, BarChart, Bar } from 'recharts';\nimport { ArrowUpRight, ArrowDownRight } from 'lucide-react';\nimport { Card, CardContent, CardHeader, CardTitle } from '@\/components\/ui\/card';\n\nexport interface StatCardProps extends React.HTMLAttributes<HTMLDivElement> {\n    title: string;\n    value: string;\n    description: string;\n    trend?: {\n        type: 'up' | 'down';\n        value: string;\n    };\n    icon?: React.ReactNode;\n    chartType?: 'area' | 'bar' | 'none';\n    chartData?: { value: number }[];\n    chartColor?: string;\n}\n\nexport function StatCard({\n    title,\n    value,\n    description,\n    trend,\n    icon,\n    chartType = 'none',\n    chartData = [],\n    chartColor = 'var(--color-primary, #6366f1)',\n    className,\n    ...props\n}: StatCardProps) {\n    const isUp = trend?.type === 'up';\n    const gradientId = React.useId().replace(\/:\/g, '');\n\n    return (\n        <Card\n            className={cn(\n                'group relative overflow-hidden bg-card\/30 backdrop-blur-sm transition-all duration-300 hover:border-primary\/20 hover:bg-muted\/40 hover:shadow-md',\n                className,\n            )}\n            {...props}\n        >\n            {\/* Hover Glow effect *\/}\n            <div className=\"pointer-events-none absolute inset-0 bg-radial from-primary\/5 via-transparent to-transparent opacity-0 transition-opacity duration-500 group-hover:opacity-100\" \/>\n\n            <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n                <CardTitle className=\"text-xs font-semibold tracking-tight text-muted-foreground uppercase\">\n                    {title}\n                <\/CardTitle>\n                <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\/40 text-muted-foreground transition-colors group-hover:text-primary\">\n                    {icon}\n                <\/div>\n            <\/CardHeader>\n            <CardContent>\n                <div className=\"flex flex-col gap-1.5\">\n                    <div className=\"flex items-baseline gap-2\">\n                        <span className=\"text-2xl font-bold tracking-tight\">\n                            {value}\n                        <\/span>\n                        {trend && (\n                            <span\n                                className={cn(\n                                    'inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-semibold',\n                                    isUp\n                                        ? 'bg-chart-2\/10 text-chart-2'\n                                        : 'bg-destructive\/10 text-destructive',\n                                )}\n                            >\n                                {isUp ? (\n                                    <ArrowUpRight className=\"size-3\" \/>\n                                ) : (\n                                    <ArrowDownRight className=\"size-3\" \/>\n                                )}\n                                {trend.value}\n                            <\/span>\n                        )}\n                    <\/div>\n                    <p className=\"text-xs text-muted-foreground\">\n                        {description}\n                    <\/p>\n                <\/div>\n\n                {chartType !== 'none' && chartData.length > 0 && (\n                    <div className=\"-mx-2 mt-4 h-12 opacity-80 transition-opacity duration-300 group-hover:opacity-100\">\n                        <ResponsiveContainer width=\"100%\" height=\"100%\">\n                            {chartType === 'area' ? (\n                                <AreaChart\n                                    data={chartData}\n                                    margin={{\n                                        top: 0,\n                                        right: 0,\n                                        left: 0,\n                                        bottom: 0,\n                                    }}\n                                >\n                                    <defs>\n                                        <linearGradient\n                                            id={gradientId}\n                                            x1=\"0\"\n                                            y1=\"0\"\n                                            x2=\"0\"\n                                            y2=\"1\"\n                                        >\n                                            <stop\n                                                offset=\"0%\"\n                                                stopColor={chartColor}\n                                                stopOpacity={0.4}\n                                            \/>\n                                            <stop\n                                                offset=\"100%\"\n                                                stopColor={chartColor}\n                                                stopOpacity={0.0}\n                                            \/>\n                                        <\/linearGradient>\n                                    <\/defs>\n                                    <Area\n                                        type=\"monotone\"\n                                        dataKey=\"value\"\n                                        stroke={chartColor}\n                                        strokeWidth={1.5}\n                                        fill={`url(#${gradientId})`}\n                                        dot={false}\n                                    \/>\n                                <\/AreaChart>\n                            ) : (\n                                <BarChart\n                                    data={chartData}\n                                    margin={{\n                                        top: 0,\n                                        right: 0,\n                                        left: 0,\n                                        bottom: 0,\n                                    }}\n                                >\n                                    <Bar\n                                        dataKey=\"value\"\n                                        fill={chartColor}\n                                        radius={[2, 2, 0, 0]}\n                                    \/>\n                                <\/BarChart>\n                            )}\n                        <\/ResponsiveContainer>\n                    <\/div>\n                )}\n            <\/CardContent>\n        <\/Card>\n    );\n}\n"}],"meta":{"category":"stats","version":"1.0.0"},"categories":["stats"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"contact-form","type":"registry:block","title":"Contact Form","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["card","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/contact-form\/contact-form.tsx","type":"registry:block","content":"'use client';\n\nimport React, { useState } from 'react';\nimport { Send, CheckCircle2 } from 'lucide-react';\nimport {\n    Card,\n    CardHeader,\n    CardTitle,\n    CardDescription,\n    CardContent,\n} from '@\/components\/ui\/card';\nimport { Button } from '@\/components\/ui\/button';\n\nexport function ContactForm() {\n    const [submitted, setSubmitted] = useState(false);\n\n    const handleSend = (e: React.FormEvent) => {\n        e.preventDefault();\n        setSubmitted(true);\n    };\n\n    return (\n        <Card className=\"mx-auto w-full max-w-md border-border\/50 bg-card\/30 backdrop-blur-xs\">\n            <CardHeader className=\"pb-3\">\n                <CardTitle className=\"text-base font-bold\">\n                    Send a Message\n                <\/CardTitle>\n                <CardDescription className=\"text-xs\">\n                    We will get back to you within 24 hours.\n                <\/CardDescription>\n            <\/CardHeader>\n            <CardContent className=\"pt-0\">\n                {submitted ? (\n                    <div className=\"space-y-2 rounded-lg border border-chart-2\/20 bg-chart-2\/10 p-6 text-center\">\n                        <CheckCircle2 className=\"mx-auto size-6 text-chart-2\" \/>\n                        <h4 className=\"text-xs font-bold text-foreground\">\n                            Message Sent!\n                        <\/h4>\n                        <p className=\"text-[10px] text-muted-foreground\">\n                            Thank you. Your message has been received.\n                        <\/p>\n                    <\/div>\n                ) : (\n                    <form onSubmit={handleSend} className=\"space-y-3.5\">\n                        <div className=\"grid grid-cols-2 gap-3\">\n                            <div className=\"space-y-1\">\n                                <label className=\"text-[9px] font-bold text-muted-foreground uppercase\">\n                                    Name\n                                <\/label>\n                                <input\n                                    type=\"text\"\n                                    required\n                                    className=\"h-8 w-full rounded-[var(--radius)] border border-border\/60 bg-muted\/40 px-2 text-xs text-foreground\"\n                                \/>\n                            <\/div>\n                            <div className=\"space-y-1\">\n                                <label className=\"text-[9px] font-bold text-muted-foreground uppercase\">\n                                    Email\n                                <\/label>\n                                <input\n                                    type=\"email\"\n                                    required\n                                    className=\"h-8 w-full rounded-[var(--radius)] border border-border\/60 bg-muted\/40 px-2 text-xs text-foreground\"\n                                \/>\n                            <\/div>\n                        <\/div>\n                        <div className=\"space-y-1\">\n                            <label className=\"text-[9px] font-bold text-muted-foreground uppercase\">\n                                Message\n                            <\/label>\n                            <textarea\n                                rows={3}\n                                required\n                                className=\"w-full rounded-[var(--radius)] border border-border\/60 bg-muted\/40 p-2 text-xs text-foreground\"\n                            \/>\n                        <\/div>\n                        <Button\n                            type=\"submit\"\n                            size=\"sm\"\n                            className=\"h-8 w-full gap-1.5 text-xs font-bold\"\n                        >\n                            <Send className=\"size-3\" \/>\n                            Send Message\n                        <\/Button>\n                    <\/form>\n                )}\n            <\/CardContent>\n        <\/Card>\n    );\n}\n\nexport default ContactForm;\n"}],"meta":{"category":"contact-form","version":"1.0.0"},"categories":["contact-form"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"cookie-banner","type":"registry:block","title":"Cookie Banner","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["card","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/cookie-banner\/cookie-banner.tsx","type":"registry:block","content":"'use client';\n\nimport React, { useState } from 'react';\nimport { ShieldAlert } from 'lucide-react';\nimport { Card, CardContent } from '@\/components\/ui\/card';\nimport { Button } from '@\/components\/ui\/button';\n\nexport function CookieBanner() {\n    const [visible, setVisible] = useState(true);\n\n    if (!visible) return null;\n\n    return (\n        <Card className=\"w-full rounded-[var(--radius)] border-border\/50 bg-card\/40 p-4 shadow-lg backdrop-blur-xs\">\n            <CardContent className=\"flex flex-col items-center justify-between gap-4 p-0 sm:flex-row\">\n                <div className=\"flex items-start gap-3\">\n                    <div className=\"mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full bg-primary\/10 text-primary\">\n                        <ShieldAlert className=\"size-4.5\" \/>\n                    <\/div>\n                    <div className=\"min-w-0\">\n                        <h4 className=\"text-xs font-bold text-foreground\">\n                            We value your privacy\n                        <\/h4>\n                        <p className=\"mt-0.5 max-w-xl text-[10px] leading-normal text-muted-foreground\">\n                            We use cookies to analyze user traffic, personalize\n                            experience, and optimize performance. By clicking\n                            \"Accept All\", you consent to our use of cookies.\n                        <\/p>\n                    <\/div>\n                <\/div>\n                <div className=\"flex shrink-0 gap-2\">\n                    <Button\n                        size=\"sm\"\n                        onClick={() => setVisible(false)}\n                        className=\"h-8 px-3 text-[10px] font-bold\"\n                    >\n                        Accept All\n                    <\/Button>\n                    <Button\n                        size=\"sm\"\n                        variant=\"outline\"\n                        onClick={() => setVisible(false)}\n                        className=\"h-8 border-border\/60 px-3 text-[10px] font-bold\"\n                    >\n                        Decline\n                    <\/Button>\n                <\/div>\n            <\/CardContent>\n        <\/Card>\n    );\n}\n\nexport default CookieBanner;\n"}],"meta":{"category":"cookie-banner","version":"1.0.0"},"categories":["cookie-banner"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"faq-section","type":"registry:block","title":"Faq Section","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/faq-section\/faq-section.tsx","type":"registry:block","content":"'use client';\n\nimport React, { useState } from 'react';\nimport { ChevronDown, HelpCircle } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Card, CardHeader, CardTitle, CardContent } from '@\/components\/ui\/card';\n\ninterface FAQItem {\n    question: string;\n    answer: string;\n}\n\nconst faqs: FAQItem[] = [\n    {\n        question: 'How do I install registry themes in my application?',\n        answer: 'You can install themes directly using the shadcn CLI commands shown on the theme details page. Choose your package manager (npm, pnpm, yarn, bun) and copy-paste the installer route command into your terminal.',\n    },\n    {\n        question: 'Can I customize the colors and fonts after installing?',\n        answer: 'Yes! Themes generate standard Tailwind CSS variables inside your global CSS file. You can adjust the HSL codes or change the font-family properties manually at any time to match your brand requirements.',\n    },\n    {\n        question: 'Are there any external dependencies required?',\n        answer: 'Most components and blocks are built natively using standard Radix UI primitives and Tailwind CSS. If a block requires a library (like recharts for graphs), it will be automatically handled or declared in the dependency manifest.',\n    },\n];\n\nexport function FAQSection() {\n    const [openIdx, setOpenIdx] = useState<number | null>(null);\n\n    const toggle = (idx: number) => {\n        setOpenIdx(openIdx === idx ? null : idx);\n    };\n\n    return (\n        <div className=\"mx-auto w-full max-w-3xl space-y-4\">\n            {faqs.map((faq, idx) => {\n                const isOpen = openIdx === idx;\n                return (\n                    <Card\n                        key={idx}\n                        className={cn(\n                            'overflow-hidden border-border\/50 bg-card\/30 backdrop-blur-xs transition-all duration-300',\n                            isOpen && 'border-primary\/20 bg-muted\/10',\n                        )}\n                    >\n                        <button\n                            onClick={() => toggle(idx)}\n                            className=\"flex w-full cursor-pointer items-center justify-between p-4 text-left text-xs font-bold transition-colors select-none hover:text-primary\"\n                        >\n                            <span className=\"flex items-center gap-2\">\n                                <HelpCircle\n                                    className={cn(\n                                        'size-4 shrink-0 transition-colors',\n                                        isOpen\n                                            ? 'text-primary'\n                                            : 'text-muted-foreground',\n                                    )}\n                                \/>\n                                {faq.question}\n                            <\/span>\n                            <ChevronDown\n                                className={cn(\n                                    'size-4 shrink-0 text-muted-foreground transition-transform duration-350',\n                                    isOpen && 'rotate-180 text-primary',\n                                )}\n                            \/>\n                        <\/button>\n                        <div\n                            className={cn(\n                                'grid transition-all duration-350 ease-in-out',\n                                isOpen\n                                    ? 'grid-rows-[1fr] opacity-100'\n                                    : 'grid-rows-[0fr] opacity-0',\n                            )}\n                        >\n                            <div className=\"overflow-hidden\">\n                                <CardContent className=\"p-4 pt-0 text-xs leading-relaxed text-muted-foreground\">\n                                    {faq.answer}\n                                <\/CardContent>\n                            <\/div>\n                        <\/div>\n                    <\/Card>\n                );\n            })}\n        <\/div>\n    );\n}\n\nexport default FAQSection;\n"}],"meta":{"category":"faq-section","version":"1.0.0"},"categories":["faq-section"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"feature-grid","type":"registry:block","title":"Feature Grid","description":"A clean grid layout to present core features of a product with icons and card hover states.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["badge","card","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/feature-grid\/feature-grid.tsx","type":"registry:block","content":"import React from 'react';\nimport {\n    Zap,\n    Shield,\n    Sparkles,\n    RefreshCw,\n    BarChart2,\n    Layers,\n} from 'lucide-react';\nimport { Badge } from '@\/components\/ui\/badge';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\nimport { cn } from '@\/lib\/utils';\n\nexport interface FeatureItem {\n    title: string;\n    description: string;\n    icon: React.ReactNode;\n    badge?: string;\n    color: string;\n}\n\nconst features: FeatureItem[] = [\n    {\n        title: 'Lightning Performance',\n        description:\n            'Sub-millisecond query execution speeds via edge-cached memory nodes scattered globally.',\n        icon: <Zap className=\"size-5\" \/>,\n        badge: 'New',\n        color: 'from-chart-4 to-chart-5',\n    },\n    {\n        title: 'Bank-Grade Cryptography',\n        description:\n            'Complete end-to-end data encryption in transit and at rest with isolated keys managed by KMS.',\n        icon: <Shield className=\"size-5\" \/>,\n        color: 'from-chart-3 to-chart-1',\n    },\n    {\n        title: 'Predictive Insights',\n        description:\n            'Leverage embedded local modeling agents that automatically predict anomalies before they impact you.',\n        icon: <Sparkles className=\"size-5\" \/>,\n        badge: 'AI Powered',\n        color: 'from-chart-1 to-chart-5',\n    },\n    {\n        title: 'Real-time Synchrony',\n        description:\n            'Bidirectional sync mechanism ensuring your state is consistently distributed across devices instantly.',\n        icon: <RefreshCw className=\"size-5\" \/>,\n        color: 'from-chart-2 to-chart-3',\n    },\n    {\n        title: 'Deep Telemetry',\n        description:\n            'Granular log indexing and monitoring charts revealing queries, load distribution, and memory profiles.',\n        icon: <BarChart2 className=\"size-5\" \/>,\n        color: 'from-chart-5 to-destructive',\n    },\n    {\n        title: 'Infinite Scalability',\n        description:\n            'Modular microservice layer that expands dynamically when request throughput crosses user thresholds.',\n        icon: <Layers className=\"size-5\" \/>,\n        badge: 'Core',\n        color: 'from-chart-3 to-primary',\n    },\n];\n\nexport function FeatureGrid() {\n    return (\n        <div className=\"mx-auto flex w-full max-w-5xl flex-col gap-10 px-4 py-8\">\n            {\/* Header *\/}\n            <div className=\"flex flex-col justify-between gap-6 border-b border-border\/20 pb-8 md:flex-row md:items-end\">\n                <div className=\"max-w-lg space-y-3\">\n                    <Badge\n                        variant=\"outline\"\n                        className=\"bg-primary\/5 px-3 py-1 font-mono text-xs tracking-widest text-primary uppercase\"\n                    >\n                        Platform Features\n                    <\/Badge>\n                    <h2 className=\"text-3xl font-extrabold tracking-tight sm:text-4xl\">\n                        Engineered for Infinite Scale\n                    <\/h2>\n                    <p className=\"text-sm leading-relaxed text-muted-foreground\">\n                        A robust, developer-first suite of tools built on\n                        cutting-edge systems, giving you the building blocks to\n                        scale to millions of users.\n                    <\/p>\n                <\/div>\n            <\/div>\n\n            {\/* Grid *\/}\n            <div className=\"grid w-full gap-6 sm:grid-cols-2 lg:grid-cols-3\">\n                {features.map((feature, idx) => (\n                    <Card\n                        key={idx}\n                        className=\"group relative flex flex-col justify-between overflow-hidden border-border\/40 bg-card\/25 backdrop-blur-xs transition-all duration-300 hover:border-primary\/20 hover:shadow-lg\"\n                    >\n                        {\/* Dynamic backdrop linear glow matching the category theme *\/}\n                        <div className=\"pointer-events-none absolute inset-0 bg-linear-to-tr from-primary\/3 via-transparent to-transparent opacity-0 transition-opacity duration-500 group-hover:opacity-100\" \/>\n\n                        <CardHeader className=\"space-y-4\">\n                            <div className=\"flex items-center justify-between\">\n                                <div\n                                    className={cn(\n                                        'flex size-10 items-center justify-center rounded-xl bg-linear-to-tr text-white shadow-md',\n                                        feature.color,\n                                    )}\n                                >\n                                    {feature.icon}\n                                <\/div>\n                                {feature.badge && (\n                                    <Badge\n                                        variant=\"secondary\"\n                                        className=\"rounded-full border border-primary\/10 px-2 py-0.5 text-[10px] font-bold\"\n                                    >\n                                        {feature.badge}\n                                    <\/Badge>\n                                )}\n                            <\/div>\n                            <CardTitle className=\"text-base font-bold transition-colors group-hover:text-primary\">\n                                {feature.title}\n                            <\/CardTitle>\n                        <\/CardHeader>\n\n                        <CardContent className=\"pb-6\">\n                            <CardDescription className=\"text-xs leading-relaxed text-muted-foreground transition-colors group-hover:text-muted-foreground\/90\">\n                                {feature.description}\n                            <\/CardDescription>\n                        <\/CardContent>\n                    <\/Card>\n                ))}\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default FeatureGrid;\n"}],"meta":{"category":"feature-grid","version":"1.0.0"},"categories":["feature-grid"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"feature-list","type":"registry:block","title":"Feature List","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/feature-list\/feature-list.tsx","type":"registry:block","content":"'use client';\n\nimport React from 'react';\nimport { Check } from 'lucide-react';\nimport { Card, CardHeader, CardTitle, CardContent } from '@\/components\/ui\/card';\n\ninterface FeatureDoc {\n    title: string;\n    details: string;\n}\n\nconst listItems: FeatureDoc[] = [\n    {\n        title: 'Dynamic CSS Variables Mapping',\n        details: 'Inject HSL variable values directly to the DOM tree root.',\n    },\n    {\n        title: 'Tailwind CSS V4 Containers Support',\n        details: 'Apply container queries to size children items responsively.',\n    },\n    {\n        title: 'Interactive WebGL Canvas Shaders',\n        details: 'Render analog post-processed glitch visual assets.',\n    },\n];\n\nexport function FeatureList() {\n    return (\n        <Card className=\"mx-auto w-full max-w-xl border-border\/50 bg-card\/30 backdrop-blur-xs\">\n            <CardHeader className=\"pb-3\">\n                <CardTitle className=\"text-base font-bold\">\n                    Capabilities Checklist\n                <\/CardTitle>\n            <\/CardHeader>\n            <CardContent className=\"space-y-3.5\">\n                {listItems.map((item, idx) => (\n                    <div key={idx} className=\"flex items-start gap-3\">\n                        <div className=\"mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full bg-primary\/10 text-primary\">\n                            <Check className=\"size-3.5\" \/>\n                        <\/div>\n                        <div className=\"min-w-0\">\n                            <h4 className=\"text-xs font-bold text-foreground\">\n                                {item.title}\n                            <\/h4>\n                            <p className=\"mt-0.5 text-[10px] leading-relaxed text-muted-foreground\">\n                                {item.details}\n                            <\/p>\n                        <\/div>\n                    <\/div>\n                ))}\n            <\/CardContent>\n        <\/Card>\n    );\n}\n\nexport default FeatureList;\n"}],"meta":{"category":"feature-list","version":"1.0.0"},"categories":["feature-list"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-conic-glow","type":"registry:block","title":"Hero Conic Glow","description":"A dark theme hero section displaying a centerpiece panel framed by a rotating conic border gradient.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-pulse.json","https:\/\/ui.test\/r\/button-gradient.json","https:\/\/ui.test\/r\/glow-conic.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-conic-glow\/hero-conic-glow.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Layers, ArrowRight } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonPulse } from '@\/registry\/new-york\/components\/ui\/buttons\/button-pulse';\nimport { ButtonGradient } from '@\/registry\/new-york\/components\/ui\/buttons\/button-gradient';\nimport GlowConic from '@\/registry\/new-york\/components\/ui\/glow\/glow-conic';\n\nexport function HeroConicGlow() {\n    return (\n        <section className=\"relative flex w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center select-none\">\n            <div className=\"relative z-10 mb-12 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Visual Edge',\n                        icon: Layers,\n                    }}\n                    heading=\"Stand out with conic border animations\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl text-foreground\"\n                    description=\"Grab attention immediately with dynamic gradient lighting. Clean hardware-accelerated CSS animations make the border glow run perfectly smooth.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-6 flex flex-wrap items-center justify-center gap-4\">\n                    <ButtonPulse>Get Started<\/ButtonPulse>\n                    <ButtonGradient className=\"flex items-center gap-1.5\">\n                        Documentation\n                        <ArrowRight className=\"size-4\" \/>\n                    <\/ButtonGradient>\n                <\/div>\n            <\/div>\n\n            {\/* Glowing Conic Border Dashboard Frame *\/}\n            <div className=\"relative h-48 w-full max-w-2xl overflow-hidden rounded-xl border border-border\/40 bg-muted\">\n                <GlowConic\n                    style={\n                        {\n                            '--conic-color': 'var(--color-primary, #10b981)',\n                        } as React.CSSProperties\n                    }\n                \/>\n                {\/* Internal card details *\/}\n                <div className=\"absolute inset-px flex flex-col items-center justify-center rounded-[11px] bg-card p-6 text-center\">\n                    <h3 className=\"mb-2 font-mono text-xs font-bold tracking-widest text-muted-foreground uppercase\">\n                        Analytics Engine Online\n                    <\/h3>\n                    <p className=\"text-2xl font-extrabold tracking-tight text-foreground sm:text-3xl\">\n                        12,842 requests \/ min\n                    <\/p>\n                    <div className=\"mt-4 flex items-center gap-4 font-mono text-[10px] text-muted-foreground\">\n                        <span className=\"flex items-center gap-1\">\n                            <span className=\"size-1.5 animate-pulse rounded-full bg-chart-2\" \/>\n                            API Status: 99.98%\n                        <\/span>\n                        <span>\u2022<\/span>\n                        <span>Ping: 12ms<\/span>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroConicGlow;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-features-grid","type":"registry:block","title":"Hero Features Grid","description":"A centered hero banner paired with a three-column micro-grid of cards displaying key app features.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-gradient.json","https:\/\/ui.test\/r\/button-draw.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-features-grid\/hero-features-grid.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Layers, Activity, Terminal, Shield, ArrowRight } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonGradient } from '@\/registry\/new-york\/components\/ui\/buttons\/button-gradient';\nimport { ButtonDraw } from '@\/registry\/new-york\/components\/ui\/buttons\/button-draw';\n\nexport function HeroFeaturesGrid() {\n    const features = [\n        {\n            icon: Terminal,\n            title: 'CLI Scaffolding',\n            description:\n                'Generate production-ready controllers, model seeders, and React components with one Artisan command.',\n        },\n        {\n            icon: Shield,\n            title: 'Fortified Security',\n            description:\n                'First-party support for two-factor authentication, email confirmation, and session security policies.',\n        },\n        {\n            icon: Activity,\n            title: 'Performance Track',\n            description:\n                'Under-the-hood optimization for lightning-fast loads, prefetching, and state synchronization.',\n        },\n    ];\n\n    return (\n        <section className=\"relative isolate flex w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center select-none\">\n            <div className=\"from absolute inset-0 z-0 bg-radial-[125%_125%_at_50%_90%] from-transparent from-40% to-primary to-100%\" \/>\n\n            <div className=\"relative z-10 mb-12 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Integrated Ecosystem',\n                        icon: Layers,\n                    }}\n                    heading=\"Engineered for high performance applications\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl\"\n                    description=\"A complete toolkit designed by developers, for developers. Clean architectures and styling conventions that speed up feature delivery.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-6 flex flex-wrap items-center justify-center gap-4\">\n                    <ButtonGradient>Get Started<\/ButtonGradient>\n                    <ButtonDraw className=\"flex items-center gap-1.5\">\n                        Read System Docs\n                        <ArrowRight className=\"size-4\" \/>\n                    <\/ButtonDraw>\n                <\/div>\n            <\/div>\n\n            {\/* Bottom 3-Column Features Grid *\/}\n            <div className=\"relative z-10 grid w-full max-w-4xl grid-cols-1 gap-6 md:grid-cols-3\">\n                {features.map((feature, i) => {\n                    const Icon = feature.icon;\n                    return (\n                        <div\n                            key={i}\n                            className=\"group flex flex-col items-start rounded-xl border border-border\/40 bg-card\/60 p-6 text-left backdrop-blur-xs transition-all hover:border-primary\/20 hover:bg-card hover:shadow-lg\"\n                        >\n                            <div className=\"mb-4 flex size-9 items-center justify-center rounded-lg bg-primary\/5 text-primary transition-colors group-hover:bg-primary group-hover:text-primary-foreground\">\n                                <Icon className=\"size-4.5\" \/>\n                            <\/div>\n                            <h4 className=\"mb-2 text-sm font-bold text-foreground\">\n                                {feature.title}\n                            <\/h4>\n                            <p className=\"text-xs leading-relaxed text-muted-foreground\">\n                                {feature.description}\n                            <\/p>\n                        <\/div>\n                    );\n                })}\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroFeaturesGrid;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-fullscreen-image","type":"registry:block","title":"Hero Fullscreen Image","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-pulse.json","https:\/\/ui.test\/r\/button-gradient.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-fullscreen-image\/hero-fullscreen-image.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Image as ImageIcon, ArrowRight } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonPulse } from '@\/registry\/new-york\/components\/ui\/buttons\/button-pulse';\nimport { ButtonGradient } from '@\/registry\/new-york\/components\/ui\/buttons\/button-gradient';\n\nexport function HeroFullscreenImage() {\n    return (\n        <section className=\"relative flex min-h-[600px] w-full items-center justify-center overflow-hidden rounded-2xl border border-border\/30 px-6 py-20 text-center select-none md:px-12\">\n            {\/* Background Image at z-0 *\/}\n            <img\n                src=\"\/hero-bg-premium.jpg\"\n                alt=\"Premium Fullscreen Background\"\n                className=\"absolute inset-0 z-0 h-full w-full object-cover object-center transition-transform duration-700 group-hover:scale-102\"\n            \/>\n            {\/* Soft Gradient Overlay at z-10 to ensure text readability *\/}\n            <div className=\"absolute inset-0 z-10 bg-gradient-to-b from-background\/40 via-background\/70 to-background\" \/>\n\n            {\/* Typography & Actions Container at z-20 *\/}\n            <div className=\"relative z-20 flex max-w-3xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Visual Experience',\n                        icon: ImageIcon,\n                    }}\n                    heading=\"Stand out with fullscreen layouts\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl drop-shadow-sm\"\n                    description=\"Capture attention immediately with high-resolution imagery and elegant gradient overlays. Perfectly responsive, auto-scaling to match all modern desktop and mobile device displays.\"\n                    descriptionClassName=\"text-muted-foreground\/90 max-w-2xl drop-shadow-xs\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-8 flex flex-wrap items-center justify-center gap-4\">\n                    <ButtonPulse>Explore Gallery<\/ButtonPulse>\n                    <ButtonGradient className=\"flex items-center gap-1.5\">\n                        View Case Study\n                        <ArrowRight className=\"size-4\" \/>\n                    <\/ButtonGradient>\n                <\/div>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroFullscreenImage;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-fullscreen-video","type":"registry:block","title":"Hero Fullscreen Video","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-pulse.json","https:\/\/ui.test\/r\/button-draw.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-fullscreen-video\/hero-fullscreen-video.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Video as VideoIcon, ArrowRight } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonPulse } from '@\/registry\/new-york\/components\/ui\/buttons\/button-pulse';\nimport { ButtonDraw } from '@\/registry\/new-york\/components\/ui\/buttons\/button-draw';\n\nexport function HeroFullscreenVideo() {\n    return (\n        <section className=\"relative flex min-h-[600px] w-full items-center justify-center overflow-hidden rounded-2xl border border-border\/30 px-6 py-20 text-center select-none md:px-12\">\n            {\/* Fullscreen Looping Video Background *\/}\n            <video\n                autoPlay\n                loop\n                muted\n                playsInline\n                className=\"absolute inset-0 z-0 h-full w-full object-cover object-center\"\n            >\n                <source\n                    src=\"https:\/\/assets.mixkit.co\/videos\/preview\/mixkit-abstract-laser-lights-background-glow-37299-large.mp4\"\n                    type=\"video\/mp4\"\n                \/>\n            <\/video>\n            {\/* Theme-Adaptive Backdrop Mask to ensure text contrast *\/}\n            <div className=\"absolute inset-0 z-10 bg-background\/85 backdrop-blur-[2px]\" \/>\n\n            {\/* Centered Content Container *\/}\n            <div className=\"relative z-20 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Motion Experience',\n                        icon: VideoIcon,\n                    }}\n                    heading=\"Engage visitors with ambient motion\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl\"\n                    description=\"Subtle background loops add a dynamic sense of depth to your SaaS landing pages. High-contrast typography and polished micro-animations keep readability perfect without distracting your users.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-8 flex flex-wrap items-center justify-center gap-4\">\n                    <ButtonPulse>Launch Demo<\/ButtonPulse>\n                    <ButtonDraw className=\"flex items-center gap-1.5\">\n                        View Whitepaper\n                        <ArrowRight className=\"size-4\" \/>\n                    <\/ButtonDraw>\n                <\/div>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroFullscreenVideo;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-glowing-cards","type":"registry:block","title":"Hero Glowing Cards","description":"A centered hero banner utilizing three mouse-tracing GlowingCard components to show features.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-pulse.json","https:\/\/ui.test\/r\/glowing-card.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-glowing-cards\/hero-glowing-cards.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Target, Zap, Layout, Shield } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonPulse } from '@\/registry\/new-york\/components\/ui\/buttons\/button-pulse';\nimport { GlowingCard } from '@\/registry\/new-york\/components\/ui\/cards\/glowing-card';\n\nexport function HeroGlowingCards() {\n    const cards = [\n        {\n            icon: Zap,\n            title: 'Dynamic Spotlights',\n            description:\n                'Hover to trace coordinates with smooth radial gradients.',\n            color: 'color-mix(in srgb, var(--color-chart-2) 12%, transparent)', \/\/ Emerald\/teal green glow\n        },\n        {\n            icon: Layout,\n            title: 'Grid Assembly',\n            description:\n                'Compose clean grids using predefined component rules.',\n            color: 'color-mix(in srgb, var(--color-chart-3) 12%, transparent)', \/\/ Indigo blue glow\n        },\n        {\n            icon: Shield,\n            title: 'Isolated Execution',\n            description: 'Keep layouts fast, modular, and easy to scale.',\n            color: 'color-mix(in srgb, var(--color-chart-1) 12%, transparent)', \/\/ Pink glow\n        },\n    ];\n\n    return (\n        <section className=\"relative flex w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center select-none\">\n            {\/* Background mesh *\/}\n            <div className=\"absolute inset-0 bg-[radial-gradient(circle_at_50%_-10%,rgba(99,102,241,0.06),rgba(0,0,0,0))]\" \/>\n\n            <div className=\"relative z-10 mb-12 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Spotlight Technology',\n                        icon: Target,\n                    }}\n                    heading=\"Build premium glowing features\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl\"\n                    description=\"Move your cursor across the cards below. Each card dynamically tracks mouse hover coordinates to render a clean spotlight glow under the text.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-4 flex justify-center\">\n                    <ButtonPulse>Launch Sandbox<\/ButtonPulse>\n                <\/div>\n            <\/div>\n\n            {\/* Glowing Cards Grid *\/}\n            <div className=\"relative z-10 grid w-full max-w-4xl grid-cols-1 gap-6 md:grid-cols-3\">\n                {cards.map((card, i) => {\n                    const Icon = card.icon;\n                    return (\n                        <GlowingCard\n                            key={i}\n                            glowColor={card.color}\n                            className=\"items-start text-left\"\n                        >\n                            <div className=\"mb-4 flex size-9 shrink-0 items-center justify-center rounded-lg bg-foreground\/5 text-foreground\">\n                                <Icon className=\"size-4.5\" \/>\n                            <\/div>\n                            <h4 className=\"mb-2 text-sm font-bold text-foreground\">\n                                {card.title}\n                            <\/h4>\n                            <p className=\"text-xs leading-relaxed text-muted-foreground\">\n                                {card.description}\n                            <\/p>\n                        <\/GlowingCard>\n                    );\n                })}\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroGlowingCards;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-high-energy","type":"registry:block","title":"Hero High Energy","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/wrapper.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-high-energy\/hero-high-energy.tsx","type":"registry:block","content":"'use client';\n\nimport React, { useState } from 'react';\nimport { Sparkles, Zap, Sliders, Layers, ArrowRight } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport Wrapper from '@\/registry\/new-york\/components\/ui\/misc\/wrapper';\n\nconst HIGHLIGHT_IMAGES = [\n    {\n        url: 'https:\/\/images.unsplash.com\/photo-1544005313-94ddf0286df2?auto=format&fit=crop&w=800&q=80',\n        tag: 'STREET CYBERNETICS',\n        desc: 'RAW PORTRAIT OVERLAYS \/\/ CHROMATIC ABERRATION ACTIVE',\n    },\n    {\n        url: 'https:\/\/images.unsplash.com\/photo-1504051771394-dd2e66b2e08f?auto=format&fit=crop&w=800&q=80',\n        tag: 'BRUTAL ARCHITECTURE',\n        desc: 'MONOLITH STRUCTURES \/\/ SOLID SHADOW EXTRUSIONS',\n    },\n    {\n        url: 'https:\/\/images.unsplash.com\/photo-1511556532299-8f662fc26c06?auto=format&fit=crop&w=800&q=80',\n        tag: 'KINETIC NEON LINES',\n        desc: 'HIGH-FREQUENCY LASERS \/\/ FLUID CONICAL GLOW',\n    },\n];\n\nexport function HeroHighEnergyImpact() {\n    const [activeIndex, setActiveIndex] = useState(0);\n    const [rgbOffset, setRgbOffset] = useState(4);\n    const [noiseFilter, setNoiseFilter] = useState(true);\n    const [aspectStretch, setAspectStretch] = useState(false);\n\n    return (\n        <section className=\"relative w-full overflow-hidden rounded-2xl border border-border\/30 bg-background py-16 select-none lg:py-24\">\n            {\/* Dynamic Grid Background Accent *\/}\n            <div className=\"pointer-events-none absolute inset-0 z-0 bg-[linear-gradient(to_right,var(--border)_1px,transparent_1px),linear-gradient(to_bottom,var(--border)_1px,transparent_1px)] bg-[size:40px_40px] opacity-15\" \/>\n\n            {\/* Decorative Neon Header Ribbons *\/}\n            <div className=\"absolute top-0 left-0 h-[3px] w-full bg-gradient-to-r from-chart-4 via-chart-1 to-chart-3 opacity-60\" \/>\n\n            <Wrapper className=\"relative z-10\">\n                <div className=\"grid grid-cols-1 items-center gap-12 lg:grid-cols-12\">\n                    {\/* Left Block: Ultra-dense Typography and Interactive Controller *\/}\n                    <div className=\"space-y-8 text-left lg:col-span-7\">\n                        <div className=\"inline-flex items-center gap-2 rounded border border-chart-4\/30 bg-chart-4\/10 px-3 py-1 font-mono text-xs tracking-widest text-chart-4 uppercase\">\n                            <Sparkles className=\"h-3 w-3 animate-pulse\" \/>\n                            <span>\n                                HIGH IMPACT V2 \/\/ HIGH RESOLUTION SPECTRUM\n                            <\/span>\n                        <\/div>\n\n                        {\/* Massive Bebas Neue Title *\/}\n                        <div className=\"space-y-1\">\n                            <h1\n                                className=\"text-6xl leading-[0.85] font-black tracking-tighter text-foreground uppercase sm:text-8xl lg:text-9xl\"\n                                style={{\n                                    fontFamily:\n                                        \"var(--font-bebas-neue, 'Bebas Neue', sans-serif)\",\n                                }}\n                            >\n                                BREAK <br \/>\n                                <span className=\"bg-gradient-to-r from-chart-4 via-chart-1 to-chart-3 bg-clip-text text-transparent\">\n                                    THE STANDARD\n                                <\/span>{' '}\n                                <br \/>\n                                ENGINE.\n                            <\/h1>\n                        <\/div>\n\n                        <p className=\"max-w-lg font-mono text-sm leading-relaxed text-muted-foreground\">\n                            We engineer hyper-optimized digital products. No\n                            templates, no generic gradients, and absolutely no\n                            compromises. Control your screen spectrum layout\n                            directly below.\n                        <\/p>\n\n                        {\/* Live Visual Controls Panel *\/}\n                        <div className=\"space-y-4 border border-l-4 border-border\/40 border-chart-4 bg-card\/90 p-5 shadow-xl\">\n                            <div className=\"flex items-center gap-2 font-mono text-xs font-bold tracking-widest text-chart-4 uppercase\">\n                                <Sliders className=\"h-4 w-4\" \/>\n                                <span>SPECTRUM CONTROL HUB<\/span>\n                            <\/div>\n\n                            <div className=\"grid grid-cols-1 gap-4 font-mono text-xs sm:grid-cols-3\">\n                                {\/* Control 1 *\/}\n                                <div className=\"space-y-1\">\n                                    <span className=\"block text-[10px] text-muted-foreground\/75\">\n                                        RGB SKEW\n                                    <\/span>\n                                    <div className=\"flex items-center gap-2\">\n                                        <input\n                                            type=\"range\"\n                                            min=\"0\"\n                                            max=\"12\"\n                                            value={rgbOffset}\n                                            onChange={(e) =>\n                                                setRgbOffset(\n                                                    parseInt(e.target.value),\n                                                )\n                                            }\n                                            className=\"h-1 w-full cursor-pointer appearance-none rounded-lg bg-muted accent-chart-4\"\n                                        \/>\n                                        <span className=\"w-6 text-right text-[10px] font-bold text-chart-4\">\n                                            {rgbOffset}px\n                                        <\/span>\n                                    <\/div>\n                                <\/div>\n\n                                {\/* Control 2 *\/}\n                                <div className=\"space-y-1\">\n                                    <span className=\"block text-[10px] text-muted-foreground\/75\">\n                                        STATIC NOISE\n                                    <\/span>\n                                    <button\n                                        onClick={() =>\n                                            setNoiseFilter(!noiseFilter)\n                                        }\n                                        className={`w-full cursor-pointer rounded border py-1.5 text-[10px] font-bold transition-all ${\n                                            noiseFilter\n                                                ? 'border-chart-4 bg-chart-4\/10 text-chart-4'\n                                                : 'border-border bg-transparent text-muted-foreground\/60'\n                                        }`}\n                                    >\n                                        {noiseFilter ? 'ACTIVE' : 'BYPASS'}\n                                    <\/button>\n                                <\/div>\n\n                                {\/* Control 3 *\/}\n                                <div className=\"space-y-1\">\n                                    <span className=\"block text-[10px] text-muted-foreground\/75\">\n                                        STRETCH ASPECT\n                                    <\/span>\n                                    <button\n                                        onClick={() =>\n                                            setAspectStretch(!aspectStretch)\n                                        }\n                                        className={`w-full cursor-pointer rounded border py-1.5 text-[10px] font-bold transition-all ${\n                                            aspectStretch\n                                                ? 'border-chart-4 bg-chart-4\/10 text-chart-4'\n                                                : 'border-border bg-transparent text-muted-foreground\/60'\n                                        }`}\n                                    >\n                                        {aspectStretch ? 'STRETCH' : 'NORMAL'}\n                                    <\/button>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n\n                        {\/* Direct Multi-Choice Custom Interactive Slider buttons *\/}\n                        <div className=\"space-y-3 pt-2\">\n                            <span className=\"block font-mono text-[10px] font-bold tracking-widest text-muted-foreground uppercase\">\n                                [ SELECT RAW VISUAL CHANNELS ]\n                            <\/span>\n                            <div className=\"flex flex-wrap gap-2\">\n                                {HIGHLIGHT_IMAGES.map((img, i) => (\n                                    <button\n                                        key={i}\n                                        onClick={() => setActiveIndex(i)}\n                                        className={`cursor-pointer border px-4 py-2 font-mono text-xs tracking-tight uppercase transition-all ${\n                                            activeIndex === i\n                                                ? 'border-foreground bg-foreground text-background shadow-[4px_4px_0_0_var(--color-chart-4)]'\n                                                : 'border-border bg-card text-muted-foreground hover:border-border\/80 hover:text-foreground'\n                                        }`}\n                                    >\n                                        0{i + 1} \/\/ {img.tag.split(' ')[0]}\n                                    <\/button>\n                                ))}\n                            <\/div>\n                        <\/div>\n\n                        {\/* Powerful Action buttons *\/}\n                        <div className=\"flex flex-wrap gap-4 pt-4\">\n                            <button className=\"cursor-pointer bg-chart-4 px-8 py-3.5 font-mono text-sm font-black text-primary-foreground uppercase shadow-[4px_4px_0px_0px_var(--color-foreground)] transition-all duration-300 hover:translate-x-1 hover:translate-y-1 hover:shadow-none\">\n                                LAUNCH SPECTRUM ENGINE\n                            <\/button>\n                            <button className=\"cursor-pointer border-2 border-border bg-transparent px-6 py-3.5 font-mono text-sm text-foreground transition-all hover:border-border\/80 hover:bg-muted\/30\">\n                                GET THE COMPILER\n                            <\/button>\n                        <\/div>\n                    <\/div>\n\n                    {\/* Right Block: Dynamic Distorted Halftone Style Interactive Image Box *\/}\n                    <div className=\"relative lg:col-span-5\">\n                        <div className=\"group relative overflow-hidden rounded-xl border border-border\/40 bg-card p-4\">\n                            {\/* Halftone \/ scan dots overlay *\/}\n                            {noiseFilter && (\n                                <div className=\"pointer-events-none absolute inset-0 z-20 bg-[radial-gradient(var(--border)_1px,transparent_1px)] bg-[size:8px_8px] opacity-40\" \/>\n                            )}\n\n                            {\/* Distorted Image container using state controls *\/}\n                            <div className=\"relative aspect-[4\/5] overflow-hidden rounded-lg border border-border\/40 bg-background\">\n                                {\/* Simulated RGB Skew offset shadow layers *\/}\n                                <div\n                                    className=\"absolute inset-0 bg-cover bg-center opacity-60 mix-blend-screen grayscale\"\n                                    style={{\n                                        backgroundImage: `url('${HIGHLIGHT_IMAGES[activeIndex].url}')`,\n                                        transform: `translate(${-rgbOffset}px, ${rgbOffset \/ 2}px) ${\n                                            aspectStretch\n                                                ? 'scaleY(1.15)'\n                                                : 'scale(1)'\n                                        }`,\n                                        transition:\n                                            'transform 0.15s ease-out, background-image 0.3s ease',\n                                    }}\n                                \/>\n                                <div\n                                    className=\"absolute inset-0 bg-cover bg-center text-chart-3 opacity-60 mix-blend-screen\"\n                                    style={{\n                                        backgroundImage: `url('${HIGHLIGHT_IMAGES[activeIndex].url}')`,\n                                        transform: `translate(${rgbOffset}px, ${-rgbOffset \/ 2}px) ${\n                                            aspectStretch\n                                                ? 'scaleY(1.15)'\n                                                : 'scale(1)'\n                                        }`,\n                                        filter: 'hue-rotate(180deg)',\n                                        transition:\n                                            'transform 0.15s ease-out, background-image 0.3s ease',\n                                    }}\n                                \/>\n                                <div\n                                    className=\"absolute inset-0 bg-cover bg-center opacity-70\"\n                                    style={{\n                                        backgroundImage: `url('${HIGHLIGHT_IMAGES[activeIndex].url}')`,\n                                        transform: aspectStretch\n                                            ? 'scaleY(1.15)'\n                                            : 'scale(1)',\n                                        transition:\n                                            'transform 0.15s ease-out, background-image 0.3s ease',\n                                    }}\n                                \/>\n\n                                {\/* Left tags inside image box *\/}\n                                <div className=\"absolute top-3 left-3 z-30 border border-border\/40 bg-card\/90 px-2 py-1 font-mono text-[9px] tracking-widest text-chart-4 uppercase\">\n                                    {HIGHLIGHT_IMAGES[activeIndex].tag}\n                                <\/div>\n\n                                {\/* Floating Aspect indicator *\/}\n                                <div className=\"absolute right-3 bottom-3 z-30 flex items-center gap-1.5 rounded border border-border\/40 bg-card\/90 px-3 py-1.5 font-mono text-[9px] text-muted-foreground\">\n                                    <Layers className=\"h-3.5 w-3.5 text-chart-4\" \/>\n                                    <span>MATRIX v.902 \/\/ ACC ACTIVE<\/span>\n                                <\/div>\n                            <\/div>\n\n                            {\/* Image Description and Stats under the preview *\/}\n                            <div className=\"mt-4 space-y-2 border-t border-border\/40 pt-4 text-left font-mono\">\n                                <div className=\"flex items-center justify-between text-xs\">\n                                    <span className=\"text-muted-foreground\">\n                                        TAG\n                                    <\/span>\n                                    <span className=\"font-bold text-foreground uppercase\">\n                                        {HIGHLIGHT_IMAGES[activeIndex].tag}\n                                    <\/span>\n                                <\/div>\n\n                                <p className=\"rounded border border-border\/20 bg-muted\/30 p-2 text-[10px] leading-relaxed text-muted-foreground\">\n                                    {HIGHLIGHT_IMAGES[activeIndex].desc}\n                                <\/p>\n\n                                <div className=\"flex items-center justify-between text-[10px] text-muted-foreground\">\n                                    <span>RESOLVED URL<\/span>\n                                    <span className=\"max-w-[180px] truncate text-muted-foreground\/80\">\n                                        {HIGHLIGHT_IMAGES[\n                                            activeIndex\n                                        ].url.substring(0, 40)}\n                                        ...\n                                    <\/span>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/Wrapper>\n        <\/section>\n    );\n}\n\nexport default HeroHighEnergyImpact;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-minimal-centered","type":"registry:block","title":"Hero Minimal Centered","description":"A clean centered hero banner with simple typography and special draw and pulse CTA buttons.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-pulse.json","https:\/\/ui.test\/r\/button-draw.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-minimal-centered\/hero-minimal-centered.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Sparkles, ArrowRight } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonPulse } from '@\/registry\/new-york\/components\/ui\/buttons\/button-pulse';\nimport { ButtonDraw } from '@\/registry\/new-york\/components\/ui\/buttons\/button-draw';\n\nexport function HeroMinimalCentered() {\n    return (\n        <section className=\"relative flex min-h-[450px] w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center select-none\">\n            {\/* Subtle glow effect *\/}\n            <div className=\"pointer-events-none absolute top-0 left-1\/2 h-[200px] w-[400px] -translate-x-1\/2 rounded-full bg-primary\/10 blur-[80px]\" \/>\n\n            <div className=\"relative z-10 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Next Generation SaaS',\n                        icon: Sparkles,\n                    }}\n                    heading=\"Ship your project at lightspeed\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl bg-clip-text text-transparent bg-gradient-to-r from-foreground via-foreground\/90 to-muted-foreground\"\n                    description=\"The modern way to build Web apps. Clean folder structures, preconfigured layouts, responsive sidebars, and customizable theme settings.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-6 flex flex-wrap items-center justify-center gap-4\">\n                    <ButtonPulse>Start Deploying<\/ButtonPulse>\n                    <ButtonDraw className=\"flex items-center gap-1.5\">\n                        Learn More\n                        <ArrowRight className=\"size-4\" \/>\n                    <\/ButtonDraw>\n                <\/div>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroMinimalCentered;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-particles","type":"registry:block","title":"Hero Particles","description":"A high-impact centered hero set against an animated backdrop of floating ambient light particles.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-neon.json","https:\/\/ui.test\/r\/button-draw.json","https:\/\/ui.test\/r\/particles-backdrop.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-particles\/hero-particles.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Star, ArrowRight } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonNeon } from '@\/registry\/new-york\/components\/ui\/buttons\/button-neon';\nimport { ButtonDraw } from '@\/registry\/new-york\/components\/ui\/buttons\/button-draw';\nimport { ParticlesBackdrop } from '@\/registry\/new-york\/components\/ui\/animations\/particles-backdrop';\n\nexport function HeroParticles() {\n    return (\n        <section className=\"relative flex min-h-[460px] w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center select-none\">\n            {\/* Static Ambient Mesh Glow *\/}\n            <div className=\"absolute inset-0 bg-[radial-gradient(circle_at_50%_30%,color-mix(in_srgb,var(--color-chart-2)_5%,transparent),transparent)]\" \/>\n\n            {\/* Reusable Particles Backdrop *\/}\n            <ParticlesBackdrop count={15} colorClassName=\"bg-chart-2\/30\" \/>\n\n            <div className=\"relative z-10 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Developer Centric',\n                        icon: Star,\n                    }}\n                    heading=\"Engineered for rapid UI design\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl text-foreground\"\n                    description=\"Spend less time configuring webpack manifests and CSS utilities, and more time delivering visual assets that impress your clients.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-6 flex flex-wrap items-center justify-center gap-4\">\n                    <ButtonNeon className=\"flex items-center gap-2\">\n                        Get Started\n                        <ArrowRight className=\"size-4\" \/>\n                    <\/ButtonNeon>\n                    <ButtonDraw>View Storybook<\/ButtonDraw>\n                <\/div>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroParticles;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-phone-mockup","type":"registry:block","title":"Hero Phone Mockup","description":"A split hero layout showcasing app copy alongside a high-fidelity glowing smartphone dashboard mockup.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-neon.json","https:\/\/ui.test\/r\/button-draw.json","https:\/\/ui.test\/r\/phone-mockup.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-phone-mockup\/hero-phone-mockup.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Smartphone, Zap, Sparkles } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonNeon } from '@\/registry\/new-york\/components\/ui\/buttons\/button-neon';\nimport { ButtonDraw } from '@\/registry\/new-york\/components\/ui\/buttons\/button-draw';\nimport { PhoneMockup } from '@\/registry\/new-york\/components\/ui\/mockups\/phone-mockup';\n\nexport function HeroPhoneMockup() {\n    return (\n        <section className=\"relative flex w-full flex-col gap-8 overflow-hidden rounded-2xl border border-border\/30 bg-background\/50 p-8 select-none lg:flex-row lg:items-center lg:p-12\">\n            <div className=\"flex-1 space-y-6 text-left\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Mobile Experience Ready',\n                        icon: Smartphone,\n                    }}\n                    heading=\"Stunning interfaces on every screen size\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl\"\n                    description=\"Responsive layouts that scale flawlessly from extra wide displays down to mobile touchscreens. Native gestures, touch states, and hardware acceleration built in.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    size=\"sm\"\n                \/>\n\n                <div className=\"flex flex-wrap items-center gap-4 pt-2\">\n                    <ButtonNeon className=\"flex items-center gap-2\">\n                        <Zap className=\"size-4\" \/>\n                        Download App\n                    <\/ButtonNeon>\n                    <ButtonDraw>View Demo<\/ButtonDraw>\n                <\/div>\n            <\/div>\n\n            {\/* Right mock smartphone *\/}\n            <div className=\"flex flex-1 items-center justify-center py-6\">\n                <PhoneMockup screenClassName=\"justify-between\">\n                    <div className=\"flex items-center justify-between font-mono text-[10px] text-zinc-500\">\n                        <span>9:41<\/span>\n                        <div className=\"flex items-center gap-1\">\n                            <span className=\"size-1.5 animate-pulse rounded-full bg-chart-2\" \/>\n                            <span>LTE<\/span>\n                        <\/div>\n                    <\/div>\n\n                    {\/* App Dashboard UI Simulator *\/}\n                    <div className=\"flex flex-1 flex-col justify-center space-y-3\">\n                        <div className=\"mx-auto flex size-10 items-center justify-center rounded-xl bg-chart-2\/20 text-chart-2\">\n                            <Sparkles className=\"size-5\" \/>\n                        <\/div>\n                        <div className=\"text-center\">\n                            <h4 className=\"text-sm font-bold text-zinc-100\">\n                                Antigravity Hub\n                            <\/h4>\n                            <p className=\"mt-0.5 text-[10px] text-zinc-400\">\n                                Control panel active\n                            <\/p>\n                        <\/div>\n\n                        <div className=\"space-y-2 pt-2\">\n                            <div className=\"bg-zinc-850\/80 flex items-center justify-between rounded-lg border border-zinc-800 p-2.5 text-[10px] text-zinc-300\">\n                                <span>Server Load<\/span>\n                                <span className=\"font-mono font-bold text-chart-2\">\n                                    24%\n                                <\/span>\n                            <\/div>\n                            <div className=\"bg-zinc-850\/80 flex items-center justify-between rounded-lg border border-zinc-800 p-2.5 text-[10px] text-zinc-300\">\n                                <span>Active Users<\/span>\n                                <span className=\"font-mono font-bold text-chart-2\">\n                                    1,842\n                                <\/span>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    {\/* Interactive mini button *\/}\n                    <button className=\"w-full cursor-pointer rounded-lg bg-chart-2 py-2 text-xs font-bold text-primary-foreground transition-colors select-none hover:bg-chart-2\/80 active:scale-95\">\n                        Quick Connect\n                    <\/button>\n                <\/PhoneMockup>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroPhoneMockup;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-section","type":"registry:block","title":"Hero Section","description":"A stunning and modern landing page hero section with typography and call to actions.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-neon.json","https:\/\/ui.test\/r\/button-gradient.json","utils","button","badge","card","https:\/\/ui.test\/r\/button-magnetic.json","https:\/\/ui.test\/r\/button-shine.json","https:\/\/ui.test\/r\/progress-circle.json","https:\/\/ui.test\/r\/interactive-rating.json","https:\/\/ui.test\/r\/button-pulse.json","https:\/\/ui.test\/r\/button-draw.json","https:\/\/ui.test\/r\/pixel-canvas.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-section\/hero-gradient.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Sparkles, ArrowRight, Zap } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonNeon } from '@\/registry\/new-york\/components\/ui\/buttons\/button-neon';\nimport { ButtonGradient } from '@\/registry\/new-york\/components\/ui\/buttons\/button-gradient';\n\nexport function HeroGradient() {\n    return (\n        <section className=\"relative flex min-h-[480px] w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center shadow-2xl select-none md:px-12 lg:px-20\">\n            {\/* Mesh Gradient Backgrounds *\/}\n            <div className=\"absolute inset-0 bg-[radial-gradient(circle_at_50%_-20%,color-mix(in_srgb,var(--color-chart-3)_12%,transparent),transparent)]\" \/>\n            <div className=\"absolute top-1\/2 left-1\/2 h-[250px] w-[500px] -translate-x-1\/2 -translate-y-1\/2 rounded-full bg-gradient-to-r from-chart-2\/8 via-chart-3\/8 to-chart-1\/8 opacity-70 blur-[100px]\" \/>\n\n            <div className=\"relative z-10 flex max-w-3xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Introducing Antigravity UI',\n                        icon: Sparkles,\n                    }}\n                    heading=\"Build premium interfaces in a fraction of the time\"\n                    headingLevel={1}\n                    headClassName=\"text-4xl leading-tight font-extrabold tracking-tight sm:text-5xl lg:text-6xl text-foreground\"\n                    description=\"Leverage pre-configured typography, unique animated buttons, and responsive layouts to compile responsive designs that wow your users.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-8 flex flex-wrap items-center justify-center gap-4\">\n                    <ButtonNeon className=\"flex items-center gap-2\">\n                        Get Started\n                        <ArrowRight className=\"size-4\" \/>\n                    <\/ButtonNeon>\n                    <ButtonGradient className=\"flex items-center gap-2\">\n                        <Zap className=\"size-4 text-primary\" \/>\n                        Explore Components\n                    <\/ButtonGradient>\n                <\/div>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroGradient;\n"},{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-section\/hero-section.tsx","type":"registry:block","content":"import React, { useState } from 'react';\nimport { ArrowRight, Sparkles, Shield, Trophy, Users } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Card, CardContent } from '@\/components\/ui\/card';\nimport { ButtonMagnetic } from '@\/registry\/new-york\/components\/ui\/buttons\/button-magnetic';\nimport { ButtonShine } from '@\/registry\/new-york\/components\/ui\/buttons\/button-shine';\nimport { ProgressCircle } from '@\/registry\/new-york\/components\/ui\/progress\/progress-circle';\nimport { InteractiveRating } from '@\/registry\/new-york\/components\/ui\/rating\/interactive-rating';\n\nexport function HeroSection() {\n    const [userRating, setUserRating] = useState(5);\n    const [submitSuccess, setSubmitSuccess] = useState(false);\n\n    const handleRatingChange = (newRating: number) => {\n        setUserRating(newRating);\n        setSubmitSuccess(true);\n        setTimeout(() => setSubmitSuccess(false), 2000);\n    };\n\n    return (\n        <section className=\"relative flex w-full flex-col items-center gap-12 overflow-hidden rounded-2xl border border-border\/30 bg-background\/50 p-6 shadow-xl select-none md:p-12 lg:flex-row lg:p-16\">\n            {\/* Ambient Background Glows *\/}\n            <div className=\"pointer-events-none absolute -top-40 -left-40 size-96 rounded-full bg-primary\/10 blur-3xl\" \/>\n            <div className=\"pointer-events-none absolute -right-40 -bottom-40 size-96 rounded-full bg-chart-2\/10 blur-3xl\" \/>\n\n            {\/* Left Content Column *\/}\n            <div className=\"relative z-10 flex-1 space-y-6 text-left\">\n                <Badge\n                    variant=\"outline\"\n                    className=\"flex w-fit animate-pulse items-center gap-1.5 border-primary\/20 bg-primary\/5 px-3 py-1 font-mono text-xs font-bold tracking-wider text-primary uppercase\"\n                >\n                    <Sparkles className=\"size-3.5\" \/>\n                    Premium Experience\n                <\/Badge>\n\n                <h1 className=\"text-4xl leading-tight font-extrabold tracking-tight sm:text-5xl\">\n                    Luxury Stays &{' '}\n                    <span className=\"bg-gradient-to-r from-primary to-chart-2 bg-clip-text text-transparent\">\n                        Creative Spaces\n                    <\/span>\n                <\/h1>\n\n                <p className=\"text-sm leading-relaxed text-muted-foreground sm:text-base\">\n                    Discover and reserve hand-crafted spaces tailored for\n                    inspiration, collaboration, and relaxation. Immerse yourself\n                    in environments designed with state-of-the-art aesthetics\n                    and premium comforts.\n                <\/p>\n\n                {\/* Star rating interaction widget *\/}\n                <div className=\"flex max-w-md flex-col gap-4 rounded-xl border border-border\/40 bg-muted\/20 p-4 sm:flex-row sm:items-center\">\n                    <div className=\"space-y-1\">\n                        <span className=\"text-xs font-bold text-foreground\">\n                            Rate your interest:\n                        <\/span>\n                        <div className=\"flex items-center gap-2\">\n                            <InteractiveRating\n                                defaultRating={5}\n                                onChange={handleRatingChange}\n                            \/>\n                            <span className=\"font-mono text-xs font-bold text-muted-foreground\">\n                                ({userRating}.0)\n                            <\/span>\n                        <\/div>\n                    <\/div>\n                    <div className=\"flex flex-col justify-center sm:border-l sm:border-border\/40 sm:pl-4\">\n                        <span className=\"text-[10px] leading-normal text-muted-foreground\">\n                            {submitSuccess ? (\n                                <span className=\"animate-bounce font-bold text-chart-2\">\n                                    Review recorded!\n                                <\/span>\n                            ) : (\n                                'Interact to send a preview rating to our dashboard.'\n                            )}\n                        <\/span>\n                    <\/div>\n                <\/div>\n\n                {\/* Call-to-action buttons using magnetic and shine effects *\/}\n                <div className=\"flex flex-wrap items-center gap-4 pt-2\">\n                    <ButtonShine className=\"flex items-center gap-1.5 rounded-xl px-6 py-5 text-sm font-semibold shadow-md\">\n                        Book Your Stay\n                        <ArrowRight className=\"size-4\" \/>\n                    <\/ButtonShine>\n\n                    <ButtonMagnetic className=\"rounded-xl border border-border\/40 bg-secondary px-6 py-5 text-sm font-semibold text-secondary-foreground hover:bg-muted\/80\">\n                        Explore Gallery\n                    <\/ButtonMagnetic>\n                <\/div>\n            <\/div>\n\n            {\/* Right Interactive Mockup\/Dashboard Column *\/}\n            <div className=\"relative z-10 w-full max-w-md flex-1\">\n                <Card className=\"relative overflow-hidden border border-border\/40 bg-card\/25 p-6 shadow-2xl backdrop-blur-md\">\n                    <div className=\"absolute top-3 right-3 opacity-30\">\n                        <Sparkles className=\"size-6 text-primary\" \/>\n                    <\/div>\n\n                    <h3 className=\"mb-4 flex items-center gap-2 border-b border-border\/20 pb-3 text-sm font-bold tracking-tight\">\n                        <Trophy className=\"size-4.5 text-primary\" \/>\n                        Guesthouse Status Core\n                    <\/h3>\n\n                    {\/* Score Circle Progress Layout *\/}\n                    <div className=\"mb-6 grid grid-cols-2 place-items-center gap-6\">\n                        <ProgressCircle\n                            value={98}\n                            size={100}\n                            strokeWidth={10}\n                            label=\"Cleanliness\"\n                        \/>\n                        <ProgressCircle\n                            value={94}\n                            size={100}\n                            strokeWidth={10}\n                            label=\"Guest Rating\"\n                        \/>\n                    <\/div>\n\n                    {\/* Stats List Items *\/}\n                    <div className=\"space-y-3.5\">\n                        <div className=\"flex items-center justify-between border-t border-border\/10 pt-3 text-xs\">\n                            <span className=\"flex items-center gap-2 text-muted-foreground\">\n                                <Users className=\"size-4 text-chart-3\" \/>\n                                Host communication\n                            <\/span>\n                            <span className=\"font-mono font-bold\">\n                                100% (Flawless)\n                            <\/span>\n                        <\/div>\n                        <div className=\"flex items-center justify-between border-t border-border\/10 pt-3 text-xs\">\n                            <span className=\"flex items-center gap-2 text-muted-foreground\">\n                                <Shield className=\"size-4 text-chart-2\" \/>\n                                Security score\n                            <\/span>\n                            <span className=\"font-mono font-bold\">\n                                99.8% (Verified)\n                            <\/span>\n                        <\/div>\n                    <\/div>\n                <\/Card>\n\n                {\/* Sub-card floating decorative info badge *\/}\n                <div className=\"pointer-events-none absolute -bottom-6 -left-6 flex hidden max-w-[180px] animate-bounce items-center gap-3 rounded-xl border border-primary\/20 bg-primary p-3 text-primary-foreground shadow-lg select-none sm:flex\">\n                    <div className=\"flex size-8 items-center justify-center rounded-full bg-primary-foreground\/15 font-mono text-xs font-black\">\n                        9.9\n                    <\/div>\n                    <div className=\"flex flex-col text-left\">\n                        <span className=\"text-[10px] leading-none font-bold tracking-wider uppercase\">\n                            Superb Score\n                        <\/span>\n                        <span className=\"mt-0.5 text-[8px] opacity-80\">\n                            Guest Favorite Choice\n                        <\/span>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroSection;\n"},{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-section\/hero-split.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Shield, Sparkles, CheckCircle2 } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonPulse } from '@\/registry\/new-york\/components\/ui\/buttons\/button-pulse';\nimport { ButtonDraw } from '@\/registry\/new-york\/components\/ui\/buttons\/button-draw';\nimport { PixelCanvas } from '@\/registry\/new-york\/components\/ui\/canvas\/pixel-canvas';\n\nexport function HeroSplit() {\n    return (\n        <section className=\"relative flex w-full flex-col gap-10 overflow-hidden rounded-2xl border border-border\/30 bg-background\/40 p-8 shadow-xl select-none lg:flex-row lg:items-center lg:p-12\">\n            {\/* Left Content Column *\/}\n            <div className=\"relative z-10 flex-1 space-y-6 text-left\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Security & Integrity Verified',\n                        icon: Shield,\n                    }}\n                    heading=\"Secure operations with zero downtime\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl\"\n                    description=\"Protect your workspace and client data with next-generation authorization mechanisms, end-to-end logging, and audit tracks.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    size=\"sm\"\n                \/>\n\n                <ul className=\"space-y-2.5 text-sm text-muted-foreground\">\n                    <li className=\"flex items-center gap-2\">\n                        <CheckCircle2 className=\"size-4.5 shrink-0 text-chart-2\" \/>\n                        <span>Biometric & Passkey authentication methods<\/span>\n                    <\/li>\n                    <li className=\"flex items-center gap-2\">\n                        <CheckCircle2 className=\"size-4.5 shrink-0 text-chart-2\" \/>\n                        <span>Real-time anomalous action detection<\/span>\n                    <\/li>\n                    <li className=\"flex items-center gap-2\">\n                        <CheckCircle2 className=\"size-4.5 shrink-0 text-chart-2\" \/>\n                        <span>99.99% high-availability cluster setups<\/span>\n                    <\/li>\n                <\/ul>\n\n                <div className=\"flex flex-wrap items-center gap-4 pt-4\">\n                    <ButtonPulse>Setup Shield<\/ButtonPulse>\n                    <ButtonDraw>Read Whitepaper<\/ButtonDraw>\n                <\/div>\n            <\/div>\n\n            {\/* Right Visual Interactive Column *\/}\n            <div className=\"relative min-h-[300px] w-full flex-1 overflow-hidden rounded-xl border border-border\/40 bg-card\/70 shadow-2xl\">\n                <PixelCanvas className=\"absolute inset-0 opacity-40\" \/>\n                <div className=\"pointer-events-none absolute inset-0 flex flex-col items-center justify-center p-6 text-center select-none\">\n                    <Sparkles className=\"mb-2 size-10 animate-pulse text-chart-2\" \/>\n                    <h3 className=\"font-bebas-neue! text-xl font-bold tracking-wider text-foreground\">\n                        Interactive Pixel Matrix\n                    <\/h3>\n                    <p className=\"mt-1 max-w-xs text-xs text-muted-foreground\">\n                        Move your mouse across the grid to interact with the\n                        responsive visual canvas.\n                    <\/p>\n                <\/div>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroSplit;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-simple-split","type":"registry:block","title":"Hero Simple Split","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["card","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-simple-split\/hero-simple-split.tsx","type":"registry:block","content":"'use client';\n\nimport React from 'react';\nimport { Sparkles, Terminal } from 'lucide-react';\nimport { Card, CardContent } from '@\/components\/ui\/card';\nimport { Button } from '@\/components\/ui\/button';\n\nexport function HeroSimpleSplit() {\n    return (\n        <div className=\"w-full py-8\">\n            <div className=\"grid grid-cols-1 items-center gap-8 md:grid-cols-2\">\n                {\/* Left text options *\/}\n                <div className=\"space-y-4 text-left\">\n                    <div className=\"inline-flex items-center gap-1.5 rounded-full border border-primary\/20 bg-primary\/10 px-3 py-1 text-[10px] font-bold text-primary uppercase\">\n                        <Sparkles className=\"size-3\" \/>\n                        Next-Gen Registry Blocks\n                    <\/div>\n                    <h2 className=\"text-2xl leading-tight font-black tracking-tight text-foreground md:text-3xl\">\n                        Modular Building Blocks for Developer Interfaces\n                    <\/h2>\n                    <p className=\"max-w-md text-xs leading-relaxed text-muted-foreground\">\n                        Drop high-quality visual widgets, charts, and form\n                        layouts into your code structure seamlessly using custom\n                        shadcn directives.\n                    <\/p>\n                    <div className=\"flex gap-2\">\n                        <Button\n                            size=\"sm\"\n                            className=\"h-9 gap-1.5 px-4 text-xs font-bold\"\n                        >\n                            <Terminal className=\"size-3.5\" \/>\n                            Explore Components\n                        <\/Button>\n                        <Button\n                            size=\"sm\"\n                            variant=\"outline\"\n                            className=\"h-9 border-border\/60 px-4 text-xs font-bold\"\n                        >\n                            Learn More\n                        <\/Button>\n                    <\/div>\n                <\/div>\n\n                {\/* Right mockup card *\/}\n                <Card className=\"relative overflow-hidden border-border\/50 bg-card\/40 p-6 backdrop-blur-xs\">\n                    <div className=\"flex size-full flex-col gap-3\">\n                        <div className=\"flex items-center gap-1.5 border-b border-border\/30 pb-3\">\n                            <div className=\"size-2.5 rounded-full bg-destructive\/80\" \/>\n                            <div className=\"size-2.5 rounded-full bg-chart-4\/80\" \/>\n                            <div className=\"size-2.5 rounded-full bg-chart-2\/80\" \/>\n                            <span className=\"ml-2 font-mono text-[9px] text-muted-foreground\">\n                                sandbox-editor.tsx\n                            <\/span>\n                        <\/div>\n                        <div className=\"space-y-1 font-mono text-[10px] text-muted-foreground\">\n                            <p>\n                                <span className=\"text-primary\">import<\/span>{' '}\n                                &#123; Button &#125;{' '}\n                                <span className=\"text-primary\">from<\/span>{' '}\n                                <span className=\"text-chart-2\">\n                                    \"@\/components\/ui\/button\"\n                                <\/span>\n                                ;\n                            <\/p>\n                            <p className=\"opacity-70\">\n                                <span className=\"text-primary\">\n                                    export default function\n                                <\/span>{' '}\n                                <span className=\"text-chart-3\">Page<\/span>()\n                                &#123;\n                            <\/p>\n                            <p className=\"pl-4 opacity-70\">\n                                <span className=\"text-primary\">return<\/span> (\n                            <\/p>\n                            <p className=\"pl-8 text-primary\">\n                                &lt;Button&gt;\n                                <span className=\"text-foreground\">\n                                    Click Me\n                                <\/span>\n                                &lt;\/Button&gt;\n                            <\/p>\n                            <p className=\"pl-4 opacity-70\">);<\/p>\n                            <p className=\"opacity-70\">&#125;<\/p>\n                        <\/div>\n                    <\/div>\n                <\/Card>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default HeroSimpleSplit;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-tabs-showcase","type":"registry:block","title":"Hero Tabs Showcase","description":"A structured full-stack hero layout with tabbed navigation displaying frontend, backend, and migration code snippets.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-neon.json","https:\/\/ui.test\/r\/animated-tabs.json","https:\/\/ui.test\/r\/code-window.json","button","typography"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-tabs-showcase\/hero-tabs-showcase.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Code, Server, Database, ArrowRight } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonNeon } from '@\/registry\/new-york\/components\/ui\/buttons\/button-neon';\nimport { AnimatedTabs } from '@\/registry\/new-york\/components\/ui\/tabs\/animated-tabs';\nimport { CodeWindow } from '@\/registry\/new-york\/components\/ui\/mockups\/code-window';\n\nexport function HeroTabsShowcase() {\n    const [activeTab, setActiveTab] = React.useState('frontend');\n\n    const tabList = [\n        { id: 'frontend', label: 'React Frontend' },\n        { id: 'backend', label: 'Laravel Backend' },\n        { id: 'database', label: 'Database Schema' },\n    ];\n\n    const snippets: Record<\n        string,\n        { title: string; lang: string; code: string }\n    > = {\n        frontend: {\n            title: 'dashboard.tsx',\n            lang: 'tsx',\n            code: `import { ButtonNeon } from '@\/components\/ui\/button';\\nimport { HeadingBlock } from '@\/components\/ui\/typography';\\n\\nexport default function App() {\\n    return (\\n        <HeadingBlock\\n            heading=\"Compile premium interfaces\"\\n            description=\"Built on React 19 & Tailwind v4\"\\n        >\\n            <ButtonNeon>Get Started<\/ButtonNeon>\\n        <\/HeadingBlock>\\n    );\\n}`,\n        },\n        backend: {\n            title: 'RouteServiceProvider.php',\n            lang: 'php',\n            code: `use App\\\\Http\\\\Controllers\\\\Auth\\\\SocialiteController;\\nuse Illuminate\\\\Support\\\\Facades\\\\Route;\\n\\nRoute::get('\/auth\/redirect\/{provider}', [SocialiteController::class, 'redirect'])\\n    ->name('socialite.redirect');\\n\\nRoute::get('\/auth\/callback\/{provider}', [SocialiteController::class, 'callback'])\\n    ->name('socialite.callback');`,\n        },\n        database: {\n            title: 'create_registries_table.php',\n            lang: 'php',\n            code: `Schema::create('registries', function (Blueprint $table) {\\n    $table->id();\\n    $table->string('name')->unique();\\n    $table->string('type');\\n    $table->string('title');\\n    $table->text('description')->nullable();\\n    $table->json('files');\\n    $table->timestamps();\\n});`,\n        },\n    };\n\n    return (\n        <section className=\"relative flex w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center select-none\">\n            <div className=\"relative z-10 mb-8 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Full Stack Ready',\n                        icon: Code,\n                    }}\n                    heading=\"Unified design from client to server\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl\"\n                    description=\"Write clean UI code, manage routing middleware, and declare migrations inside a single repository with our fully integrated templates.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-4 flex flex-wrap items-center justify-center gap-4\">\n                    <ButtonNeon className=\"flex items-center gap-1.5\">\n                        Start Building\n                        <ArrowRight className=\"size-4\" \/>\n                    <\/ButtonNeon>\n                <\/div>\n            <\/div>\n\n            {\/* Showcase Tabs and Code Window *\/}\n            <div className=\"relative z-10 flex w-full max-w-2xl flex-col items-center gap-6\">\n                <AnimatedTabs\n                    tabs={tabList}\n                    value={activeTab}\n                    onChange={setActiveTab}\n                \/>\n\n                {\/* Simulated Editor Window *\/}\n                <CodeWindow\n                    title={snippets[activeTab].title}\n                    lang={snippets[activeTab].lang}\n                    code={snippets[activeTab].code}\n                    className=\"h-64 shrink-0\"\n                \/>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroTabsShowcase;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-trusted-by","type":"registry:block","title":"Hero Trusted By","description":"A centered landing page hero banner with an integrated client brand logo cloud for social proof.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-neon.json","https:\/\/ui.test\/r\/button-draw.json","https:\/\/ui.test\/r\/logo-cloud.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-trusted-by\/hero-trusted-by.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Award, Globe, Heart, Sparkles, Terminal } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonNeon } from '@\/registry\/new-york\/components\/ui\/buttons\/button-neon';\nimport { ButtonDraw } from '@\/registry\/new-york\/components\/ui\/buttons\/button-draw';\nimport { LogoCloud } from '@\/registry\/new-york\/components\/ui\/misc\/logo-cloud';\n\nexport function HeroTrustedBy() {\n    const brands = [\n        { icon: Globe, name: 'Stripe' },\n        { icon: Heart, name: 'Vercel' },\n        { icon: Award, name: 'Github' },\n        { icon: Terminal, name: 'Supabase' },\n    ];\n\n    return (\n        <section className=\"relative flex w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center select-none\">\n            <div className=\"relative z-10 mb-12 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Enterprise Grade',\n                        icon: Award,\n                    }}\n                    heading=\"Trusted by leading software teams worldwide\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl\"\n                    description=\"From early stage startups to global enterprises, our codebase helps teams ship structured design languages, fast APIs, and responsive React SPAs.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-6 flex flex-wrap items-center justify-center gap-4\">\n                    <ButtonNeon>Book a Demo<\/ButtonNeon>\n                    <ButtonDraw>Contact Sales<\/ButtonDraw>\n                <\/div>\n            <\/div>\n\n            {\/* Logo Cloud Social Proof Strip *\/}\n            <LogoCloud title=\"POWERING TEAMS AT\" items={brands} \/>\n        <\/section>\n    );\n}\n\nexport default HeroTrustedBy;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-video-dialog","type":"registry:block","title":"Hero Video Dialog","description":"A centered hero section featuring a simulated dashboard mockup with an interactive play state.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-neon.json","https:\/\/ui.test\/r\/browser-mockup.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-video-dialog\/hero-video-dialog.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Play, Pause, Monitor, Sparkles } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonNeon } from '@\/registry\/new-york\/components\/ui\/buttons\/button-neon';\nimport { BrowserMockup } from '@\/registry\/new-york\/components\/ui\/mockups\/browser-mockup';\n\nexport function HeroVideoDialog() {\n    const [isPlaying, setIsPlaying] = React.useState(false);\n\n    return (\n        <section className=\"relative flex w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center select-none\">\n            <div className=\"relative z-10 mb-10 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Product Walkthrough',\n                        icon: Monitor,\n                    }}\n                    heading=\"Watch our 2-minute developer intro\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl\"\n                    description=\"See how our design system compiles components down to raw TypeScript, automatically formatting style grids and configuring theme states.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-4 flex justify-center\">\n                    <ButtonNeon\n                        onClick={() => setIsPlaying(!isPlaying)}\n                        className=\"flex items-center gap-2\"\n                    >\n                        {isPlaying ? (\n                            <Pause className=\"size-4\" \/>\n                        ) : (\n                            <Play className=\"size-4\" \/>\n                        )}\n                        {isPlaying ? 'Pause Demo' : 'Play Walkthrough'}\n                    <\/ButtonNeon>\n                <\/div>\n            <\/div>\n\n            {\/* Video Dashboard Mock Window *\/}\n            <BrowserMockup\n                title=\"preview-player.mp4\"\n                className=\"aspect-video max-w-3xl\"\n                viewportClassName=\"flex flex-col justify-between\"\n            >\n                {\/* Main area *\/}\n                <div className=\"relative flex flex-1 items-center justify-center overflow-hidden bg-zinc-900\/80\">\n                    {\/* Background grid *\/}\n                    <div className=\"absolute inset-0 bg-[linear-gradient(to_right,#80808012_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]\" \/>\n\n                    {isPlaying ? (\n                        <div className=\"relative z-10 flex flex-col items-center gap-3\">\n                            <span className=\"flex size-12 animate-ping items-center justify-center rounded-full bg-chart-2\/10 text-chart-2 duration-1000\" \/>\n                            <div className=\"absolute inset-0 flex size-12 items-center justify-center rounded-full bg-chart-2\/20 text-chart-2\">\n                                <Sparkles className=\"size-5 animate-pulse\" \/>\n                            <\/div>\n                            <span className=\"animate-pulse pt-8 font-mono text-xs tracking-wider text-chart-2\/90\">\n                                SIMULATING VIDEO STREAM...\n                            <\/span>\n                        <\/div>\n                    ) : (\n                        <button\n                            onClick={() => setIsPlaying(true)}\n                            className=\"group\/btn relative z-10 flex size-16 cursor-pointer items-center justify-center rounded-full border border-zinc-700\/60 bg-zinc-950\/80 text-zinc-100 shadow-2xl transition-all hover:scale-110 hover:border-chart-2 hover:text-chart-2 active:scale-95\"\n                        >\n                            <Play className=\"ml-1 size-6 transition-transform group-hover\/btn:scale-105\" \/>\n                        <\/button>\n                    )}\n                <\/div>\n\n                {\/* Simulated playbar controls *\/}\n                <div className=\"flex h-10 shrink-0 items-center justify-between border-t border-zinc-800 bg-zinc-900\/60 px-4 font-mono text-[10px] text-zinc-400\">\n                    <span>{isPlaying ? '0:24' : '0:00'} \/ 2:00<\/span>\n                    <div className=\"mx-4 h-1 flex-1 overflow-hidden rounded-full bg-zinc-800\">\n                        <div\n                            className=\"h-full bg-chart-2 transition-all duration-300\"\n                            style={{ width: isPlaying ? '20%' : '0%' }}\n                        \/>\n                    <\/div>\n                    <span>1080p HD<\/span>\n                <\/div>\n            <\/BrowserMockup>\n        <\/section>\n    );\n}\n\nexport default HeroVideoDialog;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-waitlist","type":"registry:block","title":"Hero Waitlist","description":"An interactive private beta submission form featuring custom number steppers and subscription feedback.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-neon.json","https:\/\/ui.test\/r\/input-number-stepper.json","input"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-waitlist\/hero-waitlist.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Mail, CheckCircle2, Sparkles } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonNeon } from '@\/registry\/new-york\/components\/ui\/buttons\/button-neon';\nimport { InputNumberStepper } from '@\/registry\/new-york\/components\/ui\/inputs\/input-number-stepper';\nimport { Input } from '@\/components\/ui\/input';\n\nexport function HeroWaitlist() {\n    const [email, setEmail] = React.useState('');\n    const [seats, setSeats] = React.useState<number | undefined>(3);\n    const [isSubmitted, setIsSubmitted] = React.useState(false);\n\n    const handleSubmit = (e: React.FormEvent) => {\n        e.preventDefault();\n        if (email.trim()) {\n            setIsSubmitted(true);\n        }\n    };\n\n    return (\n        <section className=\"relative flex w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center select-none\">\n            {\/* Mesh backdrop *\/}\n            <div className=\"absolute inset-0 bg-[radial-gradient(circle_at_50%_-10%,rgba(16,185,129,0.06),rgba(255,255,255,0))]\" \/>\n\n            <div className=\"relative z-10 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'Private Beta Access',\n                        icon: Mail,\n                    }}\n                    heading=\"Secure your spot for early access\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl\"\n                    description=\"We are launching our developer tools suite next month. Request early access for your team to enjoy premium rates and onboarding resources.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                {!isSubmitted ? (\n                    <form\n                        onSubmit={handleSubmit}\n                        className=\"mt-8 w-full max-w-md space-y-4 rounded-xl border border-border\/40 bg-card\/60 p-6 text-left shadow-xl backdrop-blur-xs\"\n                    >\n                        <div className=\"space-y-1.5\">\n                            <label className=\"text-xs font-semibold text-muted-foreground\">\n                                Work Email\n                            <\/label>\n                            <Input\n                                type=\"email\"\n                                placeholder=\"name@company.com\"\n                                value={email}\n                                onChange={(e) => setEmail(e.target.value)}\n                                className=\"h-10 w-full\"\n                                required\n                            \/>\n                        <\/div>\n\n                        <div className=\"flex flex-col justify-between gap-4 py-2 sm:flex-row sm:items-center\">\n                            <div className=\"space-y-0.5\">\n                                <label className=\"text-xs font-semibold text-foreground\">\n                                    Number of seats requested\n                                <\/label>\n                                <p className=\"text-[10px] text-muted-foreground\">\n                                    Select how many developer licenses you need.\n                                <\/p>\n                            <\/div>\n                            <InputNumberStepper\n                                value={seats}\n                                onValueChange={setSeats}\n                                min={1}\n                                max={20}\n                                variant=\"split\"\n                            \/>\n                        <\/div>\n\n                        <ButtonNeon\n                            type=\"submit\"\n                            className=\"mt-2 h-10 w-full font-bold\"\n                        >\n                            Request Invite ({seats} licenses)\n                        <\/ButtonNeon>\n                    <\/form>\n                ) : (\n                    <div className=\"mt-8 flex w-full max-w-md flex-col items-center gap-4 rounded-xl border border-primary\/20 bg-primary\/5 p-8 text-center shadow-xl\">\n                        <div className=\"flex size-12 items-center justify-center rounded-full bg-primary\/10 text-primary\">\n                            <CheckCircle2 className=\"size-6 animate-bounce\" \/>\n                        <\/div>\n                        <div>\n                            <h4 className=\"text-base font-bold text-foreground\">\n                                You're on the list!\n                            <\/h4>\n                            <p className=\"mx-auto mt-1 max-w-xs text-xs text-muted-foreground\">\n                                We sent a confirmation code to{' '}\n                                <span className=\"font-mono font-bold text-primary\">\n                                    {email}\n                                <\/span>\n                                . We've reserved {seats} seats for you.\n                            <\/p>\n                        <\/div>\n                        <button\n                            onClick={() => {\n                                setIsSubmitted(false);\n                                setEmail('');\n                            }}\n                            className=\"cursor-pointer text-xs font-medium text-primary underline underline-offset-4 transition-colors hover:text-primary\/80\"\n                        >\n                            Submit another email\n                        <\/button>\n                    <\/div>\n                )}\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroWaitlist;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"hero-waves","type":"registry:block","title":"Hero Waves","description":"An immersive black-themed hero banner using a WebGL 3D waves canvas backdrop behind high-end typography.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/heading-block.json","https:\/\/ui.test\/r\/button-neon.json","https:\/\/ui.test\/r\/button-draw.json","https:\/\/ui.test\/r\/waves-three.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/hero-waves\/hero-waves.tsx","type":"registry:block","content":"'use client';\n\nimport * as React from 'react';\nimport { Sparkles, ArrowRight } from 'lucide-react';\nimport HeadingBlock from '@\/registry\/new-york\/components\/ui\/typography\/heading-block';\nimport { ButtonNeon } from '@\/registry\/new-york\/components\/ui\/buttons\/button-neon';\nimport { ButtonDraw } from '@\/registry\/new-york\/components\/ui\/buttons\/button-draw';\nimport WavesThree from '@\/registry\/new-york\/components\/ui\/threejs\/waves-three';\n\nexport function HeroWaves() {\n    return (\n        <section className=\"relative flex min-h-[480px] w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border\/30 bg-background px-6 py-16 text-center shadow-2xl select-none\">\n            {\/* Interactive 3D Waves background *\/}\n            <div className=\"absolute inset-0 opacity-70\">\n                <WavesThree className=\"absolute inset-0 size-full\" \/>\n            <\/div>\n\n            {\/* Backdrop gradient mask *\/}\n            <div className=\"pointer-events-none absolute inset-0 bg-gradient-to-t from-background via-transparent to-background\" \/>\n\n            <div className=\"relative z-10 flex max-w-2xl flex-col items-center\">\n                <HeadingBlock\n                    badge={{\n                        text: 'WebGL Accelerated',\n                        icon: Sparkles,\n                    }}\n                    heading=\"Stunning WebGL 3D backdrops\"\n                    headingLevel={1}\n                    headClassName=\"text-3xl leading-tight font-extrabold tracking-tight sm:text-4xl lg:text-5xl text-foreground\"\n                    description=\"Deliver visually immersive client portals with interactive 3D particle animations. Completely optimized for hardware rendering without dropping frames.\"\n                    descriptionClassName=\"text-muted-foreground\"\n                    className=\"flex flex-col items-center\"\n                \/>\n\n                <div className=\"mt-6 flex flex-wrap items-center justify-center gap-4\">\n                    <ButtonNeon className=\"flex items-center gap-2\">\n                        Get Started\n                        <ArrowRight className=\"size-4\" \/>\n                    <\/ButtonNeon>\n                    <ButtonDraw>API Documentation<\/ButtonDraw>\n                <\/div>\n            <\/div>\n        <\/section>\n    );\n}\n\nexport default HeroWaves;\n"}],"meta":{"category":"hero-sections","version":"1.0.0"},"categories":["hero-sections"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"inputs-gallery","type":"registry:block","title":"Inputs Gallery","description":"An interactive display showcasing specialized text, phone, currency, slug, and rating input components.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/input-slug.json","https:\/\/ui.test\/r\/input-phone.json","https:\/\/ui.test\/r\/input-currency.json","https:\/\/ui.test\/r\/input-number.json","https:\/\/ui.test\/r\/input-password.json","https:\/\/ui.test\/r\/sliding-radio-group.json","https:\/\/ui.test\/r\/multi-select.json","input","card","badge"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/inputs-gallery\/inputs-gallery.tsx","type":"registry:block","content":"import React, { useState } from 'react';\nimport {\n    Tag,\n    Search,\n    Hash,\n    Lock,\n    Phone,\n    DollarSign,\n    Coins,\n    Binary,\n    Sliders,\n    Sparkles,\n    Layers,\n} from 'lucide-react';\nimport { InputSlug } from '@\/registry\/new-york\/components\/ui\/inputs\/input-slug';\nimport { InputPhone } from '@\/registry\/new-york\/components\/ui\/inputs\/input-phone';\nimport { InputCurrency } from '@\/registry\/new-york\/components\/ui\/inputs\/input-currency';\nimport { InputNumber } from '@\/registry\/new-york\/components\/ui\/inputs\/input-number';\nimport { InputPassword } from '@\/registry\/new-york\/components\/ui\/inputs\/input-password';\nimport { SlidingRadioGroup } from '@\/registry\/new-york\/components\/ui\/inputs\/sliding-radio-group';\nimport {\n    MultiSelect,\n    MultiSelectTrigger,\n    MultiSelectValue,\n    MultiSelectContent,\n    MultiSelectItem,\n} from '@\/registry\/new-york\/components\/ui\/inputs\/multi-select';\nimport { Input } from '@\/components\/ui\/input';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\nimport { Badge } from '@\/components\/ui\/badge';\n\nexport function InputsGallery() {\n    \/\/ Original states\n    const [slugValue, setSlugValue] = useState('');\n    const [glassVal, setGlassVal] = useState('gold');\n    const [neonVal, setNeonVal] = useState('monthly');\n    const [bouncyVal, setBouncyVal] = useState('all');\n    const [selectedTags, setSelectedTags] = useState<string[]>([]);\n    const [searchFocused, setSearchFocused] = useState(false);\n    const [searchValue, setSearchValue] = useState('');\n    const [passwordValue, setPasswordValue] = useState('');\n\n    \/\/ New component states\n    const [phoneValue, setPhoneValue] = useState('1234567890');\n    const [currencyUsd, setCurrencyUsd] = useState<number | undefined>(1250.75);\n    const [currencyEur, setCurrencyEur] = useState<number | undefined>(89.9);\n    const [numberVal1, setNumberVal1] = useState<number | undefined>(24);\n    const [numberVal2, setNumberVal2] = useState<number | undefined>(1.5);\n\n    const options = [\n        { label: 'Next.js', value: 'next' },\n        { label: 'Laravel', value: 'laravel' },\n        { label: 'React', value: 'react' },\n        { label: 'Vite', value: 'vite' },\n        { label: 'Tailwind CSS', value: 'tailwind' },\n    ];\n\n    return (\n        <div className=\"mx-auto flex w-full max-w-5xl flex-col gap-8 px-4 py-6\">\n            <div className=\"space-y-2\">\n                <Badge\n                    variant=\"outline\"\n                    className=\"bg-primary\/5 px-3 py-1 font-mono text-xs tracking-widest text-primary uppercase\"\n                >\n                    Component Showcase\n                <\/Badge>\n                <h2 className=\"text-2xl font-bold tracking-tight\">\n                    Interactive Inputs Gallery\n                <\/h2>\n                <p className=\"text-xs text-muted-foreground\">\n                    Explore and compare different interactive input fields, tag\n                    drop-downs, phone validators, currency formatters, and\n                    number steppers.\n                <\/p>\n            <\/div>\n\n            <div className=\"grid w-full items-stretch gap-6 sm:grid-cols-2 lg:grid-cols-3\">\n                {\/* 1. Slug Formatter Input *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Hash className=\"size-4 text-chart-5\" \/>\n                            Auto-Slug Input\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Format text dynamically into clean, URL-safe slug\n                            strings as you type.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <InputSlug\n                            value={slugValue}\n                            onValueChange={setSlugValue}\n                            placeholder=\"Type a title e.g. New Product Launch...\"\n                            className=\"h-9 w-full text-xs\"\n                        \/>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            slug:{' '}\n                            <span className=\"font-bold text-primary\">\n                                {slugValue || 'none'}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 2. Multi-Select Dropdown *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Tag className=\"size-4 text-chart-3\" \/>\n                            Multi-Select Dropdown\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Dropdown component for selecting and compiling\n                            multiple tags.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex min-h-[120px] flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <MultiSelect\n                            value={selectedTags}\n                            onValueChange={setSelectedTags}\n                        >\n                            <MultiSelectTrigger className=\"h-9 w-full text-xs\">\n                                <MultiSelectValue placeholder=\"Select technologies...\" \/>\n                            <\/MultiSelectTrigger>\n                            <MultiSelectContent>\n                                {options.map((opt) => (\n                                    <MultiSelectItem\n                                        key={opt.value}\n                                        value={opt.value}\n                                    >\n                                        {opt.label}\n                                    <\/MultiSelectItem>\n                                ))}\n                            <\/MultiSelectContent>\n                        <\/MultiSelect>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            Selected:{' '}\n                            <span className=\"font-bold text-primary\">\n                                {selectedTags.join(', ') || 'none'}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 3. Focus-Glow Search Input *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Search className=\"size-4 text-chart-2\" \/>\n                            Focus-Glow Search\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Expands and updates border glow states upon search\n                            selection.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center pb-6\">\n                        <div className=\"relative\">\n                            <Search\n                                className={`absolute top-1\/2 left-3 size-3.5 -translate-y-1\/2 transition-colors duration-300 ${\n                                    searchFocused\n                                        ? 'text-primary'\n                                        : 'text-muted-foreground'\n                                }`}\n                            \/>\n                            <Input\n                                value={searchValue}\n                                onChange={(e) => setSearchValue(e.target.value)}\n                                onFocus={() => setSearchFocused(true)}\n                                onBlur={() => setSearchFocused(false)}\n                                placeholder=\"Search queries...\"\n                                className={`h-9 pl-9 text-xs transition-all duration-300 ${\n                                    searchFocused\n                                        ? 'border-primary bg-card\/50 ring-1 ring-primary\/20'\n                                        : 'border-border\/50 bg-card\/15'\n                                }`}\n                            \/>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 4. Interactive Phone Number *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Phone className=\"size-4 text-chart-4\" \/>\n                            Formatted Phone Input\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Enforces numeric input and formats to masks like US\n                            phone standard.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <InputPhone\n                            value={phoneValue}\n                            onValueChange={setPhoneValue}\n                            placeholder=\"(555) 000-0000\"\n                            className=\"h-9 w-full text-xs\"\n                        \/>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            digits:{' '}\n                            <span className=\"font-bold text-primary\">\n                                {phoneValue || 'none'}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 5. Currency Formatter (USD) *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <DollarSign className=\"size-4 text-chart-4\" \/>\n                            Currency Input (USD)\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Thousand grouping, decimal enforcement, and\n                            auto-round on blur.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <InputCurrency\n                            value={currencyUsd}\n                            onValueChange={(val) => setCurrencyUsd(val)}\n                            currency=\"USD\"\n                            locale=\"en-US\"\n                            placeholder=\"0.00\"\n                            className=\"h-9 w-full text-xs\"\n                        \/>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            float:{' '}\n                            <span className=\"font-bold text-primary\">\n                                {currencyUsd !== undefined\n                                    ? currencyUsd\n                                    : 'none'}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 6. Currency Formatter (EUR) *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Coins className=\"size-4 text-chart-3\" \/>\n                            Currency Input (EUR)\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Supports international locales and currency symbols\n                            automatically.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <InputCurrency\n                            value={currencyEur}\n                            onValueChange={(val) => setCurrencyEur(val)}\n                            currency=\"EUR\"\n                            locale=\"de-DE\"\n                            placeholder=\"0,00\"\n                            className=\"h-9 w-full text-xs\"\n                        \/>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            float:{' '}\n                            <span className=\"font-bold text-primary\">\n                                {currencyEur !== undefined\n                                    ? currencyEur\n                                    : 'none'}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 7. Numeric Stepper \/ Suffix *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Binary className=\"size-4 text-chart-1\" \/>\n                            Numeric Spinner (px)\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Numeric stepper controls, Arrow keys, limits, and\n                            suffix labels.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <InputNumber\n                            value={numberVal1}\n                            onValueChange={setNumberVal1}\n                            min={0}\n                            max={100}\n                            step={1}\n                            suffix=\"px\"\n                            placeholder=\"0\"\n                            className=\"h-9 w-full text-xs\"\n                        \/>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            number:{' '}\n                            <span className=\"font-bold text-primary\">\n                                {numberVal1 !== undefined ? numberVal1 : 'none'}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 8. Decimals Spinner *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Sliders className=\"size-4 text-chart-5\" \/>\n                            Decimals Spinner\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Increment with float step (e.g. 0.5) and precision\n                            auto-handling.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <InputNumber\n                            value={numberVal2}\n                            onValueChange={setNumberVal2}\n                            min={0}\n                            max={10}\n                            step={0.5}\n                            placeholder=\"0.0\"\n                            className=\"h-9 w-full text-xs\"\n                        \/>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            number:{' '}\n                            <span className=\"font-bold text-primary\">\n                                {numberVal2 !== undefined ? numberVal2 : 'none'}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 9. Secure Password Field *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Lock className=\"size-4 text-chart-1\" \/>\n                            Password Input\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            A secure password input field with a toggleable\n                            visibility eye icon.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <InputPassword\n                            value={passwordValue}\n                            onChange={(e) => setPasswordValue(e.target.value)}\n                            placeholder=\"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\"\n                            className=\"h-9 w-full text-xs\"\n                        \/>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            Value:{' '}\n                            <span className=\"font-bold text-primary\">\n                                {passwordValue || 'none'}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 10. Sliding Radio Group (Glass) *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Sparkles className=\"size-4 text-chart-4\" \/>\n                            Sliding Radio (Glass Plan)\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Translucent glassmorphism style with custom\n                            per-option colored gliders.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <div className=\"flex w-full justify-center\">\n                            <SlidingRadioGroup\n                                variant=\"glass\"\n                                size=\"md\"\n                                value={glassVal}\n                                onChange={setGlassVal}\n                                options={[\n                                    {\n                                        label: 'Silver',\n                                        value: 'silver',\n                                        gliderClassName:\n                                            'bg-muted border border-border\/60 shadow-[0_0_8px_var(--color-border)] text-foreground',\n                                    },\n                                    {\n                                        label: 'Gold',\n                                        value: 'gold',\n                                        gliderClassName:\n                                            'bg-chart-4\/20 border border-chart-4\/40 shadow-[0_0_12px_rgba(245,158,11,0.25)] text-chart-4 font-bold',\n                                    },\n                                    {\n                                        label: 'Platinum',\n                                        value: 'platinum',\n                                        gliderClassName:\n                                            'bg-chart-2\/20 border border-chart-2\/40 shadow-[0_0_12px_rgba(34,211,238,0.25)] text-chart-2 font-bold',\n                                    },\n                                ]}\n                            \/>\n                        <\/div>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            Plan:{' '}\n                            <span className=\"font-bold text-primary capitalize\">\n                                {glassVal}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 11. Sliding Radio Group (Neon) *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Layers className=\"size-4 text-chart-1\" \/>\n                            Sliding Radio (Neon)\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Modern neon design with soft glowing glider backing.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <div className=\"flex w-full justify-center\">\n                            <SlidingRadioGroup\n                                variant=\"neon\"\n                                size=\"sm\"\n                                value={neonVal}\n                                onChange={setNeonVal}\n                                options={[\n                                    { label: 'Monthly', value: 'monthly' },\n                                    { label: 'Quarterly', value: 'quarterly' },\n                                    { label: 'Annually', value: 'annually' },\n                                ]}\n                            \/>\n                        <\/div>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            Cycle:{' '}\n                            <span className=\"font-bold text-primary capitalize\">\n                                {neonVal}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n\n                {\/* 12. Sliding Radio Group (Bouncy) *\/}\n                <Card className=\"flex flex-col justify-between border border-border\/40 bg-card\/25 backdrop-blur-xs\">\n                    <CardHeader className=\"pb-3\">\n                        <CardTitle className=\"flex items-center gap-2 text-sm font-bold\">\n                            <Sliders className=\"size-4 text-chart-2\" \/>\n                            Sliding Radio (Bouncy)\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Minimalist pill layout featuring a high elasticity\n                            spring glider.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex flex-1 flex-col justify-center space-y-3 pb-6\">\n                        <div className=\"flex w-full justify-center\">\n                            <SlidingRadioGroup\n                                variant=\"bouncy\"\n                                size=\"md\"\n                                value={bouncyVal}\n                                onChange={setBouncyVal}\n                                options={[\n                                    { label: 'All', value: 'all' },\n                                    { label: 'Active', value: 'active' },\n                                    { label: 'Completed', value: 'completed' },\n                                ]}\n                            \/>\n                        <\/div>\n                        <div className=\"truncate rounded border border-border\/20 bg-muted\/30 p-2.5 font-mono text-[10px] text-muted-foreground\">\n                            Filter:{' '}\n                            <span className=\"font-bold text-primary capitalize\">\n                                {bouncyVal}\n                            <\/span>\n                        <\/div>\n                    <\/CardContent>\n                <\/Card>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default InputsGallery;\n"}],"meta":{"category":"galleries","version":"1.0.0"},"categories":["galleries"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"music-player","type":"registry:block","title":"Music Player","description":"An immersive, premium client-side music player layout with playlist and visual controls.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/audio-context.json","button","utils","input","popover"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/music-player\/audio-visualizer.tsx","type":"registry:block","content":"'use client';\n\nimport { useRef, useEffect, useCallback } from 'react';\nimport type { VisualizerStyle } from '@\/registry\/new-york\/lib\/audio-context';\n\ninterface AudioVisualizerProps {\n    analyser: AnalyserNode | null;\n    isPlaying: boolean;\n    style: VisualizerStyle;\n    primaryColor?: string;\n    secondaryColor?: string;\n}\n\nexport function AudioVisualizer({\n    analyser,\n    isPlaying,\n    style,\n    primaryColor,\n    secondaryColor,\n}: AudioVisualizerProps) {\n    const canvasRef = useRef<HTMLCanvasElement>(null);\n    const animationRef = useRef<number | null>(null);\n    const particlesRef = useRef<\n        Array<{\n            x: number;\n            y: number;\n            vx: number;\n            vy: number;\n            size: number;\n            life: number;\n        }>\n    >([]);\n\n    const drawBars = useCallback(\n        (\n            ctx: CanvasRenderingContext2D,\n            dataArray: Uint8Array,\n            width: number,\n            height: number,\n        ) => {\n            const bufferLength = dataArray.length;\n            const barWidth = (width \/ bufferLength) * 2.5;\n            let x = 0;\n\n            for (let i = 0; i < bufferLength; i++) {\n                const barHeight = (dataArray[i] \/ 255) * height * 0.8;\n\n                const gradient = ctx.createLinearGradient(\n                    0,\n                    height,\n                    0,\n                    height - barHeight,\n                );\n                gradient.addColorStop(0, primaryColor || '#e54545');\n                gradient.addColorStop(1, secondaryColor || '#ff7b7b');\n\n                ctx.fillStyle = gradient;\n                ctx.fillRect(x, height - barHeight, barWidth - 2, barHeight);\n\n                \/\/ Reflection\n                ctx.fillStyle = `${primaryColor || '#e54545'}33`;\n                ctx.fillRect(x, height, barWidth - 2, barHeight * 0.3);\n\n                x += barWidth;\n            }\n        },\n        [primaryColor, secondaryColor],\n    );\n\n    const drawWave = useCallback(\n        (\n            ctx: CanvasRenderingContext2D,\n            dataArray: Uint8Array,\n            width: number,\n            height: number,\n        ) => {\n            const bufferLength = dataArray.length;\n            const sliceWidth = width \/ bufferLength;\n\n            ctx.lineWidth = 3;\n            ctx.strokeStyle = primaryColor || '#e54545';\n            ctx.shadowColor = primaryColor || '#e54545';\n            ctx.shadowBlur = 10;\n\n            ctx.beginPath();\n            let x = 0;\n\n            for (let i = 0; i < bufferLength; i++) {\n                const v = dataArray[i] \/ 128.0;\n                const y = (v * height) \/ 2;\n\n                if (i === 0) {\n                    ctx.moveTo(x, y);\n                } else {\n                    ctx.lineTo(x, y);\n                }\n\n                x += sliceWidth;\n            }\n\n            ctx.lineTo(width, height \/ 2);\n            ctx.stroke();\n\n            \/\/ Second wave with offset\n            ctx.strokeStyle = secondaryColor || '#ff7b7b';\n            ctx.globalAlpha = 0.5;\n            ctx.beginPath();\n            x = 0;\n\n            for (let i = 0; i < bufferLength; i++) {\n                const v = dataArray[i] \/ 128.0;\n                const y = (v * height) \/ 2 + 10;\n\n                if (i === 0) {\n                    ctx.moveTo(x, y);\n                } else {\n                    ctx.lineTo(x, y);\n                }\n\n                x += sliceWidth;\n            }\n\n            ctx.lineTo(width, height \/ 2);\n            ctx.stroke();\n            ctx.globalAlpha = 1;\n            ctx.shadowBlur = 0;\n        },\n        [primaryColor, secondaryColor],\n    );\n\n    const drawCircular = useCallback(\n        (\n            ctx: CanvasRenderingContext2D,\n            dataArray: Uint8Array,\n            width: number,\n            height: number,\n        ) => {\n            const centerX = width \/ 2;\n            const centerY = height \/ 2;\n            const radius = Math.min(width, height) * 0.35;\n            const bufferLength = dataArray.length;\n\n            \/\/ Draw circular bars\n            for (let i = 0; i < bufferLength; i++) {\n                const angle = (i \/ bufferLength) * Math.PI * 2 - Math.PI \/ 2;\n                const barHeight = (dataArray[i] \/ 255) * radius * 0.8;\n\n                const x1 = centerX + Math.cos(angle) * radius;\n                const y1 = centerY + Math.sin(angle) * radius;\n                const x2 = centerX + Math.cos(angle) * (radius + barHeight);\n                const y2 = centerY + Math.sin(angle) * (radius + barHeight);\n\n                const gradient = ctx.createLinearGradient(x1, y1, x2, y2);\n                gradient.addColorStop(0, primaryColor || '#e54545');\n                gradient.addColorStop(1, secondaryColor || '#ff7b7b');\n\n                ctx.beginPath();\n                ctx.strokeStyle = gradient;\n                ctx.lineWidth = 2;\n                ctx.moveTo(x1, y1);\n                ctx.lineTo(x2, y2);\n                ctx.stroke();\n            }\n\n            \/\/ Inner glow circle\n            ctx.beginPath();\n            ctx.arc(centerX, centerY, radius * 0.8, 0, Math.PI * 2);\n            ctx.strokeStyle = `${primaryColor || '#e54545'}44`;\n            ctx.lineWidth = 2;\n            ctx.stroke();\n        },\n        [primaryColor, secondaryColor],\n    );\n\n    const drawParticles = useCallback(\n        (\n            ctx: CanvasRenderingContext2D,\n            dataArray: Uint8Array,\n            width: number,\n            height: number,\n        ) => {\n            const avgAmplitude =\n                dataArray.reduce((a, b) => a + b, 0) \/ dataArray.length;\n\n            \/\/ Add new particles based on audio\n            if (avgAmplitude > 50) {\n                for (let i = 0; i < Math.floor(avgAmplitude \/ 30); i++) {\n                    particlesRef.current.push({\n                        x: Math.random() * width,\n                        y: height,\n                        vx: (Math.random() - 0.5) * 3,\n                        vy: -Math.random() * (avgAmplitude \/ 30) - 2,\n                        size: Math.random() * 4 + 2,\n                        life: 1,\n                    });\n                }\n            }\n\n            \/\/ Update and draw particles\n            particlesRef.current = particlesRef.current.filter((p) => {\n                p.x += p.vx;\n                p.y += p.vy;\n                p.vy += 0.05;\n                p.life -= 0.015;\n\n                if (p.life <= 0) {\n                    return false;\n                }\n\n                ctx.beginPath();\n                ctx.arc(p.x, p.y, p.size * p.life, 0, Math.PI * 2);\n                ctx.fillStyle =\n                    p.life > 0.5\n                        ? primaryColor || '#e54545'\n                        : secondaryColor || '#ff7b7b';\n                ctx.globalAlpha = p.life;\n                ctx.fill();\n                ctx.globalAlpha = 1;\n\n                return p.life > 0;\n            });\n\n            \/\/ Draw frequency bars at bottom\n            const barCount = 10;\n            const barWidth = width \/ barCount;\n\n            for (let i = 0; i < barCount; i++) {\n                const dataIndex = Math.floor((i \/ barCount) * dataArray.length);\n                const barHeight = (dataArray[dataIndex] \/ 255) * height * 0.3;\n\n                ctx.fillStyle = `${primaryColor || '#e54545'}88`;\n                ctx.fillRect(\n                    i * barWidth,\n                    height - barHeight,\n                    barWidth - 2,\n                    barHeight,\n                );\n            }\n        },\n        [primaryColor, secondaryColor],\n    );\n\n    useEffect(() => {\n        const canvas = canvasRef.current;\n\n        if (!canvas) {\n            return;\n        }\n\n        const ctx = canvas.getContext('2d');\n\n        if (!ctx) {\n            return;\n        }\n\n        const resizeCanvas = () => {\n            const rect = canvas.getBoundingClientRect();\n            canvas.width = rect.width * window.devicePixelRatio;\n            canvas.height = rect.height * window.devicePixelRatio;\n            ctx.scale(window.devicePixelRatio, window.devicePixelRatio);\n        };\n\n        const resizeObserver = new ResizeObserver(() => {\n            resizeCanvas();\n        });\n\n        resizeObserver.observe(canvas);\n\n        const draw = () => {\n            const rect = canvas.getBoundingClientRect();\n            const width = rect.width;\n            const height = rect.height;\n\n            ctx.clearRect(0, 0, width, height);\n\n            if (analyser && isPlaying) {\n                const bufferLength = analyser.frequencyBinCount;\n                const dataArray = new Uint8Array(bufferLength);\n                analyser.getByteFrequencyData(dataArray);\n\n                switch (style) {\n                    case 'bars':\n                        drawBars(ctx, dataArray, width, height);\n                        break;\n                    case 'wave':\n                        analyser.getByteTimeDomainData(dataArray);\n                        drawWave(ctx, dataArray, width, height);\n                        break;\n                    case 'circular':\n                        drawCircular(ctx, dataArray, width, height);\n                        break;\n                    case 'particles':\n                        drawParticles(ctx, dataArray, width, height);\n                        break;\n                }\n            } else {\n                \/\/ Draw idle animation\n                const time = Date.now() \/ 1000;\n                const bars = 22;\n                const barWidth = rect.width \/ bars;\n\n                for (let i = 0; i < bars; i++) {\n                    const barHeight =\n                        (Math.sin(time * 2 + i * 0.3) + 1) * 10 + 5;\n                    ctx.fillStyle = `${primaryColor || '#e54545'}88`;\n                    ctx.fillRect(\n                        i * barWidth,\n                        height - barHeight,\n                        barWidth - 2,\n                        barHeight,\n                    );\n                }\n            }\n\n            animationRef.current = requestAnimationFrame(draw);\n        };\n\n        draw();\n\n        return () => {\n            resizeObserver.disconnect();\n\n            if (animationRef.current) {\n                cancelAnimationFrame(animationRef.current);\n            }\n        };\n    }, [\n        analyser,\n        isPlaying,\n        style,\n        drawBars,\n        drawWave,\n        drawCircular,\n        drawParticles,\n        primaryColor,\n    ]);\n\n    return (\n        <canvas\n            ref={canvasRef}\n            className=\"h-full w-full\"\n            style={{ display: 'block' }}\n        \/>\n    );\n}\n"},{"path":"resources\/js\/registry\/new-york\/components\/blocks\/music-player\/music-player.tsx","type":"registry:block","content":"'use client';\n\nimport { Menu, ListMusic } from 'lucide-react';\n\nimport { useState, useRef, useEffect, useCallback, useMemo } from 'react';\nimport { Button } from '@\/components\/ui\/button';\nimport { useThemeColors } from '@\/lib\/theme-colors';\nimport { AudioVisualizer } from '@\/registry\/new-york\/components\/blocks\/music-player\/audio-visualizer';\nimport { PlayerControls } from '@\/registry\/new-york\/components\/blocks\/music-player\/player-controls';\nimport { PlaylistSidebar } from '@\/registry\/new-york\/components\/blocks\/music-player\/playlist-sidebar';\nimport { ProgressBar } from '@\/registry\/new-york\/components\/blocks\/music-player\/progress-bar';\nimport { TrackInfo } from '@\/registry\/new-york\/components\/blocks\/music-player\/track-info';\nimport { VisualizerSettings } from '@\/registry\/new-york\/components\/blocks\/music-player\/visualizer-settings';\nimport { VolumeControl } from '@\/registry\/new-york\/components\/blocks\/music-player\/volume-control';\nimport { samplePlaylists } from '@\/registry\/new-york\/lib\/audio-context';\nimport type {\n    Track,\n    Playlist,\n    VisualizerStyle,\n} from '@\/registry\/new-york\/lib\/audio-context';\n\nexport function MusicPlayer() {\n    \/\/ Audio state\n    const audioRef = useRef<HTMLAudioElement>(null);\n    const audioContextRef = useRef<AudioContext | null>(null);\n    const analyserRef = useRef<AnalyserNode | null>(null);\n    const sourceRef = useRef<MediaElementAudioSourceNode | null>(null);\n\n    \/\/ Player state\n    const [isPlaying, setIsPlaying] = useState(false);\n    const [currentTime, setCurrentTime] = useState(0);\n    const [duration, setDuration] = useState(0);\n    const [volume, setVolume] = useState(0.7);\n    const [isShuffled, setIsShuffled] = useState(false);\n    const [repeatMode, setRepeatMode] = useState<'off' | 'all' | 'one'>('off');\n\n    \/\/ Track and playlist state\n    const [playlists, setPlaylists] = useState<Playlist[]>(samplePlaylists);\n    const [currentPlaylist, setCurrentPlaylist] = useState<Playlist | null>(\n        samplePlaylists[2],\n    );\n    const [currentTrackIndex, setCurrentTrackIndex] = useState(0);\n    const [favorites, setFavorites] = useState<Set<string>>(new Set());\n\n    \/\/ UI state\n    const [sidebarOpen, setSidebarOpen] = useState(false);\n    const [visualizerStyle, setVisualizerStyle] =\n        useState<VisualizerStyle>('bars');\n    const [, setIsAudioReady] = useState(false);\n    const [analyser, setAnalyser] = useState<AnalyserNode | null>(null);\n\n    \/\/ Shuffle indices\n    const shuffledIndices = useMemo(() => {\n        if (!currentPlaylist) {\n            return [];\n        }\n\n        const indices = Array.from(\n            { length: currentPlaylist.tracks.length },\n            (_, i) => i,\n        );\n\n        if (isShuffled) {\n            for (let i = indices.length - 1; i > 0; i--) {\n                \/\/ eslint-disable-next-line react-hooks\/purity\n                const j = Math.floor(Math.random() * (i + 1));\n                [indices[i], indices[j]] = [indices[j], indices[i]];\n            }\n        }\n\n        return indices;\n    }, [currentPlaylist, isShuffled]);\n\n    const currentTrack =\n        currentPlaylist?.tracks[\n            isShuffled\n                ? shuffledIndices[currentTrackIndex] || 0\n                : currentTrackIndex\n        ] || null;\n\n    const { primary: primaryColor, secondary: secondaryColor } =\n        useThemeColors();\n\n    \/\/ Initialize audio context\n    const initAudioContext = useCallback(() => {\n        if (!audioRef.current || audioContextRef.current) {\n            return;\n        }\n\n        try {\n            const audioContext = new (\n                window.AudioContext ||\n                (\n                    window as typeof window & {\n                        webkitAudioContext: typeof AudioContext;\n                    }\n                ).webkitAudioContext\n            )();\n            const analyser = audioContext.createAnalyser();\n            analyser.fftSize = 256;\n            analyser.smoothingTimeConstant = 0.8;\n\n            const source = audioContext.createMediaElementSource(\n                audioRef.current,\n            );\n            source.connect(analyser);\n            analyser.connect(audioContext.destination);\n\n            audioContextRef.current = audioContext;\n            analyserRef.current = analyser;\n            sourceRef.current = source;\n            setAnalyser(analyser);\n        } catch (error) {\n            console.log('[v0] Error initializing audio context:', error);\n        }\n    }, []);\n\n    \/\/ Navigation\n    const handleNext = useCallback(() => {\n        if (!currentPlaylist) {\n            return;\n        }\n\n        const maxIndex = currentPlaylist.tracks.length - 1;\n\n        if (currentTrackIndex < maxIndex) {\n            setCurrentTrackIndex(currentTrackIndex + 1);\n        } else if (repeatMode === 'all') {\n            setCurrentTrackIndex(0);\n        } else {\n            setIsPlaying(false);\n        }\n    }, [currentPlaylist, currentTrackIndex, repeatMode]);\n\n    const handlePrevious = () => {\n        if (!audioRef.current) {\n            return;\n        }\n\n        if (audioRef.current.currentTime > 3) {\n            audioRef.current.currentTime = 0;\n        } else if (currentTrackIndex > 0) {\n            setCurrentTrackIndex(currentTrackIndex - 1);\n        }\n    };\n\n    \/\/ Audio event handlers\n    useEffect(() => {\n        const audio = audioRef.current;\n\n        if (!audio) {\n            return;\n        }\n\n        const handleTimeUpdate = () => setCurrentTime(audio.currentTime);\n        const handleDurationChange = () => setDuration(audio.duration || 0);\n        const handleEnded = () => {\n            if (repeatMode === 'one') {\n                audio.currentTime = 0;\n                audio.play();\n            } else {\n                handleNext();\n            }\n        };\n        const handleCanPlay = () => setIsAudioReady(true);\n\n        audio.addEventListener('timeupdate', handleTimeUpdate);\n        audio.addEventListener('durationchange', handleDurationChange);\n        audio.addEventListener('ended', handleEnded);\n        audio.addEventListener('canplay', handleCanPlay);\n\n        return () => {\n            audio.removeEventListener('timeupdate', handleTimeUpdate);\n            audio.removeEventListener('durationchange', handleDurationChange);\n            audio.removeEventListener('ended', handleEnded);\n            audio.removeEventListener('canplay', handleCanPlay);\n        };\n    }, [repeatMode, handleNext]);\n\n    \/\/ Volume control\n    useEffect(() => {\n        if (audioRef.current) {\n            audioRef.current.volume = volume;\n        }\n    }, [volume]);\n\n    \/\/ Play\/Pause\n    const handlePlayPause = async () => {\n        if (!audioRef.current || !currentTrack) {\n            return;\n        }\n\n        if (!audioContextRef.current) {\n            initAudioContext();\n        }\n\n        if (audioContextRef.current?.state === 'suspended') {\n            await audioContextRef.current.resume();\n        }\n\n        if (isPlaying) {\n            audioRef.current.pause();\n        } else {\n            try {\n                await audioRef.current.play();\n            } catch (error) {\n                console.log('[v0] Playback error:', error);\n            }\n        }\n\n        setIsPlaying(!isPlaying);\n    };\n\n    \/\/ Seek\n    const handleSeek = (time: number) => {\n        if (audioRef.current) {\n            audioRef.current.currentTime = time;\n        }\n    };\n\n    \/\/ Toggle controls\n    const handleShuffle = () => setIsShuffled(!isShuffled);\n    const handleRepeat = () => {\n        const modes: ('off' | 'all' | 'one')[] = ['off', 'all', 'one'];\n        const currentIndex = modes.indexOf(repeatMode);\n        setRepeatMode(modes[(currentIndex + 1) % modes.length]);\n    };\n\n    const handleToggleFavorite = () => {\n        if (!currentTrack) {\n            return;\n        }\n\n        const newFavorites = new Set(favorites);\n\n        if (newFavorites.has(currentTrack.id)) {\n            newFavorites.delete(currentTrack.id);\n        } else {\n            newFavorites.add(currentTrack.id);\n        }\n\n        setFavorites(newFavorites);\n    };\n\n    \/\/ Playlist management\n    const handleSelectPlaylist = (playlist: Playlist) => {\n        setCurrentPlaylist(playlist);\n        setCurrentTrackIndex(0);\n        setIsPlaying(false);\n    };\n\n    const handleSelectTrack = (track: Track, playlist: Playlist) => {\n        if (currentPlaylist?.id !== playlist.id) {\n            setCurrentPlaylist(playlist);\n        }\n\n        const index = playlist.tracks.findIndex((t) => t.id === track.id);\n        setCurrentTrackIndex(index >= 0 ? index : 0);\n        setIsPlaying(true);\n    };\n\n    const handleCreatePlaylist = (name: string) => {\n        const newPlaylist: Playlist = {\n            id: Date.now().toString(),\n            name,\n            tracks: [],\n        };\n        setPlaylists([...playlists, newPlaylist]);\n    };\n\n    \/\/ Auto-play when track changes\n    useEffect(() => {\n        if (audioRef.current && isPlaying && currentTrack) {\n            audioRef.current.load();\n\n            if (!audioContextRef.current) {\n                initAudioContext();\n            }\n\n            (async () => {\n                if (audioContextRef.current?.state === 'suspended') {\n                    try {\n                        await audioContextRef.current.resume();\n                    } catch (e) {\n                        console.log('[v0] Resume failed:', e);\n                    }\n                }\n\n                try {\n                    await audioRef.current?.play();\n                } catch (e) {\n                    console.error(e);\n                }\n            })();\n        }\n    }, [currentTrack, isPlaying, initAudioContext]);\n\n    const currentAnalyser = isPlaying ? analyser : null;\n\n    return (\n        <div className=\"@container flex h-screen bg-background\">\n            {\/* Hidden audio element *\/}\n            <audio ref={audioRef} src={currentTrack?.src} preload=\"metadata\" \/>\n\n            {\/* Playlist Sidebar *\/}\n            <PlaylistSidebar\n                playlists={playlists}\n                currentPlaylist={currentPlaylist}\n                currentTrack={currentTrack}\n                onSelectPlaylist={handleSelectPlaylist}\n                onSelectTrack={handleSelectTrack}\n                onCreatePlaylist={handleCreatePlaylist}\n                isOpen={sidebarOpen}\n                onClose={() => setSidebarOpen(false)}\n            \/>\n\n            {\/* Main content *\/}\n            <main className=\"flex flex-1 flex-col overflow-hidden\">\n                {\/* Header *\/}\n                <header className=\"flex items-center justify-between border-b border-border p-4\">\n                    <div className=\"flex items-center gap-4\">\n                        <Button\n                            variant=\"ghost\"\n                            size=\"icon\"\n                            onClick={() => setSidebarOpen(true)}\n                            className=\"text-muted-foreground hover:text-foreground @lg:hidden\"\n                            aria-label=\"Open playlist\"\n                        >\n                            <Menu className=\"h-5 w-5\" \/>\n                        <\/Button>\n                        <h1 className=\"text-xl font-bold text-foreground\">\n                            Sonic<span className=\"text-primary\">Wave<\/span>\n                        <\/h1>\n                    <\/div>\n\n                    <div className=\"flex items-center gap-2\">\n                        <VisualizerSettings\n                            currentStyle={visualizerStyle}\n                            onStyleChange={setVisualizerStyle}\n                        \/>\n                        <Button\n                            variant=\"ghost\"\n                            size=\"icon\"\n                            onClick={() => setSidebarOpen(!sidebarOpen)}\n                            className=\"hidden text-muted-foreground hover:text-foreground @lg:flex\"\n                            aria-label=\"Toggle playlist\"\n                        >\n                            <ListMusic className=\"h-5 w-5\" \/>\n                        <\/Button>\n                    <\/div>\n                <\/header>\n\n                {\/* Visualization area with background *\/}\n                <div className=\"relative flex-1 overflow-hidden\">\n                    {\/* Dynamic background based on album art *\/}\n                    {currentTrack?.coverUrl && (\n                        <div className=\"absolute inset-0\">\n                            <img\n                                src={currentTrack.coverUrl}\n                                alt=\"\"\n                                className=\"absolute inset-0 scale-110 object-cover opacity-30 blur-3xl\"\n                            \/>\n                            <div className=\"absolute inset-0 bg-gradient-to-t from-background via-background\/80 to-background\/40\" \/>\n                        <\/div>\n                    )}\n\n                    {\/* Visualizer *\/}\n                    <div className=\"absolute inset-0 flex items-center justify-center p-8\">\n                        <div className=\"h-full max-h-96 w-full max-w-4xl\">\n                            <AudioVisualizer\n                                analyser={currentAnalyser}\n                                isPlaying={isPlaying}\n                                style={visualizerStyle}\n                                primaryColor={primaryColor}\n                                secondaryColor={secondaryColor}\n                            \/>\n                        <\/div>\n                    <\/div>\n\n                    {\/* Current album art (centered) *\/}\n                    {currentTrack?.coverUrl && (\n                        <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n                            <div className=\"relative h-32 w-32 overflow-hidden rounded-2xl shadow-2xl shadow-primary\/20 @md:h-48 @md:w-48 @lg:h-56 @lg:w-56\">\n                                <img\n                                    src={currentTrack.coverUrl}\n                                    alt={`${currentTrack.album} cover`}\n                                    className=\"absolute inset-0 object-cover\"\n                                \/>\n                                <div className=\"absolute inset-0 bg-gradient-to-t from-background\/60 to-transparent\" \/>\n                            <\/div>\n                        <\/div>\n                    )}\n                <\/div>\n\n                {\/* Player controls *\/}\n                <div className=\"border-t border-border bg-card\/80 backdrop-blur-lg\">\n                    <div className=\"mx-auto max-w-4xl space-y-4 p-4 @md:p-6\">\n                        {\/* Track info *\/}\n                        <TrackInfo\n                            track={currentTrack}\n                            isFavorite={\n                                currentTrack\n                                    ? favorites.has(currentTrack.id)\n                                    : false\n                            }\n                            onToggleFavorite={handleToggleFavorite}\n                        \/>\n\n                        {\/* Progress bar *\/}\n                        <ProgressBar\n                            currentTime={currentTime}\n                            duration={duration}\n                            onSeek={handleSeek}\n                        \/>\n\n                        {\/* Controls row *\/}\n                        <div className=\"flex flex-col items-center justify-between gap-4 @md:flex-row\">\n                            <div className=\"flex w-full justify-center @md:block @md:flex-1\">\n                                <VolumeControl\n                                    volume={volume}\n                                    onVolumeChange={setVolume}\n                                \/>\n                            <\/div>\n\n                            <PlayerControls\n                                isPlaying={isPlaying}\n                                onPlayPause={handlePlayPause}\n                                onPrevious={handlePrevious}\n                                onNext={handleNext}\n                                onShuffle={handleShuffle}\n                                onRepeat={handleRepeat}\n                                isShuffled={isShuffled}\n                                repeatMode={repeatMode}\n                                disabled={!currentTrack}\n                            \/>\n\n                            <div className=\"hidden flex-1 @md:block\" \/>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/main>\n        <\/div>\n    );\n}\n"},{"path":"resources\/js\/registry\/new-york\/components\/blocks\/music-player\/player-controls.tsx","type":"registry:block","content":"'use client';\n\nimport {\n    Play,\n    Pause,\n    SkipBack,\n    SkipForward,\n    Shuffle,\n    Repeat,\n    Repeat1,\n} from 'lucide-react';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\ninterface PlayerControlsProps {\n    isPlaying: boolean;\n    onPlayPause: () => void;\n    onPrevious: () => void;\n    onNext: () => void;\n    onShuffle: () => void;\n    onRepeat: () => void;\n    isShuffled: boolean;\n    repeatMode: 'off' | 'all' | 'one';\n    disabled?: boolean;\n}\n\nexport function PlayerControls({\n    isPlaying,\n    onPlayPause,\n    onPrevious,\n    onNext,\n    onShuffle,\n    onRepeat,\n    isShuffled,\n    repeatMode,\n    disabled = false,\n}: PlayerControlsProps) {\n    return (\n        <div className=\"flex items-center justify-center gap-1 @md:gap-4\">\n            <Button\n                variant=\"ghost\"\n                size=\"icon\"\n                onClick={onShuffle}\n                disabled={disabled}\n                className={cn(\n                    'h-8 w-8 @md:h-10 @md:w-10',\n                    isShuffled\n                        ? 'text-primary'\n                        : 'text-muted-foreground hover:text-foreground',\n                )}\n                aria-label=\"Shuffle\"\n            >\n                <Shuffle className=\"h-3 w-3 @md:h-5 @md:w-5\" \/>\n            <\/Button>\n\n            <Button\n                variant=\"ghost\"\n                size=\"icon\"\n                onClick={onPrevious}\n                disabled={disabled}\n                className=\"h-9 w-9 text-foreground hover:text-primary @md:h-12 @md:w-12\"\n                aria-label=\"Previous track\"\n            >\n                <SkipBack className=\"h-4 w-4 @md:h-6 @md:w-6\" \/>\n            <\/Button>\n\n            <Button\n                onClick={onPlayPause}\n                disabled={disabled}\n                className={cn(\n                    'h-12 w-12 rounded-full @md:h-16 @md:w-16',\n                    'bg-primary text-primary-foreground hover:bg-primary\/90',\n                    'shadow-lg shadow-primary\/25 transition-all',\n                    'hover:scale-105 active:scale-95',\n                )}\n                aria-label={isPlaying ? 'Pause' : 'Play'}\n            >\n                {isPlaying ? (\n                    <Pause className=\"h-5 w-5 @md:h-7 @md:w-7\" \/>\n                ) : (\n                    <Play className=\"ml-0.5 h-5 w-5 @md:h-7 @md:w-7\" \/>\n                )}\n            <\/Button>\n\n            <Button\n                variant=\"ghost\"\n                size=\"icon\"\n                onClick={onNext}\n                disabled={disabled}\n                className=\"h-9 w-9 text-foreground hover:text-primary @md:h-12 @md:w-12\"\n                aria-label=\"Next track\"\n            >\n                <SkipForward className=\"h-4 w-4 @md:h-6 @md:w-6\" \/>\n            <\/Button>\n\n            <Button\n                variant=\"ghost\"\n                size=\"icon\"\n                onClick={onRepeat}\n                disabled={disabled}\n                className={cn(\n                    'h-8 w-8 @md:h-10 @md:w-10',\n                    repeatMode !== 'off'\n                        ? 'text-primary'\n                        : 'text-muted-foreground hover:text-foreground',\n                )}\n                aria-label=\"Repeat\"\n            >\n                {repeatMode === 'one' ? (\n                    <Repeat1 className=\"h-3 w-3 @md:h-5 @md:w-5\" \/>\n                ) : (\n                    <Repeat className=\"h-3 w-3 @md:h-5 @md:w-5\" \/>\n                )}\n            <\/Button>\n        <\/div>\n    );\n}\n"},{"path":"resources\/js\/registry\/new-york\/components\/blocks\/music-player\/playlist-sidebar.tsx","type":"registry:block","content":"'use client';\n\nimport { Plus, Music, ChevronRight, X, Play } from 'lucide-react';\nimport { useState } from 'react';\nimport { Button } from '@\/components\/ui\/button';\nimport { Input } from '@\/components\/ui\/input';\nimport { cn } from '@\/lib\/utils';\nimport type { Playlist, Track } from '@\/registry\/new-york\/lib\/audio-context';\nimport { formatTime } from '@\/registry\/new-york\/lib\/audio-context';\n\ninterface PlaylistSidebarProps {\n    playlists: Playlist[];\n    currentPlaylist: Playlist | null;\n    currentTrack: Track | null;\n    onSelectPlaylist: (playlist: Playlist) => void;\n    onSelectTrack: (track: Track, playlist: Playlist) => void;\n    onCreatePlaylist: (name: string) => void;\n    isOpen: boolean;\n    onClose: () => void;\n}\n\nexport function PlaylistSidebar({\n    playlists,\n    currentPlaylist,\n    currentTrack,\n    onSelectPlaylist,\n    onSelectTrack,\n    onCreatePlaylist,\n    isOpen,\n    onClose,\n}: PlaylistSidebarProps) {\n    const [isCreating, setIsCreating] = useState(false);\n    const [newPlaylistName, setNewPlaylistName] = useState('');\n    const [expandedPlaylist, setExpandedPlaylist] = useState<string | null>(\n        null,\n    );\n\n    const handleCreatePlaylist = () => {\n        if (newPlaylistName.trim()) {\n            onCreatePlaylist(newPlaylistName.trim());\n            setNewPlaylistName('');\n            setIsCreating(false);\n        }\n    };\n\n    const toggleExpand = (playlistId: string) => {\n        setExpandedPlaylist(\n            expandedPlaylist === playlistId ? null : playlistId,\n        );\n    };\n\n    return (\n        <>\n            {\/* Backdrop *\/}\n            {isOpen && (\n                <div\n                    className=\"fixed inset-0 z-40 bg-background\/80 backdrop-blur-sm @lg:hidden\"\n                    onClick={onClose}\n                \/>\n            )}\n\n            {\/* Sidebar *\/}\n            <aside\n                className={cn(\n                    'fixed top-0 left-0 z-50 h-full w-80 border-r border-border bg-card @lg:relative',\n                    'transform transition-transform duration-300 ease-in-out',\n                    isOpen\n                        ? 'translate-x-0'\n                        : '-translate-x-full @lg:translate-x-0',\n                )}\n            >\n                <div className=\"flex h-full flex-col\">\n                    {\/* Header *\/}\n                    <div className=\"flex items-center justify-between border-b border-border p-4\">\n                        <h2 className=\"text-lg font-semibold text-foreground\">\n                            Playlists\n                        <\/h2>\n                        <div className=\"flex items-center gap-2\">\n                            <Button\n                                variant=\"ghost\"\n                                size=\"icon\"\n                                onClick={() => setIsCreating(true)}\n                                className=\"text-muted-foreground hover:text-foreground\"\n                                aria-label=\"Create playlist\"\n                            >\n                                <Plus className=\"h-5 w-5\" \/>\n                            <\/Button>\n                            <Button\n                                variant=\"ghost\"\n                                size=\"icon\"\n                                onClick={onClose}\n                                className=\"text-muted-foreground hover:text-foreground @lg:hidden\"\n                                aria-label=\"Close sidebar\"\n                            >\n                                <X className=\"h-5 w-5\" \/>\n                            <\/Button>\n                        <\/div>\n                    <\/div>\n\n                    {\/* Create playlist form *\/}\n                    {isCreating && (\n                        <div className=\"border-b border-border p-4\">\n                            <Input\n                                type=\"text\"\n                                placeholder=\"Playlist name...\"\n                                value={newPlaylistName}\n                                onChange={(e) =>\n                                    setNewPlaylistName(e.target.value)\n                                }\n                                onKeyDown={(e) =>\n                                    e.key === 'Enter' && handleCreatePlaylist()\n                                }\n                                className=\"mb-2\"\n                                autoFocus\n                            \/>\n                            <div className=\"flex gap-2\">\n                                <Button\n                                    size=\"sm\"\n                                    onClick={handleCreatePlaylist}\n                                    className=\"flex-1\"\n                                >\n                                    Create\n                                <\/Button>\n                                <Button\n                                    size=\"sm\"\n                                    variant=\"outline\"\n                                    onClick={() => {\n                                        setIsCreating(false);\n                                        setNewPlaylistName('');\n                                    }}\n                                >\n                                    Cancel\n                                <\/Button>\n                            <\/div>\n                        <\/div>\n                    )}\n\n                    {\/* Playlist list *\/}\n                    <div className=\"flex-1 overflow-y-auto\">\n                        {playlists.map((playlist) => (\n                            <div\n                                key={playlist.id}\n                                className=\"border-b border-border\/50\"\n                            >\n                                <button\n                                    onClick={() => {\n                                        onSelectPlaylist(playlist);\n                                        toggleExpand(playlist.id);\n                                    }}\n                                    className={cn(\n                                        'flex w-full items-center gap-3 p-4 transition-colors hover:bg-muted\/50',\n                                        currentPlaylist?.id === playlist.id &&\n                                            'bg-muted',\n                                    )}\n                                >\n                                    <div className=\"relative h-12 w-12 flex-shrink-0 overflow-hidden rounded-lg bg-muted\">\n                                        {playlist.coverUrl ? (\n                                            <img\n                                                src={playlist.coverUrl}\n                                                alt={playlist.name}\n                                                className=\"absolute inset-0 object-cover\"\n                                            \/>\n                                        ) : (\n                                            <div className=\"flex h-full w-full items-center justify-center bg-gradient-to-br from-primary\/50 to-primary\/20\">\n                                                <Music className=\"h-6 w-6 text-primary\" \/>\n                                            <\/div>\n                                        )}\n                                    <\/div>\n\n                                    <div className=\"min-w-0 flex-1 text-left\">\n                                        <p className=\"truncate font-medium text-foreground\">\n                                            {playlist.name}\n                                        <\/p>\n                                        <p className=\"text-xs text-muted-foreground\">\n                                            {playlist.tracks.length} tracks\n                                        <\/p>\n                                    <\/div>\n\n                                    <ChevronRight\n                                        className={cn(\n                                            'h-5 w-5 text-muted-foreground transition-transform',\n                                            expandedPlaylist === playlist.id &&\n                                                'rotate-90',\n                                        )}\n                                    \/>\n                                <\/button>\n\n                                {\/* Expanded track list *\/}\n                                {expandedPlaylist === playlist.id && (\n                                    <div className=\"bg-muted\/30\">\n                                        {playlist.tracks.map((track, index) => (\n                                            <button\n                                                key={track.id}\n                                                onClick={() =>\n                                                    onSelectTrack(\n                                                        track,\n                                                        playlist,\n                                                    )\n                                                }\n                                                className={cn(\n                                                    'flex w-full items-center gap-3 px-4 py-2 transition-colors hover:bg-muted\/50',\n                                                    currentTrack?.id ===\n                                                        track.id &&\n                                                        'bg-primary\/10',\n                                                )}\n                                            >\n                                                <span className=\"w-6 text-center text-xs text-muted-foreground\">\n                                                    {currentTrack?.id ===\n                                                    track.id ? (\n                                                        <Play className=\"mx-auto h-3 w-3 fill-primary text-primary\" \/>\n                                                    ) : (\n                                                        index + 1\n                                                    )}\n                                                <\/span>\n                                                <div className=\"min-w-0 flex-1 text-left\">\n                                                    <p\n                                                        className={cn(\n                                                            'truncate text-sm',\n                                                            currentTrack?.id ===\n                                                                track.id\n                                                                ? 'text-primary'\n                                                                : 'text-foreground',\n                                                        )}\n                                                    >\n                                                        {track.title}\n                                                    <\/p>\n                                                    <p className=\"truncate text-xs text-muted-foreground\">\n                                                        {track.artist}\n                                                    <\/p>\n                                                <\/div>\n                                                <span className=\"text-xs text-muted-foreground\">\n                                                    {formatTime(track.duration)}\n                                                <\/span>\n                                            <\/button>\n                                        ))}\n                                    <\/div>\n                                )}\n                            <\/div>\n                        ))}\n                    <\/div>\n                <\/div>\n            <\/aside>\n        <\/>\n    );\n}\n"},{"path":"resources\/js\/registry\/new-york\/components\/blocks\/music-player\/progress-bar.tsx","type":"registry:block","content":"'use client';\n\nimport { useRef, useState, useCallback } from 'react';\nimport { formatTime } from '@\/registry\/new-york\/lib\/audio-context';\n\ninterface ProgressBarProps {\n    currentTime: number;\n    duration: number;\n    onSeek: (time: number) => void;\n}\n\nexport function ProgressBar({\n    currentTime,\n    duration,\n    onSeek,\n}: ProgressBarProps) {\n    const progressRef = useRef<HTMLDivElement>(null);\n    const [isDragging, setIsDragging] = useState(false);\n    const [hoverPosition, setHoverPosition] = useState<number | null>(null);\n\n    const calculatePosition = useCallback((clientX: number): number => {\n        if (!progressRef.current) {\n            return 0;\n        }\n\n        const rect = progressRef.current.getBoundingClientRect();\n        const position = (clientX - rect.left) \/ rect.width;\n\n        return Math.max(0, Math.min(1, position));\n    }, []);\n\n    const handleMouseDown = (e: React.MouseEvent) => {\n        setIsDragging(true);\n        const position = calculatePosition(e.clientX);\n        onSeek(position * duration);\n    };\n\n    const handleMouseMove = (e: React.MouseEvent) => {\n        const position = calculatePosition(e.clientX);\n        setHoverPosition(position);\n\n        if (isDragging) {\n            onSeek(position * duration);\n        }\n    };\n\n    const handleMouseUp = () => {\n        setIsDragging(false);\n    };\n\n    const handleMouseLeave = () => {\n        setHoverPosition(null);\n        setIsDragging(false);\n    };\n\n    const handleTouchStart = (e: React.TouchEvent) => {\n        const touch = e.touches[0];\n        const position = calculatePosition(touch.clientX);\n        onSeek(position * duration);\n        setIsDragging(true);\n    };\n\n    const handleTouchMove = (e: React.TouchEvent) => {\n        if (!isDragging) {\n            return;\n        }\n\n        const touch = e.touches[0];\n        const position = calculatePosition(touch.clientX);\n        onSeek(position * duration);\n    };\n\n    const handleTouchEnd = () => {\n        setIsDragging(false);\n    };\n\n    const progress = duration > 0 ? (currentTime \/ duration) * 100 : 0;\n\n    return (\n        <div className=\"w-full space-y-1\">\n            <div\n                ref={progressRef}\n                className=\"group relative h-2 cursor-pointer rounded-full bg-muted\"\n                onMouseDown={handleMouseDown}\n                onMouseMove={handleMouseMove}\n                onMouseUp={handleMouseUp}\n                onMouseLeave={handleMouseLeave}\n                onTouchStart={handleTouchStart}\n                onTouchMove={handleTouchMove}\n                onTouchEnd={handleTouchEnd}\n                role=\"slider\"\n                aria-valuemin={0}\n                aria-valuemax={duration}\n                aria-valuenow={currentTime}\n                aria-label=\"Seek\"\n                tabIndex={0}\n            >\n                {\/* Progress fill *\/}\n                <div\n                    className=\"absolute top-0 left-0 h-full rounded-full bg-primary transition-all\"\n                    style={{ width: `${progress}%` }}\n                \/>\n\n                {\/* Hover preview *\/}\n                {hoverPosition !== null && (\n                    <div\n                        className=\"absolute top-0 h-full rounded-full bg-foreground\/20\"\n                        style={{ width: `${hoverPosition * 100}%` }}\n                    \/>\n                )}\n\n                {\/* Thumb *\/}\n                <div\n                    className=\"absolute top-1\/2 h-4 w-4 -translate-y-1\/2 rounded-full bg-primary opacity-0 shadow-lg transition-opacity group-hover:opacity-100\"\n                    style={{ left: `calc(${progress}% - 8px)` }}\n                \/>\n\n                {\/* Hover time tooltip *\/}\n                {hoverPosition !== null && (\n                    <div\n                        className=\"absolute -top-8 rounded bg-card px-2 py-1 text-xs text-foreground shadow-lg\"\n                        style={{ left: `calc(${hoverPosition * 100}% - 20px)` }}\n                    >\n                        {formatTime(hoverPosition * duration)}\n                    <\/div>\n                )}\n            <\/div>\n\n            <div className=\"flex justify-between text-xs text-muted-foreground\">\n                <span>{formatTime(currentTime)}<\/span>\n                <span>{formatTime(duration)}<\/span>\n            <\/div>\n        <\/div>\n    );\n}\n"},{"path":"resources\/js\/registry\/new-york\/components\/blocks\/music-player\/track-info.tsx","type":"registry:block","content":"'use client';\n\nimport { Heart } from 'lucide-react';\n\nimport { cn } from '@\/lib\/utils';\nimport type { Track } from '@\/registry\/new-york\/lib\/audio-context';\n\ninterface TrackInfoProps {\n    track: Track | null;\n    isFavorite: boolean;\n    onToggleFavorite: () => void;\n}\n\nexport function TrackInfo({\n    track,\n    isFavorite,\n    onToggleFavorite,\n}: TrackInfoProps) {\n    if (!track) {\n        return (\n            <div className=\"flex items-center gap-4\">\n                <div className=\"h-16 w-16 animate-pulse rounded-lg bg-muted\" \/>\n                <div className=\"space-y-2\">\n                    <div className=\"h-4 w-32 animate-pulse rounded bg-muted\" \/>\n                    <div className=\"h-3 w-24 animate-pulse rounded bg-muted\" \/>\n                <\/div>\n            <\/div>\n        );\n    }\n\n    return (\n        <div className=\"flex items-center gap-4\">\n            <div className=\"group relative h-16 w-16 overflow-hidden rounded-lg shadow-lg @md:h-20 @md:w-20\">\n                {track.coverUrl ? (\n                    <img\n                        src={track.coverUrl}\n                        alt={`${track.album} cover`}\n                        className=\"object-cover transition-transform group-hover:scale-110\"\n                        crossOrigin=\"anonymous\"\n                    \/>\n                ) : (\n                    <div className=\"flex h-full w-full items-center justify-center bg-gradient-to-br from-primary to-primary\/50\">\n                        <span className=\"text-2xl font-bold text-primary-foreground\">\n                            {track.title[0]}\n                        <\/span>\n                    <\/div>\n                )}\n            <\/div>\n\n            <div className=\"min-w-0 flex-1\">\n                <h3 className=\"truncate text-sm font-semibold text-foreground @md:text-base\">\n                    {track.title}\n                <\/h3>\n                <p className=\"truncate text-xs text-muted-foreground @md:text-sm\">\n                    {track.artist}\n                <\/p>\n                <p className=\"truncate text-xs text-muted-foreground\/70\">\n                    {track.album}\n                <\/p>\n            <\/div>\n\n            <button\n                onClick={onToggleFavorite}\n                className=\"rounded-full p-2 transition-colors hover:bg-muted\"\n                aria-label={\n                    isFavorite ? 'Remove from favorites' : 'Add to favorites'\n                }\n            >\n                <Heart\n                    className={cn(\n                        'h-5 w-5 transition-all',\n                        isFavorite\n                            ? 'scale-110 fill-primary text-primary'\n                            : 'text-muted-foreground hover:text-primary',\n                    )}\n                \/>\n            <\/button>\n        <\/div>\n    );\n}\n"},{"path":"resources\/js\/registry\/new-york\/components\/blocks\/music-player\/visualizer-settings.tsx","type":"registry:block","content":"'use client';\n\nimport { Settings, Waves, BarChart3, Circle, Sparkles } from 'lucide-react';\nimport { Button } from '@\/components\/ui\/button';\nimport {\n    Popover,\n    PopoverContent,\n    PopoverTrigger,\n} from '@\/components\/ui\/popover';\nimport { cn } from '@\/lib\/utils';\nimport type { VisualizerStyle } from '@\/registry\/new-york\/lib\/audio-context';\n\ninterface VisualizerSettingsProps {\n    currentStyle: VisualizerStyle;\n    onStyleChange: (style: VisualizerStyle) => void;\n}\n\nconst visualizerOptions: {\n    style: VisualizerStyle;\n    label: string;\n    icon: React.ReactNode;\n}[] = [\n    { style: 'bars', label: 'Bars', icon: <BarChart3 className=\"size-4\" \/> },\n    { style: 'wave', label: 'Wave', icon: <Waves className=\"size-4\" \/> },\n    {\n        style: 'circular',\n        label: 'Circular',\n        icon: <Circle className=\"size-4\" \/>,\n    },\n    {\n        style: 'particles',\n        label: 'Particles',\n        icon: <Sparkles className=\"size-4\" \/>,\n    },\n];\n\nexport function VisualizerSettings({\n    currentStyle,\n    onStyleChange,\n}: VisualizerSettingsProps) {\n    return (\n        <Popover>\n            <PopoverTrigger asChild>\n                <Button\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className=\"size-9 text-muted-foreground hover:text-foreground\"\n                    aria-label=\"Visualizer settings\"\n                >\n                    <Settings className=\"size-5\" \/>\n                <\/Button>\n            <\/PopoverTrigger>\n            <PopoverContent className=\"w-64\" align=\"end\">\n                <div className=\"space-y-2\">\n                    <h4 className=\"text-sm font-medium text-foreground\">\n                        Visualizer Style\n                    <\/h4>\n                    <div className=\"grid grid-cols-2 gap-2\">\n                        {visualizerOptions.map((option) => (\n                            <Button\n                                key={option.style}\n                                variant=\"outline\"\n                                size=\"sm\"\n                                onClick={() => onStyleChange(option.style)}\n                                className={cn(\n                                    'justify-start gap-2',\n                                    currentStyle === option.style &&\n                                        'border-primary bg-primary text-primary-foreground hover:bg-primary\/90 hover:text-primary-foreground',\n                                )}\n                            >\n                                {option.icon}\n                                {option.label}\n                            <\/Button>\n                        ))}\n                    <\/div>\n                <\/div>\n            <\/PopoverContent>\n        <\/Popover>\n    );\n}\n"},{"path":"resources\/js\/registry\/new-york\/components\/blocks\/music-player\/volume-control.tsx","type":"registry:block","content":"'use client';\n\nimport { Volume2, Volume1, VolumeX } from 'lucide-react';\nimport { useState } from 'react';\nimport { Button } from '@\/components\/ui\/button';\n\ninterface VolumeControlProps {\n    volume: number;\n    onVolumeChange: (volume: number) => void;\n}\n\nexport function VolumeControl({ volume, onVolumeChange }: VolumeControlProps) {\n    const [previousVolume, setPreviousVolume] = useState(volume);\n    const [isHovered, setIsHovered] = useState(false);\n\n    const toggleMute = () => {\n        if (volume > 0) {\n            setPreviousVolume(volume);\n            onVolumeChange(0);\n        } else {\n            onVolumeChange(previousVolume || 0.7);\n        }\n    };\n\n    const VolumeIcon =\n        volume === 0 ? VolumeX : volume < 0.5 ? Volume1 : Volume2;\n\n    return (\n        <div\n            className=\"group flex items-center gap-2\"\n            onMouseEnter={() => setIsHovered(true)}\n            onMouseLeave={() => setIsHovered(false)}\n        >\n            <Button\n                variant=\"ghost\"\n                size=\"icon\"\n                onClick={toggleMute}\n                className=\"h-9 w-9 text-muted-foreground hover:text-foreground\"\n                aria-label={volume === 0 ? 'Unmute' : 'Mute'}\n            >\n                <VolumeIcon className=\"h-5 w-5\" \/>\n            <\/Button>\n\n            <div\n                className={`overflow-hidden transition-all duration-200 ${isHovered ? 'w-24 opacity-100' : 'w-0 opacity-0 @md:w-24 @md:opacity-100'} `}\n            >\n                <input\n                    type=\"range\"\n                    min={0}\n                    max={1}\n                    step={0.01}\n                    value={volume}\n                    onChange={(e) => onVolumeChange(parseFloat(e.target.value))}\n                    className=\"h-2 w-full cursor-pointer appearance-none rounded-lg bg-muted accent-primary\"\n                    style={{\n                        background: `linear-gradient(to right, var(--primary) ${volume * 100}%, var(--muted) ${volume * 100}%)`,\n                    }}\n                    aria-label=\"Volume\"\n                \/>\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"media","version":"1.0.0"},"categories":["media"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"newsletter-box","type":"registry:block","title":"Newsletter Box","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["card","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/newsletter-box\/newsletter-box.tsx","type":"registry:block","content":"'use client';\n\nimport React, { useState } from 'react';\nimport { Mail, CheckCircle } from 'lucide-react';\nimport {\n    Card,\n    CardHeader,\n    CardTitle,\n    CardDescription,\n    CardContent,\n} from '@\/components\/ui\/card';\nimport { Button } from '@\/components\/ui\/button';\n\nexport function NewsletterBox() {\n    const [email, setEmail] = useState('');\n    const [submitted, setSubmitted] = useState(false);\n\n    const handleSubmit = (e: React.FormEvent) => {\n        e.preventDefault();\n        if (email) {\n            setSubmitted(true);\n        }\n    };\n\n    return (\n        <Card className=\"mx-auto w-full max-w-md border-border\/50 bg-card\/30 backdrop-blur-xs\">\n            <CardHeader className=\"pb-2 text-center\">\n                <div className=\"mx-auto mb-2 flex size-10 items-center justify-center rounded-full bg-primary\/10 text-primary\">\n                    <Mail className=\"size-5\" \/>\n                <\/div>\n                <CardTitle className=\"text-base font-bold\">\n                    Subscribe to Newsletter\n                <\/CardTitle>\n                <CardDescription className=\"text-xs\">\n                    Get the latest registry updates and components direct to\n                    your inbox.\n                <\/CardDescription>\n            <\/CardHeader>\n            <CardContent className=\"pt-2\">\n                {submitted ? (\n                    <div className=\"space-y-2 rounded-lg border border-primary\/20 bg-primary\/10 p-4 text-center\">\n                        <CheckCircle className=\"mx-auto size-5 text-primary\" \/>\n                        <h4 className=\"text-xs font-bold text-foreground\">\n                            Subscription Confirmed!\n                        <\/h4>\n                        <p className=\"text-[10px] text-muted-foreground\">\n                            Thank you for subscribing. We will keep you updated.\n                        <\/p>\n                    <\/div>\n                ) : (\n                    <form onSubmit={handleSubmit} className=\"space-y-3\">\n                        <input\n                            type=\"email\"\n                            required\n                            placeholder=\"Enter your email address\"\n                            value={email}\n                            onChange={(e) => setEmail(e.target.value)}\n                            className=\"h-9 w-full rounded-[var(--radius)] border border-border\/60 bg-muted\/40 px-3 text-xs text-foreground focus:ring-1 focus:ring-primary focus:outline-hidden\"\n                        \/>\n                        <Button\n                            type=\"submit\"\n                            size=\"sm\"\n                            className=\"h-9 w-full text-xs font-bold\"\n                        >\n                            Subscribe\n                        <\/Button>\n                        <p className=\"text-center text-[9px] text-muted-foreground\/80\">\n                            We value your privacy. Unsubscribe at any time.\n                        <\/p>\n                    <\/form>\n                )}\n            <\/CardContent>\n        <\/Card>\n    );\n}\n\nexport default NewsletterBox;\n"}],"meta":{"category":"newsletter-box","version":"1.0.0"},"categories":["newsletter-box"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"pricing-comparison","type":"registry:block","title":"Pricing Comparison","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","badge","table","switch"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/pricing-comparison\/pricing-comparison.tsx","type":"registry:block","content":"'use client';\n\nimport React, { useState } from 'react';\nimport { Check, X, Minus } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Badge } from '@\/components\/ui\/badge';\nimport {\n    Table,\n    TableBody,\n    TableCell,\n    TableHead,\n    TableHeader,\n    TableRow,\n} from '@\/components\/ui\/table';\nimport { Switch } from '@\/components\/ui\/switch';\n\ninterface ComparisonFeature {\n    name: string;\n    description?: string;\n    hobby: React.ReactNode;\n    pro: React.ReactNode;\n    enterprise: React.ReactNode;\n}\n\ninterface FeatureSection {\n    category: string;\n    features: ComparisonFeature[];\n}\n\nconst comparisonData: FeatureSection[] = [\n    {\n        category: 'Workspace & Projects',\n        features: [\n            {\n                name: 'Active Projects',\n                hobby: 'Up to 3',\n                pro: 'Unlimited',\n                enterprise: 'Unlimited (Isolated Node)',\n            },\n            {\n                name: 'Monthly bandwidth',\n                hobby: '10GB',\n                pro: '100GB',\n                enterprise: 'Unlimited',\n            },\n            {\n                name: 'SSD Storage',\n                hobby: '5GB',\n                pro: '50GB',\n                enterprise: 'Custom Capacity',\n            },\n            {\n                name: 'Team Collaboration Seats',\n                hobby: '1 seat',\n                pro: 'Up to 5 seats',\n                enterprise: 'Infinite',\n            },\n        ],\n    },\n    {\n        category: 'Metrics & Observability',\n        features: [\n            {\n                name: 'Telemetry resolution',\n                hobby: '5 mins',\n                pro: 'Realtime (1s)',\n                enterprise: 'Realtime (sub-second)',\n            },\n            {\n                name: 'Log Retention',\n                hobby: '7 days',\n                pro: '30 days',\n                enterprise: '365 days',\n            },\n            {\n                name: 'Custom Alert Triggers',\n                hobby: <Minus className=\"size-4 text-muted-foreground\" \/>,\n                pro: <Check className=\"size-4 text-primary\" \/>,\n                enterprise: <Check className=\"size-4 text-primary\" \/>,\n            },\n            {\n                name: 'Grafana & Datadog exports',\n                hobby: <X className=\"size-4 text-destructive\" \/>,\n                pro: <Check className=\"size-4 text-primary\" \/>,\n                enterprise: <Check className=\"size-4 text-primary\" \/>,\n            },\n        ],\n    },\n    {\n        category: 'Security & SLA',\n        features: [\n            {\n                name: 'Weekly vulnerability scans',\n                hobby: <Check className=\"size-4 text-primary\" \/>,\n                pro: <Check className=\"size-4 text-primary\" \/>,\n                enterprise: <Check className=\"size-4 text-primary\" \/>,\n            },\n            {\n                name: 'SAML \/ SSO Authentications',\n                hobby: <X className=\"size-4 text-destructive\" \/>,\n                pro: <Minus className=\"size-4 text-muted-foreground\" \/>,\n                enterprise: <Check className=\"size-4 text-primary\" \/>,\n            },\n            {\n                name: 'Support Channels',\n                hobby: 'Community Forum',\n                pro: 'Priority Email',\n                enterprise: 'Dedicated Slack + 99.9% SLA',\n            },\n        ],\n    },\n];\n\nexport function PricingComparison() {\n    const [isYearly, setIsYearly] = useState(false);\n\n    return (\n        <div className=\"@container mx-auto flex w-full max-w-5xl flex-col items-center gap-8 px-4 py-12\">\n            {\/* Header *\/}\n            <div className=\"max-w-2xl space-y-4 text-center\">\n                <Badge\n                    variant=\"outline\"\n                    className=\"border-primary\/20 bg-primary\/5 px-3 py-1 font-mono text-xs tracking-widest text-primary uppercase\"\n                >\n                    Feature Comparison\n                <\/Badge>\n                <h2 className=\"text-3xl font-bold tracking-tight sm:text-4xl\">\n                    Compare Plans & Features\n                <\/h2>\n                <p className=\"mx-auto max-w-md text-sm text-muted-foreground\">\n                    Deep dive into all features to choose the exact plan that\n                    suits your production and compliance requirements.\n                <\/p>\n            <\/div>\n\n            {\/* Toggle Switch *\/}\n            <div className=\"flex items-center justify-center gap-4\">\n                <span\n                    className={cn(\n                        'text-sm font-medium',\n                        !isYearly ? 'text-foreground' : 'text-muted-foreground',\n                    )}\n                >\n                    Monthly Billing\n                <\/span>\n                <Switch checked={isYearly} onCheckedChange={setIsYearly} \/>\n                <span\n                    className={cn(\n                        'flex items-center gap-1.5 text-sm font-medium',\n                        isYearly ? 'text-foreground' : 'text-muted-foreground',\n                    )}\n                >\n                    Yearly Billing\n                    <Badge\n                        variant=\"secondary\"\n                        className=\"border-0 bg-primary\/10 px-1.5 py-0 text-[10px] text-primary\"\n                    >\n                        Save 20%\n                    <\/Badge>\n                <\/span>\n            <\/div>\n\n            {\/* Comparison Table *\/}\n            <div className=\"w-full overflow-x-auto rounded-xl border bg-card\/50 shadow-md\">\n                <Table>\n                    <TableHeader>\n                        <TableRow className=\"hover:bg-transparent\">\n                            <TableHead className=\"w-[30%] min-w-[200px] font-bold text-foreground\">\n                                Features\n                            <\/TableHead>\n                            <TableHead className=\"w-[23%] text-center\">\n                                <div className=\"space-y-1 py-2\">\n                                    <h4 className=\"text-sm font-bold text-foreground\">\n                                        Hobby\n                                    <\/h4>\n                                    <div className=\"font-mono text-base font-extrabold text-foreground\">\n                                        ${isYearly ? 7 : 9}\n                                        <span className=\"text-[10px] font-normal text-muted-foreground\">\n                                            \/mo\n                                        <\/span>\n                                    <\/div>\n                                    <Button\n                                        variant=\"outline\"\n                                        size=\"sm\"\n                                        className=\"mt-2 h-7 w-full max-w-[120px] text-xs\"\n                                    >\n                                        Get Started\n                                    <\/Button>\n                                <\/div>\n                            <\/TableHead>\n                            <TableHead className=\"w-[24%] bg-primary\/5 text-center\">\n                                <div className=\"space-y-1 py-2\">\n                                    <div className=\"inline-block rounded-full bg-primary\/10 px-2 py-0.5 text-[9px] font-bold tracking-wider text-primary uppercase\">\n                                        Popular\n                                    <\/div>\n                                    <h4 className=\"text-sm font-bold text-foreground\">\n                                        Professional\n                                    <\/h4>\n                                    <div className=\"font-mono text-base font-extrabold text-primary\">\n                                        ${isYearly ? 24 : 29}\n                                        <span className=\"text-[10px] font-normal text-muted-foreground\">\n                                            \/mo\n                                        <\/span>\n                                    <\/div>\n                                    <Button\n                                        size=\"sm\"\n                                        className=\"mt-2 h-7 w-full max-w-[120px] bg-primary text-xs text-primary-foreground hover:bg-primary\/90\"\n                                    >\n                                        Choose Pro\n                                    <\/Button>\n                                <\/div>\n                            <\/TableHead>\n                            <TableHead className=\"w-[23%] text-center\">\n                                <div className=\"space-y-1 py-2\">\n                                    <h4 className=\"text-sm font-bold text-foreground\">\n                                        Enterprise\n                                    <\/h4>\n                                    <div className=\"font-mono text-base font-extrabold text-foreground\">\n                                        ${isYearly ? 79 : 99}\n                                        <span className=\"text-[10px] font-normal text-muted-foreground\">\n                                            \/mo\n                                        <\/span>\n                                    <\/div>\n                                    <Button\n                                        variant=\"outline\"\n                                        size=\"sm\"\n                                        className=\"mt-2 h-7 w-full max-w-[120px] text-xs\"\n                                    >\n                                        Contact Sales\n                                    <\/Button>\n                                <\/div>\n                            <\/TableHead>\n                        <\/TableRow>\n                    <\/TableHeader>\n                    <TableBody>\n                        {comparisonData.map((section, sIdx) => (\n                            <React.Fragment key={sIdx}>\n                                {\/* Category Header *\/}\n                                <TableRow className=\"bg-muted\/30 text-xs font-semibold tracking-wider text-muted-foreground uppercase hover:bg-muted\/30\">\n                                    <TableCell\n                                        colSpan={4}\n                                        className=\"py-2.5 pl-4 align-middle\"\n                                    >\n                                        {section.category}\n                                    <\/TableCell>\n                                <\/TableRow>\n\n                                {\/* Features rows *\/}\n                                {section.features.map((feature, fIdx) => (\n                                    <TableRow\n                                        key={fIdx}\n                                        className=\"transition-colors hover:bg-muted\/10\"\n                                    >\n                                        <TableCell className=\"py-3 pl-4 font-medium text-foreground\">\n                                            <div className=\"flex flex-col gap-0.5\">\n                                                <span>{feature.name}<\/span>\n                                                {feature.description && (\n                                                    <span className=\"text-[10px] leading-normal font-normal text-muted-foreground\">\n                                                        {feature.description}\n                                                    <\/span>\n                                                )}\n                                            <\/div>\n                                        <\/TableCell>\n                                        <TableCell className=\"py-3 text-center text-xs font-medium\">\n                                            <div className=\"flex items-center justify-center\">\n                                                {feature.hobby}\n                                            <\/div>\n                                        <\/TableCell>\n                                        <TableCell className=\"bg-primary\/5 py-3 text-center text-xs font-semibold\">\n                                            <div className=\"flex items-center justify-center\">\n                                                {feature.pro}\n                                            <\/div>\n                                        <\/TableCell>\n                                        <TableCell className=\"py-3 text-center text-xs font-medium\">\n                                            <div className=\"flex items-center justify-center\">\n                                                {feature.enterprise}\n                                            <\/div>\n                                        <\/TableCell>\n                                    <\/TableRow>\n                                ))}\n                            <\/React.Fragment>\n                        ))}\n                    <\/TableBody>\n                <\/Table>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default PricingComparison;\n"}],"meta":{"category":"pricing","version":"1.0.0"},"categories":["pricing"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"pricing-glowing","type":"registry:block","title":"Pricing Glowing","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","badge","card","slider","switch","label"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/pricing-glowing\/pricing-glowing.tsx","type":"registry:block","content":"'use client';\n\nimport React, { useState } from 'react';\nimport { Check, Sparkles } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Badge } from '@\/components\/ui\/badge';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardFooter,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\nimport { Slider } from '@\/components\/ui\/slider';\nimport { Switch } from '@\/components\/ui\/switch';\nimport { Label } from '@\/components\/ui\/label';\n\nexport function PricingGlowing() {\n    const [isYearly, setIsYearly] = useState(false);\n    const [userCount, setUserCount] = useState([10]); \/\/ Slider state for number of team seats\n\n    const getPrice = (basePrice: number) => {\n        const multiplier = isYearly ? 0.8 : 1; \/\/ 20% discount\n        const seats = userCount[0];\n        const seatPrice = Math.max(0, (seats - 5) * 4); \/\/ Extra $4 per seat above 5 seats\n        return Math.round((basePrice + seatPrice) * multiplier);\n    };\n\n    return (\n        <div className=\"@container mx-auto flex w-full max-w-5xl flex-col items-center gap-10 px-4 py-12\">\n            {\/* Header *\/}\n            <div className=\"max-w-2xl space-y-4 text-center\">\n                <Badge\n                    variant=\"outline\"\n                    className=\"animate-pulse border-primary\/30 bg-primary\/5 px-3 py-1 font-mono text-xs tracking-widest text-primary uppercase\"\n                >\n                    <Sparkles className=\"mr-1.5 inline-block size-3.5 text-primary\" \/>\n                    Scale-on-Demand Pricing\n                <\/Badge>\n                <h2 className=\"bg-gradient-to-r from-foreground via-foreground\/90 to-muted-foreground bg-clip-text text-4xl font-extrabold tracking-tight text-transparent sm:text-5xl\">\n                    Pay Only For What You Use\n                <\/h2>\n                <p className=\"mx-auto max-w-lg text-sm text-muted-foreground\">\n                    Choose a plan built to grow with you. Adjust the seat slider\n                    below to see how our volume discounts apply.\n                <\/p>\n            <\/div>\n\n            {\/* Slider Controls *\/}\n            <Card className=\"w-full max-w-xl border bg-card\/65 p-6 shadow-md backdrop-blur-xs\">\n                <div className=\"space-y-6\">\n                    <div className=\"flex items-center justify-between\">\n                        <Label className=\"text-sm font-semibold text-foreground\">\n                            Number of Seats\n                        <\/Label>\n                        <span className=\"font-mono text-lg font-bold text-primary\">\n                            {userCount[0]}{' '}\n                            {userCount[0] === 1 ? 'user' : 'users'}\n                        <\/span>\n                    <\/div>\n                    <Slider\n                        value={userCount}\n                        onValueChange={setUserCount}\n                        min={1}\n                        max={100}\n                        step={1}\n                        className=\"py-2\"\n                    \/>\n                    <div className=\"flex items-center justify-between font-mono text-xs text-muted-foreground\">\n                        <span>1 Seat<\/span>\n                        <span>50 Seats<\/span>\n                        <span>100 Seats<\/span>\n                    <\/div>\n\n                    <div className=\"flex items-center justify-center gap-4 border-t pt-4\">\n                        <span\n                            className={cn(\n                                'text-sm font-medium',\n                                !isYearly\n                                    ? 'text-foreground'\n                                    : 'text-muted-foreground',\n                            )}\n                        >\n                            Monthly\n                        <\/span>\n                        <Switch\n                            checked={isYearly}\n                            onCheckedChange={setIsYearly}\n                        \/>\n                        <span\n                            className={cn(\n                                'flex items-center gap-1.5 text-sm font-medium',\n                                isYearly\n                                    ? 'text-foreground'\n                                    : 'text-muted-foreground',\n                            )}\n                        >\n                            Yearly\n                            <Badge\n                                variant=\"secondary\"\n                                className=\"border-0 bg-primary\/10 px-1.5 py-0 text-[10px] text-primary\"\n                            >\n                                Save 20%\n                            <\/Badge>\n                        <\/span>\n                    <\/div>\n                <\/div>\n            <\/Card>\n\n            {\/* Pricing Tiers Grid *\/}\n            <div className=\"grid w-full grid-cols-1 gap-8 @3xl:grid-cols-3\">\n                {\/* Standard \/ Hobby *\/}\n                <Card className=\"relative flex flex-col justify-between overflow-hidden border bg-card\/45 backdrop-blur-xs transition-all duration-300 hover:scale-[1.01]\">\n                    <CardHeader className=\"space-y-2\">\n                        <CardTitle className=\"text-xl font-bold\">\n                            Startup\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Ideal for small dev teams and initial projects.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex-grow space-y-6\">\n                        <div className=\"flex items-baseline\">\n                            <span className=\"font-mono text-4xl font-extrabold tracking-tight\">\n                                ${getPrice(15)}\n                            <\/span>\n                            <span className=\"ml-1 text-xs text-muted-foreground\">\n                                \/month\n                            <\/span>\n                        <\/div>\n                        <ul className=\"space-y-3 text-xs\">\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>Includes first 5 users<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>15 active repositories<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>25GB SSD Storage<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>Weekly security scans<\/span>\n                            <\/li>\n                        <\/ul>\n                    <\/CardContent>\n                    <CardFooter>\n                        <Button className=\"w-full\" variant=\"outline\">\n                            Get Started\n                        <\/Button>\n                    <\/CardFooter>\n                <\/Card>\n\n                {\/* Pro Tier (Glowing\/Popular) *\/}\n                <Card className=\"relative flex flex-col justify-between overflow-hidden border-primary bg-card\/60 shadow-lg ring-1 ring-primary backdrop-blur-xs transition-all duration-300 hover:scale-[1.02]\">\n                    <div className=\"absolute top-0 right-0 rounded-bl-lg bg-primary px-3 py-1 font-mono text-[9px] font-bold tracking-widest text-primary-foreground uppercase\">\n                        Popular\n                    <\/div>\n                    <CardHeader className=\"space-y-2\">\n                        <CardTitle className=\"text-xl font-bold text-foreground\">\n                            Pro Team\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            For teams needing advanced scaling and metrics.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex-grow space-y-6\">\n                        <div className=\"flex items-baseline\">\n                            <span className=\"font-mono text-4xl font-extrabold tracking-tight text-primary\">\n                                ${getPrice(49)}\n                            <\/span>\n                            <span className=\"ml-1 text-xs text-muted-foreground\">\n                                \/month\n                            <\/span>\n                        <\/div>\n                        <ul className=\"space-y-3 text-xs\">\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span className=\"font-semibold text-foreground\">\n                                    Custom seat scaling\n                                <\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>Unlimited repositories<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>200GB SSD Storage<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>Realtime container metrics<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>Daily automated backups<\/span>\n                            <\/li>\n                        <\/ul>\n                    <\/CardContent>\n                    <CardFooter>\n                        <Button className=\"w-full bg-primary text-primary-foreground shadow-md hover:bg-primary\/90\">\n                            Upgrade to Pro\n                        <\/Button>\n                    <\/CardFooter>\n                <\/Card>\n\n                {\/* Scale Tier *\/}\n                <Card className=\"relative flex flex-col justify-between overflow-hidden border bg-card\/45 backdrop-blur-xs transition-all duration-300 hover:scale-[1.01]\">\n                    <CardHeader className=\"space-y-2\">\n                        <CardTitle className=\"text-xl font-bold\">\n                            Scale Plan\n                        <\/CardTitle>\n                        <CardDescription className=\"text-xs\">\n                            Tailored for corporate infrastructure and strict\n                            SLA.\n                        <\/CardDescription>\n                    <\/CardHeader>\n                    <CardContent className=\"flex-grow space-y-6\">\n                        <div className=\"flex items-baseline\">\n                            <span className=\"font-mono text-4xl font-extrabold tracking-tight\">\n                                ${getPrice(149)}\n                            <\/span>\n                            <span className=\"ml-1 text-xs text-muted-foreground\">\n                                \/month\n                            <\/span>\n                        <\/div>\n                        <ul className=\"space-y-3 text-xs\">\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>Dedicated isolated nodes<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>1TB SSD Storage<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>SAML SSO Integration<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>24\/7 dedicated support SLA<\/span>\n                            <\/li>\n                        <\/ul>\n                    <\/CardContent>\n                    <CardFooter>\n                        <Button className=\"w-full\" variant=\"outline\">\n                            Contact Sales\n                        <\/Button>\n                    <\/CardFooter>\n                <\/Card>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default PricingGlowing;\n"}],"meta":{"category":"pricing","version":"1.0.0"},"categories":["pricing"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"pricing-modern-cards","type":"registry:block","title":"Pricing Modern Cards","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","badge","card","switch"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/pricing-modern-cards\/pricing-modern-cards.tsx","type":"registry:block","content":"'use client';\n\nimport React, { useState } from 'react';\nimport { Check, Shield, Zap, Target, Star } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Badge } from '@\/components\/ui\/badge';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardFooter,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\nimport { Switch } from '@\/components\/ui\/switch';\n\ninterface TierData {\n    name: string;\n    description: string;\n    monthlyPrice: number;\n    yearlyPrice: number;\n    icon: React.ReactNode;\n    features: { text: string; included: boolean }[];\n    popular?: boolean;\n    cta: string;\n}\n\nconst tiers: TierData[] = [\n    {\n        name: 'Basic Dev',\n        description: 'For students, hobbyists, and side projects.',\n        monthlyPrice: 0,\n        yearlyPrice: 0,\n        icon: <Target className=\"size-5 text-muted-foreground\" \/>,\n        features: [\n            { text: '1 active workspace node', included: true },\n            { text: 'Basic error monitoring', included: true },\n            { text: '1GB bandwidth limits', included: true },\n            { text: 'Custom domains integration', included: false },\n            { text: 'Priority Slack support', included: false },\n        ],\n        cta: 'Launch Free Node',\n    },\n    {\n        name: 'Scale Up',\n        description: 'Perfect for fast growing web applications.',\n        monthlyPrice: 19,\n        yearlyPrice: 15,\n        icon: <Zap className=\"size-5 text-primary\" \/>,\n        features: [\n            { text: '10 active workspace nodes', included: true },\n            { text: 'Real-time telemetry reports', included: true },\n            { text: '50GB bandwidth limits', included: true },\n            { text: 'Custom domains integration', included: true },\n            { text: 'Priority Slack support', included: false },\n        ],\n        popular: true,\n        cta: 'Upgrade to Scale',\n    },\n    {\n        name: 'Max Ops',\n        description: 'High performance cluster infrastructure.',\n        monthlyPrice: 89,\n        yearlyPrice: 71,\n        icon: <Shield className=\"size-5 text-primary\" \/>,\n        features: [\n            { text: 'Unlimited active nodes', included: true },\n            { text: 'Advanced security auditing', included: true },\n            { text: 'Unlimited bandwidth limits', included: true },\n            { text: 'Custom domains integration', included: true },\n            { text: 'Priority Slack support (24\/7)', included: true },\n        ],\n        cta: 'Contact Max Ops',\n    },\n];\n\nexport function PricingModernCards() {\n    const [isYearly, setIsYearly] = useState(false);\n\n    return (\n        <div className=\"@container mx-auto flex w-full max-w-5xl flex-col items-center gap-10 px-4 py-12\">\n            {\/* Header *\/}\n            <div className=\"max-w-2xl space-y-4 text-center\">\n                <Badge\n                    variant=\"outline\"\n                    className=\"border-primary\/20 bg-primary\/5 px-3 py-1 font-mono text-xs tracking-widest text-primary uppercase\"\n                >\n                    Predictable Plans\n                <\/Badge>\n                <h2 className=\"bg-gradient-to-r from-foreground via-foreground\/90 to-muted-foreground bg-clip-text text-3xl font-extrabold tracking-tight text-transparent sm:text-4xl\">\n                    Simple pricing. No hidden fees.\n                <\/h2>\n                <p className=\"mx-auto max-w-sm text-sm text-muted-foreground\">\n                    Choose the perfect subscription package for your workload.\n                    Cancel anytime.\n                <\/p>\n            <\/div>\n\n            {\/* Toggle *\/}\n            <div className=\"flex items-center justify-center gap-3\">\n                <span\n                    className={cn(\n                        'text-sm font-semibold',\n                        !isYearly ? 'text-foreground' : 'text-muted-foreground',\n                    )}\n                >\n                    Monthly\n                <\/span>\n                <Switch checked={isYearly} onCheckedChange={setIsYearly} \/>\n                <span\n                    className={cn(\n                        'flex items-center gap-1.5 text-sm font-semibold',\n                        isYearly ? 'text-foreground' : 'text-muted-foreground',\n                    )}\n                >\n                    Yearly\n                    <Badge\n                        variant=\"secondary\"\n                        className=\"border-0 bg-primary\/10 px-1.5 py-0 text-[10px] text-primary\"\n                    >\n                        2 months free\n                    <\/Badge>\n                <\/span>\n            <\/div>\n\n            {\/* Grid *\/}\n            <div className=\"grid w-full grid-cols-1 items-stretch gap-6 @3xl:grid-cols-3\">\n                {tiers.map((tier, idx) => (\n                    <Card\n                        key={idx}\n                        className={cn(\n                            'relative flex flex-col justify-between overflow-hidden border bg-card\/45 backdrop-blur-xs transition-all duration-300 hover:scale-[1.01]',\n                            tier.popular\n                                ? 'border-primary bg-card\/60 shadow-lg ring-1 ring-primary\/45'\n                                : 'shadow-sm',\n                        )}\n                    >\n                        {tier.popular && (\n                            <div className=\"absolute top-3 right-3 flex animate-pulse items-center gap-1 rounded-full border border-primary\/20 bg-primary\/10 px-2.5 py-0.5 text-[8px] font-bold tracking-wider text-primary uppercase\">\n                                <Star className=\"size-2.5 fill-current text-primary\" \/>\n                                Recommended\n                            <\/div>\n                        )}\n\n                        <CardHeader className=\"space-y-3 pb-6\">\n                            <div className=\"flex items-center gap-2\">\n                                <div className=\"shrink-0 rounded border bg-muted\/50 p-1.5\">\n                                    {tier.icon}\n                                <\/div>\n                                <CardTitle className=\"text-lg font-bold\">\n                                    {tier.name}\n                                <\/CardTitle>\n                            <\/div>\n                            <CardDescription className=\"min-h-[32px] text-xs leading-relaxed\">\n                                {tier.description}\n                            <\/CardDescription>\n                        <\/CardHeader>\n\n                        <CardContent className=\"flex-grow space-y-6 pb-6\">\n                            <div className=\"flex items-baseline\">\n                                <span className=\"font-mono text-4xl font-extrabold tracking-tight text-foreground\">\n                                    $\n                                    {isYearly\n                                        ? tier.yearlyPrice\n                                        : tier.monthlyPrice}\n                                <\/span>\n                                <span className=\"ml-1 text-xs text-muted-foreground\">\n                                    \/month\n                                <\/span>\n                            <\/div>\n\n                            <ul className=\"space-y-3 border-t pt-6 text-xs\">\n                                {tier.features.map((feat, fIdx) => (\n                                    <li\n                                        key={fIdx}\n                                        className={cn(\n                                            'flex items-center gap-2',\n                                            feat.included\n                                                ? 'text-foreground'\n                                                : 'text-muted-foreground\/60 line-through',\n                                        )}\n                                    >\n                                        <Check\n                                            className={cn(\n                                                'size-4 shrink-0',\n                                                feat.included\n                                                    ? 'text-primary'\n                                                    : 'text-muted-foreground\/30',\n                                            )}\n                                        \/>\n                                        <span>{feat.text}<\/span>\n                                    <\/li>\n                                ))}\n                            <\/ul>\n                        <\/CardContent>\n\n                        <CardFooter className=\"pt-0\">\n                            <Button\n                                className=\"h-9 w-full text-xs\"\n                                variant={tier.popular ? 'default' : 'outline'}\n                            >\n                                {tier.cta}\n                            <\/Button>\n                        <\/CardFooter>\n                    <\/Card>\n                ))}\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default PricingModernCards;\n"}],"meta":{"category":"pricing","version":"1.0.0"},"categories":["pricing"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"pricing-resources","type":"registry:block","title":"Pricing Resources","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","badge","card","slider","switch","label"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/pricing-resources\/pricing-resources.tsx","type":"registry:block","content":"'use client';\n\nimport React, { useState } from 'react';\nimport { Cpu, HardDrive, Check, Sparkles } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Badge } from '@\/components\/ui\/badge';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardFooter,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\nimport { Slider } from '@\/components\/ui\/slider';\nimport { Switch } from '@\/components\/ui\/switch';\nimport { Label } from '@\/components\/ui\/label';\n\nexport function PricingResources() {\n    const [isYearly, setIsYearly] = useState(false);\n    const [cpu, setCpu] = useState([2]); \/\/ 1 to 16 cores\n    const [ram, setRam] = useState([4]); \/\/ 2 to 64 GB\n    const [storage, setStorage] = useState([50]); \/\/ 10 to 1000 GB\n\n    const calculateMonthlyPrice = () => {\n        const cpuCost = cpu[0] * 8; \/\/ $8 per core\n        const ramCost = ram[0] * 2.5; \/\/ $2.50 per GB RAM\n        const storageCost = storage[0] * 0.15; \/\/ $0.15 per GB storage\n        const total = cpuCost + ramCost + storageCost;\n        const discountMultiplier = isYearly ? 0.8 : 1; \/\/ 20% discount\n        return Math.round(total * discountMultiplier);\n    };\n\n    return (\n        <div className=\"@container mx-auto flex w-full max-w-5xl flex-col items-center gap-10 px-4 py-12\">\n            {\/* Header *\/}\n            <div className=\"max-w-2xl space-y-4 text-center\">\n                <Badge\n                    variant=\"outline\"\n                    className=\"border-primary\/30 bg-primary\/5 px-3 py-1 font-mono text-xs tracking-widest text-primary uppercase\"\n                >\n                    <Sparkles className=\"mr-1.5 inline-block size-3.5 animate-pulse text-primary\" \/>\n                    Custom Calculator\n                <\/Badge>\n                <h2 className=\"text-4xl font-extrabold tracking-tight sm:text-5xl\">\n                    Configure Your Resources\n                <\/h2>\n                <p className=\"mx-auto max-w-lg text-sm text-muted-foreground\">\n                    Design a custom server container suited for your deployment.\n                    Move the sliders to scale CPU, RAM, and Storage.\n                <\/p>\n            <\/div>\n\n            <div className=\"grid w-full grid-cols-1 items-stretch gap-8 @4xl:grid-cols-12\">\n                {\/* Sliders Card *\/}\n                <Card className=\"col-span-1 flex flex-col justify-between space-y-8 border bg-card\/65 p-6 shadow-md backdrop-blur-xs @4xl:col-span-7\">\n                    {\/* CPU Sliders *\/}\n                    <div className=\"space-y-4\">\n                        <div className=\"flex items-center justify-between\">\n                            <Label className=\"flex items-center gap-2 text-sm font-semibold text-foreground\">\n                                <Cpu className=\"size-4 text-primary\" \/>\n                                vCPU Cores\n                            <\/Label>\n                            <span className=\"font-mono text-base font-bold text-foreground\">\n                                {cpu[0]} {cpu[0] === 1 ? 'Core' : 'Cores'}\n                            <\/span>\n                        <\/div>\n                        <Slider\n                            value={cpu}\n                            onValueChange={setCpu}\n                            min={1}\n                            max={16}\n                            step={1}\n                            className=\"py-1\"\n                        \/>\n                        <div className=\"flex justify-between font-mono text-[10px] text-muted-foreground\">\n                            <span>1 Core<\/span>\n                            <span>8 Cores<\/span>\n                            <span>16 Cores<\/span>\n                        <\/div>\n                    <\/div>\n\n                    {\/* RAM Sliders *\/}\n                    <div className=\"space-y-4\">\n                        <div className=\"flex items-center justify-between\">\n                            <Label className=\"flex items-center gap-2 text-sm font-semibold text-foreground\">\n                                <Cpu className=\"size-4 animate-pulse text-primary\" \/>\n                                Memory (RAM)\n                            <\/Label>\n                            <span className=\"font-mono text-base font-bold text-foreground\">\n                                {ram[0]} GB\n                            <\/span>\n                        <\/div>\n                        <Slider\n                            value={ram}\n                            onValueChange={setRam}\n                            min={2}\n                            max={64}\n                            step={2}\n                            className=\"py-1\"\n                        \/>\n                        <div className=\"flex justify-between font-mono text-[10px] text-muted-foreground\">\n                            <span>2 GB<\/span>\n                            <span>32 GB<\/span>\n                            <span>64 GB<\/span>\n                        <\/div>\n                    <\/div>\n\n                    {\/* Storage Slider *\/}\n                    <div className=\"space-y-4\">\n                        <div className=\"flex items-center justify-between\">\n                            <Label className=\"flex items-center gap-2 text-sm font-semibold text-foreground\">\n                                <HardDrive className=\"size-4 text-primary\" \/>\n                                SSD Storage\n                            <\/Label>\n                            <span className=\"font-mono text-base font-bold text-foreground\">\n                                {storage[0]} GB\n                            <\/span>\n                        <\/div>\n                        <Slider\n                            value={storage}\n                            onValueChange={setStorage}\n                            min={10}\n                            max={1000}\n                            step={10}\n                            className=\"py-1\"\n                        \/>\n                        <div className=\"flex justify-between font-mono text-[10px] text-muted-foreground\">\n                            <span>10 GB<\/span>\n                            <span>500 GB<\/span>\n                            <span>1TB (1000 GB)<\/span>\n                        <\/div>\n                    <\/div>\n                <\/Card>\n\n                {\/* Estimate & Checkout Card *\/}\n                <Card className=\"col-span-1 flex min-h-[380px] flex-col justify-between border border-primary bg-card\/90 p-6 shadow-xl @4xl:col-span-5\">\n                    <div className=\"space-y-6\">\n                        <CardHeader className=\"p-0\">\n                            <CardTitle className=\"text-xl font-bold\">\n                                Estimated Cost\n                            <\/CardTitle>\n                            <CardDescription className=\"text-xs\">\n                                Based on your selected vCPU, RAM, and Storage\n                                layout.\n                            <\/CardDescription>\n                        <\/CardHeader>\n\n                        {\/* Price Display *\/}\n                        <div className=\"space-y-2 border-y py-4\">\n                            <div className=\"flex items-baseline justify-center\">\n                                <span className=\"animate-pulse font-mono text-5xl font-black tracking-tight text-primary\">\n                                    ${calculateMonthlyPrice()}\n                                <\/span>\n                                <span className=\"ml-1 text-sm text-muted-foreground\">\n                                    \/month\n                                <\/span>\n                            <\/div>\n\n                            {\/* Billing Switch *\/}\n                            <div className=\"flex items-center justify-center gap-3 pt-3\">\n                                <span\n                                    className={cn(\n                                        'text-xs font-semibold',\n                                        !isYearly\n                                            ? 'text-foreground'\n                                            : 'text-muted-foreground',\n                                    )}\n                                >\n                                    Monthly\n                                <\/span>\n                                <Switch\n                                    checked={isYearly}\n                                    onCheckedChange={setIsYearly}\n                                    className=\"scale-90\"\n                                \/>\n                                <span\n                                    className={cn(\n                                        'flex items-center gap-1 text-xs font-semibold',\n                                        isYearly\n                                            ? 'text-foreground'\n                                            : 'text-muted-foreground',\n                                    )}\n                                >\n                                    Yearly\n                                    <Badge\n                                        variant=\"secondary\"\n                                        className=\"border-0 bg-primary\/15 px-1 py-0 text-[9px] text-primary\"\n                                    >\n                                        -20%\n                                    <\/Badge>\n                                <\/span>\n                            <\/div>\n                        <\/div>\n\n                        {\/* Features checklist *\/}\n                        <ul className=\"space-y-3 text-xs\">\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>Dedicated host container nodes<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>99.99% network uptime SLA<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>Automated daily snap backups<\/span>\n                            <\/li>\n                            <li className=\"flex items-center gap-2\">\n                                <Check className=\"size-4 shrink-0 text-primary\" \/>\n                                <span>\n                                    Unlimited incoming\/outgoing bandwidth\n                                <\/span>\n                            <\/li>\n                        <\/ul>\n                    <\/div>\n\n                    <CardFooter className=\"p-0 pt-6\">\n                        <Button className=\"w-full bg-primary text-primary-foreground shadow-md hover:bg-primary\/90\">\n                            Deploy Server Now\n                        <\/Button>\n                    <\/CardFooter>\n                <\/Card>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default PricingResources;\n"}],"meta":{"category":"pricing","version":"1.0.0"},"categories":["pricing"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"pricing-section","type":"registry:block","title":"Pricing Section","description":"A modern tiered pricing section with hover scale states, tags, and toggles.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","badge","card","switch","label"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/pricing-section\/pricing-section.tsx","type":"registry:block","content":"import React, { useState } from 'react';\nimport { Check, HelpCircle } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Badge } from '@\/components\/ui\/badge';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardFooter,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\nimport { Switch } from '@\/components\/ui\/switch';\nimport { Label } from '@\/components\/ui\/label';\n\nexport interface PricingTier {\n    name: string;\n    description: string;\n    monthlyPrice: number;\n    yearlyPrice: number;\n    features: string[];\n    ctaText: string;\n    popular?: boolean;\n    ctaVariant?: 'default' | 'outline' | 'secondary';\n}\n\nconst tiers: PricingTier[] = [\n    {\n        name: 'Hobby',\n        description: 'Perfect for side projects and initial prototypes.',\n        monthlyPrice: 9,\n        yearlyPrice: 7,\n        features: [\n            'Up to 3 active projects',\n            'Basic telemetry & alerts',\n            '10GB monthly bandwidth',\n            'Community forum support',\n            'API access limit (60 req\/min)',\n        ],\n        ctaText: 'Start for Free',\n        ctaVariant: 'outline',\n    },\n    {\n        name: 'Professional',\n        description: 'For growing apps requiring advanced scaling & support.',\n        monthlyPrice: 29,\n        yearlyPrice: 24,\n        features: [\n            'Unlimited active projects',\n            'Real-time detailed metrics',\n            '100GB monthly bandwidth',\n            'Priority 24\/7 support',\n            'Unlimited API access',\n            'Custom domain integration',\n            'Team collaboration (up to 5)',\n        ],\n        ctaText: 'Upgrade to Pro',\n        popular: true,\n        ctaVariant: 'default',\n    },\n    {\n        name: 'Enterprise',\n        description: 'Custom solutions for high scale corporate products.',\n        monthlyPrice: 99,\n        yearlyPrice: 79,\n        features: [\n            'Dedicated database nodes',\n            'Custom SLA contracts',\n            'Multi-region replication',\n            'Dedicated account manager',\n            'SSO\/SAML Authentication',\n            'Custom logging integrations',\n            'Infinite team seats',\n        ],\n        ctaText: 'Contact Sales',\n        ctaVariant: 'outline',\n    },\n];\n\nexport function PricingSection() {\n    const [isYearly, setIsYearly] = useState(false);\n\n    return (\n        <div className=\"@container mx-auto flex w-full max-w-5xl flex-col items-center gap-8 px-4 py-8\">\n            <div className=\"max-w-xl space-y-3 text-center\">\n                <Badge\n                    variant=\"outline\"\n                    className=\"bg-primary\/5 px-3 py-1 font-mono text-xs tracking-widest text-primary uppercase\"\n                >\n                    Flexible Pricing\n                <\/Badge>\n                <h2 className=\"text-3xl font-extrabold tracking-tight sm:text-4xl\">\n                    Fair Pricing for Everyone\n                <\/h2>\n                <p className=\"text-sm text-muted-foreground\">\n                    Get started with our free tiers and upgrade seamlessly as\n                    your production needs grow. Cancel or change plans anytime.\n                <\/p>\n            <\/div>\n\n            {\/* Toggle switch for Monthly vs Yearly billing *\/}\n            <div className=\"flex items-center gap-3 rounded-full border border-border\/40 bg-muted\/30 p-2.5 select-none\">\n                <Label\n                    htmlFor=\"billing-period\"\n                    className={cn(\n                        'cursor-pointer text-xs font-semibold transition-colors',\n                        !isYearly ? 'text-foreground' : 'text-muted-foreground',\n                    )}\n                >\n                    Monthly\n                <\/Label>\n                <Switch\n                    id=\"billing-period\"\n                    checked={isYearly}\n                    onCheckedChange={setIsYearly}\n                    className=\"data-[state=checked]:bg-primary\"\n                \/>\n                <Label\n                    htmlFor=\"billing-period\"\n                    className={cn(\n                        'flex cursor-pointer items-center gap-1.5 text-xs font-semibold transition-colors',\n                        isYearly ? 'text-foreground' : 'text-muted-foreground',\n                    )}\n                >\n                    Yearly\n                    <Badge\n                        variant=\"secondary\"\n                        className=\"border border-primary\/20 bg-primary\/5 px-1 py-0 text-[9px] font-bold text-primary hover:bg-primary\/10\"\n                    >\n                        Save 20%\n                    <\/Badge>\n                <\/Label>\n            <\/div>\n\n            {\/* Pricing cards grid *\/}\n            <div className=\"grid w-full grid-cols-1 items-stretch gap-6 @3xl:grid-cols-3\">\n                {tiers.map((tier) => {\n                    const price = isYearly\n                        ? tier.yearlyPrice\n                        : tier.monthlyPrice;\n                    return (\n                        <Card\n                            key={tier.name}\n                            className={cn(\n                                'relative flex flex-col justify-between transition-all duration-300 hover:-translate-y-1',\n                                tier.popular\n                                    ? 'border-primary bg-card\/65 shadow-lg ring-1 ring-primary\/30'\n                                    : 'border-border\/50 bg-card\/25 backdrop-blur-xs hover:border-border\/80',\n                            )}\n                        >\n                            {tier.popular && (\n                                <div className=\"absolute top-0 right-1\/2 translate-x-1\/2 -translate-y-1\/2\">\n                                    <Badge className=\"rounded-full bg-primary px-3 py-0.5 text-xs font-semibold tracking-wider text-primary-foreground uppercase shadow-md hover:bg-primary\">\n                                        Most Popular\n                                    <\/Badge>\n                                <\/div>\n                            )}\n\n                            <div>\n                                <CardHeader className=\"pb-4\">\n                                    <CardTitle className=\"text-xl font-bold\">\n                                        {tier.name}\n                                    <\/CardTitle>\n                                    <CardDescription className=\"mt-1 min-h-[32px] text-xs\">\n                                        {tier.description}\n                                    <\/CardDescription>\n                                <\/CardHeader>\n\n                                <CardContent className=\"space-y-6\">\n                                    {\/* Plan Price *\/}\n                                    <div className=\"flex items-baseline gap-1.5\">\n                                        <span className=\"text-4xl font-extrabold tracking-tight\">\n                                            ${price}\n                                        <\/span>\n                                        <span className=\"text-xs font-medium text-muted-foreground\">\n                                            \/ user \/ month\n                                        <\/span>\n                                    <\/div>\n\n                                    {\/* Features Checklist *\/}\n                                    <ul className=\"space-y-3 text-xs text-foreground\/85\">\n                                        {tier.features.map((feature) => (\n                                            <li\n                                                key={feature}\n                                                className=\"flex items-start gap-2\"\n                                            >\n                                                <div\n                                                    className={cn(\n                                                        'mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full',\n                                                        tier.popular\n                                                            ? 'bg-primary\/10 text-primary'\n                                                            : 'bg-muted text-muted-foreground',\n                                                    )}\n                                                >\n                                                    <Check className=\"size-2.5 stroke-[3]\" \/>\n                                                <\/div>\n                                                <span className=\"leading-snug\">\n                                                    {feature}\n                                                <\/span>\n                                            <\/li>\n                                        ))}\n                                    <\/ul>\n                                <\/CardContent>\n                            <\/div>\n\n                            <CardFooter className=\"pt-4\">\n                                <Button\n                                    variant={tier.ctaVariant}\n                                    className={cn(\n                                        'w-full transition-transform active:scale-95',\n                                        tier.popular &&\n                                            'shadow-md shadow-primary\/20',\n                                    )}\n                                >\n                                    {tier.ctaText}\n                                <\/Button>\n                            <\/CardFooter>\n                        <\/Card>\n                    );\n                })}\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default PricingSection;\n"}],"meta":{"category":"pricing","version":"1.0.0"},"categories":["pricing"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"pricing-table","type":"registry:block","title":"Pricing Table","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/pricing-table\/pricing-table.tsx","type":"registry:block","content":"'use client';\n\nimport React from 'react';\nimport { Check, X } from 'lucide-react';\nimport { Card, CardHeader, CardTitle, CardContent } from '@\/components\/ui\/card';\n\ninterface FeatureRow {\n    feature: string;\n    free: boolean;\n    pro: boolean;\n}\n\nconst rows: FeatureRow[] = [\n    { feature: 'Core Component Files', free: true, pro: true },\n    { feature: 'Registry CLI installer', free: true, pro: true },\n    { feature: 'Advanced Glitch shaders', free: false, pro: true },\n    { feature: 'Unlimited workspaces', free: false, pro: true },\n    { feature: 'Priority Help SLA', free: false, pro: true },\n];\n\nexport function PricingTable() {\n    return (\n        <Card className=\"w-full overflow-hidden border-border\/50 bg-card\/30 backdrop-blur-xs\">\n            <CardHeader className=\"pb-2\">\n                <CardTitle className=\"text-sm font-bold tracking-wider text-muted-foreground uppercase\">\n                    Feature Comparison\n                <\/CardTitle>\n            <\/CardHeader>\n            <CardContent className=\"p-0\">\n                <div className=\"overflow-x-auto\">\n                    <table className=\"w-full border-collapse text-left text-xs\">\n                        <thead>\n                            <tr className=\"border-b border-border\/30 bg-muted\/20\">\n                                <th className=\"p-3 font-bold text-muted-foreground\">\n                                    Feature\n                                <\/th>\n                                <th className=\"w-24 p-3 text-center font-bold\">\n                                    Free\n                                <\/th>\n                                <th className=\"w-24 p-3 text-center font-bold text-primary\">\n                                    Pro\n                                <\/th>\n                            <\/tr>\n                        <\/thead>\n                        <tbody>\n                            {rows.map((row, idx) => (\n                                <tr\n                                    key={idx}\n                                    className=\"border-b border-border\/20 last:border-0 hover:bg-muted\/10\"\n                                >\n                                    <td className=\"p-3 font-semibold text-foreground\">\n                                        {row.feature}\n                                    <\/td>\n                                    <td className=\"p-3 text-center\">\n                                        {row.free ? (\n                                            <Check className=\"mx-auto size-4 text-chart-2\" \/>\n                                        ) : (\n                                            <X className=\"mx-auto size-4 text-muted-foreground\/30\" \/>\n                                        )}\n                                    <\/td>\n                                    <td className=\"p-3 text-center\">\n                                        {row.pro ? (\n                                            <Check className=\"mx-auto size-4 text-primary\" \/>\n                                        ) : (\n                                            <X className=\"mx-auto size-4 text-muted-foreground\/30\" \/>\n                                        )}\n                                    <\/td>\n                                <\/tr>\n                            ))}\n                        <\/tbody>\n                    <\/table>\n                <\/div>\n            <\/CardContent>\n        <\/Card>\n    );\n}\n\nexport default PricingTable;\n"}],"meta":{"category":"pricing","version":"1.0.0"},"categories":["pricing"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"property-detail","type":"registry:block","title":"Property Detail","description":"A clean and rich property details display page containing descriptions, photos, and reviews.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["badge","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/property-detail\/property-detail.tsx","type":"registry:block","content":"import React from 'react';\nimport {\n    Star,\n    MapPin,\n    Users,\n    Wifi,\n    Coffee,\n    Tv,\n    Shield,\n    Compass,\n    Calendar,\n    Sparkles,\n    Check,\n    ChevronRight,\n} from 'lucide-react';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Card, CardContent } from '@\/components\/ui\/card';\nimport { BookingForm } from '..\/booking-form\/booking-form';\n\nexport function PropertyDetail() {\n    const amenities = [\n        {\n            name: 'High-speed Wi-Fi',\n            desc: '500 Mbps connection',\n            icon: <Wifi className=\"size-4 text-primary\" \/>,\n        },\n        {\n            name: 'Chef Kitchen',\n            desc: 'Professional stove & cookware',\n            icon: <Coffee className=\"size-4 text-primary\" \/>,\n        },\n        {\n            name: 'Smart Cable TV',\n            desc: 'Netflix, Prime & sound system',\n            icon: <Tv className=\"size-4 text-primary\" \/>,\n        },\n        {\n            name: 'Protected Safety',\n            desc: 'Gated entrance & smart lock',\n            icon: <Shield className=\"size-4 text-primary\" \/>,\n        },\n        {\n            name: 'Panoramic Balcony',\n            desc: 'Overlooks ocean & sunset view',\n            icon: <Compass className=\"size-4 text-primary\" \/>,\n        },\n        {\n            name: 'Wellness Bath',\n            desc: 'Rain shower & cedar hot tub',\n            icon: <Sparkles className=\"size-4 text-primary\" \/>,\n        },\n    ];\n\n    const highlights = [\n        'Selected in \"Top 100 Stays\" Worldwide by Travel Guide',\n        'Direct sand access, just 20 meters to the beach',\n        'Exceptional host with average response time of 5 minutes',\n    ];\n\n    return (\n        <div className=\"mx-auto w-full max-w-5xl space-y-8 px-4 py-6\">\n            {\/* Top Header section *\/}\n            <div className=\"space-y-2 border-b border-border\/20 pb-6\">\n                <div className=\"flex flex-wrap items-center gap-2\">\n                    <Badge className=\"bg-chart-2 font-mono text-[9px] tracking-wider text-primary-foreground uppercase hover:bg-chart-2\/90\">\n                        \u2605 Top Rated\n                    <\/Badge>\n                    <Badge\n                        variant=\"outline\"\n                        className=\"text-[9px] tracking-wider uppercase\"\n                    >\n                        Eleuthera, Bahamas\n                    <\/Badge>\n                <\/div>\n                <div className=\"flex flex-col justify-between gap-4 md:flex-row md:items-center\">\n                    <h2 className=\"font-sans text-2xl font-extrabold tracking-tight text-foreground md:text-3xl\">\n                        The Azure Wave Villa\n                    <\/h2>\n                    <div className=\"flex shrink-0 items-center gap-1.5 text-sm\">\n                        <Star className=\"size-4 fill-chart-4 text-chart-4\" \/>\n                        <span className=\"font-extrabold\">4.98<\/span>\n                        <span className=\"text-muted-foreground\">\n                            (86 reviews)\n                        <\/span>\n                        <span className=\"text-muted-foreground\">\u2022<\/span>\n                        <span className=\"cursor-pointer font-semibold text-primary underline\">\n                            Superhost\n                        <\/span>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            {\/* Premium Vector Mosaic Gallery *\/}\n            <div className=\"grid h-[300px] grid-cols-1 gap-3 overflow-hidden rounded-xl border border-border\/20 shadow-lg md:h-[400px] md:grid-cols-4\">\n                <div className=\"relative flex h-full items-center justify-center bg-gradient-to-tr from-chart-3\/95 via-chart-3\/80 to-primary\/40 p-6 text-center text-white md:col-span-2\">\n                    <div className=\"absolute inset-0 bg-black\/10 transition-colors hover:bg-black\/20\" \/>\n                    <span className=\"relative z-10 font-bebas-neue! text-3xl tracking-wider\">\n                        Ocean Front Terrace\n                    <\/span>\n                    <div className=\"absolute bottom-4 left-4 font-mono text-xs opacity-80\">\n                        Living Area & Pool\n                    <\/div>\n                <\/div>\n                <div className=\"grid h-full grid-rows-2 gap-3 md:col-span-2\">\n                    <div className=\"grid h-full grid-cols-2 gap-3\">\n                        <div className=\"relative flex items-center justify-center bg-gradient-to-br from-chart-2\/95 via-chart-2\/80 to-chart-3 text-center text-white\">\n                            <div className=\"absolute inset-0 bg-black\/10\" \/>\n                            <span className=\"relative z-10 text-xs font-bold\">\n                                Infinity Pool\n                            <\/span>\n                        <\/div>\n                        <div className=\"relative flex items-center justify-center bg-gradient-to-br from-chart-4\/95 via-chart-4\/80 to-primary\/50 text-center text-white\">\n                            <div className=\"absolute inset-0 bg-black\/10\" \/>\n                            <span className=\"relative z-10 text-xs font-bold\">\n                                Master Bed Suite\n                            <\/span>\n                        <\/div>\n                    <\/div>\n                    <div className=\"grid h-full grid-cols-2 gap-3\">\n                        <div className=\"relative flex items-center justify-center bg-gradient-to-tr from-chart-1\/95 via-chart-1\/80 to-chart-5 text-center text-white\">\n                            <div className=\"absolute inset-0 bg-black\/10\" \/>\n                            <span className=\"relative z-10 text-xs font-bold\">\n                                Wellness Bath\n                            <\/span>\n                        <\/div>\n                        <div className=\"relative flex items-center justify-center bg-gradient-to-tr from-chart-3\/95 via-chart-3\/80 to-chart-2 text-center text-white\">\n                            <div className=\"absolute inset-0 bg-black\/10\" \/>\n                            <span className=\"relative z-10 text-xs font-bold\">\n                                Direct Sand Path\n                            <\/span>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            {\/* Split Details Section *\/}\n            <div className=\"grid grid-cols-1 gap-8 lg:grid-cols-3\">\n                {\/* Left Side: Property details *\/}\n                <div className=\"space-y-8 lg:col-span-2\">\n                    {\/* Host Info *\/}\n                    <div className=\"flex items-center justify-between border-b border-border\/20 pb-6\">\n                        <div className=\"space-y-1\">\n                            <h3 className=\"text-lg font-bold text-foreground\">\n                                Entire villa hosted by Sarah\n                            <\/h3>\n                            <p className=\"text-xs text-muted-foreground\">\n                                6 guests \u2022 3 bedrooms \u2022 5 beds \u2022 3 baths\n                            <\/p>\n                        <\/div>\n                        <div className=\"relative\">\n                            <div className=\"flex size-12 items-center justify-center rounded-full border border-white\/20 bg-gradient-to-tr from-chart-2 to-chart-3 font-extrabold text-white shadow-inner\">\n                                S\n                            <\/div>\n                            <div className=\"absolute -right-1 -bottom-1 flex size-5 items-center justify-center rounded-full border-2 border-background bg-chart-2 text-primary-foreground\">\n                                <Check className=\"size-3 stroke-[3]\" \/>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    {\/* Highlights list *\/}\n                    <div className=\"space-y-3\">\n                        <h4 className=\"text-[10px] font-bold tracking-wider text-muted-foreground uppercase\">\n                            Key Highlights\n                        <\/h4>\n                        <div className=\"space-y-2.5\">\n                            {highlights.map((h, i) => (\n                                <div\n                                    key={i}\n                                    className=\"flex items-start gap-2.5 text-xs leading-relaxed text-muted-foreground\"\n                                >\n                                    <Sparkles className=\"mt-0.5 size-4.5 shrink-0 text-chart-4\" \/>\n                                    <span>{h}<\/span>\n                                <\/div>\n                            ))}\n                        <\/div>\n                    <\/div>\n\n                    {\/* Description *\/}\n                    <div className=\"space-y-3 border-t border-border\/20 pt-6\">\n                        <h4 className=\"text-[10px] font-bold tracking-wider text-muted-foreground uppercase\">\n                            About This Guesthouse\n                        <\/h4>\n                        <p className=\"text-xs leading-relaxed text-muted-foreground\">\n                            Welcome to The Azure Wave Villa, where sea meets\n                            luxury. Elevated above the sparkling waves of\n                            Eleuthera, our guesthouse features structural open\n                            ceilings, natural limestone walls, and\n                            floor-to-ceiling glass panel windows that frame\n                            magnificent panoramic views of Aspire Bay.\n                        <\/p>\n                        <p className=\"text-xs leading-relaxed text-muted-foreground\">\n                            Perfect for families or groups looking for private\n                            beach access combined with high-end modern comforts.\n                            Step onto the sunset terrace to enjoy our heated\n                            infinity pool, fire up the outdoor chef grill, or\n                            follow our private rope path down to direct pink\n                            sand shores.\n                        <\/p>\n                    <\/div>\n\n                    {\/* Amenities list *\/}\n                    <div className=\"space-y-3 border-t border-border\/20 pt-6\">\n                        <h4 className=\"text-[10px] font-bold tracking-wider text-muted-foreground uppercase\">\n                            Premium Amenities\n                        <\/h4>\n                        <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n                            {amenities.map((amenity, idx) => (\n                                <div\n                                    key={idx}\n                                    className=\"flex items-start gap-3 rounded-lg border border-border\/30 bg-muted\/10 p-3 transition-all duration-300 hover:bg-muted\/20\"\n                                >\n                                    <div className=\"flex size-8 shrink-0 items-center justify-center rounded bg-primary\/10\">\n                                        {amenity.icon}\n                                    <\/div>\n                                    <div className=\"min-w-0 space-y-0.5\">\n                                        <h5 className=\"truncate text-xs font-bold text-foreground\">\n                                            {amenity.name}\n                                        <\/h5>\n                                        <p className=\"truncate text-[10px] text-muted-foreground\">\n                                            {amenity.desc}\n                                        <\/p>\n                                    <\/div>\n                                <\/div>\n                            ))}\n                        <\/div>\n                    <\/div>\n                <\/div>\n\n                {\/* Right Side: Booking widget *\/}\n                <div className=\"relative\">\n                    <div className=\"sticky top-24\">\n                        <BookingForm\n                            pricePerNight={280}\n                            cleaningFee={65}\n                            serviceFee={35}\n                        \/>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default PropertyDetail;\n"}],"meta":{"category":"properties","version":"1.0.0"},"categories":["properties"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"rental-listings","type":"registry:block","title":"Rental Listings","description":"A responsive layout showing real estate property rental cards with search filters.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["badge","button","card","input"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/rental-listings\/rental-listings.tsx","type":"registry:block","content":"import React, { useState, useMemo } from 'react';\nimport {\n    Search,\n    Star,\n    MapPin,\n    Wifi,\n    Coffee,\n    Compass,\n    Heart,\n    Eye,\n} from 'lucide-react';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Button } from '@\/components\/ui\/button';\nimport {\n    Card,\n    CardContent,\n    CardFooter,\n    CardHeader,\n} from '@\/components\/ui\/card';\nimport { Input } from '@\/components\/ui\/input';\n\ninterface RentalItem {\n    id: string;\n    name: string;\n    description: string;\n    location: string;\n    price: number;\n    rating: number;\n    reviews: number;\n    category: 'cabin' | 'villa' | 'loft' | 'beachfront';\n    guests: number;\n    beds: number;\n    baths: number;\n    featured: boolean;\n    amenities: string[];\n    gradient: string;\n}\n\nconst LISTINGS_DATA: RentalItem[] = [\n    {\n        id: '1',\n        name: 'Whispering Pines Retreat',\n        description:\n            'Cozy rustic cabin nestled deep in a redwood forest with outdoor stone fireplace and cedar hot tub.',\n        location: 'Redwood Valley, CA',\n        price: 135,\n        rating: 4.92,\n        reviews: 124,\n        category: 'cabin',\n        guests: 4,\n        beds: 2,\n        baths: 1,\n        featured: true,\n        amenities: ['Hot Tub', 'Fireplace', 'Wifi', 'Kitchen'],\n        gradient: 'from-chart-4\/70 via-chart-4 to-primary\/80',\n    },\n    {\n        id: '2',\n        name: 'The Azure Wave Villa',\n        description:\n            'Spectacular infinity-pool seaside villa overlooking crystal blue waves with panoramic glass terrace.',\n        location: 'Amalfi Coast, Italy',\n        price: 280,\n        rating: 4.98,\n        reviews: 86,\n        category: 'villa',\n        guests: 6,\n        beds: 3,\n        baths: 3,\n        featured: true,\n        amenities: ['Pool', 'Sea View', 'Wifi', 'Breakfast'],\n        gradient: 'from-chart-3\/70 via-chart-3 to-primary\/80',\n    },\n    {\n        id: '3',\n        name: 'Celestial Heights Loft',\n        description:\n            'Ultra-modern luxury loft featuring skyscraper skyline view, home theater, and rooftop skydeck.',\n        location: 'Tokyo, Japan',\n        price: 340,\n        rating: 4.89,\n        reviews: 42,\n        category: 'loft',\n        guests: 2,\n        beds: 1,\n        baths: 1.5,\n        featured: false,\n        amenities: ['Sky View', 'Gym', 'Wifi', 'Smart Home'],\n        gradient: 'from-muted via-border\/50 to-primary\/80',\n    },\n    {\n        id: '4',\n        name: 'Coral Sands Beachfront',\n        description:\n            'Step directly onto pink powder sands. A bright beach chalet with hammocks, kayaks, and breeze deck.',\n        location: 'Eleuthera, Bahamas',\n        price: 195,\n        rating: 4.95,\n        reviews: 212,\n        category: 'beachfront',\n        guests: 5,\n        beds: 3,\n        baths: 2,\n        featured: true,\n        amenities: ['Beachfront', 'Kayaks', 'Wifi', 'Air Conditioning'],\n        gradient: 'from-chart-3\/80 via-chart-3 to-chart-2\/80',\n    },\n    {\n        id: '5',\n        name: 'Mountain Crest Lodge',\n        description:\n            'Alpine retreat with ski-in\/ski-out deck, heated floors, and majestic snowy peaks right outside.',\n        location: 'Aspen, CO',\n        price: 245,\n        rating: 4.87,\n        reviews: 73,\n        category: 'cabin',\n        guests: 8,\n        beds: 4,\n        baths: 3.5,\n        featured: false,\n        amenities: ['Ski Access', 'Fireplace', 'Wifi', 'Hot Tub'],\n        gradient: 'from-chart-5\/70 via-chart-5 to-primary\/80',\n    },\n    {\n        id: '6',\n        name: 'Emerald Vista Hideaway',\n        description:\n            'Architectural forest treehouse elevated above the jungle canopy with rain shower and suspension bridge.',\n        location: 'Monteverde, Costa Rica',\n        price: 160,\n        rating: 4.91,\n        reviews: 95,\n        category: 'beachfront',\n        guests: 3,\n        beds: 2,\n        baths: 1,\n        featured: false,\n        amenities: ['Jungle View', 'Wifi', 'Eco-Friendly', 'Deck'],\n        gradient: 'from-chart-2\/70 via-chart-2 to-primary\/80',\n    },\n];\n\nexport function RentalListings() {\n    const [search, setSearch] = useState('');\n    const [selectedCategory, setSelectedCategory] = useState<string>('all');\n    const [favorites, setFavorites] = useState<string[]>([]);\n\n    const toggleFavorite = (id: string) => {\n        setFavorites((prev) =>\n            prev.includes(id)\n                ? prev.filter((fId) => fId !== id)\n                : [...prev, id],\n        );\n    };\n\n    const categories = [\n        { label: 'All Rentals', value: 'all' },\n        { label: 'Cabins', value: 'cabin' },\n        { label: 'Villas', value: 'villa' },\n        { label: 'Lofts', value: 'loft' },\n        { label: 'Beachfront', value: 'beachfront' },\n    ];\n\n    const filteredListings = useMemo(() => {\n        return LISTINGS_DATA.filter((listing) => {\n            const matchesSearch =\n                listing.name.toLowerCase().includes(search.toLowerCase()) ||\n                listing.location.toLowerCase().includes(search.toLowerCase()) ||\n                listing.description\n                    .toLowerCase()\n                    .includes(search.toLowerCase());\n\n            const matchesCategory =\n                selectedCategory === 'all' ||\n                listing.category === selectedCategory;\n\n            return matchesSearch && matchesCategory;\n        });\n    }, [search, selectedCategory]);\n\n    const getAmenityIcon = (amenity: string) => {\n        switch (amenity.toLowerCase()) {\n            case 'wifi':\n                return <Wifi className=\"size-3\" \/>;\n            case 'breakfast':\n            case 'coffee':\n                return <Coffee className=\"size-3\" \/>;\n            default:\n                return <Compass className=\"size-3\" \/>;\n        }\n    };\n\n    return (\n        <div className=\"mx-auto flex w-full max-w-5xl flex-col gap-6 px-4 py-4\">\n            {\/* Header with Search and Category Filter *\/}\n            <div className=\"flex flex-col gap-4 border-b border-border\/20 pb-6 md:flex-row md:items-center md:justify-between\">\n                <div className=\"space-y-1\">\n                    <h2 className=\"text-xl font-bold tracking-tight\">\n                        Rental Getaways\n                    <\/h2>\n                    <p className=\"text-xs text-muted-foreground\">\n                        Find premium cabins, villas, lofts, and unique spaces\n                        around the world\n                    <\/p>\n                <\/div>\n                <div className=\"flex w-full flex-col gap-3 sm:flex-row md:max-w-md\">\n                    <div className=\"relative flex-1\">\n                        <Search className=\"absolute top-2.5 left-3 size-4 text-muted-foreground\" \/>\n                        <Input\n                            placeholder=\"Search locations or listings...\"\n                            value={search}\n                            onChange={(e) => setSearch(e.target.value)}\n                            className=\"h-9 pl-9 text-xs\"\n                        \/>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            {\/* Category Tabs *\/}\n            <div className=\"no-scrollbar flex flex-wrap gap-1.5 overflow-x-auto pb-1\">\n                {categories.map((cat) => (\n                    <Button\n                        key={cat.value}\n                        variant={\n                            selectedCategory === cat.value\n                                ? 'default'\n                                : 'outline'\n                        }\n                        size=\"sm\"\n                        onClick={() => setSelectedCategory(cat.value)}\n                        className=\"h-8 cursor-pointer rounded-full px-4 text-xs select-none\"\n                    >\n                        {cat.label}\n                    <\/Button>\n                ))}\n            <\/div>\n\n            {\/* Listings Grid *\/}\n            {filteredListings.length === 0 ? (\n                <div className=\"rounded-xl border border-dashed border-border\/50 bg-card\/25 py-16 text-center backdrop-blur-xs\">\n                    <p className=\"text-sm text-muted-foreground\">\n                        No rentals match your search filters.\n                    <\/p>\n                    <Button\n                        onClick={() => {\n                            setSearch('');\n                            setSelectedCategory('all');\n                        }}\n                        variant=\"link\"\n                        className=\"mt-2 text-xs\"\n                    >\n                        Clear all filters\n                    <\/Button>\n                <\/div>\n            ) : (\n                <div className=\"grid w-full gap-6 sm:grid-cols-2 lg:grid-cols-3\">\n                    {filteredListings.map((listing) => (\n                        <Card\n                            key={listing.id}\n                            className=\"group relative flex flex-col overflow-hidden border border-border\/40 bg-card\/15 py-0 backdrop-blur-xs transition-all duration-300 hover:border-border\/70 hover:shadow-xl\"\n                        >\n                            {\/* Graphic Vector Representation (Abstract Gradient Image) *\/}\n                            <div\n                                className={`h-48 w-full bg-linear-to-br ${listing.gradient} relative flex items-center justify-center overflow-hidden transition-all duration-500 group-hover:scale-[1.02]`}\n                            >\n                                <div className=\"absolute inset-0 bg-black\/10 transition-opacity group-hover:bg-black\/20\" \/>\n\n                                {\/* Featured Badge *\/}\n                                {listing.featured && (\n                                    <Badge className=\"absolute top-3 left-3 bg-chart-4 px-2 py-0.5 text-[9px] font-bold tracking-wide text-primary-foreground uppercase shadow-md hover:bg-chart-4\/90\">\n                                        \u2605 Featured\n                                    <\/Badge>\n                                )}\n\n                                {\/* Favorite button *\/}\n                                <button\n                                    onClick={() => toggleFavorite(listing.id)}\n                                    className=\"absolute top-3 right-3 flex size-8 cursor-pointer items-center justify-center rounded-full bg-black\/35 text-white backdrop-blur-md transition-colors select-none hover:bg-black\/55\"\n                                >\n                                    <Heart\n                                        className={`size-4 ${favorites.includes(listing.id) ? 'fill-destructive text-destructive' : 'text-white'}`}\n                                    \/>\n                                <\/button>\n\n                                {\/* Location Banner overlay *\/}\n                                <div className=\"absolute right-3 bottom-3 left-3 z-10 flex items-center justify-between text-white\">\n                                    <span className=\"flex items-center gap-1 rounded bg-black\/45 px-2 py-1 text-[10px] font-semibold backdrop-blur-xs\">\n                                        <MapPin className=\"size-3 text-chart-2\" \/>\n                                        {listing.location}\n                                    <\/span>\n                                    <span className=\"rounded-full bg-primary px-2.5 py-1 text-xs font-extrabold text-primary-foreground\">\n                                        ${listing.price}{' '}\n                                        <span className=\"text-[9px] font-normal opacity-85\">\n                                            \/ nt\n                                        <\/span>\n                                    <\/span>\n                                <\/div>\n\n                                {\/* Abstract geometric pattern representing structures *\/}\n                                <div className=\"size-24 scale-75 rotate-45 rounded border border-white\/10 opacity-20 transition-all duration-700 group-hover:scale-90 group-hover:rotate-90\" \/>\n                            <\/div>\n\n                            {\/* Card Content Details *\/}\n                            <CardHeader className=\"space-y-1 p-4 pb-2\">\n                                <div className=\"flex items-center justify-between\">\n                                    <Badge\n                                        variant=\"secondary\"\n                                        className=\"px-2 py-0.5 font-mono text-[9px] tracking-wider capitalize\"\n                                    >\n                                        {listing.category}\n                                    <\/Badge>\n                                    <div className=\"flex items-center gap-1 text-xs\">\n                                        <Star className=\"size-3.5 fill-chart-4 text-chart-4\" \/>\n                                        <span className=\"font-bold text-foreground\">\n                                            {listing.rating}\n                                        <\/span>\n                                        <span className=\"text-[10px] text-muted-foreground\">\n                                            ({listing.reviews})\n                                        <\/span>\n                                    <\/div>\n                                <\/div>\n                                <h3 className=\"mt-1 line-clamp-1 text-sm font-bold tracking-tight text-foreground transition-colors group-hover:text-primary\">\n                                    {listing.name}\n                                <\/h3>\n                            <\/CardHeader>\n\n                            <CardContent className=\"flex flex-1 flex-col gap-3 p-4 pt-0 pb-3\">\n                                <p className=\"line-clamp-2 text-xs leading-relaxed text-muted-foreground\">\n                                    {listing.description}\n                                <\/p>\n\n                                {\/* Space characteristics info *\/}\n                                <div className=\"mt-auto flex gap-3 border-y border-border\/10 py-2 text-[10px] text-muted-foreground\">\n                                    <span>\n                                        <strong>{listing.guests}<\/strong> Guests\n                                    <\/span>\n                                    <span>\u2022<\/span>\n                                    <span>\n                                        <strong>{listing.beds}<\/strong> Beds\n                                    <\/span>\n                                    <span>\u2022<\/span>\n                                    <span>\n                                        <strong>{listing.baths}<\/strong> Baths\n                                    <\/span>\n                                <\/div>\n                            <\/CardContent>\n\n                            <CardFooter className=\"mt-1 flex items-center justify-between gap-2 border-t border-border\/10 p-4 pt-0\">\n                                <div className=\"flex max-w-[65%] gap-1.5 overflow-hidden\">\n                                    {listing.amenities\n                                        .slice(0, 2)\n                                        .map((amenity) => (\n                                            <Badge\n                                                key={amenity}\n                                                variant=\"outline\"\n                                                className=\"flex shrink-0 items-center gap-1 border-border\/30 bg-muted\/5 px-1.5 py-0 text-[9px] font-normal text-muted-foreground\"\n                                            >\n                                                {getAmenityIcon(amenity)}\n                                                {amenity}\n                                            <\/Badge>\n                                        ))}\n                                <\/div>\n                                <Button\n                                    size=\"sm\"\n                                    className=\"h-8 shrink-0 cursor-pointer gap-1 text-xs font-bold\"\n                                >\n                                    <Eye className=\"size-3.5\" \/>\n                                    Details\n                                <\/Button>\n                            <\/CardFooter>\n                        <\/Card>\n                    ))}\n                <\/div>\n            )}\n        <\/div>\n    );\n}\n\nexport default RentalListings;\n"}],"meta":{"category":"properties","version":"1.0.0"},"categories":["properties"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"reviews-slider","type":"registry:block","title":"Reviews Slider","description":"A premium, smooth testimonial reviews slider with star ratings and user profiles.","author":"designbycode","dependencies":["lucide-react","swiper"],"devDependencies":[],"registryDependencies":["card","badge","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/reviews-slider\/reviews-slider.tsx","type":"registry:block","content":"import React, { useState } from 'react';\nimport {\n    Star,\n    CheckCircle,\n    ChevronLeft,\n    ChevronRight,\n    Calendar,\n    Sparkles,\n} from 'lucide-react';\nimport { Card, CardContent } from '@\/components\/ui\/card';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Button } from '@\/components\/ui\/button';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport type { Swiper as SwiperClass } from 'swiper';\n\n\/\/ Import Swiper styles\nimport 'swiper\/css';\n\ninterface Testimonial {\n    id: string;\n    author: string;\n    avatar: string;\n    date: string;\n    rating: number;\n    comment: string;\n    verified: boolean;\n    type: string;\n}\n\nconst REVIEWS_DATA: Testimonial[] = [\n    {\n        id: '1',\n        author: 'Marcus K.',\n        avatar: 'M',\n        date: 'June 2026',\n        rating: 5,\n        comment:\n            'This was by far the best rental space we have reserved. The facilities were clean, and the layout made it extremely easy to host group sessions. Sarah was an amazing host, replying to our queries within minutes. Highly recommended!',\n        verified: true,\n        type: 'Group stay',\n    },\n    {\n        id: '2',\n        author: 'Elena R.',\n        avatar: 'E',\n        date: 'May 2026',\n        rating: 5,\n        comment:\n            'Absolutely stunning views. We woke up every morning to panoramic ocean vistas. The space is extremely modern and well-equipped with premium appliances. We loved the smart-room automation. Will definitely book again next year.',\n        verified: true,\n        type: 'Premium booking',\n    },\n    {\n        id: '3',\n        author: 'David P.',\n        avatar: 'D',\n        date: 'April 2026',\n        rating: 4.8,\n        comment:\n            'Clean, peaceful, and beautifully designed. The cedar hot tub and outdoor fireplace in the pines cabin were perfect for relaxing after a long day of hiking. The check-in process was smooth via smart lock.',\n        verified: true,\n        type: 'Solo booking',\n    },\n];\n\nexport function ReviewsSlider() {\n    const [swiper, setSwiper] = useState<SwiperClass | null>(null);\n    const [activeIndex, setActiveIndex] = useState(0);\n\n    const nextReview = () => {\n        swiper?.slideNext();\n    };\n\n    const prevReview = () => {\n        swiper?.slidePrev();\n    };\n\n    const goToReview = (index: number) => {\n        swiper?.slideTo(index);\n    };\n\n    const ratings = [\n        { label: 'Cleanliness', value: 4.9 },\n        { label: 'Accuracy', value: 4.8 },\n        { label: 'Communication', value: 5.0 },\n        { label: 'Location', value: 4.9 },\n        { label: 'Value', value: 4.7 },\n    ];\n\n    const getPriorityBadge = (rating: number) => {\n        return (\n            <div className=\"flex items-center gap-0.5 text-chart-4\">\n                {[...Array(5)].map((_, i) => (\n                    <Star\n                        key={i}\n                        className={`size-4.5 ${i < Math.floor(rating) ? 'fill-current' : 'opacity-30'}`}\n                    \/>\n                ))}\n                <span className=\"ml-1.5 text-xs font-bold text-foreground\">\n                    {rating} Rating\n                <\/span>\n            <\/div>\n        );\n    };\n\n    return (\n        <div className=\"mx-auto w-full max-w-5xl space-y-8 px-4 py-4\">\n            {\/* Reviews Header and Stats *\/}\n            <div className=\"grid grid-cols-1 items-center gap-6 border-b border-border\/20 pb-6 md:grid-cols-3\">\n                <div className=\"space-y-2 text-center select-none md:text-left\">\n                    <h3 className=\"text-xl font-bold tracking-tight\">\n                        Client Testimonials\n                    <\/h3>\n                    <p className=\"text-xs text-muted-foreground\">\n                        What our customers say about their experiences\n                    <\/p>\n                    <div className=\"mt-1 flex items-center justify-center gap-2 md:justify-start\">\n                        <span className=\"text-3xl font-extrabold text-foreground\">\n                            4.92\n                        <\/span>\n                        <div className=\"flex flex-col text-left\">\n                            <div className=\"flex items-center text-chart-4\">\n                                {[...Array(5)].map((_, i) => (\n                                    <Star\n                                        key={i}\n                                        className=\"size-3.5 fill-current\"\n                                    \/>\n                                ))}\n                            <\/div>\n                            <span className=\"text-[10px] text-muted-foreground\">\n                                Based on 280+ ratings\n                            <\/span>\n                        <\/div>\n                    <\/div>\n                <\/div>\n\n                <div className=\"space-y-2 select-none md:col-span-2\">\n                    <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n                        {ratings.map((rate) => (\n                            <div\n                                key={rate.label}\n                                className=\"flex flex-col gap-1 rounded-lg border border-border\/40 bg-card\/15 p-2.5\"\n                            >\n                                <span className=\"text-[10px] font-bold tracking-wider text-muted-foreground uppercase\">\n                                    {rate.label}\n                                <\/span>\n                                <div className=\"flex items-center gap-2\">\n                                    <div className=\"h-1.5 flex-1 overflow-hidden rounded-full bg-muted\">\n                                        <div\n                                            className=\"h-full bg-primary\"\n                                            style={{\n                                                width: `${(rate.value \/ 5) * 100}%`,\n                                            }}\n                                        \/>\n                                    <\/div>\n                                    <span className=\"font-mono text-xs font-bold\">\n                                        {rate.value}\n                                    <\/span>\n                                <\/div>\n                            <\/div>\n                        ))}\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            {\/* Interactive Swiper Card Slider *\/}\n            <div className=\"relative mx-auto w-full max-w-2xl\">\n                <Swiper\n                    onSwiper={setSwiper}\n                    onSlideChange={(s) => setActiveIndex(s.activeIndex)}\n                    className=\"w-full\"\n                    spaceBetween={30}\n                    slidesPerView={1}\n                    loop={false}\n                >\n                    {REVIEWS_DATA.map((review) => (\n                        <SwiperSlide key={review.id} className=\"px-1 py-2\">\n                            <Card className=\"overflow-hidden border border-border\/40 bg-card\/25 p-6 shadow-lg backdrop-blur-xs transition-all duration-300 select-none md:p-8\">\n                                <div className=\"absolute top-4 right-4 text-primary\/10\">\n                                    <Sparkles className=\"size-16\" \/>\n                                <\/div>\n\n                                <CardContent className=\"relative z-10 space-y-6 p-0\">\n                                    {\/* Rating Stars *\/}\n                                    {getPriorityBadge(review.rating)}\n\n                                    {\/* Comment Text *\/}\n                                    <blockquote className=\"text-sm leading-relaxed text-muted-foreground italic\">\n                                        \"{review.comment}\"\n                                    <\/blockquote>\n\n                                    {\/* Guest Meta info *\/}\n                                    <div className=\"flex flex-wrap items-center justify-between gap-3 border-t border-border\/10 pt-4\">\n                                        <div className=\"flex items-center gap-3\">\n                                            <div className=\"flex size-10 items-center justify-center rounded-full border border-primary\/20 bg-primary\/10 text-sm font-extrabold text-primary\">\n                                                {review.avatar}\n                                            <\/div>\n                                            <div className=\"space-y-0.5 text-left\">\n                                                <div className=\"flex items-center gap-1.5\">\n                                                    <h4 className=\"text-xs font-bold text-foreground\">\n                                                        {review.author}\n                                                    <\/h4>\n                                                    {review.verified && (\n                                                        <Badge\n                                                            variant=\"outline\"\n                                                            className=\"flex items-center gap-0.5 border-primary\/20 bg-primary\/5 px-1 py-0 text-[8px] font-normal text-primary\"\n                                                        >\n                                                            <CheckCircle className=\"size-2.5 fill-current\" \/>\n                                                            Verified Client\n                                                        <\/Badge>\n                                                    )}\n                                                <\/div>\n                                                <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n                                                    <Calendar className=\"size-3\" \/>\n                                                    <span>\n                                                        Reserved in{' '}\n                                                        {review.date}\n                                                    <\/span>\n                                                <\/div>\n                                            <\/div>\n                                        <\/div>\n                                        <Badge\n                                            variant=\"secondary\"\n                                            className=\"px-2 py-0.5 font-mono text-[9px]\"\n                                        >\n                                            {review.type}\n                                        <\/Badge>\n                                    <\/div>\n                                <\/CardContent>\n                            <\/Card>\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n\n                {\/* Slider Navigation & Pagination Controls *\/}\n                <div className=\"mt-4 flex items-center justify-between px-2 select-none\">\n                    <div className=\"flex gap-1\">\n                        {REVIEWS_DATA.map((_, idx) => (\n                            <button\n                                key={idx}\n                                onClick={() => goToReview(idx)}\n                                className={`h-1.5 cursor-pointer rounded-full transition-all duration-300 ${\n                                    activeIndex === idx\n                                        ? 'w-6 bg-primary'\n                                        : 'w-1.5 bg-muted-foreground\/30 hover:bg-muted-foreground\/60'\n                                }`}\n                            \/>\n                        ))}\n                    <\/div>\n                    <div className=\"flex gap-1.5\">\n                        <Button\n                            onClick={prevReview}\n                            variant=\"outline\"\n                            size=\"icon\"\n                            disabled={activeIndex === 0}\n                            className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted disabled:pointer-events-none disabled:opacity-40\"\n                        >\n                            <ChevronLeft className=\"size-4\" \/>\n                        <\/Button>\n                        <Button\n                            onClick={nextReview}\n                            variant=\"outline\"\n                            size=\"icon\"\n                            disabled={activeIndex === REVIEWS_DATA.length - 1}\n                            className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted disabled:pointer-events-none disabled:opacity-40\"\n                        >\n                            <ChevronRight className=\"size-4\" \/>\n                        <\/Button>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default ReviewsSlider;\n"}],"meta":{"category":"reviews","version":"1.0.0"},"categories":["reviews"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"stats-grid","type":"registry:block","title":"Stats Grid","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/stats-grid\/stats-grid.tsx","type":"registry:block","content":"'use client';\n\nimport React from 'react';\nimport { Card, CardContent } from '@\/components\/ui\/card';\n\ninterface StatItem {\n    value: string;\n    label: string;\n    description: string;\n}\n\nconst stats: StatItem[] = [\n    {\n        value: '99.99%',\n        label: 'System Uptime',\n        description: 'Guaranteed by SLA',\n    },\n    {\n        value: '150M+',\n        label: 'Monthly Queries',\n        description: 'Processed globally',\n    },\n    { value: '10k+', label: 'Active Devs', description: 'Building workspaces' },\n    { value: '24\/7', label: 'Support SLA', description: 'Always online' },\n];\n\nexport function StatsGrid() {\n    return (\n        <div className=\"w-full\">\n            <div className=\"grid grid-cols-2 gap-4 md:grid-cols-4\">\n                {stats.map((stat, idx) => (\n                    <Card\n                        key={idx}\n                        className=\"border-border\/50 bg-card\/30 p-4 text-center backdrop-blur-xs\"\n                    >\n                        <CardContent className=\"p-0\">\n                            <div className=\"font-mono text-2xl font-black tracking-tight text-primary md:text-3xl\">\n                                {stat.value}\n                            <\/div>\n                            <div className=\"mt-1 text-xs font-bold text-foreground\">\n                                {stat.label}\n                            <\/div>\n                            <div className=\"mt-0.5 text-[10px] text-muted-foreground\">\n                                {stat.description}\n                            <\/div>\n                        <\/CardContent>\n                    <\/Card>\n                ))}\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default StatsGrid;\n"}],"meta":{"category":"stats-grid","version":"1.0.0"},"categories":["stats-grid"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"testimonials-grid","type":"registry:block","title":"Testimonials Grid","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/testimonials-grid\/testimonials-grid.tsx","type":"registry:block","content":"'use client';\n\nimport React from 'react';\nimport { Star, Quote } from 'lucide-react';\nimport {\n    Card,\n    CardContent,\n    CardHeader,\n    CardTitle,\n    CardDescription,\n} from '@\/components\/ui\/card';\n\ninterface Testimonial {\n    name: string;\n    role: string;\n    avatarText: string;\n    content: string;\n    rating: number;\n}\n\nconst testimonials: Testimonial[] = [\n    {\n        name: 'Alex Rivera',\n        role: 'Founder at DevFlow',\n        avatarText: 'AR',\n        content:\n            'This styling registry has completely transformed how our team develops dashboards. The ease of switching theme variables saved us weeks of design time.',\n        rating: 5,\n    },\n    {\n        name: 'Sarah Chen',\n        role: 'Lead Frontend Architect',\n        avatarText: 'SC',\n        content:\n            'The component curation is incredible. Everything is built natively with shadcn guidelines and is highly responsive using tailwind container queries.',\n        rating: 5,\n    },\n    {\n        name: 'Marcus Brody',\n        role: 'Product Designer at Peak',\n        avatarText: 'MB',\n        content:\n            'I love how clean the markup is. No redundant nesting, pure Tailwind CSS variables, and instant installation commands that work out of the box.',\n        rating: 5,\n    },\n];\n\nexport function TestimonialsGrid() {\n    return (\n        <div className=\"w-full\">\n            <div className=\"grid grid-cols-1 gap-6 md:grid-cols-3\">\n                {testimonials.map((item, idx) => (\n                    <Card\n                        key={idx}\n                        className=\"group relative overflow-hidden border-border\/50 bg-card\/30 backdrop-blur-xs transition-all duration-300 hover:border-primary\/30\"\n                    >\n                        <Quote className=\"pointer-events-none absolute top-4 right-4 size-10 text-foreground opacity-[0.03]\" \/>\n                        <CardHeader className=\"pb-3\">\n                            <div className=\"mb-2 flex items-center gap-1.5 text-chart-4\">\n                                {Array.from({ length: item.rating }).map(\n                                    (_, i) => (\n                                        <Star\n                                            key={i}\n                                            className=\"size-3.5 fill-current\"\n                                        \/>\n                                    ),\n                                )}\n                            <\/div>\n                            <div className=\"flex items-center gap-3\">\n                                <div className=\"flex size-8 items-center justify-center rounded-full bg-primary\/10 text-xs font-bold text-primary select-none\">\n                                    {item.avatarText}\n                                <\/div>\n                                <div className=\"min-w-0\">\n                                    <CardTitle className=\"truncate text-xs font-bold text-foreground\">\n                                        {item.name}\n                                    <\/CardTitle>\n                                    <CardDescription className=\"truncate text-[9px]\">\n                                        {item.role}\n                                    <\/CardDescription>\n                                <\/div>\n                            <\/div>\n                        <\/CardHeader>\n                        <CardContent>\n                            <p className=\"text-xs leading-relaxed text-muted-foreground\">\n                                \"{item.content}\"\n                            <\/p>\n                        <\/CardContent>\n                    <\/Card>\n                ))}\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default TestimonialsGrid;\n"}],"meta":{"category":"testimonials-grid","version":"1.0.0"},"categories":["testimonials-grid"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"user-profile-card","type":"registry:block","title":"User Profile Card","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["card","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/blocks\/user-profile-card\/user-profile-card.tsx","type":"registry:block","content":"'use client';\n\nimport React from 'react';\nimport { User, Heart, MessageSquare } from 'lucide-react';\nimport { Card, CardContent } from '@\/components\/ui\/card';\nimport { Button } from '@\/components\/ui\/button';\n\nexport function UserProfileCard() {\n    return (\n        <Card className=\"relative mx-auto w-full max-w-sm overflow-hidden border-border\/50 bg-card\/30 py-0 backdrop-blur-xs\">\n            {\/* Cover photo placeholder *\/}\n            <div className=\"relative h-32 w-full bg-linear-to-r from-primary\/30 to-accent\/30\" \/>\n\n            <CardContent className=\"pt-0 pb-6 text-center\">\n                {\/* Profile Photo *\/}\n                <div className=\"relative mx-auto -mt-14 flex size-16 items-center justify-center rounded-full border-2 border-border\/80 bg-background text-lg font-bold text-primary shadow-sm\">\n                    <User className=\"size-8\" \/>\n                <\/div>\n\n                <div className=\"mt-2.5\">\n                    <h4 className=\"text-sm font-bold text-foreground\">\n                        Sarah Jenkins\n                    <\/h4>\n                    <p className=\"text-[10px] text-muted-foreground\">\n                        Product Designer @ Peak\n                    <\/p>\n                <\/div>\n\n                <p className=\"mx-auto mt-3 max-w-xs text-[10px] leading-relaxed text-muted-foreground\/90\">\n                    UX\/UI enthusiast. Currently designing fluid responsive\n                    developer workspaces and styling libraries.\n                <\/p>\n\n                {\/* Profile metrics *\/}\n                <div className=\"mt-4 grid grid-cols-3 gap-2 border-y border-border\/20 py-2.5\">\n                    <div>\n                        <div className=\"text-xs font-black text-foreground\">\n                            4.8k\n                        <\/div>\n                        <div className=\"mt-0.5 text-[8px] font-bold text-muted-foreground uppercase\">\n                            Followers\n                        <\/div>\n                    <\/div>\n                    <div>\n                        <div className=\"text-xs font-black text-foreground\">\n                            124\n                        <\/div>\n                        <div className=\"mt-0.5 text-[8px] font-bold text-muted-foreground uppercase\">\n                            Projects\n                        <\/div>\n                    <\/div>\n                    <div>\n                        <div className=\"text-xs font-black text-foreground\">\n                            12\n                        <\/div>\n                        <div className=\"mt-0.5 text-[8px] font-bold text-muted-foreground uppercase\">\n                            Awards\n                        <\/div>\n                    <\/div>\n                <\/div>\n\n                <div className=\"mt-4 flex justify-center gap-2\">\n                    <Button\n                        size=\"sm\"\n                        className=\"h-8 gap-1.5 px-3.5 text-xs font-bold\"\n                    >\n                        <Heart className=\"size-3.5\" \/>\n                        Follow\n                    <\/Button>\n                    <Button\n                        size=\"sm\"\n                        variant=\"outline\"\n                        className=\"h-8 gap-1.5 border-border\/60 px-3.5 text-xs font-bold\"\n                    >\n                        <MessageSquare className=\"size-3.5\" \/>\n                        Message\n                    <\/Button>\n                <\/div>\n            <\/CardContent>\n        <\/Card>\n    );\n}\n\nexport default UserProfileCard;\n"}],"meta":{"category":"user-profile-card","version":"1.0.0"},"categories":["user-profile-card"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gsap-marquee","type":"registry:ui","title":"Gsap Marquee","description":"A high-performance GSAP-powered horizontal scrolling marquee component.","author":"designbycode","dependencies":["gsap"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/animations\/gsap-marquee.tsx","type":"registry:ui","content":"'use client';\n\nimport { gsap } from 'gsap';\nimport * as React from 'react';\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { cn } from '@\/lib\/utils';\n\n\/\/ ============================================================================\n\/\/ TYPES & INTERFACES\n\/\/ ============================================================================\n\nexport type MarqueeDirection = 'left' | 'right' | 'up' | 'down';\nexport type MarqueeLoopMode = 'continuous' | 'yoyo';\nexport type MarqueeEasing =\n    | 'none'\n    | 'power1.inOut'\n    | 'power2.inOut'\n    | 'power3.inOut'\n    | 'elastic.out'\n    | 'bounce.out'\n    | 'back.inOut';\n\nexport interface GSAPMarqueeProps {\n    \/** Content to be displayed in the marquee *\/\n    children: React.ReactNode;\n    \/** Direction of movement *\/\n    direction?: MarqueeDirection;\n    \/** Loop mode: continuous or yoyo (ping-pong) *\/\n    loopMode?: MarqueeLoopMode;\n    \/** Base duration in seconds for one complete cycle *\/\n    duration?: number;\n    \/** Gap between repeated items (in pixels or CSS value) *\/\n    gap?: number;\n    \/** Number of times to repeat the content *\/\n    repeat?: number;\n    \/** Pause animation on hover *\/\n    pauseOnHover?: boolean;\n    \/** Enable scroll-based velocity adjustment *\/\n    scrollVelocity?: boolean;\n    \/** Multiplier for scroll velocity effect (higher = more responsive) *\/\n    velocityMultiplier?: number;\n    \/** Maximum velocity cap to prevent extreme speeds *\/\n    maxVelocity?: number;\n    \/** Minimum velocity (can be negative for reverse on scroll) *\/\n    minVelocity?: number;\n    \/** GSAP easing function for yoyo mode *\/\n    easing?: MarqueeEasing;\n    \/** Delay before animation starts (in seconds) *\/\n    delay?: number;\n    \/** Whether the animation should start automatically *\/\n    autoPlay?: boolean;\n    \/** Callback when animation completes one cycle *\/\n    onCycleComplete?: () => void;\n    \/** Callback when animation updates *\/\n    onUpdate?: (progress: number) => void;\n    \/** Additional class names for the container *\/\n    className?: string;\n    \/** Additional class names for the track *\/\n    trackClassName?: string;\n    \/** Additional class names for individual items *\/\n    itemClassName?: string;\n    \/** Enable GPU acceleration *\/\n    useGPU?: boolean;\n    \/** Scrub animation to scroll position (0-1 for smoothness, true for instant) *\/\n    scrub?: boolean | number;\n    \/** Reverse the default direction *\/\n    reverse?: boolean;\n}\n\nexport interface GSAPMarqueeRef {\n    \/** Play the animation *\/\n    play: () => void;\n    \/** Pause the animation *\/\n    pause: () => void;\n    \/** Reverse the animation direction *\/\n    reverse: () => void;\n    \/** Seek to a specific progress (0-1) *\/\n    seek: (progress: number) => void;\n    \/** Get current progress (0-1) *\/\n    getProgress: () => number;\n    \/** Set animation speed (1 = normal, 2 = double speed, etc.) *\/\n    setSpeed: (speed: number) => void;\n    \/** Kill the animation and clean up *\/\n    kill: () => void;\n    \/** Restart the animation *\/\n    restart: () => void;\n}\n\n\/\/ ============================================================================\n\/\/ UTILITY HOOKS\n\/\/ ============================================================================\n\nfunction useScrollVelocity(\n    enabled: boolean,\n    multiplier: number,\n    maxVelocity: number,\n    minVelocity: number,\n) {\n    const velocityRef = useRef(1);\n    const lastScrollY = useRef(0);\n    const lastTime = useRef(0);\n    const rafId = useRef<number | null>(null);\n\n    useEffect(() => {\n        if (!enabled) {\n            return;\n        }\n\n        lastTime.current = Date.now();\n\n        const calculateVelocity = () => {\n            const currentScrollY = window.scrollY;\n            const currentTime = Date.now();\n            const deltaY = Math.abs(currentScrollY - lastScrollY.current);\n            const deltaTime = currentTime - lastTime.current;\n\n            if (deltaTime > 0) {\n                const rawVelocity = (deltaY \/ deltaTime) * multiplier;\n                const targetVelocity = Math.max(\n                    minVelocity,\n                    Math.min(maxVelocity, 1 + rawVelocity),\n                );\n\n                \/\/ Smooth interpolation\n                velocityRef.current = gsap.utils.interpolate(\n                    velocityRef.current,\n                    targetVelocity,\n                    0.1,\n                );\n            }\n\n            lastScrollY.current = currentScrollY;\n            lastTime.current = currentTime;\n            rafId.current = requestAnimationFrame(calculateVelocity);\n        };\n\n        rafId.current = requestAnimationFrame(calculateVelocity);\n\n        return () => {\n            if (rafId.current) {\n                cancelAnimationFrame(rafId.current);\n            }\n        };\n    }, [enabled, multiplier, maxVelocity, minVelocity]);\n\n    return velocityRef;\n}\n\n\/\/ ============================================================================\n\/\/ MAIN COMPONENT\n\/\/ ============================================================================\n\nexport const GSAPMarquee = React.forwardRef<GSAPMarqueeRef, GSAPMarqueeProps>(\n    (\n        {\n            children,\n            direction = 'left',\n            loopMode = 'continuous',\n            duration = 20,\n            gap = 24,\n            repeat = 4,\n            pauseOnHover = true,\n            scrollVelocity = false,\n            velocityMultiplier = 0.5,\n            maxVelocity = 5,\n            minVelocity = 0.2,\n            easing = 'none',\n            delay = 0,\n            autoPlay = true,\n            onCycleComplete,\n            onUpdate,\n            className,\n            trackClassName,\n            itemClassName,\n            useGPU = true,\n            reverse = false,\n            scrub = false,\n        },\n        ref,\n    ) => {\n        const containerRef = useRef<HTMLDivElement>(null);\n        const trackRef = useRef<HTMLDivElement>(null);\n        const tweenRef = useRef<gsap.core.Tween | gsap.core.Timeline | null>(\n            null,\n        );\n        const velocityRef = useScrollVelocity(\n            scrollVelocity,\n            velocityMultiplier,\n            maxVelocity,\n            minVelocity,\n        );\n        const isPausedRef = useRef(false);\n\n        const isHorizontal = direction === 'left' || direction === 'right';\n        const isPositive = direction === 'right' || direction === 'down';\n        const actualDirection = reverse ? !isPositive : isPositive;\n\n        \/\/ Calculate animation properties\n        const animationProps = useMemo(() => {\n            const prop = isHorizontal ? 'xPercent' : 'yPercent';\n            const startValue = actualDirection ? -100 \/ repeat : 0;\n            const endValue = actualDirection ? 0 : -100 \/ repeat;\n\n            return { prop, startValue, endValue };\n        }, [isHorizontal, actualDirection, repeat]);\n\n        \/\/ Create and manage animation\n        useEffect(() => {\n            if (!trackRef.current) {\n                return;\n            }\n\n            const track = trackRef.current;\n            const { prop, startValue, endValue } = animationProps;\n\n            \/\/ Set initial position\n            gsap.set(track, { [prop]: startValue });\n\n            \/\/ Create the animation\n            if (loopMode === 'continuous') {\n                tweenRef.current = gsap.to(track, {\n                    [prop]: endValue,\n                    duration,\n                    ease: 'none',\n                    repeat: -1,\n                    delay,\n                    force3D: useGPU,\n                    onRepeat: onCycleComplete,\n                    onUpdate: () => {\n                        if (onUpdate && tweenRef.current) {\n                            onUpdate(tweenRef.current.progress());\n                        }\n                    },\n                });\n            } else {\n                \/\/ Yoyo mode\n                tweenRef.current = gsap.to(track, {\n                    [prop]: endValue,\n                    duration,\n                    ease: easing,\n                    repeat: -1,\n                    yoyo: true,\n                    delay,\n                    force3D: useGPU,\n                    onRepeat: onCycleComplete,\n                    onUpdate: () => {\n                        if (onUpdate && tweenRef.current) {\n                            onUpdate(tweenRef.current.progress());\n                        }\n                    },\n                });\n            }\n\n            if (!autoPlay) {\n                tweenRef.current.pause();\n            }\n\n            return () => {\n                tweenRef.current?.kill();\n            };\n        }, [\n            animationProps,\n            duration,\n            loopMode,\n            easing,\n            delay,\n            autoPlay,\n            useGPU,\n            onCycleComplete,\n            onUpdate,\n        ]);\n\n        \/\/ Handle scroll velocity\n        useEffect(() => {\n            if (!scrollVelocity || !tweenRef.current) {\n                return;\n            }\n\n            const updateVelocity = () => {\n                if (tweenRef.current && !isPausedRef.current) {\n                    tweenRef.current.timeScale(velocityRef.current);\n                }\n\n                requestAnimationFrame(updateVelocity);\n            };\n\n            const rafId = requestAnimationFrame(updateVelocity);\n\n            return () => cancelAnimationFrame(rafId);\n        }, [scrollVelocity, velocityRef]);\n\n        \/\/ Handle scrub\n        useEffect(() => {\n            if (!scrub || !trackRef.current) {\n                return;\n            }\n\n            const { prop, startValue, endValue } = animationProps;\n\n            \/\/ Kill existing tween for scrub mode\n            tweenRef.current?.kill();\n\n            const handleScroll = () => {\n                const scrollProgress =\n                    window.scrollY \/\n                    (document.body.scrollHeight - window.innerHeight);\n                const value = gsap.utils.interpolate(\n                    startValue,\n                    endValue,\n                    scrollProgress,\n                );\n\n                if (typeof scrub === 'number') {\n                    gsap.to(trackRef.current, {\n                        [prop]: value,\n                        duration: scrub,\n                        ease: 'power2.out',\n                        overwrite: true,\n                    });\n                } else {\n                    gsap.set(trackRef.current, { [prop]: value });\n                }\n            };\n\n            window.addEventListener('scroll', handleScroll, { passive: true });\n\n            return () => window.removeEventListener('scroll', handleScroll);\n        }, [scrub, animationProps]);\n\n        \/\/ Hover handlers\n        const handleMouseEnter = useCallback(() => {\n            if (pauseOnHover && tweenRef.current) {\n                isPausedRef.current = true;\n                gsap.to(tweenRef.current, {\n                    timeScale: 0,\n                    duration: 0.5,\n                    ease: 'power2.out',\n                });\n            }\n        }, [pauseOnHover]);\n\n        const handleMouseLeave = useCallback(() => {\n            if (pauseOnHover && tweenRef.current) {\n                isPausedRef.current = false;\n                gsap.to(tweenRef.current, {\n                    timeScale: scrollVelocity ? velocityRef.current : 1,\n                    duration: 0.5,\n                    ease: 'power2.out',\n                });\n            }\n        }, [pauseOnHover, scrollVelocity, velocityRef]);\n\n        \/\/ Expose imperative handle\n        React.useImperativeHandle(ref, () => ({\n            play: () => {\n                isPausedRef.current = false;\n                tweenRef.current?.play();\n            },\n            pause: () => {\n                isPausedRef.current = true;\n                tweenRef.current?.pause();\n            },\n            reverse: () => {\n                tweenRef.current?.reverse();\n            },\n            seek: (progress: number) => {\n                tweenRef.current?.progress(progress);\n            },\n            getProgress: () => tweenRef.current?.progress() ?? 0,\n            setSpeed: (speed: number) => {\n                tweenRef.current?.timeScale(speed);\n            },\n            kill: () => {\n                tweenRef.current?.kill();\n            },\n            restart: () => {\n                tweenRef.current?.restart();\n            },\n        }));\n\n        \/\/ Generate repeated children\n        const repeatedChildren = useMemo(() => {\n            return Array.from({ length: repeat }, (_, i) => (\n                <div\n                    key={i}\n                    className={cn(\n                        'shrink-0',\n                        isHorizontal\n                            ? 'flex items-center'\n                            : 'flex flex-col items-center',\n                        itemClassName,\n                    )}\n                    style={{\n                        [isHorizontal ? 'paddingRight' : 'paddingBottom']: gap,\n                    }}\n                >\n                    {children}\n                <\/div>\n            ));\n        }, [children, repeat, gap, isHorizontal, itemClassName]);\n\n        return (\n            <div\n                ref={containerRef}\n                className={cn(\n                    'overflow-hidden',\n                    isHorizontal ? 'w-full' : 'h-full',\n                    className,\n                )}\n                onMouseEnter={handleMouseEnter}\n                onMouseLeave={handleMouseLeave}\n            >\n                <div\n                    ref={trackRef}\n                    className={cn(\n                        'flex will-change-transform',\n                        isHorizontal ? 'flex-row' : 'flex-col',\n                        trackClassName,\n                    )}\n                    style={{\n                        [isHorizontal ? 'width' : 'height']: `${repeat * 100}%`,\n                    }}\n                >\n                    {repeatedChildren}\n                <\/div>\n            <\/div>\n        );\n    },\n);\n\nGSAPMarquee.displayName = 'GSAPMarquee';\n\n\/\/ ============================================================================\n\/\/ PRESET COMPONENTS\n\/\/ ============================================================================\n\nexport interface MarqueeTextProps extends Omit<GSAPMarqueeProps, 'children'> {\n    text: string;\n    separator?: React.ReactNode;\n    textClassName?: string;\n}\n\nexport function MarqueeText({\n    text,\n    separator = <span className=\"px-8 text-muted-foreground\/50\">\u2022<\/span>,\n    textClassName,\n    ...props\n}: MarqueeTextProps) {\n    return (\n        <GSAPMarquee {...props}>\n            <span\n                className={cn(\n                    'whitespace-nowrap text-foreground',\n                    textClassName,\n                )}\n            >\n                {text}\n            <\/span>\n            {separator}\n        <\/GSAPMarquee>\n    );\n}\n\nexport interface MarqueeImagesProps extends Omit<GSAPMarqueeProps, 'children'> {\n    images: Array<{\n        src: string;\n        alt: string;\n        width?: number;\n        height?: number;\n    }>;\n    imageClassName?: string;\n}\n\nexport function MarqueeImages({\n    images,\n    imageClassName,\n    gap = 32,\n    ...props\n}: MarqueeImagesProps) {\n    return (\n        <GSAPMarquee gap={gap} {...props}>\n            <div className=\"flex items-center gap-8\">\n                {images.map((image, index) => (\n                    <img\n                        key={index}\n                        src={image.src}\n                        alt={image.alt}\n                        width={image.width}\n                        height={image.height}\n                        className={cn(\n                            'h-12 w-auto object-contain grayscale transition-all duration-300 hover:grayscale-0',\n                            imageClassName,\n                        )}\n                    \/>\n                ))}\n            <\/div>\n        <\/GSAPMarquee>\n    );\n}\n\nexport interface MarqueeCardsProps extends Omit<GSAPMarqueeProps, 'children'> {\n    cards: Array<{\n        id: string | number;\n        content: React.ReactNode;\n    }>;\n    cardClassName?: string;\n}\n\nexport function MarqueeCards({\n    cards,\n    cardClassName,\n    gap = 24,\n    ...props\n}: MarqueeCardsProps) {\n    return (\n        <GSAPMarquee gap={gap} {...props}>\n            <div\n                className={cn(\n                    'flex items-stretch',\n                    props.direction === 'up' || props.direction === 'down'\n                        ? 'flex-col gap-6'\n                        : 'gap-6',\n                )}\n            >\n                {cards.map((card) => (\n                    <div\n                        key={card.id}\n                        className={cn(\n                            'shrink-0 rounded-xl border border-border bg-card p-6 shadow-sm',\n                            cardClassName,\n                        )}\n                    >\n                        {card.content}\n                    <\/div>\n                ))}\n            <\/div>\n        <\/GSAPMarquee>\n    );\n}\n\n\/\/ ============================================================================\n\/\/ STAGGERED MARQUEE (Multiple rows with different speeds)\n\/\/ ============================================================================\n\nexport interface StaggeredMarqueeProps {\n    rows: Array<{\n        children: React.ReactNode;\n        direction?: MarqueeDirection;\n        duration?: number;\n        reverse?: boolean;\n    }>;\n    gap?: number;\n    rowGap?: number;\n    className?: string;\n    pauseOnHover?: boolean;\n    scrollVelocity?: boolean;\n}\n\nexport function StaggeredMarquee({\n    rows,\n    gap = 24,\n    rowGap = 16,\n    className,\n    pauseOnHover = true,\n    scrollVelocity = false,\n}: StaggeredMarqueeProps) {\n    return (\n        <div className={cn('flex flex-col', className)} style={{ gap: rowGap }}>\n            {rows.map((row, index) => (\n                <GSAPMarquee\n                    key={index}\n                    direction={row.direction ?? 'left'}\n                    duration={row.duration ?? 20 + index * 5}\n                    reverse={row.reverse}\n                    gap={gap}\n                    pauseOnHover={pauseOnHover}\n                    scrollVelocity={scrollVelocity}\n                >\n                    {row.children}\n                <\/GSAPMarquee>\n            ))}\n        <\/div>\n    );\n}\n\n\/\/ ============================================================================\n\/\/ VERTICAL SCROLL MARQUEE (Scroll-triggered)\n\/\/ ============================================================================\n\nexport interface ScrollTriggeredMarqueeProps extends GSAPMarqueeProps {\n    \/** Start position (e.g., \"top bottom\" means animation starts when top of element hits bottom of viewport) *\/\n    start?: string;\n    \/** End position *\/\n    end?: string;\n    \/** Pin the element during scroll *\/\n    pin?: boolean;\n}\n\nexport function ScrollTriggeredMarquee({\n    start = 'top bottom',\n    end = 'bottom top',\n    pin = false,\n    children,\n    ...props\n}: ScrollTriggeredMarqueeProps) {\n    const containerRef = useRef<HTMLDivElement>(null);\n    const trackRef = useRef<HTMLDivElement>(null);\n\n    useEffect(() => {\n        if (!containerRef.current || !trackRef.current) {\n            return;\n        }\n\n        const isHorizontal =\n            props.direction === 'left' ||\n            props.direction === 'right' ||\n            !props.direction;\n        const prop = isHorizontal ? 'xPercent' : 'yPercent';\n        const repeat = props.repeat ?? 4;\n        const isPositive =\n            props.direction === 'right' || props.direction === 'down';\n        const startValue = isPositive ? -100 \/ repeat : 0;\n        const endValue = isPositive ? 0 : -100 \/ repeat;\n\n        \/\/ Dynamic import ScrollTrigger\n        import('gsap\/ScrollTrigger').then(({ ScrollTrigger }) => {\n            gsap.registerPlugin(ScrollTrigger);\n\n            const tween = gsap.fromTo(\n                trackRef.current,\n                { [prop]: startValue },\n                {\n                    [prop]: endValue,\n                    ease: 'none',\n                    scrollTrigger: {\n                        trigger: containerRef.current,\n                        start,\n                        end,\n                        scrub: props.scrub ?? 1,\n                        pin,\n                    },\n                },\n            );\n\n            return () => {\n                tween.kill();\n                ScrollTrigger.getAll().forEach((st) => st.kill());\n            };\n        });\n    }, [props.direction, props.repeat, props.scrub, start, end, pin]);\n\n    const isHorizontal =\n        props.direction === 'left' ||\n        props.direction === 'right' ||\n        !props.direction;\n    const repeat = props.repeat ?? 4;\n    const gap = props.gap ?? 24;\n\n    const repeatedChildren = useMemo(() => {\n        return Array.from({ length: repeat }, (_, i) => (\n            <div\n                key={i}\n                className={cn(\n                    'shrink-0',\n                    isHorizontal\n                        ? 'flex items-center'\n                        : 'flex flex-col items-center',\n                )}\n                style={{\n                    [isHorizontal ? 'paddingRight' : 'paddingBottom']: gap,\n                }}\n            >\n                {children}\n            <\/div>\n        ));\n    }, [children, repeat, gap, isHorizontal]);\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(\n                'overflow-hidden',\n                isHorizontal ? 'w-full' : 'h-full',\n                props.className,\n            )}\n        >\n            <div\n                ref={trackRef}\n                className={cn(\n                    'flex will-change-transform',\n                    isHorizontal ? 'flex-row' : 'flex-col',\n                )}\n                style={{\n                    [isHorizontal ? 'width' : 'height']: `${repeat * 100}%`,\n                }}\n            >\n                {repeatedChildren}\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default GSAPMarquee;\n"}],"meta":{"category":"animations","version":"1.0.0"},"categories":["animations"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"marquee","type":"registry:ui","title":"Marquee","description":"A lightweight CSS-based horizontal text\/elements scrolling marquee.","author":"designbycode","dependencies":["@gsap\/react","gsap"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/animations\/marquee.tsx","type":"registry:ui","content":"'use client';\n\nimport { useGSAP } from '@gsap\/react';\nimport gsap from 'gsap';\nimport { ScrollTrigger } from 'gsap\/ScrollTrigger';\nimport type { CSSProperties, ReactNode } from 'react';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { cn } from '@\/lib\/utils';\n\ngsap.registerPlugin(useGSAP, ScrollTrigger);\n\nexport type MarqueeDirection = 'left' | 'right';\n\nexport interface MarqueeItemStyle {\n    className?: string;\n    style?: CSSProperties;\n    color?: string;\n    backgroundColor?: string;\n    fontSize?: string;\n    fontWeight?: string | number;\n    padding?: string;\n    borderRadius?: string;\n}\n\nexport interface MarqueeRowData<T = unknown> {\n    id: string | number;\n    items: T[];\n    direction?: MarqueeDirection;\n    \/** Base speed in px\/frame at 60fps. Default: 0.5 *\/\n    speed?: number;\n}\n\nexport interface MarqueeStyleProps {\n    textColor?: string;\n    fontSize?: string;\n    fontWeight?: string | number;\n    textTransform?: CSSProperties['textTransform'];\n    gap?: number;\n    className?: string;\n}\n\nexport interface MarqueeProps extends MarqueeStyleProps {\n    children: ReactNode;\n    \/** Base movement speed in px\/frame at 60fps. Default: 0.5 *\/\n    speed?: number;\n    direction?: MarqueeDirection;\n    pauseOnHover?: boolean;\n    \/**\n     * When true, the mouse wheel \/ trackpad controls the marquee:\n     *   - Scroll magnitude  \u2192 speed boost on top of base speed\n     *   - Scroll direction  \u2192 flips marquee direction while scrolling\n     *   - Stopping scroll   \u2192 eases back to base speed + base direction\n     * Default: true.\n     *\/\n    scrollEnabled?: boolean;\n    \/**\n     * Extra px\/frame added at peak normalised scroll input.\n     * Default: 8.\n     *\/\n    scrollBoostFactor?: number;\n    \/**\n     * Seconds to ease back to base speed + direction after scrolling stops.\n     * Default: 0.6.\n     *\/\n    scrollDecay?: number;\n    \/**\n     * ms of inactivity after the last wheel event before the ease-back starts.\n     * Default: 120.\n     *\/\n    scrollTimeout?: number;\n    contentClassName?: string;\n    style?: CSSProperties;\n}\n\nexport interface MultiRowMarqueeProps<T = unknown> extends MarqueeStyleProps {\n    rows: MarqueeRowData<T>[];\n    speed?: number;\n    direction?: MarqueeDirection;\n    pauseOnHover?: boolean;\n    scrollEnabled?: boolean;\n    scrollBoostFactor?: number;\n    scrollDecay?: number;\n    scrollTimeout?: number;\n    renderItem: (item: T, index: number, rowIndex: number) => ReactNode;\n    rowGap?: number;\n    contentClassName?: string;\n}\n\n\/\/ ============================================================================\n\/\/ Wheel input bus\n\/\/\n\/\/ One 'wheel' listener shared across every mounted Marquee.\n\/\/ Normalises raw deltaY so mouse wheel and trackpad feel identical,\n\/\/ then broadcasts to all subscribers.\n\/\/ ============================================================================\n\ninterface WheelSubscriber {\n    idleMs: number;\n\n    onWheel(normalisedDelta: number): void;\n\n    onIdle(): void;\n}\n\nconst wheelBus = (() => {\n    const subs = new Set<WheelSubscriber>();\n    const timers = new WeakMap<\n        WheelSubscriber,\n        ReturnType<typeof setTimeout>\n    >();\n    let listening = false;\n\n    \/**\n     * Normalise raw deltaY to a consistent [-60, 60] range.\n     *\n     * Trackpad: sends continuous small deltas (|delta| < 30) at high frequency.\n     * Mouse wheel: sends discrete larger deltas (~100 px per notch).\n     *\n     * We scale trackpad up (\u00d73) so both inputs land in the same perceived range,\n     * then clamp the result.\n     *\/\n    function normalise(deltaY: number): number {\n        const isTrackpad = Math.abs(deltaY) < 30;\n        const scaled = isTrackpad ? deltaY * 3 : deltaY;\n\n        return Math.max(-60, Math.min(60, scaled));\n    }\n\n    function onWheel(e: WheelEvent) {\n        const norm = normalise(e.deltaY);\n        subs.forEach((sub) => {\n            sub.onWheel(norm);\n            \/\/ Reset this subscriber's idle timer on every wheel event\n            const prev = timers.get(sub);\n\n            if (prev) {\n                clearTimeout(prev);\n            }\n\n            timers.set(\n                sub,\n                setTimeout(() => sub.onIdle(), sub.idleMs),\n            );\n        });\n    }\n\n    function boot() {\n        if (listening) {\n            return;\n        }\n\n        listening = true;\n        window.addEventListener('wheel', onWheel, { passive: true });\n    }\n\n    function teardown() {\n        if (!listening) {\n            return;\n        }\n\n        listening = false;\n        window.removeEventListener('wheel', onWheel);\n    }\n\n    return {\n        subscribe(sub: WheelSubscriber): () => void {\n            subs.add(sub);\n            boot();\n\n            return () => {\n                const t = timers.get(sub);\n\n                if (t) {\n                    clearTimeout(t);\n                }\n\n                timers.delete(sub);\n                subs.delete(sub);\n\n                if (subs.size === 0) {\n                    teardown();\n                }\n            };\n        },\n    };\n})();\n\n\/\/ ============================================================================\n\/\/ Marquee \u2014 single row\n\/\/ ============================================================================\n\nexport function Marquee({\n    children,\n    speed,\n    direction = 'left',\n    pauseOnHover = false,\n    scrollEnabled = true,\n    scrollBoostFactor = 8,\n    scrollDecay = 0.6,\n    scrollTimeout = 120,\n    gap = 24,\n    textColor,\n    fontSize,\n    fontWeight,\n    textTransform,\n    className,\n    contentClassName,\n    style,\n}: MarqueeProps) {\n    const baseSpeed = speed ?? 0.5;\n\n    \/\/ baseSign controls which axis the track moves along.\n    \/\/ direction='left'  \u2192 track moves left  \u2192 x decreases \u2192 baseSign = -1\n    \/\/ direction='right' \u2192 track moves right \u2192 x increases \u2192 baseSign = +1\n    \/\/\n    \/\/ liveSpeed.value is always in px\/frame; its sign encodes direction:\n    \/\/   positive \u2192 forward (baseSign direction)\n    \/\/   negative \u2192 reversed\n    \/\/ The ticker applies: xRef += liveSpeed.value * baseSign\n    const baseSign = direction === 'left' ? -1 : 1;\n\n    const containerRef = useRef<HTMLDivElement>(null);\n    const trackRef = useRef<HTMLDivElement>(null);\n\n    const xRef = useRef(0);\n    const setWRef = useRef(0);\n    const isPausedRef = useRef(false);\n\n    \/\/ liveSpeed.value: positive = forward, negative = reversed\n    const liveSpeed = useRef({ value: baseSpeed });\n    const quickToRef = useRef<gsap.QuickToFunc | null>(null);\n\n    const [cloneCount, setCloneCount] = useState(3);\n\n    \/\/ \u2500\u2500 GSAP: ticker + measure + resize \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    useGSAP(\n        () => {\n            if (!trackRef.current) {\n                return;\n            }\n\n            const measure = () => {\n                const contentEl = trackRef.current!.querySelector(\n                    '[data-marquee-content]',\n                ) as HTMLElement | null;\n\n                if (!contentEl) {\n                    return;\n                }\n\n                const singleW = contentEl.offsetWidth + gap;\n\n                if (singleW === 0) {\n                    return;\n                }\n\n                setWRef.current = singleW;\n\n                const copies = Math.max(\n                    3,\n                    Math.ceil((window.innerWidth * 3) \/ singleW) + 1,\n                );\n                setCloneCount(copies);\n\n                \/\/ Right-moving strips start mid-track so content is visible immediately.\n                const rawStart =\n                    baseSign === 1 ? -singleW * Math.floor(copies \/ 2) : 0;\n                xRef.current = ((rawStart % singleW) - singleW) % singleW;\n                gsap.set(trackRef.current!, { x: xRef.current });\n            };\n\n            const raf1 = requestAnimationFrame(() => {\n                const raf2 = requestAnimationFrame(() => {\n                    measure();\n\n                    \/\/ quickTo eases liveSpeed.value to any target smoothly\n                    liveSpeed.current.value = baseSpeed;\n                    quickToRef.current = gsap.quickTo(\n                        liveSpeed.current,\n                        'value',\n                        {\n                            duration: scrollDecay,\n                            ease: 'power2.inOut',\n                        },\n                    );\n\n                    let resizeTimer: ReturnType<typeof setTimeout>;\n                    const onResize = () => {\n                        clearTimeout(resizeTimer);\n                        resizeTimer = setTimeout(measure, 150);\n                    };\n                    window.addEventListener('resize', onResize);\n\n                    return () => {\n                        clearTimeout(resizeTimer);\n                        window.removeEventListener('resize', onResize);\n                    };\n                });\n\n                return () => cancelAnimationFrame(raf2);\n            });\n\n            const tick = () => {\n                if (isPausedRef.current || setWRef.current === 0) {\n                    return;\n                }\n\n                \/\/ liveSpeed.value sign encodes direction; baseSign encodes axis.\n                xRef.current += liveSpeed.current.value * baseSign;\n\n                \/\/ True modulo wrap \u2014 never jumps regardless of speed magnitude\n                const setW = setWRef.current;\n                xRef.current = ((xRef.current % setW) - setW) % setW;\n\n                gsap.set(trackRef.current!, { x: xRef.current });\n            };\n\n            gsap.ticker.add(tick);\n\n            return () => {\n                cancelAnimationFrame(raf1);\n                gsap.ticker.remove(tick);\n            };\n        },\n        {\n            scope: containerRef,\n            dependencies: [baseSpeed, baseSign, gap, scrollDecay, cloneCount],\n        },\n    );\n\n    \/\/ \u2500\u2500 Wheel bus subscription \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    \/\/ Separate from the GSAP context so toggling scrollEnabled doesn't\n    \/\/ teardown and re-run the entire animation.\n    useEffect(() => {\n        if (!scrollEnabled) {\n            return;\n        }\n\n        const unsub = wheelBus.subscribe({\n            idleMs: scrollTimeout,\n\n            onWheel(norm) {\n                if (!quickToRef.current) {\n                    return;\n                }\n\n                \/\/ norm: positive = scroll down = forward, negative = scroll up = reverse\n                \/\/ Map magnitude to a speed boost, preserve direction sign\n                const boost = (Math.abs(norm) \/ 60) * scrollBoostFactor;\n                const targetSpeed = (norm >= 0 ? 1 : -1) * (baseSpeed + boost);\n                quickToRef.current(targetSpeed);\n            },\n\n            onIdle() {\n                \/\/ Ease back to original speed in original (forward) direction\n                if (!quickToRef.current) {\n                    return;\n                }\n\n                quickToRef.current(baseSpeed);\n            },\n        });\n\n        return unsub;\n    }, [\n        scrollEnabled,\n        scrollBoostFactor,\n        scrollDecay,\n        scrollTimeout,\n        baseSpeed,\n    ]);\n\n    \/\/ \u2500\u2500 Hover pause \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    const handleMouseEnter = useCallback(() => {\n        if (pauseOnHover) {\n            isPausedRef.current = true;\n        }\n    }, [pauseOnHover]);\n\n    const handleMouseLeave = useCallback(() => {\n        if (pauseOnHover) {\n            isPausedRef.current = false;\n        }\n    }, [pauseOnHover]);\n\n    \/\/ \u2500\u2500 Render \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    const contentStyle: CSSProperties = {\n        gap: `${gap}px`,\n        color: textColor,\n        fontSize,\n        fontWeight,\n        textTransform,\n    };\n\n    const contentElements = Array.from({ length: cloneCount }, (_, i) => (\n        <div\n            key={`mq-${i}`}\n            {...(i === 0\n                ? { 'data-marquee-content': 'true' }\n                : { 'data-marquee-clone': 'true', 'aria-hidden': 'true' })}\n            className={cn('flex shrink-0 items-center', contentClassName)}\n            style={contentStyle}\n        >\n            {children}\n        <\/div>\n    ));\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(\n                'relative flex items-center overflow-hidden',\n                className,\n            )}\n            style={style}\n            onMouseEnter={handleMouseEnter}\n            onMouseLeave={handleMouseLeave}\n        >\n            <div\n                ref={trackRef}\n                className=\"flex shrink-0 items-center whitespace-nowrap\"\n                style={{ gap: `${gap}px`, willChange: 'transform' }}\n            >\n                {contentElements}\n            <\/div>\n        <\/div>\n    );\n}\n\n\/\/ ============================================================================\n\/\/ MultiRowMarquee\n\/\/ ============================================================================\n\nexport function MultiRowMarquee<T>({\n    rows,\n    speed = 0.5,\n    direction = 'left',\n    pauseOnHover = false,\n    scrollEnabled = true,\n    scrollBoostFactor = 8,\n    scrollDecay = 0.6,\n    scrollTimeout = 120,\n    gap = 24,\n    rowGap = 16,\n    textColor,\n    fontSize,\n    fontWeight,\n    textTransform,\n    className,\n    contentClassName,\n    renderItem,\n}: MultiRowMarqueeProps<T>) {\n    return (\n        <div\n            className={cn('flex flex-col', className)}\n            style={{ gap: `${rowGap}px` }}\n        >\n            {rows.map((row, rowIndex) => (\n                <Marquee\n                    key={row.id}\n                    speed={row.speed ?? speed}\n                    direction={row.direction ?? direction}\n                    pauseOnHover={pauseOnHover}\n                    scrollEnabled={scrollEnabled}\n                    scrollBoostFactor={scrollBoostFactor}\n                    scrollDecay={scrollDecay}\n                    scrollTimeout={scrollTimeout}\n                    gap={gap}\n                    textColor={textColor}\n                    fontSize={fontSize}\n                    fontWeight={fontWeight}\n                    textTransform={textTransform}\n                    contentClassName={contentClassName}\n                >\n                    {row.items.map((item, itemIndex) => (\n                        <React.Fragment key={itemIndex}>\n                            {renderItem(item, itemIndex, rowIndex)}\n                        <\/React.Fragment>\n                    ))}\n                <\/Marquee>\n            ))}\n        <\/div>\n    );\n}\n\n\/\/ ============================================================================\n\/\/ MarqueeText \u2014 preset with per-item style support\n\/\/ ============================================================================\n\nexport interface MarqueeTextItem {\n    label: string;\n    itemStyle?: MarqueeItemStyle;\n}\n\nexport interface MarqueeTextProps extends Omit<MarqueeProps, 'children'> {\n    items: string[] | MarqueeTextItem[];\n    separator?: string | ReactNode;\n    separatorColor?: string;\n}\n\nfunction isItemArray(\n    items: string[] | MarqueeTextItem[],\n): items is MarqueeTextItem[] {\n    return items.length > 0 && typeof items[0] === 'object';\n}\n\nexport function MarqueeText({\n    items,\n    separator = '\u2022',\n    separatorColor,\n    textColor = 'currentColor',\n    fontSize = 'clamp(1.5rem, 4vw, 3rem)',\n    fontWeight = 'bold',\n    textTransform = 'uppercase',\n    ...props\n}: MarqueeTextProps) {\n    const normalized: MarqueeTextItem[] = isItemArray(items)\n        ? items\n        : items.map((label) => ({ label }));\n\n    return (\n        <Marquee\n            textColor={textColor}\n            fontSize={fontSize}\n            fontWeight={fontWeight}\n            textTransform={textTransform}\n            {...props}\n        >\n            {normalized.map((item, index) => {\n                const { label, itemStyle } = item;\n                const resolvedStyle: CSSProperties = {\n                    color: itemStyle?.color,\n                    backgroundColor: itemStyle?.backgroundColor,\n                    fontSize: itemStyle?.fontSize,\n                    fontWeight: itemStyle?.fontWeight,\n                    padding: itemStyle?.padding,\n                    borderRadius: itemStyle?.borderRadius,\n                    ...itemStyle?.style,\n                };\n\n                return (\n                    <span\n                        key={index}\n                        className={cn(\n                            'flex shrink-0 items-center gap-4',\n                            itemStyle?.className,\n                        )}\n                    >\n                        <span\n                            className=\"shrink-0 select-none\"\n                            style={{\n                                letterSpacing: '0.02em',\n                                ...resolvedStyle,\n                            }}\n                        >\n                            {label}\n                        <\/span>\n                        {separator && (\n                            <span\n                                className=\"shrink-0 opacity-50 select-none\"\n                                style={{\n                                    color:\n                                        separatorColor ||\n                                        itemStyle?.color ||\n                                        textColor,\n                                    fontSize: '0.5em',\n                                }}\n                            >\n                                {separator}\n                            <\/span>\n                        )}\n                    <\/span>\n                );\n            })}\n        <\/Marquee>\n    );\n}\n\nexport default Marquee;\n"}],"meta":{"category":"animations","version":"1.0.0"},"categories":["animations"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"particles-backdrop","type":"registry:ui","title":"Particles Backdrop","description":"A pure CSS background animation engine rendering drifting ambient particle glows.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/animations\/particles-backdrop.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface ParticlesBackdropProps extends React.HTMLAttributes<HTMLDivElement> {\n    count?: number;\n    colorClassName?: string;\n}\n\nexport function ParticlesBackdrop({\n    className,\n    count = 15,\n    colorClassName = 'bg-primary\/40',\n    ...props\n}: ParticlesBackdropProps) {\n    \/\/ Generate static positions for floating particles\n    const particles = React.useMemo(() => {\n        return Array.from({ length: count }, (_, i) => ({\n            id: i,\n            top: `${Math.random() * 100}%`,\n            left: `${Math.random() * 100}%`,\n            size: Math.random() * 4 + 2, \/\/ 2px to 6px\n            delay: `${Math.random() * 8}s`,\n            duration: `${15 + Math.random() * 15}s`,\n        }));\n    }, [count]);\n\n    return (\n        <div\n            className={cn(\n                'pointer-events-none absolute inset-0 overflow-hidden select-none',\n                className,\n            )}\n            {...props}\n        >\n            <style\n                dangerouslySetInnerHTML={{\n                    __html: `\n                @keyframes float-particle-core {\n                    0% { transform: translateY(0) scale(1); opacity: 0.15; }\n                    50% { transform: translateY(-60px) scale(1.2); opacity: 0.6; }\n                    100% { transform: translateY(0) scale(1); opacity: 0.15; }\n                }\n                .floating-dot-core {\n                    animation: float-particle-core var(--duration) ease-in-out infinite;\n                    animation-delay: var(--delay);\n                }\n            `,\n                }}\n            \/>\n            {particles.map((p) => (\n                <span\n                    key={p.id}\n                    className={cn(\n                        'floating-dot-core absolute rounded-full',\n                        colorClassName,\n                    )}\n                    style={\n                        {\n                            top: p.top,\n                            left: p.left,\n                            width: `${p.size}px`,\n                            height: `${p.size}px`,\n                            '--delay': p.delay,\n                            '--duration': p.duration,\n                        } as React.CSSProperties\n                    }\n                \/>\n            ))}\n        <\/div>\n    );\n}\n\nexport default ParticlesBackdrop;\n"}],"meta":{"category":"animations","version":"1.0.0"},"categories":["animations"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"text-animator","type":"registry:ui","title":"Text Animator","description":"An elegant text animator rendering typography with premium transitions.","author":"designbycode","dependencies":["@gsap\/react","gsap"],"devDependencies":[],"registryDependencies":[],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/animations\/text-animator.tsx","type":"registry:ui","content":"'use client';\n\nimport { useGSAP } from '@gsap\/react';\nimport gsap from 'gsap';\nimport { ScrollTrigger } from 'gsap\/ScrollTrigger';\nimport type { CSSProperties, ElementType, KeyboardEvent } from 'react';\nimport React, {\n    forwardRef,\n    useCallback,\n    useEffect,\n    useImperativeHandle,\n    useMemo,\n    useRef,\n} from 'react';\n\n\/\/ \u2500\u2500\u2500 Animation Type Union \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type AnimationType =\n    \/\/ Fades\n    | 'fadeIn'\n    | 'fadeInUp'\n    | 'fadeInDown'\n    | 'fadeInLeft'\n    | 'fadeInRight'\n    | 'fadeInTopLeft'\n    | 'fadeInTopRight'\n    | 'fadeInBottomLeft'\n    | 'fadeInBottomRight'\n    \/\/ Slides\n    | 'slideUp'\n    | 'slideDown'\n    | 'slideLeft'\n    | 'slideRight'\n    | 'slideTopLeft'\n    | 'slideTopRight'\n    | 'slideBottomLeft'\n    | 'slideBottomRight'\n    \/\/ Scale\n    | 'scaleUp'\n    | 'scaleDown'\n    | 'scaleIn'\n    | 'scaleInUp'\n    | 'scaleInDown'\n    \/\/ Blur\n    | 'blurIn'\n    | 'blurOut'\n    | 'blurInLeft'\n    | 'blurInRight'\n    | 'blurInUp'\n    | 'blurInDown'\n    \/\/ Rotate\n    | 'rotateIn'\n    | 'rotateOut'\n    | 'rotateInLeft'\n    | 'rotateInRight'\n    | 'rotateOutLeft'\n    | 'rotateOutRight'\n    \/\/ Physics\n    | 'bounce'\n    | 'elastic'\n    | 'jelly'\n    | 'squash'\n    | 'liquid'\n    | 'swing'\n    | 'stretch'\n    | 'spring'\n    | 'wobble'\n    | 'shake'\n    | 'drift'\n    | 'float'\n    \/\/ Character\n    | 'wave'\n    | 'pop'\n    | 'flip'\n    | 'rollIn'\n    | 'skewIn'\n    | 'spiral'\n    | 'morph'\n    | 'crash'\n    | 'explode'\n    | 'letterByLetter'\n    | 'typewriter'\n    | 'jitter'\n    \/\/ Text effects\n    | 'reveal'\n    | 'glitch'\n    | 'gradient'\n    | 'shadow'\n    | 'neon'\n    | 'marquee'\n    | 'flicker'\n    | 'spotlight'\n    | 'outline'\n    | 'pulse'\n    | 'breathe'\n    | 'aurora'\n    \/\/ Special effects\n    | 'matrix'\n    | 'fire'\n    | 'rainbow'\n    | 'magnetic'\n    | 'particles'\n    | 'dissolve'\n    | 'scramble'\n    | 'zap'\n    | 'orbit'\n    | 'vortex'\n    | 'ripple'\n    | 'piano'\n    | 'domino'\n    | 'pendulum'\n    | 'shatter'\n    | 'smoke'\n    | 'thunder'\n    | 'crystallize'\n    | 'warp'\n    | 'cinema'\n    | 'gravity'\n    | 'levitate'\n    | 'twinkle'\n    | 'shimmerFade'\n    | 'fold'\n    | 'cascade'\n    | 'pinball'\n    | 'neonFlicker'\n    | 'rise'\n    | 'unfurl'\n    | 'stampIn'\n    | 'blinds';\n\n\/\/ \u2500\u2500\u2500 Trigger Type \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type TriggerType = 'onClick' | 'onHover' | 'scrollTrigger';\n\n\/\/ \u2500\u2500\u2500 Split Mode \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type SplitMode = 'chars' | 'words' | 'lines';\n\n\/\/ \u2500\u2500\u2500 Easing Presets \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type EasePreset =\n    | 'power1.in'\n    | 'power1.out'\n    | 'power1.inOut'\n    | 'power2.in'\n    | 'power2.out'\n    | 'power2.inOut'\n    | 'power3.in'\n    | 'power3.out'\n    | 'power3.inOut'\n    | 'power4.in'\n    | 'power4.out'\n    | 'power4.inOut'\n    | 'back.in'\n    | 'back.out'\n    | 'back.inOut'\n    | 'bounce.in'\n    | 'bounce.out'\n    | 'bounce.inOut'\n    | 'elastic.in'\n    | 'elastic.out'\n    | 'elastic.inOut'\n    | 'circ.in'\n    | 'circ.out'\n    | 'circ.inOut'\n    | 'expo.in'\n    | 'expo.out'\n    | 'expo.inOut'\n    | 'sine.in'\n    | 'sine.out'\n    | 'sine.inOut'\n    | 'none'\n    | (string & {});\n\n\/\/ \u2500\u2500\u2500 ScrollTrigger Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface ScrollTriggerOptions {\n    \/** ScrollTrigger start position. Default: `\"top 80%\"` *\/\n    start?: string;\n    \/** ScrollTrigger end position. Default: `\"bottom 20%\"` *\/\n    end?: string;\n    \/** Scrub the animation to scroll position. Default: `false` *\/\n    scrub?: boolean | number;\n    \/** Markers for debugging (dev only). Default: `false` *\/\n    markers?: boolean;\n    \/** Toggle actions string. Default: `\"play none none reverse\"` *\/\n    toggleActions?: string;\n    \/** Pin the element while animating. Default: `false` *\/\n    pin?: boolean;\n}\n\n\/\/ \u2500\u2500\u2500 Stagger Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface StaggerOptions {\n    \/** Time between each character animation in seconds. Default: `0.04` *\/\n    each?: number;\n    \/** Stagger from: `\"start\"` | `\"end\"` | `\"center\"` | `\"edges\"` | number *\/\n    from?: 'start' | 'end' | 'center' | 'edges' | number;\n    \/** Grid stagger for 2D layouts *\/\n    grid?: [number, number] | 'auto';\n    \/** Axis for grid stagger *\/\n    axis?: 'x' | 'y';\n    \/** Amount distributes the stagger across total duration *\/\n    amount?: number;\n}\n\n\/\/ \u2500\u2500\u2500 Component Props \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface TextAnimatorProps {\n    text?: string;\n    children?: string;\n    animation?: AnimationType;\n    trigger?: TriggerType;\n    splitBy?: SplitMode;\n    duration?: number;\n    delay?: number;\n    stagger?: number | StaggerOptions;\n    ease?: EasePreset;\n    repeat?: number;\n    yoyo?: boolean;\n    scrollTrigger?: ScrollTriggerOptions;\n    tag?: ElementType;\n    color?: string;\n    fontSize?: string | number;\n    className?: string;\n    style?: CSSProperties;\n    \/**\n     * Custom color(s) for color-driven animations:\n     * aurora, fire, glitch, gradient, matrix, neon, neonFlicker, rainbow, zap.\n     * Accepts a single CSS color string or an array.\n     * When one color is given it fills both the primary and secondary slots.\n     *\/\n    effectColor?: string | string[];\n    onComplete?: () => void;\n    onStart?: () => void;\n    onRepeat?: () => void;\n}\n\n\/\/ \u2500\u2500\u2500 Ref API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface TextAnimatorRef {\n    play: () => void;\n    pause: () => void;\n    reverse: () => void;\n    restart: () => void;\n    seek: (timeOrProgress: number) => void;\n    kill: () => void;\n    timeline: () => gsap.core.Timeline | null;\n    isPlaying: () => boolean;\n    progress: () => number;\n}\n\n\/\/ \u2500\u2500\u2500 Animation Config (internal) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface AnimationContext {\n    chars: HTMLElement[];\n    words: HTMLElement[];\n    el: HTMLElement;\n    opts: ResolvedAnimOpts;\n    effectColors: string[];\n}\n\nexport interface ResolvedAnimOpts {\n    duration: number;\n    delay: number;\n    stagger: number | StaggerOptions;\n    ease: string;\n    repeat: number;\n    yoyo: boolean;\n}\n\nexport interface AnimationConfig {\n    targets?: HTMLElement[];\n    from?: gsap.TweenVars;\n    to?: gsap.TweenVars;\n    overrideEase?: boolean;\n    special?: (tl: gsap.core.Timeline) => void;\n}\n\nexport type AnimationDefinition = (ctx: AnimationContext) => AnimationConfig;\n\n\/\/ \u2500\u2500\u2500 Plugin Registration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ngsap.registerPlugin(ScrollTrigger);\n\n\/\/ \u2500\u2500\u2500 Utility: Resolve stagger \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction resolveStagger(s: number | StaggerOptions, fallback = 0.04): number {\n    return typeof s === 'number' ? s : fallback;\n}\n\n\/\/ \u2500\u2500\u2500 Utility: Text Splitting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction splitChars(el: HTMLElement): HTMLElement[] {\n    const text = el.textContent ?? '';\n    el.innerHTML = '';\n\n    return [...text].map((ch) => {\n        const span = document.createElement('span');\n        span.textContent = ch === ' ' ? '\\u00A0' : ch;\n        span.style.display = 'inline-block';\n        el.appendChild(span);\n\n        return span;\n    });\n}\n\nfunction splitWords(el: HTMLElement): HTMLElement[] {\n    const words = (el.textContent ?? '').split(' ');\n    el.innerHTML = '';\n\n    return words.map((word, i) => {\n        const clip = document.createElement('span');\n        clip.style.cssText =\n            'display:inline-block;overflow:hidden;vertical-align:bottom;';\n        const inner = document.createElement('span');\n        inner.textContent = word;\n        inner.style.display = 'inline-block';\n        clip.appendChild(inner);\n        el.appendChild(clip);\n\n        if (i < words.length - 1) {\n            el.appendChild(document.createTextNode('\\u00A0'));\n        }\n\n        return inner;\n    });\n}\n\nfunction splitLines(el: HTMLElement): HTMLElement[] {\n    const lines = (el.textContent ?? '').split('\\n');\n    el.innerHTML = '';\n\n    return lines.map((line, lineIndex) => {\n        const lineWrap = document.createElement('span');\n        lineWrap.style.cssText = 'display:block;';\n        const lineInner = document.createElement('span');\n        lineInner.style.cssText =\n            'display:inline-block;overflow:hidden;vertical-align:bottom;';\n        const words = line.split(' ');\n        words.forEach((word, wordIndex) => {\n            const wordClip = document.createElement('span');\n            wordClip.style.cssText =\n                'display:inline-block;overflow:hidden;vertical-align:bottom;';\n            const wordInner = document.createElement('span');\n            wordInner.textContent = word;\n            wordInner.style.display = 'inline-block';\n            wordClip.appendChild(wordInner);\n            lineInner.appendChild(wordClip);\n\n            if (wordIndex < words.length - 1) {\n                lineInner.appendChild(document.createTextNode('\\u00A0'));\n            }\n        });\n        lineWrap.appendChild(lineInner);\n        el.appendChild(lineWrap);\n\n        if (lineIndex < lines.length - 1) {\n            el.appendChild(document.createTextNode('\\n'));\n        }\n\n        return lineInner;\n    });\n}\n\n\/\/ \u2500\u2500\u2500 Shared special builder helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\/** Builds a standard `from` tween over chars with stagger. *\/\nfunction fromChars(\n    tl: gsap.core.Timeline,\n    chars: HTMLElement[],\n    opts: ResolvedAnimOpts,\n    vars: gsap.TweenVars,\n    staggerFallback = 0.04,\n): void {\n    tl.from(chars, {\n        ...vars,\n        duration: opts.duration,\n        stagger: resolveStagger(opts.stagger, staggerFallback),\n        ease: vars.ease ?? opts.ease,\n    });\n}\n\n\/\/ \u2500\u2500\u2500 Animation Definitions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ANIMATIONS: Partial<Record<AnimationType, AnimationDefinition>> = {\n    \/\/ \u2500\u2500 Fades \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    fadeIn: ({ chars }) => ({\n        targets: chars,\n        from: { opacity: 0 },\n        to: { opacity: 1 },\n    }),\n    fadeInUp: ({ chars }) => ({\n        targets: chars,\n        from: { opacity: 0, y: 40 },\n        to: { opacity: 1, y: 0 },\n    }),\n    fadeInDown: ({ chars }) => ({\n        targets: chars,\n        from: { opacity: 0, y: -40 },\n        to: { opacity: 1, y: 0 },\n    }),\n    fadeInLeft: ({ chars }) => ({\n        targets: chars,\n        from: { opacity: 0, x: -40 },\n        to: { opacity: 1, x: 0 },\n    }),\n    fadeInRight: ({ chars }) => ({\n        targets: chars,\n        from: { opacity: 0, x: 40 },\n        to: { opacity: 1, x: 0 },\n    }),\n    fadeInTopLeft: ({ chars }) => ({\n        targets: chars,\n        from: { opacity: 0, x: -40, y: -40 },\n        to: { opacity: 1, x: 0, y: 0 },\n    }),\n    fadeInTopRight: ({ chars }) => ({\n        targets: chars,\n        from: { opacity: 0, x: 40, y: -40 },\n        to: { opacity: 1, x: 0, y: 0 },\n    }),\n    fadeInBottomLeft: ({ chars }) => ({\n        targets: chars,\n        from: { opacity: 0, x: -40, y: 40 },\n        to: { opacity: 1, x: 0, y: 0 },\n    }),\n    fadeInBottomRight: ({ chars }) => ({\n        targets: chars,\n        from: { opacity: 0, x: 40, y: 40 },\n        to: { opacity: 1, x: 0, y: 0 },\n    }),\n\n    \/\/ \u2500\u2500 Slides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    slideUp: ({ chars }) => ({\n        targets: chars,\n        from: { y: '100%', opacity: 0 },\n        to: { y: '0%', opacity: 1 },\n    }),\n    slideDown: ({ chars }) => ({\n        targets: chars,\n        from: { y: '-100%', opacity: 0 },\n        to: { y: '0%', opacity: 1 },\n    }),\n    slideLeft: ({ chars }) => ({\n        targets: chars,\n        from: { x: '-120%', opacity: 0 },\n        to: { x: '0%', opacity: 1 },\n    }),\n    slideRight: ({ chars }) => ({\n        targets: chars,\n        from: { x: '120%', opacity: 0 },\n        to: { x: '0%', opacity: 1 },\n    }),\n    slideTopLeft: ({ chars }) => ({\n        targets: chars,\n        from: { x: '-120%', y: '-100%', opacity: 0 },\n        to: { x: '0%', y: '0%', opacity: 1 },\n    }),\n    slideTopRight: ({ chars }) => ({\n        targets: chars,\n        from: { x: '120%', y: '-100%', opacity: 0 },\n        to: { x: '0%', y: '0%', opacity: 1 },\n    }),\n    slideBottomLeft: ({ chars }) => ({\n        targets: chars,\n        from: { x: '-120%', y: '100%', opacity: 0 },\n        to: { x: '0%', y: '0%', opacity: 1 },\n    }),\n    slideBottomRight: ({ chars }) => ({\n        targets: chars,\n        from: { x: '120%', y: '100%', opacity: 0 },\n        to: { x: '0%', y: '0%', opacity: 1 },\n    }),\n\n    \/\/ \u2500\u2500 Scale \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    scaleUp: ({ chars }) => ({\n        targets: chars,\n        from: { scale: 0, opacity: 0 },\n        to: { scale: 1, opacity: 1 },\n    }),\n    scaleDown: ({ chars }) => ({\n        targets: chars,\n        from: { scale: 2.5, opacity: 0 },\n        to: { scale: 1, opacity: 1 },\n    }),\n    scaleIn: ({ chars }) => ({\n        targets: chars,\n        from: { scale: 0, opacity: 0 },\n        to: { scale: 1, opacity: 1, ease: 'back.out(2)' },\n        overrideEase: true,\n    }),\n    scaleInUp: ({ chars }) => ({\n        targets: chars,\n        from: { scale: 0, y: 30, opacity: 0 },\n        to: { scale: 1, y: 0, opacity: 1 },\n    }),\n    scaleInDown: ({ chars }) => ({\n        targets: chars,\n        from: { scale: 0, y: -30, opacity: 0 },\n        to: { scale: 1, y: 0, opacity: 1 },\n    }),\n\n    \/\/ \u2500\u2500 Blur \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    blurIn: ({ chars }) => ({\n        targets: chars,\n        from: { filter: 'blur(12px)', opacity: 0 },\n        to: { filter: 'blur(0px)', opacity: 1 },\n    }),\n    blurOut: ({ chars }) => ({\n        targets: chars,\n        from: { filter: 'blur(0px)', opacity: 1 },\n        to: { filter: 'blur(12px)', opacity: 0 },\n    }),\n    blurInLeft: ({ chars }) => ({\n        targets: chars,\n        from: { filter: 'blur(12px)', x: -40, opacity: 0 },\n        to: { filter: 'blur(0px)', x: 0, opacity: 1 },\n    }),\n    blurInRight: ({ chars }) => ({\n        targets: chars,\n        from: { filter: 'blur(12px)', x: 40, opacity: 0 },\n        to: { filter: 'blur(0px)', x: 0, opacity: 1 },\n    }),\n    blurInUp: ({ chars }) => ({\n        targets: chars,\n        from: { filter: 'blur(12px)', y: 40, opacity: 0 },\n        to: { filter: 'blur(0px)', y: 0, opacity: 1 },\n    }),\n    blurInDown: ({ chars }) => ({\n        targets: chars,\n        from: { filter: 'blur(12px)', y: -40, opacity: 0 },\n        to: { filter: 'blur(0px)', y: 0, opacity: 1 },\n    }),\n\n    \/\/ \u2500\u2500 Rotate \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    rotateIn: ({ chars }) => ({\n        targets: chars,\n        from: { rotation: -180, opacity: 0, scale: 0 },\n        to: { rotation: 0, opacity: 1, scale: 1 },\n    }),\n    rotateOut: ({ chars }) => ({\n        targets: chars,\n        from: { rotation: 0, opacity: 1 },\n        to: { rotation: 180, opacity: 0 },\n    }),\n    rotateInLeft: ({ chars }) => ({\n        targets: chars,\n        from: { rotation: -90, x: -40, opacity: 0 },\n        to: { rotation: 0, x: 0, opacity: 1 },\n    }),\n    rotateInRight: ({ chars }) => ({\n        targets: chars,\n        from: { rotation: 90, x: 40, opacity: 0 },\n        to: { rotation: 0, x: 0, opacity: 1 },\n    }),\n    rotateOutLeft: ({ chars }) => ({\n        targets: chars,\n        from: { rotation: 0, opacity: 1 },\n        to: { rotation: -90, x: -40, opacity: 0 },\n    }),\n    rotateOutRight: ({ chars }) => ({\n        targets: chars,\n        from: { rotation: 0, opacity: 1 },\n        to: { rotation: 90, x: 40, opacity: 0 },\n    }),\n\n    \/\/ \u2500\u2500 Physics \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    bounce: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                y: -60,\n                opacity: 0,\n                ease: 'bounce.out',\n            });\n        },\n    }),\n\n    elastic: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                scale: 0,\n                opacity: 0,\n                ease: 'elastic.out(1, 0.3)',\n            });\n        },\n    }),\n\n    jelly: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                scaleX: 1.6,\n                scaleY: 0.4,\n                opacity: 0,\n                ease: 'elastic.out(1, 0.4)',\n            });\n        },\n    }),\n\n    squash: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                scaleY: 2.5,\n                scaleX: 0.5,\n                y: -30,\n                opacity: 0,\n                ease: 'bounce.out',\n            });\n        },\n    }),\n\n    liquid: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                scaleY: 2.5,\n                scaleX: 0.4,\n                opacity: 0,\n                ease: 'elastic.out(0.5, 0.3)',\n            });\n        },\n    }),\n\n    swing: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                rotation: -45,\n                transformOrigin: 'top center',\n                opacity: 0,\n                ease: 'elastic.out(0.8, 0.4)',\n            });\n        },\n    }),\n\n    stretch: ({ chars }) => ({\n        targets: chars,\n        from: { scaleX: 3, opacity: 0 },\n        to: { scaleX: 1, opacity: 1 },\n    }),\n\n    spring: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                scale: 0,\n                opacity: 0,\n                ease: 'elastic.out(1, 0.5)',\n            });\n        },\n    }),\n\n    wobble: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                rotation: -15,\n                opacity: 0,\n                ease: 'elastic.out(1, 0.3)',\n            });\n        },\n    }),\n\n    shake: ({ chars, opts }) => ({\n        special: (tl) => {\n            tl.from(chars, {\n                x: -10,\n                opacity: 0,\n                duration: opts.duration * 0.5,\n                stagger: resolveStagger(opts.stagger),\n                ease: 'power1.inOut',\n            });\n        },\n    }),\n\n    drift: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                x: -30,\n                y: 20,\n                opacity: 0,\n                ease: 'power2.out',\n            });\n        },\n    }),\n\n    float: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, { y: 30, opacity: 0, ease: 'sine.out' });\n        },\n    }),\n\n    \/\/ \u2500\u2500 Character \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    wave: ({ chars, opts }) => ({\n        special: (tl) => {\n            tl.from(chars, {\n                y: -20,\n                opacity: 0,\n                duration: opts.duration,\n                ease: 'sine.inOut',\n                stagger: {\n                    each: resolveStagger(opts.stagger, 0.06),\n                    yoyo: true,\n                    repeat: 1,\n                },\n            });\n        },\n    }),\n\n    pop: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                scale: 0,\n                opacity: 0,\n                ease: 'back.out(3)',\n            });\n        },\n    }),\n\n    flip: ({ chars }) => ({\n        targets: chars,\n        from: { rotationX: 90, opacity: 0, transformPerspective: 400 },\n        to: { rotationX: 0, opacity: 1, transformPerspective: 400 },\n    }),\n\n    rollIn: ({ chars }) => ({\n        targets: chars,\n        from: { x: -60, rotation: -120, opacity: 0 },\n        to: { x: 0, rotation: 0, opacity: 1 },\n    }),\n\n    skewIn: ({ chars }) => ({\n        targets: chars,\n        from: { skewX: 30, opacity: 0, x: -30 },\n        to: { skewX: 0, opacity: 1, x: 0 },\n    }),\n\n    spiral: ({ chars }) => ({\n        targets: chars,\n        from: {\n            rotation: -720,\n            scale: 0,\n            opacity: 0,\n            x: () => gsap.utils.random(-40, 40) as number,\n        },\n        to: { rotation: 0, scale: 1, opacity: 1, x: 0 },\n    }),\n\n    morph: ({ chars }) => ({\n        targets: chars,\n        from: { borderRadius: '50%', scale: 0.3, opacity: 0 },\n        to: { borderRadius: '0%', scale: 1, opacity: 1 },\n    }),\n\n    crash: ({ chars, opts }) => ({\n        special: (tl) => {\n            tl.from(chars, {\n                y: () => gsap.utils.random(-200, -80) as number,\n                x: () => gsap.utils.random(-20, 20) as number,\n                rotation: () => gsap.utils.random(-30, 30) as number,\n                opacity: 0,\n                scale: () => gsap.utils.random(0.5, 1.5) as number,\n                duration: opts.duration * 0.6,\n                stagger: resolveStagger(opts.stagger),\n                ease: 'bounce.out',\n            });\n        },\n    }),\n\n    explode: ({ chars, opts }) => ({\n        special: (tl) => {\n            tl.from(chars, {\n                x: () => gsap.utils.random(-120, 120) as number,\n                y: () => gsap.utils.random(-120, 120) as number,\n                rotation: () => gsap.utils.random(-360, 360) as number,\n                opacity: 0,\n                scale: 0,\n                duration: opts.duration,\n                stagger: resolveStagger(opts.stagger),\n                ease: opts.ease,\n            });\n        },\n    }),\n\n    \/\/ \u2500\u2500 Text Entry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    letterByLetter: ({ chars, opts }) => ({\n        special: (tl) => {\n            gsap.set(chars, { visibility: 'hidden' });\n            tl.to(chars, {\n                visibility: 'visible',\n                duration: 0,\n                stagger: (opts.duration * 0.9) \/ chars.length,\n            });\n        },\n    }),\n\n    typewriter: ({ chars, opts }) => ({\n        special: (tl) => {\n            const firstChar = chars[0];\n\n            if (!firstChar?.parentNode) {\n                return;\n            }\n\n            const cursor = document.createElement('span');\n            cursor.textContent = '|';\n            cursor.style.cssText = 'display:inline-block;margin-left:1px;';\n\n            const styleEl = document.createElement('style');\n            styleEl.textContent =\n                '@keyframes cursorBlink{0%,50%{opacity:1}51%,100%{opacity:0}}';\n            cursor.style.animation = 'cursorBlink 0.8s infinite';\n            document.head.appendChild(styleEl);\n\n            firstChar.parentNode.insertBefore(cursor, firstChar);\n            gsap.set(chars, { visibility: 'hidden' });\n\n            const charTime = (opts.duration * 0.8) \/ chars.length;\n            chars.forEach((char, i) => {\n                tl.call(\n                    () => {\n                        char.style.visibility = 'visible';\n                        cursor.parentNode?.insertBefore(\n                            cursor,\n                            char.nextSibling,\n                        );\n                    },\n                    undefined,\n                    i * charTime,\n                );\n            });\n\n            tl.call(\n                () => {\n                    const last = chars[chars.length - 1];\n\n                    if (last) {\n                        cursor.parentNode?.insertBefore(\n                            cursor,\n                            last.nextSibling,\n                        );\n                    }\n                },\n                undefined,\n                chars.length * charTime,\n            );\n\n            tl.eventCallback('onComplete', () => {\n                cursor.remove();\n                styleEl.remove();\n            });\n        },\n    }),\n\n    jitter: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.02);\n\n                for (let j = 0; j < 3; j++) {\n                    tl.to(\n                        char,\n                        {\n                            x: () => gsap.utils.random(-3, 3),\n                            duration: 0.05,\n                            ease: 'none',\n                        },\n                        t + j * 0.05,\n                    );\n                }\n\n                tl.to(\n                    char,\n                    {\n                        x: 0,\n                        opacity: 1,\n                        duration: opts.duration * 0.3,\n                        ease: 'power2.out',\n                    },\n                    t,\n                );\n            });\n        },\n    }),\n\n    reveal: ({ words, opts }) => ({\n        special: (tl) => {\n            tl.from(words, {\n                y: '110%',\n                opacity: 0,\n                duration: opts.duration,\n                stagger:\n                    typeof opts.stagger === 'number'\n                        ? opts.stagger * 2\n                        : opts.stagger,\n                ease: opts.ease,\n            });\n        },\n    }),\n\n    \/\/ \u2500\u2500 Visual Effects \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    glitch: ({ chars, opts, effectColors }) => ({\n        special: (tl) => {\n            const glitchChars = '!@#$%^&*()[]{}|;:,.<>?~`';\n            const primary = effectColors[0] ?? '#ff003c';\n            const secondary = effectColors[1] ?? '#00f7ff';\n\n            chars.forEach((char, i) => {\n                const originalText = char.textContent ?? '';\n                const t = i * resolveStagger(opts.stagger, 0.02);\n                const glitchCount = 5 + Math.floor(Math.random() * 3);\n\n                gsap.set(char, { opacity: 0, scale: 0.8 });\n                tl.to(\n                    char,\n                    {\n                        opacity: 1,\n                        scale: 1,\n                        duration: opts.duration * 0.15,\n                        ease: 'power2.out',\n                    },\n                    t,\n                );\n\n                for (let g = 0; g < glitchCount; g++) {\n                    const gs =\n                        t + opts.duration * 0.2 + g * opts.duration * 0.08;\n                    tl.to(\n                        char,\n                        {\n                            x: () => gsap.utils.random(-6, 6),\n                            y: () => gsap.utils.random(-4, 4),\n                            duration: 0.03,\n                            ease: 'none',\n                        },\n                        gs,\n                    );\n                    tl.to(\n                        char,\n                        {\n                            textShadow: `${gsap.utils.random(-4, 4)}px ${gsap.utils.random(-2, 2)}px ${primary}, ${gsap.utils.random(-4, 4)}px ${gsap.utils.random(-2, 2)}px ${secondary}`,\n                            duration: 0.03,\n                            ease: 'none',\n                        },\n                        gs,\n                    );\n                    tl.to(\n                        char,\n                        {\n                            opacity: () => (Math.random() > 0.3 ? 1 : 0.5),\n                            duration: 0.02,\n                        },\n                        gs,\n                    );\n                    tl.call(\n                        () => {\n                            if (Math.random() > 0.4) {\n                                char.textContent =\n                                    glitchChars[\n                                        Math.floor(\n                                            Math.random() * glitchChars.length,\n                                        )\n                                    ] ?? originalText;\n                            }\n                        },\n                        [],\n                        gs + 0.015,\n                    );\n                }\n\n                tl.to(\n                    char,\n                    {\n                        x: 0,\n                        y: 0,\n                        textShadow: 'none',\n                        opacity: 1,\n                        scale: 1,\n                        duration: opts.duration * 0.15,\n                        ease: 'elastic.out(1, 0.3)',\n                    },\n                    t + opts.duration * 0.6,\n                );\n                tl.call(\n                    () => {\n                        char.textContent = originalText;\n                    },\n                    [],\n                    t + opts.duration * 0.8,\n                );\n            });\n        },\n    }),\n\n    gradient: ({ el, opts, effectColors }) => ({\n        special: (tl) => {\n            const colors =\n                effectColors.length > 0\n                    ? effectColors\n                    : ['#ff6ec7', '#ffe259', '#4af', '#ff6ec7'];\n            el.style.backgroundImage = `linear-gradient(90deg, ${colors.join(', ')})`;\n            el.style.backgroundSize = '300% 100%';\n            el.style.backgroundClip = 'text';\n            (\n                el.style as CSSStyleDeclaration & {\n                    webkitTextFillColor: string;\n                }\n            ).webkitTextFillColor = 'transparent';\n            tl.fromTo(\n                el,\n                { backgroundPosition: '0% 50%' },\n                {\n                    backgroundPosition: '100% 50%',\n                    duration: opts.duration,\n                    ease: 'none',\n                    repeat: opts.repeat,\n                },\n            );\n        },\n    }),\n\n    shadow: ({ chars, opts }) => ({\n        special: (tl) => {\n            tl.from(chars, {\n                opacity: 0,\n                duration: opts.duration,\n                stagger: resolveStagger(opts.stagger),\n            }).to(\n                chars,\n                {\n                    textShadow: '4px 4px 12px rgba(0,0,0,0.5)',\n                    duration: opts.duration * 0.6,\n                },\n                0,\n            );\n        },\n    }),\n\n    neon: ({ el, opts, effectColors }) => ({\n        special: (tl) => {\n            const c = effectColors[0] ?? '#39ff14';\n            tl.fromTo(\n                el,\n                { textShadow: `0 0 0px ${c}`, opacity: 0 },\n                {\n                    textShadow: `0 0 8px ${c}, 0 0 20px ${c}, 0 0 40px ${c}`,\n                    opacity: 1,\n                    duration: opts.duration,\n                },\n            );\n        },\n    }),\n\n    marquee: ({ chars, opts }) => ({\n        special: (tl) => {\n            fromChars(tl, chars, opts, {\n                x: '110%',\n                opacity: 0,\n                ease: 'power3.out',\n            });\n        },\n    }),\n\n    flicker: ({ chars, opts }) => ({\n        special: (tl) => {\n            gsap.set(chars, { opacity: 0 });\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.03);\n                tl.to(char, { opacity: 1, duration: 0.02 }, t);\n                tl.to(char, { opacity: 0.3, duration: 0.02 }, t + 0.02);\n                tl.to(char, { opacity: 1, duration: 0.02 }, t + 0.04);\n                tl.to(char, { opacity: 0.5, duration: 0.02 }, t + 0.06);\n                tl.to(\n                    char,\n                    { opacity: 1, duration: opts.duration * 0.3 },\n                    t + 0.08,\n                );\n            });\n        },\n    }),\n\n    spotlight: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger);\n                tl.from(\n                    char,\n                    {\n                        opacity: 0,\n                        scale: 0.8,\n                        textShadow: '0 0 0px transparent',\n                        duration: opts.duration,\n                        ease: 'power2.out',\n                    },\n                    t,\n                );\n                tl.to(\n                    char,\n                    {\n                        textShadow:\n                            '0 0 20px rgba(255,255,255,0.8), 0 0 40px rgba(255,255,255,0.4)',\n                        duration: opts.duration * 0.2,\n                    },\n                    t,\n                );\n            });\n        },\n    }),\n\n    outline: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger);\n                tl.from(\n                    char,\n                    {\n                        opacity: 0,\n                        textShadow: '0 0 0 transparent',\n                        duration: opts.duration,\n                        ease: 'power2.out',\n                    },\n                    t,\n                );\n                tl.to(\n                    char,\n                    {\n                        textShadow:\n                            '0 0 2px white, 0 0 4px white, 0 0 6px white',\n                        duration: opts.duration * 0.5,\n                    },\n                    t,\n                );\n            });\n        },\n    }),\n\n    pulse: ({ chars, opts }) => ({\n        special: (tl) => {\n            gsap.set(chars, { opacity: 0, scale: 0.8 });\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.03);\n                tl.to(\n                    char,\n                    {\n                        opacity: 1,\n                        scale: 1,\n                        duration: opts.duration * 0.3,\n                        ease: 'power2.out',\n                    },\n                    t,\n                );\n                tl.to(\n                    char,\n                    {\n                        scale: 1.15,\n                        duration: opts.duration * 0.15,\n                        ease: 'sine.inOut',\n                        yoyo: true,\n                        repeat: 1,\n                    },\n                    t + opts.duration * 0.3,\n                );\n                tl.to(\n                    char,\n                    {\n                        scale: 1,\n                        duration: opts.duration * 0.15,\n                        ease: 'power2.out',\n                    },\n                    t + opts.duration * 0.6,\n                );\n            });\n        },\n    }),\n\n    breathe: ({ chars, opts }) => ({\n        special: (tl) => {\n            gsap.set(chars, { opacity: 0, scale: 0.9 });\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger);\n                tl.to(\n                    char,\n                    {\n                        opacity: 1,\n                        scale: 1,\n                        duration: opts.duration * 0.4,\n                        ease: 'sine.out',\n                    },\n                    t,\n                );\n                tl.to(\n                    char,\n                    {\n                        scale: 1.05,\n                        duration: opts.duration * 0.25,\n                        ease: 'sine.inOut',\n                        yoyo: true,\n                        repeat: 1,\n                    },\n                    t + opts.duration * 0.4,\n                );\n                tl.to(\n                    char,\n                    {\n                        scale: 1,\n                        duration: opts.duration * 0.35,\n                        ease: 'sine.inOut',\n                    },\n                    t + opts.duration * 0.9,\n                );\n            });\n        },\n    }),\n\n    aurora: ({ chars, opts, effectColors }) => ({\n        special: (tl) => {\n            const colors =\n                effectColors.length > 0\n                    ? effectColors\n                    : ['#00d4ff', '#7b2cbf', '#2ec4b6', '#ff6b6b', '#4ecdc4'];\n            gsap.set(chars, { opacity: 0, filter: 'blur(6px)' });\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger);\n                const c = colors[i % colors.length]!;\n                tl.to(\n                    char,\n                    {\n                        opacity: 1,\n                        filter: 'blur(0px)',\n                        textShadow: `0 0 10px ${c}, 0 0 20px ${c}40`,\n                        duration: opts.duration * 0.5,\n                        ease: 'power2.out',\n                    },\n                    t,\n                );\n                tl.to(\n                    char,\n                    {\n                        textShadow: `0 0 5px ${c}, 0 0 10px ${c}20`,\n                        duration: opts.duration * 0.5,\n                        ease: 'sine.inOut',\n                    },\n                    t + opts.duration * 0.5,\n                );\n            });\n        },\n    }),\n\n    \/\/ \u2500\u2500 Special Effects \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    matrix: ({ chars, opts, effectColors }) => ({\n        special: (tl) => {\n            const charset =\n                'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%^&*';\n            const originals = chars.map((c) => c.textContent ?? '');\n            const color1 = effectColors[0] ?? '#00ff41';\n            const color2 = effectColors[1] ?? '#39ff14';\n\n            gsap.set(chars, { opacity: 0 });\n            chars.forEach((char, i) => {\n                const scrambleCount = 6;\n                const stepDuration = (opts.duration * 0.6) \/ scrambleCount;\n                const startTime = i * resolveStagger(opts.stagger, 0.05);\n\n                for (let s = 0; s < scrambleCount; s++) {\n                    tl.call(\n                        () => {\n                            char.textContent =\n                                charset[\n                                    Math.floor(Math.random() * charset.length)\n                                ] ?? originals[i];\n                            char.style.opacity = '1';\n                            char.style.color = s % 2 === 0 ? color1 : color2;\n                        },\n                        [],\n                        startTime + s * stepDuration,\n                    );\n                }\n\n                tl.call(\n                    () => {\n                        char.textContent = originals[i];\n                        char.style.color = '';\n                    },\n                    [],\n                    startTime + scrambleCount * stepDuration,\n                );\n            });\n        },\n    }),\n\n    fire: ({ chars, opts, effectColors }) => ({\n        special: (tl) => {\n            const colors =\n                effectColors.length > 0\n                    ? effectColors\n                    : ['#ff4500', '#ff6a00', '#ffae00', '#ffffff'];\n            gsap.set(chars, {\n                opacity: 0,\n                y: 40,\n                scaleY: 1.4,\n                transformOrigin: 'bottom center',\n            });\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.05);\n                tl.to(\n                    char,\n                    {\n                        opacity: 1,\n                        y: 0,\n                        scaleY: 1,\n                        duration: opts.duration * 0.5,\n                        ease: 'power2.out',\n                    },\n                    t,\n                );\n                colors.forEach((color, ci) => {\n                    tl.to(\n                        char,\n                        { color, duration: opts.duration * 0.15, ease: 'none' },\n                        t + ci * opts.duration * 0.15,\n                    );\n                });\n                tl.to(\n                    char,\n                    { color: '', duration: opts.duration * 0.15 },\n                    t + colors.length * opts.duration * 0.15,\n                );\n            });\n        },\n    }),\n\n    rainbow: ({ chars, opts, effectColors }) => ({\n        special: (tl) => {\n            const defaultHues = [0, 30, 60, 120, 180, 240, 270, 310];\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger);\n                const color =\n                    effectColors.length > 0\n                        ? effectColors[i % effectColors.length]!\n                        : `hsl(${defaultHues[i % defaultHues.length]}, 100%, 60%)`;\n                tl.from(\n                    char,\n                    {\n                        opacity: 0,\n                        y: -20,\n                        duration: opts.duration,\n                        ease: opts.ease,\n                    },\n                    t,\n                );\n                tl.to(char, { color, duration: opts.duration * 0.5 }, t);\n            });\n        },\n    }),\n\n    magnetic: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const a = Math.random() * Math.PI * 2;\n                const d = gsap.utils.random(100, 250) as number;\n                tl.from(\n                    char,\n                    {\n                        x: Math.cos(a) * d,\n                        y: Math.sin(a) * d,\n                        opacity: 0,\n                        scale: 0.2,\n                        duration: opts.duration,\n                        ease: 'power4.out',\n                    },\n                    i * resolveStagger(opts.stagger, 0.05),\n                );\n            });\n        },\n    }),\n\n    particles: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        scale: 3,\n                        opacity: 0,\n                        rotation: gsap.utils.random(-180, 180) as number,\n                        x: gsap.utils.random(-60, 60) as number,\n                        y: gsap.utils.random(-60, 60) as number,\n                        filter: 'blur(8px)',\n                        duration: opts.duration,\n                        ease: 'expo.out',\n                    },\n                    i * resolveStagger(opts.stagger, 0.06),\n                );\n            });\n        },\n    }),\n\n    dissolve: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger);\n                const steps = 5;\n                gsap.set(char, { opacity: 0 });\n\n                for (let s = 0; s < steps; s++) {\n                    tl.to(\n                        char,\n                        {\n                            opacity: s % 2 === 0 ? 0.6 : 0.1,\n                            duration: opts.duration \/ steps \/ 2,\n                            ease: 'none',\n                        },\n                        t + s * (opts.duration \/ steps \/ 2),\n                    );\n                }\n\n                tl.to(\n                    char,\n                    {\n                        opacity: 1,\n                        duration: opts.duration \/ steps,\n                        ease: 'power2.out',\n                    },\n                    t + steps * (opts.duration \/ steps \/ 2),\n                );\n            });\n        },\n    }),\n\n    scramble: ({ chars, opts }) => ({\n        special: (tl) => {\n            const pool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%';\n            const originals = chars.map((c) => c.textContent ?? '');\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.05);\n                const iters = 8;\n                const step = (opts.duration * 0.7) \/ iters;\n                gsap.set(char, { opacity: 1 });\n\n                for (let s = 0; s < iters; s++) {\n                    tl.call(\n                        () => {\n                            char.textContent =\n                                pool[Math.floor(Math.random() * pool.length)] ??\n                                originals[i];\n                        },\n                        [],\n                        t + s * step,\n                    );\n                }\n\n                tl.call(\n                    () => {\n                        char.textContent = originals[i];\n                    },\n                    [],\n                    t + iters * step,\n                );\n            });\n        },\n    }),\n\n    zap: ({ chars, opts, effectColors }) => ({\n        special: (tl) => {\n            const c1 = effectColors[0] ?? '#ffe600';\n            const c2 = effectColors[1] ?? '#ff6a00';\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger);\n                tl.set(char, { opacity: 0 }, t)\n                    .to(\n                        char,\n                        {\n                            opacity: 1,\n                            color: '#fff',\n                            textShadow: `0 0 20px ${c1}, 0 0 40px ${c2}`,\n                            scale: 1.3,\n                            duration: 0.06,\n                        },\n                        t,\n                    )\n                    .to(\n                        char,\n                        {\n                            color: '',\n                            textShadow: 'none',\n                            scale: 1,\n                            duration: opts.duration * 0.6,\n                            ease: 'power3.out',\n                        },\n                        t + 0.06,\n                    );\n            });\n        },\n    }),\n\n    orbit: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const angle = (i \/ chars.length) * Math.PI * 2 - Math.PI \/ 2;\n                tl.from(\n                    char,\n                    {\n                        x: Math.cos(angle) * 80,\n                        y: Math.sin(angle) * 80,\n                        opacity: 0,\n                        scale: 0,\n                        duration: opts.duration,\n                        ease: 'power3.out',\n                    },\n                    i * resolveStagger(opts.stagger),\n                );\n            });\n        },\n    }),\n\n    vortex: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        rotation: (i \/ chars.length) * 720,\n                        scale: 0,\n                        opacity: 0,\n                        x: Math.sin((i \/ chars.length) * Math.PI * 4) * 60,\n                        y: Math.cos((i \/ chars.length) * Math.PI * 4) * 60,\n                        duration: opts.duration,\n                        ease: 'power3.out',\n                    },\n                    i * resolveStagger(opts.stagger, 0.03),\n                );\n            });\n        },\n    }),\n\n    ripple: ({ chars, opts }) => ({\n        special: (tl) => {\n            const center = Math.floor(chars.length \/ 2);\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        y: -30,\n                        opacity: 0,\n                        scale: 0.5,\n                        duration: opts.duration,\n                        ease: 'elastic.out(1, 0.5)',\n                    },\n                    Math.abs(i - center) *\n                        resolveStagger(opts.stagger, 0.04) *\n                        1.5,\n                );\n            });\n        },\n    }),\n\n    piano: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.05);\n                tl.from(\n                    char,\n                    {\n                        y: -80,\n                        scaleY: 1.5,\n                        opacity: 0,\n                        duration: opts.duration * 0.4,\n                        ease: 'power2.in',\n                    },\n                    t,\n                )\n                    .to(\n                        char,\n                        { y: 5, scaleY: 0.9, duration: opts.duration * 0.1 },\n                        t + opts.duration * 0.4,\n                    )\n                    .to(\n                        char,\n                        {\n                            y: 0,\n                            scaleY: 1,\n                            duration: opts.duration * 0.5,\n                            ease: 'bounce.out',\n                        },\n                        t + opts.duration * 0.5,\n                    );\n            });\n        },\n    }),\n\n    domino: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        rotationZ: -90,\n                        transformOrigin: 'bottom center',\n                        opacity: 0,\n                        duration: opts.duration * 0.6,\n                        ease: 'power2.out',\n                    },\n                    i * resolveStagger(opts.stagger, 0.07),\n                );\n            });\n        },\n    }),\n\n    pendulum: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        rotationZ: (i % 2 === 0 ? 1 : -1) * 60,\n                        transformOrigin: 'top center',\n                        opacity: 0,\n                        duration: opts.duration,\n                        ease: 'elastic.out(0.6, 0.3)',\n                    },\n                    i * resolveStagger(opts.stagger, 0.05),\n                );\n            });\n        },\n    }),\n\n    shatter: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        skewX: gsap.utils.random(-40, 40) as number,\n                        skewY: gsap.utils.random(-20, 20) as number,\n                        x: gsap.utils.random(-50, 50) as number,\n                        scale: gsap.utils.random(0.1, 2) as number,\n                        opacity: 0,\n                        rotation: gsap.utils.random(-45, 45) as number,\n                        duration: opts.duration,\n                        ease: 'power4.out',\n                    },\n                    i * resolveStagger(opts.stagger),\n                );\n            });\n        },\n    }),\n\n    smoke: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        y: gsap.utils.random(20, 60) as number,\n                        x: gsap.utils.random(-15, 15) as number,\n                        opacity: 0,\n                        filter: 'blur(8px)',\n                        scale: gsap.utils.random(0.8, 1.4) as number,\n                        duration: opts.duration,\n                        ease: 'power1.out',\n                    },\n                    i * resolveStagger(opts.stagger, 0.05),\n                );\n            });\n        },\n    }),\n\n    thunder: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.05);\n                tl.set(char, { opacity: 0 }, t)\n                    .to(char, { opacity: 1, y: -100, duration: 0.01 }, t)\n                    .to(\n                        char,\n                        {\n                            y: 0,\n                            duration: opts.duration * 0.3,\n                            ease: 'power4.in',\n                        },\n                        t + 0.01,\n                    )\n                    .to(\n                        char,\n                        { textShadow: '0 0 20px #ffe600', duration: 0.05 },\n                        t + opts.duration * 0.3,\n                    )\n                    .to(\n                        char,\n                        {\n                            textShadow: 'none',\n                            duration: opts.duration * 0.3,\n                            ease: 'power2.out',\n                        },\n                        t + opts.duration * 0.35,\n                    )\n                    .to(\n                        char,\n                        { y: -5, duration: 0.06 },\n                        t + opts.duration * 0.3,\n                    )\n                    .to(\n                        char,\n                        { y: 0, duration: 0.1, ease: 'bounce.out' },\n                        t + opts.duration * 0.36,\n                    );\n            });\n        },\n    }),\n\n    crystallize: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.06);\n                tl.from(\n                    char,\n                    {\n                        opacity: 0,\n                        scale: 1.8,\n                        skewX: gsap.utils.random(-30, 30) as number,\n                        skewY: gsap.utils.random(-15, 15) as number,\n                        filter: 'blur(4px) brightness(2)',\n                        color: '#a0e4ff',\n                        duration: opts.duration,\n                        ease: 'power3.out',\n                    },\n                    t,\n                );\n                tl.to(\n                    char,\n                    {\n                        color: '',\n                        filter: 'none',\n                        duration: opts.duration * 0.3,\n                    },\n                    t + opts.duration * 0.7,\n                );\n            });\n        },\n    }),\n\n    warp: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger);\n                tl.from(\n                    char,\n                    {\n                        scaleX: 8,\n                        opacity: 0,\n                        duration: opts.duration * 0.4,\n                        ease: 'power3.out',\n                    },\n                    t,\n                )\n                    .to(\n                        char,\n                        { scaleX: 0.8, duration: opts.duration * 0.15 },\n                        t + opts.duration * 0.4,\n                    )\n                    .to(\n                        char,\n                        {\n                            scaleX: 1,\n                            duration: opts.duration * 0.45,\n                            ease: 'elastic.out(1, 0.6)',\n                        },\n                        t + opts.duration * 0.55,\n                    );\n            });\n        },\n    }),\n\n    cinema: ({ el, opts }) => ({\n        special: (tl) => {\n            gsap.set(el, {\n                opacity: 0,\n                filter: 'sepia(1) contrast(2) brightness(0.5)',\n            });\n\n            for (let f = 0; f < 8; f++) {\n                tl.to(el, {\n                    opacity:\n                        f % 2 === 0\n                            ? (gsap.utils.random(0.2, 0.7) as number)\n                            : 0,\n                    duration: opts.duration \/ 16,\n                    ease: 'none',\n                });\n            }\n\n            tl.to(el, { opacity: 1, duration: opts.duration * 0.3 }).to(el, {\n                filter: 'sepia(0) contrast(1) brightness(1)',\n                duration: opts.duration * 0.5,\n                ease: 'power2.inOut',\n            });\n        },\n    }),\n\n    gravity: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        y: -100,\n                        rotation: -30,\n                        opacity: 0,\n                        duration: opts.duration * 0.7,\n                        ease: 'bounce.out',\n                    },\n                    i * resolveStagger(opts.stagger),\n                );\n            });\n        },\n    }),\n\n    levitate: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        y: 50,\n                        opacity: 0,\n                        duration: opts.duration,\n                        ease: 'power3.out',\n                    },\n                    i * resolveStagger(opts.stagger, 0.05),\n                );\n            });\n        },\n    }),\n\n    twinkle: ({ chars, opts }) => ({\n        special: (tl) => {\n            gsap.set(chars, { opacity: 0, scale: 0.5 });\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.03);\n                tl.to(\n                    char,\n                    {\n                        opacity: 1,\n                        scale: 1,\n                        duration: opts.duration * 0.3,\n                        ease: 'power2.out',\n                    },\n                    t,\n                );\n                tl.to(\n                    char,\n                    {\n                        opacity: 0.3,\n                        scale: 0.8,\n                        duration: opts.duration * 0.15,\n                        ease: 'sine.inOut',\n                        yoyo: true,\n                        repeat: 1,\n                    },\n                    t + opts.duration * 0.3,\n                );\n                tl.to(\n                    char,\n                    { opacity: 1, scale: 1, duration: opts.duration * 0.2 },\n                    t + opts.duration * 0.6,\n                );\n            });\n        },\n    }),\n\n    shimmerFade: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger);\n                tl.from(\n                    char,\n                    {\n                        opacity: 0,\n                        duration: opts.duration * 0.5,\n                        ease: 'power2.out',\n                    },\n                    t,\n                );\n                tl.to(\n                    char,\n                    {\n                        opacity: 0.7,\n                        duration: opts.duration * 0.2,\n                        ease: 'sine.inOut',\n                        yoyo: true,\n                        repeat: 1,\n                    },\n                    t + opts.duration * 0.5,\n                );\n                tl.to(\n                    char,\n                    { opacity: 1, duration: opts.duration * 0.3 },\n                    t + opts.duration * 0.9,\n                );\n            });\n        },\n    }),\n\n    fold: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        scaleY: 0,\n                        opacity: 0,\n                        transformOrigin: 'bottom center',\n                        duration: opts.duration,\n                        ease: 'back.out(1.5)',\n                    },\n                    i * resolveStagger(opts.stagger, 0.05),\n                );\n            });\n        },\n    }),\n\n    cascade: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const startY = gsap.utils.random(-120, -40) as number;\n                const t = i * resolveStagger(opts.stagger, 0.04);\n                tl.from(\n                    char,\n                    {\n                        y: startY,\n                        opacity: 0,\n                        duration: opts.duration * 0.6,\n                        ease: 'power3.in',\n                    },\n                    t,\n                ).to(\n                    char,\n                    { y: 0, duration: opts.duration * 0.4, ease: 'bounce.out' },\n                    t + opts.duration * 0.6,\n                );\n            });\n        },\n    }),\n\n    pinball: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.06);\n                const dir = i % 2 === 0 ? 1 : -1;\n                gsap.set(char, { opacity: 0 });\n                tl.to(char, { opacity: 1, duration: 0.01 }, t)\n                    .from(\n                        char,\n                        {\n                            x: dir * 80,\n                            duration: opts.duration * 0.25,\n                            ease: 'power2.in',\n                        },\n                        t,\n                    )\n                    .to(\n                        char,\n                        {\n                            x: -dir * 30,\n                            duration: opts.duration * 0.2,\n                            ease: 'power1.out',\n                        },\n                        t + opts.duration * 0.25,\n                    )\n                    .to(\n                        char,\n                        {\n                            x: dir * 10,\n                            duration: opts.duration * 0.15,\n                            ease: 'power1.in',\n                        },\n                        t + opts.duration * 0.45,\n                    )\n                    .to(\n                        char,\n                        {\n                            x: 0,\n                            duration: opts.duration * 0.2,\n                            ease: 'bounce.out',\n                        },\n                        t + opts.duration * 0.6,\n                    );\n            });\n        },\n    }),\n\n    neonFlicker: ({ chars, opts, effectColors }) => ({\n        special: (tl) => {\n            const glowColor = effectColors[0] ?? '#39ff14';\n            const flickerOffsets = [0, 0.05, 0.1, 0.16, 0.22, 0.3];\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.05);\n                gsap.set(char, { opacity: 0 });\n                flickerOffsets.forEach((offset, fi) => {\n                    tl.to(\n                        char,\n                        {\n                            opacity: fi % 2 === 0 ? 1 : 0.15,\n                            color: glowColor,\n                            textShadow:\n                                fi % 2 === 0\n                                    ? `0 0 6px ${glowColor}, 0 0 20px ${glowColor}`\n                                    : 'none',\n                            duration: 0.04,\n                            ease: 'none',\n                        },\n                        t + offset,\n                    );\n                });\n                tl.to(\n                    char,\n                    {\n                        opacity: 1,\n                        color: '',\n                        textShadow: 'none',\n                        duration: opts.duration * 0.4,\n                        ease: 'power2.out',\n                    },\n                    t + 0.34,\n                );\n            });\n        },\n    }),\n\n    rise: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const sway = gsap.utils.random(-12, 12) as number;\n                const t = i * resolveStagger(opts.stagger, 0.05);\n                tl.from(\n                    char,\n                    {\n                        y: 60,\n                        x: sway,\n                        opacity: 0,\n                        scale: 0.7,\n                        filter: 'blur(4px)',\n                        duration: opts.duration,\n                        ease: 'power2.out',\n                    },\n                    t,\n                );\n                tl.to(\n                    char,\n                    {\n                        x: 0,\n                        filter: 'blur(0px)',\n                        duration: opts.duration * 0.4,\n                        ease: 'sine.out',\n                    },\n                    t + opts.duration * 0.6,\n                );\n            });\n        },\n    }),\n\n    unfurl: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                tl.from(\n                    char,\n                    {\n                        rotationY: -90,\n                        opacity: 0,\n                        transformPerspective: 600,\n                        transformOrigin: 'left center',\n                        duration: opts.duration,\n                        ease: 'back.out(1.4)',\n                    },\n                    i * resolveStagger(opts.stagger, 0.05),\n                );\n            });\n        },\n    }),\n\n    stampIn: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                const t = i * resolveStagger(opts.stagger, 0.12);\n                tl.from(\n                    char,\n                    {\n                        y: -120,\n                        scaleY: 1.4,\n                        opacity: 0,\n                        transformOrigin: 'top center',\n                        duration: opts.duration * 0.35,\n                        ease: 'power4.in',\n                    },\n                    t,\n                )\n                    .to(\n                        char,\n                        {\n                            scaleY: 0.6,\n                            scaleX: 1.3,\n                            duration: opts.duration * 0.1,\n                            ease: 'power1.out',\n                        },\n                        t + opts.duration * 0.35,\n                    )\n                    .to(\n                        char,\n                        {\n                            scaleY: 1.1,\n                            scaleX: 0.95,\n                            duration: opts.duration * 0.12,\n                            ease: 'power1.inOut',\n                        },\n                        t + opts.duration * 0.45,\n                    )\n                    .to(\n                        char,\n                        {\n                            scaleY: 1,\n                            scaleX: 1,\n                            duration: opts.duration * 0.31,\n                            ease: 'elastic.out(1, 0.5)',\n                        },\n                        t + opts.duration * 0.57,\n                    );\n            });\n        },\n    }),\n\n    blinds: ({ chars, opts }) => ({\n        special: (tl) => {\n            chars.forEach((char, i) => {\n                gsap.set(char, {\n                    transformOrigin: 'top center',\n                    scaleY: 0,\n                    opacity: 1,\n                });\n                tl.to(\n                    char,\n                    {\n                        scaleY: 1,\n                        duration: opts.duration,\n                        ease: 'back.out(1.6)',\n                    },\n                    i * resolveStagger(opts.stagger, 0.1),\n                );\n            });\n        },\n    }),\n};\n\n\/\/ \u2500\u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst TextAnimator = forwardRef<TextAnimatorRef, TextAnimatorProps>(\n    function TextAnimator(\n        {\n            text,\n            children,\n            animation = 'fadeInUp',\n            trigger = 'scrollTrigger',\n            splitBy = 'chars',\n            tag: Tag = 'span',\n            duration = 0.8,\n            delay = 0,\n            stagger = 0.04,\n            ease = 'power3.out',\n            repeat = 0,\n            yoyo = false,\n            scrollTrigger: scrollTriggerOpts,\n            color,\n            fontSize,\n            className = '',\n            style = {},\n            effectColor,\n            onComplete,\n            onStart,\n            onRepeat,\n        },\n        ref,\n    ) {\n        const elRef = useRef<HTMLElement>(null);\n        const tlRef = useRef<gsap.core.Timeline | null>(null);\n        const stRef = useRef<ScrollTrigger | null>(null);\n\n        \/\/ \u2500\u2500 Stable callback refs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n        const onCompleteRef = useRef(onComplete);\n        const onStartRef = useRef(onStart);\n        const onRepeatRef = useRef(onRepeat);\n\n        useEffect(() => {\n            onCompleteRef.current = onComplete;\n        }, [onComplete]);\n        useEffect(() => {\n            onStartRef.current = onStart;\n        }, [onStart]);\n        useEffect(() => {\n            onRepeatRef.current = onRepeat;\n        }, [onRepeat]);\n\n        const content: string = children ?? text ?? 'Animate Me';\n\n        const resolvedOpts: ResolvedAnimOpts = useMemo(\n            () => ({ duration, delay, stagger, ease, repeat, yoyo }),\n            [duration, delay, stagger, ease, repeat, yoyo],\n        );\n\n        \/\/ \u2500\u2500 Build timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n        const buildTimeline = useCallback((): gsap.core.Timeline | null => {\n            const el = elRef.current;\n\n            if (!el) {\n                return null;\n            }\n\n            const def = ANIMATIONS[animation] ?? ANIMATIONS['fadeIn']!;\n            el.textContent = content;\n\n            let chars: HTMLElement[] = [];\n            let words: HTMLElement[] = [];\n\n            if (splitBy === 'chars') {\n                chars = splitChars(el);\n            } else if (splitBy === 'words') {\n                words = splitWords(el);\n                chars = words;\n            } else if (splitBy === 'lines') {\n                words = splitLines(el);\n                chars = words;\n            }\n\n            const rawColors = Array.isArray(effectColor)\n                ? effectColor\n                : effectColor\n                  ? [effectColor]\n                  : [];\n            const effectColors =\n                rawColors.length === 1\n                    ? [rawColors[0]!, rawColors[0]!]\n                    : rawColors;\n\n            const ctx: AnimationContext = {\n                chars,\n                words,\n                el,\n                opts: resolvedOpts,\n                effectColors,\n            };\n            const config = def(ctx);\n\n            const tl = gsap.timeline({\n                paused: true,\n                defaults: {\n                    duration: resolvedOpts.duration,\n                    ease: resolvedOpts.ease,\n                },\n                onStart: () => onStartRef.current?.(),\n                onComplete: () => onCompleteRef.current?.(),\n                onRepeat: () => onRepeatRef.current?.(),\n                delay: resolvedOpts.delay,\n                repeat: resolvedOpts.repeat,\n                yoyo: resolvedOpts.yoyo,\n            });\n\n            if (config.special) {\n                config.special(tl);\n            } else if (config.targets && config.from && config.to) {\n                tl.fromTo(config.targets, config.from, {\n                    ...config.to,\n                    stagger: resolvedOpts.stagger,\n                    ease: config.overrideEase\n                        ? config.to.ease\n                        : resolvedOpts.ease,\n                });\n            }\n\n            return tl;\n        }, [animation, content, splitBy, effectColor, resolvedOpts]);\n\n        \/\/ \u2500\u2500 GSAP context \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n        useGSAP(\n            () => {\n                const el = elRef.current;\n\n                if (!el) {\n                    return;\n                }\n\n                stRef.current?.kill();\n                tlRef.current?.kill();\n\n                const tl = buildTimeline();\n                tlRef.current = tl;\n\n                if (!tl) {\n                    return;\n                }\n\n                if (trigger === 'scrollTrigger') {\n                    stRef.current = ScrollTrigger.create({\n                        trigger: el,\n                        start: scrollTriggerOpts?.start ?? 'top 80%',\n                        end: scrollTriggerOpts?.end ?? 'bottom 20%',\n                        scrub: scrollTriggerOpts?.scrub ?? false,\n                        markers: scrollTriggerOpts?.markers ?? false,\n                        pin: scrollTriggerOpts?.pin ?? false,\n                        toggleActions:\n                            scrollTriggerOpts?.toggleActions ??\n                            'play none none reverse',\n                        animation: tl,\n                    });\n                }\n            },\n            {\n                scope: elRef,\n                dependencies: [\n                    animation,\n                    content,\n                    trigger,\n                    splitBy,\n                    resolvedOpts,\n                    scrollTriggerOpts,\n                    buildTimeline,\n                ],\n            },\n        );\n\n        \/\/ \u2500\u2500 Trigger handlers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n        const handleClick = useCallback(() => {\n            if (trigger !== 'onClick') {\n                return;\n            }\n\n            tlRef.current?.restart();\n        }, [trigger]);\n\n        const handleMouseEnter = useCallback(() => {\n            if (trigger !== 'onHover') {\n                return;\n            }\n\n            tlRef.current?.play();\n        }, [trigger]);\n\n        const handleMouseLeave = useCallback(() => {\n            if (trigger !== 'onHover') {\n                return;\n            }\n\n            tlRef.current?.reverse();\n        }, [trigger]);\n\n        const handleKeyDown = useCallback(\n            (e: KeyboardEvent<Element>) => {\n                if (\n                    trigger === 'onClick' &&\n                    (e.key === 'Enter' || e.key === ' ')\n                ) {\n                    handleClick();\n                }\n            },\n            [trigger, handleClick],\n        );\n\n        \/\/ \u2500\u2500 Ref API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n        useImperativeHandle(ref, () => ({\n            play: () => tlRef.current?.play(),\n            pause: () => tlRef.current?.pause(),\n            reverse: () => tlRef.current?.reverse(),\n            restart: () => tlRef.current?.restart(),\n            seek: (t: number) => tlRef.current?.seek(t),\n            kill: () => {\n                tlRef.current?.kill();\n                stRef.current?.kill();\n            },\n            timeline: () => tlRef.current,\n            isPlaying: () => tlRef.current?.isActive() ?? false,\n            progress: () => tlRef.current?.progress() ?? 0,\n        }));\n\n        \/\/ \u2500\u2500 Render \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n        const tagStyle: React.CSSProperties = {\n            display: 'inline-block',\n            cursor: trigger === 'onClick' ? 'pointer' : 'default',\n            ...(color ? { color } : {}),\n            ...(fontSize ? { fontSize } : {}),\n            ...style,\n        };\n\n        return (\n            <Tag\n                ref={elRef as React.RefObject<HTMLElement>}\n                className={`text-animator ${className}`.trim()}\n                style={tagStyle}\n                onClick={handleClick}\n                onMouseEnter={handleMouseEnter}\n                onMouseLeave={handleMouseLeave}\n                aria-label={content}\n                role={trigger === 'onClick' ? 'button' : undefined}\n                tabIndex={trigger === 'onClick' ? 0 : undefined}\n                onKeyDown={trigger === 'onClick' ? handleKeyDown : undefined}\n            >\n                {content}\n            <\/Tag>\n        );\n    },\n);\n\nexport default TextAnimator;\nexport { ANIMATIONS };\n"}],"meta":{"category":"animations","version":"1.0.0"},"categories":["animations"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"text-circle-loader","type":"registry:ui","title":"Text Circle Loader","description":"A circular rotating loader featuring character animation powered by TextAnimator and custom radial keyframe effects.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/text-animator.json","utils","https:\/\/ui.test\/r\/animate-css\/animate-neon-ring-rotate.json","https:\/\/ui.test\/r\/animate-css\/animate-liquid-blob-rotate.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/animations\/text-circle-loader.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport TextAnimator from '@\/registry\/new-york\/components\/ui\/animations\/text-animator';\nimport type { AnimationType } from '@\/registry\/new-york\/components\/ui\/animations\/text-animator';\nimport { cn } from '@\/lib\/utils';\n\nexport interface TextCircleLoaderProps extends React.HTMLAttributes<HTMLDivElement> {\n    \/**\n     * Text to display and animate inside the circle loader.\n     * Default: \"Generating...\"\n     *\/\n    text?: string;\n    \/**\n     * Pre-defined aesthetic variants\n     * - `neon-ring`: Solid spinning ring with deep inset glow shadows mapping to primary and chart colors\n     * - `gradient-dash`: Concentric dashed borders rotating in opposite directions for a techy HUD feel\n     * - `liquid-blob`: A rotating organic blob that morphs shape fluidly using keyframed border-radius transitions\n     *\/\n    variant?: 'neon-ring' | 'gradient-dash' | 'liquid-blob';\n    \/**\n     * Sizing of the loader\n     * - `sm`: 140px\n     * - `md`: 180px\n     * - `lg`: 220px\n     * Or pass a number (in pixels) for custom sizes.\n     *\/\n    size?: 'sm' | 'md' | 'lg' | number;\n    \/**\n     * GSAP text animation type from TextAnimator component.\n     * Default: \"wave\"\n     *\/\n    textAnimation?: AnimationType;\n    \/**\n     * Duration of the text animation loop in seconds.\n     * Default: 1.5\n     *\/\n    textDuration?: number;\n    \/**\n     * Stagger delay between characters.\n     * Default: 0.06\n     *\/\n    textStagger?: number;\n    \/**\n     * Rotation \/ morphing speed of the ring in seconds.\n     * Default: 2.5\n     *\/\n    ringDuration?: number;\n}\n\nexport function TextCircleLoader({\n    text = 'Generating',\n    variant = 'neon-ring',\n    size = 'md',\n    textAnimation = 'wave',\n    textDuration = 1.5,\n    textStagger = 0.06,\n    ringDuration = 2.5,\n    className,\n    style,\n    ...props\n}: TextCircleLoaderProps) {\n    const sizePx =\n        typeof size === 'number' ? size : { sm: 140, md: 180, lg: 220 }[size];\n\n    return (\n        <div\n            className={cn(\n                'relative flex items-center justify-center rounded-full border border-border\/10 bg-transparent select-none',\n                className,\n            )}\n            style={{\n                width: sizePx,\n                height: sizePx,\n                ...style,\n            }}\n            {...props}\n        >\n            {\/* Rotating \/ Animating Ring backdrops *\/}\n            {variant === 'neon-ring' && (\n                <div\n                    className=\"absolute inset-0 z-0 animate-neon-ring-rotate rounded-full bg-transparent\"\n                    style={{\n                        ['--animate-neon-ring-rotate-duration' as any]: `${ringDuration}s`,\n                    }}\n                \/>\n            )}\n\n            {variant === 'gradient-dash' && (\n                <>\n                    {\/* Outer Dashed Ring *\/}\n                    <div\n                        className=\"absolute inset-0 z-0 animate-spin rounded-full border-2 border-dashed border-primary\/50\"\n                        style={{\n                            animationDuration: `${ringDuration}s`,\n                        }}\n                    \/>\n                    {\/* Inner Dotted Ring - Counter Rotating *\/}\n                    <div\n                        className=\"absolute inset-3 z-0 animate-spin rounded-full border border-dotted border-chart-2\/60\"\n                        style={{\n                            animationDuration: `${ringDuration * 1.5}s`,\n                            animationDirection: 'reverse',\n                        }}\n                    \/>\n                    {\/* Secondary Accent Ring *\/}\n                    <div className=\"absolute inset-6 z-0 animate-[pulse_2s_ease-in-out_infinite] rounded-full border border-primary\/10\" \/>\n                <\/>\n            )}\n\n            {variant === 'liquid-blob' && (\n                <div\n                    className=\"absolute inset-0 z-0 animate-liquid-blob-rotate bg-transparent\"\n                    style={{\n                        ['--animate-liquid-blob-rotate-duration' as any]: `${ringDuration * 1.6}s`,\n                    }}\n                \/>\n            )}\n\n            {\/* Text Animator Component for letters *\/}\n            <div className=\"relative z-10 font-medium tracking-wide text-foreground\">\n                <TextAnimator\n                    text={text}\n                    animation={textAnimation}\n                    duration={textDuration}\n                    stagger={textStagger}\n                    repeat={-1}\n                    yoyo={true}\n                    fontSize={sizePx * 0.09}\n                    className=\"font-semibold text-foreground\/90 drop-shadow-sm select-none\"\n                \/>\n            <\/div>\n        <\/div>\n    );\n}\n\nTextCircleLoader.displayName = 'TextCircleLoader';\n"}],"meta":{"category":"animations","version":"1.0.0"},"categories":["animations"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"banner-expandable","type":"registry:ui","title":"Banner Expandable","description":"A collapsible header banner that expands vertically to reveal rich release logs or details.","author":"designbycode","dependencies":["motion","lucide-react"],"devDependencies":[],"registryDependencies":["utils","https:\/\/ui.test\/r\/wrapper.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/banners\/banner-expandable.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { motion, AnimatePresence } from 'motion\/react';\nimport { X, ChevronDown } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport Wrapper from '@\/registry\/new-york\/components\/ui\/misc\/wrapper';\n\ninterface BannerExpandableProps extends React.HTMLAttributes<HTMLDivElement> {\n    title: string;\n    description: React.ReactNode;\n    badgeLabel?: string;\n    onClose?: () => void;\n}\n\nexport function BannerExpandable({\n    title,\n    description,\n    badgeLabel,\n    onClose,\n    className,\n    ...props\n}: BannerExpandableProps) {\n    const [isExpanded, setIsExpanded] = React.useState(false);\n    const [isVisible, setIsVisible] = React.useState(true);\n\n    if (!isVisible) return null;\n\n    return (\n        <div\n            className={cn(\n                'relative w-full border-b border-border bg-card\/65 backdrop-blur-md transition-all duration-350 select-none',\n                isExpanded && 'border-border\/80 bg-card shadow-md',\n                className,\n            )}\n            {...props}\n        >\n            <Wrapper className=\"flex flex-col justify-between gap-3 py-3.5 text-xs md:flex-row md:items-center\">\n                {\/* Header Section *\/}\n                <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n                    {badgeLabel && (\n                        <span className=\"shrink-0 rounded-full border border-primary\/20 bg-primary\/10 px-2.5 py-0.5 text-[10px] font-bold tracking-wide text-primary uppercase\">\n                            {badgeLabel}\n                        <\/span>\n                    )}\n                    <span className=\"cursor-default truncate font-bold text-foreground select-text\">\n                        {title}\n                    <\/span>\n                    <button\n                        onClick={() => setIsExpanded(!isExpanded)}\n                        className=\"ml-1 inline-flex shrink-0 cursor-pointer items-center gap-1 border-0 bg-transparent font-semibold text-primary transition-all hover:text-primary\/95 hover:underline\"\n                    >\n                        {isExpanded ? 'Show Less' : 'Learn More'}\n                        <ChevronDown\n                            className={cn(\n                                'size-3.5 transition-transform duration-200',\n                                isExpanded && 'rotate-180 text-primary',\n                            )}\n                        \/>\n                    <\/button>\n                <\/div>\n\n                {\/* Dismiss Button *\/}\n                <div className=\"flex items-center justify-end gap-2\">\n                    <button\n                        onClick={() => {\n                            setIsVisible(false);\n                            if (onClose) onClose();\n                        }}\n                        className=\"shrink-0 cursor-pointer rounded-lg p-1 text-muted-foreground\/70 transition-all hover:bg-muted hover:text-foreground\"\n                    >\n                        <X className=\"size-4\" \/>\n                    <\/button>\n                <\/div>\n            <\/Wrapper>\n\n            {\/* Expand Panel *\/}\n            <AnimatePresence initial={false}>\n                {isExpanded && (\n                    <motion.div\n                        initial={{ height: 0, opacity: 0 }}\n                        animate={{ height: 'auto', opacity: 1 }}\n                        exit={{ height: 0, opacity: 0 }}\n                        transition={{ duration: 0.25, ease: 'easeInOut' }}\n                        className=\"overflow-hidden border-t border-border\/50 bg-muted\/20\"\n                    >\n                        <Wrapper className=\"py-5 text-xs leading-relaxed text-muted-foreground\">\n                            {description}\n                        <\/Wrapper>\n                    <\/motion.div>\n                )}\n            <\/AnimatePresence>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"banners","version":"1.0.0"},"categories":["banners"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"banner-floating","type":"registry:ui","title":"Banner Floating","description":"A floating dismissible card banner layout with entry and exit spring motion transitions.","author":"designbycode","dependencies":["motion","lucide-react"],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/banners\/banner-floating.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { motion, AnimatePresence } from 'motion\/react';\nimport { X } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nconst MotionCard = motion(Card);\n\ninterface BannerFloatingProps extends React.HTMLAttributes<HTMLDivElement> {\n    title: string;\n    description: string;\n    actionLabel?: string;\n    onActionClick?: () => void;\n    onClose?: () => void;\n    position?: 'bottom-right' | 'bottom-left' | 'top-center';\n    icon?: React.ReactNode;\n}\n\nexport function BannerFloating({\n    title,\n    description,\n    actionLabel,\n    onActionClick,\n    onClose,\n    position = 'bottom-right',\n    icon,\n    className,\n    ...props\n}: BannerFloatingProps) {\n    const [isVisible, setIsVisible] = React.useState(true);\n\n    const { onDrag, onDragStart, onDragEnd, onAnimationStart, ...safeProps } =\n        props as any;\n\n    const handleDismiss = () => {\n        setIsVisible(false);\n        if (onClose) {\n            onClose();\n        }\n    };\n\n    const positionClasses = {\n        'bottom-right': 'bottom-6 right-6 md:max-w-md',\n        'bottom-left': 'bottom-6 left-6 md:max-w-md',\n        'top-center':\n            'top-6 left-1\/2 -translate-x-1\/2 md:max-w-xl w-[calc(100%-2rem)]',\n    };\n\n    const animations = {\n        'bottom-right': {\n            initial: { opacity: 0, y: 50, scale: 0.95 },\n            animate: { opacity: 1, y: 0, scale: 1 },\n            exit: { opacity: 0, y: 20, scale: 0.95 },\n        },\n        'bottom-left': {\n            initial: { opacity: 0, y: 50, scale: 0.95 },\n            animate: { opacity: 1, y: 0, scale: 1 },\n            exit: { opacity: 0, y: 20, scale: 0.95 },\n        },\n        'top-center': {\n            initial: { opacity: 0, y: -50, scale: 0.95 },\n            animate: { opacity: 1, y: 0, scale: 1 },\n            exit: { opacity: 0, y: -20, scale: 0.95 },\n        },\n    };\n\n    return (\n        <AnimatePresence>\n            {isVisible && (\n                <MotionCard\n                    initial={animations[position].initial}\n                    animate={animations[position].animate}\n                    exit={animations[position].exit}\n                    transition={{ type: 'spring', stiffness: 260, damping: 20 }}\n                    className={cn(\n                        'fixed z-50 bg-card\/95 p-5 shadow-lg backdrop-blur-md select-none',\n                        positionClasses[position],\n                        className,\n                    )}\n                    {...safeProps}\n                >\n                    <div className=\"flex items-start gap-4\">\n                        {icon && (\n                            <div className=\"flex size-9 shrink-0 items-center justify-center rounded-lg border border-border\/40 bg-muted text-foreground\">\n                                {icon}\n                            <\/div>\n                        )}\n                        <div className=\"flex-1 space-y-1\">\n                            <h4 className=\"text-sm font-bold tracking-tight text-foreground\">\n                                {title}\n                            <\/h4>\n                            <p className=\"text-xs leading-relaxed text-muted-foreground\">\n                                {description}\n                            <\/p>\n                            {actionLabel && (\n                                <div className=\"pt-2\">\n                                    <button\n                                        onClick={onActionClick}\n                                        className=\"inline-flex h-7 cursor-pointer items-center justify-center rounded-md bg-primary px-3 text-[11px] font-semibold text-primary-foreground shadow-xs transition-colors hover:bg-primary\/95 active:scale-95\"\n                                    >\n                                        {actionLabel}\n                                    <\/button>\n                                <\/div>\n                            )}\n                        <\/div>\n                        <button\n                            onClick={handleDismiss}\n                            className=\"cursor-pointer rounded-lg p-1.5 text-muted-foreground\/70 transition-all hover:bg-muted hover:text-foreground\"\n                        >\n                            <X className=\"size-4\" \/>\n                        <\/button>\n                    <\/div>\n                <\/MotionCard>\n            )}\n        <\/AnimatePresence>\n    );\n}\n"}],"meta":{"category":"banners","version":"1.0.0"},"categories":["banners"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"banner-glow","type":"registry:ui","title":"Banner Glow","description":"A premium launch announcement bar styled with animated glowing neon gradient borders.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/banners\/banner-glow.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { X, Sparkles } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\n\ninterface BannerGlowProps extends React.HTMLAttributes<HTMLDivElement> {\n    message: string;\n    actionLabel?: string;\n    onActionClick?: () => void;\n    onClose?: () => void;\n}\n\nexport function BannerGlow({\n    message,\n    actionLabel,\n    onActionClick,\n    onClose,\n    className,\n    ...props\n}: BannerGlowProps) {\n    const [isVisible, setIsVisible] = React.useState(true);\n\n    if (!isVisible) return null;\n\n    return (\n        <div\n            className={cn(\n                'relative flex w-full items-center justify-between gap-4 overflow-hidden border-b border-border\/80 bg-card px-4 py-3 shadow-sm select-none',\n                className,\n            )}\n            {...props}\n        >\n            {\/* Animated background glow tracks *\/}\n            <div className=\"pointer-events-none absolute inset-0 bg-linear-to-r from-violet-500\/8 via-pink-500\/8 to-indigo-500\/8\" \/>\n\n            {\/* Bottom glowing line edge *\/}\n            <div className=\"pointer-events-none absolute right-0 bottom-0 left-0 h-[1.5px] animate-pulse bg-linear-to-r from-violet-500 via-pink-500 to-indigo-500\" \/>\n\n            <div className=\"relative z-10 flex flex-1 flex-wrap items-center justify-center gap-x-3 gap-y-1 text-xs\">\n                <span className=\"inline-flex items-center gap-1.5 text-center font-semibold text-foreground\">\n                    <Sparkles className=\"size-3.5 shrink-0 animate-pulse text-pink-500\" \/>\n                    {message}\n                <\/span>\n                {actionLabel && (\n                    <button\n                        onClick={onActionClick}\n                        className=\"inline-flex h-6 cursor-pointer items-center justify-center rounded-md border border-pink-500\/20 bg-linear-to-r from-violet-600 to-pink-600 px-3 text-[10px] font-bold text-white shadow-md transition-all hover:brightness-110 active:scale-95\"\n                    >\n                        {actionLabel}\n                    <\/button>\n                )}\n            <\/div>\n\n            <button\n                onClick={() => {\n                    setIsVisible(false);\n                    if (onClose) onClose();\n                }}\n                className=\"relative z-10 shrink-0 cursor-pointer rounded-lg p-1 text-muted-foreground\/70 transition-all hover:bg-muted hover:text-foreground\"\n            >\n                <X className=\"size-4\" \/>\n            <\/button>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"banners","version":"1.0.0"},"categories":["banners"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"banner-sliding","type":"registry:ui","title":"Banner Sliding","description":"A rotating carousel announcement bar sliding automatically through multiple marketing steps.","author":"designbycode","dependencies":["motion","lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/banners\/banner-sliding.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { motion, AnimatePresence } from 'motion\/react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\n\ninterface SlidingMessage {\n    id: string | number;\n    text: string;\n    actionLabel?: string;\n    onActionClick?: () => void;\n}\n\ninterface BannerSlidingProps extends React.HTMLAttributes<HTMLDivElement> {\n    messages: SlidingMessage[];\n    interval?: number; \/\/ ms, default 4000\n    transitionType?: 'slide-horizontal' | 'fade';\n}\n\nexport function BannerSliding({\n    messages,\n    interval = 4500,\n    transitionType = 'slide-horizontal',\n    className,\n    ...props\n}: BannerSlidingProps) {\n    const [index, setIndex] = React.useState(0);\n    const [isHovered, setIsHovered] = React.useState(false);\n\n    React.useEffect(() => {\n        if (isHovered || messages.length <= 1) return;\n        const timer = setInterval(() => {\n            setIndex((prev) => (prev + 1) % messages.length);\n        }, interval);\n        return () => clearInterval(timer);\n    }, [isHovered, messages.length, interval]);\n\n    if (messages.length === 0) return null;\n\n    const currentMessage = messages[index];\n\n    \/\/ Slide horizontal variables\n    const slideVariants = {\n        initial: {\n            opacity: 0,\n            x: transitionType === 'slide-horizontal' ? 30 : 0,\n        },\n        animate: { opacity: 1, x: 0 },\n        exit: {\n            opacity: 0,\n            x: transitionType === 'slide-horizontal' ? -30 : 0,\n        },\n    };\n\n    const handlePrev = () => {\n        setIndex((prev) => (prev === 0 ? messages.length - 1 : prev - 1));\n    };\n\n    const handleNext = () => {\n        setIndex((prev) => (prev + 1) % messages.length);\n    };\n\n    return (\n        <div\n            className={cn(\n                'group relative flex w-full items-center justify-between gap-4 border-b border-border bg-muted px-8 py-2.5 text-xs font-semibold text-foreground select-none',\n                className,\n            )}\n            onMouseEnter={() => setIsHovered(true)}\n            onMouseLeave={() => setIsHovered(false)}\n            {...props}\n        >\n            {\/* Nav Prev Button *\/}\n            {messages.length > 1 && (\n                <button\n                    onClick={handlePrev}\n                    className=\"absolute top-1\/2 left-2 z-10 flex size-6 -translate-y-1\/2 cursor-pointer items-center justify-center rounded-md border border-transparent p-1 text-muted-foreground\/60 opacity-0 transition-all group-hover:opacity-100 hover:border-border hover:bg-background hover:text-foreground\"\n                >\n                    <ChevronLeft className=\"size-3.5\" \/>\n                <\/button>\n            )}\n\n            {\/* Sliding Content *\/}\n            <div className=\"flex min-h-6 flex-1 items-center justify-center overflow-hidden\">\n                <AnimatePresence mode=\"wait\">\n                    <motion.div\n                        key={index}\n                        variants={slideVariants}\n                        initial=\"initial\"\n                        animate=\"animate\"\n                        exit=\"exit\"\n                        transition={{ duration: 0.3, ease: 'easeInOut' }}\n                        className=\"flex flex-wrap items-center justify-center gap-x-2 gap-y-0.5 px-4 text-center\"\n                    >\n                        <span>{currentMessage.text}<\/span>\n                        {currentMessage.actionLabel && (\n                            <button\n                                onClick={currentMessage.onActionClick}\n                                className=\"inline-flex cursor-pointer items-center gap-0.5 font-bold text-primary underline hover:text-primary\/95\"\n                            >\n                                {currentMessage.actionLabel}\n                            <\/button>\n                        )}\n                    <\/motion.div>\n                <\/AnimatePresence>\n            <\/div>\n\n            {\/* Nav Next Button *\/}\n            {messages.length > 1 && (\n                <button\n                    onClick={handleNext}\n                    className=\"absolute top-1\/2 right-2 z-10 flex size-6 -translate-y-1\/2 cursor-pointer items-center justify-center rounded-md border border-transparent p-1 text-muted-foreground\/60 opacity-0 transition-all group-hover:opacity-100 hover:border-border hover:bg-background hover:text-foreground\"\n                >\n                    <ChevronRight className=\"size-3.5\" \/>\n                <\/button>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"banners","version":"1.0.0"},"categories":["banners"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"banner-sticky","type":"registry:ui","title":"Banner Sticky","description":"A top-pinned sticky announcement bar featuring click action triggers and custom dismiss controls.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/banners\/banner-sticky.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { X, ArrowRight } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\n\ninterface BannerStickyProps extends React.HTMLAttributes<HTMLDivElement> {\n    message: string;\n    actionLabel?: string;\n    onActionClick?: () => void;\n    onClose?: () => void;\n    sticky?: boolean;\n}\n\nexport function BannerSticky({\n    message,\n    actionLabel,\n    onActionClick,\n    onClose,\n    sticky = true,\n    className,\n    ...props\n}: BannerStickyProps) {\n    const [isVisible, setIsVisible] = React.useState(true);\n\n    if (!isVisible) return null;\n\n    return (\n        <div\n            className={cn(\n                'flex w-full items-center justify-between gap-4 border-b border-border\/80 bg-linear-to-r from-primary\/10 via-primary\/5 to-background px-4 py-3 select-none',\n                sticky && 'sticky top-0 z-45',\n                className,\n            )}\n            {...props}\n        >\n            <div className=\"flex flex-1 flex-wrap items-center justify-center gap-x-3 gap-y-1 text-xs\">\n                <span className=\"text-center font-semibold text-foreground\">\n                    {message}\n                <\/span>\n                {actionLabel && (\n                    <button\n                        onClick={onActionClick}\n                        className=\"group inline-flex cursor-pointer items-center gap-1 text-xs font-bold text-primary transition-all hover:text-primary\/95 hover:underline\"\n                    >\n                        {actionLabel}\n                        <ArrowRight className=\"size-3.5 transition-transform group-hover:translate-x-0.5\" \/>\n                    <\/button>\n                )}\n            <\/div>\n\n            <button\n                onClick={() => {\n                    setIsVisible(false);\n                    if (onClose) onClose();\n                }}\n                className=\"shrink-0 cursor-pointer rounded-lg p-1 text-muted-foreground\/70 transition-all hover:bg-muted hover:text-foreground\"\n            >\n                <X className=\"size-4\" \/>\n            <\/button>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"banners","version":"1.0.0"},"categories":["banners"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"rainbow-border","type":"registry:ui","title":"Rainbow Border","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/borders\/rainbow-border.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport const colorMap: Record<string, string> = {\n    slate: '#64748b',\n    gray: '#6b7280',\n    zinc: '#71717a',\n    stone: '#78716c',\n    red: '#ef4444',\n    orange: '#f97316',\n    amber: '#f59e0b',\n    yellow: '#eab308',\n    lime: '#84cc16',\n    green: '#22c55e',\n    emerald: '#10b981',\n    teal: '#14b8a6',\n    cyan: '#06b6d4',\n    sky: '#0ea5e9',\n    blue: '#3b82f6',\n    indigo: '#6366f1',\n    violet: '#8b5cf6',\n    purple: '#a855f7',\n    fuchsia: '#d946ef',\n    pink: '#ec4899',\n    rose: '#f43f5e',\n};\n\nexport const roundedMap: Record<string, string> = {\n    none: 'rounded-none',\n    xs: 'rounded-xs',\n    sm: 'rounded-sm',\n    md: 'rounded-md',\n    lg: 'rounded-lg',\n    full: 'rounded-full',\n};\n\nexport interface RainbowBorderProps {\n    borderWidth?: string;\n    animationDuration?: string;\n    colors?: string[];\n    rounded?: keyof typeof roundedMap;\n    glow?: boolean;\n    glowBlur?: string;\n    glowOpacity?: number;\n    className?: string;\n    children: React.ReactNode;\n}\n\nfunction RainbowBorder({\n    borderWidth = '2px',\n    animationDuration = '3s',\n    colors,\n    rounded = 'md',\n    glow = true,\n    glowBlur = `30px`,\n    glowOpacity = 50,\n    className,\n    children,\n}: RainbowBorderProps) {\n    const defaultColors = [\n        'var(--rainbow-1)',\n        'var(--rainbow-2)',\n        'var(--rainbow-3)',\n        'var(--rainbow-4)',\n        'var(--rainbow-5)',\n        'var(--rainbow-6)',\n        'var(--rainbow-7)',\n    ];\n\n    const gradientColors = React.useMemo(() => {\n        const userColors = colors && colors.length > 0 ? colors : defaultColors;\n        const resolvedColors = userColors.map((color) => {\n            const lowerColor = color.toLowerCase();\n\n            if (color.startsWith('#')) {\n                return color;\n            }\n\n            return colorMap[lowerColor] || color;\n        });\n\n        return resolvedColors.join(', ');\n    }, [colors]);\n\n    const roundedClass = roundedMap[rounded] || 'rounded-md';\n\n    return (\n        <div className={cn(`group relative isolate inline-flex`, className)}>\n            {\/* Inject keyframes and variables if not globally defined *\/}\n            <style>{`\n                @keyframes rainbow-scroll {\n                    0% { background-position: 0% 50%; }\n                    100% { background-position: 200% 50%; }\n                }\n                :root {\n                    --rainbow-1: #ef4444;\n                    --rainbow-2: #f97316;\n                    --rainbow-3: #f59e0b;\n                    --rainbow-4: #10b981;\n                    --rainbow-5: #3b82f6;\n                    --rainbow-6: #6366f1;\n                    --rainbow-7: #a855f7;\n                }\n            `}<\/style>\n\n            <div\n                aria-hidden=\"true\"\n                className={cn(\n                    `pointer-events-none absolute inset-0 z-10 bg-repeat-x transition-opacity duration-300`,\n                    roundedClass,\n                )}\n                style={{\n                    background: `linear-gradient(90deg, ${gradientColors})`,\n                    backgroundSize: '200% 100%',\n                    animation: `rainbow-scroll ${animationDuration} linear infinite`,\n                    opacity: glow ? glowOpacity \/ 100 : 0,\n                    filter: `blur(${glowBlur})`,\n                }}\n            \/>\n            <div\n                aria-hidden=\"true\"\n                className={cn(\n                    'pointer-events-none absolute inset-0 z-20 bg-repeat-x blur-lg',\n                    roundedClass,\n                )}\n                style={{\n                    background: `repeating-linear-gradient(90deg, ${gradientColors})`,\n                    backgroundSize: '200% 100%',\n                    animation: `rainbow-scroll ${animationDuration} linear infinite`,\n                    padding: borderWidth,\n                    WebkitMask:\n                        'repeating-linear-gradient(#fff 0 0) content-box, repeating-linear-gradient(#fff 0 0)',\n                    WebkitMaskComposite: 'xor',\n                    maskComposite: 'exclude',\n                }}\n            \/>\n            {children}\n            <div\n                className=\"absolute inset-x-5 -bottom-1 block h-1 rounded-full blur-sm\"\n                style={{\n                    background: `repeating-linear-gradient(90deg, ${gradientColors})`,\n                    backgroundSize: '200% 100%',\n                    animation: `rainbow-scroll ${animationDuration} linear infinite`,\n                }}\n            \/>\n        <\/div>\n    );\n}\n\nRainbowBorder.displayName = 'RainbowBorder';\n\nexport { RainbowBorder };\nexport default RainbowBorder;\n"}],"meta":{"category":"borders","version":"1.0.0"},"categories":["borders"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"button-arrow","type":"registry:ui","title":"Button Arrow","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/button-arrow.tsx","type":"registry:ui","content":"'use client';\nimport * as React from 'react';\nimport { ArrowRight } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\nexport interface ButtonArrowProps extends React.ComponentPropsWithRef<\n    typeof Button\n> {}\n\nexport const ButtonArrow = React.forwardRef<\n    HTMLButtonElement,\n    ButtonArrowProps\n>(({ className, children, ...props }, ref) => {\n    return (\n        <Button\n            ref={ref}\n            className={cn(\n                'group relative overflow-hidden pr-10 transition-all duration-300 select-none active:scale-95',\n                className,\n            )}\n            {...props}\n        >\n            <span>{children}<\/span>\n            <span className=\"absolute right-4 flex items-center justify-center transition-transform duration-300 group-hover:translate-x-1 group-hover:scale-110\">\n                <ArrowRight className=\"size-4 shrink-0\" \/>\n            <\/span>\n        <\/Button>\n    );\n});\n\nButtonArrow.displayName = 'ButtonArrow';\n\nexport default ButtonArrow;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"button-draw","type":"registry:ui","title":"Button Draw","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/button-draw.tsx","type":"registry:ui","content":"'use client';\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\nexport interface ButtonDrawProps extends React.ComponentPropsWithRef<\n    typeof Button\n> {}\n\nexport const ButtonDraw = React.forwardRef<HTMLButtonElement, ButtonDrawProps>(\n    ({ className, children, ...props }, ref) => {\n        return (\n            <Button\n                ref={ref}\n                className={cn(\n                    'relative overflow-hidden border border-border bg-transparent text-foreground select-none after:absolute after:bottom-0 after:left-0 after:h-[2px] after:w-full after:origin-left after:scale-x-0 after:bg-primary after:transition-transform after:duration-300 hover:bg-muted\/30 hover:after:scale-x-100 active:scale-95',\n                    className,\n                )}\n                {...props}\n            >\n                {children}\n            <\/Button>\n        );\n    },\n);\n\nButtonDraw.displayName = 'ButtonDraw';\n\nexport default ButtonDraw;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"button-glowing-aura","type":"registry:ui","title":"Button Glowing Aura","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/button-glowing-aura.tsx","type":"registry:ui","content":"'use client';\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\nexport interface ButtonGlowingAuraProps extends React.ComponentPropsWithRef<\n    typeof Button\n> {\n    auraColor?: string;\n}\n\nexport const ButtonGlowingAura = React.forwardRef<\n    HTMLButtonElement,\n    ButtonGlowingAuraProps\n>(\n    (\n        { className, children, auraColor = 'var(--color-primary)', ...props },\n        ref,\n    ) => {\n        return (\n            <div className=\"group relative inline-block\">\n                {\/* Glowing backlight aura *\/}\n                <div\n                    className=\"absolute -inset-1 -z-10 rounded-lg opacity-40 blur-md transition duration-500 group-hover:opacity-75 group-hover:blur-lg\"\n                    style={{\n                        background: `radial-gradient(circle, ${auraColor} 0%, transparent 70%)`,\n                    }}\n                \/>\n                <Button\n                    ref={ref}\n                    className={cn(\n                        'relative border border-primary\/20 shadow-lg select-none active:scale-95',\n                        className,\n                    )}\n                    {...props}\n                >\n                    {children}\n                <\/Button>\n            <\/div>\n        );\n    },\n);\n\nButtonGlowingAura.displayName = 'ButtonGlowingAura';\n\nexport default ButtonGlowingAura;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"button-gradient","type":"registry:ui","title":"Button Gradient","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","button","https:\/\/ui.test\/r\/use-hover.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/button-gradient.tsx","type":"registry:ui","content":"'use client';\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\nimport { useHover } from '@\/registry\/new-york\/hooks\/use-hover';\n\nexport interface ButtonGradientProps extends React.ComponentPropsWithRef<\n    typeof Button\n> {}\n\nexport const ButtonGradient = React.forwardRef<\n    HTMLButtonElement,\n    ButtonGradientProps\n>(({ className, children, ...props }, ref) => {\n    const { isHovered, hoverRef } = useHover();\n\n    const combinedRef = React.useCallback(\n        (node: HTMLButtonElement | null) => {\n            hoverRef(node);\n            if (typeof ref === 'function') {\n                ref(node);\n            } else if (ref) {\n                (\n                    ref as React.MutableRefObject<HTMLButtonElement | null>\n                ).current = node;\n            }\n        },\n        [ref, hoverRef],\n    );\n\n    return (\n        <Button\n            ref={combinedRef}\n            className={cn(\n                'relative border border-transparent text-foreground select-none active:scale-95',\n                className,\n            )}\n            style={{\n                backgroundImage: isHovered\n                    ? 'linear-gradient(var(--background), var(--background)), linear-gradient(to right, var(--color-chart-3), var(--color-chart-1), var(--color-chart-5))'\n                    : 'linear-gradient(var(--background), var(--background)), linear-gradient(to right, var(--color-chart-1), var(--color-chart-5), var(--color-chart-3))',\n                backgroundOrigin: 'border-box',\n                backgroundClip: 'padding-box, border-box',\n            }}\n            {...props}\n        >\n            {children}\n        <\/Button>\n    );\n});\n\nButtonGradient.displayName = 'ButtonGradient';\n\nexport default ButtonGradient;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"button-magnetic","type":"registry:ui","title":"Button Magnetic","description":"A premium magnetic button pull effect that snaps to the cursor position on hover.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/button-magnetic.tsx","type":"registry:ui","content":"import React, { useRef, useState, useEffect } from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\nexport interface ButtonMagneticProps extends React.ComponentProps<\n    typeof Button\n> {\n    range?: number; \/\/ Distance from center where magnetism activates\n    actionStrength?: number; \/\/ How strongly the button pulls toward the mouse (0.1 to 1.0)\n}\n\nexport function ButtonMagnetic({\n    range = 60,\n    actionStrength = 0.35,\n    children,\n    className,\n    style,\n    ...props\n}: ButtonMagneticProps) {\n    const triggerRef = useRef<HTMLDivElement>(null);\n    const [position, setPosition] = useState({ x: 0, y: 0 });\n    const [isHovered, setIsHovered] = useState(false);\n\n    useEffect(() => {\n        const trigger = triggerRef.current;\n        if (!trigger) {\n            return;\n        }\n\n        const handleMouseMove = (e: MouseEvent) => {\n            const rect = trigger.getBoundingClientRect();\n\n            \/\/ Calculate absolute center of the trigger area (which is completely static)\n            const centerX = rect.left + rect.width \/ 2;\n            const centerY = rect.top + rect.height \/ 2;\n\n            \/\/ Distance from mouse to center\n            const deltaX = e.clientX - centerX;\n            const deltaY = e.clientY - centerY;\n            const distance = Math.hypot(deltaX, deltaY);\n\n            \/\/ Determine active range based on dimensions or specified range\n            const activeRange = Math.max(\n                range,\n                Math.max(rect.width, rect.height) \/ 1.5,\n            );\n\n            if (distance < activeRange) {\n                setIsHovered(true);\n                \/\/ Pull toward mouse\n                setPosition({\n                    x: deltaX * actionStrength,\n                    y: deltaY * actionStrength,\n                });\n            } else {\n                setIsHovered(false);\n                setPosition({ x: 0, y: 0 });\n            }\n        };\n\n        const handleMouseLeave = () => {\n            setIsHovered(false);\n            setPosition({ x: 0, y: 0 });\n        };\n\n        window.addEventListener('mousemove', handleMouseMove, {\n            passive: true,\n        });\n        trigger.addEventListener('mouseleave', handleMouseLeave);\n\n        return () => {\n            window.removeEventListener('mousemove', handleMouseMove);\n            trigger.removeEventListener('mouseleave', handleMouseLeave);\n        };\n    }, [range, actionStrength]);\n\n    return (\n        <div ref={triggerRef} className=\"inline-block\">\n            <Button\n                className={cn('select-none active:scale-95', className)}\n                style={{\n                    transform: `translate3d(${position.x}px, ${position.y}px, 0)`,\n                    \/\/ Use a smooth, fast bezier transition when tracking to eliminate jumps, and a springy transition on snap-back\n                    transition: isHovered\n                        ? 'transform 0.2s cubic-bezier(0.25, 1, 0.5, 1)'\n                        : 'transform 0.45s cubic-bezier(0.175, 0.885, 0.32, 1.275)',\n                    willChange: 'transform',\n                    ...style,\n                }}\n                {...props}\n            >\n                <span className=\"pointer-events-none relative z-10 transition-transform duration-200 group-hover:scale-105\">\n                    {children}\n                <\/span>\n            <\/Button>\n        <\/div>\n    );\n}\n\nexport default ButtonMagnetic;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"button-neon","type":"registry:ui","title":"Button Neon","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/button-neon.tsx","type":"registry:ui","content":"'use client';\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\nexport interface ButtonNeonProps extends React.ComponentPropsWithRef<\n    typeof Button\n> {}\n\nexport const ButtonNeon = React.forwardRef<HTMLButtonElement, ButtonNeonProps>(\n    ({ className, children, ...props }, ref) => {\n        return (\n            <Button\n                ref={ref}\n                className={cn(\n                    'relative border border-primary\/50 bg-primary\/15 text-primary shadow-[0_0_15px] shadow-primary\/10 select-none hover:border-primary\/50 hover:bg-primary\/10 hover:text-primary hover:shadow-[0_0_20px] hover:shadow-primary\/20 active:scale-95',\n                    className,\n                )}\n                {...props}\n            >\n                {children}\n            <\/Button>\n        );\n    },\n);\n\nButtonNeon.displayName = 'ButtonNeon';\n\nexport default ButtonNeon;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"button-particles","type":"registry:ui","title":"Button Particles","description":"A vibrant button trigger releasing interactive confetti\/particle explosions on click.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/button-particles.tsx","type":"registry:ui","content":"'use client';\nimport * as React from 'react';\nimport { useEffect, useRef } from 'react';\nimport { Button, buttonVariants } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\n\/\/ --- Particle style injection ---\n\/\/ One unique keyframe per particle slot so each gets its own randomised\n\/\/ endpoint baked in at style-injection time. CSS custom properties\n\/\/ (--pdx, --pdy, --pdur) are set on the element at click time.\n\nconst DEFAULT_PARTICLE_COUNT = 20;\nconst PARTICLE_STYLE_ID = 'button-particle-styles-v2';\n\nfunction injectParticleStyles(maxIndex: number) {\n    if (typeof document === 'undefined') {\n        return;\n    }\n\n    let style = document.getElementById(PARTICLE_STYLE_ID);\n    let existingCss = '';\n    let existingMax = 0;\n\n    if (style) {\n        existingCss = style.textContent || '';\n        existingMax = parseInt(style.dataset.maxIndex || '0', 10);\n\n        if (existingMax >= maxIndex) {\n            return;\n        }\n    } else {\n        style = document.createElement('style');\n        style.id = PARTICLE_STYLE_ID;\n    }\n\n    style.dataset.maxIndex = String(maxIndex);\n\n    let css = existingCss;\n\n    if (!css) {\n        css = `\n        .bp-particle {\n            position: absolute;\n            border-radius: 50%;\n            pointer-events: none;\n            z-index: 99999;\n            will-change: transform, opacity;\n        }\n    `;\n    }\n\n    for (let i = existingMax + 1; i <= maxIndex; i++) {\n        css += `\n            @keyframes particle-burst-${i} {\n                0%   { transform: translate(-50%, -50%) translate(0px, 0px) scale(1); opacity: 1; }\n                60%  { opacity: 0.9; }\n                100% { transform: translate(-50%, -50%) translate(var(--pdx), var(--pdy)) scale(0); opacity: 0; }\n            }\n            .bp-particle[data-particle=\"burst\"][data-idx=\"${i}\"] {\n                animation: particle-burst-${i} var(--pdur) cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;\n            }\n\n            @keyframes sparkle-burst-${i} {\n                0%   { transform: translate(-50%, -50%) translate(0px, 0px) rotate(0deg) scale(1); opacity: 1; }\n                60%  { opacity: 0.9; }\n                100% { transform: translate(-50%, -50%) translate(var(--pdx), var(--pdy)) rotate(180deg) scale(0.3); opacity: 0; }\n            }\n            .bp-particle[data-particle=\"sparkle\"][data-idx=\"${i}\"] {\n                animation: sparkle-burst-${i} var(--pdur) cubic-bezier(0.2, 0.8, 0.2, 1) forwards;\n            }\n\n            @keyframes confetti-spray-${i} {\n                0%   { transform: translate(-50%, -50%) translate(0px, 0px) rotate(0deg) scale(1); opacity: 1; }\n                60%  { opacity: 0.9; }\n                100% { transform: translate(-50%, -50%) translate(var(--pdx), var(--pdy)) rotate(360deg) scale(0.5); opacity: 0; }\n            }\n            .bp-particle[data-particle=\"confetti\"][data-idx=\"${i}\"] {\n                animation: confetti-spray-${i} var(--pdur) cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;\n            }\n\n            @keyframes vburst-${i} {\n                0%   { transform: translate(-50%, -50%) translate(0px, 0px) scale(1); opacity: 1; }\n                60%  { opacity: 0.9; }\n                100% { transform: translate(-50%, -50%) translate(var(--pdx), var(--pdy)) scale(0); opacity: 0; }\n            }\n            .bp-particle[data-particle=\"vburst\"][data-idx=\"${i}\"] {\n                animation: vburst-${i} var(--pdur) cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;\n            }\n\n            @keyframes hburst-${i} {\n                0%   { transform: translate(-50%, -50%) translate(0px, 0px) scale(1); opacity: 1; }\n                60%  { opacity: 0.9; }\n                100% { transform: translate(-50%, -50%) translate(var(--pdx), var(--pdy)) scale(0); opacity: 0; }\n            }\n            .bp-particle[data-particle=\"hburst\"][data-idx=\"${i}\"] {\n                animation: hburst-${i} var(--pdur) cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;\n            }\n\n            @keyframes spiral-burst-${i} {\n                0%   { transform: translate(-50%, -50%) translate(0px, 0px) rotate(0deg) scale(1); opacity: 1; }\n                60%  { opacity: 0.9; }\n                100% { transform: translate(-50%, -50%) translate(var(--pdx), var(--pdy)) rotate(720deg) scale(0); opacity: 0; }\n            }\n            .bp-particle[data-particle=\"spiral\"][data-idx=\"${i}\"] {\n                animation: spiral-burst-${i} var(--pdur) cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;\n            }\n        `;\n    }\n\n    style.textContent = css;\n    document.head.appendChild(style);\n}\n\ninjectParticleStyles(DEFAULT_PARTICLE_COUNT);\n\n\/\/ --- Colour palette ---\nconst DEFAULT_COLORS = [\n    '#ff0083', \/\/ hot pink\n    '#ff6b6b', \/\/ coral red\n    '#ffd93d', \/\/ golden yellow\n    '#6bcb77', \/\/ mint green\n    '#4d96ff', \/\/ vivid blue\n    '#c77dff', \/\/ violet\n    '#ff9f1c', \/\/ amber orange\n    '#00f5d4', \/\/ cyan\n];\n\nexport type ParticleType =\n    'burst' | 'sparkle' | 'confetti' | 'vburst' | 'hburst' | 'spiral';\n\ninterface ButtonParticlesProps extends React.ComponentProps<typeof Button> {\n    particle?: ParticleType;\n    particles?: number;\n    colors?: string[];\n}\n\nfunction ButtonParticles({\n    className,\n    particle = 'burst',\n    particles = DEFAULT_PARTICLE_COUNT,\n    colors = DEFAULT_COLORS,\n    children,\n    ...props\n}: ButtonParticlesProps) {\n    const ref = useRef<HTMLButtonElement>(null);\n\n    useEffect(() => {\n        injectParticleStyles(particles);\n    }, [particles]);\n\n    const createParticle = (\n        buttonEl: HTMLElement,\n        originX: number,\n        originY: number,\n        index: number,\n    ) => {\n        if (!buttonEl) {\n            return;\n        }\n\n        const el = document.createElement('div');\n        el.classList.add('bp-particle');\n        el.dataset.idx = String(index);\n        el.dataset.particle = particle;\n\n        const color = colors[Math.floor(Math.random() * colors.length)];\n        \/\/ Odd index \u2192 stroke only (mirrors the SCSS nth-of-type(odd) rule)\n        const isStroke = index % 2 === 1;\n\n        switch (particle) {\n            case 'burst': {\n                const angle = Math.random() * 2 * Math.PI;\n                const dist = 70 + Math.random() * 90;\n                const sz = 14 + Math.random() * 14;\n                el.style.width = `${sz}px`;\n                el.style.height = `${sz}px`;\n\n                if (isStroke) {\n                    el.style.backgroundColor = 'transparent';\n                    el.style.border = `3px solid ${color}`;\n                } else {\n                    el.style.backgroundColor = color;\n                    el.style.border = 'none';\n                }\n\n                const dur = 550 + Math.random() * 400;\n                el.style.setProperty('--pdx', `${Math.cos(angle) * dist}px`);\n                el.style.setProperty('--pdy', `${Math.sin(angle) * dist}px`);\n                el.style.setProperty('--pdur', `${dur}ms`);\n                el.style.left = `${originX - sz \/ 2}px`;\n                el.style.top = `${originY - sz \/ 2}px`;\n                buttonEl.appendChild(el);\n                setTimeout(() => el.remove(), dur + 50);\n                break;\n            }\n            case 'sparkle': {\n                const dx = (Math.random() - 0.5) * 80;\n                const dy = -(60 + Math.random() * 100);\n                const sz = 8 + Math.random() * 12;\n                el.style.width = `${sz}px`;\n                el.style.height = `${sz}px`;\n\n                if (isStroke) {\n                    el.style.backgroundColor = 'transparent';\n                    el.style.border = `2px solid ${color}`;\n                } else {\n                    el.style.backgroundColor = color;\n                    el.style.border = 'none';\n                }\n\n                const dur = 600 + Math.random() * 400;\n                el.style.setProperty('--pdx', `${dx}px`);\n                el.style.setProperty('--pdy', `${dy}px`);\n                el.style.setProperty('--pdur', `${dur}ms`);\n                el.style.left = `${originX - sz \/ 2}px`;\n                el.style.top = `${originY - sz \/ 2}px`;\n                buttonEl.appendChild(el);\n                setTimeout(() => el.remove(), dur + 50);\n                break;\n            }\n            case 'confetti': {\n                const spreadAngle = (Math.random() - 0.5) * Math.PI * 0.8;\n                const angle = -Math.PI \/ 2 + spreadAngle;\n                const dist = 80 + Math.random() * 120;\n                const dx = Math.cos(angle) * dist;\n                const dy = Math.sin(angle) * dist - 40;\n                const sz = 10 + Math.random() * 8;\n                el.style.width = `${sz}px`;\n                el.style.height = `${sz * 0.5}px`;\n                el.style.borderRadius = '2px';\n                el.style.backgroundColor = color;\n                el.style.border = 'none';\n                const dur = 700 + Math.random() * 400;\n                el.style.setProperty('--pdx', `${dx}px`);\n                el.style.setProperty('--pdy', `${dy}px`);\n                el.style.setProperty('--pdur', `${dur}ms`);\n                el.style.left = `${originX - sz \/ 2}px`;\n                el.style.top = `${originY - sz \/ 4}px`;\n                buttonEl.appendChild(el);\n                setTimeout(() => el.remove(), dur + 50);\n                break;\n            }\n            case 'vburst': {\n                const isUp = index % 2 === 0;\n                const dist = 80 + Math.random() * 100;\n                const sz = 12 + Math.random() * 12;\n                el.style.width = `${sz}px`;\n                el.style.height = `${sz}px`;\n                el.style.backgroundColor = color;\n                el.style.border = 'none';\n                const dur = 550 + Math.random() * 400;\n                el.style.setProperty(\n                    '--pdx',\n                    `${(Math.random() - 0.5) * 20}px`,\n                );\n                el.style.setProperty('--pdy', `${isUp ? -dist : dist}px`);\n                el.style.setProperty('--pdur', `${dur}ms`);\n                el.style.left = `${originX - sz \/ 2}px`;\n                el.style.top = `${originY - sz \/ 2}px`;\n                buttonEl.appendChild(el);\n                setTimeout(() => el.remove(), dur + 50);\n                break;\n            }\n            case 'hburst': {\n                const isRight = index % 2 === 0;\n                const dist = 80 + Math.random() * 100;\n                const sz = 12 + Math.random() * 12;\n                el.style.width = `${sz}px`;\n                el.style.height = `${sz}px`;\n                el.style.backgroundColor = color;\n                el.style.border = 'none';\n                const dur = 550 + Math.random() * 400;\n                el.style.setProperty('--pdx', `${isRight ? dist : -dist}px`);\n                el.style.setProperty(\n                    '--pdy',\n                    `${(Math.random() - 0.5) * 40}px`,\n                );\n                el.style.setProperty('--pdur', `${dur}ms`);\n                el.style.left = `${originX - sz \/ 2}px`;\n                el.style.top = `${originY - sz \/ 2}px`;\n                buttonEl.appendChild(el);\n                setTimeout(() => el.remove(), dur + 50);\n                break;\n            }\n            case 'spiral': {\n                const baseAngle = Math.random() * 2 * Math.PI;\n                const dist = 60 + Math.random() * 100;\n                const sz = 8 + Math.random() * 8;\n                el.style.width = `${sz}px`;\n                el.style.height = `${sz}px`;\n                el.style.backgroundColor = color;\n                el.style.border = 'none';\n                const dur = 600 + Math.random() * 400;\n                el.style.setProperty(\n                    '--pdx',\n                    `${Math.cos(baseAngle) * dist}px`,\n                );\n                el.style.setProperty(\n                    '--pdy',\n                    `${Math.sin(baseAngle) * dist}px`,\n                );\n                el.style.setProperty('--pdur', `${dur}ms`);\n                el.style.left = `${originX - sz \/ 2}px`;\n                el.style.top = `${originY - sz \/ 2}px`;\n                buttonEl.appendChild(el);\n                setTimeout(() => el.remove(), dur + 50);\n                break;\n            }\n        }\n    };\n\n    const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n        if (!ref.current) {\n            return;\n        }\n\n        props.onClick?.(e);\n\n        if (e.defaultPrevented) {\n            return;\n        }\n\n        const cx = ref.current.offsetWidth \/ 2;\n        const cy = ref.current.offsetHeight \/ 2;\n        const buttonEl = ref.current;\n\n        for (let i = 1; i <= particles; i++) {\n            setTimeout(() => createParticle(buttonEl, cx, cy, i), i * 12);\n        }\n    };\n\n    return (\n        <Button\n            ref={ref}\n            data-particle={particle}\n            className={cn('relative isolate overflow-visible', className)}\n            {...props}\n            onClick={handleClick}\n        >\n            {children}\n        <\/Button>\n    );\n}\n\nexport { ButtonParticles, buttonVariants };\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"button-pulse","type":"registry:ui","title":"Button Pulse","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/button-pulse.tsx","type":"registry:ui","content":"'use client';\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\nexport interface ButtonPulseProps extends React.ComponentPropsWithRef<\n    typeof Button\n> {}\n\nexport const ButtonPulse = React.forwardRef<\n    HTMLButtonElement,\n    ButtonPulseProps\n>(({ className, children, ...props }, ref) => {\n    return (\n        <Button\n            ref={ref}\n            className={cn(\n                'relative bg-primary text-primary-foreground shadow-lg shadow-primary\/20 select-none before:absolute before:inset-0 before:animate-ping before:rounded-md before:bg-primary before:opacity-10 before:duration-1000 hover:shadow-primary\/30 hover:brightness-105 active:scale-95',\n                className,\n            )}\n            {...props}\n        >\n            {children}\n        <\/Button>\n    );\n});\n\nButtonPulse.displayName = 'ButtonPulse';\n\nexport default ButtonPulse;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"button-ripple","type":"registry:ui","title":"Button Ripple","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/button-ripple.tsx","type":"registry:ui","content":"'use client';\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\nexport interface ButtonRippleProps extends React.ComponentPropsWithRef<\n    typeof Button\n> {}\n\nconst RIPPLE_STYLE_ID = 'button-ripple-styles';\nfunction injectRippleStyles() {\n    if (\n        typeof document === 'undefined' ||\n        document.getElementById(RIPPLE_STYLE_ID)\n    ) {\n        return;\n    }\n    const style = document.createElement('style');\n    style.id = RIPPLE_STYLE_ID;\n    style.textContent = `\n        @keyframes bp-ripple-effect {\n            0% { transform: translate(-50%, -50%) scale(0); opacity: 0.5; }\n            100% { transform: translate(-50%, -50%) scale(40); opacity: 0; }\n        }\n        .bp-ripple {\n            position: absolute;\n            border-radius: 50%;\n            pointer-events: none;\n            background-color: currentColor;\n            opacity: 0.25;\n            width: 8px;\n            height: 8px;\n            animation: bp-ripple-effect 0.6s cubic-bezier(0.1, 0.8, 0.3, 1) forwards;\n        }\n    `;\n    document.head.appendChild(style);\n}\n\nexport const ButtonRipple = React.forwardRef<\n    HTMLButtonElement,\n    ButtonRippleProps\n>(({ className, children, onClick, ...props }, ref) => {\n    const [ripples, setRipples] = React.useState<\n        Array<{ id: number; x: number; y: number }>\n    >([]);\n    const nextId = React.useRef(0);\n\n    React.useEffect(() => {\n        injectRippleStyles();\n    }, []);\n\n    const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n        const button = e.currentTarget;\n        const rect = button.getBoundingClientRect();\n        const x = e.clientX - rect.left;\n        const y = e.clientY - rect.top;\n\n        const id = nextId.current++;\n        setRipples((prev) => [...prev, { id, x, y }]);\n\n        onClick?.(e);\n    };\n\n    React.useEffect(() => {\n        if (ripples.length > 0) {\n            const timer = setTimeout(() => {\n                setRipples([]);\n            }, 600);\n            return () => clearTimeout(timer);\n        }\n    }, [ripples]);\n\n    return (\n        <Button\n            ref={ref}\n            onClick={handleClick}\n            className={cn(\n                'relative isolate overflow-hidden select-none active:scale-95',\n                className,\n            )}\n            {...props}\n        >\n            <span className=\"relative z-10\">{children}<\/span>\n            {ripples.map((ripple) => (\n                <span\n                    key={ripple.id}\n                    className=\"bp-ripple\"\n                    style={{\n                        left: ripple.x,\n                        top: ripple.y,\n                    }}\n                \/>\n            ))}\n        <\/Button>\n    );\n});\n\nButtonRipple.displayName = 'ButtonRipple';\n\nexport default ButtonRipple;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"button-shine","type":"registry:ui","title":"Button Shine","description":"A sleek button design showcasing a subtle glowing reflective shine transition.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/button-shine.tsx","type":"registry:ui","content":"import React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\nexport interface ButtonShineProps extends React.ComponentProps<typeof Button> {\n    shineColor?: string;\n}\n\nexport function ButtonShine({\n    children,\n    shineColor = 'rgba(255, 255, 255, 0.3)',\n    className,\n    style,\n    ...props\n}: ButtonShineProps) {\n    return (\n        <Button\n            className={cn(\n                'group relative overflow-hidden select-none active:scale-95',\n                className,\n            )}\n            style={style}\n            {...props}\n        >\n            {\/* Shimmer glossy shine gradient wrapper *\/}\n            <span\n                className=\"pointer-events-none absolute inset-0 block h-full w-[200%] -translate-x-full bg-gradient-to-r from-transparent via-white\/20 to-transparent group-hover:animate-shine\"\n                style={{\n                    backgroundImage: `linear-gradient(to right, transparent, ${shineColor} 50%, transparent)`,\n                    animationDuration: '1s',\n                }}\n            \/>\n            <span className=\"relative z-10\">{children}<\/span>\n        <\/Button>\n    );\n}\n\nexport default ButtonShine;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"rainbow-border-button","type":"registry:ui","title":"Rainbow Border Button","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","button","https:\/\/ui.test\/r\/rainbow-border.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/rainbow-border-button.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { RainbowBorder } from '@\/registry\/new-york\/components\/ui\/borders\/rainbow-border';\n\nexport interface RainbowBorderButtonProps extends React.ComponentProps<\n    typeof Button\n> {\n    borderWidth?: string;\n    animationDuration?: string;\n    colors?: string[];\n    rounded?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'full';\n    glow?: boolean;\n    glowBlur?: string;\n    glowOpacity?: number;\n}\n\nexport const RainbowBorderButton = React.forwardRef<\n    HTMLButtonElement,\n    RainbowBorderButtonProps\n>(\n    (\n        {\n            className,\n            borderWidth = '2px',\n            animationDuration = '3s',\n            colors,\n            rounded = 'md',\n            glow = true,\n            glowBlur = '30px',\n            glowOpacity = 50,\n            children,\n            ...props\n        },\n        ref,\n    ) => {\n        const roundedButtonClass =\n            rounded === 'none'\n                ? 'rounded-none'\n                : rounded === 'xs'\n                  ? 'rounded-xs'\n                  : rounded === 'sm'\n                    ? 'rounded-sm'\n                    : rounded === 'md'\n                      ? 'rounded-md'\n                      : rounded === 'lg'\n                        ? 'rounded-lg'\n                        : 'rounded-full';\n\n        return (\n            <RainbowBorder\n                borderWidth={borderWidth}\n                animationDuration={animationDuration}\n                colors={colors}\n                rounded={rounded}\n                glow={glow}\n                glowBlur={glowBlur}\n                glowOpacity={glowOpacity}\n                className=\"p-[1px]\"\n            >\n                <Button\n                    ref={ref}\n                    className={cn(\n                        'h-9 border-0 bg-background px-4 text-xs font-semibold text-foreground transition-all select-none hover:bg-background\/95 active:scale-95',\n                        roundedButtonClass,\n                        className,\n                    )}\n                    {...props}\n                >\n                    {children}\n                <\/Button>\n            <\/RainbowBorder>\n        );\n    },\n);\n\nRainbowBorderButton.displayName = 'RainbowBorderButton';\n\nexport default RainbowBorderButton;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"rainbow-button","type":"registry:ui","title":"Rainbow Button","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/buttons\/rainbow-button.tsx","type":"registry:ui","content":"'use client';\nimport React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\ntype GradientDirection =\n    | 'right'\n    | 'left'\n    | 'top'\n    | 'bottom'\n    | 'top-left'\n    | 'top-right'\n    | 'bottom-left'\n    | 'bottom-right';\n\ninterface GradientButtonProps extends React.ComponentProps<typeof Button> {\n    colors?: string[];\n    direction?: GradientDirection;\n}\n\nconst directionMap: Record<GradientDirection, string> = {\n    right: 'to right',\n    left: 'to left',\n    top: 'to top',\n    bottom: 'to bottom',\n    'top-left': 'to top left',\n    'top-right': 'to top right',\n    'bottom-left': 'to bottom left',\n    'bottom-right': 'to bottom right',\n};\n\nconst GradientButton = ({\n    className,\n    colors,\n    direction = 'right',\n    ...props\n}: GradientButtonProps) => {\n    const gradientColors = colors ?? [\n        'var(--color-primary)',\n        'var(--color-secondary)',\n    ];\n    const gradient = `linear-gradient(${directionMap[direction]}, ${gradientColors.join(', ')})`;\n\n    return (\n        <Button\n            className={cn(\n                'border-0 text-primary-foreground transition-all duration-300 hover:scale-105 dark:text-foreground',\n                className,\n            )}\n            style={{\n                background: gradient,\n            }}\n            {...props}\n        \/>\n    );\n};\n\nexport { GradientButton };\nexport default GradientButton;\n"}],"meta":{"category":"buttons","version":"1.0.0"},"categories":["buttons"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"aurora-canvas","type":"registry:ui","title":"Aurora Canvas","description":"A slow-waving glow animation displaying layered shifting bezier bands resembling the northern lights.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/canvas\/aurora-canvas.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface AuroraCanvasProps extends React.HTMLAttributes<HTMLDivElement> {\n    \/** Number of colored auroral bands to render *\/\n    bandCount?: number;\n    \/** Shifting speed of the waves *\/\n    speed?: number;\n    \/** Vertical wave amplitude *\/\n    amplitude?: number;\n    \/** Color bands palette array *\/\n    colors?: string[];\n    \/** Canvas global composite blend operation (e.g. 'screen', 'lighter', 'source-over') *\/\n    blendMode?: GlobalCompositeOperation;\n    \/** Enable gentle mouse interaction to attract the aurora bands *\/\n    interactive?: boolean;\n}\n\nexport const AuroraCanvas = React.forwardRef<HTMLDivElement, AuroraCanvasProps>(\n    (\n        {\n            className,\n            bandCount = 4,\n            speed = 0.6,\n            amplitude = 50,\n            colors = ['#10b981', '#06b6d4', '#3b82f6', '#8b5cf6'],\n            blendMode = 'screen',\n            interactive = true,\n            ...props\n        },\n        ref,\n    ) => {\n        const containerRef = React.useRef<HTMLDivElement>(null);\n        const canvasRef = React.useRef<HTMLCanvasElement>(null);\n        const mouseRef = React.useRef<{ x: number; y: number } | null>(null);\n\n        React.useImperativeHandle(\n            ref,\n            () => containerRef.current as HTMLDivElement,\n        );\n\n        React.useEffect(() => {\n            const canvas = canvasRef.current;\n            const container = containerRef.current;\n            if (!canvas || !container) {\n                return;\n            }\n\n            const ctx = canvas.getContext('2d');\n            if (!ctx) {\n                return;\n            }\n\n            let animationId: number;\n            let width = (canvas.width = container.offsetWidth);\n            let height = (canvas.height = container.offsetHeight);\n            let time = 0;\n\n            const resizeObserver = new ResizeObserver((entries) => {\n                for (const entry of entries) {\n                    width = canvas.width = entry.contentRect.width;\n                    height = canvas.height = entry.contentRect.height;\n                }\n            });\n            resizeObserver.observe(container);\n\n            const handleMouseMove = (e: MouseEvent) => {\n                if (!interactive) return;\n                const rect = canvas.getBoundingClientRect();\n                mouseRef.current = {\n                    x: e.clientX - rect.left,\n                    y: e.clientY - rect.top,\n                };\n            };\n\n            const handleMouseLeave = () => {\n                mouseRef.current = null;\n            };\n\n            if (interactive) {\n                container.addEventListener('mousemove', handleMouseMove);\n                container.addEventListener('mouseleave', handleMouseLeave);\n            }\n\n            const resolveColor = (colorStr: string, defaultVal: string) => {\n                if (!colorStr) return defaultVal;\n                let targetColor = colorStr;\n                if (colorStr.startsWith('--')) {\n                    targetColor = `var(${colorStr})`;\n                }\n                if (\n                    !targetColor.includes('var(') &&\n                    !targetColor.includes('--')\n                ) {\n                    return targetColor;\n                }\n                try {\n                    const temp = document.createElement('div');\n                    temp.style.color = targetColor;\n                    container.appendChild(temp);\n                    const resolved = window.getComputedStyle(temp).color;\n                    container.removeChild(temp);\n                    return resolved || defaultVal;\n                } catch (e) {\n                    return defaultVal;\n                }\n            };\n\n            \/\/ Draw loop\n            const draw = () => {\n                \/\/ Clear canvas with black\/transparent depending on theme\n                ctx.clearRect(0, 0, width, height);\n\n                ctx.save();\n                ctx.globalCompositeOperation = blendMode;\n\n                time += speed * 0.003;\n\n                \/\/ Render each auroral wave band\n                for (let i = 0; i < bandCount; i++) {\n                    const colorIndex = i % colors.length;\n                    const baseColor = colors[colorIndex];\n                    const activeBaseColor = resolveColor(baseColor, '#10b981');\n                    const offset = i * (Math.PI \/ bandCount);\n\n                    \/\/ Dynamic wave points\n                    const y1 =\n                        height * 0.5 + Math.sin(time + offset) * amplitude;\n                    const y2 =\n                        height * 0.5 +\n                        Math.cos(time + offset * 1.5) * amplitude;\n\n                    \/\/ Mouse influence\n                    let mouseInfluenceX = 0;\n                    let mouseInfluenceY = 0;\n                    if (mouseRef.current) {\n                        mouseInfluenceX =\n                            (mouseRef.current.x - width * 0.5) * 0.05;\n                        mouseInfluenceY =\n                            (mouseRef.current.y - height * 0.5) * 0.15;\n                    }\n\n                    const cp1x = width * 0.25 + mouseInfluenceX;\n                    const cp1y =\n                        height * 0.5 +\n                        Math.sin(time * 1.2 + offset * 2) * (amplitude * 2) +\n                        mouseInfluenceY;\n                    const cp2x = width * 0.75 - mouseInfluenceX;\n                    const cp2y =\n                        height * 0.5 +\n                        Math.cos(time * 0.8 + offset * 2.5) *\n                            (amplitude * 2.5) +\n                        mouseInfluenceY;\n\n                    \/\/ Setup linear gradient for glowing transparency along the path\n                    const grad = ctx.createLinearGradient(0, 0, width, 0);\n                    grad.addColorStop(0, 'rgba(0,0,0,0)');\n                    grad.addColorStop(0.3, activeBaseColor);\n                    grad.addColorStop(0.7, activeBaseColor);\n                    grad.addColorStop(1, 'rgba(0,0,0,0)');\n\n                    \/\/ Wave path\n                    ctx.beginPath();\n                    ctx.moveTo(0, y1);\n                    ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, width, y2);\n\n                    \/\/ Thick strokes with high opacity blur mimic auroral bands\n                    ctx.strokeStyle = grad;\n                    ctx.lineWidth = 90 + Math.sin(time + i) * 30; \/\/ Shifting wave thickness\n                    ctx.lineCap = 'round';\n                    ctx.shadowColor = activeBaseColor;\n                    ctx.shadowBlur = 45;\n                    ctx.globalAlpha = 0.22 - i * 0.03; \/\/ Overlay layers nicely\n                    ctx.stroke();\n                }\n\n                ctx.restore();\n                animationId = requestAnimationFrame(draw);\n            };\n\n            draw();\n\n            return () => {\n                cancelAnimationFrame(animationId);\n                resizeObserver.disconnect();\n                if (interactive) {\n                    container.removeEventListener('mousemove', handleMouseMove);\n                    container.removeEventListener(\n                        'mouseleave',\n                        handleMouseLeave,\n                    );\n                }\n            };\n        }, [bandCount, speed, amplitude, colors, blendMode, interactive]);\n\n        return (\n            <div\n                ref={containerRef}\n                className={cn(\n                    'relative h-full w-full overflow-hidden bg-background\/55 select-none',\n                    className,\n                )}\n                {...props}\n            >\n                <canvas\n                    ref={canvasRef}\n                    className=\"absolute inset-0 size-full\"\n                    style={{ pointerEvents: 'none' }}\n                \/>\n            <\/div>\n        );\n    },\n);\n\nAuroraCanvas.displayName = 'AuroraCanvas';\n\nexport default AuroraCanvas;\n"}],"meta":{"category":"canvas","version":"1.0.0"},"categories":["canvas"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"constellation-canvas","type":"registry:ui","title":"Constellation Canvas","description":"An interactive network of floating particles that draw connecting links to neighboring nodes and follow mouse movements.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/canvas\/constellation-canvas.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface ConstellationCanvasProps extends React.HTMLAttributes<HTMLDivElement> {\n    \/** Number of particles in the constellation *\/\n    particleCount?: number;\n    \/** Maximum distance between connected particles *\/\n    maxDistance?: number;\n    \/** Movement speed multiplier *\/\n    speed?: number;\n    \/** Color of the particles, defaults to CSS variable or currentColor *\/\n    particleColor?: string;\n    \/** Color of the connecting lines *\/\n    linkColor?: string;\n    \/** Enable mouse interaction *\/\n    interactive?: boolean;\n    \/** Size of the particles *\/\n    particleSize?: number;\n}\n\ninterface Particle {\n    x: number;\n    y: number;\n    vx: number;\n    vy: number;\n    radius: number;\n}\n\nexport const ConstellationCanvas = React.forwardRef<\n    HTMLDivElement,\n    ConstellationCanvasProps\n>(\n    (\n        {\n            className,\n            particleCount = 60,\n            maxDistance = 100,\n            speed = 0.5,\n            particleColor,\n            linkColor,\n            interactive = true,\n            particleSize = 2,\n            ...props\n        },\n        ref,\n    ) => {\n        const containerRef = React.useRef<HTMLDivElement>(null);\n        const canvasRef = React.useRef<HTMLCanvasElement>(null);\n        const mouseRef = React.useRef<{ x: number; y: number } | null>(null);\n\n        React.useImperativeHandle(\n            ref,\n            () => containerRef.current as HTMLDivElement,\n        );\n\n        React.useEffect(() => {\n            const canvas = canvasRef.current;\n            const container = containerRef.current;\n            if (!canvas || !container) {\n                return;\n            }\n\n            const ctx = canvas.getContext('2d');\n            if (!ctx) {\n                return;\n            }\n\n            let animationId: number;\n            let width = (canvas.width = container.offsetWidth);\n            let height = (canvas.height = container.offsetHeight);\n\n            const particles: Particle[] = [];\n\n            \/\/ Initialize particles\n            const initParticles = () => {\n                particles.length = 0;\n                for (let i = 0; i < particleCount; i++) {\n                    particles.push({\n                        x: Math.random() * width,\n                        y: Math.random() * height,\n                        vx: (Math.random() - 0.5) * speed,\n                        vy: (Math.random() - 0.5) * speed,\n                        radius: Math.random() * particleSize + 1,\n                    });\n                }\n            };\n\n            initParticles();\n\n            \/\/ Resize observer\n            const resizeObserver = new ResizeObserver((entries) => {\n                for (const entry of entries) {\n                    width = canvas.width = entry.contentRect.width;\n                    height = canvas.height = entry.contentRect.height;\n                    initParticles();\n                }\n            });\n            resizeObserver.observe(container);\n\n            \/\/ Mouse events\n            const handleMouseMove = (e: MouseEvent) => {\n                if (!interactive) return;\n                const rect = canvas.getBoundingClientRect();\n                mouseRef.current = {\n                    x: e.clientX - rect.left,\n                    y: e.clientY - rect.top,\n                };\n            };\n\n            const handleMouseLeave = () => {\n                mouseRef.current = null;\n            };\n\n            if (interactive) {\n                container.addEventListener('mousemove', handleMouseMove);\n                container.addEventListener('mouseleave', handleMouseLeave);\n            }\n\n            const resolveColor = (colorStr: string, defaultVal: string) => {\n                if (!colorStr) return defaultVal;\n                \/\/ If it is a raw HSL variable (like \"240 5.9% 90%\"), wrap it in var() if it is a variable name,\n                \/\/ or if it contains spaces and no HSL wrapper, try wrapping it.\n                let targetColor = colorStr;\n                if (colorStr.startsWith('--')) {\n                    targetColor = `var(${colorStr})`;\n                }\n                if (\n                    !targetColor.includes('var(') &&\n                    !targetColor.includes('--')\n                ) {\n                    return targetColor;\n                }\n                try {\n                    const temp = document.createElement('div');\n                    temp.style.color = targetColor;\n                    container.appendChild(temp);\n                    const resolved = window.getComputedStyle(temp).color;\n                    container.removeChild(temp);\n                    return resolved || defaultVal;\n                } catch (e) {\n                    return defaultVal;\n                }\n            };\n\n            \/\/ Draw loop\n            const draw = () => {\n                ctx.clearRect(0, 0, width, height);\n\n                \/\/ Fetch colors inside loop to support reactive color scheme swaps\n                const activeParticleColor = resolveColor(\n                    particleColor || getComputedStyle(container).color,\n                    'rgba(16, 185, 129, 0.8)',\n                );\n                const activeLinkColor = resolveColor(\n                    linkColor || `var(--border)`,\n                    'rgba(226, 232, 240, 0.4)',\n                );\n\n                \/\/ Update and draw particles\n                particles.forEach((p) => {\n                    p.x += p.vx;\n                    p.y += p.vy;\n\n                    \/\/ Boundary collision\n                    if (p.x < 0 || p.x > width) p.vx *= -1;\n                    if (p.y < 0 || p.y > height) p.vy *= -1;\n\n                    \/\/ Draw particle\n                    ctx.beginPath();\n                    ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);\n                    ctx.fillStyle = activeParticleColor;\n                    ctx.fill();\n                });\n\n                \/\/ Connect particles\n                for (let i = 0; i < particles.length; i++) {\n                    const pi = particles[i];\n\n                    \/\/ Connect to mouse if active\n                    if (mouseRef.current) {\n                        const dx = mouseRef.current.x - pi.x;\n                        const dy = mouseRef.current.y - pi.y;\n                        const dist = Math.sqrt(dx * dx + dy * dy);\n\n                        if (dist < maxDistance * 1.5) {\n                            ctx.beginPath();\n                            ctx.moveTo(pi.x, pi.y);\n                            ctx.lineTo(mouseRef.current.x, mouseRef.current.y);\n                            const alpha =\n                                (1 - dist \/ (maxDistance * 1.5)) * 0.45;\n                            ctx.strokeStyle = activeLinkColor.includes('rgba')\n                                ? activeLinkColor.replace(\n                                      \/[\\d.]+\\)$\/,\n                                      `${alpha})`,\n                                  )\n                                : `rgba(16, 185, 129, ${alpha})`;\n                            ctx.lineWidth = 1;\n                            ctx.stroke();\n                        }\n                    }\n\n                    for (let j = i + 1; j < particles.length; j++) {\n                        const pj = particles[j];\n                        const dx = pi.x - pj.x;\n                        const dy = pi.y - pj.y;\n                        const dist = Math.sqrt(dx * dx + dy * dy);\n\n                        if (dist < maxDistance) {\n                            ctx.beginPath();\n                            ctx.moveTo(pi.x, pi.y);\n                            ctx.lineTo(pj.x, pj.y);\n                            const alpha = (1 - dist \/ maxDistance) * 0.25;\n                            ctx.strokeStyle = activeLinkColor.includes('rgba')\n                                ? activeLinkColor.replace(\n                                      \/[\\d.]+\\)$\/,\n                                      `${alpha})`,\n                                  )\n                                : `rgba(16, 185, 129, ${alpha})`;\n                            ctx.lineWidth = 0.5;\n                            ctx.stroke();\n                        }\n                    }\n                }\n\n                animationId = requestAnimationFrame(draw);\n            };\n\n            draw();\n\n            return () => {\n                cancelAnimationFrame(animationId);\n                resizeObserver.disconnect();\n                if (interactive) {\n                    container.removeEventListener('mousemove', handleMouseMove);\n                    container.removeEventListener(\n                        'mouseleave',\n                        handleMouseLeave,\n                    );\n                }\n            };\n        }, [\n            particleCount,\n            maxDistance,\n            speed,\n            particleColor,\n            linkColor,\n            interactive,\n            particleSize,\n        ]);\n\n        return (\n            <div\n                ref={containerRef}\n                className={cn(\n                    'relative h-full w-full overflow-hidden select-none',\n                    className,\n                )}\n                {...props}\n            >\n                <canvas\n                    ref={canvasRef}\n                    className=\"absolute inset-0 size-full\"\n                    style={{ pointerEvents: 'none' }}\n                \/>\n            <\/div>\n        );\n    },\n);\n\nConstellationCanvas.displayName = 'ConstellationCanvas';\n\nexport default ConstellationCanvas;\n"}],"meta":{"category":"canvas","version":"1.0.0"},"categories":["canvas"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"flow-field-canvas","type":"registry:ui","title":"Flow Field Canvas","description":"A dynamic particle flow simulation mapping trailing lines along mathematical vector wave coordinates.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/canvas\/flow-field-canvas.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface FlowFieldCanvasProps extends React.HTMLAttributes<HTMLDivElement> {\n    \/** Number of particles flowing in the field *\/\n    particleCount?: number;\n    \/** Speed multiplier for the particle movement *\/\n    speed?: number;\n    \/** Scale of the vector field grid (lower is smoother waves, higher is more chaotic) *\/\n    fieldScale?: number;\n    \/** Line width of the particle trails *\/\n    lineWidth?: number;\n    \/** Particle trail fade speed (0.01 - 0.1 for longer trails, 1 for no trails) *\/\n    fadeRate?: number;\n    \/** Color of the flow lines, defaults to primary or text color *\/\n    color?: string;\n    \/** Enable mouse interaction to deflect the vector field *\/\n    interactive?: boolean;\n}\n\ninterface FlowParticle {\n    x: number;\n    y: number;\n    px: number;\n    py: number;\n    vx: number;\n    vy: number;\n    life: number;\n    maxLife: number;\n}\n\nexport const FlowFieldCanvas = React.forwardRef<\n    HTMLDivElement,\n    FlowFieldCanvasProps\n>(\n    (\n        {\n            className,\n            particleCount = 200,\n            speed = 1.2,\n            fieldScale = 0.004,\n            lineWidth = 1.2,\n            fadeRate = 0.06,\n            color,\n            interactive = true,\n            ...props\n        },\n        ref,\n    ) => {\n        const containerRef = React.useRef<HTMLDivElement>(null);\n        const canvasRef = React.useRef<HTMLCanvasElement>(null);\n        const mouseRef = React.useRef<{ x: number; y: number } | null>(null);\n\n        React.useImperativeHandle(\n            ref,\n            () => containerRef.current as HTMLDivElement,\n        );\n\n        React.useEffect(() => {\n            const canvas = canvasRef.current;\n            const container = containerRef.current;\n            if (!canvas || !container) {\n                return;\n            }\n\n            const ctx = canvas.getContext('2d', { willReadFrequently: false });\n            if (!ctx) {\n                return;\n            }\n\n            let animationId: number;\n            let width = (canvas.width = container.offsetWidth);\n            let height = (canvas.height = container.offsetHeight);\n            let time = 0;\n\n            const particles: FlowParticle[] = [];\n\n            const createParticle = (): FlowParticle => {\n                const rx = Math.random() * width;\n                const ry = Math.random() * height;\n                return {\n                    x: rx,\n                    y: ry,\n                    px: rx,\n                    py: ry,\n                    vx: 0,\n                    vy: 0,\n                    life: 0,\n                    maxLife: Math.random() * 200 + 100,\n                };\n            };\n\n            const initParticles = () => {\n                particles.length = 0;\n                for (let i = 0; i < particleCount; i++) {\n                    particles.push(createParticle());\n                }\n                ctx.clearRect(0, 0, width, height);\n            };\n\n            initParticles();\n\n            \/\/ Resize listener\n            const resizeObserver = new ResizeObserver((entries) => {\n                for (const entry of entries) {\n                    width = canvas.width = entry.contentRect.width;\n                    height = canvas.height = entry.contentRect.height;\n                    initParticles();\n                }\n            });\n            resizeObserver.observe(container);\n\n            \/\/ Mouse coordinates\n            const handleMouseMove = (e: MouseEvent) => {\n                if (!interactive) return;\n                const rect = canvas.getBoundingClientRect();\n                mouseRef.current = {\n                    x: e.clientX - rect.left,\n                    y: e.clientY - rect.top,\n                };\n            };\n\n            const handleMouseLeave = () => {\n                mouseRef.current = null;\n            };\n\n            if (interactive) {\n                container.addEventListener('mousemove', handleMouseMove);\n                container.addEventListener('mouseleave', handleMouseLeave);\n            }\n\n            const resolveColor = (colorStr: string, defaultVal: string) => {\n                if (!colorStr) return defaultVal;\n                let targetColor = colorStr;\n                if (colorStr.startsWith('--')) {\n                    targetColor = `var(${colorStr})`;\n                }\n                if (\n                    !targetColor.includes('var(') &&\n                    !targetColor.includes('--')\n                ) {\n                    return targetColor;\n                }\n                try {\n                    const temp = document.createElement('div');\n                    temp.style.color = targetColor;\n                    container.appendChild(temp);\n                    const resolved = window.getComputedStyle(temp).color;\n                    container.removeChild(temp);\n                    return resolved || defaultVal;\n                } catch (e) {\n                    return defaultVal;\n                }\n            };\n\n            \/\/ Draw loop\n            const draw = () => {\n                \/\/ Apply trail fade effect\n                ctx.fillStyle = `rgba(0, 0, 0, ${fadeRate})`;\n\n                \/\/ If trail fade is not 1, we fill with translucent black\/card background to fade trails\n                \/\/ We fetch the theme background color to make trail fade work on light\/dark modes\n                const bgStyle =\n                    window.getComputedStyle(container).backgroundColor;\n                const isDark =\n                    bgStyle.includes('rgba(0, 0, 0') ||\n                    bgStyle.includes('rgb(0, 0, 0') ||\n                    bgStyle.includes('rgb(9, 9, 11');\n\n                ctx.fillStyle = isDark\n                    ? `rgba(9, 9, 11, ${fadeRate})`\n                    : `rgba(255, 255, 255, ${fadeRate})`;\n\n                ctx.fillRect(0, 0, width, height);\n\n                const activeColor = resolveColor(\n                    color || window.getComputedStyle(container).color,\n                    'rgba(16, 185, 129, 0.8)',\n                );\n\n                time += 0.003;\n\n                particles.forEach((p, idx) => {\n                    p.life++;\n\n                    \/\/ Respawn dead particles or boundary checks\n                    if (\n                        p.life > p.maxLife ||\n                        p.x < 0 ||\n                        p.x > width ||\n                        p.y < 0 ||\n                        p.y > height\n                    ) {\n                        Object.assign(p, createParticle());\n                    }\n\n                    \/\/ Vector field generation using nested trigonometric math functions (Perlin surrogate)\n                    let angle =\n                        Math.sin(p.x * fieldScale + time) * Math.PI * 2 +\n                        Math.cos(p.y * fieldScale - time) * Math.PI * 2;\n\n                    \/\/ Mouse attraction influence\n                    if (mouseRef.current) {\n                        const dx = mouseRef.current.x - p.x;\n                        const dy = mouseRef.current.y - p.y;\n                        const dist = Math.sqrt(dx * dx + dy * dy);\n                        if (dist < 150) {\n                            const mouseAngle = Math.atan2(dy, dx);\n                            \/\/ Blend angle towards mouse direction\n                            const blendStrength = (1 - dist \/ 150) * 0.45;\n                            angle =\n                                angle * (1 - blendStrength) +\n                                mouseAngle * blendStrength;\n                        }\n                    }\n\n                    \/\/ Compute velocity from angle\n                    p.vx = Math.cos(angle) * speed;\n                    p.vy = Math.sin(angle) * speed;\n\n                    p.px = p.x;\n                    p.py = p.y;\n\n                    p.x += p.vx;\n                    p.y += p.vy;\n\n                    \/\/ Draw line segments\n                    ctx.beginPath();\n                    ctx.moveTo(p.px, p.py);\n                    ctx.lineTo(p.x, p.y);\n                    ctx.strokeStyle = activeColor;\n                    ctx.lineWidth = lineWidth;\n                    ctx.lineCap = 'round';\n                    ctx.stroke();\n                });\n\n                animationId = requestAnimationFrame(draw);\n            };\n\n            draw();\n\n            return () => {\n                cancelAnimationFrame(animationId);\n                resizeObserver.disconnect();\n                if (interactive) {\n                    container.removeEventListener('mousemove', handleMouseMove);\n                    container.removeEventListener(\n                        'mouseleave',\n                        handleMouseLeave,\n                    );\n                }\n            };\n        }, [\n            particleCount,\n            speed,\n            fieldScale,\n            lineWidth,\n            fadeRate,\n            color,\n            interactive,\n        ]);\n\n        return (\n            <div\n                ref={containerRef}\n                className={cn(\n                    'relative h-full w-full overflow-hidden select-none',\n                    className,\n                )}\n                {...props}\n            >\n                <canvas\n                    ref={canvasRef}\n                    className=\"absolute inset-0 size-full\"\n                    style={{ pointerEvents: 'none' }}\n                \/>\n            <\/div>\n        );\n    },\n);\n\nFlowFieldCanvas.displayName = 'FlowFieldCanvas';\n\nexport default FlowFieldCanvas;\n"}],"meta":{"category":"canvas","version":"1.0.0"},"categories":["canvas"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"metaball-canvas","type":"registry:ui","title":"Metaball Canvas","description":"Organic fluid liquid spheres that bounce around the canvas and seamlessly merge together on contact.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/canvas\/metaball-canvas.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface MetaballCanvasProps extends React.HTMLAttributes<HTMLDivElement> {\n    \/** Number of fluid blobs *\/\n    blobCount?: number;\n    \/** Base blob radius range (min and max) *\/\n    minRadius?: number;\n    maxRadius?: number;\n    \/** Bouncing speed *\/\n    speed?: number;\n    \/** Color of the metaballs, defaults to primary *\/\n    color?: string;\n    \/** Enable mouse interaction (mouse acts as a large custom blob) *\/\n    interactive?: boolean;\n}\n\ninterface Blob {\n    x: number;\n    y: number;\n    vx: number;\n    vy: number;\n    radius: number;\n}\n\nexport const MetaballCanvas = React.forwardRef<\n    HTMLDivElement,\n    MetaballCanvasProps\n>(\n    (\n        {\n            className,\n            blobCount = 10,\n            minRadius = 30,\n            maxRadius = 60,\n            speed = 1.0,\n            color,\n            interactive = true,\n            ...props\n        },\n        ref,\n    ) => {\n        const containerRef = React.useRef<HTMLDivElement>(null);\n        const canvasRef = React.useRef<HTMLCanvasElement>(null);\n        const mouseRef = React.useRef<{ x: number; y: number } | null>(null);\n\n        React.useImperativeHandle(\n            ref,\n            () => containerRef.current as HTMLDivElement,\n        );\n\n        React.useEffect(() => {\n            const canvas = canvasRef.current;\n            const container = containerRef.current;\n            if (!canvas || !container) {\n                return;\n            }\n\n            const ctx = canvas.getContext('2d');\n            if (!ctx) {\n                return;\n            }\n\n            let animationId: number;\n            let width = (canvas.width = container.offsetWidth);\n            let height = (canvas.height = container.offsetHeight);\n\n            const blobs: Blob[] = [];\n\n            \/\/ Initialize blobs\n            const initBlobs = () => {\n                blobs.length = 0;\n                for (let i = 0; i < blobCount; i++) {\n                    const radius =\n                        Math.random() * (maxRadius - minRadius) + minRadius;\n                    blobs.push({\n                        x: Math.random() * (width - radius * 2) + radius,\n                        y: Math.random() * (height - radius * 2) + radius,\n                        vx: (Math.random() - 0.5) * speed * 2,\n                        vy: (Math.random() - 0.5) * speed * 2,\n                        radius,\n                    });\n                }\n            };\n\n            initBlobs();\n\n            \/\/ Resize listener\n            const resizeObserver = new ResizeObserver((entries) => {\n                for (const entry of entries) {\n                    width = canvas.width = entry.contentRect.width;\n                    height = canvas.height = entry.contentRect.height;\n                    initBlobs();\n                }\n            });\n            resizeObserver.observe(container);\n\n            \/\/ Mouse coordinate updates\n            const handleMouseMove = (e: MouseEvent) => {\n                if (!interactive) return;\n                const rect = canvas.getBoundingClientRect();\n                mouseRef.current = {\n                    x: e.clientX - rect.left,\n                    y: e.clientY - rect.top,\n                };\n            };\n\n            const handleMouseLeave = () => {\n                mouseRef.current = null;\n            };\n\n            if (interactive) {\n                container.addEventListener('mousemove', handleMouseMove);\n                container.addEventListener('mouseleave', handleMouseLeave);\n            }\n\n            const resolveColor = (colorStr: string) => {\n                if (!colorStr) return 'rgb(16, 185, 129)';\n                if (!colorStr.includes('var(') && !colorStr.includes('--')) {\n                    return colorStr;\n                }\n                try {\n                    const temp = document.createElement('div');\n                    temp.style.color = colorStr;\n                    container.appendChild(temp);\n                    const resolved = window.getComputedStyle(temp).color;\n                    container.removeChild(temp);\n                    return resolved || 'rgb(16, 185, 129)';\n                } catch (e) {\n                    return 'rgb(16, 185, 129)';\n                }\n            };\n\n            \/\/ Draw loop\n            const draw = () => {\n                \/\/ Clear with transparent background\n                ctx.clearRect(0, 0, width, height);\n\n                const activeColor = resolveColor(\n                    color ||\n                        window.getComputedStyle(container).color ||\n                        '#10b981',\n                );\n\n                \/\/ Draw standard blobs\n                blobs.forEach((b) => {\n                    b.x += b.vx;\n                    b.y += b.vy;\n\n                    \/\/ Bounce logic\n                    if (b.x - b.radius < 0) {\n                        b.x = b.radius;\n                        b.vx *= -1;\n                    } else if (b.x + b.radius > width) {\n                        b.x = width - b.radius;\n                        b.vx *= -1;\n                    }\n\n                    if (b.y - b.radius < 0) {\n                        b.y = b.radius;\n                        b.vy *= -1;\n                    } else if (b.y + b.radius > height) {\n                        b.y = height - b.radius;\n                        b.vy *= -1;\n                    }\n\n                    \/\/ Render blob with soft radial edge that contrast filter will solidify\n                    const grad = ctx.createRadialGradient(\n                        b.x,\n                        b.y,\n                        b.radius * 0.1,\n                        b.x,\n                        b.y,\n                        b.radius,\n                    );\n                    grad.addColorStop(0, activeColor);\n                    grad.addColorStop(1, 'rgba(0, 0, 0, 0)');\n\n                    ctx.beginPath();\n                    ctx.arc(b.x, b.y, b.radius, 0, Math.PI * 2);\n                    ctx.fillStyle = grad;\n                    ctx.fill();\n                });\n\n                \/\/ Draw mouse cursor blob\n                if (mouseRef.current) {\n                    const mouseRadius = (minRadius + maxRadius) * 0.6;\n                    const grad = ctx.createRadialGradient(\n                        mouseRef.current.x,\n                        mouseRef.current.y,\n                        mouseRadius * 0.1,\n                        mouseRef.current.x,\n                        mouseRef.current.y,\n                        mouseRadius,\n                    );\n                    grad.addColorStop(0, activeColor);\n                    grad.addColorStop(1, 'rgba(0, 0, 0, 0)');\n\n                    ctx.beginPath();\n                    ctx.arc(\n                        mouseRef.current.x,\n                        mouseRef.current.y,\n                        mouseRadius,\n                        0,\n                        Math.PI * 2,\n                    );\n                    ctx.fillStyle = grad;\n                    ctx.fill();\n                }\n\n                animationId = requestAnimationFrame(draw);\n            };\n\n            draw();\n\n            return () => {\n                cancelAnimationFrame(animationId);\n                resizeObserver.disconnect();\n                if (interactive) {\n                    container.removeEventListener('mousemove', handleMouseMove);\n                    container.removeEventListener(\n                        'mouseleave',\n                        handleMouseLeave,\n                    );\n                }\n            };\n        }, [blobCount, minRadius, maxRadius, speed, color, interactive]);\n\n        return (\n            <div\n                ref={containerRef}\n                className={cn(\n                    'relative h-full w-full overflow-hidden bg-background select-none',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* The CSS filter properties create the gooey metaball fusion effect *\/}\n                <canvas\n                    ref={canvasRef}\n                    className=\"absolute inset-0 size-full\"\n                    style={{\n                        pointerEvents: 'none',\n                        filter: 'blur(14px) contrast(20) hue-rotate(0deg)',\n                    }}\n                \/>\n            <\/div>\n        );\n    },\n);\n\nMetaballCanvas.displayName = 'MetaballCanvas';\n\nexport default MetaballCanvas;\n"}],"meta":{"category":"canvas","version":"1.0.0"},"categories":["canvas"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"pixel-canvas","type":"registry:ui","title":"Pixel Canvas","description":"An interactive background canvas that draws pixel highlights under the mouse cursor.","author":"designbycode","dependencies":["class-variance-authority"],"devDependencies":[],"registryDependencies":["utils","https:\/\/ui.test\/r\/use-pixel-canvas.json","https:\/\/ui.test\/r\/pixel-canvas-helper.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/canvas\/pixel-canvas.tsx","type":"registry:ui","content":"'use client';\n\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { usePixelCanvas } from '@\/registry\/new-york\/hooks\/use-pixel-canvas';\nimport type {\n    AnimationType,\n    PixelConfig,\n    PixelShape,\n} from '@\/registry\/new-york\/lib\/pixel-canvas-helper';\nimport { colorPresets } from '@\/registry\/new-york\/lib\/pixel-canvas-helper';\n\nconst pixelCanvasVariants = cva('relative overflow-hidden', {\n    variants: {\n        \/**\n         * Visual style variant\n         * - default: Standard pixel animation\n         * - subtle: Softer, more muted animation\n         * - vibrant: Bold, high-contrast colors\n         * - glow: Adds a subtle glow effect\n         * - minimal: Very sparse pixel density\n         *\/\n        variant: {\n            default: '',\n            subtle: '',\n            vibrant: '',\n            glow: '',\n            minimal: '',\n        },\n    },\n    defaultVariants: {\n        variant: 'default',\n    },\n});\n\n\/\/ Variant configurations\nconst variantConfigs: Record<string, Partial<PixelConfig>> = {\n    default: {\n        colors: colorPresets.slate,\n        gap: 6,\n        speed: 35,\n        shimmerIntensity: 0.5,\n    },\n    subtle: {\n        colors: ['#f8fafc', '#f1f5f9', '#e2e8f0'],\n        gap: 8,\n        speed: 20,\n        shimmerIntensity: 0.3,\n    },\n    vibrant: {\n        colors: colorPresets.neon,\n        gap: 5,\n        speed: 50,\n        shimmerIntensity: 0.7,\n    },\n    glow: {\n        colors: colorPresets.cyan,\n        gap: 6,\n        speed: 40,\n        shimmerIntensity: 0.6,\n    },\n    minimal: {\n        colors: colorPresets.slate,\n        gap: 12,\n        speed: 25,\n        shimmerIntensity: 0.4,\n    },\n};\n\nexport interface PixelCanvasProps\n    extends\n        React.HTMLAttributes<HTMLDivElement>,\n        VariantProps<typeof pixelCanvasVariants> {\n    \/** Custom colors array (overrides variant colors) - e.g. ['#ff0000', '#00ff00', '#0000ff'] *\/\n    colors?: string[];\n    \/** Color preset name *\/\n    colorPreset?: keyof typeof colorPresets;\n    \/** Gap between pixels *\/\n    gap?: number;\n    \/** Animation speed (0-100) *\/\n    speed?: number;\n    \/** Minimum pixel size *\/\n    minSize?: number;\n    \/** Maximum pixel size *\/\n    maxSize?: number;\n    \/** Shimmer intensity (0-1) *\/\n    shimmerIntensity?: number;\n    \/** Pixel shape *\/\n    shape?: PixelShape;\n    \/** Animation pattern type *\/\n    animationType?: AnimationType;\n    \/**\n     * Controls continuous animation\n     * - true: Animation runs continuously without interaction\n     * - false: Animation only runs when triggered\n     *\/\n    active?: boolean;\n    \/**\n     * Enable mouse interaction\n     * - true: Hover triggers appear\/disappear\n     * - false: Mouse events are ignored\n     *\/\n    mouseActive?: boolean;\n    \/** @deprecated Use `active` instead *\/\n    autoStart?: boolean;\n    \/** @deprecated Use `mouseActive` instead *\/\n    hoverTrigger?: boolean;\n    \/** Disable focus events *\/\n    noFocus?: boolean;\n}\n\nconst PixelCanvas = React.forwardRef<HTMLDivElement, PixelCanvasProps>(\n    (\n        {\n            className,\n            variant = 'default',\n            colors,\n            colorPreset,\n            gap,\n            speed,\n            minSize,\n            maxSize,\n            shimmerIntensity,\n            shape,\n            animationType,\n            active,\n            mouseActive,\n            autoStart,\n            hoverTrigger,\n            noFocus = false,\n            style,\n            ...props\n        },\n        ref,\n    ) => {\n        const variantConfig = variantConfigs[variant || 'default'];\n\n        const resolvedColors =\n            colors ||\n            (colorPreset ? colorPresets[colorPreset] : variantConfig.colors);\n\n        \/\/ Handle backwards compatibility\n        const resolvedActive = active ?? autoStart ?? false;\n        \/\/ If active is explicitly set, disable mouse events to override hover behavior\n        const resolvedMouseActive =\n            active !== undefined\n                ? false\n                : (mouseActive ?? hoverTrigger ?? true);\n\n        const { canvasRef, containerRef } = usePixelCanvas({\n            colors: resolvedColors,\n            gap: gap ?? variantConfig.gap,\n            speed: speed ?? variantConfig.speed,\n            minSize: minSize ?? 0.5,\n            maxSize: maxSize ?? 2,\n            shimmerIntensity:\n                shimmerIntensity ?? variantConfig.shimmerIntensity,\n            shape: shape ?? 'square',\n            animationType: animationType ?? 'radial',\n            active: resolvedActive,\n            mouseActive: resolvedMouseActive,\n            noFocus,\n        });\n\n        \/\/ Merge refs\n        React.useImperativeHandle(\n            ref,\n            () => containerRef.current as HTMLDivElement,\n        );\n\n        return (\n            <div\n                ref={containerRef}\n                className={cn(pixelCanvasVariants({ variant }), className)}\n                style={style}\n                {...props}\n            >\n                <canvas\n                    ref={canvasRef}\n                    className={cn(\n                        'absolute inset-0 h-full w-full',\n                        variant === 'glow' && 'blur-[0.5px]',\n                    )}\n                    style={{ pointerEvents: 'none' }}\n                \/>\n            <\/div>\n        );\n    },\n);\nPixelCanvas.displayName = 'PixelCanvas';\n\nexport { PixelCanvas, pixelCanvasVariants };\n"}],"meta":{"category":"canvas","version":"1.0.0"},"categories":["canvas"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"wave-grid-canvas","type":"registry:ui","title":"Wave Grid Canvas","description":"A grid of geometric nodes that dynamically ripple, scale, and rotate in response to mouse cursor distance.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/canvas\/wave-grid-canvas.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface WaveGridCanvasProps extends React.HTMLAttributes<HTMLDivElement> {\n    \/** Spacing between grid points in pixels *\/\n    gridSpacing?: number;\n    \/** Shape to render at grid nodes ('circle' | 'square' | 'cross') *\/\n    shape?: 'circle' | 'square' | 'cross';\n    \/** Maximum scale factor when rippling *\/\n    maxScale?: number;\n    \/** Animation speed multiplier *\/\n    speed?: number;\n    \/** Grid color, defaults to muted border color or primary *\/\n    color?: string;\n    \/** Enable hover interaction (ripple originates from mouse pointer) *\/\n    interactive?: boolean;\n}\n\nexport const WaveGridCanvas = React.forwardRef<\n    HTMLDivElement,\n    WaveGridCanvasProps\n>(\n    (\n        {\n            className,\n            gridSpacing = 30,\n            shape = 'circle',\n            maxScale = 2.0,\n            speed = 1.0,\n            color,\n            interactive = true,\n            ...props\n        },\n        ref,\n    ) => {\n        const containerRef = React.useRef<HTMLDivElement>(null);\n        const canvasRef = React.useRef<HTMLCanvasElement>(null);\n        const mouseRef = React.useRef<{ x: number; y: number } | null>(null);\n\n        React.useImperativeHandle(\n            ref,\n            () => containerRef.current as HTMLDivElement,\n        );\n\n        React.useEffect(() => {\n            const canvas = canvasRef.current;\n            const container = containerRef.current;\n            if (!canvas || !container) {\n                return;\n            }\n\n            const ctx = canvas.getContext('2d');\n            if (!ctx) {\n                return;\n            }\n\n            let animationId: number;\n            let width = (canvas.width = container.offsetWidth);\n            let height = (canvas.height = container.offsetHeight);\n            let time = 0;\n\n            const resizeObserver = new ResizeObserver((entries) => {\n                for (const entry of entries) {\n                    width = canvas.width = entry.contentRect.width;\n                    height = canvas.height = entry.contentRect.height;\n                }\n            });\n            resizeObserver.observe(container);\n\n            const handleMouseMove = (e: MouseEvent) => {\n                if (!interactive) return;\n                const rect = canvas.getBoundingClientRect();\n                mouseRef.current = {\n                    x: e.clientX - rect.left,\n                    y: e.clientY - rect.top,\n                };\n            };\n\n            const handleMouseLeave = () => {\n                mouseRef.current = null;\n            };\n\n            if (interactive) {\n                container.addEventListener('mousemove', handleMouseMove);\n                container.addEventListener('mouseleave', handleMouseLeave);\n            }\n\n            const resolveColor = (colorStr: string, defaultVal: string) => {\n                if (!colorStr) return defaultVal;\n                let targetColor = colorStr;\n                if (colorStr.startsWith('--')) {\n                    targetColor = `var(${colorStr})`;\n                }\n                if (\n                    !targetColor.includes('var(') &&\n                    !targetColor.includes('--')\n                ) {\n                    return targetColor;\n                }\n                try {\n                    const temp = document.createElement('div');\n                    temp.style.color = targetColor;\n                    container.appendChild(temp);\n                    const resolved = window.getComputedStyle(temp).color;\n                    container.removeChild(temp);\n                    return resolved || defaultVal;\n                } catch (e) {\n                    return defaultVal;\n                }\n            };\n\n            \/\/ Draw loop\n            const draw = () => {\n                ctx.clearRect(0, 0, width, height);\n\n                const activeColor = resolveColor(\n                    color || window.getComputedStyle(container).color,\n                    'rgba(16, 185, 129, 0.4)',\n                );\n\n                time += speed * 0.05;\n\n                const cols = Math.floor(width \/ gridSpacing) + 2;\n                const rows = Math.floor(height \/ gridSpacing) + 2;\n\n                const offsetX = (width % gridSpacing) \/ 2;\n                const offsetY = (height % gridSpacing) \/ 2;\n\n                for (let c = 0; c < cols; c++) {\n                    for (let r = 0; r < rows; r++) {\n                        const x = c * gridSpacing - gridSpacing \/ 2 + offsetX;\n                        const y = r * gridSpacing - gridSpacing \/ 2 + offsetY;\n\n                        let dist = 0;\n                        let influence = 0;\n\n                        if (mouseRef.current) {\n                            const dx = mouseRef.current.x - x;\n                            const dy = mouseRef.current.y - y;\n                            dist = Math.sqrt(dx * dx + dy * dy);\n\n                            \/\/ Proximity influence within 200px of mouse\n                            if (dist < 220) {\n                                influence = 1 - dist \/ 220;\n                            }\n                        } else {\n                            \/\/ Subtle default pulsing wave in the center if no mouse\n                            const dx = width * 0.5 - x;\n                            const dy = height * 0.5 - y;\n                            dist = Math.sqrt(dx * dx + dy * dy);\n                            influence =\n                                Math.sin(dist * 0.02 - time * 0.3) * 0.5 + 0.5;\n                        }\n\n                        \/\/ Calculate scale & opacity based on influence and sine ripples\n                        const waveFactor =\n                            Math.sin(dist * 0.04 - time) * 0.5 + 0.5;\n                        const scale =\n                            1.0 + (maxScale - 1.0) * influence * waveFactor;\n                        const opacity = 0.15 + 0.65 * influence * waveFactor;\n\n                        ctx.save();\n                        ctx.translate(x, y);\n                        ctx.globalAlpha = opacity;\n                        ctx.fillStyle = activeColor;\n                        ctx.strokeStyle = activeColor;\n\n                        const baseSize = 2.5;\n                        const size = baseSize * scale;\n\n                        \/\/ Render geometric shape\n                        if (shape === 'circle') {\n                            ctx.beginPath();\n                            ctx.arc(0, 0, size, 0, Math.PI * 2);\n                            ctx.fill();\n                        } else if (shape === 'square') {\n                            ctx.fillRect(-size, -size, size * 2, size * 2);\n                        } else if (shape === 'cross') {\n                            ctx.lineWidth = 1.2;\n                            ctx.beginPath();\n                            \/\/ Horizontal\n                            ctx.moveTo(-size, 0);\n                            ctx.lineTo(size, 0);\n                            \/\/ Vertical\n                            ctx.moveTo(0, -size);\n                            ctx.lineTo(0, size);\n                            ctx.stroke();\n                        }\n\n                        ctx.restore();\n                    }\n                }\n\n                animationId = requestAnimationFrame(draw);\n            };\n\n            draw();\n\n            return () => {\n                cancelAnimationFrame(animationId);\n                resizeObserver.disconnect();\n                if (interactive) {\n                    container.removeEventListener('mousemove', handleMouseMove);\n                    container.removeEventListener(\n                        'mouseleave',\n                        handleMouseLeave,\n                    );\n                }\n            };\n        }, [gridSpacing, shape, maxScale, speed, color, interactive]);\n\n        return (\n            <div\n                ref={containerRef}\n                className={cn(\n                    'relative h-full w-full overflow-hidden bg-background select-none',\n                    className,\n                )}\n                {...props}\n            >\n                <canvas\n                    ref={canvasRef}\n                    className=\"absolute inset-0 size-full\"\n                    style={{ pointerEvents: 'none' }}\n                \/>\n            <\/div>\n        );\n    },\n);\n\nWaveGridCanvas.displayName = 'WaveGridCanvas';\n\nexport default WaveGridCanvas;\n"}],"meta":{"category":"canvas","version":"1.0.0"},"categories":["canvas"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"expandable-card","type":"registry:ui","title":"Expandable Card","description":"A card with smooth layout-animated accordion-style expansions powered by Framer Motion.","author":"designbycode","dependencies":["motion","lucide-react"],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/expandable-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { motion, AnimatePresence } from 'motion\/react';\nimport { ChevronDown } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nconst MotionCard = motion(Card);\n\nexport interface ExpandableCardProps extends React.ComponentProps<typeof Card> {\n    title: string;\n    description?: string;\n    expandedContent?: React.ReactNode;\n    defaultExpanded?: boolean;\n}\n\nconst ExpandableCard = React.forwardRef<HTMLDivElement, ExpandableCardProps>(\n    (\n        {\n            className,\n            title,\n            description,\n            expandedContent,\n            defaultExpanded = false,\n            children,\n            ...props\n        },\n        ref,\n    ) => {\n        const [isExpanded, setIsExpanded] = React.useState(defaultExpanded);\n\n        const {\n            onDrag,\n            onDragStart,\n            onDragEnd,\n            onAnimationStart,\n            ...safeProps\n        } = props as any;\n\n        return (\n            <MotionCard\n                layout\n                ref={ref}\n                className={cn(\n                    'relative overflow-hidden p-6 shadow-md transition-shadow hover:shadow-lg',\n                    className,\n                )}\n                {...safeProps}\n            >\n                {\/* Header section always visible *\/}\n                <div\n                    onClick={() => setIsExpanded(!isExpanded)}\n                    className=\"flex cursor-pointer items-start justify-between gap-4 select-none\"\n                >\n                    <div className=\"space-y-1\">\n                        <motion.h3\n                            layout=\"position\"\n                            className=\"text-lg font-bold tracking-tight\"\n                        >\n                            {title}\n                        <\/motion.h3>\n                        {description && (\n                            <motion.p\n                                layout=\"position\"\n                                className=\"text-sm text-muted-foreground\"\n                            >\n                                {description}\n                            <\/motion.p>\n                        )}\n                    <\/div>\n                    <motion.div\n                        layout\n                        animate={{ rotate: isExpanded ? 180 : 0 }}\n                        transition={{ duration: 0.2 }}\n                        className=\"rounded-full p-1.5 text-muted-foreground transition-colors hover:bg-muted\"\n                    >\n                        <ChevronDown className=\"h-4 w-4\" \/>\n                    <\/motion.div>\n                <\/div>\n\n                {\/* Default layout children *\/}\n                {children && (\n                    <motion.div layout=\"position\" className=\"mt-4\">\n                        {children}\n                    <\/motion.div>\n                )}\n\n                {\/* Expanded content section *\/}\n                <AnimatePresence initial={false}>\n                    {isExpanded && expandedContent && (\n                        <motion.div\n                            initial={{ height: 0, opacity: 0 }}\n                            animate={{ height: 'auto', opacity: 1 }}\n                            exit={{ height: 0, opacity: 0 }}\n                            transition={{ duration: 0.3, ease: 'easeInOut' }}\n                            className=\"overflow-hidden\"\n                        >\n                            <div className=\"mt-4 border-t border-border\/40 pt-4 text-sm text-muted-foreground\">\n                                {expandedContent}\n                            <\/div>\n                        <\/motion.div>\n                    )}\n                <\/AnimatePresence>\n            <\/MotionCard>\n        );\n    },\n);\n\nExpandableCard.displayName = 'ExpandableCard';\n\nexport { ExpandableCard };\nexport default ExpandableCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"glass-glare-card","type":"registry:ui","title":"Glass Glare Card","description":"A premium frosted glass layout featuring realistic cursor-following glare reflections.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card","https:\/\/ui.test\/r\/use-hover.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/glass-glare-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nimport { useHover } from '@\/registry\/new-york\/hooks\/use-hover';\n\nexport interface GlassGlareCardProps extends React.ComponentProps<typeof Card> {\n    glareColor?: string;\n    opacity?: number;\n}\n\nconst GlassGlareCard = React.forwardRef<HTMLDivElement, GlassGlareCardProps>(\n    (\n        {\n            className,\n            children,\n            glareColor = 'rgba(255, 255, 255, 0.15)',\n            opacity = 0.2,\n            ...props\n        },\n        ref,\n    ) => {\n        const localRef = React.useRef<HTMLDivElement>(null);\n        const { isHovered, hoverRef } = useHover();\n        const [glarePos, setGlarePos] = React.useState({ x: 50, y: 50 });\n\n        const combinedRef = React.useCallback(\n            (node: HTMLDivElement | null) => {\n                hoverRef(node);\n                if (typeof ref === 'function') {\n                    ref(node);\n                } else if (ref) {\n                    (\n                        ref as React.MutableRefObject<HTMLDivElement | null>\n                    ).current = node;\n                }\n                (\n                    localRef as React.MutableRefObject<HTMLDivElement | null>\n                ).current = node;\n            },\n            [ref, hoverRef],\n        );\n\n        const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n            const card = localRef.current;\n            if (!card) return;\n            const rect = card.getBoundingClientRect();\n            const x = ((e.clientX - rect.left) \/ rect.width) * 100;\n            const y = ((e.clientY - rect.top) \/ rect.height) * 100;\n            setGlarePos({ x, y });\n        };\n\n        return (\n            <Card\n                ref={combinedRef}\n                onMouseMove={handleMouseMove}\n                className={cn(\n                    'relative overflow-hidden bg-card\/40 p-6 shadow-2xl backdrop-blur-md transition-all duration-300',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Dynamic Glare Overlay *\/}\n                <div\n                    className=\"pointer-events-none absolute inset-0 -z-10 transition-opacity duration-300\"\n                    style={{\n                        background: `radial-gradient(circle at ${glarePos.x}% ${glarePos.y}%, ${glareColor}, transparent 50%)`,\n                        opacity: isHovered ? opacity : 0,\n                    }}\n                \/>\n\n                {\/* Linear Shine overlay *\/}\n                <div\n                    className=\"pointer-events-none absolute inset-0 -z-10 transition-opacity duration-500\"\n                    style={{\n                        background: `linear-gradient(${135 + (glarePos.x - 50) \/ 2}deg, transparent 40%, rgba(255, 255, 255, 0.08) 50%, transparent 60%)`,\n                        opacity: isHovered ? 1 : 0,\n                    }}\n                \/>\n\n                <div className=\"relative z-10 text-foreground\">{children}<\/div>\n            <\/Card>\n        );\n    },\n);\n\nGlassGlareCard.displayName = 'GlassGlareCard';\n\nexport { GlassGlareCard };\nexport default GlassGlareCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"glowing-card","type":"registry:ui","title":"Glowing Card","description":"An interactive card container that tracks mouse hover coordinates to trace a glowing radial spotlight.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card","https:\/\/ui.test\/r\/use-hover.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/glowing-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nimport { useHover } from '@\/registry\/new-york\/hooks\/use-hover';\n\nexport interface GlowingCardProps extends React.ComponentProps<typeof Card> {\n    glowColor?: string;\n}\n\nconst GlowingCard = React.forwardRef<HTMLDivElement, GlowingCardProps>(\n    (\n        {\n            className,\n            children,\n            glowColor = 'color-mix(in srgb, var(--color-chart-2) 15%, transparent)',\n            ...props\n        },\n        ref,\n    ) => {\n        const localRef = React.useRef<HTMLDivElement>(null);\n        const { isHovered, hoverRef } = useHover();\n        const [coords, setCoords] = React.useState({ x: 0, y: 0 });\n\n        const combinedRef = React.useCallback(\n            (node: HTMLDivElement | null) => {\n                hoverRef(node);\n                if (typeof ref === 'function') {\n                    ref(node);\n                } else if (ref) {\n                    (\n                        ref as React.MutableRefObject<HTMLDivElement | null>\n                    ).current = node;\n                }\n                (\n                    localRef as React.MutableRefObject<HTMLDivElement | null>\n                ).current = node;\n            },\n            [ref, hoverRef],\n        );\n\n        const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n            if (!localRef.current) return;\n            const rect = localRef.current.getBoundingClientRect();\n            setCoords({\n                x: e.clientX - rect.left,\n                y: e.clientY - rect.top,\n            });\n        };\n\n        return (\n            <Card\n                ref={combinedRef}\n                onMouseMove={handleMouseMove}\n                className={cn(\n                    'relative overflow-hidden bg-card\/60 p-6 backdrop-blur-xs transition-all',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Mouse-tracking Radial Spotlight *\/}\n                <div\n                    className=\"pointer-events-none absolute inset-0 -z-10 transition-opacity duration-300\"\n                    style={{\n                        background: `radial-gradient(200px circle at ${coords.x}px ${coords.y}px, ${glowColor}, transparent 80%)`,\n                        opacity: isHovered ? 1 : 0,\n                    }}\n                \/>\n                {children}\n            <\/Card>\n        );\n    },\n);\n\nGlowingCard.displayName = 'GlowingCard';\n\nexport { GlowingCard };\nexport default GlowingCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"grainy-noise-card","type":"registry:ui","title":"Grainy Noise Card","description":"A card applying textured frosted glassmorphism overlays with glowing color backlights.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card","https:\/\/ui.test\/r\/use-hover.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/grainy-noise-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nimport { useHover } from '@\/registry\/new-york\/hooks\/use-hover';\n\nexport interface GrainyNoiseCardProps extends React.ComponentProps<\n    typeof Card\n> {\n    noiseOpacity?: number;\n    glowColor?: string;\n}\n\nconst GrainyNoiseCard = React.forwardRef<HTMLDivElement, GrainyNoiseCardProps>(\n    (\n        {\n            className,\n            children,\n            noiseOpacity = 0.04,\n            glowColor = 'var(--color-primary)',\n            ...props\n        },\n        ref,\n    ) => {\n        const { isHovered, hoverRef } = useHover();\n\n        const combinedRef = React.useCallback(\n            (node: HTMLDivElement | null) => {\n                hoverRef(node);\n                if (typeof ref === 'function') {\n                    ref(node);\n                } else if (ref) {\n                    (\n                        ref as React.MutableRefObject<HTMLDivElement | null>\n                    ).current = node;\n                }\n            },\n            [ref, hoverRef],\n        );\n\n        return (\n            <Card\n                ref={combinedRef}\n                className={cn(\n                    'relative overflow-hidden bg-card\/75 p-6 shadow-xl backdrop-blur-md transition-all duration-500',\n                    isHovered ? 'scale-[1.01] border-border\/80 shadow-2xl' : '',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* SVG Grain\/Noise Filter Overlay *\/}\n                <div\n                    className=\"pointer-events-none absolute inset-0 -z-10 mix-blend-overlay transition-opacity duration-300\"\n                    style={{\n                        opacity: noiseOpacity,\n                        backgroundImage: `url(\"data:image\/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http:\/\/www.w3.org\/2000\/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'\/%3E%3C\/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'\/%3E%3C\/svg%3E\")`,\n                    }}\n                \/>\n\n                {\/* Glowing Soft Backdrop Accent *\/}\n                <div\n                    className=\"pointer-events-none absolute -top-20 -right-20 -z-20 size-48 rounded-full opacity-20 blur-3xl transition-all duration-700\"\n                    style={{\n                        background: glowColor,\n                        transform: isHovered\n                            ? 'scale(1.3) translate3d(-10px, 10px, 0)'\n                            : 'scale(1) translate3d(0, 0, 0)',\n                    }}\n                \/>\n\n                <div className=\"relative text-card-foreground\">{children}<\/div>\n            <\/Card>\n        );\n    },\n);\n\nGrainyNoiseCard.displayName = 'GrainyNoiseCard';\n\nexport { GrainyNoiseCard };\nexport default GrainyNoiseCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"magnetic-card","type":"registry:ui","title":"Magnetic Card","description":"A tactile card that translates physically towards the cursor position on hover.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/magnetic-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nexport interface MagneticCardProps extends React.ComponentProps<typeof Card> {\n    strength?: number;\n}\n\nconst MagneticCard = React.forwardRef<HTMLDivElement, MagneticCardProps>(\n    ({ className, children, strength = 15, ...props }, ref) => {\n        const localRef = React.useRef<HTMLDivElement>(null);\n        const resolvedRef = (ref ||\n            localRef) as React.RefObject<HTMLDivElement | null>;\n        const [style, setStyle] = React.useState<React.CSSProperties>({});\n\n        const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n            const card = resolvedRef.current;\n            if (!card) return;\n\n            const rect = card.getBoundingClientRect();\n            const mouseX = e.clientX - rect.left - rect.width \/ 2;\n            const mouseY = e.clientY - rect.top - rect.height \/ 2;\n\n            \/\/ Normalized translation coordinates\n            const x = (mouseX \/ (rect.width \/ 2)) * strength;\n            const y = (mouseY \/ (rect.height \/ 2)) * strength;\n\n            setStyle({\n                transform: `translate3d(${x}px, ${y}px, 0)`,\n                transition: 'transform 0.1s cubic-bezier(0.25, 1, 0.5, 1)',\n            });\n        };\n\n        const handleMouseLeave = () => {\n            setStyle({\n                transform: 'translate3d(0, 0, 0)',\n                transition: 'transform 0.5s cubic-bezier(0.25, 1, 0.5, 1)',\n            });\n        };\n\n        return (\n            <Card\n                ref={resolvedRef}\n                onMouseMove={handleMouseMove}\n                onMouseLeave={handleMouseLeave}\n                style={style}\n                className={cn(\n                    'relative overflow-hidden p-6 shadow-md transition-shadow select-none hover:shadow-lg',\n                    className,\n                )}\n                {...props}\n            >\n                {children}\n            <\/Card>\n        );\n    },\n);\n\nMagneticCard.displayName = 'MagneticCard';\n\nexport { MagneticCard };\nexport default MagneticCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"metric-breakdown-card","type":"registry:ui","title":"Metric Breakdown Card","description":"A container-responsive dashboard statistics card displaying main metrics and sub-metric breakdown progress lists.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card","https:\/\/ui.test\/r\/use-hover.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/metric-breakdown-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\nimport { useHover } from '@\/registry\/new-york\/hooks\/use-hover';\n\nexport interface BreakdownItem {\n    label: string;\n    value: string;\n    percentage: number;\n    color?: string; \/\/ Optional custom bar color\n}\n\nexport interface MetricBreakdownCardProps extends React.ComponentProps<\n    typeof Card\n> {\n    title: string;\n    value: string;\n    trend?: string;\n    trendType?: 'positive' | 'negative' | 'neutral';\n    items: BreakdownItem[];\n}\n\nconst MetricBreakdownCard = React.forwardRef<\n    HTMLDivElement,\n    MetricBreakdownCardProps\n>(\n    (\n        {\n            className,\n            title,\n            value,\n            trend,\n            trendType = 'positive',\n            items = [],\n            children,\n            ...props\n        },\n        ref,\n    ) => {\n        const { isHovered, hoverRef } = useHover();\n\n        const combinedRef = React.useCallback(\n            (node: HTMLDivElement | null) => {\n                hoverRef(node);\n                if (typeof ref === 'function') {\n                    ref(node);\n                } else if (ref) {\n                    (\n                        ref as React.MutableRefObject<HTMLDivElement | null>\n                    ).current = node;\n                }\n            },\n            [ref, hoverRef],\n        );\n\n        return (\n            <Card\n                ref={combinedRef}\n                className={cn(\n                    '@container relative overflow-hidden p-6 shadow-md transition-all hover:shadow-lg',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Responsive header layout using container queries *\/}\n                <div className=\"flex flex-col gap-2 @sm:flex-row @sm:items-start @sm:justify-between\">\n                    <div className=\"space-y-1\">\n                        <span className=\"text-xs font-semibold tracking-wider text-muted-foreground uppercase\">\n                            {title}\n                        <\/span>\n                        <div className=\"font-mono text-2xl font-black tracking-tight text-foreground\">\n                            {value}\n                        <\/div>\n                    <\/div>\n\n                    {trend && (\n                        <span\n                            className={cn(\n                                'self-start rounded px-2 py-0.5 font-mono text-[10px] font-bold tracking-wide @sm:self-auto',\n                                trendType === 'positive' &&\n                                    'border border-primary\/20 bg-primary\/10 text-primary',\n                                trendType === 'negative' &&\n                                    'border border-destructive\/20 bg-destructive\/10 text-destructive',\n                                trendType === 'neutral' &&\n                                    'bg-muted text-muted-foreground',\n                            )}\n                        >\n                            {trend}\n                        <\/span>\n                    )}\n                <\/div>\n\n                {\/* Sub-metrics section adapting layout dynamically based on container size *\/}\n                <div className=\"mt-6 border-t border-border\/50 pt-4\">\n                    <div className=\"grid grid-cols-1 gap-4 @md:grid-cols-2 @lg:grid-cols-3\">\n                        {items.map((item, idx) => (\n                            <div\n                                key={idx}\n                                className=\"space-y-2 rounded-lg border border-border\/30 bg-muted\/10 p-3\"\n                            >\n                                <div className=\"flex items-center justify-between text-xs\">\n                                    <span className=\"font-semibold text-muted-foreground\">\n                                        {item.label}\n                                    <\/span>\n                                    <span className=\"font-mono font-bold text-foreground\">\n                                        {item.value}\n                                    <\/span>\n                                <\/div>\n\n                                <div className=\"relative h-1.5 w-full overflow-hidden rounded-full bg-muted\/40\">\n                                    <div\n                                        className=\"h-full rounded-full transition-all duration-700 ease-out\"\n                                        style={{\n                                            width: isHovered\n                                                ? `${item.percentage}%`\n                                                : '0%',\n                                            backgroundColor:\n                                                item.color ||\n                                                'var(--color-primary)',\n                                            boxShadow:\n                                                isHovered && !item.color\n                                                    ? '0 0 4px var(--color-primary)'\n                                                    : 'none',\n                                        }}\n                                    \/>\n                                <\/div>\n\n                                <div className=\"text-right font-mono text-[9px] text-muted-foreground\">\n                                    {item.percentage}% of total\n                                <\/div>\n                            <\/div>\n                        ))}\n                    <\/div>\n                <\/div>\n\n                {children && <div className=\"mt-4 text-xs\">{children}<\/div>}\n            <\/Card>\n        );\n    },\n);\n\nMetricBreakdownCard.displayName = 'MetricBreakdownCard';\n\nexport { MetricBreakdownCard };\nexport default MetricBreakdownCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"metric-comparison-card","type":"registry:ui","title":"Metric Comparison Card","description":"A dashboard statistics card comparing current vs. previous stats side-by-side with animated horizontal progress bars.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card","https:\/\/ui.test\/r\/use-hover.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/metric-comparison-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\nimport { useHover } from '@\/registry\/new-york\/hooks\/use-hover';\n\nexport interface MetricComparisonCardProps extends React.ComponentProps<\n    typeof Card\n> {\n    title: string;\n    currentValue: string;\n    currentLabel?: string;\n    comparisonValue: string;\n    comparisonLabel?: string;\n    ratio: number; \/\/ 0 to 1 (e.g. currentValue \/ comparisonValue)\n    trend?: string;\n    trendType?: 'positive' | 'negative' | 'neutral';\n}\n\nconst MetricComparisonCard = React.forwardRef<\n    HTMLDivElement,\n    MetricComparisonCardProps\n>(\n    (\n        {\n            className,\n            title,\n            currentValue,\n            currentLabel = 'Current Period',\n            comparisonValue,\n            comparisonLabel = 'Previous Period',\n            ratio,\n            trend,\n            trendType = 'positive',\n            children,\n            ...props\n        },\n        ref,\n    ) => {\n        const { isHovered, hoverRef } = useHover();\n\n        const combinedRef = React.useCallback(\n            (node: HTMLDivElement | null) => {\n                hoverRef(node);\n                if (typeof ref === 'function') {\n                    ref(node);\n                } else if (ref) {\n                    (\n                        ref as React.MutableRefObject<HTMLDivElement | null>\n                    ).current = node;\n                }\n            },\n            [ref, hoverRef],\n        );\n\n        const currentPercentage = Math.min(Math.max(ratio * 100, 0), 100);\n\n        return (\n            <Card\n                ref={combinedRef}\n                className={cn(\n                    'relative overflow-hidden p-6 shadow-md transition-all hover:shadow-lg',\n                    className,\n                )}\n                {...props}\n            >\n                <div className=\"flex items-start justify-between\">\n                    <div className=\"space-y-1\">\n                        <span className=\"text-xs font-semibold tracking-wider text-muted-foreground uppercase\">\n                            {title}\n                        <\/span>\n                        <div className=\"flex items-baseline gap-2\">\n                            <span className=\"font-mono text-2xl font-black tracking-tight text-foreground\">\n                                {currentValue}\n                            <\/span>\n                            <span className=\"text-xs text-muted-foreground\">\n                                vs {comparisonValue}\n                            <\/span>\n                        <\/div>\n                    <\/div>\n\n                    {trend && (\n                        <span\n                            className={cn(\n                                'rounded px-2 py-0.5 font-mono text-[10px] font-bold tracking-wide',\n                                trendType === 'positive' &&\n                                    'border border-primary\/20 bg-primary\/10 text-primary',\n                                trendType === 'negative' &&\n                                    'border border-destructive\/20 bg-destructive\/10 text-destructive',\n                                trendType === 'neutral' &&\n                                    'bg-muted text-muted-foreground',\n                            )}\n                        >\n                            {trend}\n                        <\/span>\n                    )}\n                <\/div>\n\n                {\/* Comparative Horizontal Progress Bars *\/}\n                <div className=\"mt-6 space-y-3\">\n                    <div className=\"space-y-1.5\">\n                        <div className=\"flex items-center justify-between text-[10px] font-bold text-muted-foreground uppercase\">\n                            <span>{currentLabel}<\/span>\n                            <span className=\"font-mono text-foreground\">\n                                {currentPercentage.toFixed(0)}%\n                            <\/span>\n                        <\/div>\n                        <div className=\"h-2 w-full overflow-hidden rounded-full bg-muted\/40\">\n                            <div\n                                className=\"h-full rounded-full bg-primary transition-all duration-700 ease-out\"\n                                style={{\n                                    width: isHovered\n                                        ? `${currentPercentage}%`\n                                        : '0%',\n                                    boxShadow: isHovered\n                                        ? '0 0 6px var(--color-primary)'\n                                        : 'none',\n                                }}\n                            \/>\n                        <\/div>\n                    <\/div>\n\n                    <div className=\"space-y-1.5\">\n                        <div className=\"flex items-center justify-between text-[10px] font-bold text-muted-foreground uppercase\">\n                            <span>{comparisonLabel}<\/span>\n                            <span className=\"font-mono text-foreground\">\n                                100%\n                            <\/span>\n                        <\/div>\n                        <div className=\"h-2 w-full overflow-hidden rounded-full bg-muted\/40\">\n                            <div\n                                className=\"h-full rounded-full bg-foreground\/30 transition-all duration-500 ease-out\"\n                                style={{\n                                    width: isHovered ? '100%' : '0%',\n                                }}\n                            \/>\n                        <\/div>\n                    <\/div>\n                <\/div>\n\n                {children && <div className=\"mt-4 text-xs\">{children}<\/div>}\n            <\/Card>\n        );\n    },\n);\n\nMetricComparisonCard.displayName = 'MetricComparisonCard';\n\nexport { MetricComparisonCard };\nexport default MetricComparisonCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"metric-progress-card","type":"registry:ui","title":"Metric Progress Card","description":"A dashboard statistics card featuring an animated circular progress ring, target status tracking, and trend badges.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card","https:\/\/ui.test\/r\/use-hover.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/metric-progress-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\nimport { useHover } from '@\/registry\/new-york\/hooks\/use-hover';\n\nexport interface MetricProgressCardProps extends React.ComponentProps<\n    typeof Card\n> {\n    title: string;\n    value: string;\n    progress: number; \/\/ 0 to 100\n    targetLabel?: string;\n    targetValue?: string;\n    trend?: string;\n    trendType?: 'positive' | 'negative' | 'neutral';\n    accentColor?: string; \/\/ CSS color string or custom variable\n}\n\nconst MetricProgressCard = React.forwardRef<\n    HTMLDivElement,\n    MetricProgressCardProps\n>(\n    (\n        {\n            className,\n            title,\n            value,\n            progress,\n            targetLabel = 'Target',\n            targetValue,\n            trend,\n            trendType = 'positive',\n            accentColor = 'var(--color-primary)',\n            children,\n            ...props\n        },\n        ref,\n    ) => {\n        const { isHovered, hoverRef } = useHover();\n\n        const combinedRef = React.useCallback(\n            (node: HTMLDivElement | null) => {\n                hoverRef(node);\n                if (typeof ref === 'function') {\n                    ref(node);\n                } else if (ref) {\n                    (\n                        ref as React.MutableRefObject<HTMLDivElement | null>\n                    ).current = node;\n                }\n            },\n            [ref, hoverRef],\n        );\n\n        \/\/ Circular SVG configuration\n        const radius = 24;\n        const circumference = 2 * Math.PI * radius;\n        const fillOffset =\n            circumference -\n            (Math.min(Math.max(progress, 0), 100) \/ 100) * circumference;\n\n        return (\n            <Card\n                ref={combinedRef}\n                className={cn(\n                    'relative overflow-hidden p-6 shadow-md transition-all hover:shadow-lg',\n                    className,\n                )}\n                {...props}\n            >\n                <div className=\"flex items-start justify-between\">\n                    <div className=\"space-y-1\">\n                        <span className=\"text-xs font-semibold tracking-wider text-muted-foreground uppercase\">\n                            {title}\n                        <\/span>\n                        <div className=\"font-mono text-2xl font-black tracking-tight text-foreground\">\n                            {value}\n                        <\/div>\n                    <\/div>\n\n                    <div className=\"relative flex size-14 items-center justify-center select-none\">\n                        <svg className=\"size-full -rotate-90\">\n                            {\/* Track Circle *\/}\n                            <circle\n                                cx=\"28\"\n                                cy=\"28\"\n                                r={radius}\n                                fill=\"transparent\"\n                                stroke=\"var(--color-muted)\"\n                                strokeWidth=\"4.5\"\n                                className=\"opacity-40\"\n                            \/>\n                            {\/* Animated Active Circle *\/}\n                            <circle\n                                cx=\"28\"\n                                cy=\"28\"\n                                r={radius}\n                                fill=\"transparent\"\n                                stroke={accentColor}\n                                strokeWidth=\"4.5\"\n                                strokeDasharray={circumference}\n                                strokeDashoffset={\n                                    isHovered ? fillOffset - 5 : fillOffset\n                                }\n                                strokeLinecap=\"round\"\n                                className=\"transition-all duration-700 ease-out\"\n                                style={{\n                                    filter: isHovered\n                                        ? `drop-shadow(0 0 3px ${accentColor})`\n                                        : 'none',\n                                }}\n                            \/>\n                        <\/svg>\n                        <span className=\"absolute font-mono text-[10px] font-extrabold text-foreground\">\n                            {Math.round(progress)}%\n                        <\/span>\n                    <\/div>\n                <\/div>\n\n                <div className=\"mt-6 flex items-center justify-between border-t border-border\/50 pt-4\">\n                    <div className=\"space-y-0.5\">\n                        <span className=\"text-[10px] font-semibold text-muted-foreground uppercase\">\n                            {targetLabel}\n                        <\/span>\n                        {targetValue && (\n                            <div className=\"font-mono text-xs font-bold text-foreground\">\n                                {targetValue}\n                            <\/div>\n                        )}\n                    <\/div>\n\n                    {trend && (\n                        <span\n                            className={cn(\n                                'rounded px-2 py-0.5 font-mono text-[10px] font-bold tracking-wide',\n                                trendType === 'positive' &&\n                                    'border border-primary\/20 bg-primary\/10 text-primary',\n                                trendType === 'negative' &&\n                                    'border border-destructive\/20 bg-destructive\/10 text-destructive',\n                                trendType === 'neutral' &&\n                                    'bg-muted text-muted-foreground',\n                            )}\n                        >\n                            {trend}\n                        <\/span>\n                    )}\n                <\/div>\n\n                {children && <div className=\"mt-4 text-xs\">{children}<\/div>}\n            <\/Card>\n        );\n    },\n);\n\nMetricProgressCard.displayName = 'MetricProgressCard';\n\nexport { MetricProgressCard };\nexport default MetricProgressCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"metric-radial-card","type":"registry:ui","title":"Metric Radial Card","description":"A container-responsive dashboard statistics card displaying nested Apple-Watch-style progress rings with interactive legends.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card","https:\/\/ui.test\/r\/use-hover.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/metric-radial-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\nimport { useHover } from '@\/registry\/new-york\/hooks\/use-hover';\n\nexport interface RadialMetricItem {\n    label: string;\n    value: string;\n    percentage: number; \/\/ 0 to 100\n    color: string; \/\/ CSS color string or variable\n}\n\nexport interface MetricRadialCardProps extends React.ComponentProps<\n    typeof Card\n> {\n    title: string;\n    value: string;\n    items: RadialMetricItem[]; \/\/ Exactly 3 items recommended\n}\n\nconst MetricRadialCard = React.forwardRef<\n    HTMLDivElement,\n    MetricRadialCardProps\n>(({ className, title, value, items = [], children, ...props }, ref) => {\n    const { isHovered, hoverRef } = useHover();\n\n    const combinedRef = React.useCallback(\n        (node: HTMLDivElement | null) => {\n            hoverRef(node);\n            if (typeof ref === 'function') {\n                ref(node);\n            } else if (ref) {\n                (ref as React.MutableRefObject<HTMLDivElement | null>).current =\n                    node;\n            }\n        },\n        [ref, hoverRef],\n    );\n\n    \/\/ Nested rings configuration\n    const svgSize = 120;\n    const center = svgSize \/ 2;\n\n    \/\/ Setup ring geometries with varying radii\n    const ringConfigs = [\n        { radius: 44, strokeWidth: 8 },\n        { radius: 32, strokeWidth: 8 },\n        { radius: 20, strokeWidth: 8 },\n    ];\n\n    return (\n        <Card\n            ref={combinedRef}\n            className={cn(\n                '@container relative overflow-hidden p-6 shadow-md transition-all hover:shadow-lg',\n                className,\n            )}\n            {...props}\n        >\n            <div className=\"space-y-1\">\n                <span className=\"text-xs font-semibold tracking-wider text-muted-foreground uppercase\">\n                    {title}\n                <\/span>\n                <div className=\"font-mono text-2xl font-black tracking-tight text-foreground\">\n                    {value}\n                <\/div>\n            <\/div>\n\n            {\/* Responsive container layout splitting into side-by-side at container-width >= 380px *\/}\n            <div className=\"mt-6 flex flex-col items-center gap-6 @sm:flex-row @sm:items-center @sm:justify-between\">\n                {\/* SVG Nested Rings *\/}\n                <div className=\"relative flex size-32 shrink-0 items-center justify-center select-none\">\n                    <svg\n                        width={svgSize}\n                        height={svgSize}\n                        className=\"-rotate-90\"\n                    >\n                        {items.slice(0, 3).map((item, idx) => {\n                            const config = ringConfigs[idx] || ringConfigs[0];\n                            const circumference = 2 * Math.PI * config.radius;\n                            const fillOffset =\n                                circumference -\n                                (Math.min(Math.max(item.percentage, 0), 100) \/\n                                    100) *\n                                    circumference;\n\n                            return (\n                                <g key={idx}>\n                                    {\/* Background Track *\/}\n                                    <circle\n                                        cx={center}\n                                        cy={center}\n                                        r={config.radius}\n                                        fill=\"transparent\"\n                                        stroke=\"var(--color-muted)\"\n                                        strokeWidth={config.strokeWidth}\n                                        className=\"opacity-20\"\n                                    \/>\n                                    {\/* Active Progress Ring *\/}\n                                    <circle\n                                        cx={center}\n                                        cy={center}\n                                        r={config.radius}\n                                        fill=\"transparent\"\n                                        stroke={item.color}\n                                        strokeWidth={config.strokeWidth}\n                                        strokeDasharray={circumference}\n                                        strokeDashoffset={\n                                            isHovered\n                                                ? fillOffset - 4\n                                                : fillOffset\n                                        }\n                                        strokeLinecap=\"round\"\n                                        className=\"transition-all duration-1000 ease-out\"\n                                        style={{\n                                            filter: isHovered\n                                                ? `drop-shadow(0 0 2.5px ${item.color})`\n                                                : 'none',\n                                        }}\n                                    \/>\n                                <\/g>\n                            );\n                        })}\n                    <\/svg>\n                <\/div>\n\n                {\/* Breakdown labels grid *\/}\n                <div className=\"w-full space-y-3.5\">\n                    {items.slice(0, 3).map((item, idx) => (\n                        <div\n                            key={idx}\n                            className=\"flex items-center justify-between gap-3 text-xs\"\n                        >\n                            <div className=\"flex min-w-0 items-center gap-2\">\n                                <span\n                                    className=\"size-2 shrink-0 rounded-full\"\n                                    style={{ backgroundColor: item.color }}\n                                \/>\n                                <span className=\"truncate font-semibold text-muted-foreground\">\n                                    {item.label}\n                                <\/span>\n                            <\/div>\n                            <div className=\"flex shrink-0 items-center gap-1.5 font-mono\">\n                                <span className=\"font-bold text-foreground\">\n                                    {item.value}\n                                <\/span>\n                                <span className=\"text-[10px] text-muted-foreground\">\n                                    ({Math.round(item.percentage)}%)\n                                <\/span>\n                            <\/div>\n                        <\/div>\n                    ))}\n                <\/div>\n            <\/div>\n\n            {children && <div className=\"mt-4 text-xs\">{children}<\/div>}\n        <\/Card>\n    );\n});\n\nMetricRadialCard.displayName = 'MetricRadialCard';\n\nexport { MetricRadialCard };\nexport default MetricRadialCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"metric-spark-card","type":"registry:ui","title":"Metric Spark Card","description":"A dashboard statistics card featuring a glowing mini-sparkline SVG that dynamically animates on hover.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card","https:\/\/ui.test\/r\/use-hover.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/metric-spark-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nimport { useHover } from '@\/registry\/new-york\/hooks\/use-hover';\n\nexport interface MetricSparkCardProps extends React.ComponentProps<\n    typeof Card\n> {\n    title: string;\n    value: string;\n    trend?: string;\n    trendType?: 'positive' | 'negative' | 'neutral';\n    dataPoints?: number[];\n}\n\nconst MetricSparkCard = React.forwardRef<HTMLDivElement, MetricSparkCardProps>(\n    (\n        {\n            className,\n            title,\n            value,\n            trend,\n            trendType = 'positive',\n            dataPoints = [10, 22, 18, 35, 30, 45, 40, 55],\n            children,\n            ...props\n        },\n        ref,\n    ) => {\n        const { isHovered, hoverRef } = useHover();\n\n        const combinedRef = React.useCallback(\n            (node: HTMLDivElement | null) => {\n                hoverRef(node);\n                if (typeof ref === 'function') {\n                    ref(node);\n                } else if (ref) {\n                    (\n                        ref as React.MutableRefObject<HTMLDivElement | null>\n                    ).current = node;\n                }\n            },\n            [ref, hoverRef],\n        );\n\n        \/\/ SVG Sparkline path generation\n        const svgWidth = 140;\n        const svgHeight = 40;\n        const maxVal = Math.max(...dataPoints);\n        const minVal = Math.min(...dataPoints);\n        const range = maxVal - minVal || 1;\n\n        const points = dataPoints\n            .map((val, idx) => {\n                const x = (idx \/ (dataPoints.length - 1)) * svgWidth;\n                const y =\n                    svgHeight - 4 - ((val - minVal) \/ range) * (svgHeight - 8);\n                return `${x},${y}`;\n            })\n            .join(' ');\n\n        return (\n            <Card\n                ref={combinedRef}\n                className={cn(\n                    'relative overflow-hidden p-6 shadow-md transition-all hover:shadow-lg',\n                    className,\n                )}\n                {...props}\n            >\n                <div className=\"flex items-start justify-between\">\n                    <div className=\"space-y-1\">\n                        <span className=\"text-xs font-semibold tracking-wider text-muted-foreground uppercase\">\n                            {title}\n                        <\/span>\n                        <div className=\"font-mono text-2xl font-black tracking-tight\">\n                            {value}\n                        <\/div>\n                    <\/div>\n\n                    {trend && (\n                        <span\n                            className={cn(\n                                'rounded px-2 py-0.5 font-mono text-[10px] font-bold tracking-wide',\n                                trendType === 'positive' &&\n                                    'border border-primary\/20 bg-primary\/10 text-primary',\n                                trendType === 'negative' &&\n                                    'border border-destructive\/20 bg-destructive\/10 text-destructive',\n                                trendType === 'neutral' &&\n                                    'bg-muted text-muted-foreground',\n                            )}\n                        >\n                            {trend}\n                        <\/span>\n                    )}\n                <\/div>\n\n                <div className=\"mt-6 flex items-center justify-between gap-4\">\n                    {\/* Glowing Sparkline visualization *\/}\n                    <div className=\"relative\">\n                        <svg\n                            width={svgWidth}\n                            height={svgHeight}\n                            className=\"overflow-visible\"\n                        >\n                            <polyline\n                                fill=\"none\"\n                                stroke=\"var(--color-primary)\"\n                                strokeWidth=\"2.5\"\n                                strokeLinecap=\"round\"\n                                strokeLinejoin=\"round\"\n                                points={points}\n                                className=\"transition-all duration-500 ease-out\"\n                                style={{\n                                    strokeDasharray: isHovered ? '0' : '300',\n                                    strokeDashoffset: isHovered ? '0' : '10',\n                                    filter: isHovered\n                                        ? 'drop-shadow(0 0 4px var(--color-primary))'\n                                        : 'none',\n                                }}\n                            \/>\n                        <\/svg>\n                    <\/div>\n\n                    {children && <div className=\"text-xs\">{children}<\/div>}\n                <\/div>\n            <\/Card>\n        );\n    },\n);\n\nMetricSparkCard.displayName = 'MetricSparkCard';\n\nexport { MetricSparkCard };\nexport default MetricSparkCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"neon-border-card","type":"registry:ui","title":"Neon Border Card","description":"A modern card containing a glowing rotating conic border gradient beam.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/neon-border-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nexport interface NeonBorderCardProps extends React.HTMLAttributes<HTMLDivElement> {\n    duration?: number;\n    colorFrom?: string;\n    colorTo?: string;\n    borderWidth?: number;\n    beamSize?: number;\n}\n\nconst NeonBorderCard = React.forwardRef<HTMLDivElement, NeonBorderCardProps>(\n    (\n        {\n            className,\n            children,\n            duration = 4,\n            colorFrom = 'var(--color-primary)',\n            colorTo = 'var(--color-chart-1)',\n            borderWidth = 1,\n            beamSize = 120,\n            ...props\n        },\n        ref,\n    ) => {\n        return (\n            <div\n                ref={ref}\n                className={cn(\n                    'relative overflow-hidden rounded-xl bg-card p-[1px] shadow-lg transition-shadow duration-300 hover:shadow-primary\/10',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Neon Border Beam layer *\/}\n                <div\n                    className=\"pointer-events-none absolute inset-0 -z-10 rounded-xl\"\n                    style={\n                        {\n                            '--beam-duration': `${duration}s`,\n                            '--color-from': colorFrom,\n                            '--color-to': colorTo,\n                            position: 'absolute',\n                            width: '200%',\n                            height: '200%',\n                            top: '-50%',\n                            left: '-50%',\n                            background:\n                                'conic-gradient(from 0deg at 50% 50%, transparent 60%, var(--color-from) 85%, var(--color-to) 95%, transparent 100%)',\n                            animation:\n                                'spin var(--beam-duration) linear infinite',\n                        } as React.CSSProperties\n                    }\n                \/>\n\n                {\/* Card interior content composed with standard Card component *\/}\n                <Card className=\"relative flex h-full w-full flex-col rounded-[11px] border-0 bg-card\/95 p-6 text-card-foreground shadow-none backdrop-blur-xs\">\n                    {children}\n                <\/Card>\n            <\/div>\n        );\n    },\n);\n\nNeonBorderCard.displayName = 'NeonBorderCard';\n\nexport { NeonBorderCard };\nexport default NeonBorderCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"parallax-image-card","type":"registry:ui","title":"Parallax Image Card","description":"A visual card component displaying a background image that shifts in parallax response to cursor movements.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/parallax-image-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nexport interface ParallaxImageCardProps extends React.ComponentProps<\n    typeof Card\n> {\n    imageUrl: string;\n    imageAlt?: string;\n    parallaxStrength?: number;\n    overlayGradient?: string;\n}\n\nconst ParallaxImageCard = React.forwardRef<\n    HTMLDivElement,\n    ParallaxImageCardProps\n>(\n    (\n        {\n            className,\n            children,\n            imageUrl,\n            imageAlt = 'Card image',\n            parallaxStrength = 15,\n            overlayGradient = 'linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.3) 50%, rgba(0, 0, 0, 0) 100%)',\n            ...props\n        },\n        ref,\n    ) => {\n        const localRef = React.useRef<HTMLDivElement>(null);\n        const resolvedRef = (ref ||\n            localRef) as React.RefObject<HTMLDivElement | null>;\n        const [offset, setOffset] = React.useState({ x: 0, y: 0 });\n\n        const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n            const card = resolvedRef.current;\n            if (!card) return;\n\n            const rect = card.getBoundingClientRect();\n            const mouseX = e.clientX - rect.left;\n            const mouseY = e.clientY - rect.top;\n\n            \/\/ Calculate offset between -1 and 1\n            const xPercent = (mouseX \/ rect.width - 0.5) * 2;\n            const yPercent = (mouseY \/ rect.height - 0.5) * 2;\n\n            setOffset({\n                x: xPercent * parallaxStrength,\n                y: yPercent * parallaxStrength,\n            });\n        };\n\n        const handleMouseLeave = () => {\n            setOffset({ x: 0, y: 0 });\n        };\n\n        return (\n            <Card\n                ref={resolvedRef}\n                onMouseMove={handleMouseMove}\n                onMouseLeave={handleMouseLeave}\n                className={cn(\n                    'group relative flex aspect-[4\/5] w-full flex-col justify-end gap-0 overflow-hidden p-0 shadow-md select-none',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Parallax Background Image Wrapper *\/}\n                <div\n                    className=\"absolute inset-0 -z-20 scale-110 transition-transform duration-300 ease-out\"\n                    style={{\n                        transform: `translate3d(${-offset.x}px, ${-offset.y}px, 0)`,\n                    }}\n                >\n                    <img\n                        src={imageUrl}\n                        alt={imageAlt}\n                        className=\"h-full w-full object-cover object-center transition-all duration-700 group-hover:scale-105\"\n                    \/>\n                <\/div>\n\n                {\/* Dark Gradient Overlay *\/}\n                <div\n                    className=\"pointer-events-none absolute inset-0 -z-10\"\n                    style={{ background: overlayGradient }}\n                \/>\n\n                {\/* Content Overlay *\/}\n                <div className=\"p-6 text-white transition-transform duration-300 ease-out group-hover:translate-y-[-4px]\">\n                    {children}\n                <\/div>\n            <\/Card>\n        );\n    },\n);\n\nParallaxImageCard.displayName = 'ParallaxImageCard';\n\nexport { ParallaxImageCard };\nexport default ParallaxImageCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"rainbow-border-card","type":"registry:ui","title":"Rainbow Border Card","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card","https:\/\/ui.test\/r\/rainbow-border.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/rainbow-border-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport {\n    Card,\n    CardContent,\n    CardDescription,\n    CardFooter,\n    CardHeader,\n    CardTitle,\n} from '@\/components\/ui\/card';\nimport { RainbowBorder } from '@\/registry\/new-york\/components\/ui\/borders\/rainbow-border';\n\nexport interface RainbowBorderCardProps extends React.ComponentProps<\n    typeof Card\n> {\n    borderWidth?: string;\n    animationDuration?: string;\n    colors?: string[];\n    rounded?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'full';\n    glow?: boolean;\n    glowBlur?: string;\n    glowOpacity?: number;\n}\n\nexport const RainbowBorderCard = React.forwardRef<\n    HTMLDivElement,\n    RainbowBorderCardProps\n>(\n    (\n        {\n            className,\n            borderWidth = '2px',\n            animationDuration = '4s',\n            colors,\n            rounded = 'lg',\n            glow = true,\n            glowBlur = '40px',\n            glowOpacity = 40,\n            children,\n            ...props\n        },\n        ref,\n    ) => {\n        const roundedCardClass =\n            rounded === 'none'\n                ? 'rounded-none'\n                : rounded === 'xs'\n                  ? 'rounded-xs'\n                  : rounded === 'sm'\n                    ? 'rounded-sm'\n                    : rounded === 'md'\n                      ? 'rounded-md'\n                      : rounded === 'lg'\n                        ? 'rounded-lg'\n                        : 'rounded-full';\n\n        return (\n            <RainbowBorder\n                borderWidth={borderWidth}\n                animationDuration={animationDuration}\n                colors={colors}\n                rounded={rounded}\n                glow={glow}\n                glowBlur={glowBlur}\n                glowOpacity={glowOpacity}\n                className=\"w-full p-[1px]\"\n            >\n                <Card\n                    ref={ref}\n                    className={cn(\n                        'w-full border-0 bg-card text-card-foreground shadow-sm',\n                        roundedCardClass,\n                        className,\n                    )}\n                    {...props}\n                >\n                    {children}\n                <\/Card>\n            <\/RainbowBorder>\n        );\n    },\n);\n\nRainbowBorderCard.displayName = 'RainbowBorderCard';\n\nexport default RainbowBorderCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"reveal-card","type":"registry:ui","title":"Reveal Card","description":"An interactive card with a mouse-tracking border spotlight glow.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card","https:\/\/ui.test\/r\/use-hover.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/reveal-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nimport { useHover } from '@\/registry\/new-york\/hooks\/use-hover';\n\nexport interface RevealCardProps extends React.HTMLAttributes<HTMLDivElement> {\n    borderColor?: string;\n    borderWidth?: number;\n    spotlightRadius?: number;\n}\n\nconst RevealCard = React.forwardRef<HTMLDivElement, RevealCardProps>(\n    (\n        {\n            className,\n            children,\n            borderColor = 'color-mix(in srgb, var(--color-primary) 35%, transparent)',\n            borderWidth = 1,\n            spotlightRadius = 150,\n            ...props\n        },\n        ref,\n    ) => {\n        const localRef = React.useRef<HTMLDivElement>(null);\n        const { isHovered, hoverRef } = useHover();\n        const [coords, setCoords] = React.useState({ x: 0, y: 0 });\n\n        const combinedRef = React.useCallback(\n            (node: HTMLDivElement | null) => {\n                hoverRef(node);\n                if (typeof ref === 'function') {\n                    ref(node);\n                } else if (ref) {\n                    (\n                        ref as React.MutableRefObject<HTMLDivElement | null>\n                    ).current = node;\n                }\n                (\n                    localRef as React.MutableRefObject<HTMLDivElement | null>\n                ).current = node;\n            },\n            [ref, hoverRef],\n        );\n\n        const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n            const card = localRef.current;\n            if (!card) return;\n            const rect = card.getBoundingClientRect();\n            setCoords({\n                x: e.clientX - rect.left,\n                y: e.clientY - rect.top,\n            });\n        };\n\n        return (\n            <div\n                ref={combinedRef}\n                onMouseMove={handleMouseMove}\n                className={cn(\n                    'relative overflow-hidden rounded-xl bg-muted\/40 p-[1px] transition-all',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Border spotlight overlay *\/}\n                <div\n                    className=\"pointer-events-none absolute inset-0 transition-opacity duration-300\"\n                    style={{\n                        background: `radial-gradient(${spotlightRadius}px circle at ${coords.x}px ${coords.y}px, ${borderColor}, transparent 80%)`,\n                        opacity: isHovered ? 1 : 0,\n                    }}\n                \/>\n\n                {\/* Card body composed with standard Card component *\/}\n                <Card className=\"relative flex h-full w-full flex-col rounded-[11px] border-0 bg-card\/90 p-6 text-card-foreground shadow-none backdrop-blur-xs\">\n                    {children}\n                <\/Card>\n            <\/div>\n        );\n    },\n);\n\nRevealCard.displayName = 'RevealCard';\n\nexport { RevealCard };\nexport default RevealCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"scratch-card","type":"registry:ui","title":"Scratch Card","description":"An interactive scratch-off card using an HTML5 Canvas to reveal hidden secret content.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/scratch-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nexport interface ScratchCardProps extends React.ComponentProps<typeof Card> {\n    width?: number;\n    height?: number;\n    overlayColor?: string;\n    brushRadius?: number;\n    percentToReveal?: number;\n    onComplete?: () => void;\n}\n\nconst ScratchCard = React.forwardRef<HTMLDivElement, ScratchCardProps>(\n    (\n        {\n            className,\n            overlayColor = '#3f3f46', \/\/ Zinc-700\n            brushRadius = 20,\n            percentToReveal = 50,\n            onComplete,\n            children,\n            ...props\n        },\n        ref,\n    ) => {\n        const localRef = React.useRef<HTMLDivElement>(null);\n        const resolvedRef = (ref ||\n            localRef) as React.RefObject<HTMLDivElement | null>;\n        const canvasRef = React.useRef<HTMLCanvasElement>(null);\n        const [isScratching, setIsScratching] = React.useState(false);\n        const [isFinished, setIsFinished] = React.useState(false);\n\n        React.useEffect(() => {\n            const canvas = canvasRef.current;\n            const container = resolvedRef.current;\n            if (!canvas || !container) return;\n\n            const rect = container.getBoundingClientRect();\n            canvas.width = rect.width;\n            canvas.height = rect.height;\n\n            const ctx = canvas.getContext('2d');\n            if (!ctx) return;\n\n            \/\/ Fill canvas with overlay color\n            ctx.fillStyle = overlayColor;\n            ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n            \/\/ Draw a subtle texture or text on top of scratch card\n            ctx.fillStyle = '#71717a'; \/\/ Zinc-500\n            ctx.font = 'bold 12px sans-serif';\n            ctx.textAlign = 'center';\n            ctx.textBaseline = 'middle';\n            ctx.fillText(\n                'SCRATCH TO REVEAL',\n                canvas.width \/ 2,\n                canvas.height \/ 2,\n            );\n        }, [overlayColor, resolvedRef]);\n\n        const getMousePos = (e: React.MouseEvent | React.TouchEvent) => {\n            const canvas = canvasRef.current;\n            if (!canvas) return { x: 0, y: 0 };\n            const rect = canvas.getBoundingClientRect();\n\n            \/\/ Handle touch events vs mouse events\n            const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;\n            const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY;\n\n            return {\n                x: clientX - rect.left,\n                y: clientY - rect.top,\n            };\n        };\n\n        const scratch = (e: React.MouseEvent | React.TouchEvent) => {\n            const canvas = canvasRef.current;\n            if (!canvas || !isScratching || isFinished) return;\n\n            const ctx = canvas.getContext('2d');\n            if (!ctx) return;\n\n            const { x, y } = getMousePos(e);\n\n            ctx.globalCompositeOperation = 'destination-out';\n            ctx.beginPath();\n            ctx.arc(x, y, brushRadius, 0, Math.PI * 2);\n            ctx.fill();\n\n            checkRevealPercentage();\n        };\n\n        const checkRevealPercentage = () => {\n            const canvas = canvasRef.current;\n            if (!canvas) return;\n\n            const ctx = canvas.getContext('2d');\n            if (!ctx) return;\n\n            const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n            const pixels = imgData.data;\n            let transparentPixels = 0;\n\n            for (let i = 3; i < pixels.length; i += 4) {\n                if (pixels[i] === 0) {\n                    transparentPixels++;\n                }\n            }\n\n            const percentage = (transparentPixels \/ (pixels.length \/ 4)) * 100;\n            if (percentage >= percentToReveal && !isFinished) {\n                setIsFinished(true);\n                \/\/ Clear the whole canvas\n                ctx.clearRect(0, 0, canvas.width, canvas.height);\n                if (onComplete) onComplete();\n            }\n        };\n\n        return (\n            <Card\n                ref={resolvedRef}\n                className={cn(\n                    'relative overflow-hidden p-6 shadow-md select-none',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Hidden contents below the scratch layer *\/}\n                <div className=\"relative z-0 h-full w-full\">{children}<\/div>\n\n                {\/* Scratch Canvas layer *\/}\n                {!isFinished && (\n                    <canvas\n                        ref={canvasRef}\n                        onMouseDown={() => setIsScratching(true)}\n                        onMouseUp={() => setIsScratching(false)}\n                        onMouseLeave={() => setIsScratching(false)}\n                        onMouseMove={scratch}\n                        onTouchStart={() => setIsScratching(true)}\n                        onTouchEnd={() => setIsScratching(false)}\n                        onTouchMove={scratch}\n                        className=\"absolute inset-0 z-20 cursor-crosshair touch-none\"\n                    \/>\n                )}\n            <\/Card>\n        );\n    },\n);\n\nScratchCard.displayName = 'ScratchCard';\n\nexport { ScratchCard };\nexport default ScratchCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"split-preview-card","type":"registry:ui","title":"Split Preview Card","description":"An interactive split-layout card linking lists to morphing color and detail previews.","author":"designbycode","dependencies":["motion"],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/split-preview-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { motion, AnimatePresence } from 'motion\/react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nexport interface SplitPreviewItem {\n    id: string;\n    label: string;\n    details: string;\n    previewColor: string; \/\/ e.g. 'var(--color-chart-1)' or 'var(--color-primary)'\n    icon?: React.ReactNode;\n}\n\nexport interface SplitPreviewCardProps extends React.ComponentProps<\n    typeof Card\n> {\n    items: SplitPreviewItem[];\n    defaultActiveId?: string;\n}\n\nconst SplitPreviewCard = React.forwardRef<\n    HTMLDivElement,\n    SplitPreviewCardProps\n>(({ className, items, defaultActiveId, ...props }, ref) => {\n    const [activeId, setActiveId] = React.useState(\n        defaultActiveId || items[0]?.id,\n    );\n    const activeItem = items.find((item) => item.id === activeId) || items[0];\n\n    return (\n        <Card\n            ref={ref}\n            className={cn(\n                'grid grid-cols-1 gap-0 overflow-hidden p-0 shadow-md md:grid-cols-12',\n                className,\n            )}\n            {...props}\n        >\n            {\/* Left side: Dynamic morphing preview block *\/}\n            <div\n                className=\"relative flex flex-col justify-between p-6 text-white transition-colors duration-500 md:col-span-5\"\n                style={{\n                    backgroundColor: activeItem\n                        ? `color-mix(in srgb, ${activeItem.previewColor} 12%, rgba(0,0,0,0.85))`\n                        : 'black',\n                    borderRight: '1px solid var(--color-border)',\n                }}\n            >\n                {\/* Glowing backlight overlay *\/}\n                <div\n                    className=\"pointer-events-none absolute inset-0 opacity-40 blur-2xl transition-all duration-700\"\n                    style={{\n                        background: `radial-gradient(circle at 50% 50%, ${activeItem?.previewColor || 'var(--color-primary)'}, transparent 70%)`,\n                    }}\n                \/>\n\n                <div className=\"relative z-10 flex items-center justify-between\">\n                    <span className=\"font-mono text-xs tracking-wider uppercase opacity-60\">\n                        STATUS PREVIEW\n                    <\/span>\n                    <div\n                        className=\"size-3.5 animate-pulse rounded-full\"\n                        style={{ backgroundColor: activeItem?.previewColor }}\n                    \/>\n                <\/div>\n\n                <div className=\"relative z-10 my-8 flex justify-center\">\n                    <AnimatePresence mode=\"wait\">\n                        <motion.div\n                            key={activeItem?.id}\n                            initial={{ scale: 0.8, opacity: 0, rotate: -10 }}\n                            animate={{ scale: 1, opacity: 1, rotate: 0 }}\n                            exit={{ scale: 0.8, opacity: 0, rotate: 10 }}\n                            transition={{ duration: 0.25 }}\n                            className=\"flex size-16 items-center justify-center rounded-xl border border-white\/20 bg-white\/10 text-white shadow-lg backdrop-blur-xs\"\n                            style={{\n                                boxShadow: `0 8px 32px 0 color-mix(in srgb, ${activeItem?.previewColor} 30%, transparent)`,\n                            }}\n                        >\n                            {activeItem?.icon || (\n                                <div className=\"size-6 rounded bg-white\/30\" \/>\n                            )}\n                        <\/motion.div>\n                    <\/AnimatePresence>\n                <\/div>\n\n                <div className=\"relative z-10 space-y-1\">\n                    <AnimatePresence mode=\"wait\">\n                        <motion.h4\n                            key={activeItem?.id}\n                            initial={{ y: 10, opacity: 0 }}\n                            animate={{ y: 0, opacity: 1 }}\n                            exit={{ y: -10, opacity: 0 }}\n                            transition={{ duration: 0.2 }}\n                            className=\"text-base font-black tracking-tight uppercase\"\n                        >\n                            {activeItem?.label}\n                        <\/motion.h4>\n                    <\/AnimatePresence>\n                    <AnimatePresence mode=\"wait\">\n                        <motion.p\n                            key={activeItem?.id}\n                            initial={{ y: 10, opacity: 0 }}\n                            animate={{ y: 0, opacity: 1 }}\n                            exit={{ y: -10, opacity: 0 }}\n                            transition={{ duration: 0.2 }}\n                            className=\"line-clamp-2 text-xs opacity-75\"\n                        >\n                            {activeItem?.details}\n                        <\/motion.p>\n                    <\/AnimatePresence>\n                <\/div>\n            <\/div>\n\n            {\/* Right side: Interactive navigation items *\/}\n            <div className=\"flex flex-col justify-center bg-card p-4 md:col-span-7\">\n                <div className=\"space-y-1\">\n                    {items.map((item) => (\n                        <div\n                            key={item.id}\n                            onMouseEnter={() => setActiveId(item.id)}\n                            className={cn(\n                                'relative flex cursor-pointer items-center justify-between rounded-lg p-3 transition-colors select-none',\n                                activeId === item.id\n                                    ? 'bg-muted text-foreground'\n                                    : 'text-muted-foreground hover:bg-muted\/40',\n                            )}\n                        >\n                            <div className=\"space-y-0.5\">\n                                <span className=\"text-sm font-bold text-foreground\">\n                                    {item.label}\n                                <\/span>\n                                <p className=\"line-clamp-1 text-xs text-muted-foreground\">\n                                    {item.details}\n                                <\/p>\n                            <\/div>\n                            {activeId === item.id && (\n                                <motion.div\n                                    layoutId=\"activeIndicator\"\n                                    className=\"absolute right-3 size-2 rounded-full\"\n                                    style={{\n                                        backgroundColor: item.previewColor,\n                                    }}\n                                \/>\n                            )}\n                        <\/div>\n                    ))}\n                <\/div>\n            <\/div>\n        <\/Card>\n    );\n});\n\nSplitPreviewCard.displayName = 'SplitPreviewCard';\n\nexport { SplitPreviewCard };\nexport default SplitPreviewCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"tilt-card","type":"registry:ui","title":"Tilt Card","description":"A 3D perspective tilting card that follows the user's cursor with a dynamic lighting glare layer.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/cards\/tilt-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nexport interface TiltCardProps extends React.ComponentProps<typeof Card> {\n    maxTilt?: number;\n    perspective?: number;\n    scale?: number;\n    glareOpacity?: number;\n}\n\nconst TiltCard = React.forwardRef<HTMLDivElement, TiltCardProps>(\n    (\n        {\n            className,\n            children,\n            maxTilt = 15,\n            perspective = 1000,\n            scale = 1.02,\n            glareOpacity = 0.15,\n            ...props\n        },\n        ref,\n    ) => {\n        const localRef = React.useRef<HTMLDivElement>(null);\n        const resolvedRef = (ref ||\n            localRef) as React.RefObject<HTMLDivElement | null>;\n        const [style, setStyle] = React.useState<React.CSSProperties>({});\n        const [glareStyle, setGlareStyle] = React.useState<React.CSSProperties>(\n            { opacity: 0 },\n        );\n\n        const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n            const card = resolvedRef.current;\n            if (!card) return;\n\n            const rect = card.getBoundingClientRect();\n            const width = rect.width;\n            const height = rect.height;\n\n            const mouseX = e.clientX - rect.left - width \/ 2;\n            const mouseY = e.clientY - rect.top - height \/ 2;\n\n            const rotateX = ((-mouseY \/ (height \/ 2)) * maxTilt).toFixed(2);\n            const rotateY = ((mouseX \/ (width \/ 2)) * maxTilt).toFixed(2);\n\n            setStyle({\n                transform: `perspective(${perspective}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale3d(${scale}, ${scale}, ${scale})`,\n                transition: 'transform 0.1s cubic-bezier(0.25, 1, 0.5, 1)',\n            });\n\n            \/\/ Calculate position for glare\n            const glareX = ((e.clientX - rect.left) \/ width) * 100;\n            const glareY = ((e.clientY - rect.top) \/ height) * 100;\n\n            setGlareStyle({\n                background: `radial-gradient(circle at ${glareX}% ${glareY}%, rgba(255, 255, 255, ${glareOpacity}), transparent 60%)`,\n                opacity: 1,\n            });\n        };\n\n        const handleMouseLeave = () => {\n            setStyle({\n                transform: `perspective(${perspective}px) rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)`,\n                transition: 'transform 0.5s cubic-bezier(0.25, 1, 0.5, 1)',\n            });\n            setGlareStyle({\n                opacity: 0,\n                transition: 'opacity 0.5s cubic-bezier(0.25, 1, 0.5, 1)',\n            });\n        };\n\n        return (\n            <Card\n                ref={resolvedRef}\n                onMouseMove={handleMouseMove}\n                onMouseLeave={handleMouseLeave}\n                style={style}\n                className={cn(\n                    'relative overflow-hidden bg-card\/60 p-6 backdrop-blur-xs select-none',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Glare effect layer *\/}\n                <div\n                    className=\"pointer-events-none absolute inset-0 -z-10 transition-opacity\"\n                    style={glareStyle}\n                \/>\n                {children}\n            <\/Card>\n        );\n    },\n);\n\nTiltCard.displayName = 'TiltCard';\n\nexport { TiltCard };\nexport default TiltCard;\n"}],"meta":{"category":"cards","version":"1.0.0"},"categories":["cards"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"carousel-3d","type":"registry:ui","title":"Carousel 3D","description":"A premium 3D Coverflow slider using Swiper with rotation and depth adjustments.","author":"designbycode","dependencies":["lucide-react","swiper"],"devDependencies":[],"registryDependencies":["button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/carousels\/carousel-3d.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport type { Swiper as SwiperClass } from 'swiper';\nimport { Autoplay, EffectCoverflow } from 'swiper\/modules';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\nimport 'swiper\/css';\nimport 'swiper\/css\/effect-coverflow';\n\ninterface Carousel3dProps {\n    items: React.ReactNode[];\n    autoplay?: boolean;\n    autoplayDelay?: number;\n    className?: string;\n}\n\nexport function Carousel3d({\n    items,\n    autoplay = true,\n    autoplayDelay = 3000,\n    className,\n}: Carousel3dProps) {\n    const [swiper, setSwiper] = React.useState<SwiperClass | null>(null);\n    const [activeIndex, setActiveIndex] = React.useState(0);\n\n    return (\n        <div className={cn('relative w-full space-y-6', className)}>\n            <div className=\"relative overflow-hidden py-4\">\n                <Swiper\n                    modules={[Autoplay, EffectCoverflow]}\n                    effect=\"coverflow\"\n                    grabCursor={true}\n                    centeredSlides={true}\n                    slidesPerView=\"auto\"\n                    coverflowEffect={{\n                        rotate: 35,\n                        stretch: 0,\n                        depth: 160,\n                        modifier: 1,\n                        slideShadows: false,\n                    }}\n                    onSwiper={setSwiper}\n                    onSlideChange={(s) => setActiveIndex(s.realIndex)}\n                    autoplay={\n                        autoplay\n                            ? {\n                                  delay: autoplayDelay,\n                                  disableOnInteraction: false,\n                              }\n                            : false\n                    }\n                    loop={true}\n                    className=\"w-full max-w-3xl\"\n                >\n                    {items.map((item, idx) => (\n                        <SwiperSlide\n                            key={idx}\n                            className=\"w-[280px] sm:w-[320px]\"\n                        >\n                            <div className=\"h-full w-full select-none\">\n                                {item}\n                            <\/div>\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n            <\/div>\n\n            {\/* Controls *\/}\n            <div className=\"flex items-center justify-between px-2 select-none\">\n                <div className=\"flex gap-1.5\">\n                    {items.map((_, idx) => (\n                        <button\n                            key={idx}\n                            onClick={() => swiper?.slideToLoop(idx)}\n                            className={cn(\n                                'h-1.5 cursor-pointer rounded-full transition-all duration-300',\n                                activeIndex === idx\n                                    ? 'w-6 bg-primary'\n                                    : 'w-1.5 bg-muted-foreground\/30 hover:bg-muted-foreground\/60',\n                            )}\n                            aria-label={`Go to slide ${idx + 1}`}\n                        \/>\n                    ))}\n                <\/div>\n                <div className=\"flex gap-2\">\n                    <Button\n                        onClick={() => swiper?.slidePrev()}\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    >\n                        <ChevronLeft className=\"size-4\" \/>\n                    <\/Button>\n                    <Button\n                        onClick={() => swiper?.slideNext()}\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    >\n                        <ChevronRight className=\"size-4\" \/>\n                    <\/Button>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default Carousel3d;\n"}],"meta":{"category":"carousels","version":"1.0.0"},"categories":["carousels"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"carousel-auto-scroll","type":"registry:ui","title":"Carousel Auto Scroll","description":"A continuous linear auto-scrolling carousel (logo wall \/ infinite ticker tape effect).","author":"designbycode","dependencies":["swiper"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/carousels\/carousel-auto-scroll.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport { Autoplay } from 'swiper\/modules';\nimport { cn } from '@\/lib\/utils';\n\nimport 'swiper\/css';\n\ninterface CarouselAutoScrollProps {\n    items: React.ReactNode[];\n    speed?: number;\n    spaceBetween?: number;\n    className?: string;\n    pauseOnHover?: boolean;\n}\n\nexport function CarouselAutoScroll({\n    items,\n    speed = 3000,\n    spaceBetween = 20,\n    className,\n    pauseOnHover = true,\n}: CarouselAutoScrollProps) {\n    return (\n        <div\n            className={cn(\n                'relative w-full overflow-hidden rounded-xl border border-border\/40 bg-card\/15 py-4',\n                className,\n            )}\n        >\n            <Swiper\n                modules={[Autoplay]}\n                speed={speed}\n                autoplay={{\n                    delay: 0,\n                    disableOnInteraction: false,\n                    pauseOnMouseEnter: pauseOnHover,\n                }}\n                loop={true}\n                allowTouchMove={true}\n                slidesPerView=\"auto\"\n                spaceBetween={spaceBetween}\n                className=\"[&>.swiper-wrapper]:!transition-timing-function-[linear] w-full [&>.swiper-wrapper]:!ease-linear\"\n            >\n                {items.map((item, idx) => (\n                    <SwiperSlide\n                        key={idx}\n                        className=\"flex w-auto items-center justify-center\"\n                    >\n                        <div className=\"shrink-0 select-none\">{item}<\/div>\n                    <\/SwiperSlide>\n                ))}\n            <\/Swiper>\n        <\/div>\n    );\n}\n\nexport default CarouselAutoScroll;\n"}],"meta":{"category":"carousels","version":"1.0.0"},"categories":["carousels"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"carousel-basic","type":"registry:ui","title":"Carousel Basic","description":"A basic, fully responsive card\/item carousel using Swiper with custom external controls.","author":"designbycode","dependencies":["lucide-react","swiper"],"devDependencies":[],"registryDependencies":["button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/carousels\/carousel-basic.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport type { Swiper as SwiperClass } from 'swiper';\nimport { Autoplay, Pagination } from 'swiper\/modules';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\nimport 'swiper\/css';\n\ninterface CarouselBasicProps {\n    items: React.ReactNode[];\n    autoplay?: boolean;\n    autoplayDelay?: number;\n    loop?: boolean;\n    slidesPerView?: number;\n    spaceBetween?: number;\n    className?: string;\n}\n\nexport function CarouselBasic({\n    items,\n    autoplay = true,\n    autoplayDelay = 3000,\n    loop = true,\n    slidesPerView = 3,\n    spaceBetween = 20,\n    className,\n}: CarouselBasicProps) {\n    const [swiper, setSwiper] = React.useState<SwiperClass | null>(null);\n    const [activeIndex, setActiveIndex] = React.useState(0);\n\n    return (\n        <div className={cn('relative w-full space-y-4', className)}>\n            <div className=\"relative overflow-hidden rounded-xl border border-border\/40 bg-card\/15 p-4.5\">\n                <Swiper\n                    modules={[Autoplay, Pagination]}\n                    onSwiper={setSwiper}\n                    onSlideChange={(s) => setActiveIndex(s.realIndex)}\n                    autoplay={\n                        autoplay\n                            ? {\n                                  delay: autoplayDelay,\n                                  disableOnInteraction: false,\n                              }\n                            : false\n                    }\n                    loop={loop}\n                    spaceBetween={spaceBetween}\n                    slidesPerView={1}\n                    breakpoints={{\n                        640: { slidesPerView: Math.min(2, slidesPerView) },\n                        1024: { slidesPerView: slidesPerView },\n                    }}\n                    className=\"w-full\"\n                >\n                    {items.map((item, idx) => (\n                        <SwiperSlide key={idx} className=\"h-auto\">\n                            <div className=\"h-full w-full select-none\">\n                                {item}\n                            <\/div>\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n            <\/div>\n\n            {\/* Controls *\/}\n            <div className=\"flex items-center justify-between px-2 select-none\">\n                <div className=\"flex gap-1.5\">\n                    {items.map((_, idx) => (\n                        <button\n                            key={idx}\n                            onClick={() => swiper?.slideToLoop(idx)}\n                            className={cn(\n                                'h-1.5 cursor-pointer rounded-full transition-all duration-300',\n                                activeIndex === idx\n                                    ? 'w-6 bg-primary'\n                                    : 'w-1.5 bg-muted-foreground\/30 hover:bg-muted-foreground\/60',\n                            )}\n                            aria-label={`Go to slide ${idx + 1}`}\n                        \/>\n                    ))}\n                <\/div>\n                <div className=\"flex gap-2\">\n                    <Button\n                        onClick={() => swiper?.slidePrev()}\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    >\n                        <ChevronLeft className=\"size-4\" \/>\n                    <\/Button>\n                    <Button\n                        onClick={() => swiper?.slideNext()}\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    >\n                        <ChevronRight className=\"size-4\" \/>\n                    <\/Button>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default CarouselBasic;\n"}],"meta":{"category":"carousels","version":"1.0.0"},"categories":["carousels"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"carousel-cards","type":"registry:ui","title":"Carousel Cards","description":"A stacked card deck slider using Swiper EffectCards module.","author":"designbycode","dependencies":["lucide-react","swiper"],"devDependencies":[],"registryDependencies":["button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/carousels\/carousel-cards.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport type { Swiper as SwiperClass } from 'swiper';\nimport { Autoplay, EffectCards } from 'swiper\/modules';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\nimport 'swiper\/css';\nimport 'swiper\/css\/effect-cards';\n\ninterface CarouselCardsProps {\n    items: React.ReactNode[];\n    autoplay?: boolean;\n    autoplayDelay?: number;\n    className?: string;\n}\n\nexport function CarouselCards({\n    items,\n    autoplay = true,\n    autoplayDelay = 3000,\n    className,\n}: CarouselCardsProps) {\n    const [swiper, setSwiper] = React.useState<SwiperClass | null>(null);\n\n    return (\n        <div\n            className={cn(\n                'relative flex flex-col items-center gap-4',\n                className,\n            )}\n        >\n            <div className=\"w-full max-w-[280px] py-4 sm:max-w-[320px]\">\n                <Swiper\n                    modules={[Autoplay, EffectCards]}\n                    effect=\"cards\"\n                    grabCursor={true}\n                    onSwiper={setSwiper}\n                    autoplay={\n                        autoplay\n                            ? {\n                                  delay: autoplayDelay,\n                                  disableOnInteraction: false,\n                              }\n                            : false\n                    }\n                    loop={true}\n                    className=\"aspect-3\/4 w-full\"\n                >\n                    {items.map((item, idx) => (\n                        <SwiperSlide\n                            key={idx}\n                            className=\"overflow-hidden rounded-xl border border-border\/40 shadow-lg\"\n                        >\n                            <div className=\"h-full w-full select-none\">\n                                {item}\n                            <\/div>\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n            <\/div>\n\n            {\/* Navigation Controls *\/}\n            <div className=\"flex gap-2 select-none\">\n                <Button\n                    onClick={() => swiper?.slidePrev()}\n                    variant=\"outline\"\n                    size=\"icon\"\n                    className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                >\n                    <ChevronLeft className=\"size-4\" \/>\n                <\/Button>\n                <Button\n                    onClick={() => swiper?.slideNext()}\n                    variant=\"outline\"\n                    size=\"icon\"\n                    className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                >\n                    <ChevronRight className=\"size-4\" \/>\n                <\/Button>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default CarouselCards;\n"}],"meta":{"category":"carousels","version":"1.0.0"},"categories":["carousels"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"carousel-creative","type":"registry:ui","title":"Carousel Creative","description":"A creative-transition slider using Swiper EffectCreative module.","author":"designbycode","dependencies":["lucide-react","swiper"],"devDependencies":[],"registryDependencies":["button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/carousels\/carousel-creative.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport type { Swiper as SwiperClass } from 'swiper';\nimport { Autoplay, EffectCreative } from 'swiper\/modules';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\nimport 'swiper\/css';\nimport 'swiper\/css\/effect-creative';\n\ninterface CarouselCreativeProps {\n    items: React.ReactNode[];\n    autoplay?: boolean;\n    autoplayDelay?: number;\n    className?: string;\n}\n\nexport function CarouselCreative({\n    items,\n    autoplay = true,\n    autoplayDelay = 3500,\n    className,\n}: CarouselCreativeProps) {\n    const [swiper, setSwiper] = React.useState<SwiperClass | null>(null);\n    const [activeIndex, setActiveIndex] = React.useState(0);\n\n    return (\n        <div className={cn('relative w-full space-y-4', className)}>\n            <div className=\"relative overflow-hidden rounded-xl border border-border\/40 bg-card\/15 p-4\">\n                <Swiper\n                    modules={[Autoplay, EffectCreative]}\n                    effect=\"creative\"\n                    grabCursor={true}\n                    creativeEffect={{\n                        prev: {\n                            shadow: true,\n                            translate: ['-20%', 0, -1],\n                        },\n                        next: {\n                            translate: ['100%', 0, 0],\n                        },\n                    }}\n                    onSwiper={setSwiper}\n                    onSlideChange={(s) => setActiveIndex(s.realIndex)}\n                    autoplay={\n                        autoplay\n                            ? {\n                                  delay: autoplayDelay,\n                                  disableOnInteraction: false,\n                              }\n                            : false\n                    }\n                    loop={true}\n                    slidesPerView={1}\n                    className=\"w-full\"\n                >\n                    {items.map((item, idx) => (\n                        <SwiperSlide key={idx} className=\"h-auto\">\n                            <div className=\"h-full w-full select-none\">\n                                {item}\n                            <\/div>\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n            <\/div>\n\n            {\/* Controls *\/}\n            <div className=\"flex items-center justify-between px-2 select-none\">\n                <div className=\"flex gap-1.5\">\n                    {items.map((_, idx) => (\n                        <button\n                            key={idx}\n                            onClick={() => swiper?.slideToLoop(idx)}\n                            className={cn(\n                                'h-1.5 cursor-pointer rounded-full transition-all duration-300',\n                                activeIndex === idx\n                                    ? 'w-6 bg-primary'\n                                    : 'w-1.5 bg-muted-foreground\/30 hover:bg-muted-foreground\/60',\n                            )}\n                            aria-label={`Go to slide ${idx + 1}`}\n                        \/>\n                    ))}\n                <\/div>\n                <div className=\"flex gap-2\">\n                    <Button\n                        onClick={() => swiper?.slidePrev()}\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    >\n                        <ChevronLeft className=\"size-4\" \/>\n                    <\/Button>\n                    <Button\n                        onClick={() => swiper?.slideNext()}\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    >\n                        <ChevronRight className=\"size-4\" \/>\n                    <\/Button>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default CarouselCreative;\n"}],"meta":{"category":"carousels","version":"1.0.0"},"categories":["carousels"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"carousel-fade","type":"registry:ui","title":"Carousel Fade","description":"A cross-fade carousel using Swiper for premium and smooth transition effects.","author":"designbycode","dependencies":["lucide-react","swiper"],"devDependencies":[],"registryDependencies":["button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/carousels\/carousel-fade.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport type { Swiper as SwiperClass } from 'swiper';\nimport { Autoplay, EffectFade } from 'swiper\/modules';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\nimport 'swiper\/css';\nimport 'swiper\/css\/effect-fade';\n\ninterface CarouselFadeProps {\n    items: React.ReactNode[];\n    autoplay?: boolean;\n    autoplayDelay?: number;\n    className?: string;\n}\n\nexport function CarouselFade({\n    items,\n    autoplay = true,\n    autoplayDelay = 4000,\n    className,\n}: CarouselFadeProps) {\n    const [swiper, setSwiper] = React.useState<SwiperClass | null>(null);\n    const [activeIndex, setActiveIndex] = React.useState(0);\n\n    return (\n        <div className={cn('relative w-full space-y-4', className)}>\n            <div className=\"relative overflow-hidden rounded-xl border border-border\/40 bg-card\/15\">\n                <Swiper\n                    modules={[Autoplay, EffectFade]}\n                    effect=\"fade\"\n                    fadeEffect={{ crossFade: true }}\n                    onSwiper={setSwiper}\n                    onSlideChange={(s) => setActiveIndex(s.realIndex)}\n                    autoplay={\n                        autoplay\n                            ? {\n                                  delay: autoplayDelay,\n                                  disableOnInteraction: false,\n                              }\n                            : false\n                    }\n                    loop={true}\n                    slidesPerView={1}\n                    className=\"w-full\"\n                >\n                    {items.map((item, idx) => (\n                        <SwiperSlide key={idx} className=\"h-auto\">\n                            <div className=\"h-full w-full select-none\">\n                                {item}\n                            <\/div>\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n            <\/div>\n\n            {\/* Controls *\/}\n            <div className=\"flex items-center justify-between px-2 select-none\">\n                <div className=\"flex gap-1.5\">\n                    {items.map((_, idx) => (\n                        <button\n                            key={idx}\n                            onClick={() => swiper?.slideToLoop(idx)}\n                            className={cn(\n                                'h-1.5 cursor-pointer rounded-full transition-all duration-300',\n                                activeIndex === idx\n                                    ? 'w-6 bg-primary'\n                                    : 'w-1.5 bg-muted-foreground\/30 hover:bg-muted-foreground\/60',\n                            )}\n                            aria-label={`Go to slide ${idx + 1}`}\n                        \/>\n                    ))}\n                <\/div>\n                <div className=\"flex gap-2\">\n                    <Button\n                        onClick={() => swiper?.slidePrev()}\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    >\n                        <ChevronLeft className=\"size-4\" \/>\n                    <\/Button>\n                    <Button\n                        onClick={() => swiper?.slideNext()}\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    >\n                        <ChevronRight className=\"size-4\" \/>\n                    <\/Button>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default CarouselFade;\n"}],"meta":{"category":"carousels","version":"1.0.0"},"categories":["carousels"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"carousel-motion","type":"registry:ui","title":"Carousel Motion","description":"A physics-driven drag slider using motion\/react with spring animation effects.","author":"designbycode","dependencies":["lucide-react","motion"],"devDependencies":[],"registryDependencies":["button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/carousels\/carousel-motion.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { motion } from 'motion\/react';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\ninterface CarouselMotionProps {\n    items: React.ReactNode[];\n    className?: string;\n}\n\nexport function CarouselMotion({ items, className }: CarouselMotionProps) {\n    const containerRef = React.useRef<HTMLDivElement>(null);\n    const [width, setWidth] = React.useState(0);\n    const [position, setPosition] = React.useState(0);\n\n    React.useEffect(() => {\n        if (!containerRef.current) return;\n        const updateWidth = () => {\n            setWidth(\n                containerRef.current!.scrollWidth -\n                    containerRef.current!.offsetWidth,\n            );\n        };\n        updateWidth();\n        window.addEventListener('resize', updateWidth);\n        return () => window.removeEventListener('resize', updateWidth);\n    }, [items]);\n\n    const handlePrev = () => {\n        setPosition((prev) => Math.min(0, prev + 300));\n    };\n\n    const handleNext = () => {\n        setPosition((prev) => Math.max(-width, prev - 300));\n    };\n\n    return (\n        <div className={cn('relative w-full space-y-4', className)}>\n            <motion.div\n                ref={containerRef}\n                className=\"cursor-grab overflow-hidden rounded-xl border border-border\/40 bg-card\/15 p-4.5 active:cursor-grabbing\"\n            >\n                <motion.div\n                    drag=\"x\"\n                    dragConstraints={{ right: 0, left: -width }}\n                    dragElastic={0.15}\n                    animate={{ x: position }}\n                    transition={{ type: 'spring', damping: 25, stiffness: 180 }}\n                    onDragEnd={(_, info) => {\n                        const targetX = Math.max(\n                            -width,\n                            Math.min(0, position + info.offset.x),\n                        );\n                        setPosition(targetX);\n                    }}\n                    className=\"flex w-max gap-4\"\n                >\n                    {items.map((item, idx) => (\n                        <div\n                            key={idx}\n                            className=\"w-[260px] shrink-0 select-none sm:w-[300px]\"\n                        >\n                            {item}\n                        <\/div>\n                    ))}\n                <\/motion.div>\n            <\/motion.div>\n\n            {\/* Controls *\/}\n            <div className=\"flex justify-end gap-2 px-2 select-none\">\n                <Button\n                    onClick={handlePrev}\n                    variant=\"outline\"\n                    size=\"icon\"\n                    disabled={position >= 0}\n                    className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted disabled:opacity-40\"\n                >\n                    <ChevronLeft className=\"size-4\" \/>\n                <\/Button>\n                <Button\n                    onClick={handleNext}\n                    variant=\"outline\"\n                    size=\"icon\"\n                    disabled={position <= -width}\n                    className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted disabled:opacity-40\"\n                >\n                    <ChevronRight className=\"size-4\" \/>\n                <\/Button>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default CarouselMotion;\n"}],"meta":{"category":"carousels","version":"1.0.0"},"categories":["carousels"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"carousel-scale","type":"registry:ui","title":"Carousel Scale","description":"A center-scale focus slider using Swiper with custom responsive viewports.","author":"designbycode","dependencies":["lucide-react","swiper"],"devDependencies":[],"registryDependencies":["button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/carousels\/carousel-scale.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport type { Swiper as SwiperClass } from 'swiper';\nimport { Autoplay, Pagination } from 'swiper\/modules';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\nimport 'swiper\/css';\n\ninterface CarouselScaleProps {\n    items: React.ReactNode[];\n    autoplay?: boolean;\n    autoplayDelay?: number;\n    className?: string;\n}\n\nexport function CarouselScale({\n    items,\n    autoplay = true,\n    autoplayDelay = 3000,\n    className,\n}: CarouselScaleProps) {\n    const [swiper, setSwiper] = React.useState<SwiperClass | null>(null);\n    const [activeIndex, setActiveIndex] = React.useState(0);\n\n    return (\n        <div className={cn('relative w-full space-y-6', className)}>\n            <div className=\"relative overflow-hidden py-4\">\n                <Swiper\n                    modules={[Autoplay, Pagination]}\n                    centeredSlides={true}\n                    slidesPerView={1.5}\n                    spaceBetween={16}\n                    onSwiper={setSwiper}\n                    onSlideChange={(s) => setActiveIndex(s.realIndex)}\n                    autoplay={\n                        autoplay\n                            ? {\n                                  delay: autoplayDelay,\n                                  disableOnInteraction: false,\n                              }\n                            : false\n                    }\n                    loop={true}\n                    breakpoints={{\n                        640: { slidesPerView: 2.2, spaceBetween: 24 },\n                        1024: { slidesPerView: 3, spaceBetween: 30 },\n                    }}\n                    className=\"w-full\"\n                >\n                    {items.map((item, idx) => (\n                        <SwiperSlide key={idx} className=\"h-auto\">\n                            {({ isActive }) => (\n                                <div\n                                    className={cn(\n                                        'h-full w-full transform transition-all duration-500 ease-out select-none',\n                                        isActive\n                                            ? 'scale-100 opacity-100 shadow-md'\n                                            : 'scale-85 opacity-40 blur-[0.5px]',\n                                    )}\n                                >\n                                    {item}\n                                <\/div>\n                            )}\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n            <\/div>\n\n            {\/* Controls *\/}\n            <div className=\"flex items-center justify-between px-2 select-none\">\n                <div className=\"flex gap-1.5\">\n                    {items.map((_, idx) => (\n                        <button\n                            key={idx}\n                            onClick={() => swiper?.slideToLoop(idx)}\n                            className={cn(\n                                'h-1.5 cursor-pointer rounded-full transition-all duration-300',\n                                activeIndex === idx\n                                    ? 'w-6 bg-primary'\n                                    : 'w-1.5 bg-muted-foreground\/30 hover:bg-muted-foreground\/60',\n                            )}\n                            aria-label={`Go to slide ${idx + 1}`}\n                        \/>\n                    ))}\n                <\/div>\n                <div className=\"flex gap-2\">\n                    <Button\n                        onClick={() => swiper?.slidePrev()}\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    >\n                        <ChevronLeft className=\"size-4\" \/>\n                    <\/Button>\n                    <Button\n                        onClick={() => swiper?.slideNext()}\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    >\n                        <ChevronRight className=\"size-4\" \/>\n                    <\/Button>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default CarouselScale;\n"}],"meta":{"category":"carousels","version":"1.0.0"},"categories":["carousels"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"carousel-thumbs","type":"registry:ui","title":"Carousel Thumbs","description":"A thumbnail slider using Swiper with double slide controllers and sync updates.","author":"designbycode","dependencies":["lucide-react","swiper"],"devDependencies":[],"registryDependencies":["button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/carousels\/carousel-thumbs.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport type { Swiper as SwiperClass } from 'swiper';\nimport { Thumbs, FreeMode } from 'swiper\/modules';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\nimport 'swiper\/css';\nimport 'swiper\/css\/thumbs';\nimport 'swiper\/css\/free-mode';\n\ninterface CarouselThumbsProps {\n    items: React.ReactNode[];\n    thumbnails: React.ReactNode[];\n    className?: string;\n}\n\nexport function CarouselThumbs({\n    items,\n    thumbnails,\n    className,\n}: CarouselThumbsProps) {\n    const [mainSwiper, setMainSwiper] = React.useState<SwiperClass | null>(\n        null,\n    );\n    const [thumbsSwiper, setThumbsSwiper] = React.useState<any>(null);\n    const [activeIndex, setActiveIndex] = React.useState(0);\n\n    return (\n        <div className={cn('w-full space-y-4', className)}>\n            {\/* Main Swiper Slider *\/}\n            <div className=\"relative overflow-hidden rounded-xl border border-border\/40 bg-card\/15 p-4\">\n                <Swiper\n                    modules={[Thumbs, FreeMode]}\n                    thumbs={{\n                        swiper:\n                            thumbsSwiper && !thumbsSwiper.destroyed\n                                ? thumbsSwiper\n                                : null,\n                    }}\n                    onSwiper={setMainSwiper}\n                    onSlideChange={(s) => setActiveIndex(s.activeIndex)}\n                    spaceBetween={10}\n                    slidesPerView={1}\n                    className=\"w-full\"\n                >\n                    {items.map((item, idx) => (\n                        <SwiperSlide key={idx} className=\"h-auto\">\n                            <div className=\"h-full w-full select-none\">\n                                {item}\n                            <\/div>\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n\n                {\/* Left\/Right Arrows *\/}\n                <Button\n                    onClick={() => mainSwiper?.slidePrev()}\n                    variant=\"outline\"\n                    size=\"icon\"\n                    className=\"absolute top-1\/2 left-6 z-10 size-8 -translate-y-1\/2 rounded-full border-border\/40 bg-background\/80 shadow-sm backdrop-blur-xs hover:bg-muted\"\n                >\n                    <ChevronLeft className=\"size-4\" \/>\n                <\/Button>\n                <Button\n                    onClick={() => mainSwiper?.slideNext()}\n                    variant=\"outline\"\n                    size=\"icon\"\n                    className=\"absolute top-1\/2 right-6 z-10 size-8 -translate-y-1\/2 rounded-full border-border\/40 bg-background\/80 shadow-sm backdrop-blur-xs hover:bg-muted\"\n                >\n                    <ChevronRight className=\"size-4\" \/>\n                <\/Button>\n            <\/div>\n\n            {\/* Thumbnail Navigation Slider *\/}\n            <div className=\"px-2\">\n                <Swiper\n                    onSwiper={setThumbsSwiper}\n                    spaceBetween={10}\n                    slidesPerView={4}\n                    freeMode={true}\n                    watchSlidesProgress={true}\n                    modules={[Thumbs, FreeMode]}\n                    className=\"w-full cursor-pointer select-none\"\n                    breakpoints={{\n                        640: { slidesPerView: Math.min(6, thumbnails.length) },\n                    }}\n                >\n                    {thumbnails.map((thumb, idx) => (\n                        <SwiperSlide key={idx}>\n                            <div\n                                className={cn(\n                                    'overflow-hidden rounded-lg border-2 transition-all duration-300',\n                                    activeIndex === idx\n                                        ? 'scale-95 border-primary bg-primary\/5 shadow-sm'\n                                        : 'border-border\/30 hover:border-border\/80',\n                                )}\n                            >\n                                {thumb}\n                            <\/div>\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default CarouselThumbs;\n"}],"meta":{"category":"carousels","version":"1.0.0"},"categories":["carousels"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"carousel-vertical","type":"registry:ui","title":"Carousel Vertical","description":"A vertical layout card slider using Swiper.","author":"designbycode","dependencies":["lucide-react","swiper"],"devDependencies":[],"registryDependencies":["button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/carousels\/carousel-vertical.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { ChevronUp, ChevronDown } from 'lucide-react';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport type { Swiper as SwiperClass } from 'swiper';\nimport { Autoplay, Pagination } from 'swiper\/modules';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\nimport 'swiper\/css';\nimport 'swiper\/css\/pagination';\n\ninterface CarouselVerticalProps {\n    items: React.ReactNode[];\n    autoplay?: boolean;\n    autoplayDelay?: number;\n    className?: string;\n    height?: string;\n}\n\nexport function CarouselVertical({\n    items,\n    autoplay = true,\n    autoplayDelay = 3000,\n    className,\n    height = '240px',\n}: CarouselVerticalProps) {\n    const [swiper, setSwiper] = React.useState<SwiperClass | null>(null);\n    const [activeIndex, setActiveIndex] = React.useState(0);\n\n    return (\n        <div\n            className={cn(\n                'relative flex w-full items-center justify-center gap-4',\n                className,\n            )}\n        >\n            {\/* Slider container with constrained height *\/}\n            <div\n                style={{ height }}\n                className=\"relative flex-1 overflow-hidden rounded-xl border border-border\/40 bg-card\/15 p-4\"\n            >\n                <Swiper\n                    modules={[Autoplay, Pagination]}\n                    direction=\"vertical\"\n                    onSwiper={setSwiper}\n                    onSlideChange={(s) => setActiveIndex(s.realIndex)}\n                    autoplay={\n                        autoplay\n                            ? {\n                                  delay: autoplayDelay,\n                                  disableOnInteraction: false,\n                              }\n                            : false\n                    }\n                    loop={true}\n                    slidesPerView={1}\n                    className=\"h-full w-full\"\n                >\n                    {items.map((item, idx) => (\n                        <SwiperSlide key={idx} className=\"h-full\">\n                            <div className=\"h-full w-full select-none\">\n                                {item}\n                            <\/div>\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n            <\/div>\n\n            {\/* Vertical Controls and Pagination *\/}\n            <div className=\"flex flex-col items-center gap-4 select-none\">\n                <Button\n                    onClick={() => swiper?.slidePrev()}\n                    variant=\"outline\"\n                    size=\"icon\"\n                    className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    aria-label=\"Previous slide\"\n                >\n                    <ChevronUp className=\"size-4\" \/>\n                <\/Button>\n\n                {\/* Vertical indicators *\/}\n                <div className=\"flex flex-col gap-2\">\n                    {items.map((_, idx) => (\n                        <button\n                            key={idx}\n                            onClick={() => swiper?.slideToLoop(idx)}\n                            className={cn(\n                                'w-1.5 cursor-pointer rounded-full transition-all duration-300',\n                                activeIndex === idx\n                                    ? 'h-6 bg-primary'\n                                    : 'h-1.5 bg-muted-foreground\/30 hover:bg-muted-foreground\/60',\n                            )}\n                            aria-label={`Go to slide ${idx + 1}`}\n                        \/>\n                    ))}\n                <\/div>\n\n                <Button\n                    onClick={() => swiper?.slideNext()}\n                    variant=\"outline\"\n                    size=\"icon\"\n                    className=\"size-8 cursor-pointer rounded-full border-border\/40 hover:bg-muted\"\n                    aria-label=\"Next slide\"\n                >\n                    <ChevronDown className=\"size-4\" \/>\n                <\/Button>\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default CarouselVertical;\n"}],"meta":{"category":"carousels","version":"1.0.0"},"categories":["carousels"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"comparison-slider-basic","type":"registry:ui","title":"Comparison Slider Basic","description":"A premium horizontal before\/after image comparison slider with an interactive drag handle.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/comparison-sliders\/comparison-slider-basic.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { ChevronsLeftRight } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\n\ninterface ComparisonSliderBasicProps extends React.HTMLAttributes<HTMLDivElement> {\n    beforeImage: string;\n    afterImage: string;\n    beforeLabel?: string;\n    afterLabel?: string;\n    defaultPosition?: number;\n    aspectRatio?: 'video' | 'square' | 'wide' | 'auto';\n}\n\nexport function ComparisonSliderBasic({\n    beforeImage,\n    afterImage,\n    beforeLabel = 'Before',\n    afterLabel = 'After',\n    defaultPosition = 50,\n    aspectRatio = 'video',\n    className,\n    ...props\n}: ComparisonSliderBasicProps) {\n    const [sliderPosition, setSliderPosition] = React.useState(defaultPosition);\n    const [isDragging, setIsDragging] = React.useState(false);\n    const containerRef = React.useRef<HTMLDivElement>(null);\n\n    const handleMove = (clientX: number) => {\n        if (!containerRef.current) return;\n        const rect = containerRef.current.getBoundingClientRect();\n        const x = clientX - rect.left;\n        const position = Math.max(0, Math.min(100, (x \/ rect.width) * 100));\n        setSliderPosition(position);\n    };\n\n    const handleTouchMove = (e: TouchEvent) => {\n        if (!isDragging) return;\n        handleMove(e.touches[0].clientX);\n    };\n\n    const handleMouseMove = (e: MouseEvent) => {\n        if (!isDragging) return;\n        handleMove(e.clientX);\n    };\n\n    const handleMouseUp = () => {\n        setIsDragging(false);\n    };\n\n    React.useEffect(() => {\n        if (isDragging) {\n            window.addEventListener('mousemove', handleMouseMove);\n            window.addEventListener('mouseup', handleMouseUp);\n            window.addEventListener('touchmove', handleTouchMove);\n            window.addEventListener('touchend', handleMouseUp);\n        }\n\n        return () => {\n            window.removeEventListener('mousemove', handleMouseMove);\n            window.removeEventListener('mouseup', handleMouseUp);\n            window.removeEventListener('touchmove', handleTouchMove);\n            window.removeEventListener('touchend', handleMouseUp);\n        };\n    }, [isDragging]);\n\n    const handleMouseDown = (e: React.MouseEvent) => {\n        e.preventDefault();\n        setIsDragging(true);\n        if (containerRef.current) {\n            const rect = containerRef.current.getBoundingClientRect();\n            const x = e.clientX - rect.left;\n            setSliderPosition(\n                Math.max(0, Math.min(100, (x \/ rect.width) * 100)),\n            );\n        }\n    };\n\n    const handleTouchStart = (e: React.TouchEvent) => {\n        setIsDragging(true);\n        if (containerRef.current) {\n            const rect = containerRef.current.getBoundingClientRect();\n            const x = e.touches[0].clientX - rect.left;\n            setSliderPosition(\n                Math.max(0, Math.min(100, (x \/ rect.width) * 100)),\n            );\n        }\n    };\n\n    const aspectClasses = {\n        video: 'aspect-video',\n        square: 'aspect-square',\n        wide: 'aspect-21\/9',\n        auto: 'h-full w-full',\n    };\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(\n                'relative overflow-hidden rounded-xl border border-border bg-muted shadow-lg select-none',\n                aspectClasses[aspectRatio],\n                className,\n            )}\n            onMouseDown={handleMouseDown}\n            onTouchStart={handleTouchStart}\n            {...props}\n        >\n            {\/* After Image (Base) *\/}\n            <img\n                src={afterImage}\n                alt=\"After\"\n                className=\"pointer-events-none absolute inset-0 size-full object-cover\"\n            \/>\n\n            {\/* After Label *\/}\n            {afterLabel && (\n                <div className=\"absolute right-4 bottom-4 z-10 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\">\n                    {afterLabel}\n                <\/div>\n            )}\n\n            {\/* Before Image (Clipped overlay) *\/}\n            <div\n                className=\"pointer-events-none absolute inset-0 size-full\"\n                style={{\n                    clipPath: `polygon(0 0, ${sliderPosition}% 0, ${sliderPosition}% 100%, 0 100%)`,\n                }}\n            >\n                <img\n                    src={beforeImage}\n                    alt=\"Before\"\n                    className=\"absolute inset-0 size-full object-cover\"\n                \/>\n            <\/div>\n\n            {\/* Before Label *\/}\n            {beforeLabel && (\n                <div\n                    className=\"absolute bottom-4 left-4 z-10 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\"\n                    style={{\n                        opacity: sliderPosition < 15 ? 0 : 1,\n                    }}\n                >\n                    {beforeLabel}\n                <\/div>\n            )}\n\n            {\/* Slider Line & Handle *\/}\n            <div\n                className=\"absolute top-0 bottom-0 z-20 w-0.5 cursor-ew-resize bg-background\/85 transition-colors hover:bg-background\/95\"\n                style={{ left: `${sliderPosition}%` }}\n            >\n                <div\n                    className={cn(\n                        'absolute top-1\/2 flex size-9 -translate-x-1\/2 -translate-y-1\/2 items-center justify-center rounded-full border border-border bg-background shadow-md transition-transform duration-200 select-none',\n                        isDragging && 'scale-110 border-primary',\n                    )}\n                >\n                    <ChevronsLeftRight className=\"size-4 text-muted-foreground\" \/>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"comparison-sliders","version":"1.0.0"},"categories":["comparison-sliders"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"comparison-slider-diagonal","type":"registry:ui","title":"Comparison Slider Diagonal","description":"A diagonal split before\/after image comparison slider using responsive clip paths.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/comparison-sliders\/comparison-slider-diagonal.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { ChevronsLeftRight } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\n\ninterface ComparisonSliderDiagonalProps extends React.HTMLAttributes<HTMLDivElement> {\n    beforeImage: string;\n    afterImage: string;\n    beforeLabel?: string;\n    afterLabel?: string;\n    defaultPosition?: number;\n    aspectRatio?: 'video' | 'square' | 'wide' | 'auto';\n    maxSkew?: number; \/\/ percentage skew at center, default 8\n}\n\nexport function ComparisonSliderDiagonal({\n    beforeImage,\n    afterImage,\n    beforeLabel = 'Before',\n    afterLabel = 'After',\n    defaultPosition = 50,\n    aspectRatio = 'video',\n    maxSkew = 8,\n    className,\n    ...props\n}: ComparisonSliderDiagonalProps) {\n    const [sliderPosition, setSliderPosition] = React.useState(defaultPosition);\n    const [isDragging, setIsDragging] = React.useState(false);\n    const containerRef = React.useRef<HTMLDivElement>(null);\n\n    const handleMove = (clientX: number) => {\n        if (!containerRef.current) return;\n        const rect = containerRef.current.getBoundingClientRect();\n        const x = clientX - rect.left;\n        const position = Math.max(0, Math.min(100, (x \/ rect.width) * 100));\n        setSliderPosition(position);\n    };\n\n    const handleTouchMove = (e: TouchEvent) => {\n        if (!isDragging) return;\n        handleMove(e.touches[0].clientX);\n    };\n\n    const handleMouseMove = (e: MouseEvent) => {\n        if (!isDragging) return;\n        handleMove(e.clientX);\n    };\n\n    const handleMouseUp = () => {\n        setIsDragging(false);\n    };\n\n    React.useEffect(() => {\n        if (isDragging) {\n            window.addEventListener('mousemove', handleMouseMove);\n            window.addEventListener('mouseup', handleMouseUp);\n            window.addEventListener('touchmove', handleTouchMove);\n            window.addEventListener('touchend', handleMouseUp);\n        }\n\n        return () => {\n            window.removeEventListener('mousemove', handleMouseMove);\n            window.removeEventListener('mouseup', handleMouseUp);\n            window.removeEventListener('touchmove', handleTouchMove);\n            window.removeEventListener('touchend', handleMouseUp);\n        };\n    }, [isDragging]);\n\n    const handleMouseDown = (e: React.MouseEvent) => {\n        e.preventDefault();\n        setIsDragging(true);\n        if (containerRef.current) {\n            const rect = containerRef.current.getBoundingClientRect();\n            const x = e.clientX - rect.left;\n            setSliderPosition(\n                Math.max(0, Math.min(100, (x \/ rect.width) * 100)),\n            );\n        }\n    };\n\n    const handleTouchStart = (e: React.TouchEvent) => {\n        setIsDragging(true);\n        if (containerRef.current) {\n            const rect = containerRef.current.getBoundingClientRect();\n            const x = e.touches[0].clientX - rect.left;\n            setSliderPosition(\n                Math.max(0, Math.min(100, (x \/ rect.width) * 100)),\n            );\n        }\n    };\n\n    \/\/ Calculate skewed clip-path coordinates. Taper skew to 0 at the bounds (0 and 100).\n    const currentSkew = maxSkew * (1 - Math.abs(sliderPosition - 50) \/ 50);\n    const topPoint = Math.max(0, Math.min(100, sliderPosition - currentSkew));\n    const bottomPoint = Math.max(\n        0,\n        Math.min(100, sliderPosition + currentSkew),\n    );\n\n    const aspectClasses = {\n        video: 'aspect-video',\n        square: 'aspect-square',\n        wide: 'aspect-21\/9',\n        auto: 'h-full w-full',\n    };\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(\n                'relative overflow-hidden rounded-xl border border-border bg-muted shadow-lg select-none',\n                aspectClasses[aspectRatio],\n                className,\n            )}\n            onMouseDown={handleMouseDown}\n            onTouchStart={handleTouchStart}\n            {...props}\n        >\n            {\/* After Image (Base) *\/}\n            <img\n                src={afterImage}\n                alt=\"After\"\n                className=\"pointer-events-none absolute inset-0 size-full object-cover\"\n            \/>\n\n            {\/* After Label *\/}\n            {afterLabel && (\n                <div className=\"absolute right-4 bottom-4 z-10 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\">\n                    {afterLabel}\n                <\/div>\n            )}\n\n            {\/* Before Image (Clipped overlay) *\/}\n            <div\n                className=\"pointer-events-none absolute inset-0 size-full\"\n                style={{\n                    clipPath: `polygon(0 0, ${topPoint}% 0, ${bottomPoint}% 100%, 0 100%)`,\n                }}\n            >\n                <img\n                    src={beforeImage}\n                    alt=\"Before\"\n                    className=\"absolute inset-0 size-full object-cover\"\n                \/>\n            <\/div>\n\n            {\/* Before Label *\/}\n            {beforeLabel && (\n                <div\n                    className=\"absolute bottom-4 left-4 z-10 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\"\n                    style={{\n                        opacity: sliderPosition < 15 ? 0 : 1,\n                    }}\n                >\n                    {beforeLabel}\n                <\/div>\n            )}\n\n            {\/* Diagonal SVG Divider Line *\/}\n            <svg\n                className=\"pointer-events-none absolute inset-0 z-20 size-full\"\n                style={{ filter: 'drop-shadow(0px 0px 1px rgba(0,0,0,0.5))' }}\n            >\n                <line\n                    x1={`${topPoint}%`}\n                    y1=\"0\"\n                    x2={`${bottomPoint}%`}\n                    y2=\"100%\"\n                    className=\"stroke-background\/90\"\n                    strokeWidth=\"2.5\"\n                \/>\n            <\/svg>\n\n            {\/* Slider Handle (located at center of diagonal line) *\/}\n            <div\n                className=\"absolute top-1\/2 z-20 -translate-x-1\/2 -translate-y-1\/2 cursor-ew-resize\"\n                style={{ left: `${sliderPosition}%` }}\n            >\n                <div\n                    className={cn(\n                        'flex size-9 items-center justify-center rounded-full border border-border bg-background shadow-md transition-transform duration-200 select-none',\n                        isDragging && 'scale-110 border-primary',\n                    )}\n                >\n                    <ChevronsLeftRight className=\"size-4 text-muted-foreground\" \/>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"comparison-sliders","version":"1.0.0"},"categories":["comparison-sliders"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"comparison-slider-hover","type":"registry:ui","title":"Comparison Slider Hover","description":"A cursor-following hover-reveal before\/after image comparison slider with optional click locking.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/comparison-sliders\/comparison-slider-hover.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { Lock, Unlock } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\n\ninterface ComparisonSliderHoverProps extends React.HTMLAttributes<HTMLDivElement> {\n    beforeImage: string;\n    afterImage: string;\n    beforeLabel?: string;\n    afterLabel?: string;\n    defaultPosition?: number;\n    aspectRatio?: 'video' | 'square' | 'wide' | 'auto';\n    resetOnLeave?: boolean;\n}\n\nexport function ComparisonSliderHover({\n    beforeImage,\n    afterImage,\n    beforeLabel = 'Before',\n    afterLabel = 'After',\n    defaultPosition = 50,\n    aspectRatio = 'video',\n    resetOnLeave = false,\n    className,\n    ...props\n}: ComparisonSliderHoverProps) {\n    const [sliderPosition, setSliderPosition] = React.useState(defaultPosition);\n    const [isLocked, setIsLocked] = React.useState(false);\n    const containerRef = React.useRef<HTMLDivElement>(null);\n\n    const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n        if (isLocked || !containerRef.current) return;\n        const rect = containerRef.current.getBoundingClientRect();\n        const x = e.clientX - rect.left;\n        const position = Math.max(0, Math.min(100, (x \/ rect.width) * 100));\n        setSliderPosition(position);\n    };\n\n    const handleMouseLeave = () => {\n        if (isLocked || !resetOnLeave) return;\n        setSliderPosition(defaultPosition);\n    };\n\n    const handleContainerClick = (e: React.MouseEvent) => {\n        \/\/ Toggle locking\n        setIsLocked(!isLocked);\n    };\n\n    const aspectClasses = {\n        video: 'aspect-video',\n        square: 'aspect-square',\n        wide: 'aspect-21\/9',\n        auto: 'h-full w-full',\n    };\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(\n                'relative cursor-crosshair overflow-hidden rounded-xl border border-border bg-muted shadow-lg select-none',\n                aspectClasses[aspectRatio],\n                className,\n            )}\n            onMouseMove={handleMouseMove}\n            onMouseLeave={handleMouseLeave}\n            onClick={handleContainerClick}\n            {...props}\n        >\n            {\/* After Image (Base) *\/}\n            <img\n                src={afterImage}\n                alt=\"After\"\n                className=\"pointer-events-none absolute inset-0 size-full object-cover\"\n            \/>\n\n            {\/* After Label *\/}\n            {afterLabel && (\n                <div className=\"absolute right-4 bottom-4 z-10 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\">\n                    {afterLabel}\n                <\/div>\n            )}\n\n            {\/* Before Image (Clipped overlay) *\/}\n            <div\n                className=\"pointer-events-none absolute inset-0 size-full\"\n                style={{\n                    clipPath: `polygon(0 0, ${sliderPosition}% 0, ${sliderPosition}% 100%, 0 100%)`,\n                }}\n            >\n                <img\n                    src={beforeImage}\n                    alt=\"Before\"\n                    className=\"absolute inset-0 size-full object-cover\"\n                \/>\n            <\/div>\n\n            {\/* Before Label *\/}\n            {beforeLabel && (\n                <div\n                    className=\"absolute bottom-4 left-4 z-10 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\"\n                    style={{\n                        opacity: sliderPosition < 15 ? 0 : 1,\n                    }}\n                >\n                    {beforeLabel}\n                <\/div>\n            )}\n\n            {\/* Locked\/Unlocked Alert Tooltip *\/}\n            <div className=\"absolute top-4 right-4 z-10 rounded-md border border-border bg-background\/80 px-2 py-1 text-[10px] font-semibold text-foreground shadow-xs backdrop-blur-xs\">\n                {isLocked\n                    ? 'Locked (Click to unlock)'\n                    : 'Hover to move (Click to lock)'}\n            <\/div>\n\n            {\/* Slider Line & Handle *\/}\n            <div\n                className={cn(\n                    'pointer-events-none absolute top-0 bottom-0 z-20 w-0.5 bg-background\/80 transition-colors hover:bg-background\/95',\n                    isLocked && 'bg-primary',\n                )}\n                style={{ left: `${sliderPosition}%` }}\n            >\n                <div\n                    className={cn(\n                        'absolute top-1\/2 flex size-9 -translate-x-1\/2 -translate-y-1\/2 items-center justify-center rounded-full border bg-background shadow-md transition-all duration-200',\n                        isLocked\n                            ? 'scale-110 border-primary text-primary'\n                            : 'border-border text-muted-foreground',\n                    )}\n                >\n                    {isLocked ? (\n                        <Lock className=\"size-4\" \/>\n                    ) : (\n                        <Unlock className=\"size-4 animate-pulse\" \/>\n                    )}\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"comparison-sliders","version":"1.0.0"},"categories":["comparison-sliders"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"comparison-slider-three-way","type":"registry:ui","title":"Comparison Slider Three Way","description":"A multi-image before\/after\/filtered image comparison slider featuring dual interactive drag handles.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/comparison-sliders\/comparison-slider-three-way.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { ChevronsLeftRight } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\n\ninterface ComparisonSliderThreeWayProps extends React.HTMLAttributes<HTMLDivElement> {\n    leftImage: string;\n    centerImage: string;\n    rightImage: string;\n    leftLabel?: string;\n    centerLabel?: string;\n    rightLabel?: string;\n    defaultLeftPosition?: number;\n    defaultRightPosition?: number;\n    minGap?: number; \/\/ minimum percentage gap between handles\n    aspectRatio?: 'video' | 'square' | 'wide' | 'auto';\n}\n\nexport function ComparisonSliderThreeWay({\n    leftImage,\n    centerImage,\n    rightImage,\n    leftLabel = 'Original',\n    centerLabel = 'Filtered',\n    rightLabel = 'B&W',\n    defaultLeftPosition = 33,\n    defaultRightPosition = 66,\n    minGap = 5,\n    aspectRatio = 'video',\n    className,\n    ...props\n}: ComparisonSliderThreeWayProps) {\n    const [leftPos, setLeftPos] = React.useState(defaultLeftPosition);\n    const [rightPos, setRightPos] = React.useState(defaultRightPosition);\n    const [activeHandle, setActiveHandle] = React.useState<\n        'left' | 'right' | null\n    >(null);\n    const containerRef = React.useRef<HTMLDivElement>(null);\n\n    const handleMove = (clientX: number) => {\n        if (!containerRef.current || !activeHandle) return;\n        const rect = containerRef.current.getBoundingClientRect();\n        const x = clientX - rect.left;\n        const percentage = Math.max(0, Math.min(100, (x \/ rect.width) * 100));\n\n        if (activeHandle === 'left') {\n            \/\/ Left handle cannot exceed right handle minus minimum gap\n            const newLeft = Math.min(percentage, rightPos - minGap);\n            setLeftPos(newLeft);\n        } else {\n            \/\/ Right handle cannot be less than left handle plus minimum gap\n            const newRight = Math.max(percentage, leftPos + minGap);\n            setRightPos(newRight);\n        }\n    };\n\n    const handleTouchMove = (e: TouchEvent) => {\n        if (!activeHandle) return;\n        handleMove(e.touches[0].clientX);\n    };\n\n    const handleMouseMove = (e: MouseEvent) => {\n        if (!activeHandle) return;\n        handleMove(e.clientX);\n    };\n\n    const handleMouseUp = () => {\n        setActiveHandle(null);\n    };\n\n    React.useEffect(() => {\n        if (activeHandle) {\n            window.addEventListener('mousemove', handleMouseMove);\n            window.addEventListener('mouseup', handleMouseUp);\n            window.addEventListener('touchmove', handleTouchMove);\n            window.addEventListener('touchend', handleMouseUp);\n        }\n\n        return () => {\n            window.removeEventListener('mousemove', handleMouseMove);\n            window.removeEventListener('mouseup', handleMouseUp);\n            window.removeEventListener('touchmove', handleTouchMove);\n            window.removeEventListener('touchend', handleMouseUp);\n        };\n    }, [activeHandle, leftPos, rightPos]);\n\n    const startDraggingLeft = (e: React.MouseEvent | React.TouchEvent) => {\n        e.stopPropagation();\n        setActiveHandle('left');\n    };\n\n    const startDraggingRight = (e: React.MouseEvent | React.TouchEvent) => {\n        e.stopPropagation();\n        setActiveHandle('right');\n    };\n\n    const aspectClasses = {\n        video: 'aspect-video',\n        square: 'aspect-square',\n        wide: 'aspect-21\/9',\n        auto: 'h-full w-full',\n    };\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(\n                'relative overflow-hidden rounded-xl border border-border bg-muted shadow-lg select-none',\n                aspectClasses[aspectRatio],\n                className,\n            )}\n            {...props}\n        >\n            {\/* Right Image (Base \/ Rightmost) *\/}\n            <img\n                src={rightImage}\n                alt=\"Right state\"\n                className=\"pointer-events-none absolute inset-0 size-full object-cover\"\n            \/>\n\n            {\/* Right Label (Bottom right) *\/}\n            {rightLabel && (\n                <div className=\"absolute right-4 bottom-4 z-10 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\">\n                    {rightLabel}\n                <\/div>\n            )}\n\n            {\/* Center Image (Clipped overlay \/ Center section) *\/}\n            <div\n                className=\"pointer-events-none absolute inset-0 size-full\"\n                style={{\n                    clipPath: `polygon(${leftPos}% 0, ${rightPos}% 0, ${rightPos}% 100%, ${leftPos}% 100%)`,\n                }}\n            >\n                <img\n                    src={centerImage}\n                    alt=\"Center state\"\n                    className=\"absolute inset-0 size-full object-cover\"\n                \/>\n            <\/div>\n\n            {\/* Center Label (Bottom center) *\/}\n            {centerLabel && (\n                <div\n                    className=\"absolute bottom-4 left-1\/2 z-10 -translate-x-1\/2 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\"\n                    style={{\n                        opacity: rightPos - leftPos < 20 ? 0 : 1,\n                    }}\n                >\n                    {centerLabel}\n                <\/div>\n            )}\n\n            {\/* Left Image (Clipped overlay \/ Left section) *\/}\n            <div\n                className=\"pointer-events-none absolute inset-0 size-full\"\n                style={{\n                    clipPath: `polygon(0 0, ${leftPos}% 0, ${leftPos}% 100%, 0 100%)`,\n                }}\n            >\n                <img\n                    src={leftImage}\n                    alt=\"Left state\"\n                    className=\"absolute inset-0 size-full object-cover\"\n                \/>\n            <\/div>\n\n            {\/* Left Label (Bottom left) *\/}\n            {leftLabel && (\n                <div\n                    className=\"absolute bottom-4 left-4 z-10 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\"\n                    style={{\n                        opacity: leftPos < 15 ? 0 : 1,\n                    }}\n                >\n                    {leftLabel}\n                <\/div>\n            )}\n\n            {\/* Left Divider Line & Handle *\/}\n            <div\n                className={cn(\n                    'absolute top-0 bottom-0 z-20 w-0.5 cursor-ew-resize transition-colors',\n                    activeHandle === 'left'\n                        ? 'bg-primary'\n                        : 'bg-background\/80 hover:bg-background\/95',\n                )}\n                style={{ left: `${leftPos}%` }}\n                onMouseDown={startDraggingLeft}\n                onTouchStart={startDraggingLeft}\n            >\n                <div\n                    className={cn(\n                        'absolute top-1\/2 flex size-8 -translate-x-1\/2 -translate-y-1\/2 items-center justify-center rounded-full border border-border bg-background shadow-md transition-transform duration-200 select-none',\n                        activeHandle === 'left' && 'scale-110 border-primary',\n                    )}\n                >\n                    <ChevronsLeftRight className=\"size-3.5 text-muted-foreground\" \/>\n                <\/div>\n            <\/div>\n\n            {\/* Right Divider Line & Handle *\/}\n            <div\n                className={cn(\n                    'absolute top-0 bottom-0 z-20 w-0.5 cursor-ew-resize transition-colors',\n                    activeHandle === 'right'\n                        ? 'bg-primary'\n                        : 'bg-background\/80 hover:bg-background\/95',\n                )}\n                style={{ left: `${rightPos}%` }}\n                onMouseDown={startDraggingRight}\n                onTouchStart={startDraggingRight}\n            >\n                <div\n                    className={cn(\n                        'absolute top-1\/2 flex size-8 -translate-x-1\/2 -translate-y-1\/2 items-center justify-center rounded-full border border-border bg-background shadow-md transition-transform duration-200 select-none',\n                        activeHandle === 'right' && 'scale-110 border-primary',\n                    )}\n                >\n                    <ChevronsLeftRight className=\"size-3.5 text-muted-foreground\" \/>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"comparison-sliders","version":"1.0.0"},"categories":["comparison-sliders"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"comparison-slider-vertical","type":"registry:ui","title":"Comparison Slider Vertical","description":"A premium vertical before\/after image comparison slider with an interactive drag handle.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/comparison-sliders\/comparison-slider-vertical.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { ChevronsUpDown } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\n\ninterface ComparisonSliderVerticalProps extends React.HTMLAttributes<HTMLDivElement> {\n    beforeImage: string;\n    afterImage: string;\n    beforeLabel?: string;\n    afterLabel?: string;\n    defaultPosition?: number;\n    aspectRatio?: 'video' | 'square' | 'wide' | 'auto';\n}\n\nexport function ComparisonSliderVertical({\n    beforeImage,\n    afterImage,\n    beforeLabel = 'Before',\n    afterLabel = 'After',\n    defaultPosition = 50,\n    aspectRatio = 'video',\n    className,\n    ...props\n}: ComparisonSliderVerticalProps) {\n    const [sliderPosition, setSliderPosition] = React.useState(defaultPosition);\n    const [isDragging, setIsDragging] = React.useState(false);\n    const containerRef = React.useRef<HTMLDivElement>(null);\n\n    const handleMove = (clientY: number) => {\n        if (!containerRef.current) return;\n        const rect = containerRef.current.getBoundingClientRect();\n        const y = clientY - rect.top;\n        const position = Math.max(0, Math.min(100, (y \/ rect.height) * 100));\n        setSliderPosition(position);\n    };\n\n    const handleTouchMove = (e: TouchEvent) => {\n        if (!isDragging) return;\n        handleMove(e.touches[0].clientY);\n    };\n\n    const handleMouseMove = (e: MouseEvent) => {\n        if (!isDragging) return;\n        handleMove(e.clientY);\n    };\n\n    const handleMouseUp = () => {\n        setIsDragging(false);\n    };\n\n    React.useEffect(() => {\n        if (isDragging) {\n            window.addEventListener('mousemove', handleMouseMove);\n            window.addEventListener('mouseup', handleMouseUp);\n            window.addEventListener('touchmove', handleTouchMove);\n            window.addEventListener('touchend', handleMouseUp);\n        }\n\n        return () => {\n            window.removeEventListener('mousemove', handleMouseMove);\n            window.removeEventListener('mouseup', handleMouseUp);\n            window.removeEventListener('touchmove', handleTouchMove);\n            window.removeEventListener('touchend', handleMouseUp);\n        };\n    }, [isDragging]);\n\n    const handleMouseDown = (e: React.MouseEvent) => {\n        e.preventDefault();\n        setIsDragging(true);\n        if (containerRef.current) {\n            const rect = containerRef.current.getBoundingClientRect();\n            const y = e.clientY - rect.top;\n            setSliderPosition(\n                Math.max(0, Math.min(100, (y \/ rect.height) * 100)),\n            );\n        }\n    };\n\n    const handleTouchStart = (e: React.TouchEvent) => {\n        setIsDragging(true);\n        if (containerRef.current) {\n            const rect = containerRef.current.getBoundingClientRect();\n            const y = e.touches[0].clientY - rect.top;\n            setSliderPosition(\n                Math.max(0, Math.min(100, (y \/ rect.height) * 100)),\n            );\n        }\n    };\n\n    const aspectClasses = {\n        video: 'aspect-video',\n        square: 'aspect-square',\n        wide: 'aspect-21\/9',\n        auto: 'h-full w-full',\n    };\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(\n                'relative overflow-hidden rounded-xl border border-border bg-muted shadow-lg select-none',\n                aspectClasses[aspectRatio],\n                className,\n            )}\n            onMouseDown={handleMouseDown}\n            onTouchStart={handleTouchStart}\n            {...props}\n        >\n            {\/* After Image (Base \/ Bottom) *\/}\n            <img\n                src={afterImage}\n                alt=\"After\"\n                className=\"pointer-events-none absolute inset-0 size-full object-cover\"\n            \/>\n\n            {\/* After Label (Bottom right) *\/}\n            {afterLabel && (\n                <div className=\"absolute right-4 bottom-4 z-10 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\">\n                    {afterLabel}\n                <\/div>\n            )}\n\n            {\/* Before Image (Clipped overlay \/ Top) *\/}\n            <div\n                className=\"pointer-events-none absolute inset-0 size-full\"\n                style={{\n                    clipPath: `polygon(0 0, 100% 0, 100% ${sliderPosition}%, 0 ${sliderPosition}%)`,\n                }}\n            >\n                <img\n                    src={beforeImage}\n                    alt=\"Before\"\n                    className=\"absolute inset-0 size-full object-cover\"\n                \/>\n            <\/div>\n\n            {\/* Before Label (Top left) *\/}\n            {beforeLabel && (\n                <div\n                    className=\"absolute top-4 left-4 z-10 rounded-md bg-background\/70 px-2.5 py-1 text-xs font-medium text-foreground backdrop-blur-xs transition-opacity duration-300\"\n                    style={{\n                        opacity: sliderPosition < 15 ? 0 : 1,\n                    }}\n                >\n                    {beforeLabel}\n                <\/div>\n            )}\n\n            {\/* Slider Line & Handle (Horizontal Line sliding up\/down) *\/}\n            <div\n                className=\"absolute right-0 left-0 z-20 h-0.5 cursor-ns-resize bg-background\/85 transition-colors hover:bg-background\/95\"\n                style={{ top: `${sliderPosition}%` }}\n            >\n                <div\n                    className={cn(\n                        'absolute left-1\/2 flex size-9 -translate-x-1\/2 -translate-y-1\/2 items-center justify-center rounded-full border border-border bg-background shadow-md transition-transform duration-200 select-none',\n                        isDragging && 'scale-110 border-primary',\n                    )}\n                >\n                    <ChevronsUpDown className=\"size-4 text-muted-foreground\" \/>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"comparison-sliders","version":"1.0.0"},"categories":["comparison-sliders"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"avatar-dropzone-badge","type":"registry:ui","title":"Avatar Dropzone Badge","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","avatar","badge","progress","tooltip"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/avatar-dropzone-badge.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Avatar, AvatarImage, AvatarFallback } from '@\/components\/ui\/avatar';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Progress } from '@\/components\/ui\/progress';\nimport {\n    Tooltip,\n    TooltipContent,\n    TooltipTrigger,\n} from '@\/components\/ui\/tooltip';\nimport { User, Camera, Check, AlertCircle, Loader2 } from 'lucide-react';\n\ninterface AvatarDropzoneBadgeProps {\n    className?: string;\n    onFileSelect?: (file: File | null) => void;\n    maxSize?: number;\n    defaultImage?: string;\n    size?: 'sm' | 'md' | 'lg';\n}\n\ntype Status = 'idle' | 'uploading' | 'success' | 'error';\n\nconst sizeMap = {\n    sm: { avatar: 'size-12', icon: 'size-4', badge: 'size-4' },\n    md: { avatar: 'size-20', icon: 'size-6', badge: 'size-6' },\n    lg: { avatar: 'size-28', icon: 'size-8', badge: 'size-8' },\n};\n\nexport function AvatarDropzoneBadge({\n    className,\n    onFileSelect,\n    maxSize = 5,\n    defaultImage,\n    size = 'md',\n}: AvatarDropzoneBadgeProps) {\n    const [isDragOver, setIsDragOver] = React.useState(false);\n    const [preview, setPreview] = React.useState<string | null>(\n        defaultImage || null,\n    );\n    const [status, setStatus] = React.useState<Status>('idle');\n    const [progress, setProgress] = React.useState(0);\n    const [error, setError] = React.useState<string | null>(null);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const sizes = sizeMap[size];\n\n    const simulateUpload = React.useCallback(() => {\n        setStatus('uploading');\n        setProgress(0);\n        setError(null);\n        const interval = setInterval(() => {\n            setProgress((prev) => {\n                if (prev >= 100) {\n                    clearInterval(interval);\n                    setStatus('success');\n                    return 100;\n                }\n                return prev + 15;\n            });\n        }, 120);\n    }, []);\n\n    const handleFile = React.useCallback(\n        (file: File) => {\n            setError(null);\n            if (!file.type.startsWith('image\/')) {\n                setError('Invalid file type');\n                setStatus('error');\n                return;\n            }\n            if (file.size > maxSize * 1024 * 1024) {\n                setError(`Max size is ${maxSize}MB`);\n                setStatus('error');\n                return;\n            }\n\n            const reader = new FileReader();\n            reader.onload = (e) => {\n                setPreview(e.target?.result as string);\n                simulateUpload();\n                onFileSelect?.(file);\n            };\n            reader.readAsDataURL(file);\n        },\n        [maxSize, onFileSelect, simulateUpload],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragOver(false);\n            const file = e.dataTransfer.files[0];\n            if (file) handleFile(file);\n        },\n        [handleFile],\n    );\n\n    const statusBadge = () => {\n        if (status === 'uploading') {\n            return (\n                <Badge\n                    className={cn(sizes.badge, 'rounded-full bg-primary p-0')}\n                >\n                    <Loader2 className=\"size-3 animate-spin text-primary-foreground\" \/>\n                <\/Badge>\n            );\n        }\n        if (status === 'success') {\n            return (\n                <Badge\n                    className={cn(sizes.badge, 'bg-success rounded-full p-0')}\n                >\n                    <Check className=\"text-success-foreground size-3\" \/>\n                <\/Badge>\n            );\n        }\n        if (status === 'error') {\n            return (\n                <Tooltip>\n                    <TooltipTrigger asChild>\n                        <Badge\n                            className={cn(\n                                sizes.badge,\n                                'cursor-help rounded-full bg-destructive p-0',\n                            )}\n                        >\n                            <AlertCircle className=\"size-3 text-white\" \/>\n                        <\/Badge>\n                    <\/TooltipTrigger>\n                    <TooltipContent>{error || 'Upload failed'}<\/TooltipContent>\n                <\/Tooltip>\n            );\n        }\n        return null;\n    };\n\n    return (\n        <div className={cn('flex flex-col items-center gap-3', className)}>\n            <Tooltip>\n                <TooltipTrigger asChild>\n                    <div\n                        role=\"button\"\n                        tabIndex={0}\n                        aria-label=\"Upload avatar\"\n                        onClick={() => inputRef.current?.click()}\n                        onKeyDown={(e) =>\n                            (e.key === 'Enter' || e.key === ' ') &&\n                            inputRef.current?.click()\n                        }\n                        onDrop={handleDrop}\n                        onDragOver={(e) => {\n                            e.preventDefault();\n                            setIsDragOver(true);\n                        }}\n                        onDragLeave={(e) => {\n                            e.preventDefault();\n                            setIsDragOver(false);\n                        }}\n                        className={cn(\n                            'group relative cursor-pointer rounded-full transition-all',\n                            isDragOver &&\n                                'ring-2 ring-primary ring-offset-2 ring-offset-background',\n                        )}\n                    >\n                        <Avatar\n                            className={cn(\n                                sizes.avatar,\n                                'border-2 border-border transition-all group-hover:border-primary',\n                            )}\n                        >\n                            {preview ? (\n                                <AvatarImage\n                                    src={preview}\n                                    alt=\"Avatar\"\n                                    className=\"object-cover\"\n                                \/>\n                            ) : (\n                                <AvatarFallback className=\"bg-muted\">\n                                    <User\n                                        className={cn(\n                                            sizes.icon,\n                                            'text-muted-foreground',\n                                        )}\n                                    \/>\n                                <\/AvatarFallback>\n                            )}\n                        <\/Avatar>\n\n                        {\/* Camera overlay on hover *\/}\n                        <div className=\"absolute inset-0 flex items-center justify-center rounded-full bg-foreground\/50 opacity-0 transition-opacity group-hover:opacity-100\">\n                            <Camera className=\"size-5 text-background\" \/>\n                        <\/div>\n\n                        {\/* Status badge *\/}\n                        <div className=\"absolute -right-1 -bottom-1\">\n                            {statusBadge()}\n                        <\/div>\n                    <\/div>\n                <\/TooltipTrigger>\n                <TooltipContent>Click to upload photo<\/TooltipContent>\n            <\/Tooltip>\n\n            {status === 'uploading' && (\n                <Progress value={progress} className=\"h-1 w-20\" \/>\n            )}\n\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                onChange={(e) =>\n                    e.target.files?.[0] && handleFile(e.target.files[0])\n                }\n                className=\"sr-only\"\n            \/>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"avatar-dropzone-card","type":"registry:ui","title":"Avatar Dropzone Card","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","avatar","button","card","progress","badge"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/avatar-dropzone-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Avatar, AvatarImage, AvatarFallback } from '@\/components\/ui\/avatar';\nimport { Button } from '@\/components\/ui\/button';\nimport { Card, CardContent } from '@\/components\/ui\/card';\nimport { Progress } from '@\/components\/ui\/progress';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { User, Upload, Trash2, CheckCircle2 } from 'lucide-react';\n\ninterface AvatarDropzoneCardProps {\n    className?: string;\n    onFileSelect?: (file: File | null) => void;\n    maxSize?: number;\n    defaultImage?: string;\n}\n\ntype Status = 'idle' | 'uploading' | 'success' | 'error';\n\nexport function AvatarDropzoneCard({\n    className,\n    onFileSelect,\n    maxSize = 5,\n    defaultImage,\n}: AvatarDropzoneCardProps) {\n    const [isDragOver, setIsDragOver] = React.useState(false);\n    const [preview, setPreview] = React.useState<string | null>(\n        defaultImage || null,\n    );\n    const [status, setStatus] = React.useState<Status>('idle');\n    const [progress, setProgress] = React.useState(0);\n    const [fileName, setFileName] = React.useState<string | null>(null);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const simulateUpload = React.useCallback(() => {\n        setStatus('uploading');\n        setProgress(0);\n        const interval = setInterval(() => {\n            setProgress((prev) => {\n                if (prev >= 100) {\n                    clearInterval(interval);\n                    setStatus('success');\n                    return 100;\n                }\n                return prev + 12;\n            });\n        }, 100);\n    }, []);\n\n    const handleFile = React.useCallback(\n        (file: File) => {\n            if (\n                !file.type.startsWith('image\/') ||\n                file.size > maxSize * 1024 * 1024\n            ) {\n                setStatus('error');\n                return;\n            }\n\n            setFileName(file.name);\n            const reader = new FileReader();\n            reader.onload = (e) => {\n                setPreview(e.target?.result as string);\n                simulateUpload();\n                onFileSelect?.(file);\n            };\n            reader.readAsDataURL(file);\n        },\n        [maxSize, onFileSelect, simulateUpload],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragOver(false);\n            const file = e.dataTransfer.files[0];\n            if (file) handleFile(file);\n        },\n        [handleFile],\n    );\n\n    const handleRemove = () => {\n        setPreview(null);\n        setStatus('idle');\n        setProgress(0);\n        setFileName(null);\n        onFileSelect?.(null);\n    };\n\n    return (\n        <Card className={cn('w-full max-w-xs', className)}>\n            <CardContent className=\"flex items-center gap-4 p-4\">\n                <div\n                    role=\"button\"\n                    tabIndex={0}\n                    aria-label=\"Upload avatar\"\n                    onClick={() => inputRef.current?.click()}\n                    onKeyDown={(e) =>\n                        (e.key === 'Enter' || e.key === ' ') &&\n                        inputRef.current?.click()\n                    }\n                    onDrop={handleDrop}\n                    onDragOver={(e) => {\n                        e.preventDefault();\n                        setIsDragOver(true);\n                    }}\n                    onDragLeave={(e) => {\n                        e.preventDefault();\n                        setIsDragOver(false);\n                    }}\n                    className={cn(\n                        'shrink-0 cursor-pointer rounded-full ring-2 ring-offset-2 ring-offset-background transition-all',\n                        isDragOver\n                            ? 'scale-105 ring-primary'\n                            : 'ring-transparent hover:ring-muted-foreground\/30',\n                    )}\n                >\n                    <Avatar className=\"size-16\">\n                        {preview ? (\n                            <AvatarImage\n                                src={preview}\n                                alt=\"Avatar\"\n                                className=\"object-cover\"\n                            \/>\n                        ) : (\n                            <AvatarFallback className=\"bg-muted\">\n                                <User className=\"size-6 text-muted-foreground\" \/>\n                            <\/AvatarFallback>\n                        )}\n                    <\/Avatar>\n                <\/div>\n\n                <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n                    {status === 'idle' && !preview && (\n                        <>\n                            <p className=\"text-sm font-medium\">Profile Photo<\/p>\n                            <Button\n                                variant=\"outline\"\n                                size=\"sm\"\n                                onClick={() => inputRef.current?.click()}\n                                className=\"w-fit\"\n                            >\n                                <Upload className=\"mr-1.5 size-3.5\" \/>\n                                Upload\n                            <\/Button>\n                        <\/>\n                    )}\n\n                    {status === 'uploading' && (\n                        <>\n                            <p className=\"truncate text-sm font-medium\">\n                                {fileName}\n                            <\/p>\n                            <Progress value={progress} className=\"h-1.5\" \/>\n                            <span className=\"text-xs text-muted-foreground\">\n                                {progress}% uploaded\n                            <\/span>\n                        <\/>\n                    )}\n\n                    {status === 'success' && preview && (\n                        <>\n                            <div className=\"flex items-center gap-2\">\n                                <p className=\"truncate text-sm font-medium\">\n                                    {fileName}\n                                <\/p>\n                                <Badge\n                                    variant=\"secondary\"\n                                    className=\"text-success shrink-0 gap-1\"\n                                >\n                                    <CheckCircle2 className=\"size-3\" \/>\n                                    Done\n                                <\/Badge>\n                            <\/div>\n                            <Button\n                                variant=\"ghost\"\n                                size=\"sm\"\n                                onClick={handleRemove}\n                                className=\"w-fit text-muted-foreground hover:text-destructive\"\n                            >\n                                <Trash2 className=\"mr-1.5 size-3.5\" \/>\n                                Remove\n                            <\/Button>\n                        <\/>\n                    )}\n                <\/div>\n\n                <input\n                    ref={inputRef}\n                    type=\"file\"\n                    accept=\"image\/*\"\n                    onChange={(e) =>\n                        e.target.files?.[0] && handleFile(e.target.files[0])\n                    }\n                    className=\"sr-only\"\n                \/>\n            <\/CardContent>\n        <\/Card>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"avatar-dropzone-field","type":"registry:ui","title":"Avatar Dropzone Field","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","label","avatar"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/avatar-dropzone-field.tsx","type":"registry:ui","content":"'use client';\n\nimport { useState, useCallback, useRef } from 'react';\nimport { Upload, Trash2, RefreshCw, Loader2 } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Label } from '@\/components\/ui\/label';\nimport { Avatar, AvatarFallback, AvatarImage } from '@\/components\/ui\/avatar';\n\ninterface AvatarDropzoneFieldProps {\n    label?: string;\n    description?: string;\n    onFileSelect?: (file: File | null) => void;\n    defaultImage?: string;\n    initials?: string;\n    maxSize?: number;\n    className?: string;\n}\n\nexport function AvatarDropzoneField({\n    label = 'Profile photo',\n    description = 'JPG, PNG or GIF. Max 5MB.',\n    onFileSelect,\n    defaultImage,\n    initials = 'U',\n    maxSize = 5 * 1024 * 1024,\n    className,\n}: AvatarDropzoneFieldProps) {\n    const [preview, setPreview] = useState<string | null>(defaultImage || null);\n    const [isUploading, setIsUploading] = useState(false);\n    const [isDragging, setIsDragging] = useState(false);\n    const inputRef = useRef<HTMLInputElement>(null);\n\n    const handleFile = useCallback(\n        (file: File) => {\n            if (!file.type.startsWith('image\/') || file.size > maxSize) return;\n\n            const reader = new FileReader();\n            reader.onload = (e) => {\n                setPreview(e.target?.result as string);\n                setIsUploading(true);\n\n                setTimeout(() => {\n                    setIsUploading(false);\n                    onFileSelect?.(file);\n                }, 1000);\n            };\n            reader.readAsDataURL(file);\n        },\n        [maxSize, onFileSelect],\n    );\n\n    const handleDrop = useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragging(false);\n            const file = e.dataTransfer.files[0];\n            if (file) handleFile(file);\n        },\n        [handleFile],\n    );\n\n    const handleRemove = () => {\n        setPreview(defaultImage || null);\n        onFileSelect?.(null);\n        if (inputRef.current) inputRef.current.value = '';\n    };\n\n    return (\n        <div className={cn('space-y-2', className)}>\n            {label && <Label>{label}<\/Label>}\n\n            <div\n                className={cn(\n                    'flex items-center gap-4 rounded-lg border p-4 transition-colors',\n                    isDragging && 'border-primary bg-muted\/50',\n                )}\n                onDragOver={(e) => {\n                    e.preventDefault();\n                    setIsDragging(true);\n                }}\n                onDragLeave={() => setIsDragging(false)}\n                onDrop={handleDrop}\n            >\n                <input\n                    ref={inputRef}\n                    type=\"file\"\n                    accept=\"image\/*\"\n                    onChange={(e) => {\n                        const file = e.target.files?.[0];\n                        if (file) handleFile(file);\n                    }}\n                    className=\"sr-only\"\n                \/>\n\n                <Avatar className=\"size-16\">\n                    <AvatarImage src={preview || undefined} alt=\"Avatar\" \/>\n                    <AvatarFallback className=\"bg-muted text-xl text-muted-foreground\">\n                        {initials}\n                    <\/AvatarFallback>\n                <\/Avatar>\n\n                <div className=\"flex flex-1 flex-col gap-1\">\n                    {description && (\n                        <p className=\"text-sm text-muted-foreground\">\n                            {description}\n                        <\/p>\n                    )}\n\n                    <div className=\"flex items-center gap-2\">\n                        <Button\n                            type=\"button\"\n                            variant=\"outline\"\n                            size=\"sm\"\n                            onClick={() => inputRef.current?.click()}\n                            disabled={isUploading}\n                        >\n                            {isUploading ? (\n                                <>\n                                    <Loader2 className=\"mr-2 size-4 animate-spin\" \/>\n                                    Uploading...\n                                <\/>\n                            ) : preview ? (\n                                <>\n                                    <RefreshCw className=\"mr-2 size-4\" \/>\n                                    Change\n                                <\/>\n                            ) : (\n                                <>\n                                    <Upload className=\"mr-2 size-4\" \/>\n                                    Upload\n                                <\/>\n                            )}\n                        <\/Button>\n\n                        {preview && !isUploading && (\n                            <Button\n                                type=\"button\"\n                                variant=\"ghost\"\n                                size=\"sm\"\n                                onClick={handleRemove}\n                            >\n                                <Trash2 className=\"mr-2 size-4\" \/>\n                                Remove\n                            <\/Button>\n                        )}\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"avatar-dropzone-ghost","type":"registry:ui","title":"Avatar Dropzone Ghost","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","avatar"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/avatar-dropzone-ghost.tsx","type":"registry:ui","content":"'use client';\n\nimport { useState, useCallback, useRef } from 'react';\nimport { Camera, X, Loader2 } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Avatar, AvatarFallback, AvatarImage } from '@\/components\/ui\/avatar';\n\ninterface AvatarDropzoneGhostProps {\n    onFileSelect?: (file: File | null) => void;\n    defaultImage?: string;\n    initials?: string;\n    maxSize?: number;\n    className?: string;\n}\n\nexport function AvatarDropzoneGhost({\n    onFileSelect,\n    defaultImage,\n    initials = '?',\n    maxSize = 5 * 1024 * 1024,\n    className,\n}: AvatarDropzoneGhostProps) {\n    const [preview, setPreview] = useState<string | null>(defaultImage || null);\n    const [isUploading, setIsUploading] = useState(false);\n    const [isHovered, setIsHovered] = useState(false);\n    const inputRef = useRef<HTMLInputElement>(null);\n\n    const handleFile = useCallback(\n        (file: File) => {\n            if (!file.type.startsWith('image\/') || file.size > maxSize) return;\n\n            const reader = new FileReader();\n            reader.onload = (e) => {\n                setPreview(e.target?.result as string);\n                setIsUploading(true);\n\n                setTimeout(() => {\n                    setIsUploading(false);\n                    onFileSelect?.(file);\n                }, 1200);\n            };\n            reader.readAsDataURL(file);\n        },\n        [maxSize, onFileSelect],\n    );\n\n    const handleDrop = useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsHovered(false);\n            const file = e.dataTransfer.files[0];\n            if (file) handleFile(file);\n        },\n        [handleFile],\n    );\n\n    const handleRemove = (e: React.MouseEvent) => {\n        e.stopPropagation();\n        setPreview(defaultImage || null);\n        onFileSelect?.(null);\n        if (inputRef.current) inputRef.current.value = '';\n    };\n\n    return (\n        <div\n            className={cn('group relative cursor-pointer', className)}\n            onMouseEnter={() => setIsHovered(true)}\n            onMouseLeave={() => setIsHovered(false)}\n            onDragOver={(e) => {\n                e.preventDefault();\n                setIsHovered(true);\n            }}\n            onDragLeave={() => setIsHovered(false)}\n            onDrop={handleDrop}\n            onClick={() => inputRef.current?.click()}\n            onKeyDown={(e) => {\n                if (e.key === 'Enter' || e.key === ' ') {\n                    e.preventDefault();\n                    inputRef.current?.click();\n                }\n            }}\n            tabIndex={0}\n            role=\"button\"\n            aria-label=\"Upload avatar\"\n        >\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                onChange={(e) => {\n                    const file = e.target.files?.[0];\n                    if (file) handleFile(file);\n                }}\n                className=\"sr-only\"\n            \/>\n\n            <Avatar className=\"size-24 ring-2 ring-transparent transition-all group-hover:ring-primary\/20 group-focus-visible:ring-ring\">\n                <AvatarImage src={preview || undefined} alt=\"Avatar\" \/>\n                <AvatarFallback className=\"bg-muted text-lg\">\n                    {initials}\n                <\/AvatarFallback>\n            <\/Avatar>\n\n            <div\n                className={cn(\n                    'absolute inset-0 flex items-center justify-center rounded-full bg-black\/50 transition-opacity',\n                    isHovered || isUploading ? 'opacity-100' : 'opacity-0',\n                )}\n            >\n                {isUploading ? (\n                    <Loader2 className=\"size-6 animate-spin text-white\" \/>\n                ) : (\n                    <Camera className=\"size-6 text-white\" \/>\n                )}\n            <\/div>\n\n            {preview && preview !== defaultImage && !isUploading && (\n                <button\n                    onClick={handleRemove}\n                    className={cn(\n                        'absolute -top-1 -right-1 flex size-6 items-center justify-center rounded-full bg-muted text-muted-foreground shadow-sm transition-all hover:bg-destructive hover:text-white',\n                        isHovered ? 'opacity-100' : 'opacity-0',\n                    )}\n                    aria-label=\"Remove avatar\"\n                >\n                    <X className=\"size-3\" \/>\n                <\/button>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"avatar-dropzone-inline","type":"registry:ui","title":"Avatar Dropzone Inline","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","avatar","button","skeleton"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/avatar-dropzone-inline.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Avatar, AvatarImage, AvatarFallback } from '@\/components\/ui\/avatar';\nimport { Button } from '@\/components\/ui\/button';\nimport { Skeleton } from '@\/components\/ui\/skeleton';\nimport { User, Pencil, X } from 'lucide-react';\n\ninterface AvatarDropzoneInlineProps {\n    className?: string;\n    onFileSelect?: (file: File | null) => void;\n    maxSize?: number;\n    defaultImage?: string;\n    label?: string;\n    description?: string;\n}\n\nexport function AvatarDropzoneInline({\n    className,\n    onFileSelect,\n    maxSize = 5,\n    defaultImage,\n    label = 'Profile picture',\n    description = 'JPG, PNG or GIF. Max 5MB.',\n}: AvatarDropzoneInlineProps) {\n    const [preview, setPreview] = React.useState<string | null>(\n        defaultImage || null,\n    );\n    const [isUploading, setIsUploading] = React.useState(false);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const handleFile = React.useCallback(\n        (file: File) => {\n            if (\n                !file.type.startsWith('image\/') ||\n                file.size > maxSize * 1024 * 1024\n            )\n                return;\n\n            setIsUploading(true);\n            const reader = new FileReader();\n            reader.onload = (e) => {\n                setTimeout(() => {\n                    setPreview(e.target?.result as string);\n                    setIsUploading(false);\n                    onFileSelect?.(file);\n                }, 800);\n            };\n            reader.readAsDataURL(file);\n        },\n        [maxSize, onFileSelect],\n    );\n\n    return (\n        <div className={cn('flex items-center gap-4', className)}>\n            <div className=\"relative\">\n                {isUploading ? (\n                    <Skeleton className=\"size-14 rounded-full\" \/>\n                ) : (\n                    <Avatar className=\"size-14 border border-border\">\n                        {preview ? (\n                            <AvatarImage\n                                src={preview}\n                                alt=\"Avatar\"\n                                className=\"object-cover\"\n                            \/>\n                        ) : (\n                            <AvatarFallback className=\"bg-muted\">\n                                <User className=\"size-6 text-muted-foreground\" \/>\n                            <\/AvatarFallback>\n                        )}\n                    <\/Avatar>\n                )}\n\n                {preview && !isUploading && (\n                    <button\n                        type=\"button\"\n                        onClick={() => {\n                            setPreview(null);\n                            onFileSelect?.(null);\n                        }}\n                        className=\"absolute -top-1 -right-1 flex size-5 items-center justify-center rounded-full border border-border bg-background shadow-sm transition-colors hover:border-destructive hover:bg-destructive hover:text-white\"\n                        aria-label=\"Remove photo\"\n                    >\n                        <X className=\"size-3\" \/>\n                    <\/button>\n                )}\n            <\/div>\n\n            <div className=\"flex flex-col gap-1\">\n                <p className=\"text-sm font-medium text-foreground\">{label}<\/p>\n                <p className=\"text-xs text-muted-foreground\">{description}<\/p>\n                <div className=\"mt-1 flex gap-2\">\n                    <Button\n                        variant=\"outline\"\n                        size=\"sm\"\n                        onClick={() => inputRef.current?.click()}\n                        disabled={isUploading}\n                        className=\"h-7 text-xs\"\n                    >\n                        <Pencil className=\"mr-1 size-3\" \/>\n                        {preview ? 'Change' : 'Upload'}\n                    <\/Button>\n                <\/div>\n            <\/div>\n\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                onChange={(e) =>\n                    e.target.files?.[0] && handleFile(e.target.files[0])\n                }\n                className=\"sr-only\"\n            \/>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"avatar-dropzone-minimal","type":"registry:ui","title":"Avatar Dropzone Minimal","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","avatar","spinner"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/avatar-dropzone-minimal.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Avatar, AvatarImage, AvatarFallback } from '@\/components\/ui\/avatar';\nimport { Spinner } from '@\/components\/ui\/spinner';\nimport { Camera, X } from 'lucide-react';\n\ninterface AvatarDropzoneMinimalProps {\n    className?: string;\n    onFileSelect?: (file: File | null) => void;\n    maxSize?: number;\n    defaultImage?: string;\n}\n\nexport function AvatarDropzoneMinimal({\n    className,\n    onFileSelect,\n    maxSize = 5,\n    defaultImage,\n}: AvatarDropzoneMinimalProps) {\n    const [isDragOver, setIsDragOver] = React.useState(false);\n    const [preview, setPreview] = React.useState<string | null>(\n        defaultImage || null,\n    );\n    const [isUploading, setIsUploading] = React.useState(false);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const handleFile = React.useCallback(\n        (file: File) => {\n            if (\n                !file.type.startsWith('image\/') ||\n                file.size > maxSize * 1024 * 1024\n            )\n                return;\n\n            setIsUploading(true);\n            const reader = new FileReader();\n            reader.onload = (e) => {\n                setPreview(e.target?.result as string);\n                setTimeout(() => {\n                    setIsUploading(false);\n                    onFileSelect?.(file);\n                }, 1000);\n            };\n            reader.readAsDataURL(file);\n        },\n        [maxSize, onFileSelect],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragOver(false);\n            const file = e.dataTransfer.files[0];\n            if (file) handleFile(file);\n        },\n        [handleFile],\n    );\n\n    return (\n        <div className={cn('flex flex-col items-center gap-2', className)}>\n            <div\n                role=\"button\"\n                tabIndex={0}\n                aria-label=\"Upload avatar\"\n                onClick={() => inputRef.current?.click()}\n                onKeyDown={(e) =>\n                    (e.key === 'Enter' || e.key === ' ') &&\n                    inputRef.current?.click()\n                }\n                onDrop={handleDrop}\n                onDragOver={(e) => {\n                    e.preventDefault();\n                    setIsDragOver(true);\n                }}\n                onDragLeave={(e) => {\n                    e.preventDefault();\n                    setIsDragOver(false);\n                }}\n                className={cn(\n                    'group relative size-16 cursor-pointer transition-transform hover:scale-105',\n                    isDragOver && 'scale-110',\n                )}\n            >\n                <Avatar className=\"size-full border-2 border-border\">\n                    {preview ? (\n                        <AvatarImage\n                            src={preview}\n                            alt=\"Avatar\"\n                            className=\"object-cover\"\n                        \/>\n                    ) : (\n                        <AvatarFallback className=\"bg-muted text-muted-foreground\">\n                            <Camera className=\"size-5\" \/>\n                        <\/AvatarFallback>\n                    )}\n                <\/Avatar>\n\n                {isUploading && (\n                    <div className=\"absolute inset-0 flex items-center justify-center rounded-full bg-background\/80\">\n                        <Spinner className=\"size-5 text-primary\" \/>\n                    <\/div>\n                )}\n\n                {!isUploading && (\n                    <div className=\"absolute inset-0 flex items-center justify-center rounded-full bg-foreground\/60 opacity-0 transition-opacity group-hover:opacity-100\">\n                        <Camera className=\"size-4 text-background\" \/>\n                    <\/div>\n                )}\n\n                {preview && !isUploading && (\n                    <button\n                        type=\"button\"\n                        onClick={(e) => {\n                            e.stopPropagation();\n                            setPreview(null);\n                            onFileSelect?.(null);\n                        }}\n                        className=\"absolute -top-1 -right-1 flex size-5 items-center justify-center rounded-full bg-destructive text-white\"\n                        aria-label=\"Remove\"\n                    >\n                        <X className=\"size-3\" \/>\n                    <\/button>\n                )}\n            <\/div>\n\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                onChange={(e) =>\n                    e.target.files?.[0] && handleFile(e.target.files[0])\n                }\n                className=\"sr-only\"\n            \/>\n\n            <span className=\"text-xs text-muted-foreground\">\n                Click to upload\n            <\/span>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"avatar-dropzone-outlined","type":"registry:ui","title":"Avatar Dropzone Outlined","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/avatar-dropzone-outlined.tsx","type":"registry:ui","content":"'use client';\n\nimport { useState, useCallback, useRef } from 'react';\nimport { Upload, X, Check, AlertCircle, Loader2 } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\ninterface AvatarDropzoneOutlinedProps {\n    onFileSelect?: (file: File | null) => void;\n    maxSize?: number;\n    className?: string;\n}\n\nexport function AvatarDropzoneOutlined({\n    onFileSelect,\n    maxSize = 5 * 1024 * 1024,\n    className,\n}: AvatarDropzoneOutlinedProps) {\n    const [preview, setPreview] = useState<string | null>(null);\n    const [isDragging, setIsDragging] = useState(false);\n    const [status, setStatus] = useState<\n        'idle' | 'uploading' | 'success' | 'error'\n    >('idle');\n    const [error, setError] = useState<string | null>(null);\n    const inputRef = useRef<HTMLInputElement>(null);\n\n    const handleFile = useCallback(\n        (file: File) => {\n            setError(null);\n\n            if (!file.type.startsWith('image\/')) {\n                setError('Please upload an image file');\n                setStatus('error');\n                return;\n            }\n\n            if (file.size > maxSize) {\n                setError(\n                    `File must be less than ${Math.round(maxSize \/ 1024 \/ 1024)}MB`,\n                );\n                setStatus('error');\n                return;\n            }\n\n            const reader = new FileReader();\n            reader.onload = (e) => {\n                setPreview(e.target?.result as string);\n                setStatus('uploading');\n\n                setTimeout(() => {\n                    setStatus('success');\n                    onFileSelect?.(file);\n                }, 1500);\n            };\n            reader.readAsDataURL(file);\n        },\n        [maxSize, onFileSelect],\n    );\n\n    const handleDrop = useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragging(false);\n            const file = e.dataTransfer.files[0];\n            if (file) handleFile(file);\n        },\n        [handleFile],\n    );\n\n    const handleChange = useCallback(\n        (e: React.ChangeEvent<HTMLInputElement>) => {\n            const file = e.target.files?.[0];\n            if (file) handleFile(file);\n        },\n        [handleFile],\n    );\n\n    const handleRemove = () => {\n        setPreview(null);\n        setStatus('idle');\n        setError(null);\n        onFileSelect?.(null);\n        if (inputRef.current) inputRef.current.value = '';\n    };\n\n    return (\n        <div className={cn('flex flex-col items-center gap-3', className)}>\n            <div\n                className={cn(\n                    'relative size-28 rounded-full border-2 border-dashed transition-all duration-200',\n                    isDragging && 'scale-105 border-primary bg-primary\/5',\n                    status === 'error' && 'border-destructive',\n                    status === 'success' && 'border-primary',\n                    !preview &&\n                        status === 'idle' &&\n                        'border-muted-foreground\/25 hover:border-muted-foreground\/50',\n                )}\n                onDragOver={(e) => {\n                    e.preventDefault();\n                    setIsDragging(true);\n                }}\n                onDragLeave={() => setIsDragging(false)}\n                onDrop={handleDrop}\n            >\n                <input\n                    ref={inputRef}\n                    type=\"file\"\n                    accept=\"image\/*\"\n                    onChange={handleChange}\n                    className=\"absolute inset-0 cursor-pointer rounded-full opacity-0\"\n                    aria-label=\"Upload avatar image\"\n                \/>\n\n                {preview ? (\n                    <img\n                        src={preview}\n                        alt=\"Avatar preview\"\n                        className=\"size-full rounded-full object-cover\"\n                    \/>\n                ) : (\n                    <div className=\"absolute inset-0 flex flex-col items-center justify-center text-muted-foreground\">\n                        <Upload className=\"mb-1 size-6\" \/>\n                        <span className=\"text-xs\">Upload<\/span>\n                    <\/div>\n                )}\n\n                {status === 'uploading' && (\n                    <div className=\"absolute inset-0 flex items-center justify-center rounded-full bg-background\/80\">\n                        <Loader2 className=\"size-6 animate-spin text-primary\" \/>\n                    <\/div>\n                )}\n\n                {status === 'success' && preview && (\n                    <div className=\"absolute -right-1 -bottom-1 flex size-7 items-center justify-center rounded-full border-2 border-background bg-primary text-primary-foreground\">\n                        <Check className=\"size-4\" \/>\n                    <\/div>\n                )}\n\n                {status === 'error' && (\n                    <div className=\"absolute -right-1 -bottom-1 flex size-7 items-center justify-center rounded-full border-2 border-background bg-destructive text-white\">\n                        <AlertCircle className=\"size-4\" \/>\n                    <\/div>\n                )}\n            <\/div>\n\n            {preview && status !== 'uploading' && (\n                <Button\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    onClick={handleRemove}\n                    className=\"text-muted-foreground\"\n                >\n                    <X className=\"mr-1 size-4\" \/>\n                    Remove\n                <\/Button>\n            )}\n\n            {error && <p className=\"text-xs text-destructive\">{error}<\/p>}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"avatar-dropzone-sortable-row","type":"registry:ui","title":"Avatar Dropzone Sortable Row","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react","@dnd-kit\/react"],"devDependencies":[],"registryDependencies":["utils","button","card","badge","avatar"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/avatar-dropzone-sortable-row.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport {\n    Card,\n    CardContent,\n    CardHeader,\n    CardTitle,\n    CardDescription,\n} from '@\/components\/ui\/card';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Avatar, AvatarFallback, AvatarImage } from '@\/components\/ui\/avatar';\nimport { Plus, X, GripVertical, User, Upload, Trash2 } from 'lucide-react';\nimport { DragDropProvider } from '@dnd-kit\/react';\nimport { useSortable, isSortable } from '@dnd-kit\/react\/sortable';\n\ninterface AvatarFile {\n    file: File;\n    preview: string;\n    id: string;\n}\n\ninterface SortableAvatarRowItemProps {\n    avatar: AvatarFile;\n    index: number;\n    onRemove: (id: string) => void;\n    showHandle?: boolean;\n}\n\nfunction SortableAvatarRowItem({\n    avatar,\n    index,\n    onRemove,\n    showHandle,\n}: SortableAvatarRowItemProps) {\n    const { ref, handleRef, isDragging } = useSortable({\n        id: avatar.id,\n        index,\n    });\n\n    return (\n        <div\n            ref={ref}\n            className={cn(\n                'group flex items-center gap-3 rounded-md border bg-card p-2 transition-all',\n                isDragging && 'z-10 shadow-md ring-2 ring-primary',\n            )}\n        >\n            {showHandle && (\n                <button\n                    ref={handleRef}\n                    className=\"flex size-6 cursor-grab items-center justify-center rounded text-muted-foreground hover:bg-muted active:cursor-grabbing\"\n                    aria-label=\"Drag to reorder\"\n                >\n                    <GripVertical className=\"size-4\" \/>\n                <\/button>\n            )}\n\n            <Avatar className=\"size-10 border\">\n                <AvatarImage src={avatar.preview} alt=\"\" \/>\n                <AvatarFallback>\n                    <User className=\"size-5 text-muted-foreground\" \/>\n                <\/AvatarFallback>\n            <\/Avatar>\n\n            <div className=\"flex min-w-0 flex-1 flex-col\">\n                <span className=\"truncate text-sm font-medium\">\n                    {avatar.file.name}\n                <\/span>\n                <span className=\"text-xs text-muted-foreground\">\n                    {(avatar.file.size \/ 1024).toFixed(1)} KB\n                <\/span>\n            <\/div>\n\n            <Badge variant=\"secondary\" className=\"shrink-0\">\n                #{index + 1}\n            <\/Badge>\n\n            <Button\n                variant=\"ghost\"\n                size=\"sm\"\n                onClick={() => onRemove(avatar.id)}\n                className=\"size-8 shrink-0 p-0 text-muted-foreground hover:text-destructive\"\n            >\n                <X className=\"size-4\" \/>\n            <\/Button>\n        <\/div>\n    );\n}\n\ninterface AvatarDropzoneSortableRowProps {\n    onFilesSelect?: (files: File[]) => void;\n    onReorder?: (files: File[]) => void;\n    maxAvatars?: number;\n    maxSize?: number;\n    className?: string;\n    enableReorder?: boolean;\n    title?: string;\n    description?: string;\n}\n\nexport function AvatarDropzoneSortableRow({\n    onFilesSelect,\n    onReorder,\n    maxAvatars = 4,\n    maxSize = 5 * 1024 * 1024,\n    className,\n    enableReorder = true,\n    title = 'Team Members',\n    description = 'Add and reorder team member avatars',\n}: AvatarDropzoneSortableRowProps) {\n    const [avatars, setAvatars] = React.useState<AvatarFile[]>([]);\n    const [isDragging, setIsDragging] = React.useState(false);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const handleFiles = React.useCallback(\n        (newFiles: FileList) => {\n            const validFiles = Array.from(newFiles)\n                .filter(\n                    (file) =>\n                        file.type.startsWith('image\/') && file.size <= maxSize,\n                )\n                .slice(0, maxAvatars - avatars.length);\n\n            const newAvatarObjects = validFiles.map((file) => ({\n                file,\n                preview: URL.createObjectURL(file),\n                id: Math.random().toString(36).slice(2),\n            }));\n\n            const updated = [...avatars, ...newAvatarObjects].slice(\n                0,\n                maxAvatars,\n            );\n            setAvatars(updated);\n            onFilesSelect?.(updated.map((a) => a.file));\n        },\n        [avatars, maxAvatars, maxSize, onFilesSelect],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragging(false);\n            if (e.dataTransfer.files.length) handleFiles(e.dataTransfer.files);\n        },\n        [handleFiles],\n    );\n\n    const removeAvatar = (id: string) => {\n        const updated = avatars.filter((a) => a.id !== id);\n        setAvatars(updated);\n        onFilesSelect?.(updated.map((a) => a.file));\n    };\n\n    const clearAll = () => {\n        setAvatars([]);\n        onFilesSelect?.([]);\n        if (inputRef.current) inputRef.current.value = '';\n    };\n\n    const handleDragEnd = React.useCallback(\n        (event: { canceled: boolean; operation: { source: unknown } }) => {\n            if (event.canceled) return;\n\n            const source = event.operation.source as any;\n\n            if (isSortable(source)) {\n                const { initialIndex, index } = source;\n\n                if (initialIndex !== index) {\n                    setAvatars((prev) => {\n                        const newAvatars = [...prev];\n                        const [removed] = newAvatars.splice(initialIndex, 1);\n                        newAvatars.splice(index, 0, removed);\n                        onReorder?.(newAvatars.map((a) => a.file));\n                        return newAvatars;\n                    });\n                }\n            }\n        },\n        [onReorder],\n    );\n\n    const avatarsContent = (\n        <div className=\"space-y-2\">\n            {avatars.map((avatar, index) => (\n                <SortableAvatarRowItem\n                    key={avatar.id}\n                    avatar={avatar}\n                    index={index}\n                    onRemove={removeAvatar}\n                    showHandle={enableReorder}\n                \/>\n            ))}\n        <\/div>\n    );\n\n    return (\n        <Card className={cn(className)}>\n            <CardHeader className=\"pb-4\">\n                <div className=\"flex items-center justify-between\">\n                    <div>\n                        <CardTitle className=\"text-base\">{title}<\/CardTitle>\n                        <CardDescription className=\"text-sm\">\n                            {description}\n                        <\/CardDescription>\n                    <\/div>\n                    {avatars.length > 0 && (\n                        <Button\n                            variant=\"ghost\"\n                            size=\"sm\"\n                            onClick={clearAll}\n                            className=\"gap-1 text-muted-foreground hover:text-destructive\"\n                        >\n                            <Trash2 className=\"size-3\" \/>\n                            Clear\n                        <\/Button>\n                    )}\n                <\/div>\n            <\/CardHeader>\n\n            <CardContent className=\"space-y-4\">\n                <input\n                    ref={inputRef}\n                    type=\"file\"\n                    accept=\"image\/*\"\n                    multiple\n                    onChange={(e) =>\n                        e.target.files && handleFiles(e.target.files)\n                    }\n                    className=\"sr-only\"\n                \/>\n\n                {avatars.length === 0 ? (\n                    <div\n                        className={cn(\n                            'flex cursor-pointer flex-col items-center gap-2 rounded-md border-2 border-dashed p-6 transition-colors',\n                            isDragging\n                                ? 'border-primary bg-primary\/5'\n                                : 'border-muted hover:border-muted-foreground\/50',\n                        )}\n                        onDragOver={(e) => {\n                            e.preventDefault();\n                            setIsDragging(true);\n                        }}\n                        onDragLeave={() => setIsDragging(false)}\n                        onDrop={handleDrop}\n                        onClick={() => inputRef.current?.click()}\n                        onKeyDown={(e) => {\n                            if (e.key === 'Enter' || e.key === ' ') {\n                                e.preventDefault();\n                                inputRef.current?.click();\n                            }\n                        }}\n                        tabIndex={0}\n                        role=\"button\"\n                        aria-label=\"Upload avatars\"\n                    >\n                        <Upload className=\"size-6 text-muted-foreground\" \/>\n                        <p className=\"text-sm text-muted-foreground\">\n                            Drop images or click to add team members\n                        <\/p>\n                    <\/div>\n                ) : (\n                    <>\n                        {enableReorder ? (\n                            <DragDropProvider onDragEnd={handleDragEnd}>\n                                {avatarsContent}\n                            <\/DragDropProvider>\n                        ) : (\n                            avatarsContent\n                        )}\n\n                        {avatars.length < maxAvatars && (\n                            <Button\n                                variant=\"outline\"\n                                size=\"sm\"\n                                onClick={() => inputRef.current?.click()}\n                                className=\"w-full gap-1\"\n                            >\n                                <Plus className=\"size-4\" \/>\n                                Add Member ({avatars.length}\/{maxAvatars})\n                            <\/Button>\n                        )}\n\n                        {enableReorder && (\n                            <p className=\"text-center text-xs text-muted-foreground\">\n                                Drag items to change order\n                            <\/p>\n                        )}\n                    <\/>\n                )}\n            <\/CardContent>\n        <\/Card>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"avatar-dropzone-sortable-stack","type":"registry:ui","title":"Avatar Dropzone Sortable Stack","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react","@dnd-kit\/react"],"devDependencies":[],"registryDependencies":["utils","button","tooltip","avatar"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/avatar-dropzone-sortable-stack.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport {\n    Tooltip,\n    TooltipContent,\n    TooltipProvider,\n    TooltipTrigger,\n} from '@\/components\/ui\/tooltip';\nimport { Avatar, AvatarFallback, AvatarImage } from '@\/components\/ui\/avatar';\nimport { Plus, X, GripVertical, UserCircle } from 'lucide-react';\nimport { DragDropProvider } from '@dnd-kit\/react';\nimport { useSortable, isSortable } from '@dnd-kit\/react\/sortable';\n\ninterface AvatarFile {\n    file: File;\n    preview: string;\n    id: string;\n}\n\ninterface SortableAvatarProps {\n    avatar: AvatarFile;\n    index: number;\n    onRemove: (id: string) => void;\n    showHandle?: boolean;\n    size?: 'sm' | 'md' | 'lg';\n}\n\nconst sizeClasses = {\n    sm: 'size-8',\n    md: 'size-10',\n    lg: 'size-12',\n};\n\nfunction SortableAvatar({\n    avatar,\n    index,\n    onRemove,\n    showHandle,\n    size = 'md',\n}: SortableAvatarProps) {\n    const { ref, handleRef, isDragging } = useSortable({\n        id: avatar.id,\n        index,\n    });\n\n    return (\n        <TooltipProvider>\n            <Tooltip>\n                <TooltipTrigger asChild>\n                    <div\n                        ref={ref}\n                        className={cn(\n                            'group relative -ml-2 first:ml-0',\n                            isDragging && 'z-10',\n                        )}\n                    >\n                        <Avatar\n                            className={cn(\n                                sizeClasses[size],\n                                'border-2 border-background transition-transform',\n                                isDragging && 'scale-110 ring-2 ring-primary',\n                            )}\n                        >\n                            <AvatarImage src={avatar.preview} alt=\"\" \/>\n                            <AvatarFallback>\n                                <UserCircle className=\"size-full text-muted-foreground\" \/>\n                            <\/AvatarFallback>\n                        <\/Avatar>\n\n                        <div className=\"absolute -top-1 -right-1 flex gap-0.5 opacity-0 transition-opacity group-hover:opacity-100\">\n                            {showHandle && (\n                                <button\n                                    ref={handleRef}\n                                    className=\"flex size-4 cursor-grab items-center justify-center rounded-full bg-muted text-muted-foreground shadow-sm active:cursor-grabbing\"\n                                    aria-label=\"Drag to reorder\"\n                                >\n                                    <GripVertical className=\"size-2.5\" \/>\n                                <\/button>\n                            )}\n                            <button\n                                onClick={() => onRemove(avatar.id)}\n                                className=\"flex size-4 items-center justify-center rounded-full bg-destructive text-destructive-foreground shadow-sm\"\n                                aria-label=\"Remove\"\n                            >\n                                <X className=\"size-2.5\" \/>\n                            <\/button>\n                        <\/div>\n                    <\/div>\n                <\/TooltipTrigger>\n                <TooltipContent>\n                    <p className=\"text-xs\">{avatar.file.name}<\/p>\n                <\/TooltipContent>\n            <\/Tooltip>\n        <\/TooltipProvider>\n    );\n}\n\ninterface AvatarDropzoneSortableStackProps {\n    onFilesSelect?: (files: File[]) => void;\n    onReorder?: (files: File[]) => void;\n    maxAvatars?: number;\n    maxSize?: number;\n    className?: string;\n    enableReorder?: boolean;\n    size?: 'sm' | 'md' | 'lg';\n}\n\nexport function AvatarDropzoneSortableStack({\n    onFilesSelect,\n    onReorder,\n    maxAvatars = 5,\n    maxSize = 5 * 1024 * 1024,\n    className,\n    enableReorder = true,\n    size = 'md',\n}: AvatarDropzoneSortableStackProps) {\n    const [avatars, setAvatars] = React.useState<AvatarFile[]>([]);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const handleFiles = React.useCallback(\n        (newFiles: FileList) => {\n            const validFiles = Array.from(newFiles)\n                .filter(\n                    (file) =>\n                        file.type.startsWith('image\/') && file.size <= maxSize,\n                )\n                .slice(0, maxAvatars - avatars.length);\n\n            const newAvatarObjects = validFiles.map((file) => ({\n                file,\n                preview: URL.createObjectURL(file),\n                id: Math.random().toString(36).slice(2),\n            }));\n\n            const updated = [...avatars, ...newAvatarObjects].slice(\n                0,\n                maxAvatars,\n            );\n            setAvatars(updated);\n            onFilesSelect?.(updated.map((a) => a.file));\n        },\n        [avatars, maxAvatars, maxSize, onFilesSelect],\n    );\n\n    const removeAvatar = (id: string) => {\n        const updated = avatars.filter((a) => a.id !== id);\n        setAvatars(updated);\n        onFilesSelect?.(updated.map((a) => a.file));\n    };\n\n    const handleDragEnd = React.useCallback(\n        (event: { canceled: boolean; operation: { source: unknown } }) => {\n            if (event.canceled) return;\n\n            const source = event.operation.source as any;\n\n            if (isSortable(source)) {\n                const { initialIndex, index } = source;\n\n                if (initialIndex !== index) {\n                    setAvatars((prev) => {\n                        const newAvatars = [...prev];\n                        const [removed] = newAvatars.splice(initialIndex, 1);\n                        newAvatars.splice(index, 0, removed);\n                        onReorder?.(newAvatars.map((a) => a.file));\n                        return newAvatars;\n                    });\n                }\n            }\n        },\n        [onReorder],\n    );\n\n    const avatarsContent = (\n        <div className=\"flex items-center\">\n            {avatars.map((avatar, index) => (\n                <SortableAvatar\n                    key={avatar.id}\n                    avatar={avatar}\n                    index={index}\n                    onRemove={removeAvatar}\n                    showHandle={enableReorder}\n                    size={size}\n                \/>\n            ))}\n\n            {avatars.length < maxAvatars && (\n                <TooltipProvider>\n                    <Tooltip>\n                        <TooltipTrigger asChild>\n                            <Button\n                                variant=\"outline\"\n                                size=\"icon\"\n                                onClick={() => inputRef.current?.click()}\n                                className={cn(\n                                    sizeClasses[size],\n                                    'ml-2 rounded-full border-dashed',\n                                )}\n                            >\n                                <Plus className=\"size-4\" \/>\n                            <\/Button>\n                        <\/TooltipTrigger>\n                        <TooltipContent>\n                            <p>\n                                Add avatar ({avatars.length}\/{maxAvatars})\n                            <\/p>\n                        <\/TooltipContent>\n                    <\/Tooltip>\n                <\/TooltipProvider>\n            )}\n        <\/div>\n    );\n\n    return (\n        <div className={cn('flex flex-col gap-2', className)}>\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                multiple\n                onChange={(e) => e.target.files && handleFiles(e.target.files)}\n                className=\"sr-only\"\n            \/>\n\n            {enableReorder ? (\n                <DragDropProvider onDragEnd={handleDragEnd}>\n                    {avatarsContent}\n                <\/DragDropProvider>\n            ) : (\n                avatarsContent\n            )}\n\n            {avatars.length > 0 && (\n                <p className=\"text-xs text-muted-foreground\">\n                    {enableReorder\n                        ? 'Drag to reorder avatars'\n                        : `${avatars.length} avatar${avatars.length > 1 ? 's' : ''}`}\n                <\/p>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"avatar-dropzone-square","type":"registry:ui","title":"Avatar Dropzone Square","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","progress","badge"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/avatar-dropzone-square.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Progress } from '@\/components\/ui\/progress';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { User, Upload, RotateCcw, Check, X } from 'lucide-react';\n\ninterface AvatarDropzoneSquareProps {\n    className?: string;\n    onFileSelect?: (file: File | null) => void;\n    maxSize?: number;\n    defaultImage?: string;\n}\n\ntype Status = 'idle' | 'uploading' | 'success' | 'error';\n\nexport function AvatarDropzoneSquare({\n    className,\n    onFileSelect,\n    maxSize = 5,\n    defaultImage,\n}: AvatarDropzoneSquareProps) {\n    const [isDragOver, setIsDragOver] = React.useState(false);\n    const [preview, setPreview] = React.useState<string | null>(\n        defaultImage || null,\n    );\n    const [status, setStatus] = React.useState<Status>('idle');\n    const [progress, setProgress] = React.useState(0);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const simulateUpload = React.useCallback(() => {\n        setStatus('uploading');\n        setProgress(0);\n        const interval = setInterval(() => {\n            setProgress((prev) => {\n                if (prev >= 100) {\n                    clearInterval(interval);\n                    setStatus('success');\n                    return 100;\n                }\n                return prev + 10;\n            });\n        }, 100);\n    }, []);\n\n    const handleFile = React.useCallback(\n        (file: File) => {\n            if (\n                !file.type.startsWith('image\/') ||\n                file.size > maxSize * 1024 * 1024\n            ) {\n                setStatus('error');\n                return;\n            }\n\n            const reader = new FileReader();\n            reader.onload = (e) => {\n                setPreview(e.target?.result as string);\n                simulateUpload();\n                onFileSelect?.(file);\n            };\n            reader.readAsDataURL(file);\n        },\n        [maxSize, onFileSelect, simulateUpload],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragOver(false);\n            const file = e.dataTransfer.files[0];\n            if (file) handleFile(file);\n        },\n        [handleFile],\n    );\n\n    const handleRemove = () => {\n        setPreview(null);\n        setStatus('idle');\n        setProgress(0);\n        onFileSelect?.(null);\n    };\n\n    return (\n        <div className={cn('flex flex-col items-center gap-3', className)}>\n            <div\n                role=\"button\"\n                tabIndex={0}\n                aria-label=\"Upload avatar\"\n                onClick={() =>\n                    status !== 'success' && inputRef.current?.click()\n                }\n                onKeyDown={(e) =>\n                    (e.key === 'Enter' || e.key === ' ') &&\n                    status !== 'success' &&\n                    inputRef.current?.click()\n                }\n                onDrop={handleDrop}\n                onDragOver={(e) => {\n                    e.preventDefault();\n                    setIsDragOver(true);\n                }}\n                onDragLeave={(e) => {\n                    e.preventDefault();\n                    setIsDragOver(false);\n                }}\n                className={cn(\n                    'relative size-32 overflow-hidden rounded-lg border-2 transition-all',\n                    status !== 'success' && 'cursor-pointer',\n                    isDragOver\n                        ? 'scale-[1.02] border-primary bg-primary\/5'\n                        : status === 'error'\n                          ? 'border-destructive'\n                          : status === 'success'\n                            ? 'border-success'\n                            : 'border-dashed border-border hover:border-primary\/50',\n                )}\n            >\n                {preview ? (\n                    <img\n                        src={preview}\n                        alt=\"Avatar preview\"\n                        className=\"h-full w-full object-cover\"\n                    \/>\n                ) : (\n                    <div className=\"flex h-full w-full flex-col items-center justify-center gap-2 bg-muted\/30\">\n                        <User className=\"size-10 text-muted-foreground\/50\" \/>\n                        <span className=\"text-xs text-muted-foreground\">\n                            No image\n                        <\/span>\n                    <\/div>\n                )}\n\n                {\/* Upload overlay *\/}\n                {!preview && isDragOver && (\n                    <div className=\"absolute inset-0 flex items-center justify-center bg-primary\/10\">\n                        <Upload className=\"size-8 text-primary\" \/>\n                    <\/div>\n                )}\n\n                {\/* Progress overlay *\/}\n                {status === 'uploading' && (\n                    <div className=\"absolute inset-0 flex flex-col items-center justify-center bg-background\/80\">\n                        <div className=\"mb-2 text-lg font-bold text-foreground\">\n                            {Math.round(progress)}%\n                        <\/div>\n                        <Progress value={progress} className=\"h-1.5 w-24\" \/>\n                    <\/div>\n                )}\n\n                {\/* Success badge *\/}\n                {status === 'success' && (\n                    <Badge className=\"bg-success text-success-foreground absolute top-2 right-2 gap-1\">\n                        <Check className=\"size-3\" \/>\n                        Uploaded\n                    <\/Badge>\n                )}\n            <\/div>\n\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                onChange={(e) =>\n                    e.target.files?.[0] && handleFile(e.target.files[0])\n                }\n                className=\"sr-only\"\n            \/>\n\n            {\/* Action buttons *\/}\n            <div className=\"flex gap-2\">\n                {status === 'success' ? (\n                    <>\n                        <Button\n                            variant=\"outline\"\n                            size=\"sm\"\n                            onClick={() => inputRef.current?.click()}\n                        >\n                            <RotateCcw className=\"mr-1.5 size-3.5\" \/>\n                            Replace\n                        <\/Button>\n                        <Button\n                            variant=\"ghost\"\n                            size=\"sm\"\n                            onClick={handleRemove}\n                            className=\"text-destructive hover:text-destructive\"\n                        >\n                            <X className=\"mr-1.5 size-3.5\" \/>\n                            Remove\n                        <\/Button>\n                    <\/>\n                ) : (\n                    <Button\n                        variant=\"outline\"\n                        size=\"sm\"\n                        onClick={() => inputRef.current?.click()}\n                    >\n                        <Upload className=\"mr-1.5 size-3.5\" \/>\n                        Select Image\n                    <\/Button>\n                )}\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-carousel","type":"registry:ui","title":"Gallery Dropzone Carousel","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","progress","badge","scroll-area"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-carousel.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Progress } from '@\/components\/ui\/progress';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { ScrollArea, ScrollBar } from '@\/components\/ui\/scroll-area';\nimport {\n    ImageIcon,\n    Upload,\n    X,\n    Check,\n    ChevronLeft,\n    ChevronRight,\n    Plus,\n} from 'lucide-react';\n\ninterface ImageFile {\n    id: string;\n    file: File;\n    preview: string;\n    progress: number;\n    status: 'uploading' | 'success' | 'error';\n}\n\ninterface GalleryDropzoneCarouselProps {\n    className?: string;\n    onFilesChange?: (files: File[]) => void;\n    maxFiles?: number;\n    maxSize?: number;\n}\n\nexport function GalleryDropzoneCarousel({\n    className,\n    onFilesChange,\n    maxFiles = 10,\n    maxSize = 10,\n}: GalleryDropzoneCarouselProps) {\n    const [isDragOver, setIsDragOver] = React.useState(false);\n    const [images, setImages] = React.useState<ImageFile[]>([]);\n    const [activeIndex, setActiveIndex] = React.useState(0);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n    const scrollRef = React.useRef<HTMLDivElement>(null);\n\n    const simulateUpload = React.useCallback((imageId: string) => {\n        const interval = setInterval(() => {\n            setImages((prev) =>\n                prev.map((img) => {\n                    if (img.id !== imageId) return img;\n                    if (img.progress >= 100) {\n                        clearInterval(interval);\n                        return { ...img, progress: 100, status: 'success' };\n                    }\n                    return { ...img, progress: img.progress + 18 };\n                }),\n            );\n        }, 100);\n    }, []);\n\n    const processFiles = React.useCallback(\n        (files: FileList | File[]) => {\n            const fileArray = Array.from(files);\n            const remainingSlots = maxFiles - images.length;\n            const filesToProcess = fileArray.slice(0, remainingSlots);\n\n            const newImages: ImageFile[] = filesToProcess.map((file) => {\n                const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n                if (\n                    !file.type.startsWith('image\/') ||\n                    file.size > maxSize * 1024 * 1024\n                ) {\n                    return {\n                        id,\n                        file,\n                        preview: '',\n                        progress: 0,\n                        status: 'error' as const,\n                    };\n                }\n\n                const reader = new FileReader();\n                reader.onload = (e) => {\n                    setImages((prev) =>\n                        prev.map((img) =>\n                            img.id === id\n                                ? {\n                                      ...img,\n                                      preview: e.target?.result as string,\n                                  }\n                                : img,\n                        ),\n                    );\n                };\n                reader.readAsDataURL(file);\n\n                return {\n                    id,\n                    file,\n                    preview: '',\n                    progress: 0,\n                    status: 'uploading' as const,\n                };\n            });\n\n            setImages((prev) => [...prev, ...newImages]);\n            newImages.forEach((img) => {\n                if (img.status !== 'error')\n                    setTimeout(() => simulateUpload(img.id), 50);\n            });\n\n            onFilesChange?.(\n                [...images, ...newImages]\n                    .filter((i) => i.status !== 'error')\n                    .map((i) => i.file),\n            );\n        },\n        [images, maxFiles, maxSize, onFilesChange, simulateUpload],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragOver(false);\n            processFiles(e.dataTransfer.files);\n        },\n        [processFiles],\n    );\n\n    const handleRemove = React.useCallback(\n        (id: string) => {\n            setImages((prev) => {\n                const updated = prev.filter((img) => img.id !== id);\n                onFilesChange?.(\n                    updated\n                        .filter((i) => i.status !== 'error')\n                        .map((i) => i.file),\n                );\n                if (activeIndex >= updated.length)\n                    setActiveIndex(Math.max(0, updated.length - 1));\n                return updated;\n            });\n        },\n        [activeIndex, onFilesChange],\n    );\n\n    const activeImage = images[activeIndex];\n\n    return (\n        <div className={cn('flex flex-col gap-4', className)}>\n            {\/* Main preview area *\/}\n            <div\n                role=\"button\"\n                tabIndex={0}\n                aria-label=\"Upload images\"\n                onClick={() => images.length === 0 && inputRef.current?.click()}\n                onKeyDown={(e) =>\n                    (e.key === 'Enter' || e.key === ' ') &&\n                    images.length === 0 &&\n                    inputRef.current?.click()\n                }\n                onDrop={handleDrop}\n                onDragOver={(e) => {\n                    e.preventDefault();\n                    setIsDragOver(true);\n                }}\n                onDragLeave={(e) => {\n                    e.preventDefault();\n                    setIsDragOver(false);\n                }}\n                className={cn(\n                    'relative aspect-[16\/10] overflow-hidden rounded-lg border-2 transition-all',\n                    images.length === 0 && 'cursor-pointer border-dashed',\n                    isDragOver\n                        ? 'border-primary bg-primary\/5'\n                        : 'border-border',\n                )}\n            >\n                {images.length === 0 ? (\n                    <div className=\"flex h-full flex-col items-center justify-center gap-3\">\n                        <div className=\"rounded-full bg-muted p-4\">\n                            <ImageIcon className=\"size-10 text-muted-foreground\" \/>\n                        <\/div>\n                        <div className=\"text-center\">\n                            <p className=\"font-medium\">\n                                Add photos to your gallery\n                            <\/p>\n                            <p className=\"text-sm text-muted-foreground\">\n                                Drag & drop or click to upload\n                            <\/p>\n                        <\/div>\n                        <Button variant=\"outline\">\n                            <Upload className=\"mr-2 size-4\" \/>\n                            Browse Files\n                        <\/Button>\n                    <\/div>\n                ) : activeImage ? (\n                    <>\n                        {activeImage.preview ? (\n                            <img\n                                src={activeImage.preview}\n                                alt=\"\"\n                                className=\"h-full w-full bg-muted object-contain\"\n                            \/>\n                        ) : (\n                            <div className=\"flex h-full w-full items-center justify-center bg-muted\">\n                                <ImageIcon className=\"size-12 text-muted-foreground\" \/>\n                            <\/div>\n                        )}\n\n                        {activeImage.status === 'uploading' && (\n                            <div className=\"absolute inset-0 flex flex-col items-center justify-center bg-background\/70\">\n                                <span className=\"mb-2 text-lg font-bold\">\n                                    {Math.round(activeImage.progress)}%\n                                <\/span>\n                                <Progress\n                                    value={activeImage.progress}\n                                    className=\"h-2 w-1\/2\"\n                                \/>\n                            <\/div>\n                        )}\n\n                        {activeImage.status === 'success' && (\n                            <Badge className=\"bg-success text-success-foreground absolute top-3 right-3 gap-1\">\n                                <Check className=\"size-3.5\" \/>\n                                Uploaded\n                            <\/Badge>\n                        )}\n\n                        <button\n                            type=\"button\"\n                            onClick={() => handleRemove(activeImage.id)}\n                            className=\"absolute right-3 bottom-3 flex size-8 items-center justify-center rounded-full bg-foreground\/80 text-background hover:bg-destructive\"\n                            aria-label=\"Remove image\"\n                        >\n                            <X className=\"size-4\" \/>\n                        <\/button>\n\n                        {\/* Navigation arrows *\/}\n                        {images.length > 1 && (\n                            <>\n                                <button\n                                    type=\"button\"\n                                    onClick={() =>\n                                        setActiveIndex(\n                                            (prev) =>\n                                                (prev - 1 + images.length) %\n                                                images.length,\n                                        )\n                                    }\n                                    className=\"absolute top-1\/2 left-2 flex size-8 -translate-y-1\/2 items-center justify-center rounded-full bg-foreground\/80 text-background hover:bg-foreground\"\n                                    aria-label=\"Previous image\"\n                                >\n                                    <ChevronLeft className=\"size-5\" \/>\n                                <\/button>\n                                <button\n                                    type=\"button\"\n                                    onClick={() =>\n                                        setActiveIndex(\n                                            (prev) =>\n                                                (prev + 1) % images.length,\n                                        )\n                                    }\n                                    className=\"absolute top-1\/2 right-2 flex size-8 -translate-y-1\/2 items-center justify-center rounded-full bg-foreground\/80 text-background hover:bg-foreground\"\n                                    aria-label=\"Next image\"\n                                >\n                                    <ChevronRight className=\"size-5\" \/>\n                                <\/button>\n                            <\/>\n                        )}\n\n                        <div className=\"absolute bottom-3 left-3 rounded-full bg-foreground\/80 px-2 py-0.5 text-xs text-background\">\n                            {activeIndex + 1} \/ {images.length}\n                        <\/div>\n                    <\/>\n                ) : null}\n\n                {isDragOver && (\n                    <div className=\"absolute inset-0 flex items-center justify-center bg-primary\/20\">\n                        <Upload className=\"size-12 text-primary\" \/>\n                    <\/div>\n                )}\n            <\/div>\n\n            {\/* Thumbnail strip *\/}\n            {images.length > 0 && (\n                <ScrollArea className=\"w-full whitespace-nowrap\">\n                    <div ref={scrollRef} className=\"flex gap-2 pb-2\">\n                        {images.map((image, idx) => (\n                            <button\n                                key={image.id}\n                                type=\"button\"\n                                onClick={() => setActiveIndex(idx)}\n                                className={cn(\n                                    'relative size-16 shrink-0 overflow-hidden rounded-md border-2 transition-all',\n                                    idx === activeIndex\n                                        ? 'border-primary ring-2 ring-primary\/20'\n                                        : 'border-transparent hover:border-muted-foreground\/30',\n                                )}\n                            >\n                                {image.preview ? (\n                                    <img\n                                        src={image.preview}\n                                        alt=\"\"\n                                        className=\"h-full w-full object-cover\"\n                                    \/>\n                                ) : (\n                                    <div className=\"flex h-full w-full items-center justify-center bg-muted\">\n                                        <ImageIcon className=\"size-5 text-muted-foreground\" \/>\n                                    <\/div>\n                                )}\n                                {image.status === 'uploading' && (\n                                    <div className=\"absolute inset-0 flex items-center justify-center bg-background\/60\">\n                                        <Progress\n                                            value={image.progress}\n                                            className=\"h-1 w-10\"\n                                        \/>\n                                    <\/div>\n                                )}\n                            <\/button>\n                        ))}\n\n                        {images.length < maxFiles && (\n                            <button\n                                type=\"button\"\n                                onClick={() => inputRef.current?.click()}\n                                className=\"flex size-16 shrink-0 items-center justify-center rounded-md border-2 border-dashed border-muted-foreground\/30 hover:border-primary\/50 hover:bg-muted\/30\"\n                                aria-label=\"Add more images\"\n                            >\n                                <Plus className=\"size-5 text-muted-foreground\" \/>\n                            <\/button>\n                        )}\n                    <\/div>\n                    <ScrollBar orientation=\"horizontal\" \/>\n                <\/ScrollArea>\n            )}\n\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                multiple\n                onChange={(e) => e.target.files && processFiles(e.target.files)}\n                className=\"sr-only\"\n            \/>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-compact","type":"registry:ui","title":"Gallery Dropzone Compact","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","progress","tooltip"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-compact.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Progress } from '@\/components\/ui\/progress';\nimport {\n    Tooltip,\n    TooltipContent,\n    TooltipTrigger,\n} from '@\/components\/ui\/tooltip';\nimport { ImageIcon, Plus, X, Check, AlertCircle } from 'lucide-react';\n\ninterface ImageFile {\n    id: string;\n    file: File;\n    preview: string;\n    progress: number;\n    status: 'uploading' | 'success' | 'error';\n}\n\ninterface GalleryDropzoneCompactProps {\n    className?: string;\n    onFilesChange?: (files: File[]) => void;\n    maxFiles?: number;\n    maxSize?: number;\n}\n\nexport function GalleryDropzoneCompact({\n    className,\n    onFilesChange,\n    maxFiles = 6,\n    maxSize = 10,\n}: GalleryDropzoneCompactProps) {\n    const [images, setImages] = React.useState<ImageFile[]>([]);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const simulateUpload = React.useCallback((imageId: string) => {\n        const interval = setInterval(() => {\n            setImages((prev) =>\n                prev.map((img) => {\n                    if (img.id !== imageId) return img;\n                    if (img.progress >= 100) {\n                        clearInterval(interval);\n                        return { ...img, progress: 100, status: 'success' };\n                    }\n                    return { ...img, progress: img.progress + 20 };\n                }),\n            );\n        }, 100);\n    }, []);\n\n    const processFiles = React.useCallback(\n        (files: FileList | File[]) => {\n            const fileArray = Array.from(files);\n            const remainingSlots = maxFiles - images.length;\n            const filesToProcess = fileArray.slice(0, remainingSlots);\n\n            const newImages: ImageFile[] = filesToProcess.map((file) => {\n                const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n                if (\n                    !file.type.startsWith('image\/') ||\n                    file.size > maxSize * 1024 * 1024\n                ) {\n                    return {\n                        id,\n                        file,\n                        preview: '',\n                        progress: 0,\n                        status: 'error' as const,\n                    };\n                }\n\n                const reader = new FileReader();\n                reader.onload = (e) => {\n                    setImages((prev) =>\n                        prev.map((img) =>\n                            img.id === id\n                                ? {\n                                      ...img,\n                                      preview: e.target?.result as string,\n                                  }\n                                : img,\n                        ),\n                    );\n                };\n                reader.readAsDataURL(file);\n\n                return {\n                    id,\n                    file,\n                    preview: '',\n                    progress: 0,\n                    status: 'uploading' as const,\n                };\n            });\n\n            setImages((prev) => [...prev, ...newImages]);\n            newImages.forEach((img) => {\n                if (img.status !== 'error')\n                    setTimeout(() => simulateUpload(img.id), 50);\n            });\n\n            onFilesChange?.(\n                [...images, ...newImages]\n                    .filter((i) => i.status !== 'error')\n                    .map((i) => i.file),\n            );\n        },\n        [images, maxFiles, maxSize, onFilesChange, simulateUpload],\n    );\n\n    const handleRemove = React.useCallback(\n        (id: string) => {\n            setImages((prev) => {\n                const updated = prev.filter((img) => img.id !== id);\n                onFilesChange?.(\n                    updated\n                        .filter((i) => i.status !== 'error')\n                        .map((i) => i.file),\n                );\n                return updated;\n            });\n        },\n        [onFilesChange],\n    );\n\n    return (\n        <div className={cn('flex flex-wrap items-center gap-2', className)}>\n            {images.map((image) => (\n                <Tooltip key={image.id}>\n                    <TooltipTrigger asChild>\n                        <div className=\"group relative size-14 overflow-hidden rounded-md border bg-muted\">\n                            {image.preview ? (\n                                <img\n                                    src={image.preview}\n                                    alt=\"\"\n                                    className=\"h-full w-full object-cover\"\n                                \/>\n                            ) : (\n                                <div className=\"flex h-full w-full items-center justify-center\">\n                                    <ImageIcon className=\"size-5 text-muted-foreground\" \/>\n                                <\/div>\n                            )}\n\n                            {\/* Progress overlay *\/}\n                            {image.status === 'uploading' && (\n                                <div className=\"absolute inset-0 flex items-center justify-center bg-background\/70\">\n                                    <Progress\n                                        value={Math.min(image.progress, 100)}\n                                        className=\"h-1 w-10\"\n                                    \/>\n                                <\/div>\n                            )}\n\n                            {\/* Status icons *\/}\n                            {image.status === 'success' && (\n                                <div className=\"bg-success absolute right-0.5 bottom-0.5 rounded-full p-0.5\">\n                                    <Check className=\"text-success-foreground size-2.5\" \/>\n                                <\/div>\n                            )}\n                            {image.status === 'error' && (\n                                <div className=\"absolute right-0.5 bottom-0.5 rounded-full bg-destructive p-0.5\">\n                                    <AlertCircle className=\"size-2.5 text-white\" \/>\n                                <\/div>\n                            )}\n\n                            {\/* Remove button *\/}\n                            <button\n                                type=\"button\"\n                                onClick={() => handleRemove(image.id)}\n                                className=\"absolute top-0.5 right-0.5 flex size-4 items-center justify-center rounded-full bg-foreground\/80 text-background opacity-0 transition-opacity group-hover:opacity-100\"\n                                aria-label=\"Remove\"\n                            >\n                                <X className=\"size-2.5\" \/>\n                            <\/button>\n                        <\/div>\n                    <\/TooltipTrigger>\n                    <TooltipContent side=\"bottom\" className=\"text-xs\">\n                        {image.file.name}\n                    <\/TooltipContent>\n                <\/Tooltip>\n            ))}\n\n            {images.length < maxFiles && (\n                <Button\n                    variant=\"outline\"\n                    size=\"sm\"\n                    onClick={() => inputRef.current?.click()}\n                    className=\"size-14 border-dashed\"\n                >\n                    <Plus className=\"size-5 text-muted-foreground\" \/>\n                <\/Button>\n            )}\n\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                multiple\n                onChange={(e) => e.target.files && processFiles(e.target.files)}\n                className=\"sr-only\"\n            \/>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-dialog","type":"registry:ui","title":"Gallery Dropzone Dialog","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","progress","badge","dialog"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-dialog.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Progress } from '@\/components\/ui\/progress';\nimport { Badge } from '@\/components\/ui\/badge';\nimport {\n    Dialog,\n    DialogContent,\n    DialogDescription,\n    DialogHeader,\n    DialogTitle,\n    DialogTrigger,\n    DialogFooter,\n} from '@\/components\/ui\/dialog';\nimport { ImageIcon, Upload, X, Check, Plus, Images } from 'lucide-react';\n\ninterface ImageFile {\n    id: string;\n    file: File;\n    preview: string;\n    progress: number;\n    status: 'uploading' | 'success' | 'error';\n}\n\ninterface GalleryDropzoneDialogProps {\n    className?: string;\n    onFilesChange?: (files: File[]) => void;\n    maxFiles?: number;\n    maxSize?: number;\n}\n\nexport function GalleryDropzoneDialog({\n    className,\n    onFilesChange,\n    maxFiles = 12,\n    maxSize = 10,\n}: GalleryDropzoneDialogProps) {\n    const [isOpen, setIsOpen] = React.useState(false);\n    const [isDragOver, setIsDragOver] = React.useState(false);\n    const [images, setImages] = React.useState<ImageFile[]>([]);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const simulateUpload = React.useCallback((imageId: string) => {\n        const interval = setInterval(() => {\n            setImages((prev) =>\n                prev.map((img) => {\n                    if (img.id !== imageId) return img;\n                    if (img.progress >= 100) {\n                        clearInterval(interval);\n                        return { ...img, progress: 100, status: 'success' };\n                    }\n                    return { ...img, progress: img.progress + 12 };\n                }),\n            );\n        }, 100);\n    }, []);\n\n    const processFiles = React.useCallback(\n        (files: FileList | File[]) => {\n            const fileArray = Array.from(files);\n            const remainingSlots = maxFiles - images.length;\n            const filesToProcess = fileArray.slice(0, remainingSlots);\n\n            const newImages: ImageFile[] = filesToProcess.map((file) => {\n                const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n                if (\n                    !file.type.startsWith('image\/') ||\n                    file.size > maxSize * 1024 * 1024\n                ) {\n                    return {\n                        id,\n                        file,\n                        preview: '',\n                        progress: 0,\n                        status: 'error' as const,\n                    };\n                }\n\n                const reader = new FileReader();\n                reader.onload = (e) => {\n                    setImages((prev) =>\n                        prev.map((img) =>\n                            img.id === id\n                                ? {\n                                      ...img,\n                                      preview: e.target?.result as string,\n                                  }\n                                : img,\n                        ),\n                    );\n                };\n                reader.readAsDataURL(file);\n\n                return {\n                    id,\n                    file,\n                    preview: '',\n                    progress: 0,\n                    status: 'uploading' as const,\n                };\n            });\n\n            setImages((prev) => [...prev, ...newImages]);\n            newImages.forEach((img) => {\n                if (img.status !== 'error')\n                    setTimeout(() => simulateUpload(img.id), 50);\n            });\n        },\n        [images.length, maxFiles, maxSize, simulateUpload],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragOver(false);\n            processFiles(e.dataTransfer.files);\n        },\n        [processFiles],\n    );\n\n    const handleRemove = (id: string) =>\n        setImages((prev) => prev.filter((img) => img.id !== id));\n\n    const handleSave = () => {\n        onFilesChange?.(\n            images.filter((i) => i.status === 'success').map((i) => i.file),\n        );\n        setIsOpen(false);\n    };\n\n    const successCount = images.filter((i) => i.status === 'success').length;\n\n    return (\n        <Dialog open={isOpen} onOpenChange={setIsOpen}>\n            <DialogTrigger asChild>\n                <Button variant=\"outline\" className={cn('gap-2', className)}>\n                    <Images className=\"size-4\" \/>\n                    Upload Gallery\n                    {successCount > 0 && (\n                        <Badge variant=\"secondary\" className=\"ml-1\">\n                            {successCount}\n                        <\/Badge>\n                    )}\n                <\/Button>\n            <\/DialogTrigger>\n\n            <DialogContent className=\"max-w-2xl\">\n                <DialogHeader>\n                    <DialogTitle>Upload Images<\/DialogTitle>\n                    <DialogDescription>\n                        Add up to {maxFiles} images to your gallery. Max{' '}\n                        {maxSize}MB per file.\n                    <\/DialogDescription>\n                <\/DialogHeader>\n\n                {\/* Dropzone area *\/}\n                <div\n                    role=\"button\"\n                    tabIndex={0}\n                    aria-label=\"Upload images\"\n                    onClick={() =>\n                        images.length < maxFiles && inputRef.current?.click()\n                    }\n                    onKeyDown={(e) =>\n                        (e.key === 'Enter' || e.key === ' ') &&\n                        images.length < maxFiles &&\n                        inputRef.current?.click()\n                    }\n                    onDrop={handleDrop}\n                    onDragOver={(e) => {\n                        e.preventDefault();\n                        setIsDragOver(true);\n                    }}\n                    onDragLeave={(e) => {\n                        e.preventDefault();\n                        setIsDragOver(false);\n                    }}\n                    className={cn(\n                        'relative min-h-[300px] rounded-lg border-2 border-dashed p-4 transition-all',\n                        images.length < maxFiles && 'cursor-pointer',\n                        isDragOver\n                            ? 'border-primary bg-primary\/5'\n                            : 'border-muted hover:border-primary\/40',\n                    )}\n                >\n                    {images.length === 0 ? (\n                        <div className=\"flex h-full min-h-[260px] flex-col items-center justify-center gap-4\">\n                            <div className=\"rounded-full bg-muted p-5\">\n                                <Upload className=\"size-10 text-muted-foreground\" \/>\n                            <\/div>\n                            <div className=\"text-center\">\n                                <p className=\"font-medium\">\n                                    Drag & drop your images here\n                                <\/p>\n                                <p className=\"text-sm text-muted-foreground\">\n                                    or click anywhere to browse\n                                <\/p>\n                            <\/div>\n                        <\/div>\n                    ) : (\n                        <div className=\"grid grid-cols-3 gap-3\">\n                            {images.map((image) => (\n                                <div\n                                    key={image.id}\n                                    className=\"group relative aspect-square overflow-hidden rounded-md border bg-muted\"\n                                >\n                                    {image.preview ? (\n                                        <img\n                                            src={image.preview}\n                                            alt=\"\"\n                                            className=\"h-full w-full object-cover\"\n                                        \/>\n                                    ) : (\n                                        <div className=\"flex h-full w-full items-center justify-center\">\n                                            <ImageIcon className=\"size-8 text-muted-foreground\" \/>\n                                        <\/div>\n                                    )}\n\n                                    {image.status === 'uploading' && (\n                                        <div className=\"absolute inset-0 flex flex-col items-center justify-center bg-background\/70\">\n                                            <span className=\"mb-1 text-sm font-medium\">\n                                                {Math.round(image.progress)}%\n                                            <\/span>\n                                            <Progress\n                                                value={image.progress}\n                                                className=\"h-1.5 w-3\/4\"\n                                            \/>\n                                        <\/div>\n                                    )}\n\n                                    {image.status === 'success' && (\n                                        <div className=\"bg-success absolute top-1.5 right-1.5 rounded-full p-1\">\n                                            <Check className=\"text-success-foreground size-3\" \/>\n                                        <\/div>\n                                    )}\n\n                                    <button\n                                        type=\"button\"\n                                        onClick={(e) => {\n                                            e.stopPropagation();\n                                            handleRemove(image.id);\n                                        }}\n                                        className=\"absolute top-1.5 left-1.5 flex size-6 items-center justify-center rounded-full bg-foreground\/80 text-background opacity-0 transition-opacity group-hover:opacity-100 hover:bg-destructive\"\n                                        aria-label=\"Remove\"\n                                    >\n                                        <X className=\"size-3.5\" \/>\n                                    <\/button>\n                                <\/div>\n                            ))}\n\n                            {images.length < maxFiles && (\n                                <button\n                                    type=\"button\"\n                                    onClick={(e) => {\n                                        e.stopPropagation();\n                                        inputRef.current?.click();\n                                    }}\n                                    className=\"flex aspect-square items-center justify-center rounded-md border-2 border-dashed border-muted-foreground\/30 hover:border-primary\/50\"\n                                    aria-label=\"Add more\"\n                                >\n                                    <Plus className=\"size-8 text-muted-foreground\" \/>\n                                <\/button>\n                            )}\n                        <\/div>\n                    )}\n\n                    {isDragOver && (\n                        <div className=\"absolute inset-0 flex items-center justify-center rounded-lg bg-primary\/20\">\n                            <Upload className=\"size-12 text-primary\" \/>\n                        <\/div>\n                    )}\n                <\/div>\n\n                <input\n                    ref={inputRef}\n                    type=\"file\"\n                    accept=\"image\/*\"\n                    multiple\n                    onChange={(e) =>\n                        e.target.files && processFiles(e.target.files)\n                    }\n                    className=\"sr-only\"\n                \/>\n\n                <DialogFooter className=\"gap-2 sm:gap-0\">\n                    <div className=\"mr-auto text-sm text-muted-foreground\">\n                        {images.length} of {maxFiles} images\n                    <\/div>\n                    <Button variant=\"outline\" onClick={() => setIsOpen(false)}>\n                        Cancel\n                    <\/Button>\n                    <Button onClick={handleSave} disabled={successCount === 0}>\n                        Save {successCount > 0 && `(${successCount})`}\n                    <\/Button>\n                <\/DialogFooter>\n            <\/DialogContent>\n        <\/Dialog>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-list","type":"registry:ui","title":"Gallery Dropzone List","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","progress","badge","separator","scroll-area"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-list.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Progress } from '@\/components\/ui\/progress';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Separator } from '@\/components\/ui\/separator';\nimport { ScrollArea } from '@\/components\/ui\/scroll-area';\nimport { ImageIcon, Upload, X, Check, FileWarning, Trash2 } from 'lucide-react';\n\ninterface ImageFile {\n    id: string;\n    file: File;\n    preview: string;\n    progress: number;\n    status: 'uploading' | 'success' | 'error';\n    error?: string;\n}\n\ninterface GalleryDropzoneListProps {\n    className?: string;\n    onFilesChange?: (files: File[]) => void;\n    maxFiles?: number;\n    maxSize?: number;\n}\n\nexport function GalleryDropzoneList({\n    className,\n    onFilesChange,\n    maxFiles = 10,\n    maxSize = 10,\n}: GalleryDropzoneListProps) {\n    const [isDragOver, setIsDragOver] = React.useState(false);\n    const [images, setImages] = React.useState<ImageFile[]>([]);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const simulateUpload = React.useCallback((imageId: string) => {\n        const interval = setInterval(() => {\n            setImages((prev) =>\n                prev.map((img) => {\n                    if (img.id !== imageId) return img;\n                    if (img.progress >= 100) {\n                        clearInterval(interval);\n                        return { ...img, progress: 100, status: 'success' };\n                    }\n                    return {\n                        ...img,\n                        progress: img.progress + Math.random() * 20 + 10,\n                    };\n                }),\n            );\n        }, 150);\n    }, []);\n\n    const processFiles = React.useCallback(\n        (files: FileList | File[]) => {\n            const fileArray = Array.from(files);\n            const remainingSlots = maxFiles - images.length;\n            const filesToProcess = fileArray.slice(0, remainingSlots);\n\n            const newImages: ImageFile[] = filesToProcess.map((file) => {\n                const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\n                if (!file.type.startsWith('image\/')) {\n                    return {\n                        id,\n                        file,\n                        preview: '',\n                        progress: 0,\n                        status: 'error' as const,\n                        error: 'Not an image',\n                    };\n                }\n                if (file.size > maxSize * 1024 * 1024) {\n                    return {\n                        id,\n                        file,\n                        preview: '',\n                        progress: 0,\n                        status: 'error' as const,\n                        error: `Max ${maxSize}MB`,\n                    };\n                }\n\n                const reader = new FileReader();\n                reader.onload = (e) => {\n                    setImages((prev) =>\n                        prev.map((img) =>\n                            img.id === id\n                                ? {\n                                      ...img,\n                                      preview: e.target?.result as string,\n                                  }\n                                : img,\n                        ),\n                    );\n                };\n                reader.readAsDataURL(file);\n\n                return {\n                    id,\n                    file,\n                    preview: '',\n                    progress: 0,\n                    status: 'uploading' as const,\n                };\n            });\n\n            setImages((prev) => [...prev, ...newImages]);\n            newImages.forEach((img) => {\n                if (img.status !== 'error')\n                    setTimeout(() => simulateUpload(img.id), 50);\n            });\n\n            onFilesChange?.(\n                [...images, ...newImages]\n                    .filter((i) => i.status !== 'error')\n                    .map((i) => i.file),\n            );\n        },\n        [images, maxFiles, maxSize, onFilesChange, simulateUpload],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragOver(false);\n            processFiles(e.dataTransfer.files);\n        },\n        [processFiles],\n    );\n\n    const handleRemove = React.useCallback(\n        (id: string) => {\n            setImages((prev) => {\n                const updated = prev.filter((img) => img.id !== id);\n                onFilesChange?.(\n                    updated\n                        .filter((i) => i.status !== 'error')\n                        .map((i) => i.file),\n                );\n                return updated;\n            });\n        },\n        [onFilesChange],\n    );\n\n    const formatSize = (bytes: number) => {\n        if (bytes < 1024) return bytes + ' B';\n        if (bytes < 1024 * 1024) return (bytes \/ 1024).toFixed(1) + ' KB';\n        return (bytes \/ (1024 * 1024)).toFixed(1) + ' MB';\n    };\n\n    return (\n        <div\n            className={cn(\n                'flex flex-col gap-4 rounded-lg border border-border p-4',\n                className,\n            )}\n        >\n            {\/* Dropzone header *\/}\n            <div\n                role=\"button\"\n                tabIndex={0}\n                aria-label=\"Upload images\"\n                onClick={() => inputRef.current?.click()}\n                onKeyDown={(e) =>\n                    (e.key === 'Enter' || e.key === ' ') &&\n                    inputRef.current?.click()\n                }\n                onDrop={handleDrop}\n                onDragOver={(e) => {\n                    e.preventDefault();\n                    setIsDragOver(true);\n                }}\n                onDragLeave={(e) => {\n                    e.preventDefault();\n                    setIsDragOver(false);\n                }}\n                className={cn(\n                    'flex cursor-pointer flex-col items-center gap-3 rounded-md border-2 border-dashed p-6 transition-colors',\n                    isDragOver\n                        ? 'border-primary bg-primary\/5'\n                        : 'border-muted hover:border-muted-foreground\/50',\n                )}\n            >\n                <div className=\"rounded-full bg-muted p-3\">\n                    <Upload className=\"size-5 text-muted-foreground\" \/>\n                <\/div>\n                <div className=\"text-center\">\n                    <p className=\"text-sm font-medium\">\n                        Drop files here or click to browse\n                    <\/p>\n                    <p className=\"text-xs text-muted-foreground\">\n                        Max {maxFiles} files, {maxSize}MB each\n                    <\/p>\n                <\/div>\n            <\/div>\n\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                multiple\n                onChange={(e) => e.target.files && processFiles(e.target.files)}\n                className=\"sr-only\"\n            \/>\n\n            {\/* File list *\/}\n            {images.length > 0 && (\n                <>\n                    <div className=\"flex items-center justify-between\">\n                        <span className=\"text-sm font-medium\">\n                            {images.length} file{images.length > 1 ? 's' : ''}\n                        <\/span>\n                        <Button\n                            variant=\"ghost\"\n                            size=\"sm\"\n                            onClick={() => {\n                                setImages([]);\n                                onFilesChange?.([]);\n                            }}\n                            className=\"h-7 text-xs text-muted-foreground hover:text-destructive\"\n                        >\n                            <Trash2 className=\"mr-1 size-3\" \/>\n                            Clear all\n                        <\/Button>\n                    <\/div>\n\n                    <ScrollArea className=\"max-h-[240px]\">\n                        <div className=\"space-y-2\">\n                            {images.map((image, idx) => (\n                                <React.Fragment key={image.id}>\n                                    <div className=\"flex items-center gap-3 py-2\">\n                                        {\/* Thumbnail *\/}\n                                        <div className=\"size-10 shrink-0 overflow-hidden rounded border bg-muted\">\n                                            {image.preview ? (\n                                                <img\n                                                    src={image.preview}\n                                                    alt=\"\"\n                                                    className=\"h-full w-full object-cover\"\n                                                \/>\n                                            ) : (\n                                                <div className=\"flex h-full w-full items-center justify-center\">\n                                                    <ImageIcon className=\"size-4 text-muted-foreground\" \/>\n                                                <\/div>\n                                            )}\n                                        <\/div>\n\n                                        {\/* File info *\/}\n                                        <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n                                            <div className=\"flex items-center gap-2\">\n                                                <span className=\"truncate text-sm\">\n                                                    {image.file.name}\n                                                <\/span>\n                                                {image.status === 'success' && (\n                                                    <Badge\n                                                        variant=\"secondary\"\n                                                        className=\"text-success shrink-0 gap-0.5 px-1.5 py-0 text-xs\"\n                                                    >\n                                                        <Check className=\"size-3\" \/>{' '}\n                                                        Done\n                                                    <\/Badge>\n                                                )}\n                                                {image.status === 'error' && (\n                                                    <Badge\n                                                        variant=\"destructive\"\n                                                        className=\"shrink-0 gap-0.5 px-1.5 py-0 text-xs\"\n                                                    >\n                                                        <FileWarning className=\"size-3\" \/>{' '}\n                                                        {image.error}\n                                                    <\/Badge>\n                                                )}\n                                            <\/div>\n                                            {image.status === 'uploading' ? (\n                                                <Progress\n                                                    value={Math.min(\n                                                        image.progress,\n                                                        100,\n                                                    )}\n                                                    className=\"h-1\"\n                                                \/>\n                                            ) : (\n                                                <span className=\"text-xs text-muted-foreground\">\n                                                    {formatSize(\n                                                        image.file.size,\n                                                    )}\n                                                <\/span>\n                                            )}\n                                        <\/div>\n\n                                        {\/* Remove *\/}\n                                        <Button\n                                            variant=\"ghost\"\n                                            size=\"sm\"\n                                            onClick={() =>\n                                                handleRemove(image.id)\n                                            }\n                                            className=\"size-8 shrink-0 p-0 text-muted-foreground hover:text-destructive\"\n                                        >\n                                            <X className=\"size-4\" \/>\n                                        <\/Button>\n                                    <\/div>\n                                    {idx < images.length - 1 && <Separator \/>}\n                                <\/React.Fragment>\n                            ))}\n                        <\/div>\n                    <\/ScrollArea>\n                <\/>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-masonry","type":"registry:ui","title":"Gallery Dropzone Masonry","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","card","progress","badge"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-masonry.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport {\n    Card,\n    CardContent,\n    CardHeader,\n    CardTitle,\n    CardDescription,\n} from '@\/components\/ui\/card';\nimport { Progress } from '@\/components\/ui\/progress';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { ImageIcon, Upload, X, Check, Images, Trash2 } from 'lucide-react';\n\ninterface ImageFile {\n    id: string;\n    file: File;\n    preview: string;\n    progress: number;\n    status: 'uploading' | 'success' | 'error';\n    aspectRatio: number;\n}\n\ninterface GalleryDropzoneMasonryProps {\n    className?: string;\n    onFilesChange?: (files: File[]) => void;\n    maxFiles?: number;\n    maxSize?: number;\n}\n\nexport function GalleryDropzoneMasonry({\n    className,\n    onFilesChange,\n    maxFiles = 9,\n    maxSize = 10,\n}: GalleryDropzoneMasonryProps) {\n    const [isDragOver, setIsDragOver] = React.useState(false);\n    const [images, setImages] = React.useState<ImageFile[]>([]);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const simulateUpload = React.useCallback((imageId: string) => {\n        const interval = setInterval(() => {\n            setImages((prev) =>\n                prev.map((img) => {\n                    if (img.id !== imageId) return img;\n                    if (img.progress >= 100) {\n                        clearInterval(interval);\n                        return { ...img, progress: 100, status: 'success' };\n                    }\n                    return { ...img, progress: img.progress + 15 };\n                }),\n            );\n        }, 120);\n    }, []);\n\n    const processFiles = React.useCallback(\n        (files: FileList | File[]) => {\n            const fileArray = Array.from(files);\n            const remainingSlots = maxFiles - images.length;\n            const filesToProcess = fileArray.slice(0, remainingSlots);\n\n            filesToProcess.forEach((file) => {\n                if (\n                    !file.type.startsWith('image\/') ||\n                    file.size > maxSize * 1024 * 1024\n                )\n                    return;\n\n                const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n                const reader = new FileReader();\n\n                reader.onload = (e) => {\n                    const img = new Image();\n                    img.crossOrigin = 'anonymous';\n                    img.onload = () => {\n                        const aspectRatio = img.width \/ img.height;\n                        setImages((prev) => [\n                            ...prev,\n                            {\n                                id,\n                                file,\n                                preview: e.target?.result as string,\n                                progress: 0,\n                                status: 'uploading',\n                                aspectRatio,\n                            },\n                        ]);\n                        setTimeout(() => simulateUpload(id), 50);\n                    };\n                    img.src = e.target?.result as string;\n                };\n                reader.readAsDataURL(file);\n            });\n        },\n        [images.length, maxFiles, maxSize, simulateUpload],\n    );\n\n    React.useEffect(() => {\n        onFilesChange?.(\n            images.filter((i) => i.status === 'success').map((i) => i.file),\n        );\n    }, [images, onFilesChange]);\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragOver(false);\n            processFiles(e.dataTransfer.files);\n        },\n        [processFiles],\n    );\n\n    const handleRemove = (id: string) =>\n        setImages((prev) => prev.filter((img) => img.id !== id));\n\n    const successCount = images.filter((i) => i.status === 'success').length;\n\n    \/\/ Distribute images into columns for masonry\n    const columns: ImageFile[][] = [[], [], []];\n    images.forEach((img, idx) => {\n        columns[idx % 3].push(img);\n    });\n\n    return (\n        <Card className={cn('w-full', className)}>\n            <CardHeader className=\"pb-4\">\n                <div className=\"flex items-start justify-between\">\n                    <div>\n                        <CardTitle className=\"flex items-center gap-2\">\n                            <Images className=\"size-5\" \/>\n                            Photo Gallery\n                        <\/CardTitle>\n                        <CardDescription>\n                            {images.length === 0\n                                ? `Upload up to ${maxFiles} images`\n                                : `${successCount} of ${images.length} uploaded`}\n                        <\/CardDescription>\n                    <\/div>\n                    {images.length > 0 && (\n                        <Button\n                            variant=\"ghost\"\n                            size=\"sm\"\n                            onClick={() => setImages([])}\n                            className=\"text-muted-foreground hover:text-destructive\"\n                        >\n                            <Trash2 className=\"mr-1 size-3.5\" \/>\n                            Clear\n                        <\/Button>\n                    )}\n                <\/div>\n            <\/CardHeader>\n\n            <CardContent>\n                {\/* Dropzone *\/}\n                <div\n                    role=\"button\"\n                    tabIndex={0}\n                    aria-label=\"Upload images\"\n                    onClick={() =>\n                        images.length < maxFiles && inputRef.current?.click()\n                    }\n                    onKeyDown={(e) =>\n                        (e.key === 'Enter' || e.key === ' ') &&\n                        images.length < maxFiles &&\n                        inputRef.current?.click()\n                    }\n                    onDrop={handleDrop}\n                    onDragOver={(e) => {\n                        e.preventDefault();\n                        setIsDragOver(true);\n                    }}\n                    onDragLeave={(e) => {\n                        e.preventDefault();\n                        setIsDragOver(false);\n                    }}\n                    className={cn(\n                        'relative min-h-[200px] rounded-lg border-2 border-dashed p-4 transition-all',\n                        images.length < maxFiles && 'cursor-pointer',\n                        isDragOver\n                            ? 'border-primary bg-primary\/5'\n                            : 'border-border hover:border-primary\/30',\n                    )}\n                >\n                    {images.length === 0 ? (\n                        <div className=\"flex h-[180px] flex-col items-center justify-center gap-3\">\n                            <div className=\"rounded-full bg-muted p-4\">\n                                <ImageIcon className=\"size-8 text-muted-foreground\" \/>\n                            <\/div>\n                            <div className=\"text-center\">\n                                <p className=\"font-medium\">Drop images here<\/p>\n                                <p className=\"text-sm text-muted-foreground\">\n                                    or click to browse\n                                <\/p>\n                            <\/div>\n                            <Button variant=\"outline\" size=\"sm\">\n                                <Upload className=\"mr-2 size-4\" \/>\n                                Select Files\n                            <\/Button>\n                        <\/div>\n                    ) : (\n                        <div className=\"flex gap-3\">\n                            {columns.map((col, colIdx) => (\n                                <div\n                                    key={colIdx}\n                                    className=\"flex flex-1 flex-col gap-3\"\n                                >\n                                    {col.map((image) => (\n                                        <div\n                                            key={image.id}\n                                            className=\"group relative overflow-hidden rounded-md border bg-muted\"\n                                            style={{\n                                                aspectRatio: image.aspectRatio,\n                                            }}\n                                        >\n                                            <img\n                                                src={image.preview}\n                                                alt=\"\"\n                                                className=\"h-full w-full object-cover\"\n                                            \/>\n\n                                            {image.status === 'uploading' && (\n                                                <div className=\"absolute inset-0 flex flex-col items-center justify-center bg-background\/60\">\n                                                    <span className=\"mb-1 text-sm font-medium\">\n                                                        {Math.round(\n                                                            image.progress,\n                                                        )}\n                                                        %\n                                                    <\/span>\n                                                    <Progress\n                                                        value={image.progress}\n                                                        className=\"h-1 w-2\/3\"\n                                                    \/>\n                                                <\/div>\n                                            )}\n\n                                            {image.status === 'success' && (\n                                                <Badge className=\"bg-success\/90 text-success-foreground absolute top-1.5 right-1.5 gap-1\">\n                                                    <Check className=\"size-3\" \/>\n                                                <\/Badge>\n                                            )}\n\n                                            <button\n                                                type=\"button\"\n                                                onClick={(e) => {\n                                                    e.stopPropagation();\n                                                    handleRemove(image.id);\n                                                }}\n                                                className=\"absolute top-1.5 left-1.5 flex size-6 items-center justify-center rounded-full bg-foreground\/80 text-background opacity-0 transition-opacity group-hover:opacity-100 hover:bg-destructive\"\n                                                aria-label=\"Remove\"\n                                            >\n                                                <X className=\"size-3.5\" \/>\n                                            <\/button>\n                                        <\/div>\n                                    ))}\n                                <\/div>\n                            ))}\n                        <\/div>\n                    )}\n\n                    {isDragOver && (\n                        <div className=\"absolute inset-0 flex items-center justify-center rounded-lg bg-primary\/10\">\n                            <div className=\"rounded-full bg-primary p-4\">\n                                <Upload className=\"size-8 text-primary-foreground\" \/>\n                            <\/div>\n                        <\/div>\n                    )}\n                <\/div>\n\n                <input\n                    ref={inputRef}\n                    type=\"file\"\n                    accept=\"image\/*\"\n                    multiple\n                    onChange={(e) =>\n                        e.target.files && processFiles(e.target.files)\n                    }\n                    className=\"sr-only\"\n                \/>\n            <\/CardContent>\n        <\/Card>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-pills","type":"registry:ui","title":"Gallery Dropzone Pills","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","badge"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-pills.tsx","type":"registry:ui","content":"'use client';\n\nimport { useState, useCallback, useRef } from 'react';\nimport { Plus, X, Loader2, Check } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Badge } from '@\/components\/ui\/badge';\n\ninterface FileWithStatus {\n    file: File;\n    preview: string;\n    id: string;\n    status: 'uploading' | 'complete';\n}\n\ninterface GalleryDropzonePillsProps {\n    onFilesSelect?: (files: File[]) => void;\n    maxFiles?: number;\n    maxSize?: number;\n    className?: string;\n}\n\nexport function GalleryDropzonePills({\n    onFilesSelect,\n    maxFiles = 8,\n    maxSize = 10 * 1024 * 1024,\n    className,\n}: GalleryDropzonePillsProps) {\n    const [files, setFiles] = useState<FileWithStatus[]>([]);\n    const [isDragging, setIsDragging] = useState(false);\n    const inputRef = useRef<HTMLInputElement>(null);\n\n    const handleFiles = useCallback(\n        (newFiles: FileList) => {\n            const validFiles = Array.from(newFiles)\n                .filter(\n                    (file) =>\n                        file.type.startsWith('image\/') && file.size <= maxSize,\n                )\n                .slice(0, maxFiles - files.length);\n\n            const newFileObjects = validFiles.map((file) => ({\n                file,\n                preview: URL.createObjectURL(file),\n                id: Math.random().toString(36).slice(2),\n                status: 'uploading' as const,\n            }));\n\n            const updated = [...files, ...newFileObjects].slice(0, maxFiles);\n            setFiles(updated);\n\n            \/\/ Simulate upload\n            newFileObjects.forEach((fileObj) => {\n                setTimeout(\n                    () => {\n                        setFiles((prev) =>\n                            prev.map((f) =>\n                                f.id === fileObj.id\n                                    ? { ...f, status: 'complete' }\n                                    : f,\n                            ),\n                        );\n                    },\n                    800 + Math.random() * 800,\n                );\n            });\n\n            onFilesSelect?.(updated.map((f) => f.file));\n        },\n        [files, maxFiles, maxSize, onFilesSelect],\n    );\n\n    const handleDrop = useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragging(false);\n            if (e.dataTransfer.files.length) handleFiles(e.dataTransfer.files);\n        },\n        [handleFiles],\n    );\n\n    const removeFile = (id: string) => {\n        const updated = files.filter((f) => f.id !== id);\n        setFiles(updated);\n        onFilesSelect?.(updated.map((f) => f.file));\n    };\n\n    return (\n        <div\n            className={cn(\n                'flex min-h-[48px] flex-wrap items-center gap-2 rounded-lg border p-3 transition-colors',\n                isDragging && 'border-primary bg-muted\/50',\n                className,\n            )}\n            onDragOver={(e) => {\n                e.preventDefault();\n                setIsDragging(true);\n            }}\n            onDragLeave={() => setIsDragging(false)}\n            onDrop={handleDrop}\n        >\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                multiple\n                onChange={(e) => e.target.files && handleFiles(e.target.files)}\n                className=\"sr-only\"\n            \/>\n\n            {files.map((file) => (\n                <Badge\n                    key={file.id}\n                    variant=\"secondary\"\n                    className=\"h-8 gap-2 pr-1 pl-1\"\n                >\n                    <div className=\"size-6 overflow-hidden rounded\">\n                        <img\n                            src={file.preview}\n                            alt=\"\"\n                            className=\"size-full object-cover\"\n                        \/>\n                    <\/div>\n                    <span className=\"max-w-[100px] truncate text-xs\">\n                        {file.file.name}\n                    <\/span>\n                    {file.status === 'uploading' ? (\n                        <Loader2 className=\"size-3 animate-spin\" \/>\n                    ) : (\n                        <button\n                            onClick={() => removeFile(file.id)}\n                            className=\"flex size-4 items-center justify-center rounded-full hover:bg-muted\"\n                            aria-label=\"Remove\"\n                        >\n                            <X className=\"size-3\" \/>\n                        <\/button>\n                    )}\n                <\/Badge>\n            ))}\n\n            {files.length < maxFiles && (\n                <button\n                    onClick={() => inputRef.current?.click()}\n                    className=\"flex h-8 items-center gap-1 rounded-md border border-dashed px-3 text-sm text-muted-foreground transition-colors hover:border-foreground hover:text-foreground\"\n                >\n                    <Plus className=\"size-4\" \/>\n                    Add images\n                <\/button>\n            )}\n\n            {files.length === 0 && (\n                <span className=\"text-sm text-muted-foreground\">\n                    Drop images here or click to add\n                <\/span>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-simple","type":"registry:ui","title":"Gallery Dropzone Simple","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-simple.tsx","type":"registry:ui","content":"'use client';\n\nimport { useState, useCallback, useRef } from 'react';\nimport { Upload, X, ImageIcon } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\n\ninterface FileWithPreview {\n    file: File;\n    preview: string;\n    id: string;\n}\n\ninterface GalleryDropzoneSimpleProps {\n    onFilesSelect?: (files: File[]) => void;\n    maxFiles?: number;\n    maxSize?: number;\n    className?: string;\n}\n\nexport function GalleryDropzoneSimple({\n    onFilesSelect,\n    maxFiles = 6,\n    maxSize = 10 * 1024 * 1024,\n    className,\n}: GalleryDropzoneSimpleProps) {\n    const [files, setFiles] = useState<FileWithPreview[]>([]);\n    const [isDragging, setIsDragging] = useState(false);\n    const inputRef = useRef<HTMLInputElement>(null);\n\n    const handleFiles = useCallback(\n        (newFiles: FileList) => {\n            const validFiles = Array.from(newFiles)\n                .filter(\n                    (file) =>\n                        file.type.startsWith('image\/') && file.size <= maxSize,\n                )\n                .slice(0, maxFiles - files.length);\n\n            const newFileObjects = validFiles.map((file) => ({\n                file,\n                preview: URL.createObjectURL(file),\n                id: Math.random().toString(36).slice(2),\n            }));\n\n            const updated = [...files, ...newFileObjects].slice(0, maxFiles);\n            setFiles(updated);\n            onFilesSelect?.(updated.map((f) => f.file));\n        },\n        [files, maxFiles, maxSize, onFilesSelect],\n    );\n\n    const handleDrop = useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragging(false);\n            if (e.dataTransfer.files.length) handleFiles(e.dataTransfer.files);\n        },\n        [handleFiles],\n    );\n\n    const removeFile = (id: string) => {\n        const updated = files.filter((f) => f.id !== id);\n        setFiles(updated);\n        onFilesSelect?.(updated.map((f) => f.file));\n    };\n\n    const clearAll = () => {\n        setFiles([]);\n        onFilesSelect?.([]);\n        if (inputRef.current) inputRef.current.value = '';\n    };\n\n    return (\n        <div className={cn('space-y-4', className)}>\n            <div\n                className={cn(\n                    'flex min-h-[160px] cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-6 transition-colors',\n                    isDragging\n                        ? 'border-primary bg-muted\/50'\n                        : 'border-muted-foreground\/25 hover:border-muted-foreground\/50',\n                )}\n                onDragOver={(e) => {\n                    e.preventDefault();\n                    setIsDragging(true);\n                }}\n                onDragLeave={() => setIsDragging(false)}\n                onDrop={handleDrop}\n                onClick={() => inputRef.current?.click()}\n                onKeyDown={(e) => {\n                    if (e.key === 'Enter' || e.key === ' ') {\n                        e.preventDefault();\n                        inputRef.current?.click();\n                    }\n                }}\n                tabIndex={0}\n                role=\"button\"\n                aria-label=\"Upload images\"\n            >\n                <input\n                    ref={inputRef}\n                    type=\"file\"\n                    accept=\"image\/*\"\n                    multiple\n                    onChange={(e) =>\n                        e.target.files && handleFiles(e.target.files)\n                    }\n                    className=\"sr-only\"\n                \/>\n\n                <div className=\"flex size-12 items-center justify-center rounded-full bg-muted\">\n                    <Upload className=\"size-6 text-muted-foreground\" \/>\n                <\/div>\n                <div className=\"text-center\">\n                    <p className=\"text-sm font-medium\">\n                        Drop images here or click to upload\n                    <\/p>\n                    <p className=\"text-xs text-muted-foreground\">\n                        PNG, JPG, GIF up to {Math.round(maxSize \/ 1024 \/ 1024)}\n                        MB\n                    <\/p>\n                <\/div>\n            <\/div>\n\n            {files.length > 0 && (\n                <div className=\"space-y-3\">\n                    <div className=\"flex items-center justify-between\">\n                        <p className=\"text-sm text-muted-foreground\">\n                            {files.length} of {maxFiles} images\n                        <\/p>\n                        <Button\n                            variant=\"ghost\"\n                            size=\"sm\"\n                            onClick={clearAll}\n                            className=\"text-muted-foreground\"\n                        >\n                            Clear all\n                        <\/Button>\n                    <\/div>\n\n                    <div className=\"grid grid-cols-3 gap-3\">\n                        {files.map((file) => (\n                            <div\n                                key={file.id}\n                                className=\"group relative aspect-square overflow-hidden rounded-md border bg-muted\"\n                            >\n                                <img\n                                    src={file.preview}\n                                    alt=\"\"\n                                    className=\"size-full object-cover\"\n                                \/>\n                                <button\n                                    onClick={() => removeFile(file.id)}\n                                    className=\"absolute top-1 right-1 flex size-6 items-center justify-center rounded-full bg-background\/80 opacity-0 shadow-sm transition-opacity group-hover:opacity-100\"\n                                    aria-label=\"Remove image\"\n                                >\n                                    <X className=\"size-3\" \/>\n                                <\/button>\n                            <\/div>\n                        ))}\n\n                        {files.length < maxFiles && (\n                            <button\n                                onClick={() => inputRef.current?.click()}\n                                className=\"flex aspect-square flex-col items-center justify-center gap-1 rounded-md border-2 border-dashed border-muted-foreground\/25 text-muted-foreground transition-colors hover:border-muted-foreground\/50 hover:bg-muted\/50\"\n                            >\n                                <ImageIcon className=\"size-5\" \/>\n                                <span className=\"text-xs\">Add<\/span>\n                            <\/button>\n                        )}\n                    <\/div>\n                <\/div>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-sortable-cards","type":"registry:ui","title":"Gallery Dropzone Sortable Cards","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react","@dnd-kit\/react"],"devDependencies":[],"registryDependencies":["utils","button","card","badge"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-sortable-cards.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Card, CardContent } from '@\/components\/ui\/card';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Upload, X, GripVertical, Star, Trash2 } from 'lucide-react';\nimport { DragDropProvider } from '@dnd-kit\/react';\nimport { useSortable, isSortable } from '@dnd-kit\/react\/sortable';\n\ninterface FileWithPreview {\n    file: File;\n    preview: string;\n    id: string;\n}\n\ninterface SortableCardProps {\n    image: FileWithPreview;\n    index: number;\n    onRemove: (id: string) => void;\n    onSetPrimary?: (id: string) => void;\n    isPrimary: boolean;\n    showHandle?: boolean;\n}\n\nfunction SortableCard({\n    image,\n    index,\n    onRemove,\n    onSetPrimary,\n    isPrimary,\n    showHandle,\n}: SortableCardProps) {\n    const { ref, handleRef, isDragging } = useSortable({\n        id: image.id,\n        index,\n    });\n\n    return (\n        <Card\n            ref={ref}\n            className={cn(\n                'group overflow-hidden transition-all',\n                isDragging && 'z-10 scale-[1.02] shadow-lg ring-2 ring-primary',\n                isPrimary && 'ring-2 ring-primary',\n            )}\n        >\n            <div className=\"relative aspect-[4\/3] overflow-hidden bg-muted\">\n                <img\n                    src={image.preview}\n                    alt=\"\"\n                    className=\"size-full object-cover transition-transform group-hover:scale-105\"\n                    draggable={false}\n                \/>\n\n                {isPrimary && (\n                    <Badge className=\"absolute top-2 left-2 gap-1 bg-primary text-primary-foreground\">\n                        <Star className=\"size-3 fill-current\" \/>\n                        Primary\n                    <\/Badge>\n                )}\n\n                <div className=\"absolute inset-x-0 bottom-0 flex items-center justify-between bg-gradient-to-t from-black\/60 to-transparent p-2 opacity-0 transition-opacity group-hover:opacity-100\">\n                    {showHandle && (\n                        <button\n                            ref={handleRef}\n                            className=\"flex size-7 cursor-grab items-center justify-center rounded bg-white\/20 text-white backdrop-blur-sm active:cursor-grabbing\"\n                            aria-label=\"Drag to reorder\"\n                        >\n                            <GripVertical className=\"size-4\" \/>\n                        <\/button>\n                    )}\n\n                    <div className={cn('flex gap-1', !showHandle && 'ml-auto')}>\n                        {!isPrimary && onSetPrimary && (\n                            <Button\n                                variant=\"secondary\"\n                                size=\"sm\"\n                                onClick={() => onSetPrimary(image.id)}\n                                className=\"h-7 gap-1 text-xs\"\n                            >\n                                <Star className=\"size-3\" \/>\n                                Set Primary\n                            <\/Button>\n                        )}\n                        <Button\n                            variant=\"destructive\"\n                            size=\"sm\"\n                            onClick={() => onRemove(image.id)}\n                            className=\"size-7 p-0\"\n                        >\n                            <X className=\"size-4\" \/>\n                        <\/Button>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <CardContent className=\"p-2\">\n                <p className=\"truncate text-xs text-muted-foreground\">\n                    {image.file.name}\n                <\/p>\n            <\/CardContent>\n        <\/Card>\n    );\n}\n\ninterface GalleryDropzoneSortableCardsProps {\n    onFilesSelect?: (files: File[]) => void;\n    onReorder?: (files: File[]) => void;\n    onPrimaryChange?: (file: File) => void;\n    maxFiles?: number;\n    maxSize?: number;\n    className?: string;\n    enableReorder?: boolean;\n}\n\nexport function GalleryDropzoneSortableCards({\n    onFilesSelect,\n    onReorder,\n    onPrimaryChange,\n    maxFiles = 8,\n    maxSize = 10 * 1024 * 1024,\n    className,\n    enableReorder = true,\n}: GalleryDropzoneSortableCardsProps) {\n    const [files, setFiles] = React.useState<FileWithPreview[]>([]);\n    const [primaryId, setPrimaryId] = React.useState<string | null>(null);\n    const [isDragging, setIsDragging] = React.useState(false);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const handleFiles = React.useCallback(\n        (newFiles: FileList) => {\n            const validFiles = Array.from(newFiles)\n                .filter(\n                    (file) =>\n                        file.type.startsWith('image\/') && file.size <= maxSize,\n                )\n                .slice(0, maxFiles - files.length);\n\n            const newFileObjects = validFiles.map((file) => ({\n                file,\n                preview: URL.createObjectURL(file),\n                id: Math.random().toString(36).slice(2),\n            }));\n\n            const updated = [...files, ...newFileObjects].slice(0, maxFiles);\n            setFiles(updated);\n\n            if (!primaryId && updated.length > 0) {\n                setPrimaryId(updated[0].id);\n                onPrimaryChange?.(updated[0].file);\n            }\n\n            onFilesSelect?.(updated.map((f) => f.file));\n        },\n        [files, maxFiles, maxSize, onFilesSelect, primaryId, onPrimaryChange],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragging(false);\n            if (e.dataTransfer.files.length) handleFiles(e.dataTransfer.files);\n        },\n        [handleFiles],\n    );\n\n    const removeFile = (id: string) => {\n        const updated = files.filter((f) => f.id !== id);\n        setFiles(updated);\n        if (primaryId === id && updated.length > 0) {\n            setPrimaryId(updated[0].id);\n            onPrimaryChange?.(updated[0].file);\n        } else if (updated.length === 0) {\n            setPrimaryId(null);\n        }\n        onFilesSelect?.(updated.map((f) => f.file));\n    };\n\n    const setPrimary = (id: string) => {\n        setPrimaryId(id);\n        const file = files.find((f) => f.id === id);\n        if (file) onPrimaryChange?.(file.file);\n    };\n\n    const clearAll = () => {\n        setFiles([]);\n        setPrimaryId(null);\n        onFilesSelect?.([]);\n        if (inputRef.current) inputRef.current.value = '';\n    };\n\n    const handleDragEnd = React.useCallback(\n        (event: { canceled: boolean; operation: { source: unknown } }) => {\n            if (event.canceled) return;\n\n            const source = event.operation.source as any;\n\n            if (isSortable(source)) {\n                const { initialIndex, index } = source;\n\n                if (initialIndex !== index) {\n                    setFiles((prev) => {\n                        const newFiles = [...prev];\n                        const [removed] = newFiles.splice(initialIndex, 1);\n                        newFiles.splice(index, 0, removed);\n                        onReorder?.(newFiles.map((f) => f.file));\n                        return newFiles;\n                    });\n                }\n            }\n        },\n        [onReorder],\n    );\n\n    const cardsContent = (\n        <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4\">\n            {files.map((file, index) => (\n                <SortableCard\n                    key={file.id}\n                    image={file}\n                    index={index}\n                    onRemove={removeFile}\n                    onSetPrimary={setPrimary}\n                    isPrimary={file.id === primaryId}\n                    showHandle={enableReorder}\n                \/>\n            ))}\n        <\/div>\n    );\n\n    return (\n        <div className={cn('space-y-4', className)}>\n            <div\n                className={cn(\n                    'flex min-h-[120px] cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-4 transition-colors',\n                    isDragging\n                        ? 'border-primary bg-primary\/5'\n                        : 'border-muted-foreground\/25 hover:border-muted-foreground\/50',\n                )}\n                onDragOver={(e) => {\n                    e.preventDefault();\n                    setIsDragging(true);\n                }}\n                onDragLeave={() => setIsDragging(false)}\n                onDrop={handleDrop}\n                onClick={() => inputRef.current?.click()}\n                onKeyDown={(e) => {\n                    if (e.key === 'Enter' || e.key === ' ') {\n                        e.preventDefault();\n                        inputRef.current?.click();\n                    }\n                }}\n                tabIndex={0}\n                role=\"button\"\n                aria-label=\"Upload images\"\n            >\n                <Upload className=\"size-8 text-muted-foreground\" \/>\n                <div className=\"text-center\">\n                    <p className=\"text-sm font-medium\">\n                        Click or drag images to upload\n                    <\/p>\n                    <p className=\"text-xs text-muted-foreground\">\n                        {files.length} of {maxFiles} images\n                    <\/p>\n                <\/div>\n            <\/div>\n\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                multiple\n                onChange={(e) => e.target.files && handleFiles(e.target.files)}\n                className=\"sr-only\"\n            \/>\n\n            {files.length > 0 && (\n                <>\n                    <div className=\"flex items-center justify-between\">\n                        <p className=\"text-sm text-muted-foreground\">\n                            {enableReorder\n                                ? 'Drag cards to reorder. First image is primary.'\n                                : 'Click star to set primary image.'}\n                        <\/p>\n                        <Button\n                            variant=\"outline\"\n                            size=\"sm\"\n                            onClick={clearAll}\n                            className=\"gap-1\"\n                        >\n                            <Trash2 className=\"size-3\" \/>\n                            Clear All\n                        <\/Button>\n                    <\/div>\n\n                    {enableReorder ? (\n                        <DragDropProvider onDragEnd={handleDragEnd}>\n                            {cardsContent}\n                        <\/DragDropProvider>\n                    ) : (\n                        cardsContent\n                    )}\n                <\/>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-sortable-grid","type":"registry:ui","title":"Gallery Dropzone Sortable Grid","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react","@dnd-kit\/react"],"devDependencies":[],"registryDependencies":["utils","button"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-sortable-grid.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Upload, X, ImageIcon, GripVertical } from 'lucide-react';\nimport { DragDropProvider } from '@dnd-kit\/react';\nimport { useSortable, isSortable } from '@dnd-kit\/react\/sortable';\n\ninterface FileWithPreview {\n    file: File;\n    preview: string;\n    id: string;\n}\n\ninterface SortableImageProps {\n    image: FileWithPreview;\n    index: number;\n    onRemove: (id: string) => void;\n    showHandle?: boolean;\n}\n\nfunction SortableImage({\n    image,\n    index,\n    onRemove,\n    showHandle,\n}: SortableImageProps) {\n    const { ref, handleRef, isDragging } = useSortable({\n        id: image.id,\n        index,\n    });\n\n    return (\n        <div\n            ref={ref}\n            className={cn(\n                'group relative aspect-square overflow-hidden rounded-md border bg-muted transition-all',\n                isDragging && 'z-10 scale-105 shadow-lg ring-2 ring-primary',\n            )}\n        >\n            <img\n                src={image.preview}\n                alt=\"\"\n                className=\"size-full object-cover\"\n                draggable={false}\n            \/>\n\n            {showHandle && (\n                <button\n                    ref={handleRef}\n                    className=\"absolute top-1 left-1 flex size-6 cursor-grab items-center justify-center rounded bg-background\/80 opacity-0 shadow-sm transition-opacity group-hover:opacity-100 active:cursor-grabbing\"\n                    aria-label=\"Drag to reorder\"\n                >\n                    <GripVertical className=\"size-3\" \/>\n                <\/button>\n            )}\n\n            <button\n                onClick={() => onRemove(image.id)}\n                className=\"absolute top-1 right-1 flex size-6 items-center justify-center rounded-full bg-background\/80 opacity-0 shadow-sm transition-opacity group-hover:opacity-100\"\n                aria-label=\"Remove image\"\n            >\n                <X className=\"size-3\" \/>\n            <\/button>\n\n            <div className=\"absolute bottom-1 left-1 flex size-5 items-center justify-center rounded bg-foreground\/70 text-xs font-medium text-background\">\n                {index + 1}\n            <\/div>\n        <\/div>\n    );\n}\n\ninterface GalleryDropzoneSortableGridProps {\n    onFilesSelect?: (files: File[]) => void;\n    onReorder?: (files: File[]) => void;\n    maxFiles?: number;\n    maxSize?: number;\n    className?: string;\n    enableReorder?: boolean;\n}\n\nexport function GalleryDropzoneSortableGrid({\n    onFilesSelect,\n    onReorder,\n    maxFiles = 9,\n    maxSize = 10 * 1024 * 1024,\n    className,\n    enableReorder = true,\n}: GalleryDropzoneSortableGridProps) {\n    const [files, setFiles] = React.useState<FileWithPreview[]>([]);\n    const [isDragging, setIsDragging] = React.useState(false);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const handleFiles = React.useCallback(\n        (newFiles: FileList) => {\n            const validFiles = Array.from(newFiles)\n                .filter(\n                    (file) =>\n                        file.type.startsWith('image\/') && file.size <= maxSize,\n                )\n                .slice(0, maxFiles - files.length);\n\n            const newFileObjects = validFiles.map((file) => ({\n                file,\n                preview: URL.createObjectURL(file),\n                id: Math.random().toString(36).slice(2),\n            }));\n\n            const updated = [...files, ...newFileObjects].slice(0, maxFiles);\n            setFiles(updated);\n            onFilesSelect?.(updated.map((f) => f.file));\n        },\n        [files, maxFiles, maxSize, onFilesSelect],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragging(false);\n            if (e.dataTransfer.files.length) handleFiles(e.dataTransfer.files);\n        },\n        [handleFiles],\n    );\n\n    const removeFile = (id: string) => {\n        const updated = files.filter((f) => f.id !== id);\n        setFiles(updated);\n        onFilesSelect?.(updated.map((f) => f.file));\n    };\n\n    const clearAll = () => {\n        setFiles([]);\n        onFilesSelect?.([]);\n        if (inputRef.current) inputRef.current.value = '';\n    };\n\n    const handleDragEnd = React.useCallback(\n        (event: { canceled: boolean; operation: { source: unknown } }) => {\n            if (event.canceled) return;\n\n            const source = event.operation.source as any;\n\n            if (isSortable(source)) {\n                const { initialIndex, index } = source;\n\n                if (initialIndex !== index) {\n                    setFiles((prev) => {\n                        const newFiles = [...prev];\n                        const [removed] = newFiles.splice(initialIndex, 1);\n                        newFiles.splice(index, 0, removed);\n                        onReorder?.(newFiles.map((f) => f.file));\n                        return newFiles;\n                    });\n                }\n            }\n        },\n        [onReorder],\n    );\n\n    const gridContent = (\n        <div className=\"grid grid-cols-3 gap-3\">\n            {files.map((file, index) => (\n                <SortableImage\n                    key={file.id}\n                    image={file}\n                    index={index}\n                    onRemove={removeFile}\n                    showHandle={enableReorder}\n                \/>\n            ))}\n\n            {files.length < maxFiles && (\n                <button\n                    onClick={() => inputRef.current?.click()}\n                    className=\"flex aspect-square flex-col items-center justify-center gap-1 rounded-md border-2 border-dashed border-muted-foreground\/25 text-muted-foreground transition-colors hover:border-muted-foreground\/50 hover:bg-muted\/50\"\n                >\n                    <ImageIcon className=\"size-5\" \/>\n                    <span className=\"text-xs\">Add<\/span>\n                <\/button>\n            )}\n        <\/div>\n    );\n\n    return (\n        <div className={cn('space-y-4', className)}>\n            {files.length === 0 && (\n                <div\n                    className={cn(\n                        'flex min-h-[160px] cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-6 transition-colors',\n                        isDragging\n                            ? 'border-primary bg-primary\/5'\n                            : 'border-muted-foreground\/25 hover:border-muted-foreground\/50',\n                    )}\n                    onDragOver={(e) => {\n                        e.preventDefault();\n                        setIsDragging(true);\n                    }}\n                    onDragLeave={() => setIsDragging(false)}\n                    onDrop={handleDrop}\n                    onClick={() => inputRef.current?.click()}\n                    onKeyDown={(e) => {\n                        if (e.key === 'Enter' || e.key === ' ') {\n                            e.preventDefault();\n                            inputRef.current?.click();\n                        }\n                    }}\n                    tabIndex={0}\n                    role=\"button\"\n                    aria-label=\"Upload images\"\n                >\n                    <div className=\"flex size-12 items-center justify-center rounded-full bg-muted\">\n                        <Upload className=\"size-6 text-muted-foreground\" \/>\n                    <\/div>\n                    <div className=\"text-center\">\n                        <p className=\"text-sm font-medium\">\n                            Drop images here or click to upload\n                        <\/p>\n                        <p className=\"text-xs text-muted-foreground\">\n                            PNG, JPG, GIF up to{' '}\n                            {Math.round(maxSize \/ 1024 \/ 1024)}MB\n                        <\/p>\n                    <\/div>\n                <\/div>\n            )}\n\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                multiple\n                onChange={(e) => e.target.files && handleFiles(e.target.files)}\n                className=\"sr-only\"\n            \/>\n\n            {files.length > 0 && (\n                <div className=\"space-y-3\">\n                    <div className=\"flex items-center justify-between\">\n                        <p className=\"text-sm text-muted-foreground\">\n                            {files.length} of {maxFiles} images\n                            {enableReorder && (\n                                <span className=\"ml-2 text-xs\">\n                                    (drag to reorder)\n                                <\/span>\n                            )}\n                        <\/p>\n                        <Button\n                            variant=\"ghost\"\n                            size=\"sm\"\n                            onClick={clearAll}\n                            className=\"text-muted-foreground\"\n                        >\n                            Clear all\n                        <\/Button>\n                    <\/div>\n\n                    {enableReorder ? (\n                        <DragDropProvider onDragEnd={handleDragEnd}>\n                            {gridContent}\n                        <\/DragDropProvider>\n                    ) : (\n                        gridContent\n                    )}\n                <\/div>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-sortable-list","type":"registry:ui","title":"Gallery Dropzone Sortable List","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react","@dnd-kit\/react"],"devDependencies":[],"registryDependencies":["utils","button","badge","separator","scroll-area"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-sortable-list.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Badge } from '@\/components\/ui\/badge';\nimport { Separator } from '@\/components\/ui\/separator';\nimport { ScrollArea } from '@\/components\/ui\/scroll-area';\nimport {\n    ImageIcon,\n    Upload,\n    X,\n    GripVertical,\n    Check,\n    AlertCircle,\n} from 'lucide-react';\nimport { DragDropProvider } from '@dnd-kit\/react';\nimport { useSortable, isSortable } from '@dnd-kit\/react\/sortable';\n\ninterface ImageFile {\n    id: string;\n    file: File;\n    preview: string;\n    status: 'ready' | 'uploading' | 'success' | 'error';\n}\n\ninterface SortableListItemProps {\n    image: ImageFile;\n    index: number;\n    onRemove: (id: string) => void;\n    showHandle?: boolean;\n}\n\nfunction SortableListItem({\n    image,\n    index,\n    onRemove,\n    showHandle,\n}: SortableListItemProps) {\n    const { ref, handleRef, isDragging } = useSortable({\n        id: image.id,\n        index,\n    });\n\n    const formatSize = (bytes: number) => {\n        if (bytes < 1024) return bytes + ' B';\n        if (bytes < 1024 * 1024) return (bytes \/ 1024).toFixed(1) + ' KB';\n        return (bytes \/ (1024 * 1024)).toFixed(1) + ' MB';\n    };\n\n    return (\n        <div\n            ref={ref}\n            className={cn(\n                'flex items-center gap-3 rounded-md p-2 transition-all',\n                isDragging && 'z-10 bg-muted shadow-md ring-1 ring-border',\n            )}\n        >\n            {showHandle && (\n                <button\n                    ref={handleRef}\n                    className=\"flex size-8 shrink-0 cursor-grab items-center justify-center rounded text-muted-foreground hover:bg-muted active:cursor-grabbing\"\n                    aria-label=\"Drag to reorder\"\n                >\n                    <GripVertical className=\"size-4\" \/>\n                <\/button>\n            )}\n\n            <div className=\"size-10 shrink-0 overflow-hidden rounded border bg-muted\">\n                {image.preview ? (\n                    <img\n                        src={image.preview}\n                        alt=\"\"\n                        className=\"size-full object-cover\"\n                    \/>\n                ) : (\n                    <div className=\"flex size-full items-center justify-center\">\n                        <ImageIcon className=\"size-4 text-muted-foreground\" \/>\n                    <\/div>\n                )}\n            <\/div>\n\n            <div className=\"flex min-w-0 flex-1 flex-col\">\n                <span className=\"truncate text-sm font-medium\">\n                    {image.file.name}\n                <\/span>\n                <span className=\"text-xs text-muted-foreground\">\n                    {formatSize(image.file.size)}\n                <\/span>\n            <\/div>\n\n            <div className=\"flex items-center gap-2\">\n                {image.status === 'success' && (\n                    <Badge variant=\"secondary\" className=\"text-success gap-1\">\n                        <Check className=\"size-3\" \/>\n                        Done\n                    <\/Badge>\n                )}\n                {image.status === 'error' && (\n                    <Badge variant=\"destructive\" className=\"gap-1\">\n                        <AlertCircle className=\"size-3\" \/>\n                        Error\n                    <\/Badge>\n                )}\n\n                <Button\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    onClick={() => onRemove(image.id)}\n                    className=\"size-8 p-0 text-muted-foreground hover:text-destructive\"\n                >\n                    <X className=\"size-4\" \/>\n                <\/Button>\n            <\/div>\n        <\/div>\n    );\n}\n\ninterface GalleryDropzoneSortableListProps {\n    className?: string;\n    onFilesChange?: (files: File[]) => void;\n    onReorder?: (files: File[]) => void;\n    maxFiles?: number;\n    maxSize?: number;\n    enableReorder?: boolean;\n}\n\nexport function GalleryDropzoneSortableList({\n    className,\n    onFilesChange,\n    onReorder,\n    maxFiles = 10,\n    maxSize = 10,\n    enableReorder = true,\n}: GalleryDropzoneSortableListProps) {\n    const [isDragOver, setIsDragOver] = React.useState(false);\n    const [images, setImages] = React.useState<ImageFile[]>([]);\n    const inputRef = React.useRef<HTMLInputElement>(null);\n\n    const processFiles = React.useCallback(\n        (files: FileList | File[]) => {\n            const fileArray = Array.from(files);\n            const remainingSlots = maxFiles - images.length;\n            const filesToProcess = fileArray.slice(0, remainingSlots);\n\n            const newImages: ImageFile[] = filesToProcess\n                .filter(\n                    (file) =>\n                        file.type.startsWith('image\/') &&\n                        file.size <= maxSize * 1024 * 1024,\n                )\n                .map((file) => {\n                    const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n                    const preview = URL.createObjectURL(file);\n                    return { id, file, preview, status: 'ready' as const };\n                });\n\n            const updated = [...images, ...newImages];\n            setImages(updated);\n            onFilesChange?.(updated.map((i) => i.file));\n        },\n        [images, maxFiles, maxSize, onFilesChange],\n    );\n\n    const handleDrop = React.useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragOver(false);\n            processFiles(e.dataTransfer.files);\n        },\n        [processFiles],\n    );\n\n    const handleRemove = React.useCallback(\n        (id: string) => {\n            setImages((prev) => {\n                const updated = prev.filter((img) => img.id !== id);\n                onFilesChange?.(updated.map((i) => i.file));\n                return updated;\n            });\n        },\n        [onFilesChange],\n    );\n\n    const handleDragEnd = React.useCallback(\n        (event: { canceled: boolean; operation: { source: unknown } }) => {\n            if (event.canceled) return;\n\n            const source = event.operation.source as any;\n\n            if (isSortable(source)) {\n                const { initialIndex, index } = source;\n\n                if (initialIndex !== index) {\n                    setImages((prev) => {\n                        const newImages = [...prev];\n                        const [removed] = newImages.splice(initialIndex, 1);\n                        newImages.splice(index, 0, removed);\n                        onReorder?.(newImages.map((f) => f.file));\n                        return newImages;\n                    });\n                }\n            }\n        },\n        [onReorder],\n    );\n\n    const listContent = (\n        <div className=\"space-y-1\">\n            {images.map((image, idx) => (\n                <React.Fragment key={image.id}>\n                    <SortableListItem\n                        image={image}\n                        index={idx}\n                        onRemove={handleRemove}\n                        showHandle={enableReorder}\n                    \/>\n                    {idx < images.length - 1 && <Separator \/>}\n                <\/React.Fragment>\n            ))}\n        <\/div>\n    );\n\n    return (\n        <div\n            className={cn(\n                'flex flex-col gap-4 rounded-lg border p-4',\n                className,\n            )}\n        >\n            <div\n                role=\"button\"\n                tabIndex={0}\n                aria-label=\"Upload images\"\n                onClick={() => inputRef.current?.click()}\n                onKeyDown={(e) =>\n                    (e.key === 'Enter' || e.key === ' ') &&\n                    inputRef.current?.click()\n                }\n                onDrop={handleDrop}\n                onDragOver={(e) => {\n                    e.preventDefault();\n                    setIsDragOver(true);\n                }}\n                onDragLeave={(e) => {\n                    e.preventDefault();\n                    setIsDragOver(false);\n                }}\n                className={cn(\n                    'flex cursor-pointer flex-col items-center gap-3 rounded-md border-2 border-dashed p-6 transition-colors',\n                    isDragOver\n                        ? 'border-primary bg-primary\/5'\n                        : 'border-muted hover:border-muted-foreground\/50',\n                )}\n            >\n                <div className=\"rounded-full bg-muted p-3\">\n                    <Upload className=\"size-5 text-muted-foreground\" \/>\n                <\/div>\n                <div className=\"text-center\">\n                    <p className=\"text-sm font-medium\">\n                        Drop files here or click to browse\n                    <\/p>\n                    <p className=\"text-xs text-muted-foreground\">\n                        Max {maxFiles} files, {maxSize}MB each\n                    <\/p>\n                <\/div>\n            <\/div>\n\n            <input\n                ref={inputRef}\n                type=\"file\"\n                accept=\"image\/*\"\n                multiple\n                onChange={(e) => e.target.files && processFiles(e.target.files)}\n                className=\"sr-only\"\n            \/>\n\n            {images.length > 0 && (\n                <>\n                    <div className=\"flex items-center justify-between\">\n                        <span className=\"text-sm font-medium\">\n                            {images.length} file{images.length > 1 ? 's' : ''}\n                            {enableReorder && (\n                                <span className=\"ml-2 text-xs text-muted-foreground\">\n                                    (drag to reorder)\n                                <\/span>\n                            )}\n                        <\/span>\n                        <Button\n                            variant=\"ghost\"\n                            size=\"sm\"\n                            onClick={() => {\n                                setImages([]);\n                                onFilesChange?.([]);\n                            }}\n                            className=\"h-7 text-xs text-muted-foreground hover:text-destructive\"\n                        >\n                            Clear all\n                        <\/Button>\n                    <\/div>\n\n                    <ScrollArea className=\"max-h-[280px]\">\n                        {enableReorder ? (\n                            <DragDropProvider onDragEnd={handleDragEnd}>\n                                {listContent}\n                            <\/DragDropProvider>\n                        ) : (\n                            listContent\n                        )}\n                    <\/ScrollArea>\n                <\/>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"gallery-dropzone-table","type":"registry:ui","title":"Gallery Dropzone Table","description":"A beautiful component for your application.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","button","progress","table"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/dropzones\/gallery-dropzone-table.tsx","type":"registry:ui","content":"'use client';\n\nimport { useState, useCallback, useRef } from 'react';\nimport { Upload, X, File, Check, Loader2 } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Button } from '@\/components\/ui\/button';\nimport { Progress } from '@\/components\/ui\/progress';\nimport {\n    Table,\n    TableBody,\n    TableCell,\n    TableHead,\n    TableHeader,\n    TableRow,\n} from '@\/components\/ui\/table';\n\ninterface FileWithProgress {\n    file: File;\n    preview: string;\n    id: string;\n    progress: number;\n    status: 'uploading' | 'complete' | 'error';\n}\n\ninterface GalleryDropzoneTableProps {\n    onFilesSelect?: (files: File[]) => void;\n    maxFiles?: number;\n    maxSize?: number;\n    className?: string;\n}\n\nexport function GalleryDropzoneTable({\n    onFilesSelect,\n    maxFiles = 10,\n    maxSize = 10 * 1024 * 1024,\n    className,\n}: GalleryDropzoneTableProps) {\n    const [files, setFiles] = useState<FileWithProgress[]>([]);\n    const [isDragging, setIsDragging] = useState(false);\n    const inputRef = useRef<HTMLInputElement>(null);\n\n    const handleFiles = useCallback(\n        (newFiles: FileList) => {\n            const validFiles = Array.from(newFiles)\n                .filter(\n                    (file) =>\n                        file.type.startsWith('image\/') && file.size <= maxSize,\n                )\n                .slice(0, maxFiles - files.length);\n\n            const newFileObjects = validFiles.map((file) => ({\n                file,\n                preview: URL.createObjectURL(file),\n                id: Math.random().toString(36).slice(2),\n                progress: 0,\n                status: 'uploading' as const,\n            }));\n\n            const updated = [...files, ...newFileObjects].slice(0, maxFiles);\n            setFiles(updated);\n\n            \/\/ Simulate upload progress\n            newFileObjects.forEach((fileObj) => {\n                let progress = 0;\n                const interval = setInterval(() => {\n                    progress += Math.random() * 30;\n                    if (progress >= 100) {\n                        progress = 100;\n                        clearInterval(interval);\n                        setFiles((prev) =>\n                            prev.map((f) =>\n                                f.id === fileObj.id\n                                    ? {\n                                          ...f,\n                                          progress: 100,\n                                          status: 'complete',\n                                      }\n                                    : f,\n                            ),\n                        );\n                    } else {\n                        setFiles((prev) =>\n                            prev.map((f) =>\n                                f.id === fileObj.id ? { ...f, progress } : f,\n                            ),\n                        );\n                    }\n                }, 200);\n            });\n\n            onFilesSelect?.(updated.map((f) => f.file));\n        },\n        [files, maxFiles, maxSize, onFilesSelect],\n    );\n\n    const handleDrop = useCallback(\n        (e: React.DragEvent) => {\n            e.preventDefault();\n            setIsDragging(false);\n            if (e.dataTransfer.files.length) handleFiles(e.dataTransfer.files);\n        },\n        [handleFiles],\n    );\n\n    const removeFile = (id: string) => {\n        const updated = files.filter((f) => f.id !== id);\n        setFiles(updated);\n        onFilesSelect?.(updated.map((f) => f.file));\n    };\n\n    const formatSize = (bytes: number) => {\n        if (bytes < 1024) return `${bytes} B`;\n        if (bytes < 1024 * 1024) return `${(bytes \/ 1024).toFixed(1)} KB`;\n        return `${(bytes \/ 1024 \/ 1024).toFixed(1)} MB`;\n    };\n\n    return (\n        <div className={cn('space-y-4', className)}>\n            <div\n                className={cn(\n                    'flex cursor-pointer items-center justify-center gap-3 rounded-lg border-2 border-dashed p-4 transition-colors',\n                    isDragging\n                        ? 'border-primary bg-muted\/50'\n                        : 'border-muted-foreground\/25 hover:border-muted-foreground\/50',\n                )}\n                onDragOver={(e) => {\n                    e.preventDefault();\n                    setIsDragging(true);\n                }}\n                onDragLeave={() => setIsDragging(false)}\n                onDrop={handleDrop}\n                onClick={() => inputRef.current?.click()}\n                tabIndex={0}\n                role=\"button\"\n                aria-label=\"Upload images\"\n            >\n                <input\n                    ref={inputRef}\n                    type=\"file\"\n                    accept=\"image\/*\"\n                    multiple\n                    onChange={(e) =>\n                        e.target.files && handleFiles(e.target.files)\n                    }\n                    className=\"sr-only\"\n                \/>\n\n                <Upload className=\"size-5 text-muted-foreground\" \/>\n                <span className=\"text-sm\">\n                    Drop files here or click to browse\n                <\/span>\n            <\/div>\n\n            {files.length > 0 && (\n                <div className=\"rounded-md border\">\n                    <Table>\n                        <TableHeader>\n                            <TableRow>\n                                <TableHead className=\"w-12\"><\/TableHead>\n                                <TableHead>Name<\/TableHead>\n                                <TableHead className=\"w-24\">Size<\/TableHead>\n                                <TableHead className=\"w-32\">Status<\/TableHead>\n                                <TableHead className=\"w-12\"><\/TableHead>\n                            <\/TableRow>\n                        <\/TableHeader>\n                        <TableBody>\n                            {files.map((file) => (\n                                <TableRow key={file.id}>\n                                    <TableCell>\n                                        <div className=\"size-10 overflow-hidden rounded border bg-muted\">\n                                            <img\n                                                src={file.preview}\n                                                alt=\"\"\n                                                className=\"size-full object-cover\"\n                                            \/>\n                                        <\/div>\n                                    <\/TableCell>\n                                    <TableCell className=\"font-medium\">\n                                        <span className=\"line-clamp-1\">\n                                            {file.file.name}\n                                        <\/span>\n                                    <\/TableCell>\n                                    <TableCell className=\"text-muted-foreground\">\n                                        {formatSize(file.file.size)}\n                                    <\/TableCell>\n                                    <TableCell>\n                                        {file.status === 'uploading' ? (\n                                            <div className=\"flex items-center gap-2\">\n                                                <Progress\n                                                    value={file.progress}\n                                                    className=\"h-2 w-16\"\n                                                \/>\n                                                <span className=\"text-xs text-muted-foreground\">\n                                                    {Math.round(file.progress)}%\n                                                <\/span>\n                                            <\/div>\n                                        ) : (\n                                            <div className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n                                                <Check className=\"size-4\" \/>\n                                                Complete\n                                            <\/div>\n                                        )}\n                                    <\/TableCell>\n                                    <TableCell>\n                                        <Button\n                                            variant=\"ghost\"\n                                            size=\"icon\"\n                                            className=\"size-8\"\n                                            onClick={() => removeFile(file.id)}\n                                        >\n                                            <X className=\"size-4\" \/>\n                                        <\/Button>\n                                    <\/TableCell>\n                                <\/TableRow>\n                            ))}\n                        <\/TableBody>\n                    <\/Table>\n                <\/div>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"dropzones","version":"1.0.0"},"categories":["dropzones"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"back-light","type":"registry:ui","title":"Back Light","description":"A modern card wrapper creating a glowing, color-matching backlight shadow behind components.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/glow\/back-light.tsx","type":"registry:ui","content":"import type { ReactNode } from 'react';\nimport { useId } from 'react';\nimport { cn } from '@\/lib\/utils';\n\ntype BackLightProps = {\n    children?: ReactNode;\n    className?: string;\n    blur?: number;\n    intensity?: number;\n    saturation?: number;\n    opacity?: number;\n};\n\nexport function BackLight({\n    blur = 20,\n    intensity = 1,\n    saturation = 4,\n    opacity = 0.6,\n    children,\n    className,\n}: BackLightProps) {\n    const id = useId();\n\n    return (\n        <div className={cn('relative', className)}>\n            <svg width=\"0\" height=\"0\" aria-hidden=\"true\">\n                <filter id={id} x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n                    <feGaussianBlur stdDeviation={blur} result=\"blur\" \/>\n                    <feColorMatrix\n                        in=\"blur\"\n                        type=\"matrix\"\n                        values={`\n              ${saturation} 0 0 0 0\n              0 ${saturation} 0 0 0\n              0 0 ${saturation} 0 0\n              0 0 0 ${intensity} 0\n            `}\n                    \/>\n                <\/filter>\n            <\/svg>\n\n            {\/* Glow layer *\/}\n            <div\n                style={{\n                    position: 'absolute',\n                    inset: 0,\n                    filter: `url(#${id})`,\n                    opacity,\n                    pointerEvents: 'none',\n                    willChange: 'filter',\n                    transform: 'translateZ(0)',\n                }}\n            >\n                {children}\n            <\/div>\n\n            {\/* Actual content *\/}\n            <div style={{ position: 'relative' }}>{children}<\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"glow","version":"1.0.0"},"categories":["glow"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"glow-conic","type":"registry:ui","title":"Glow Conic","description":"A beautiful border animation powered by a rotating conic color gradient.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/glow\/glow-conic.tsx","type":"registry:ui","content":"import { cn } from '@\/lib\/utils';\n\nexport interface GlowConicProps {\n    className?: string;\n    style?: React.CSSProperties;\n    [key: string]: unknown;\n}\n\nexport default function GlowConic({\n    className,\n    style,\n    ...props\n}: GlowConicProps) {\n    return (\n        <div\n            {...props}\n            className={cn(\n                'absolute inset-0 animate-glow-conic rounded-[inherit] p-px',\n                className,\n            )}\n            style={{\n                background:\n                    'repeating-conic-gradient(from var(--glow-conic-angle), var(--conic-color) 0%, transparent 50%)',\n                mask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0) border-box',\n                maskComposite: 'exclude' as const,\n                WebkitMask:\n                    'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0) border-box',\n                WebkitMaskComposite: 'xor' as const,\n                ...style,\n            }}\n        ><\/div>\n    );\n}\n"}],"meta":{"category":"glow","version":"1.0.0"},"categories":["glow"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"glow-radial","type":"registry:ui","title":"Glow Radial","description":"An interactive background overlay that reflects cursor positioning with radial gradients. Requires GlowStack wrapping to function.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","https:\/\/ui.test\/r\/glow-stack.json","https:\/\/ui.test\/r\/glow-geometry.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/glow\/glow-radial.tsx","type":"registry:ui","content":"'use client';\nimport type { HTMLAttributes, ReactNode } from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { useGlowStack } from '@\/registry\/new-york\/components\/ui\/glow\/glow-stack';\nimport {\n    isCircleOverlappingRect,\n    isPointInRect,\n    toElementSpace,\n} from '@\/registry\/new-york\/lib\/glow-geometry';\n\nconst BORDER_MASK = {\n    padding: '2px',\n    background: 'transparent',\n    mask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0) border-box',\n    maskComposite: 'exclude' as const,\n    WebkitMask:\n        'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0) border-box',\n    WebkitMaskComposite: 'xor' as const,\n} as const;\n\ninterface GlowRadialProps extends HTMLAttributes<HTMLElement> {\n    children?: ReactNode;\n    \/** Colors for the radial gradient. First color is the center. *\/\n    colors?: string | string[];\n    \/** Gradient radius in px. Default: 500 *\/\n    size?: number;\n    \/** Border width in px. Default: 2 *\/\n    borderWidth?: number;\n    \/** Render as any block element. Default: \"div\" *\/\n    as?: 'div' | 'section' | 'article' | 'main' | 'header' | 'footer' | 'aside';\n}\n\n\/**\n * GlowRadial creates an interactive mouse-glow border and background effect.\n *\n * IMPORTANT: This component MUST be wrapped inside a <GlowStack> component\n * to track mouse movements and function properly.\n *\/\nexport function GlowRadial({\n    className,\n    children,\n    colors = 'var(--color-primary)',\n    size = 500,\n    borderWidth = 3,\n    as: Comp = 'div',\n    style,\n    ...props\n}: GlowRadialProps) {\n    const ref = useRef<HTMLDivElement>(null);\n    const glowStack = useGlowStack();\n    const position = glowStack?.position ?? { x: -1000, y: -1000 };\n    const radius = glowStack?.radius ?? 100;\n    const [rect, setRect] = useState<DOMRect | null>(null);\n\n    useEffect(() => {\n        const updateRect = () => {\n            setRect(ref.current?.getBoundingClientRect() ?? null);\n        };\n\n        updateRect();\n\n        const handleUpdate = () => updateRect();\n        window.addEventListener('resize', handleUpdate, { passive: true });\n        window.addEventListener('scroll', handleUpdate, { passive: true });\n\n        return () => {\n            window.removeEventListener('resize', handleUpdate);\n            window.removeEventListener('scroll', handleUpdate);\n        };\n    }, []);\n\n    const near = rect ? isCircleOverlappingRect(position, radius, rect) : false;\n    const over = rect ? isPointInRect(position, rect) : false;\n    const ep = rect ? toElementSpace(position, rect) : { x: 0, y: 0 };\n\n    const colorsArray = Array.isArray(colors)\n        ? colors\n        : [colors, 'transparent'];\n    const gradient = `radial-gradient(circle at ${ep.x}px ${ep.y}px, ${colorsArray.join(', ')}, transparent ${size}px)`;\n    const borderMask = { ...BORDER_MASK, padding: `${borderWidth}px` };\n\n    return (\n        <Comp\n            ref={ref}\n            className={cn(\n                'absolute inset-0 isolate z-10 rounded-[inherit]',\n                children ? 'pointer-events-auto' : 'pointer-events-none',\n                className,\n            )}\n            style={style}\n            {...props}\n        >\n            {\/* Hard border glow *\/}\n            <div\n                aria-hidden\n                className={cn(\n                    'pointer-events-none! absolute inset-0 z-10 rounded-[inherit] transition-opacity duration-300',\n                    near ? 'opacity-100' : 'opacity-0',\n                )}\n                style={{ ...borderMask, background: gradient }}\n            \/>\n            {\/* Soft blur halo *\/}\n            <div\n                aria-hidden\n                className={cn(\n                    'pointer-events-none! absolute inset-0 rounded-[inherit] blur-2xl transition-opacity duration-300',\n                    near ? 'opacity-10' : 'opacity-0',\n                )}\n                style={{ ...borderMask, background: gradient }}\n            \/>\n            {\/* Subtle fill when directly over *\/}\n            <div\n                aria-hidden\n                className={cn(\n                    'pointer-events-none! absolute inset-0 rounded-[inherit] transition-opacity duration-300',\n                    over ? 'opacity-5' : 'opacity-0',\n                )}\n                style={{ background: gradient }}\n            \/>\n            {children}\n        <\/Comp>\n    );\n}\n"}],"meta":{"category":"glow","version":"1.0.0"},"categories":["glow"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"glow-stack","type":"registry:ui","title":"Glow Stack","description":"A coordinated hover effect sharing cursor coordinates across a card stack.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":[],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/glow\/glow-stack.tsx","type":"registry:ui","content":"'use client';\nimport { createContext, useContext, useEffect, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\n\ninterface MouseGlowContext {\n    position: { x: number; y: number };\n    radius: number;\n}\nexport const GlowContext = createContext<MouseGlowContext>({\n    position: { x: -9999, y: -9999 },\n    radius: 100,\n});\nexport const useGlowStack = (): MouseGlowContext => {\n    const context = useContext(GlowContext);\n\n    return context ?? { position: { x: -9999, y: -9999 }, radius: 100 };\n};\n\ninterface GlowStackProps {\n    children: ReactNode;\n    radius?: number;\n    className?: string;\n    style?: React.CSSProperties;\n}\n\nexport function GlowStack({\n    children,\n    radius = 100,\n    className,\n    style,\n}: GlowStackProps) {\n    const [pos, setPos] = useState({ x: -9999, y: -9999 });\n    const rafRef = useRef<number>(0);\n\n    useEffect(() => {\n        const onMove = (e: MouseEvent) => {\n            cancelAnimationFrame(rafRef.current);\n            rafRef.current = requestAnimationFrame(() =>\n                setPos({ x: e.clientX, y: e.clientY }),\n            );\n        };\n\n        window.addEventListener('mousemove', onMove, { passive: true });\n\n        return () => {\n            window.removeEventListener('mousemove', onMove);\n            cancelAnimationFrame(rafRef.current);\n        };\n    }, []);\n\n    return (\n        <GlowContext.Provider value={{ position: pos, radius }}>\n            <div className={className} style={style}>\n                {children}\n            <\/div>\n        <\/GlowContext.Provider>\n    );\n}\n"}],"meta":{"category":"glow","version":"1.0.0"},"categories":["glow"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"input-currency","type":"registry:ui","title":"Input Currency","description":"A smart text input formatting numeric entries into localized currency notation as you type.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["input","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/inputs\/input-currency.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { Input } from '@\/components\/ui\/input';\nimport { cn } from '@\/lib\/utils';\n\ninterface InputCurrencyProps extends Omit<\n    React.InputHTMLAttributes<HTMLInputElement>,\n    'value' | 'onChange'\n> {\n    \/**\n     * The numeric value (as float or integer)\n     *\/\n    value?: number | string;\n    \/**\n     * Callback when the numeric value changes\n     * @param value The parsed number or raw string representation\n     * @param formattedValue The formatted display value\n     *\/\n    onValueChange?: (value: number | undefined, formattedValue: string) => void;\n    \/**\n     * ISO 4217 Currency Code\n     * @default 'USD'\n     *\/\n    currency?: string;\n    \/**\n     * Locale for formatting\n     * @default 'en-US'\n     *\/\n    locale?: string;\n    \/**\n     * Allow decimal digits\n     * @default true\n     *\/\n    allowDecimals?: boolean;\n    \/**\n     * Maximum decimal places allowed\n     * @default 2\n     *\/\n    decimalsLimit?: boolean | number;\n    \/**\n     * Allow negative values\n     * @default false\n     *\/\n    allowNegativeValue?: boolean;\n}\n\n\/**\n * Get currency symbol based on locale and currency code\n *\/\nfunction getCurrencySymbol(locale: string, currency: string): string {\n    try {\n        return (0)\n            .toLocaleString(locale, {\n                style: 'currency',\n                currency,\n                minimumFractionDigits: 0,\n                maximumFractionDigits: 0,\n            })\n            .replace(\/\\d\/g, '')\n            .trim();\n    } catch {\n        return '$';\n    }\n}\n\n\/**\n * Format string as currency while typing\n *\/\nfunction formatCurrencyString(\n    value: string,\n    locale: string,\n    allowDecimals: boolean,\n    decimalsLimit: number,\n    allowNegative: boolean,\n): string {\n    if (!value) return '';\n\n    \/\/ Check if it's negative\n    const isNegative = allowNegative && value.startsWith('-');\n\n    \/\/ Clean string: keep digits, dot, and handle empty state\n    let clean = value.replace(\/[^\\d.]\/g, '');\n\n    \/\/ Make sure we only have one decimal point\n    const dotIdx = clean.indexOf('.');\n    if (dotIdx !== -1) {\n        clean =\n            clean.substring(0, dotIdx + 1) +\n            clean.substring(dotIdx + 1).replace(\/\\.\/g, '');\n    }\n\n    const parts = clean.split('.');\n    let integerPart = parts[0];\n    let decimalPart = parts[1];\n\n    if (integerPart) {\n        const number = parseInt(integerPart, 10);\n        if (!isNaN(number)) {\n            integerPart = new Intl.NumberFormat(locale, {\n                useGrouping: true,\n            }).format(number);\n        }\n    }\n\n    if (allowDecimals && decimalPart !== undefined) {\n        decimalPart = decimalPart.slice(0, decimalsLimit);\n        return `${isNegative ? '-' : ''}${integerPart}.${decimalPart}`;\n    }\n\n    return `${isNegative ? '-' : ''}${integerPart}`;\n}\n\nconst InputCurrency = React.forwardRef<HTMLInputElement, InputCurrencyProps>(\n    (\n        {\n            value: controlledValue,\n            onValueChange,\n            currency = 'USD',\n            locale = 'en-US',\n            allowDecimals = true,\n            decimalsLimit = 2,\n            allowNegativeValue = false,\n            className,\n            placeholder = '0.00',\n            onBlur,\n            onFocus,\n            ...props\n        },\n        ref,\n    ) => {\n        const isControlled = controlledValue !== undefined;\n        const [localValue, setLocalValue] = React.useState('');\n        const localInputRef = React.useRef<HTMLInputElement>(null);\n\n        const resolvedRef = (ref ||\n            localInputRef) as React.RefObject<HTMLInputElement | null>;\n\n        const decimalLimitVal =\n            typeof decimalsLimit === 'number' ? decimalsLimit : 2;\n\n        const symbol = React.useMemo(() => {\n            return getCurrencySymbol(locale, currency);\n        }, [locale, currency]);\n\n        \/\/ Synchronize external changes\n        React.useEffect(() => {\n            if (isControlled) {\n                if (\n                    controlledValue === undefined ||\n                    controlledValue === null ||\n                    controlledValue === ''\n                ) {\n                    setLocalValue('');\n                } else {\n                    const strVal = String(controlledValue);\n                    const formatted = formatCurrencyString(\n                        strVal,\n                        locale,\n                        allowDecimals,\n                        decimalLimitVal,\n                        allowNegativeValue,\n                    );\n                    setLocalValue(formatted);\n                }\n            }\n        }, [\n            controlledValue,\n            isControlled,\n            locale,\n            allowDecimals,\n            decimalLimitVal,\n            allowNegativeValue,\n        ]);\n\n        const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n            const rawInput = e.target.value;\n            const inputEl = resolvedRef.current;\n\n            \/\/ Save cursor position\n            let cursorPosition = inputEl?.selectionStart ?? 0;\n            const lengthBefore = rawInput.length;\n\n            const formatted = formatCurrencyString(\n                rawInput,\n                locale,\n                allowDecimals,\n                decimalLimitVal,\n                allowNegativeValue,\n            );\n\n            \/\/ Calculate new cursor position to prevent jumping\n            const lengthAfter = formatted.length;\n            cursorPosition = cursorPosition + (lengthAfter - lengthBefore);\n\n            setLocalValue(formatted);\n\n            \/\/ Emit raw numeric value\n            const numericString = formatted.replace(\/[^\\d.-]\/g, '');\n            const numericValue = numericString\n                ? parseFloat(numericString)\n                : undefined;\n\n            onValueChange?.(numericValue, formatted);\n\n            \/\/ Restore cursor position on next tick\n            setTimeout(() => {\n                if (inputEl) {\n                    inputEl.setSelectionRange(cursorPosition, cursorPosition);\n                }\n            }, 0);\n        };\n\n        const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n            let finalValue = localValue;\n\n            \/\/ Format to fixed decimal places on blur if decimals are allowed and value is present\n            if (allowDecimals && localValue) {\n                const numericString = localValue.replace(\/[^\\d.-]\/g, '');\n                const number = parseFloat(numericString);\n                if (!isNaN(number)) {\n                    finalValue = new Intl.NumberFormat(locale, {\n                        useGrouping: true,\n                        minimumFractionDigits: decimalLimitVal,\n                        maximumFractionDigits: decimalLimitVal,\n                    }).format(number);\n\n                    if (\n                        allowNegativeValue &&\n                        numericString.startsWith('-') &&\n                        !finalValue.startsWith('-')\n                    ) {\n                        finalValue = '-' + finalValue;\n                    }\n                }\n            }\n\n            setLocalValue(finalValue);\n\n            const numericString = finalValue.replace(\/[^\\d.-]\/g, '');\n            const numericValue = numericString\n                ? parseFloat(numericString)\n                : undefined;\n            onValueChange?.(numericValue, finalValue);\n\n            onBlur?.(e);\n        };\n\n        return (\n            <div className=\"relative w-full\">\n                <span className=\"pointer-events-none absolute top-1\/2 left-3 -translate-y-1\/2 text-sm font-medium text-muted-foreground\/70 select-none\">\n                    {symbol}\n                <\/span>\n                <Input\n                    ref={resolvedRef}\n                    type=\"text\"\n                    value={localValue}\n                    onChange={handleChange}\n                    onBlur={handleBlur}\n                    placeholder={placeholder}\n                    className={cn('pl-7', className)}\n                    {...props}\n                \/>\n            <\/div>\n        );\n    },\n);\n\nInputCurrency.displayName = 'InputCurrency';\n\nexport { InputCurrency, getCurrencySymbol, formatCurrencyString };\nexport type { InputCurrencyProps };\n"}],"meta":{"category":"inputs","version":"1.0.0"},"categories":["inputs"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"input-number-stepper","type":"registry:ui","title":"Input Number Stepper","description":"A numeric entry component with side-by-side plus and minus adjustment buttons.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["input","button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/inputs\/input-number-stepper.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { Plus, Minus } from 'lucide-react';\nimport { Input } from '@\/components\/ui\/input';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\ninterface InputNumberStepperProps extends Omit<\n    React.InputHTMLAttributes<HTMLInputElement>,\n    'value' | 'onChange' | 'min' | 'max' | 'step'\n> {\n    \/** Controlled numeric value *\/\n    value?: number;\n    \/** Default value for uncontrolled usage *\/\n    defaultValue?: number;\n    \/** Callback when value changes *\/\n    onValueChange?: (value: number | undefined) => void;\n    \/** Minimum allowed value *\/\n    min?: number;\n    \/** Maximum allowed value *\/\n    max?: number;\n    \/** Step interval *\/\n    step?: number;\n    \/** Precision of decimal points *\/\n    precision?: number;\n    \/**\n     * Stepper control variations\n     * @default 'split'\n     *\/\n    variant?: 'split' | 'right' | 'left' | 'inline';\n}\n\nconst InputNumberStepper = React.forwardRef<\n    HTMLInputElement,\n    InputNumberStepperProps\n>(\n    (\n        {\n            value: controlledValue,\n            defaultValue,\n            onValueChange,\n            min,\n            max,\n            step = 1,\n            precision,\n            variant = 'split',\n            className,\n            disabled,\n            ...props\n        },\n        ref,\n    ) => {\n        const isControlled = controlledValue !== undefined;\n        const [localValue, setLocalValue] = React.useState<string>(\n            defaultValue !== undefined ? String(defaultValue) : '0',\n        );\n\n        const activeValueStr = isControlled\n            ? controlledValue !== undefined\n                ? String(controlledValue)\n                : ''\n            : localValue;\n        const activeValue =\n            activeValueStr !== '' ? parseFloat(activeValueStr) : undefined;\n\n        const resolvedPrecision = React.useMemo(() => {\n            if (precision !== undefined) return precision;\n            const stepStr = String(step);\n            if (stepStr.indexOf('.') === -1) return 0;\n            return stepStr.length - stepStr.indexOf('.') - 1;\n        }, [step, precision]);\n\n        React.useEffect(() => {\n            if (isControlled) {\n                setLocalValue(\n                    controlledValue !== undefined\n                        ? String(controlledValue)\n                        : '',\n                );\n            }\n        }, [controlledValue, isControlled]);\n\n        const clamp = React.useCallback(\n            (val: number): number => {\n                let clamped = val;\n                if (min !== undefined && clamped < min) clamped = min;\n                if (max !== undefined && clamped > max) clamped = max;\n                return parseFloat(clamped.toFixed(resolvedPrecision));\n            },\n            [min, max, resolvedPrecision],\n        );\n\n        const updateValue = React.useCallback(\n            (newVal: number | undefined) => {\n                let finalVal = newVal;\n                if (finalVal !== undefined) {\n                    finalVal = clamp(finalVal);\n                }\n\n                if (!isControlled) {\n                    setLocalValue(\n                        finalVal !== undefined ? String(finalVal) : '',\n                    );\n                }\n                onValueChange?.(finalVal);\n            },\n            [isControlled, clamp, onValueChange],\n        );\n\n        const handleIncrement = () => {\n            if (disabled) return;\n            const current = activeValue ?? min ?? 0;\n            updateValue(current + step);\n        };\n\n        const handleDecrement = () => {\n            if (disabled) return;\n            const current = activeValue ?? min ?? 0;\n            updateValue(current - step);\n        };\n\n        const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n            const raw = e.target.value;\n            if (raw === '' || raw === '-') {\n                setLocalValue(raw);\n                onValueChange?.(undefined);\n                return;\n            }\n\n            const parsed = parseFloat(raw);\n            if (!isNaN(parsed)) {\n                setLocalValue(raw);\n                onValueChange?.(parsed);\n            }\n        };\n\n        const handleBlur = () => {\n            if (activeValueStr === '' || activeValueStr === '-') {\n                updateValue(undefined);\n            } else {\n                const parsed = parseFloat(activeValueStr);\n                updateValue(isNaN(parsed) ? undefined : parsed);\n            }\n        };\n\n        const buttonClass =\n            'size-9 cursor-pointer hover:bg-muted\/70 active:scale-95 transition-all text-muted-foreground hover:text-foreground shrink-0';\n\n        \/\/ Layout Variants\n        if (variant === 'split') {\n            return (\n                <div className={cn('flex items-center gap-1', className)}>\n                    <Button\n                        type=\"button\"\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className={buttonClass}\n                        onClick={handleDecrement}\n                        disabled={\n                            disabled ||\n                            (min !== undefined &&\n                                activeValue !== undefined &&\n                                activeValue <= min)\n                        }\n                    >\n                        <Minus className=\"size-4\" \/>\n                    <\/Button>\n                    <Input\n                        ref={ref}\n                        type=\"text\"\n                        inputMode=\"decimal\"\n                        value={activeValueStr}\n                        onChange={handleChange}\n                        onBlur={handleBlur}\n                        disabled={disabled}\n                        className=\"h-9 w-16 text-center focus-visible:ring-1\"\n                        {...props}\n                    \/>\n                    <Button\n                        type=\"button\"\n                        variant=\"outline\"\n                        size=\"icon\"\n                        className={buttonClass}\n                        onClick={handleIncrement}\n                        disabled={\n                            disabled ||\n                            (max !== undefined &&\n                                activeValue !== undefined &&\n                                activeValue >= max)\n                        }\n                    >\n                        <Plus className=\"size-4\" \/>\n                    <\/Button>\n                <\/div>\n            );\n        }\n\n        if (variant === 'left') {\n            return (\n                <div className={cn('flex items-center gap-1', className)}>\n                    <div className=\"flex overflow-hidden rounded-md border bg-background\">\n                        <Button\n                            type=\"button\"\n                            variant=\"ghost\"\n                            className={cn(buttonClass, 'rounded-none border-r')}\n                            onClick={handleDecrement}\n                            disabled={\n                                disabled ||\n                                (min !== undefined &&\n                                    activeValue !== undefined &&\n                                    activeValue <= min)\n                            }\n                        >\n                            <Minus className=\"size-4\" \/>\n                        <\/Button>\n                        <Button\n                            type=\"button\"\n                            variant=\"ghost\"\n                            className={cn(buttonClass, 'rounded-none')}\n                            onClick={handleIncrement}\n                            disabled={\n                                disabled ||\n                                (max !== undefined &&\n                                    activeValue !== undefined &&\n                                    activeValue >= max)\n                            }\n                        >\n                            <Plus className=\"size-4\" \/>\n                        <\/Button>\n                    <\/div>\n                    <Input\n                        ref={ref}\n                        type=\"text\"\n                        inputMode=\"decimal\"\n                        value={activeValueStr}\n                        onChange={handleChange}\n                        onBlur={handleBlur}\n                        disabled={disabled}\n                        className=\"h-9 w-16 text-center\"\n                        {...props}\n                    \/>\n                <\/div>\n            );\n        }\n\n        if (variant === 'right') {\n            return (\n                <div className={cn('flex items-center gap-1', className)}>\n                    <Input\n                        ref={ref}\n                        type=\"text\"\n                        inputMode=\"decimal\"\n                        value={activeValueStr}\n                        onChange={handleChange}\n                        onBlur={handleBlur}\n                        disabled={disabled}\n                        className=\"h-9 w-16 text-center\"\n                        {...props}\n                    \/>\n                    <div className=\"flex overflow-hidden rounded-md border bg-background\">\n                        <Button\n                            type=\"button\"\n                            variant=\"ghost\"\n                            className={cn(buttonClass, 'rounded-none border-r')}\n                            onClick={handleDecrement}\n                            disabled={\n                                disabled ||\n                                (min !== undefined &&\n                                    activeValue !== undefined &&\n                                    activeValue <= min)\n                            }\n                        >\n                            <Minus className=\"size-4\" \/>\n                        <\/Button>\n                        <Button\n                            type=\"button\"\n                            variant=\"ghost\"\n                            className={cn(buttonClass, 'rounded-none')}\n                            onClick={handleIncrement}\n                            disabled={\n                                disabled ||\n                                (max !== undefined &&\n                                    activeValue !== undefined &&\n                                    activeValue >= max)\n                            }\n                        >\n                            <Plus className=\"size-4\" \/>\n                        <\/Button>\n                    <\/div>\n                <\/div>\n            );\n        }\n\n        \/\/ Inline minimal variant: buttons overlaid inside input edges\n        return (\n            <div\n                className={cn(\n                    'relative flex max-w-[120px] items-center',\n                    className,\n                )}\n            >\n                <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className=\"absolute left-1 z-10 size-7 cursor-pointer rounded-sm text-muted-foreground hover:bg-muted\"\n                    onClick={handleDecrement}\n                    disabled={\n                        disabled ||\n                        (min !== undefined &&\n                            activeValue !== undefined &&\n                            activeValue <= min)\n                    }\n                >\n                    <Minus className=\"size-3.5\" \/>\n                <\/Button>\n                <Input\n                    ref={ref}\n                    type=\"text\"\n                    inputMode=\"decimal\"\n                    value={activeValueStr}\n                    onChange={handleChange}\n                    onBlur={handleBlur}\n                    disabled={disabled}\n                    className=\"h-9 w-full px-8 text-center\"\n                    {...props}\n                \/>\n                <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className=\"absolute right-1 z-10 size-7 cursor-pointer rounded-sm text-muted-foreground hover:bg-muted\"\n                    onClick={handleIncrement}\n                    disabled={\n                        disabled ||\n                        (max !== undefined &&\n                            activeValue !== undefined &&\n                            activeValue >= max)\n                    }\n                >\n                    <Plus className=\"size-3.5\" \/>\n                <\/Button>\n            <\/div>\n        );\n    },\n);\n\nInputNumberStepper.displayName = 'InputNumberStepper';\n\nexport { InputNumberStepper };\nexport type { InputNumberStepperProps };\n"}],"meta":{"category":"inputs","version":"1.0.0"},"categories":["inputs"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"input-number","type":"registry:ui","title":"Input Number","description":"A numeric spinner input containing up\/down stepper buttons and range constraints.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["input","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/inputs\/input-number.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { ChevronUp, ChevronDown } from 'lucide-react';\nimport { Input } from '@\/components\/ui\/input';\nimport { cn } from '@\/lib\/utils';\n\ninterface InputNumberProps extends Omit<\n    React.InputHTMLAttributes<HTMLInputElement>,\n    'value' | 'onChange' | 'min' | 'max' | 'step'\n> {\n    \/**\n     * Controlled numeric value\n     *\/\n    value?: number;\n    \/**\n     * Default value for uncontrolled usage\n     *\/\n    defaultValue?: number;\n    \/**\n     * Callback when number changes\n     *\/\n    onValueChange?: (value: number | undefined) => void;\n    \/**\n     * Minimum allowed value\n     *\/\n    min?: number;\n    \/**\n     * Maximum allowed value\n     *\/\n    max?: number;\n    \/**\n     * Step interval for increment\/decrement\n     * @default 1\n     *\/\n    step?: number;\n    \/**\n     * Decimal places precision. If omitted, is computed automatically from step.\n     *\/\n    precision?: number;\n    \/**\n     * Unit suffix (e.g. 'px', 'rem', '%', 'kg')\n     *\/\n    suffix?: string;\n    \/**\n     * Disable up\/down stepper buttons\n     * @default false\n     *\/\n    hideStepper?: boolean;\n}\n\nconst InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>(\n    (\n        {\n            value: controlledValue,\n            defaultValue,\n            onValueChange,\n            min,\n            max,\n            step = 1,\n            precision,\n            suffix,\n            hideStepper = false,\n            className,\n            disabled,\n            ...props\n        },\n        ref,\n    ) => {\n        const isControlled = controlledValue !== undefined;\n        const [localValue, setLocalValue] = React.useState<string>(\n            defaultValue !== undefined ? String(defaultValue) : '',\n        );\n\n        const activeValueStr = isControlled\n            ? controlledValue !== undefined\n                ? String(controlledValue)\n                : ''\n            : localValue;\n        const activeValue =\n            activeValueStr !== '' ? parseFloat(activeValueStr) : undefined;\n\n        \/\/ Auto-detect precision from step if not provided\n        const resolvedPrecision = React.useMemo(() => {\n            if (precision !== undefined) return precision;\n            const stepStr = String(step);\n            if (stepStr.indexOf('.') === -1) return 0;\n            return stepStr.length - stepStr.indexOf('.') - 1;\n        }, [step, precision]);\n\n        \/\/ Sync controlled values\n        React.useEffect(() => {\n            if (isControlled) {\n                setLocalValue(\n                    controlledValue !== undefined\n                        ? String(controlledValue)\n                        : '',\n                );\n            }\n        }, [controlledValue, isControlled]);\n\n        \/\/ Clamp value inside min\/max bounds\n        const clamp = React.useCallback(\n            (val: number): number => {\n                let clamped = val;\n                if (min !== undefined && clamped < min) clamped = min;\n                if (max !== undefined && clamped > max) clamped = max;\n                return parseFloat(clamped.toFixed(resolvedPrecision));\n            },\n            [min, max, resolvedPrecision],\n        );\n\n        const updateValue = React.useCallback(\n            (newVal: number | undefined) => {\n                let finalVal = newVal;\n                if (finalVal !== undefined) {\n                    finalVal = clamp(finalVal);\n                }\n\n                if (!isControlled) {\n                    setLocalValue(\n                        finalVal !== undefined ? String(finalVal) : '',\n                    );\n                }\n                onValueChange?.(finalVal);\n            },\n            [isControlled, clamp, onValueChange],\n        );\n\n        const handleIncrement = React.useCallback(() => {\n            if (disabled) return;\n            const current = activeValue ?? min ?? 0;\n            updateValue(current + step);\n        }, [activeValue, min, step, updateValue, disabled]);\n\n        const handleDecrement = React.useCallback(() => {\n            if (disabled) return;\n            const current = activeValue ?? min ?? 0;\n            updateValue(current - step);\n        }, [activeValue, min, step, updateValue, disabled]);\n\n        \/\/ Long-press continuous step handler\n        const timerRef = React.useRef<ReturnType<typeof setTimeout> | null>(\n            null,\n        );\n        const intervalRef = React.useRef<ReturnType<typeof setInterval> | null>(\n            null,\n        );\n\n        const clearTimers = React.useCallback(() => {\n            if (timerRef.current) clearTimeout(timerRef.current);\n            if (intervalRef.current) clearInterval(intervalRef.current);\n        }, []);\n\n        const startStepper = (action: () => void) => {\n            if (disabled) return;\n            action();\n            clearTimers();\n            timerRef.current = setTimeout(() => {\n                intervalRef.current = setInterval(action, 60);\n            }, 400);\n        };\n\n        React.useEffect(() => {\n            return () => clearTimers();\n        }, [clearTimers]);\n\n        const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n            if (e.key === 'ArrowUp') {\n                e.preventDefault();\n                handleIncrement();\n            } else if (e.key === 'ArrowDown') {\n                e.preventDefault();\n                handleDecrement();\n            }\n        };\n\n        const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n            const raw = e.target.value;\n            \/\/ Allow typing numbers, decimals, minus sign\n            if (raw === '' || raw === '-') {\n                setLocalValue(raw);\n                onValueChange?.(undefined);\n                return;\n            }\n\n            const parsed = parseFloat(raw);\n            if (!isNaN(parsed)) {\n                setLocalValue(raw);\n                onValueChange?.(parsed);\n            }\n        };\n\n        const handleBlur = () => {\n            \/\/ Normalize value on blur\n            if (activeValueStr === '' || activeValueStr === '-') {\n                updateValue(undefined);\n            } else {\n                const parsed = parseFloat(activeValueStr);\n                if (!isNaN(parsed)) {\n                    updateValue(parsed);\n                } else {\n                    updateValue(undefined);\n                }\n            }\n        };\n\n        return (\n            <div className=\"relative flex w-full items-center\">\n                <Input\n                    ref={ref}\n                    type=\"text\"\n                    inputMode=\"decimal\"\n                    value={activeValueStr}\n                    onChange={handleChange}\n                    onKeyDown={handleKeyDown}\n                    onBlur={handleBlur}\n                    disabled={disabled}\n                    className={cn(\n                        'pr-8',\n                        suffix && 'pr-14',\n                        hideStepper && 'pr-3',\n                        className,\n                    )}\n                    {...props}\n                \/>\n\n                {suffix && (\n                    <span\n                        className={cn(\n                            'pointer-events-none absolute text-xs text-muted-foreground transition-opacity select-none',\n                            hideStepper ? 'right-3' : 'right-8',\n                            disabled && 'opacity-50',\n                        )}\n                    >\n                        {suffix}\n                    <\/span>\n                )}\n\n                {!hideStepper && !disabled && (\n                    <div className=\"absolute top-0.5 right-0.5 bottom-0.5 flex w-6 flex-col border-l border-border\/40 bg-background\/50\">\n                        <button\n                            type=\"button\"\n                            className=\"flex flex-1 cursor-pointer items-center justify-center rounded-tr-md border-b border-border\/20 text-muted-foreground\/70 transition-colors select-none hover:bg-muted\/50 hover:text-foreground active:bg-muted\"\n                            onMouseDown={() => startStepper(handleIncrement)}\n                            onMouseUp={clearTimers}\n                            onMouseLeave={clearTimers}\n                            title=\"Increment\"\n                        >\n                            <ChevronUp className=\"size-3\" \/>\n                        <\/button>\n                        <button\n                            type=\"button\"\n                            className=\"flex flex-1 cursor-pointer items-center justify-center rounded-br-md text-muted-foreground\/70 transition-colors select-none hover:bg-muted\/50 hover:text-foreground active:bg-muted\"\n                            onMouseDown={() => startStepper(handleDecrement)}\n                            onMouseUp={clearTimers}\n                            onMouseLeave={clearTimers}\n                            title=\"Decrement\"\n                        >\n                            <ChevronDown className=\"size-3\" \/>\n                        <\/button>\n                    <\/div>\n                )}\n            <\/div>\n        );\n    },\n);\n\nInputNumber.displayName = 'InputNumber';\n\nexport { InputNumber };\nexport type { InputNumberProps };\n"}],"meta":{"category":"inputs","version":"1.0.0"},"categories":["inputs"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"input-password","type":"registry:ui","title":"Input Password","description":"A password input field with a toggleable eye icon to show\/hide the password text.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["input","button","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/inputs\/input-password.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { Eye, EyeOff } from 'lucide-react';\nimport { Input } from '@\/components\/ui\/input';\nimport { Button } from '@\/components\/ui\/button';\nimport { cn } from '@\/lib\/utils';\n\ninterface InputPasswordProps extends React.ComponentProps<'input'> {\n    \/**\n     * Custom class name for the toggle button\n     *\/\n    toggleClassName?: string;\n}\n\nconst InputPassword = React.forwardRef<HTMLInputElement, InputPasswordProps>(\n    ({ className, toggleClassName, ...props }, ref) => {\n        const [showPassword, setShowPassword] = React.useState(false);\n\n        const toggleVisibility = () => {\n            setShowPassword((prev) => !prev);\n        };\n\n        return (\n            <div className=\"relative w-full\">\n                <Input\n                    type={showPassword ? 'text' : 'password'}\n                    className={cn('pr-10', className)}\n                    ref={ref}\n                    {...props}\n                \/>\n                <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className={cn(\n                        'absolute top-1\/2 right-0 size-9 -translate-y-1\/2 cursor-pointer text-muted-foreground\/70 select-none hover:bg-transparent hover:text-foreground',\n                        toggleClassName,\n                    )}\n                    onClick={toggleVisibility}\n                    aria-label={\n                        showPassword ? 'Hide password' : 'Show password'\n                    }\n                >\n                    {showPassword ? (\n                        <EyeOff className=\"size-4\" \/>\n                    ) : (\n                        <Eye className=\"size-4\" \/>\n                    )}\n                <\/Button>\n            <\/div>\n        );\n    },\n);\n\nInputPassword.displayName = 'InputPassword';\n\nexport { InputPassword };\nexport type { InputPasswordProps };\n"}],"meta":{"category":"inputs","version":"1.0.0"},"categories":["inputs"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"input-phone","type":"registry:ui","title":"Input Phone","description":"A formatted text input enforcing phone masks and raw numeric outputs.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["input","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/inputs\/input-phone.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { Phone } from 'lucide-react';\nimport { Input } from '@\/components\/ui\/input';\nimport { cn } from '@\/lib\/utils';\n\ninterface InputPhoneProps extends Omit<\n    React.InputHTMLAttributes<HTMLInputElement>,\n    'value' | 'onChange'\n> {\n    \/**\n     * Raw numeric value (digits only)\n     *\/\n    value?: string;\n    \/**\n     * Callback when the raw digit value changes\n     *\/\n    onValueChange?: (value: string) => void;\n    \/**\n     * Custom phone format mask. Use '9' for digits.\n     * @default '(999) 999-9999'\n     *\/\n    mask?: string;\n    \/**\n     * Show\/hide the phone icon prefix\n     * @default true\n     *\/\n    showIcon?: boolean;\n}\n\n\/**\n * Formats a raw string of digits using the provided mask.\n *\/\nfunction formatPhone(digits: string, mask: string): string {\n    let formatted = '';\n    let digitIdx = 0;\n\n    for (let i = 0; i < mask.length; i++) {\n        const maskChar = mask[i];\n        if (digitIdx >= digits.length) {\n            break;\n        }\n\n        if (maskChar === '9') {\n            formatted += digits[digitIdx];\n            digitIdx++;\n        } else {\n            formatted += maskChar;\n        }\n    }\n    return formatted;\n}\n\nconst InputPhone = React.forwardRef<HTMLInputElement, InputPhoneProps>(\n    (\n        {\n            value: controlledValue,\n            onValueChange,\n            mask = '(999) 999-9999',\n            showIcon = true,\n            className,\n            placeholder = '(555) 000-0000',\n            ...props\n        },\n        ref,\n    ) => {\n        const isControlled = controlledValue !== undefined;\n        const [localValue, setLocalValue] = React.useState('');\n\n        const rawValue = isControlled ? controlledValue : localValue;\n\n        \/\/ Strip non-digits to get raw value\n        const getRawDigits = (val: string) => val.replace(\/\\D\/g, '');\n\n        const maxDigits = React.useMemo(() => {\n            return mask.split('').filter((c) => c === '9').length;\n        }, [mask]);\n\n        const formattedDisplayValue = React.useMemo(() => {\n            return formatPhone(rawValue, mask);\n        }, [rawValue, mask]);\n\n        const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n            const rawDigits = getRawDigits(e.target.value).slice(0, maxDigits);\n\n            if (!isControlled) {\n                setLocalValue(rawDigits);\n            }\n            onValueChange?.(rawDigits);\n        };\n\n        \/\/ Handle pasting and character deletion\n        const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n            \/\/ Prevent entering non-numeric chars (allow control keys)\n            const allowedKeys = [\n                'Backspace',\n                'Delete',\n                'ArrowLeft',\n                'ArrowRight',\n                'Tab',\n                'Enter',\n                'v',\n                'c',\n                'a',\n            ];\n            const isControlKey =\n                allowedKeys.includes(e.key) || e.ctrlKey || e.metaKey;\n\n            if (!isControlKey && !\/^\\d$\/.test(e.key)) {\n                e.preventDefault();\n            }\n        };\n\n        return (\n            <div className=\"relative w-full\">\n                {showIcon && (\n                    <Phone className=\"pointer-events-none absolute top-1\/2 left-3 size-4 -translate-y-1\/2 text-muted-foreground\/70\" \/>\n                )}\n                <Input\n                    ref={ref}\n                    type=\"text\"\n                    value={formattedDisplayValue}\n                    onChange={handleChange}\n                    onKeyDown={handleKeyDown}\n                    placeholder={placeholder}\n                    className={cn(showIcon && 'pl-9', className)}\n                    {...props}\n                \/>\n            <\/div>\n        );\n    },\n);\n\nInputPhone.displayName = 'InputPhone';\n\nexport { InputPhone, formatPhone };\nexport type { InputPhoneProps };\n"}],"meta":{"category":"inputs","version":"1.0.0"},"categories":["inputs"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"input-slug","type":"registry:ui","title":"Input Slug","description":"A reactive field transforming raw keystrokes into clean URL-safe slug strings.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["input"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/inputs\/input-slug.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { Input } from '@\/components\/ui\/input';\n\ninterface InputSlugProps extends Omit<\n    React.InputHTMLAttributes<HTMLInputElement>,\n    'value' | 'onChange'\n> {\n    \/**\n     * The controlled display value (already-slugified string)\n     *\/\n    value?: string;\n    \/**\n     * Callback when the slug value changes (debounced, fully cleaned)\n     *\/\n    onValueChange?: (value: string) => void;\n    \/**\n     * Callback fires on every keystroke with the intermediate display value\n     *\/\n    onSlugChange?: (slug: string) => void;\n    \/**\n     * Custom slug generation function\n     *\/\n    slugify?: (value: string) => string;\n}\n\n\/**\n * Partial slugify \u2014 applied on every keystroke so the input feels live.\n * Allows a trailing dash while the user is still typing.\n *\/\nfunction partialSlugify(value: string): string {\n    return value\n        .toLowerCase()\n        .replace(\/[\\s_]+\/g, '-') \/\/ spaces \/ underscores \u2192 dash\n        .replace(\/[^\\w-]\/g, '') \/\/ strip everything that isn't a word char or dash\n        .replace(\/-{2,}\/g, '-') \/\/ collapse consecutive dashes\n        .replace(\/^-+\/, ''); \/\/ strip leading dashes\n}\n\n\/**\n * Final slugify \u2014 strips the trailing dash once the debounce fires.\n *\/\nfunction defaultSlugify(value: string): string {\n    return partialSlugify(value).replace(\/-+$\/, '');\n}\n\nconst InputSlug = React.forwardRef<HTMLInputElement, InputSlugProps>(\n    (\n        {\n            value: controlledValue,\n            onValueChange,\n            onSlugChange,\n            slugify = defaultSlugify,\n            ...props\n        },\n        ref,\n    ) => {\n        \/\/ Always drive the input from internal state so we can strip the trailing\n        \/\/ dash on debounce regardless of whether the component is controlled.\n        const [displayValue, setDisplayValue] = React.useState(\n            controlledValue !== undefined ? controlledValue : '',\n        );\n\n        const debounceRef = React.useRef<ReturnType<typeof setTimeout> | null>(\n            null,\n        );\n        \/\/ Keep the latest partial value so the debounce closure always reads it.\n        const latestPartialRef = React.useRef('');\n        const isControlled = controlledValue !== undefined;\n\n        \/\/ Sync external controlled value changes (e.g. form reset, programmatic update).\n        \/\/ Skip if the incoming value matches what we already show \u2014 prevents the parent\n        \/\/ echoing onValueChange back and overwriting our debounced cleanup.\n        const prevControlledRef = React.useRef(controlledValue);\n        React.useEffect(() => {\n            if (isControlled && controlledValue !== prevControlledRef.current) {\n                prevControlledRef.current = controlledValue;\n                setDisplayValue(controlledValue ?? '');\n            }\n        }, [controlledValue, isControlled]);\n\n        const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n            const raw = e.target.value;\n\n            \/\/ Partial transform: live, allows trailing dash mid-typing\n            const partial = partialSlugify(raw);\n            latestPartialRef.current = partial;\n\n            \/\/ Always update display immediately so typing feels instant\n            setDisplayValue(partial);\n\n            \/\/ Fire onSlugChange on every keystroke with the intermediate value\n            onSlugChange?.(partial);\n\n            \/\/ Debounce the final cleanup (strip trailing dash)\n            if (debounceRef.current) {\n                clearTimeout(debounceRef.current);\n            }\n\n            debounceRef.current = setTimeout(() => {\n                const final = slugify(latestPartialRef.current);\n\n                \/\/ Strip trailing dash in the input itself\n                setDisplayValue(final);\n                prevControlledRef.current = final;\n\n                onValueChange?.(final);\n            }, 1000);\n        };\n\n        \/\/ Clean up on unmount\n        React.useEffect(() => {\n            return () => {\n                if (debounceRef.current) {\n                    clearTimeout(debounceRef.current);\n                }\n            };\n        }, []);\n\n        return (\n            <Input\n                ref={ref}\n                type=\"text\"\n                value={displayValue}\n                onChange={handleChange}\n                {...props}\n            \/>\n        );\n    },\n);\n\nInputSlug.displayName = 'InputSlug';\n\nexport { InputSlug, defaultSlugify, partialSlugify };\nexport type { InputSlugProps };\n"}],"meta":{"category":"inputs","version":"1.0.0"},"categories":["inputs"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"multi-select","type":"registry:ui","title":"Multi Select","description":"A dropdown selector allowing search, selection, and creation of multiple tags.","author":"designbycode","dependencies":["cmdk","lucide-react"],"devDependencies":[],"registryDependencies":["badge","popover","utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/inputs\/multi-select.tsx","type":"registry:ui","content":"'use client';\n\nimport { Command as CommandPrimitive } from 'cmdk';\nimport { CheckIcon, ChevronsUpDownIcon, PlusIcon, XIcon } from 'lucide-react';\nimport * as React from 'react';\n\nimport { Badge } from '@\/components\/ui\/badge';\nimport {\n    Popover,\n    PopoverContent,\n    PopoverTrigger,\n} from '@\/components\/ui\/popover';\nimport { cn } from '@\/lib\/utils';\n\n\/\/ Context for the MultiSelect compound component\ninterface MultiSelectContextValue {\n    open: boolean;\n    setOpen: (open: boolean) => void;\n    selected: string[];\n    onSelect: (value: string) => void;\n    onDeselect: (value: string) => void;\n    search: string;\n    setSearch: (search: string) => void;\n    options: Map<string, string>;\n    registerOption: (value: string, label: string) => void;\n    onCreateOption?: (value: string) => void;\n    allowCreate: boolean;\n}\n\nconst MultiSelectContext = React.createContext<MultiSelectContextValue | null>(\n    null,\n);\n\nfunction useMultiSelect() {\n    const context = React.useContext(MultiSelectContext);\n\n    if (!context) {\n        throw new Error(\n            'MultiSelect components must be used within a MultiSelect',\n        );\n    }\n\n    return context;\n}\n\n\/\/ Root component\ninterface MultiSelectProps {\n    value?: string[];\n    defaultValue?: string[];\n    onValueChange?: (value: string[]) => void;\n    onCreateOption?: (value: string) => void;\n    allowCreate?: boolean;\n    children: React.ReactNode;\n}\n\nfunction MultiSelect({\n    value,\n    defaultValue = [],\n    onValueChange,\n    onCreateOption,\n    allowCreate = true,\n    children,\n}: MultiSelectProps) {\n    const [open, setOpen] = React.useState(false);\n    const [search, setSearch] = React.useState('');\n    const [internalSelected, setInternalSelected] =\n        React.useState<string[]>(defaultValue);\n    const [options, setOptions] = React.useState<Map<string, string>>(\n        new Map(),\n    );\n\n    const selected = value ?? internalSelected;\n\n    const registerOption = React.useCallback(\n        (optionValue: string, label: string) => {\n            setOptions((prev) => {\n                const next = new Map(prev);\n                next.set(optionValue, label);\n\n                return next;\n            });\n        },\n        [],\n    );\n\n    const handleSelect = React.useCallback(\n        (itemValue: string) => {\n            const newSelected = selected.includes(itemValue)\n                ? selected.filter((v) => v !== itemValue)\n                : [...selected, itemValue];\n\n            if (value === undefined) {\n                setInternalSelected(newSelected);\n            }\n\n            onValueChange?.(newSelected);\n        },\n        [selected, value, onValueChange],\n    );\n\n    const handleDeselect = React.useCallback(\n        (itemValue: string) => {\n            const newSelected = selected.filter((v) => v !== itemValue);\n\n            if (value === undefined) {\n                setInternalSelected(newSelected);\n            }\n\n            onValueChange?.(newSelected);\n        },\n        [selected, value, onValueChange],\n    );\n\n    const handleCreateOption = React.useCallback(\n        (newValue: string) => {\n            if (onCreateOption) {\n                onCreateOption(newValue);\n            }\n\n            \/\/ Select the new option\n            const newSelected = [...selected, newValue];\n\n            if (value === undefined) {\n                setInternalSelected(newSelected);\n            }\n\n            onValueChange?.(newSelected);\n            setSearch('');\n        },\n        [selected, value, onValueChange, onCreateOption],\n    );\n\n    return (\n        <MultiSelectContext.Provider\n            value={{\n                open,\n                setOpen,\n                selected,\n                onSelect: handleSelect,\n                onDeselect: handleDeselect,\n                search,\n                setSearch,\n                options,\n                registerOption,\n                onCreateOption: handleCreateOption,\n                allowCreate,\n            }}\n        >\n            <Popover open={open} onOpenChange={setOpen}>\n                {children}\n            <\/Popover>\n        <\/MultiSelectContext.Provider>\n    );\n}\n\n\/\/ Trigger component\ntype MultiSelectTriggerProps = React.ComponentProps<typeof PopoverTrigger>;\n\nfunction MultiSelectTrigger({\n    className,\n    children,\n    ...props\n}: MultiSelectTriggerProps) {\n    const { selected, options, onDeselect } = useMultiSelect();\n\n    return (\n        <PopoverTrigger asChild {...props}>\n            <button\n                type=\"button\"\n                role=\"combobox\"\n                data-slot=\"multi-select-trigger\"\n                className={cn(\n                    'flex min-h-10 w-full items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50',\n                    className,\n                )}\n            >\n                <div className=\"flex flex-1 flex-wrap items-center gap-1.5\">\n                    {selected.length > 0\n                        ? selected.map((value) => (\n                              <Badge\n                                  key={value}\n                                  variant=\"secondary\"\n                                  className=\"gap-1 pr-1\"\n                              >\n                                  {options.get(value) || value}\n                                  <button\n                                      type=\"button\"\n                                      className=\"rounded-sm p-0.5 hover:bg-muted\"\n                                      onClick={(e) => {\n                                          e.stopPropagation();\n                                          onDeselect(value);\n                                      }}\n                                  >\n                                      <XIcon className=\"size-3\" \/>\n                                      <span className=\"sr-only\">\n                                          Remove {options.get(value) || value}\n                                      <\/span>\n                                  <\/button>\n                              <\/Badge>\n                          ))\n                        : children}\n                <\/div>\n                <ChevronsUpDownIcon className=\"size-4 shrink-0 opacity-50\" \/>\n            <\/button>\n        <\/PopoverTrigger>\n    );\n}\n\n\/\/ Value\/placeholder component\ninterface MultiSelectValueProps {\n    placeholder?: string;\n}\n\nfunction MultiSelectValue({ placeholder }: MultiSelectValueProps) {\n    const { selected } = useMultiSelect();\n\n    if (selected.length > 0) {\n        return null;\n    }\n\n    return (\n        <span className=\"pointer-events-none text-muted-foreground\">\n            {placeholder}\n        <\/span>\n    );\n}\n\n\/\/ Content component\ntype MultiSelectContentProps = React.ComponentProps<typeof PopoverContent>;\n\nfunction MultiSelectContent({\n    className,\n    children,\n    ...props\n}: MultiSelectContentProps) {\n    const {\n        search,\n        setSearch,\n        selected,\n        options,\n        onCreateOption,\n        allowCreate,\n    } = useMultiSelect();\n\n    \/\/ Check if the current search matches any existing option\n    const searchLower = search.toLowerCase().trim();\n    const hasExactMatch = React.useMemo(() => {\n        for (const [value, label] of options) {\n            if (\n                value.toLowerCase() === searchLower ||\n                label.toLowerCase() === searchLower\n            ) {\n                return true;\n            }\n        }\n\n        return false;\n    }, [options, searchLower]);\n\n    const showCreateOption =\n        allowCreate &&\n        search.trim() !== '' &&\n        !hasExactMatch &&\n        !selected.includes(search.trim());\n\n    return (\n        <PopoverContent\n            data-slot=\"multi-select-content\"\n            className={cn('w-(--radix-popover-trigger-width) p-0', className)}\n            align=\"start\"\n            {...props}\n        >\n            <CommandPrimitive\n                className=\"flex h-full w-full flex-col overflow-hidden rounded-md\"\n                shouldFilter={true}\n            >\n                <div className=\"flex items-center border-b px-3\">\n                    <CommandPrimitive.Input\n                        data-slot=\"multi-select-input\"\n                        placeholder=\"Search or create...\"\n                        value={search}\n                        onValueChange={setSearch}\n                        className=\"flex h-10 w-full bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\"\n                    \/>\n                <\/div>\n                <CommandPrimitive.List className=\"max-h-50 overflow-y-auto p-1\">\n                    <CommandPrimitive.Empty className=\"py-6 text-center text-sm\">\n                        No options found.\n                    <\/CommandPrimitive.Empty>\n                    {children}\n                    {showCreateOption && (\n                        <CommandPrimitive.Item\n                            data-slot=\"multi-select-create\"\n                            value={`create-${search}`}\n                            onSelect={() => onCreateOption?.(search.trim())}\n                            className=\"relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground\"\n                        >\n                            <PlusIcon className=\"size-4 shrink-0\" \/>\n                            <span>Create &quot;{search.trim()}&quot;<\/span>\n                        <\/CommandPrimitive.Item>\n                    )}\n                <\/CommandPrimitive.List>\n            <\/CommandPrimitive>\n        <\/PopoverContent>\n    );\n}\n\n\/\/ Group component\ntype MultiSelectGroupProps = React.ComponentProps<\n    typeof CommandPrimitive.Group\n>;\n\nfunction MultiSelectGroup({ className, ...props }: MultiSelectGroupProps) {\n    return (\n        <CommandPrimitive.Group\n            data-slot=\"multi-select-group\"\n            className={cn(\n                'overflow-hidden text-foreground **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:text-muted-foreground',\n                className,\n            )}\n            {...props}\n        \/>\n    );\n}\n\n\/\/ Item component\ninterface MultiSelectItemProps extends Omit<\n    React.ComponentProps<typeof CommandPrimitive.Item>,\n    'onSelect'\n> {\n    value: string;\n    children: React.ReactNode;\n}\n\nfunction MultiSelectItem({\n    value,\n    children,\n    className,\n    ...props\n}: MultiSelectItemProps) {\n    const { selected, onSelect, registerOption } = useMultiSelect();\n    const isSelected = selected.includes(value);\n\n    \/\/ Register this option\n    React.useEffect(() => {\n        const label = typeof children === 'string' ? children : value;\n        registerOption(value, label);\n    }, [value, children, registerOption]);\n\n    return (\n        <CommandPrimitive.Item\n            data-slot=\"multi-select-item\"\n            value={value}\n            onSelect={() => onSelect(value)}\n            className={cn(\n                'relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground',\n                className,\n            )}\n            {...props}\n        >\n            <div\n                className={cn(\n                    'flex size-4 shrink-0 items-center justify-center rounded-sm border border-primary',\n                    isSelected\n                        ? 'bg-primary text-primary-foreground'\n                        : 'opacity-50',\n                )}\n            >\n                {isSelected && <CheckIcon className=\"size-3\" \/>}\n            <\/div>\n            <span>{children}<\/span>\n        <\/CommandPrimitive.Item>\n    );\n}\n\nexport {\n    MultiSelect,\n    MultiSelectTrigger,\n    MultiSelectValue,\n    MultiSelectContent,\n    MultiSelectGroup,\n    MultiSelectItem,\n};\n"}],"meta":{"category":"inputs","version":"1.0.0"},"categories":["inputs"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"rainbow-border-input","type":"registry:ui","title":"Rainbow Border Input","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","input","https:\/\/ui.test\/r\/rainbow-border.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/inputs\/rainbow-border-input.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Input } from '@\/components\/ui\/input';\nimport { RainbowBorder } from '@\/registry\/new-york\/components\/ui\/borders\/rainbow-border';\n\nexport interface RainbowBorderInputProps extends React.ComponentProps<\n    typeof Input\n> {\n    borderWidth?: string;\n    animationDuration?: string;\n    colors?: string[];\n    rounded?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'full';\n    glow?: boolean;\n    glowBlur?: string;\n    glowOpacity?: number;\n    wrapperClassName?: string;\n}\n\nexport const RainbowBorderInput = React.forwardRef<\n    HTMLInputElement,\n    RainbowBorderInputProps\n>(\n    (\n        {\n            className,\n            borderWidth = '1.5px',\n            animationDuration = '3s',\n            colors,\n            rounded = 'md',\n            glow = true,\n            glowBlur = '20px',\n            glowOpacity = 30,\n            wrapperClassName,\n            ...props\n        },\n        ref,\n    ) => {\n        const roundedInputClass =\n            rounded === 'none'\n                ? 'rounded-none'\n                : rounded === 'xs'\n                  ? 'rounded-xs'\n                  : rounded === 'sm'\n                    ? 'rounded-sm'\n                    : rounded === 'md'\n                      ? 'rounded-md'\n                      : rounded === 'lg'\n                        ? 'rounded-lg'\n                        : 'rounded-full';\n\n        return (\n            <RainbowBorder\n                borderWidth={borderWidth}\n                animationDuration={animationDuration}\n                colors={colors}\n                rounded={rounded}\n                glow={glow}\n                glowBlur={glowBlur}\n                glowOpacity={glowOpacity}\n                className={cn('w-full p-[1px]', wrapperClassName)}\n            >\n                <Input\n                    ref={ref}\n                    className={cn(\n                        'w-full border-0 bg-background text-foreground shadow-xs focus-visible:ring-0 focus-visible:ring-offset-0',\n                        roundedInputClass,\n                        className,\n                    )}\n                    {...props}\n                \/>\n            <\/RainbowBorder>\n        );\n    },\n);\n\nRainbowBorderInput.displayName = 'RainbowBorderInput';\n\nexport default RainbowBorderInput;\n"}],"meta":{"category":"inputs","version":"1.0.0"},"categories":["inputs"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"sliding-radio-group","type":"registry:ui","title":"Sliding Radio Group","description":"An interactive sliding radio group with smooth spring animations and multiple design variants.","author":"designbycode","dependencies":["motion"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/inputs\/sliding-radio-group.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { LayoutGroup, motion } from 'motion\/react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface SlidingRadioOption {\n    label: React.ReactNode;\n    value: string;\n    disabled?: boolean;\n    \/**\n     * Custom class names specifically for the active glider background and text when this option is selected.\n     * Use this to create custom per-option gradient effects or custom glow shadows.\n     *\/\n    gliderClassName?: string;\n}\n\nexport interface SlidingRadioGroupProps {\n    options: SlidingRadioOption[];\n    value?: string;\n    defaultValue?: string;\n    onChange?: (value: string) => void;\n    name?: string;\n    \/**\n     * Pre-defined aesthetic styles\n     * - `glass`: Translucent blurred background with subtle borders and glossy glider\n     * - `neon`: Dark-mode optimized card layout with a glowing accent-colored glider\n     * - `bouncy`: Minimalist, pill-shaped design with a high-elasticity glider transition\n     *\/\n    variant?: 'glass' | 'neon' | 'bouncy';\n    size?: 'sm' | 'md' | 'lg';\n    className?: string;\n    labelClassName?: string;\n    disabled?: boolean;\n}\n\nexport function SlidingRadioGroup({\n    options,\n    value,\n    defaultValue,\n    onChange,\n    name,\n    variant = 'glass',\n    size = 'md',\n    className,\n    labelClassName,\n    disabled = false,\n}: SlidingRadioGroupProps) {\n    const uniqueId = React.useId();\n    const [localValue, setLocalValue] = React.useState(defaultValue || '');\n\n    const isControlled = value !== undefined;\n    const selectedValue = isControlled ? value : localValue;\n\n    const handleSelect = (val: string) => {\n        if (disabled) return;\n        if (!isControlled) {\n            setLocalValue(val);\n        }\n        onChange?.(val);\n    };\n\n    \/\/ Ensure we have a valid selection; default to first if none is selected\n    React.useEffect(() => {\n        if (!selectedValue && options.length > 0) {\n            const firstEnabled = options.find((opt) => !opt.disabled);\n            if (firstEnabled) {\n                handleSelect(firstEnabled.value);\n            }\n        }\n    }, [selectedValue, options]);\n\n    \/\/ Active option details\n    const activeOption = options.find((opt) => opt.value === selectedValue);\n\n    \/\/ Variant style maps\n    const wrapperVariants = {\n        glass: 'bg-muted\/10 border border-border\/40 backdrop-blur-md shadow-[inset_0_1px_2px_rgba(255,255,255,0.05),0_4px_12px_rgba(0,0,0,0.05)] rounded-xl p-1',\n        neon: 'bg-card border border-border\/60 shadow-xs rounded-lg p-1',\n        bouncy: 'bg-muted\/80 border border-border\/30 rounded-full p-1',\n    };\n\n    const labelVariants = {\n        glass: 'text-muted-foreground hover:text-foreground font-semibold',\n        neon: 'text-muted-foreground hover:text-foreground font-medium',\n        bouncy: 'text-muted-foreground hover:text-foreground font-medium',\n    };\n\n    const activeLabelVariants = {\n        glass: 'text-foreground',\n        neon: 'text-primary',\n        bouncy: 'text-foreground font-semibold',\n    };\n\n    const gliderDefaultVariants = {\n        glass: 'bg-linear-to-br from-primary\/30 to-primary\/10 border border-primary\/20 shadow-xs rounded-lg',\n        neon: 'bg-primary\/10 border border-primary text-primary shadow-[0_0_12px_rgba(var(--color-primary),0.15)] rounded-md',\n        bouncy: 'bg-background shadow-md border border-border\/10 rounded-full',\n    };\n\n    const sizeClasses = {\n        sm: {\n            wrapper: 'h-8 gap-0.5',\n            label: 'text-xs px-3 py-1 min-w-[70px]',\n        },\n        md: {\n            wrapper: 'h-10 gap-1',\n            label: 'text-sm px-4 py-1.5 min-w-[90px]',\n        },\n        lg: {\n            wrapper: 'h-12 gap-1.5',\n            label: 'text-base px-6 py-2 min-w-[110px]',\n        },\n    };\n\n    \/\/ Transition styles for the glider\n    const gliderTransitions = {\n        glass: { type: 'spring', stiffness: 350, damping: 28 },\n        neon: { type: 'spring', stiffness: 400, damping: 30 },\n        bouncy: { type: 'spring', stiffness: 480, damping: 22 }, \/\/ High elasticity \/ bounce\n    };\n\n    const radioGroupName = name || `sliding-radio-${uniqueId}`;\n\n    return (\n        <LayoutGroup id={uniqueId}>\n            <div\n                role=\"radiogroup\"\n                aria-disabled={disabled}\n                className={cn(\n                    'relative inline-flex w-fit items-center select-none',\n                    wrapperVariants[variant],\n                    sizeClasses[size].wrapper,\n                    disabled && 'cursor-not-allowed opacity-60',\n                    className,\n                )}\n            >\n                {options.map((option) => {\n                    const isSelected = selectedValue === option.value;\n                    const isDisabled = disabled || option.disabled;\n\n                    return (\n                        <label\n                            key={option.value}\n                            className={cn(\n                                'relative flex h-full cursor-pointer items-center justify-center transition-colors duration-200 ease-in-out focus-within:outline-none',\n                                sizeClasses[size].label,\n                                isSelected\n                                    ? activeLabelVariants[variant]\n                                    : labelVariants[variant],\n                                isDisabled &&\n                                    'pointer-events-none cursor-not-allowed opacity-40',\n                                labelClassName,\n                            )}\n                        >\n                            <input\n                                type=\"radio\"\n                                name={radioGroupName}\n                                value={option.value}\n                                checked={isSelected}\n                                disabled={isDisabled}\n                                onChange={() => handleSelect(option.value)}\n                                className=\"sr-only\"\n                            \/>\n\n                            {\/* Sliding gliders *\/}\n                            {isSelected && (\n                                <motion.div\n                                    layoutId=\"active-glider\"\n                                    className={cn(\n                                        'absolute inset-0 z-0',\n                                        option.gliderClassName ||\n                                            gliderDefaultVariants[variant],\n                                    )}\n                                    transition={gliderTransitions[variant]}\n                                \/>\n                            )}\n\n                            {\/* Label text *\/}\n                            <span className=\"relative z-10\">\n                                {option.label}\n                            <\/span>\n                        <\/label>\n                    );\n                })}\n            <\/div>\n        <\/LayoutGroup>\n    );\n}\n\nSlidingRadioGroup.displayName = 'SlidingRadioGroup';\n"}],"meta":{"category":"inputs","version":"1.0.0"},"categories":["inputs"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"logo-cloud","type":"registry:ui","title":"Logo Cloud","description":"A horizontal social proof logo grid displaying client\/partner brands.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/misc\/logo-cloud.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface LogoItem {\n    icon: React.ComponentType<{ className?: string }>;\n    name: string;\n}\n\nexport interface LogoCloudProps extends React.HTMLAttributes<HTMLDivElement> {\n    title?: string;\n    items: LogoItem[];\n}\n\nexport function LogoCloud({\n    className,\n    title,\n    items,\n    ...props\n}: LogoCloudProps) {\n    return (\n        <div\n            className={cn(\n                'relative z-10 flex w-full max-w-2xl flex-col items-center gap-4 border-t border-border\/40 pt-8 select-none',\n                className,\n            )}\n            {...props}\n        >\n            {title && (\n                <span className=\"text-[10px] font-bold tracking-widest text-muted-foreground uppercase\">\n                    {title}\n                <\/span>\n            )}\n            <div className=\"mt-2 flex flex-wrap items-center justify-center gap-8 md:gap-12\">\n                {items.map((item, i) => {\n                    const Icon = item.icon;\n                    return (\n                        <div\n                            key={i}\n                            className=\"group flex cursor-pointer items-center gap-2 text-muted-foreground\/70 transition-colors hover:text-foreground\"\n                        >\n                            <Icon className=\"size-5 text-muted-foreground\/50 transition-colors group-hover:text-primary\" \/>\n                            <span className=\"font-mono text-sm font-bold tracking-tight\">\n                                {item.name}\n                            <\/span>\n                        <\/div>\n                    );\n                })}\n            <\/div>\n        <\/div>\n    );\n}\n\nexport default LogoCloud;\n"}],"meta":{"category":"misc","version":"1.0.0"},"categories":["misc"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"wrapper","type":"registry:ui","title":"Wrapper","description":"A beautiful component for your application.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/misc\/wrapper.tsx","type":"registry:ui","content":"import { cn } from '@\/lib\/utils';\n\nexport default function Wrapper({\n    className,\n    as,\n    children,\n    ...props\n}: {\n    className?: string;\n    as?: React.ElementType;\n    children: React.ReactNode;\n}) {\n    const Comp = as || 'div';\n\n    return (\n        <Comp\n            className={cn(\n                'mx-auto w-full max-w-7xl px-4 sm:px-6 lg:px-8',\n                className,\n            )}\n            {...props}\n        >\n            {children}\n        <\/Comp>\n    );\n}\n\nWrapper.displayName = 'Wrapper';\n"}],"meta":{"category":"misc","version":"1.0.0"},"categories":["misc"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"browser-mockup","type":"registry:ui","title":"Browser Mockup","description":"A clean browser mockup container frame with close\/minimize chrome controls and viewport slot.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/mockups\/browser-mockup.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface BrowserMockupProps extends React.HTMLAttributes<HTMLDivElement> {\n    title?: string;\n    viewportClassName?: string;\n}\n\nconst BrowserMockup = React.forwardRef<HTMLDivElement, BrowserMockupProps>(\n    (\n        {\n            className,\n            children,\n            title = 'preview.app',\n            viewportClassName,\n            ...props\n        },\n        ref,\n    ) => {\n        return (\n            <div\n                ref={ref}\n                className={cn(\n                    'group relative flex w-full flex-col justify-between overflow-hidden rounded-xl border border-border\/40 bg-zinc-950 shadow-2xl select-none',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Window Chrome Header *\/}\n                <div className=\"flex h-9 shrink-0 items-center gap-2 border-b border-zinc-800 bg-zinc-900\/60 px-4\">\n                    <div className=\"flex shrink-0 gap-1.5\">\n                        <span className=\"size-3 rounded-full bg-destructive\/80\" \/>\n                        <span className=\"size-3 rounded-full bg-chart-4\/80\" \/>\n                        <span className=\"size-3 rounded-full bg-chart-2\/80\" \/>\n                    <\/div>\n                    <div className=\"mx-auto max-w-xs truncate font-mono text-[10px] text-zinc-500 select-none\">\n                        {title}\n                    <\/div>\n                <\/div>\n\n                {\/* Main Viewport *\/}\n                <div\n                    className={cn(\n                        'relative flex-1 overflow-hidden bg-zinc-900\/80',\n                        viewportClassName,\n                    )}\n                >\n                    {children}\n                <\/div>\n            <\/div>\n        );\n    },\n);\n\nBrowserMockup.displayName = 'BrowserMockup';\n\nexport { BrowserMockup };\nexport default BrowserMockup;\n"}],"meta":{"category":"mockups","version":"1.0.0"},"categories":["mockups"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"code-window","type":"registry:ui","title":"Code Window","description":"An interactive code editor window mockup with custom file tags and active indicators.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/mockups\/code-window.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface CodeWindowProps extends React.HTMLAttributes<HTMLDivElement> {\n    title: string;\n    lang?: string;\n    code: string;\n    active?: boolean;\n}\n\nconst CodeWindow = React.forwardRef<HTMLDivElement, CodeWindowProps>(\n    ({ className, title, lang, code, active = true, ...props }, ref) => {\n        return (\n            <div\n                ref={ref}\n                className={cn(\n                    'flex w-full flex-col overflow-hidden rounded-xl border border-border\/40 bg-zinc-950 text-left font-mono text-xs shadow-2xl select-none',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Header bar *\/}\n                <div className=\"flex h-9 shrink-0 items-center justify-between border-b border-zinc-800 bg-zinc-900\/60 px-4 text-zinc-500\">\n                    <div className=\"flex items-center gap-2\">\n                        <span\n                            className={cn(\n                                'size-2 rounded-full transition-colors',\n                                active\n                                    ? 'animate-pulse bg-chart-2'\n                                    : 'bg-muted',\n                            )}\n                        \/>\n                        <span>{title}<\/span>\n                    <\/div>\n                    {lang && (\n                        <span className=\"text-[10px] font-bold tracking-widest text-zinc-600 uppercase\">\n                            {lang}\n                        <\/span>\n                    )}\n                <\/div>\n\n                {\/* Code Container *\/}\n                <div className=\"flex-1 overflow-y-auto bg-zinc-950\/85 p-4 font-mono text-[11px] leading-relaxed whitespace-pre text-zinc-300\">\n                    {code}\n                <\/div>\n            <\/div>\n        );\n    },\n);\n\nCodeWindow.displayName = 'CodeWindow';\n\nexport { CodeWindow };\nexport default CodeWindow;\n"}],"meta":{"category":"mockups","version":"1.0.0"},"categories":["mockups"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"phone-mockup","type":"registry:ui","title":"Phone Mockup","description":"A high-fidelity CSS-only smartphone mock frame that acts as a container for mobile previews.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/mockups\/phone-mockup.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface PhoneMockupProps extends React.HTMLAttributes<HTMLDivElement> {\n    screenClassName?: string;\n}\n\nconst PhoneMockup = React.forwardRef<HTMLDivElement, PhoneMockupProps>(\n    ({ className, children, screenClassName, ...props }, ref) => {\n        return (\n            <div\n                ref={ref}\n                className={cn(\n                    'relative mx-auto h-[480px] w-64 shrink-0 rounded-[36px] border-[6px] border-zinc-800 bg-zinc-950 p-3 shadow-2xl ring-1 ring-zinc-700\/50 select-none',\n                    className,\n                )}\n                {...props}\n            >\n                {\/* Ear Speaker Notch *\/}\n                <div className=\"absolute top-2 left-1\/2 flex h-4 w-20 -translate-x-1\/2 items-center justify-center rounded-full bg-zinc-800\">\n                    <span className=\"h-1 w-8 rounded-full bg-zinc-900\" \/>\n                <\/div>\n\n                {\/* Screen Content Container *\/}\n                <div\n                    className={cn(\n                        'flex h-full w-full flex-col overflow-hidden rounded-[28px] border border-zinc-800\/40 bg-zinc-900 p-4',\n                        screenClassName,\n                    )}\n                >\n                    {children}\n                <\/div>\n            <\/div>\n        );\n    },\n);\n\nPhoneMockup.displayName = 'PhoneMockup';\n\nexport { PhoneMockup };\nexport default PhoneMockup;\n"}],"meta":{"category":"mockups","version":"1.0.0"},"categories":["mockups"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"progress-circle","type":"registry:ui","title":"Progress Circle","description":"A clean SVG circular progress meter displaying animated percentage levels.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/progress\/progress-circle.tsx","type":"registry:ui","content":"import React, { useEffect, useState } from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface ProgressCircleProps {\n    value: number;\n    size?: number;\n    strokeWidth?: number;\n    className?: string;\n    showValue?: boolean;\n    label?: string;\n}\n\nexport function ProgressCircle({\n    value = 0,\n    size = 80,\n    strokeWidth = 8,\n    className,\n    showValue = true,\n    label,\n}: ProgressCircleProps) {\n    const [currentValue, setCurrentValue] = useState(0);\n    const radius = (size - strokeWidth) \/ 2;\n    const circumference = radius * 2 * Math.PI;\n\n    useEffect(() => {\n        const timer = setTimeout(() => {\n            setCurrentValue(Math.min(Math.max(value, 0), 100));\n        }, 100);\n        return () => clearTimeout(timer);\n    }, [value]);\n\n    const strokeDashoffset =\n        circumference - (currentValue \/ 100) * circumference;\n\n    return (\n        <div\n            className={cn(\n                'relative inline-flex flex-col items-center justify-center select-none',\n                className,\n            )}\n            style={{ width: size, height: size }}\n        >\n            <svg className=\"-rotate-90 transform\" width={size} height={size}>\n                {\/* Background Circle *\/}\n                <circle\n                    className=\"text-muted\/30\"\n                    stroke=\"currentColor\"\n                    strokeWidth={strokeWidth}\n                    fill=\"transparent\"\n                    r={radius}\n                    cx={size \/ 2}\n                    cy={size \/ 2}\n                \/>\n                {\/* Foreground Circle *\/}\n                <circle\n                    className=\"text-primary transition-all duration-1000 ease-out\"\n                    stroke=\"currentColor\"\n                    strokeWidth={strokeWidth}\n                    strokeDasharray={circumference}\n                    strokeDashoffset={strokeDashoffset}\n                    strokeLinecap=\"round\"\n                    fill=\"transparent\"\n                    r={radius}\n                    cx={size \/ 2}\n                    cy={size \/ 2}\n                \/>\n            <\/svg>\n\n            {showValue && (\n                <div className=\"absolute inset-0 flex flex-col items-center justify-center text-center\">\n                    <span className=\"font-mono text-sm leading-none font-extrabold tracking-tight text-foreground\">\n                        {Math.round(currentValue)}%\n                    <\/span>\n                    {label && (\n                        <span className=\"mt-0.5 text-[8px] font-bold tracking-wider text-muted-foreground uppercase\">\n                            {label}\n                        <\/span>\n                    )}\n                <\/div>\n            )}\n        <\/div>\n    );\n}\n\nexport default ProgressCircle;\n"}],"meta":{"category":"progress","version":"1.0.0"},"categories":["progress"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"interactive-rating","type":"registry:ui","title":"Interactive Rating","description":"A star-based rating component supporting interactive hover feedback and selections.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/rating\/interactive-rating.tsx","type":"registry:ui","content":"import React, { useState } from 'react';\nimport { Star } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface InteractiveRatingProps {\n    maxRating?: number;\n    defaultRating?: number;\n    onChange?: (rating: number) => void;\n    className?: string;\n}\n\nexport function InteractiveRating({\n    maxRating = 5,\n    defaultRating = 0,\n    onChange,\n    className,\n}: InteractiveRatingProps) {\n    const [rating, setRating] = useState(defaultRating);\n    const [hoverRating, setHoverRating] = useState<number | null>(null);\n\n    const handleSelect = (val: number) => {\n        setRating(val);\n        if (onChange) {\n            onChange(val);\n        }\n    };\n\n    return (\n        <div className={cn('flex items-center gap-1 select-none', className)}>\n            {[...Array(maxRating)].map((_, i) => {\n                const starVal = i + 1;\n                const isActive =\n                    hoverRating !== null\n                        ? starVal <= hoverRating\n                        : starVal <= rating;\n                return (\n                    <button\n                        key={i}\n                        type=\"button\"\n                        onClick={() => handleSelect(starVal)}\n                        onMouseEnter={() => setHoverRating(starVal)}\n                        onMouseLeave={() => setHoverRating(null)}\n                        className=\"cursor-pointer transition-transform duration-100 hover:scale-115 focus:outline-hidden active:scale-95\"\n                    >\n                        <Star\n                            className={cn(\n                                'size-5 transition-colors duration-150',\n                                isActive\n                                    ? 'fill-chart-4 text-chart-4'\n                                    : 'text-muted-foreground\/35 hover:text-muted-foreground\/60',\n                            )}\n                        \/>\n                    <\/button>\n                );\n            })}\n        <\/div>\n    );\n}\n\nexport default InteractiveRating;\n"}],"meta":{"category":"rating","version":"1.0.0"},"categories":["rating"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"review-card","type":"registry:ui","title":"Review Card","description":"A reusable client review card displaying star ratings, verified badges, and client profile data.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/reviews\/review-card.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { Star, CheckCircle } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nexport interface ReviewItem {\n    id: string | number;\n    author: string;\n    avatar?: string; \/\/ image URL or initial letter\n    role?: string;\n    company?: string;\n    rating: number;\n    comment: string;\n    date?: string;\n    verified?: boolean;\n    tags?: string[];\n}\n\ninterface ReviewCardProps extends React.ComponentProps<typeof Card> {\n    review: ReviewItem;\n    showQuoteIcon?: boolean;\n}\n\nexport function ReviewCard({\n    review,\n    showQuoteIcon = false,\n    className,\n    ...props\n}: ReviewCardProps) {\n    const renderStars = (rating: number) => {\n        const floor = Math.floor(rating);\n        return (\n            <div className=\"flex items-center gap-0.5 text-chart-4\">\n                {[...Array(5)].map((_, i) => (\n                    <Star\n                        key={i}\n                        className={cn(\n                            'size-4 fill-current',\n                            i >= floor &&\n                                'fill-transparent text-muted-foreground\/40 opacity-25',\n                        )}\n                    \/>\n                ))}\n            <\/div>\n        );\n    };\n\n    return (\n        <Card\n            className={cn(\n                'relative flex flex-col justify-between overflow-hidden bg-card\/65 p-6 backdrop-blur-md transition-all duration-300 select-none hover:border-primary\/20 hover:shadow-md',\n                className,\n            )}\n            {...props}\n        >\n            {\/* Background Quote Mark *\/}\n            {showQuoteIcon && (\n                <span className=\"pointer-events-none absolute -top-3 -right-2 font-serif text-8xl font-bold text-primary\/5 select-none\">\n                    \u201c\n                <\/span>\n            )}\n\n            <div className=\"space-y-4\">\n                {\/* Rating & Verified Badge *\/}\n                <div className=\"flex items-center justify-between gap-4\">\n                    {renderStars(review.rating)}\n                    {review.verified && (\n                        <span className=\"inline-flex items-center gap-1 rounded-full border border-chart-2\/20 bg-chart-2\/10 px-2 py-0.5 text-[9px] font-semibold text-chart-2\">\n                            <CheckCircle className=\"size-2.5 fill-current\" \/>\n                            Verified\n                        <\/span>\n                    )}\n                <\/div>\n\n                {\/* Comment Text *\/}\n                <p className=\"text-sm leading-relaxed text-muted-foreground italic\">\n                    \"{review.comment}\"\n                <\/p>\n            <\/div>\n\n            {\/* Author Profile Footer *\/}\n            <div className=\"mt-6 flex items-center justify-between gap-4 border-t border-border\/50 pt-4\">\n                <div className=\"flex items-center gap-3\">\n                    {review.avatar && review.avatar.startsWith('http') ? (\n                        <img\n                            src={review.avatar}\n                            alt={review.author}\n                            className=\"size-10 rounded-full border border-border object-cover\"\n                        \/>\n                    ) : (\n                        <div className=\"flex size-10 shrink-0 items-center justify-center rounded-full border border-primary\/20 bg-primary\/10 text-sm font-extrabold text-primary uppercase\">\n                            {review.avatar || review.author.charAt(0)}\n                        <\/div>\n                    )}\n\n                    <div className=\"min-w-0 space-y-0.5 text-left\">\n                        <h4 className=\"truncate text-xs font-bold text-foreground\">\n                            {review.author}\n                        <\/h4>\n                        {(review.role || review.company) && (\n                            <p className=\"truncate text-[10px] text-muted-foreground\">\n                                {review.role}{' '}\n                                {review.company && `@ ${review.company}`}\n                            <\/p>\n                        )}\n                    <\/div>\n                <\/div>\n\n                {review.date && (\n                    <span className=\"shrink-0 text-[10px] font-medium text-muted-foreground\/80\">\n                        {review.date}\n                    <\/span>\n                )}\n            <\/div>\n\n            {\/* Pill tags *\/}\n            {review.tags && review.tags.length > 0 && (\n                <div className=\"mt-3.5 flex flex-wrap gap-1\">\n                    {review.tags.map((tag) => (\n                        <span\n                            key={tag}\n                            className=\"rounded-full border border-border\/20 bg-muted\/60 px-2 py-0.5 text-[9px] font-medium text-muted-foreground\/80\"\n                        >\n                            #{tag}\n                        <\/span>\n                    ))}\n                <\/div>\n            )}\n        <\/Card>\n    );\n}\n\nexport default ReviewCard;\n"}],"meta":{"category":"reviews","version":"1.0.0"},"categories":["reviews"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"review-carousel","type":"registry:ui","title":"Review Carousel","description":"A dynamic client reviews slider utilizing Swiper with auto-scroll and dot pagination controls.","author":"designbycode","dependencies":["swiper","lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/reviews\/review-carousel.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { Swiper, SwiperSlide } from 'swiper\/react';\nimport type { Swiper as SwiperClass } from 'swiper';\nimport { Autoplay, Pagination, Navigation } from 'swiper\/modules';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { ReviewItem, ReviewCard } from '.\/review-card';\n\n\/\/ Import Swiper styles\nimport 'swiper\/css';\nimport 'swiper\/css\/pagination';\nimport 'swiper\/css\/navigation';\n\ninterface ReviewCarouselProps extends React.HTMLAttributes<HTMLDivElement> {\n    reviews: ReviewItem[];\n    autoplay?: boolean;\n    autoplayDelay?: number;\n    slidesPerView?: number | 'auto';\n    spaceBetween?: number;\n}\n\nexport function ReviewCarousel({\n    reviews,\n    autoplay = true,\n    autoplayDelay = 5000,\n    slidesPerView = 1,\n    spaceBetween = 24,\n    className,\n    ...props\n}: ReviewCarouselProps) {\n    const [swiper, setSwiper] = React.useState<SwiperClass | null>(null);\n    const [activeIndex, setActiveIndex] = React.useState(0);\n\n    const handlePrev = () => {\n        swiper?.slidePrev();\n    };\n\n    const handleNext = () => {\n        swiper?.slideNext();\n    };\n\n    const handleDotClick = (index: number) => {\n        swiper?.slideTo(index);\n    };\n\n    const modules = [];\n    if (autoplay) {\n        modules.push(Autoplay);\n    }\n    modules.push(Pagination, Navigation);\n\n    return (\n        <div\n            className={cn(\n                'group relative mx-auto w-full max-w-5xl px-4 py-8 select-none',\n                className,\n            )}\n            {...props}\n        >\n            <div className=\"relative overflow-visible\">\n                <Swiper\n                    onSwiper={setSwiper}\n                    onSlideChange={(s) => setActiveIndex(s.activeIndex)}\n                    modules={modules}\n                    spaceBetween={spaceBetween}\n                    slidesPerView={slidesPerView}\n                    centeredSlides={slidesPerView === 1 ? false : true}\n                    loop={reviews.length > 2}\n                    autoplay={\n                        autoplay\n                            ? {\n                                  delay: autoplayDelay,\n                                  disableOnInteraction: false,\n                                  pauseOnMouseEnter: true,\n                              }\n                            : false\n                    }\n                    breakpoints={{\n                        640: {\n                            slidesPerView: Math.min(\n                                slidesPerView === 'auto'\n                                    ? 2\n                                    : (slidesPerView as number),\n                                2,\n                            ),\n                        },\n                        1024: {\n                            slidesPerView:\n                                slidesPerView === 'auto'\n                                    ? 3\n                                    : (slidesPerView as number),\n                        },\n                    }}\n                    className=\"w-full\"\n                >\n                    {reviews.map((review) => (\n                        <SwiperSlide\n                            key={review.id}\n                            className=\"flex h-auto py-2\"\n                        >\n                            <ReviewCard\n                                review={review}\n                                showQuoteIcon\n                                className=\"h-full w-full flex-1\"\n                            \/>\n                        <\/SwiperSlide>\n                    ))}\n                <\/Swiper>\n\n                {\/* Styled Arrow Navigation (shown on hover) *\/}\n                {reviews.length > 1 && (\n                    <>\n                        <button\n                            onClick={handlePrev}\n                            className=\"absolute top-1\/2 -left-4 z-20 flex size-9 -translate-y-1\/2 cursor-pointer items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 shadow-xs transition-all group-hover:opacity-100 hover:bg-muted hover:text-foreground active:scale-90\"\n                        >\n                            <ChevronLeft className=\"size-4\" \/>\n                        <\/button>\n                        <button\n                            onClick={handleNext}\n                            className=\"absolute top-1\/2 -right-4 z-20 flex size-9 -translate-y-1\/2 cursor-pointer items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 shadow-xs transition-all group-hover:opacity-100 hover:bg-muted hover:text-foreground active:scale-90\"\n                        >\n                            <ChevronRight className=\"size-4\" \/>\n                        <\/button>\n                    <\/>\n                )}\n            <\/div>\n\n            {\/* Custom styled slider dot indicators *\/}\n            {reviews.length > 1 && (\n                <div className=\"mt-6 flex items-center justify-center gap-1.5\">\n                    {reviews.map((_, idx) => (\n                        <button\n                            key={idx}\n                            onClick={() => handleDotClick(idx)}\n                            className={cn(\n                                'h-1.5 cursor-pointer rounded-full transition-all duration-300',\n                                activeIndex === idx\n                                    ? 'w-5 bg-primary'\n                                    : 'w-1.5 bg-muted-foreground\/30 hover:bg-muted-foreground\/60',\n                            )}\n                        \/>\n                    ))}\n                <\/div>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"reviews","version":"1.0.0"},"categories":["reviews"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"review-grid","type":"registry:ui","title":"Review Grid","description":"A responsive grid layout to present client reviews in neat columns.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/reviews\/review-grid.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { ReviewItem, ReviewCard } from '.\/review-card';\n\ninterface ReviewGridProps extends React.HTMLAttributes<HTMLDivElement> {\n    reviews: ReviewItem[];\n    columns?: 1 | 2 | 3 | 4;\n}\n\nexport function ReviewGrid({\n    reviews,\n    columns = 3,\n    className,\n    ...props\n}: ReviewGridProps) {\n    const columnClasses = {\n        1: 'grid-cols-1',\n        2: 'grid-cols-1 md:grid-cols-2',\n        3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',\n        4: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4',\n    };\n\n    return (\n        <div\n            className={cn(\n                'mx-auto grid w-full max-w-7xl gap-6 px-4 py-8',\n                columnClasses[columns],\n                className,\n            )}\n            {...props}\n        >\n            {reviews.map((review) => (\n                <ReviewCard key={review.id} review={review} showQuoteIcon \/>\n            ))}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"reviews","version":"1.0.0"},"categories":["reviews"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"review-hero","type":"registry:ui","title":"Review Hero","description":"A premium single centerpiece spotlight customer review hero component.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/reviews\/review-hero.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { Star, CheckCircle } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\nimport { ReviewItem } from '.\/review-card';\n\ninterface ReviewHeroProps extends React.ComponentProps<typeof Card> {\n    review: ReviewItem;\n}\n\nexport function ReviewHero({ review, className, ...props }: ReviewHeroProps) {\n    const renderStars = (rating: number) => {\n        const floor = Math.floor(rating);\n        return (\n            <div className=\"flex items-center gap-1 text-chart-4\">\n                {[...Array(5)].map((_, i) => (\n                    <Star\n                        key={i}\n                        className={cn(\n                            'size-5 fill-current',\n                            i >= floor &&\n                                'fill-transparent text-muted-foreground\/40 opacity-25',\n                        )}\n                    \/>\n                ))}\n            <\/div>\n        );\n    };\n\n    return (\n        <Card\n            className={cn(\n                'relative mx-auto flex max-w-4xl flex-col justify-between overflow-hidden bg-card\/45 p-8 shadow-xl backdrop-blur-md select-none md:p-12',\n                className,\n            )}\n            {...props}\n        >\n            {\/* Ambient Radial Backlight Glow *\/}\n            <div className=\"pointer-events-none absolute -top-36 -right-36 -z-10 size-96 rounded-full bg-primary\/5 blur-3xl\" \/>\n            <div className=\"pointer-events-none absolute -bottom-36 -left-36 -z-10 size-96 rounded-full bg-primary\/5 blur-3xl\" \/>\n\n            {\/* Giant quote mark backdrop *\/}\n            <span className=\"pointer-events-none absolute top-4 left-6 font-serif text-[180px] leading-none font-bold text-primary\/8 select-none\">\n                \u201c\n            <\/span>\n\n            <div className=\"relative z-10 space-y-6 pt-8\">\n                {\/* Rating stars *\/}\n                <div className=\"flex items-center gap-4\">\n                    {renderStars(review.rating)}\n                    {review.verified && (\n                        <span className=\"inline-flex items-center gap-1 rounded-full border border-chart-2\/20 bg-chart-2\/10 px-3 py-0.5 text-[10px] font-semibold text-chart-2\">\n                            <CheckCircle className=\"size-3 fill-current\" \/>\n                            Verified Customer Feedback\n                        <\/span>\n                    )}\n                <\/div>\n\n                {\/* Big testimonial quotation comment *\/}\n                <blockquote className=\"text-lg leading-relaxed font-medium text-foreground italic md:text-xl\">\n                    \"{review.comment}\"\n                <\/blockquote>\n            <\/div>\n\n            {\/* Author Profile and Details *\/}\n            <div className=\"relative z-10 mt-8 flex flex-col justify-between gap-4 border-t border-border\/50 pt-6 sm:flex-row sm:items-center\">\n                <div className=\"flex items-center gap-4\">\n                    {review.avatar && review.avatar.startsWith('http') ? (\n                        <img\n                            src={review.avatar}\n                            alt={review.author}\n                            className=\"size-12 rounded-full border border-border object-cover\"\n                        \/>\n                    ) : (\n                        <div className=\"flex size-12 shrink-0 items-center justify-center rounded-full border border-primary\/20 bg-primary\/10 text-base font-extrabold text-primary uppercase\">\n                            {review.avatar || review.author.charAt(0)}\n                        <\/div>\n                    )}\n\n                    <div className=\"min-w-0 space-y-1 text-left\">\n                        <h4 className=\"truncate text-sm font-bold text-foreground\">\n                            {review.author}\n                        <\/h4>\n                        {(review.role || review.company) && (\n                            <p className=\"truncate text-xs text-muted-foreground\">\n                                {review.role}{' '}\n                                {review.company && `at ${review.company}`}\n                            <\/p>\n                        )}\n                    <\/div>\n                <\/div>\n\n                {review.date && (\n                    <span className=\"shrink-0 text-xs font-semibold text-muted-foreground\/80\">\n                        {review.date}\n                    <\/span>\n                )}\n            <\/div>\n\n            {\/* Tags display *\/}\n            {review.tags && review.tags.length > 0 && (\n                <div className=\"relative z-10 mt-4 flex flex-wrap gap-2\">\n                    {review.tags.map((tag) => (\n                        <span\n                            key={tag}\n                            className=\"rounded-md border border-border\/30 bg-muted px-2.5 py-0.5 text-[10px] font-semibold text-muted-foreground\"\n                        >\n                            #{tag}\n                        <\/span>\n                    ))}\n                <\/div>\n            )}\n        <\/Card>\n    );\n}\n\nexport default ReviewHero;\n"}],"meta":{"category":"reviews","version":"1.0.0"},"categories":["reviews"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"review-marquee","type":"registry:ui","title":"Review Marquee","description":"An infinite scrolling testimonial track marquee that pauses on hover.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/reviews\/review-marquee.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { ReviewItem, ReviewCard } from '.\/review-card';\n\ninterface ReviewMarqueeProps extends React.HTMLAttributes<HTMLDivElement> {\n    reviews: ReviewItem[];\n    speed?: 'slow' | 'medium' | 'fast';\n    direction?: 'left' | 'right';\n    pauseOnHover?: boolean;\n}\n\nexport function ReviewMarquee({\n    reviews,\n    speed = 'medium',\n    direction = 'left',\n    pauseOnHover = true,\n    className,\n    ...props\n}: ReviewMarqueeProps) {\n    const speedClasses = {\n        slow: '[animation-duration:55s]',\n        medium: '[animation-duration:35s]',\n        fast: '[animation-duration:20s]',\n    };\n\n    const directionClasses = {\n        left: 'animate-marquee flex-row',\n        right: 'animate-marquee flex-row [animation-direction:reverse]',\n    };\n\n    \/\/ Duplicate reviews to fill the scrolling track cleanly\n    const doubledReviews = [...reviews, ...reviews];\n\n    return (\n        <div\n            className={cn(\n                'mask-image-horizontal relative flex w-full overflow-x-hidden py-8 select-none',\n                className,\n            )}\n            {...props}\n        >\n            {\/* Masking visual fades on edges *\/}\n            <div className=\"pointer-events-none absolute inset-y-0 left-0 z-10 w-24 bg-linear-to-r from-background to-transparent\" \/>\n            <div className=\"pointer-events-none absolute inset-y-0 right-0 z-10 w-24 bg-linear-to-l from-background to-transparent\" \/>\n\n            <div\n                className={cn(\n                    'flex w-max shrink-0 gap-6',\n                    directionClasses[direction],\n                    speedClasses[speed],\n                    pauseOnHover && 'hover:[animation-play-state:paused]',\n                )}\n            >\n                {doubledReviews.map((review, index) => (\n                    <ReviewCard\n                        key={`${review.id}-${index}`}\n                        review={review}\n                        className=\"w-[300px] shrink-0 md:w-[360px]\"\n                    \/>\n                ))}\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"reviews","version":"1.0.0"},"categories":["reviews"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"review-masonry","type":"registry:ui","title":"Review Masonry","description":"A wall-of-love style masonry layout that handles varying testimonial text heights.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/reviews\/review-masonry.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { ReviewItem, ReviewCard } from '.\/review-card';\n\ninterface ReviewMasonryProps extends React.HTMLAttributes<HTMLDivElement> {\n    reviews: ReviewItem[];\n    columns?: 1 | 2 | 3 | 4;\n}\n\nexport function ReviewMasonry({\n    reviews,\n    columns = 3,\n    className,\n    ...props\n}: ReviewMasonryProps) {\n    const columnClasses = {\n        1: 'columns-1',\n        2: 'columns-1 md:columns-2',\n        3: 'columns-1 md:columns-2 lg:columns-3',\n        4: 'columns-1 sm:columns-2 md:columns-3 lg:columns-4',\n    };\n\n    return (\n        <div\n            className={cn(\n                'mx-auto w-full max-w-7xl gap-6 px-4 py-8',\n                columnClasses[columns],\n                className,\n            )}\n            {...props}\n        >\n            {reviews.map((review) => (\n                <div key={review.id} className=\"mb-6 break-inside-avoid\">\n                    <ReviewCard review={review} showQuoteIcon \/>\n                <\/div>\n            ))}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"reviews","version":"1.0.0"},"categories":["reviews"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"animated-tabs","type":"registry:ui","title":"Animated Tabs","description":"A tab selection bar showcasing smooth fluid sliding indicator animations.","author":"designbycode","dependencies":["motion"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/tabs\/animated-tabs.tsx","type":"registry:ui","content":"'use client';\n\nimport { LayoutGroup, motion } from 'motion\/react';\nimport type { HTMLAttributes, ReactNode } from 'react';\nimport { useId, useState } from 'react';\n\nimport { cn } from '@\/lib\/utils';\n\nexport type AnimatedTabsProps = Omit<\n    HTMLAttributes<HTMLDivElement>,\n    'onChange'\n> & {\n    tabs: {\n        id: string;\n        label: ReactNode;\n        content?: ReactNode;\n    }[];\n    value?: string;\n    defaultValue?: string;\n    onChange?: (tabId: string) => void;\n    tabsClassName?: string;\n    tabClassName?: string;\n    activeTabClassName?: string;\n    inactiveTabClassName?: string;\n    indicatorClassName?: string;\n    contentClassName?: string;\n    showContent?: boolean;\n};\n\nexport function AnimatedTabs({\n    tabs,\n    value,\n    defaultValue,\n    onChange,\n    className,\n    tabsClassName,\n    tabClassName,\n    activeTabClassName,\n    inactiveTabClassName,\n    indicatorClassName,\n    contentClassName,\n    showContent = false,\n    ...props\n}: AnimatedTabsProps) {\n    const id = useId();\n\n    const resolveIndex = (tabId?: string) => {\n        if (!tabId) {\n            return 0;\n        }\n\n        const idx = tabs.findIndex((t) => t.id === tabId);\n\n        return idx >= 0 ? idx : 0;\n    };\n\n    const [activeIndex, setActiveIndex] = useState(() =>\n        resolveIndex(defaultValue),\n    );\n\n    const isControlled = value !== undefined;\n    const activeTabIndex = isControlled ? resolveIndex(value) : activeIndex;\n    const activeTab = tabs[activeTabIndex] ?? tabs[0];\n\n    const handleChange = (index: number) => {\n        if (!isControlled) {\n            setActiveIndex(index);\n        }\n\n        onChange?.(tabs[index].id);\n    };\n\n    return (\n        <div className={cn('w-full', className)} {...props}>\n            <LayoutGroup id={id}>\n                <div\n                    role=\"tablist\"\n                    className={cn(\n                        'flex items-center gap-1 rounded-md border border-border bg-background p-1',\n                        tabsClassName,\n                    )}\n                >\n                    {tabs.map((tab, index) => (\n                        <button\n                            key={tab.id}\n                            role=\"tab\"\n                            aria-selected={activeTabIndex === index}\n                            aria-controls={`${id}-panel-${tab.id}`}\n                            id={`${id}-tab-${tab.id}`}\n                            onClick={() => handleChange(index)}\n                            className={cn(\n                                'relative rounded-sm px-4 py-2 text-xs font-medium transition focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none',\n                                tabClassName,\n                                activeTabIndex === index\n                                    ? cn('text-foreground', activeTabClassName)\n                                    : cn(\n                                          'text-muted-foreground hover:text-foreground',\n                                          inactiveTabClassName,\n                                      ),\n                            )}\n                        >\n                            {activeTabIndex === index && (\n                                <motion.div\n                                    layoutId=\"indicator\"\n                                    className={cn(\n                                        'absolute inset-0 rounded-sm bg-muted',\n                                        indicatorClassName,\n                                    )}\n                                    transition={{\n                                        type: 'spring',\n                                        stiffness: 500,\n                                        damping: 30,\n                                    }}\n                                \/>\n                            )}\n                            <span className=\"relative z-10\">{tab.label}<\/span>\n                        <\/button>\n                    ))}\n                <\/div>\n            <\/LayoutGroup>\n\n            {showContent && activeTab?.content && (\n                <div\n                    role=\"tabpanel\"\n                    id={`${id}-panel-${activeTab.id}`}\n                    aria-labelledby={`${id}-tab-${activeTab.id}`}\n                    className={cn('mt-4', contentClassName)}\n                >\n                    <motion.div\n                        key={activeTab.id}\n                        initial={{ opacity: 0, y: 4 }}\n                        animate={{ opacity: 1, y: 0 }}\n                        exit={{ opacity: 0, y: -4 }}\n                        transition={{ duration: 0.2 }}\n                    >\n                        {activeTab.content}\n                    <\/motion.div>\n                <\/div>\n            )}\n        <\/div>\n    );\n}\n"}],"meta":{"category":"tabs","version":"1.0.0"},"categories":["tabs"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"black-hole","type":"registry:ui","title":"Black Hole","description":"An interactive 3D WebGL Black Hole simulation with an accretion disk and gravitational lensing glow effects powered by Three.js.","author":"designbycode","dependencies":["three"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/threejs\/black-hole.tsx","type":"registry:ui","content":"\/* eslint-disable *\/\n`use client`;\n\nimport { useEffect, useRef, useState } from 'react';\nimport * as THREE from 'three';\nimport { OrbitControls } from 'three\/examples\/jsm\/controls\/OrbitControls.js';\nimport { cn } from '@\/lib\/utils';\n\nexport interface BlackHoleProps {\n    className?: string;\n\n    \/**\n     * Radius of the event horizon (singularity silhouette).\n     * Default: 1.2\n     *\/\n    eventHorizonRadius?: number;\n\n    \/**\n     * Inner radius of the accretion disk.\n     * Default: 2.2\n     *\/\n    diskRadiusInner?: number;\n\n    \/**\n     * Outer radius of the accretion disk.\n     * Default: 7.2\n     *\/\n    diskRadiusOuter?: number;\n\n    \/**\n     * Density of the vector rings.\n     * Default: 90\n     *\/\n    ringDensity?: number;\n\n    \/**\n     * Thickness of the accretion disk vector ribbons.\n     * Default: 0.08\n     *\/\n    lineWidth?: number;\n\n    \/**\n     * Colors for the accretion disk (inner hot color, outer cool color).\n     * Default: ['#ffaa00', '#0077ff'] (orange to blue)\n     *\/\n    colors?: string[];\n\n    \/**\n     * Color of the Einstein Ring lensing glow.\n     * Default: '#ff8800'\n     *\/\n    glowColor?: string;\n\n    \/**\n     * Speed multiplier for the rotation and wave animations.\n     * Default: 1.0\n     *\/\n    speed?: number;\n\n    \/**\n     * Enable interactive OrbitControls (drag to rotate, scroll to zoom).\n     * Default: true\n     *\/\n    enableOrbitControls?: boolean;\n\n    \/**\n     * Enable camera auto-orbit around the black hole.\n     * Default: true\n     *\/\n    autoRotate?: boolean;\n\n    \/**\n     * Initial position of the camera in 3D space.\n     * Default: { x: 0, y: 1.8, z: 9 }\n     *\/\n    cameraPosition?: { x: number; y: number; z: number };\n\n    \/**\n     * Max device pixel ratio for performance scaling.\n     * Default: 2\n     *\/\n    maxPixelRatio?: number;\n\n    \/**\n     * Callback when the Three.js scene is fully initialized.\n     *\/\n    onReady?: () => void;\n}\n\nexport function BlackHole({\n    className,\n    eventHorizonRadius = 1.2,\n    diskRadiusInner = 2.2,\n    diskRadiusOuter = 7.2,\n    ringDensity = 90,\n    lineWidth = 0.08,\n    colors = ['#ffcc00', '#ff3300'],\n    glowColor = '#ff6600',\n    speed = 1.0,\n    enableOrbitControls = true,\n    autoRotate = true,\n    cameraPosition = { x: 0, y: 1.8, z: 9 },\n    maxPixelRatio = 2,\n    onReady,\n}: BlackHoleProps) {\n    const containerRef = useRef<HTMLDivElement>(null);\n    const [size, setSize] = useState({ width: 0, height: 0 });\n\n    useEffect(() => {\n        if (!containerRef.current) return;\n\n        const updateSize = () => {\n            if (containerRef.current) {\n                setSize({\n                    width: containerRef.current.clientWidth,\n                    height: containerRef.current.clientHeight,\n                });\n            }\n        };\n\n        updateSize();\n\n        const observer = new ResizeObserver(updateSize);\n        observer.observe(containerRef.current);\n\n        return () => observer.disconnect();\n    }, []);\n\n    useEffect(() => {\n        if (!containerRef.current || size.width === 0 || size.height === 0)\n            return;\n\n        const el = containerRef.current;\n\n        \/\/ 1. Scene & Camera\n        const scene = new THREE.Scene();\n        const camera = new THREE.PerspectiveCamera(\n            60,\n            size.width \/ size.height,\n            0.1,\n            100,\n        );\n        camera.position.set(\n            cameraPosition.x,\n            cameraPosition.y,\n            cameraPosition.z,\n        );\n\n        \/\/ 2. Renderer\n        const renderer = new THREE.WebGLRenderer({\n            alpha: true,\n            antialias: true,\n            powerPreference: 'high-performance',\n        });\n        renderer.setSize(size.width, size.height);\n        renderer.setPixelRatio(\n            Math.min(window.devicePixelRatio, maxPixelRatio),\n        );\n        el.appendChild(renderer.domElement);\n\n        \/\/ 3. OrbitControls Setup\n        let controls: OrbitControls | null = null;\n        if (enableOrbitControls) {\n            controls = new OrbitControls(camera, renderer.domElement);\n            controls.enableDamping = true;\n            controls.dampingFactor = 0.05;\n            controls.enableZoom = true;\n            controls.minDistance = 3.5;\n            controls.maxDistance = 22.0;\n            controls.enablePan = false; \/\/ Lock focal center on black hole\n\n            controls.autoRotate = autoRotate;\n            controls.autoRotateSpeed = speed * 1.5;\n        }\n\n        \/\/ Color helper\n        const colorInner = new THREE.Color(colors[0] || '#ffcc00');\n        const colorOuter = new THREE.Color(colors[1] || '#ff3300');\n        const colorGlow = new THREE.Color(glowColor);\n\n        const getPaletteColor = (t: number) => {\n            return new THREE.Color().copy(colorInner).lerp(colorOuter, t);\n        };\n\n        \/\/ 4. Singularity (Event Horizon)\n        const horizonGeometry = new THREE.SphereGeometry(\n            eventHorizonRadius,\n            32,\n            32,\n        );\n        const horizonMaterial = new THREE.MeshBasicMaterial({\n            color: 0x000000,\n        });\n        const eventHorizon = new THREE.Mesh(horizonGeometry, horizonMaterial);\n        scene.add(eventHorizon);\n\n        \/\/ 5. Einstein Ring Lensing Glow (Camera-facing Billboarded Glow Corona)\n        const glowSize = eventHorizonRadius * 3.8;\n        const glowGeometry = new THREE.PlaneGeometry(glowSize, glowSize);\n        const glowMaterial = new THREE.ShaderMaterial({\n            uniforms: {\n                uColor: { value: colorGlow },\n                uInnerRadius: { value: eventHorizonRadius },\n            },\n            vertexShader: `\n                varying vec2 vUv;\n                void main() {\n                    vUv = uv;\n                    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n                }\n            `,\n            fragmentShader: `\n                varying vec2 vUv;\n                uniform vec3 uColor;\n                uniform float uInnerRadius;\n                void main() {\n                    float dist = length(vUv - vec2(0.5)) * 2.0;\n                    \/\/ Corona falloff around event horizon\n                    float border = 0.45;\n                    float glow = exp(-pow((dist - border) * 4.5, 2.0));\n\n                    \/\/ Darken the center where the event horizon is\n                    float centerMask = smoothstep(border - 0.08, border + 0.02, dist);\n\n                    gl_FragColor = vec4(uColor * glow * 1.6, glow * centerMask * 0.85);\n                }\n            `,\n            transparent: true,\n            blending: THREE.AdditiveBlending,\n            depthWrite: false,\n        });\n        const glowMesh = new THREE.Mesh(glowGeometry, glowMaterial);\n        scene.add(glowMesh);\n\n        \/\/ 6. Horizontal Accretion Disk (Smooth, Concentric Vector Ribbons)\n        const diskLinesList: {\n            mesh: THREE.Mesh;\n            speed: number;\n            baseRotationY: number;\n        }[] = [];\n        const diskGroup = new THREE.Group();\n\n        for (let i = 0; i < ringDensity; i++) {\n            const t = i \/ (ringDensity - 1);\n            const r =\n                diskRadiusInner +\n                Math.pow(t, 1.8) * (diskRadiusOuter - diskRadiusInner);\n            const segments = 120;\n\n            const vertices: number[] = [];\n            const indices: number[] = [];\n\n            \/\/ Add wave fluctuations along the ring path\n            const waveFreq = 2 + Math.floor(Math.random() * 4);\n            const waveAmp = 0.03 + Math.random() * 0.06 * (r \/ diskRadiusOuter);\n            const wavePhase = Math.random() * Math.PI * 2;\n\n            for (let j = 0; j <= segments; j++) {\n                const theta = (j \/ segments) * Math.PI * 2;\n                const wave = Math.sin(theta * waveFreq + wavePhase) * waveAmp;\n                const currR = r + wave;\n\n                const rInner = currR - lineWidth \/ 2;\n                const rOuter = currR + lineWidth \/ 2;\n\n                const cos = Math.cos(theta);\n                const sin = Math.sin(theta);\n\n                \/\/ Inner vertex\n                vertices.push(rInner * cos, 0, rInner * sin);\n                \/\/ Outer vertex\n                vertices.push(rOuter * cos, 0, rOuter * sin);\n            }\n\n            for (let j = 0; j < segments; j++) {\n                const i0 = j * 2;\n                const i1 = j * 2 + 1;\n                const i2 = (j + 1) * 2;\n                const i3 = (j + 1) * 2 + 1;\n\n                indices.push(i0, i1, i2);\n                indices.push(i1, i3, i2);\n            }\n\n            const ribbonGeometry = new THREE.BufferGeometry();\n            ribbonGeometry.setAttribute(\n                'position',\n                new THREE.Float32BufferAttribute(vertices, 3),\n            );\n            ribbonGeometry.setIndex(indices);\n\n            const lineColor = getPaletteColor(t);\n\n            const ribbonMaterial = new THREE.MeshBasicMaterial({\n                color: lineColor,\n                transparent: true,\n                opacity: 0.15 + (1.0 - t) * 0.4,\n                blending: THREE.AdditiveBlending,\n                depthWrite: false,\n                side: THREE.DoubleSide,\n            });\n\n            const ribbon = new THREE.Mesh(ribbonGeometry, ribbonMaterial);\n            diskGroup.add(ribbon);\n\n            \/\/ Keplerian velocity: inner rings rotate faster than outer\n            const lineSpeed =\n                (0.2 + Math.random() * 0.2) * (0.05 \/ Math.sqrt(r));\n            diskLinesList.push({\n                mesh: ribbon,\n                speed: lineSpeed,\n                baseRotationY: Math.random() * Math.PI * 2,\n            });\n        }\n        scene.add(diskGroup);\n\n        \/\/ 7. Gravitational Lensing Halo (Camera-facing bent ring vector ribbons)\n        \/\/ Mimics the light warped over and under the event horizon\n        const haloLinesList: {\n            mesh: THREE.Mesh;\n            speed: number;\n            baseRotationZ: number;\n        }[] = [];\n        const haloGroup = new THREE.Group();\n        const haloDensity = Math.floor(ringDensity * 0.5);\n\n        for (let i = 0; i < haloDensity; i++) {\n            const t = i \/ (haloDensity - 1);\n            \/\/ Sits closely wrapping the event horizon\n            const r =\n                eventHorizonRadius * 1.05 +\n                Math.pow(t, 1.5) * (eventHorizonRadius * 0.8);\n            const segments = 90;\n\n            const vertices: number[] = [];\n            const indices: number[] = [];\n\n            const waveFreq = 2 + Math.floor(Math.random() * 3);\n            const waveAmp = 0.015 + Math.random() * 0.03;\n            const wavePhase = Math.random() * Math.PI * 2;\n\n            for (let j = 0; j <= segments; j++) {\n                const theta = (j \/ segments) * Math.PI * 2;\n                const wave = Math.sin(theta * waveFreq + wavePhase) * waveAmp;\n                const currR = r + wave;\n\n                const rInner = currR - lineWidth \/ 2;\n                const rOuter = currR + lineWidth \/ 2;\n\n                const cos = Math.cos(theta);\n                const sin = Math.sin(theta);\n\n                \/\/ Inner vertex\n                vertices.push(rInner * cos, rInner * sin, 0);\n                \/\/ Outer vertex\n                vertices.push(rOuter * cos, rOuter * sin, 0);\n            }\n\n            for (let j = 0; j < segments; j++) {\n                const i0 = j * 2;\n                const i1 = j * 2 + 1;\n                const i2 = (j + 1) * 2;\n                const i3 = (j + 1) * 2 + 1;\n\n                indices.push(i0, i1, i2);\n                indices.push(i1, i3, i2);\n            }\n\n            const ribbonGeometry = new THREE.BufferGeometry();\n            ribbonGeometry.setAttribute(\n                'position',\n                new THREE.Float32BufferAttribute(vertices, 3),\n            );\n            ribbonGeometry.setIndex(indices);\n\n            const lineColor = getPaletteColor(t * 0.7);\n\n            const ribbonMaterial = new THREE.MeshBasicMaterial({\n                color: lineColor,\n                transparent: true,\n                opacity: 0.25 + (1.0 - t) * 0.45,\n                blending: THREE.AdditiveBlending,\n                depthWrite: false,\n                side: THREE.DoubleSide,\n            });\n\n            const ribbon = new THREE.Mesh(ribbonGeometry, ribbonMaterial);\n            haloGroup.add(ribbon);\n\n            const lineSpeed =\n                (0.2 + Math.random() * 0.3) * (0.04 \/ Math.sqrt(r));\n            haloLinesList.push({\n                mesh: ribbon,\n                speed: lineSpeed,\n                baseRotationZ: Math.random() * Math.PI * 2,\n            });\n        }\n        scene.add(haloGroup);\n\n        \/\/ 8. Background Stars (Stable, anti-aliased Point cloud)\n        const starGeometry = new THREE.BufferGeometry();\n        const starsCount = 800;\n        const starPos = new Float32Array(starsCount * 3);\n        for (let i = 0; i < starsCount; i++) {\n            const r = 25.0 + Math.random() * 20.0;\n            const theta = Math.random() * Math.PI * 2;\n            const phi = Math.acos(2.0 * Math.random() - 1.0);\n\n            starPos[i * 3] = r * Math.sin(phi) * Math.cos(theta);\n            starPos[i * 3 + 1] = r * Math.sin(phi) * Math.sin(theta);\n            starPos[i * 3 + 2] = r * Math.cos(phi);\n        }\n        starGeometry.setAttribute(\n            'position',\n            new THREE.BufferAttribute(starPos, 3),\n        );\n        const starMaterial = new THREE.PointsMaterial({\n            color: 0xffffff,\n            size: 0.08,\n            transparent: true,\n            opacity: 0.75,\n            sizeAttenuation: true,\n        });\n        const starsPoints = new THREE.Points(starGeometry, starMaterial);\n        scene.add(starsPoints);\n\n        \/\/ 9. Animation Loop\n        const clock = new THREE.Clock();\n        let rafId: number;\n\n        const animate = () => {\n            const elapsedTime = clock.getElapsedTime();\n\n            \/\/ Rotate Accretion Disk (horizontal lines rotate around local Y)\n            diskLinesList.forEach((line) => {\n                line.mesh.rotation.y =\n                    line.baseRotationY + elapsedTime * line.speed * speed * 2.0;\n            });\n\n            \/\/ Rotate Lensing Halo (vertical lines rotate around local Z)\n            haloLinesList.forEach((line) => {\n                line.mesh.rotation.z =\n                    line.baseRotationZ + elapsedTime * line.speed * speed * 2.0;\n            });\n\n            \/\/ Keep Lensing Halo & Glow mesh facing the camera\n            haloGroup.lookAt(camera.position);\n            glowMesh.lookAt(camera.position);\n\n            \/\/ Handle Camera movement (controls or auto-rotation)\n            if (controls) {\n                controls.update();\n            } else if (autoRotate) {\n                const orbitRadius = Math.sqrt(\n                    cameraPosition.x * cameraPosition.x +\n                        cameraPosition.z * cameraPosition.z,\n                );\n                const baseAngle = Math.atan2(\n                    cameraPosition.z,\n                    cameraPosition.x,\n                );\n                const angle = baseAngle + elapsedTime * 0.04 * speed;\n\n                camera.position.x = Math.cos(angle) * orbitRadius;\n                camera.position.z = Math.sin(angle) * orbitRadius;\n                camera.lookAt(0, 0, 0);\n            }\n\n            renderer.render(scene, camera);\n            rafId = requestAnimationFrame(animate);\n        };\n\n        animate();\n        onReady?.();\n\n        \/\/ 10. Resize handler\n        const handleResize = () => {\n            if (!containerRef.current) return;\n            const w = containerRef.current.clientWidth;\n            const h = containerRef.current.clientHeight;\n            camera.aspect = w \/ h;\n            camera.updateProjectionMatrix();\n            renderer.setSize(w, h);\n        };\n        window.addEventListener('resize', handleResize);\n\n        \/\/ 11. Cleanup\n        return () => {\n            cancelAnimationFrame(rafId);\n            window.removeEventListener('resize', handleResize);\n\n            \/\/ Event Horizon cleanup\n            scene.remove(eventHorizon);\n            horizonGeometry.dispose();\n            horizonMaterial.dispose();\n\n            \/\/ Glow Corona cleanup\n            scene.remove(glowMesh);\n            glowGeometry.dispose();\n            glowMaterial.dispose();\n\n            \/\/ Accretion Disk cleanup\n            scene.remove(diskGroup);\n            diskLinesList.forEach((line) => {\n                line.mesh.geometry.dispose();\n                (line.mesh.material as THREE.Material).dispose();\n            });\n\n            \/\/ Halo cleanup\n            scene.remove(haloGroup);\n            haloLinesList.forEach((line) => {\n                line.mesh.geometry.dispose();\n                (line.mesh.material as THREE.Material).dispose();\n            });\n\n            \/\/ Stars cleanup\n            scene.remove(starsPoints);\n            starGeometry.dispose();\n            starMaterial.dispose();\n\n            if (controls) {\n                controls.dispose();\n            }\n\n            renderer.dispose();\n            if (el.contains(renderer.domElement)) {\n                el.removeChild(renderer.domElement);\n            }\n        };\n    }, [\n        size.width,\n        size.height,\n        eventHorizonRadius,\n        diskRadiusInner,\n        diskRadiusOuter,\n        ringDensity,\n        lineWidth,\n        colors,\n        glowColor,\n        speed,\n        enableOrbitControls,\n        autoRotate,\n        cameraPosition,\n        maxPixelRatio,\n        onReady,\n    ]);\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(\n                'relative h-full min-h-[300px] w-full overflow-hidden bg-black select-none',\n                className,\n            )}\n            aria-hidden=\"true\"\n        \/>\n    );\n}\n\nexport default BlackHole;\n"}],"meta":{"category":"canvas","version":"1.0.0"},"categories":["canvas"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"feedback-star","type":"registry:ui","title":"Feedback Star","description":"A dynamic reaction-diffusion WebGL noise star shader simulation utilizing a double buffered feedback loop.","author":"designbycode","dependencies":["three"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/threejs\/feedback-star.tsx","type":"registry:ui","content":"'use client';\n\nimport { useEffect, useRef, useState } from 'react';\nimport * as THREE from 'three';\nimport { OrbitControls } from 'three\/examples\/jsm\/controls\/OrbitControls.js';\nimport { cn } from '@\/lib\/utils';\n\nexport interface FeedbackStarProps {\n    className?: string;\n\n    \/**\n     * Geometry shape to render in the scene.\n     * Default: 'torus-knot'\n     *\/\n    geometryType?: 'torus-knot' | 'sphere' | 'icosahedron' | 'torus';\n\n    \/**\n     * Color of the 3D mesh object.\n     * Default: '#ffffff'\n     *\/\n    meshColor?: string;\n\n    \/**\n     * Speed multiplier for the glitch animation.\n     * Default: 1.0\n     *\/\n    speed?: number;\n\n    \/**\n     * Enable interactive camera OrbitControls.\n     * Default: true\n     *\/\n    enableOrbitControls?: boolean;\n}\n\nexport function FeedbackStar({\n    className,\n    geometryType = 'torus-knot',\n    meshColor = '#ffffff',\n    speed = 1.0,\n    enableOrbitControls = true,\n}: FeedbackStarProps) {\n    const containerRef = useRef<HTMLDivElement>(null);\n    const [size, setSize] = useState({ width: 0, height: 0 });\n\n    useEffect(() => {\n        if (!containerRef.current) return;\n\n        const updateSize = () => {\n            if (containerRef.current) {\n                setSize({\n                    width: containerRef.current.clientWidth,\n                    height: containerRef.current.clientHeight,\n                });\n            }\n        };\n\n        updateSize();\n\n        const observer = new ResizeObserver(updateSize);\n        observer.observe(containerRef.current);\n\n        return () => {\n            observer.disconnect();\n        };\n    }, []);\n\n    useEffect(() => {\n        if (size.width === 0 || size.height === 0 || !containerRef.current)\n            return;\n\n        const el = containerRef.current;\n        const width = size.width;\n        const height = size.height;\n\n        \/\/ 1. Renderer Setup\n        const renderer = new THREE.WebGLRenderer({\n            antialias: true,\n            alpha: false,\n        });\n        const pixelRatio = Math.min(window.devicePixelRatio, 2);\n        renderer.setPixelRatio(pixelRatio);\n        renderer.setSize(width, height);\n        renderer.setClearColor(0x000000, 1.0);\n        el.appendChild(renderer.domElement);\n\n        \/\/ 2. Render Target for Post-Processing\n        const rtWidth = Math.floor(width * pixelRatio);\n        const rtHeight = Math.floor(height * pixelRatio);\n\n        const renderTarget = new THREE.WebGLRenderTarget(rtWidth, rtHeight, {\n            minFilter: THREE.LinearFilter,\n            magFilter: THREE.LinearFilter,\n            format: THREE.RGBAFormat,\n        });\n\n        \/\/ 3. 3D Scene (Gets rendered to texture)\n        const scene3d = new THREE.Scene();\n        const camera3d = new THREE.PerspectiveCamera(\n            45,\n            width \/ height,\n            0.1,\n            1000,\n        );\n        camera3d.position.z = 30;\n\n        \/\/ Add Lights\n        scene3d.add(new THREE.AmbientLight(0x222222));\n        const dirLight = new THREE.DirectionalLight(0xffffff, 1.5);\n        dirLight.position.set(1, 1, 1);\n        scene3d.add(dirLight);\n\n        \/\/ Add 3D Mesh\n        let geometry: THREE.BufferGeometry;\n        if (geometryType === 'sphere') {\n            geometry = new THREE.SphereGeometry(8, 64, 64);\n        } else if (geometryType === 'icosahedron') {\n            geometry = new THREE.IcosahedronGeometry(8, 0);\n        } else if (geometryType === 'torus') {\n            geometry = new THREE.TorusGeometry(8, 3, 32, 100);\n        } else {\n            geometry = new THREE.TorusKnotGeometry(5.5, 1.8, 256, 32);\n        }\n\n        const meshMaterial = new THREE.MeshPhongMaterial({\n            color: new THREE.Color(meshColor),\n            shininess: 60,\n        });\n\n        const mesh = new THREE.Mesh(geometry, meshMaterial);\n        scene3d.add(mesh);\n\n        \/\/ 4. Post-processing Screen Scene & Camera\n        const sceneScreen = new THREE.Scene();\n        const cameraScreen = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n        const screenGeometry = new THREE.PlaneGeometry(2, 2);\n\n        \/\/ 5. Orbit Controls for 3D camera\n        let controls: OrbitControls | null = null;\n        if (enableOrbitControls) {\n            controls = new OrbitControls(camera3d, renderer.domElement);\n            controls.enableDamping = true;\n            controls.dampingFactor = 0.05;\n            controls.enablePan = false;\n        }\n\n        \/\/ 6. Shader Uniforms\n        const uniforms = {\n            u_time: { value: 0.0 },\n            u_frame: { value: 0.0 },\n            u_resolution: { value: new THREE.Vector2(rtWidth, rtHeight) },\n            u_mouse: {\n                value: new THREE.Vector2(rtWidth * 0.5, rtHeight * 0.5),\n            },\n            u_texture: { value: renderTarget.texture as any },\n        };\n\n        \/\/ 7. Shaders Code\n        const vertexShader = `\n            varying vec2 v_uv;\n            void main() {\n                v_uv = uv;\n                gl_Position = vec4(position, 1.0);\n            }\n        `;\n\n        const fragmentShader = `\n            uniform vec2 u_resolution;\n            uniform vec2 u_mouse;\n            uniform float u_time;\n            uniform float u_frame;\n            uniform sampler2D u_texture;\n            varying vec2 v_uv;\n\n            highp float random1d(float dt) {\n                highp float c = 43758.5453;\n                highp float sn = mod(dt, 3.14);\n                return fract(sin(sn) * c);\n            }\n\n            highp float noise1d(float value) {\n                highp float i = floor(value);\n                highp float f = fract(value);\n                return mix(random1d(i), random1d(i + 1.0), smoothstep(0.0, 1.0, f));\n            }\n\n            highp float random2d(vec2 co) {\n                highp float a = 12.9898;\n                highp float b = 78.233;\n                highp float c = 43758.5453;\n                highp float dt = dot(co.xy, vec2(a, b));\n                highp float sn = mod(dt, 3.14);\n                return fract(sin(sn) * c);\n            }\n\n            void main() {\n                \/\/ Calculate the effect relative strength\n                float strength = (0.3 + 0.7 * noise1d(0.3 * u_time)) * u_mouse.x \/ u_resolution.x;\n\n                \/\/ Calculate the effect jump at the current time interval\n                float jump = 500.0 * floor(0.3 * (u_mouse.x \/ u_resolution.x) * (u_time + noise1d(u_time)));\n\n                \/\/ Shift the texture coordinates\n                vec2 uv = v_uv;\n                uv.y += 0.2 * strength * (noise1d(5.0 * v_uv.y + 2.0 * u_time + jump) - 0.5);\n                uv.x += 0.1 * strength * (noise1d(100.0 * strength * uv.y + 3.0 * u_time + jump) - 0.5);\n\n                \/\/ Get the texture pixel color\n                vec3 pixel_color = texture2D(u_texture, uv).rgb;\n\n                \/\/ Add some white noise\n                pixel_color += vec3(5.0 * strength * (random2d(v_uv + 1.133001 * vec2(u_time, 1.13)) - 0.5));\n\n                gl_FragColor = vec4(pixel_color, 1.0);\n            }\n        `;\n\n        const materialShader = new THREE.ShaderMaterial({\n            uniforms,\n            vertexShader,\n            fragmentShader,\n            depthWrite: false,\n            depthTest: false,\n        });\n\n        const screenMesh = new THREE.Mesh(screenGeometry, materialShader);\n        sceneScreen.add(screenMesh);\n\n        \/\/ 8. Render loop\n        const clock = new THREE.Clock();\n        let animationFrameId: number;\n\n        const animate = () => {\n            const time = clock.getElapsedTime() * speed;\n            uniforms.u_time.value = time;\n            uniforms.u_frame.value += 1.0;\n\n            \/\/ Animate object slightly\n            mesh.rotation.y += 0.005;\n            mesh.rotation.x += 0.003;\n\n            if (controls) {\n                controls.update();\n            }\n\n            \/\/ Render 3D Scene into RenderTarget texture\n            renderer.setRenderTarget(renderTarget);\n            renderer.render(scene3d, camera3d);\n\n            \/\/ Render screen-space Quad applying glitch shader\n            renderer.setRenderTarget(null);\n            renderer.render(sceneScreen, cameraScreen);\n\n            animationFrameId = requestAnimationFrame(animate);\n        };\n\n        animate();\n\n        \/\/ 9. Event Listeners\n        const handleMouseMove = (e: MouseEvent) => {\n            const rect = el.getBoundingClientRect();\n            const x = (e.clientX - rect.left) * pixelRatio;\n            const y = (rect.bottom - e.clientY) * pixelRatio;\n            uniforms.u_mouse.value.set(x, y);\n        };\n\n        const handleTouchMove = (e: TouchEvent) => {\n            if (e.touches.length === 0) return;\n            const rect = el.getBoundingClientRect();\n            const x = (e.touches[0].clientX - rect.left) * pixelRatio;\n            const y = (rect.bottom - e.touches[0].clientY) * pixelRatio;\n            uniforms.u_mouse.value.set(x, y);\n        };\n\n        el.addEventListener('mousemove', handleMouseMove);\n        el.addEventListener('touchmove', handleTouchMove, { passive: true });\n\n        \/\/ 10. Cleanups\n        return () => {\n            cancelAnimationFrame(animationFrameId);\n            el.removeEventListener('mousemove', handleMouseMove);\n            el.removeEventListener('touchmove', handleTouchMove);\n\n            geometry.dispose();\n            meshMaterial.dispose();\n            screenGeometry.dispose();\n            materialShader.dispose();\n            renderTarget.dispose();\n\n            if (controls) {\n                controls.dispose();\n            }\n\n            renderer.dispose();\n            if (el.contains(renderer.domElement)) {\n                el.removeChild(renderer.domElement);\n            }\n        };\n    }, [\n        size.width,\n        size.height,\n        geometryType,\n        meshColor,\n        speed,\n        enableOrbitControls,\n    ]);\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(\n                'relative h-full min-h-[350px] w-full overflow-hidden select-none',\n                className,\n            )}\n            aria-hidden=\"true\"\n        \/>\n    );\n}\n\nexport default FeedbackStar;\n"}],"meta":{"category":"canvas","version":"1.0.0"},"categories":["canvas"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"waves-three","type":"registry:ui","title":"Waves Three","description":"A responsive WebGL 3D waves animation powered by Three.js.","author":"designbycode","dependencies":["three"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/threejs\/waves-three.tsx","type":"registry:ui","content":"\/* eslint-disable *\/\n`use client`;\n\nimport { useEffect, useRef, useState } from 'react';\nimport * as THREE from 'three';\nimport { cn } from '@\/lib\/utils';\n\n\/\/ ---------------------------------------------------------------------------\n\/\/ Types\n\/\/ ---------------------------------------------------------------------------\n\nexport type WaveStyle =\n    | 'wireframe' \/\/ triangulated mesh (has diagonals \u2014 legacy)\n    | 'grid' \/\/ axis-aligned squares, no diagonals\n    | 'dots' \/\/ round filled circles at every vertex (shader-based)\n    | 'dots-wave' \/\/ round dots that scale in size with Z height\n    | 'crosses' \/\/ small + at every vertex\n    | 'diagonal-left' \/\/ parallel lines leaning left  (\\\\\\)\n    | 'diagonal-right' \/\/ parallel lines leaning right (\/\/\/)\n    | 'zigzag' \/\/ alternating chevron rows\n    | 'hexagons' \/\/ hexagonal cell grid\n    | 'dashes' \/\/ dashed horizontal + vertical lines (gaps between cells)\n    | 'contour' \/\/ topographic iso-lines drawn at fixed Z thresholds\n    | 'solid'; \/\/ shaded solid surface with lighting\n\nexport interface WavesThreeProps {\n    className?: string;\n\n    \/**\n     * Visual style of the wave. See WaveStyle for all options.\n     * Default: 'grid'\n     *\/\n    style?: WaveStyle;\n\n    \/**\n     * Which lines to draw \u2014 applies to 'grid' and 'dashes' styles.\n     *  - 'both'       \u2014 horizontal + vertical (default)\n     *  - 'horizontal' \u2014 only lines running left\u2192right\n     *  - 'vertical'   \u2014 only lines running top\u2192bottom\n     *\/\n    lines?: 'both' | 'horizontal' | 'vertical';\n\n    \/**\n     * CSS\/hex color strings blended left\u2192right across the mesh.\n     * Minimum 2. Auto-detects dark\/light mode if omitted.\n     *\/\n    colors?: string[];\n\n    \/** Camera XYZ position. Default: { x:0, y:0, z:10 } *\/\n    cameraPosition?: { x: number; y: number; z: number };\n\n    \/** Plane width in world units. Default: 80 *\/\n    planeWidth?: number;\n    \/** Plane height in world units. Default: 40 *\/\n    planeHeight?: number;\n\n    \/** Grid columns \u2014 higher = denser. Default: 60 *\/\n    segmentsX?: number;\n    \/** Grid rows. Default: 30 *\/\n    segmentsY?: number;\n\n    \/** Animation speed multiplier. Default: 1 *\/\n    speed?: number;\n    \/** Wave peak height. Default: 1.5 *\/\n    amplitude?: number;\n    \/** Wave spatial density \u2014 lower = wider. Default: 0.3 *\/\n    frequency?: number;\n    \/** Global opacity 0\u20131. Default: 0.6 *\/\n    opacity?: number;\n    \/** Pause animation. Default: false *\/\n    paused?: boolean;\n\n    \/** Mouse influence on wave phase. Default: 2 *\/\n    mouseInfluence?: number;\n    \/** Mouse influence on mesh tilt. Default: 0.1 *\/\n    mouseRotation?: number;\n\n    \/**\n     * Dot radius in screen pixels \u2014 'dots' and 'dots-wave' styles.\n     * Dots are perfectly round via a GLSL discard shader. Default: 3\n     *\/\n    dotSize?: number;\n\n    \/**\n     * For 'dots-wave': minimum dot size at wave valleys. Default: 1\n     *\/\n    dotSizeMin?: number;\n\n    \/** Cross arm half-length in world units \u2014 'crosses' style. Default: 0.3 *\/\n    crossSize?: number;\n\n    \/**\n     * Dash fill ratio 0\u20131 \u2014 'dashes' style.\n     * 0.5 = half line, half gap. Default: 0.5\n     *\/\n    dashRatio?: number;\n\n    \/**\n     * Number of contour threshold levels \u2014 'contour' style. Default: 6\n     *\/\n    contourLevels?: number;\n\n    \/** High-DPI pixel ratio cap. Default: 2 *\/\n    maxPixelRatio?: number;\n\n    \/** Called once the renderer and first frame are ready *\/\n    onReady?: () => void;\n}\n\n\/\/ ---------------------------------------------------------------------------\n\/\/ Constants\n\/\/ ---------------------------------------------------------------------------\n\nconst DEFAULT_LIGHT: string[] = ['#525252', '#525252'];\nconst DEFAULT_DARK: string[] = ['#444444', '#757575'];\n\n\/\/ ---------------------------------------------------------------------------\n\/\/ Color helpers\n\/\/ ---------------------------------------------------------------------------\n\nfunction lerpPalette(t: number, stops: THREE.Color[]): THREE.Color {\n    const scaled = Math.max(0, Math.min(1, t)) * (stops.length - 1);\n    const lo = Math.floor(scaled);\n    const hi = Math.min(lo + 1, stops.length - 1);\n\n    return stops[lo].clone().lerp(stops[hi], scaled - lo);\n}\n\nfunction makeColorBuffer(count: number, stops: THREE.Color[]): Float32Array {\n    const buf = new Float32Array(count * 3);\n\n    for (let i = 0; i < count; i++) {\n        const c = lerpPalette(i \/ Math.max(count - 1, 1), stops);\n        buf[i * 3] = c.r;\n        buf[i * 3 + 1] = c.g;\n        buf[i * 3 + 2] = c.b;\n    }\n\n    return buf;\n}\n\n\/\/ ---------------------------------------------------------------------------\n\/\/ Shared vertex-grid builder\n\/\/ Returns a flat XY grid of (cols+1)\u00d7(rows+1) vertices, Z=0.\n\/\/ ---------------------------------------------------------------------------\n\nfunction makeVertexGrid(\n    cols: number,\n    rows: number,\n    w: number,\n    h: number,\n): Float32Array {\n    const cx = cols + 1;\n    const ry = rows + 1;\n    const pos = new Float32Array(cx * ry * 3);\n    const sx = w \/ cols;\n    const sy = h \/ rows;\n\n    for (let r = 0; r < ry; r++) {\n        for (let c = 0; c < cx; c++) {\n            const i = (r * cx + c) * 3;\n            pos[i] = -w \/ 2 + c * sx;\n            pos[i + 1] = -h \/ 2 + r * sy;\n            pos[i + 2] = 0;\n        }\n    }\n\n    return pos;\n}\n\n\/\/ ---------------------------------------------------------------------------\n\/\/ Wave Z calculator \u2014 used in every style's animation loop\n\/\/ ---------------------------------------------------------------------------\n\nfunction calcZ(\n    x: number,\n    y: number,\n    time: number,\n    freq: number,\n    amp: number,\n    mx: number,\n    my: number,\n    mi: number,\n): number {\n    return (\n        Math.sin(x * freq + time * 2 + mx * mi) * amp +\n        Math.cos(y * freq + time * 1.5 + my * mi)\n    );\n}\n\n\/\/ ---------------------------------------------------------------------------\n\/\/ Geometry builders\n\/\/ ---------------------------------------------------------------------------\n\n\/\/ GRID \u2014 axis-aligned lines only, no diagonals\nfunction buildGrid(\n    cols: number,\n    rows: number,\n    w: number,\n    h: number,\n    stops: THREE.Color[],\n    lines: 'both' | 'horizontal' | 'vertical',\n): { geo: THREE.BufferGeometry; pos: Float32Array } {\n    const cx = cols + 1;\n    const ry = rows + 1;\n    const total = cx * ry;\n    const pos = makeVertexGrid(cols, rows, w, h);\n\n    const hSegs = lines !== 'vertical' ? ry * cols : 0;\n    const vSegs = lines !== 'horizontal' ? cx * rows : 0;\n    const idx = new Uint32Array((hSegs + vSegs) * 2);\n    let ptr = 0;\n\n    if (lines !== 'vertical') {\n        for (let r = 0; r < ry; r++) {\n            for (let c = 0; c < cols; c++) {\n                idx[ptr++] = r * cx + c;\n                idx[ptr++] = r * cx + c + 1;\n            }\n        }\n    }\n\n    if (lines !== 'horizontal') {\n        for (let c = 0; c < cx; c++) {\n            for (let r = 0; r < rows; r++) {\n                idx[ptr++] = r * cx + c;\n                idx[ptr++] = (r + 1) * cx + c;\n            }\n        }\n    }\n\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));\n    geo.setAttribute(\n        'color',\n        new THREE.BufferAttribute(makeColorBuffer(total, stops), 3),\n    );\n    geo.setIndex(new THREE.BufferAttribute(idx, 1));\n\n    return { geo, pos };\n}\n\n\/\/ DOTS \u2014 round circles via ShaderMaterial + gl_PointCoord discard\nfunction buildDots(\n    cols: number,\n    rows: number,\n    w: number,\n    h: number,\n    stops: THREE.Color[],\n): { geo: THREE.BufferGeometry; pos: Float32Array } {\n    const total = (cols + 1) * (rows + 1);\n    const pos = makeVertexGrid(cols, rows, w, h);\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));\n    geo.setAttribute(\n        'color',\n        new THREE.BufferAttribute(makeColorBuffer(total, stops), 3),\n    );\n\n    return { geo, pos };\n}\n\n\/\/ Round-dot ShaderMaterial \u2014 discards fragments outside the circle\nfunction makeRoundDotMaterial(\n    size: number,\n    opacity: number,\n): THREE.ShaderMaterial {\n    return new THREE.ShaderMaterial({\n        uniforms: {\n            uSize: { value: size },\n            uOpacity: { value: opacity },\n        },\n        vertexShader: \/* glsl *\/ `\n            attribute vec3 color;\n            varying   vec3 vColor;\n            uniform   float uSize;\n            void main() {\n                vColor = color;\n                vec4 mvPos = modelViewMatrix * vec4(position, 1.0);\n                gl_PointSize = uSize;\n                gl_Position  = projectionMatrix * mvPos;\n            }\n        `,\n        fragmentShader: \/* glsl *\/ `\n            varying vec3  vColor;\n            uniform float uOpacity;\n            void main() {\n                \/\/ gl_PointCoord is 0..1 across the point sprite\n                vec2  uv   = gl_PointCoord - vec2(0.5);\n                float dist = length(uv);\n                if (dist > 0.5) discard;          \/\/ outside circle \u2192 transparent\n                \/\/ soft anti-alias ring at the edge\n                float alpha = 1.0 - smoothstep(0.45, 0.5, dist);\n                gl_FragColor = vec4(vColor, alpha * uOpacity);\n            }\n        `,\n        transparent: true,\n        depthWrite: false,\n    });\n}\n\n\/\/ DOTS-WAVE \u2014 same as dots but size is modulated by Z in the vertex shader\nfunction makeRoundDotWaveMaterial(\n    sizeMin: number,\n    sizeMax: number,\n    amplitude: number,\n    opacity: number,\n): THREE.ShaderMaterial {\n    return new THREE.ShaderMaterial({\n        uniforms: {\n            uSizeMin: { value: sizeMin },\n            uSizeMax: { value: sizeMax },\n            uAmp: { value: amplitude },\n            uOpacity: { value: opacity },\n        },\n        vertexShader: \/* glsl *\/ `\n            attribute vec3  color;\n            varying   vec3  vColor;\n            uniform   float uSizeMin;\n            uniform   float uSizeMax;\n            uniform   float uAmp;\n            void main() {\n                vColor = color;\n                \/\/ Map Z (-amp..+amp) \u2192 (sizeMin..sizeMax)\n                float t       = clamp((position.z + uAmp) \/ (2.0 * uAmp), 0.0, 1.0);\n                gl_PointSize  = mix(uSizeMin, uSizeMax, t);\n                gl_Position   = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n            }\n        `,\n        fragmentShader: \/* glsl *\/ `\n            varying vec3  vColor;\n            uniform float uOpacity;\n            void main() {\n                vec2  uv   = gl_PointCoord - vec2(0.5);\n                float dist = length(uv);\n                if (dist > 0.5) discard;\n                float alpha = 1.0 - smoothstep(0.45, 0.5, dist);\n                gl_FragColor = vec4(vColor, alpha * uOpacity);\n            }\n        `,\n        transparent: true,\n        depthWrite: false,\n    });\n}\n\n\/\/ CROSSES\nfunction buildCrosses(\n    cols: number,\n    rows: number,\n    w: number,\n    h: number,\n    stops: THREE.Color[],\n    armLen: number,\n): { geo: THREE.BufferGeometry; centers: Float32Array; pos: Float32Array } {\n    const cx = cols + 1;\n    const ry = rows + 1;\n    const total = cx * ry;\n    const half = armLen \/ 2;\n    const sx = w \/ cols;\n    const sy = h \/ rows;\n\n    const centers = new Float32Array(total * 3);\n    const pos = new Float32Array(total * 4 * 3);\n    const col = new Float32Array(total * 4 * 3);\n\n    for (let r = 0; r < ry; r++) {\n        for (let c = 0; c < cx; c++) {\n            const vi = r * cx + c;\n            const bx = -w \/ 2 + c * sx;\n            const by = -h \/ 2 + r * sy;\n            centers[vi * 3] = bx;\n            centers[vi * 3 + 1] = by;\n            centers[vi * 3 + 2] = 0;\n            const b = vi * 12;\n            pos[b] = bx - half;\n            pos[b + 1] = by;\n            pos[b + 2] = 0;\n            pos[b + 3] = bx + half;\n            pos[b + 4] = by;\n            pos[b + 5] = 0;\n            pos[b + 6] = bx;\n            pos[b + 7] = by - half;\n            pos[b + 8] = 0;\n            pos[b + 9] = bx;\n            pos[b + 10] = by + half;\n            pos[b + 11] = 0;\n            const clr = lerpPalette(vi \/ Math.max(total - 1, 1), stops);\n\n            for (let p = 0; p < 4; p++) {\n                col[b + p * 3] = clr.r;\n                col[b + p * 3 + 1] = clr.g;\n                col[b + p * 3 + 2] = clr.b;\n            }\n        }\n    }\n\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));\n    geo.setAttribute('color', new THREE.BufferAttribute(col, 3));\n\n    return { geo, centers, pos };\n}\n\n\/\/ DIAGONAL-LEFT (\\\\\\) or DIAGONAL-RIGHT (\/\/\/)\nfunction buildDiagonal(\n    cols: number,\n    rows: number,\n    w: number,\n    h: number,\n    stops: THREE.Color[],\n    dir: 'left' | 'right',\n): { geo: THREE.BufferGeometry; pos: Float32Array } {\n    const cx = cols + 1;\n    const ry = rows + 1;\n    const pos = makeVertexGrid(cols, rows, w, h);\n\n    \/\/ Each diagonal goes from (r,c) \u2192 (r+1,c+1) for right, (r,c+1) \u2192 (r+1,c) for left\n    const idx = new Uint32Array(cols * rows * 2);\n    let ptr = 0;\n\n    for (let r = 0; r < rows; r++) {\n        for (let c = 0; c < cols; c++) {\n            if (dir === 'right') {\n                idx[ptr++] = r * cx + c;\n                idx[ptr++] = (r + 1) * cx + c + 1;\n            } else {\n                idx[ptr++] = r * cx + c + 1;\n                idx[ptr++] = (r + 1) * cx + c;\n            }\n        }\n    }\n\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));\n    geo.setAttribute(\n        'color',\n        new THREE.BufferAttribute(makeColorBuffer(cx * ry, stops), 3),\n    );\n    geo.setIndex(new THREE.BufferAttribute(idx, 1));\n\n    return { geo, pos };\n}\n\n\/\/ ZIGZAG \u2014 alternating row direction creates chevrons\nfunction buildZigzag(\n    cols: number,\n    rows: number,\n    w: number,\n    h: number,\n    stops: THREE.Color[],\n): { geo: THREE.BufferGeometry; pos: Float32Array } {\n    const cx = cols + 1;\n    const ry = rows + 1;\n    const pos = makeVertexGrid(cols, rows, w, h);\n\n    \/\/ Per row: connect across the row as a zigzag (top vertices to bottom vertices alternating)\n    const segCount = rows * cols * 2; \/\/ 2 segments per cell (v-shape)\n    const idx = new Uint32Array(segCount * 2);\n    let ptr = 0;\n\n    for (let r = 0; r < rows; r++) {\n        for (let c = 0; c < cols; c++) {\n            const even = r % 2 === 0;\n\n            \/\/ Each cell: draw one diagonal and horizontal to form chevron\n            if (even) {\n                idx[ptr++] = r * cx + c;\n                idx[ptr++] = (r + 1) * cx + c + 1;\n                idx[ptr++] = r * cx + c + 1;\n                idx[ptr++] = (r + 1) * cx + c + 1;\n            } else {\n                idx[ptr++] = r * cx + c + 1;\n                idx[ptr++] = (r + 1) * cx + c;\n                idx[ptr++] = r * cx + c;\n                idx[ptr++] = (r + 1) * cx + c;\n            }\n        }\n    }\n\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));\n    geo.setAttribute(\n        'color',\n        new THREE.BufferAttribute(makeColorBuffer(cx * ry, stops), 3),\n    );\n    geo.setIndex(new THREE.BufferAttribute(idx, 1));\n\n    return { geo, pos };\n}\n\n\/\/ HEXAGONS \u2014 flat-top hexagonal cells\nfunction buildHexagons(\n    cols: number,\n    rows: number,\n    w: number,\n    h: number,\n    stops: THREE.Color[],\n): { geo: THREE.BufferGeometry; pos: Float32Array; hexCenters: Float32Array } {\n    \/\/ Each hexagon = 6 line segments = 12 endpoints (no shared verts \u2192 clean vertex colors)\n    const hexCols = cols;\n    const hexRows = rows;\n    const hexCount = hexCols * hexRows;\n    const hexR = w \/ hexCols \/ 2; \/\/ circumradius\n    const hexH = hexR * Math.sqrt(3); \/\/ flat-top hex height\n\n    const pos = new Float32Array(hexCount * 12 * 3); \/\/ 6 edges \u00d7 2 pts \u00d7 3 floats\n    const col = new Float32Array(hexCount * 12 * 3);\n    const centers = new Float32Array(hexCount * 3);\n\n    let hi = 0; \/\/ hex index\n\n    for (let row = 0; row < hexRows; row++) {\n        for (let col2 = 0; col2 < hexCols; col2++) {\n            const offset = col2 % 2 === 0 ? 0 : hexH * 0.5;\n            const cx2 = -w \/ 2 + hexR + col2 * hexR * 1.5;\n            const cy2 = -h \/ 2 + hexH * 0.5 + row * hexH + offset;\n\n            centers[hi * 3] = cx2;\n            centers[hi * 3 + 1] = cy2;\n            centers[hi * 3 + 2] = 0;\n\n            const t = hi \/ Math.max(hexCount - 1, 1);\n            const clr = lerpPalette(t, stops);\n\n            \/\/ 6 vertices of flat-top hexagon\n            const verts: [number, number][] = [];\n\n            for (let k = 0; k < 6; k++) {\n                const angle = (Math.PI \/ 3) * k; \/\/ 0\u00b0,60\u00b0,120\u00b0\u2026\n                verts.push([\n                    cx2 + hexR * Math.cos(angle),\n                    cy2 + hexR * Math.sin(angle),\n                ]);\n            }\n\n            \/\/ 6 edges \u2014 each as a line segment pair\n            for (let k = 0; k < 6; k++) {\n                const a = verts[k];\n                const b = verts[(k + 1) % 6];\n                const base = (hi * 6 + k) * 6; \/\/ 2 pts \u00d7 3 floats per edge\n                pos[base] = a[0];\n                pos[base + 1] = a[1];\n                pos[base + 2] = 0;\n                pos[base + 3] = b[0];\n                pos[base + 4] = b[1];\n                pos[base + 5] = 0;\n\n                for (let p = 0; p < 2; p++) {\n                    col[base + p * 3] = clr.r;\n                    col[base + p * 3 + 1] = clr.g;\n                    col[base + p * 3 + 2] = clr.b;\n                }\n            }\n\n            hi++;\n        }\n    }\n\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute(\n        'position',\n        new THREE.BufferAttribute(pos.slice(0, hi * 6 * 6), 3),\n    );\n    geo.setAttribute(\n        'color',\n        new THREE.BufferAttribute(col.slice(0, hi * 6 * 6), 3),\n    );\n\n    return { geo, pos, hexCenters: centers.slice(0, hi * 3) };\n}\n\n\/\/ DASHES \u2014 like grid but with a gap in the middle of each segment\nfunction buildDashes(\n    cols: number,\n    rows: number,\n    w: number,\n    h: number,\n    stops: THREE.Color[],\n    lines: 'both' | 'horizontal' | 'vertical',\n    dashRatio: number,\n): { geo: THREE.BufferGeometry; pos: Float32Array; basePos: Float32Array } {\n    const cx = cols + 1;\n    const ry = rows + 1;\n    const sx = w \/ cols;\n    const sy = h \/ rows;\n    const half = dashRatio \/ 2;\n\n    \/\/ Each dash = 2 endpoints, no shared verts\n    const hCount = lines !== 'vertical' ? ry * cols : 0;\n    const vCount = lines !== 'horizontal' ? cx * rows : 0;\n    const total = (hCount + vCount) * 2;\n\n    const pos = new Float32Array(total * 3);\n    const basePos = new Float32Array(total * 3); \/\/ stored XY, updated Z each frame\n    const col = new Float32Array(total * 3);\n\n    let p = 0;\n\n    const push = (\n        x1: number,\n        y1: number,\n        x2: number,\n        y2: number,\n        ci: number,\n    ) => {\n        const clr = ci \/ Math.max(cx * ry - 1, 1);\n        const c = lerpPalette(clr, stops);\n\n        for (let k = 0; k < 2; k++) {\n            const [px2, py] = k === 0 ? [x1, y1] : [x2, y2];\n            pos[p * 3] = px2;\n            pos[p * 3 + 1] = py;\n            pos[p * 3 + 2] = 0;\n            basePos[p * 3] = px2;\n            basePos[p * 3 + 1] = py;\n            basePos[p * 3 + 2] = 0;\n            col[p * 3] = c.r;\n            col[p * 3 + 1] = c.g;\n            col[p * 3 + 2] = c.b;\n            p++;\n        }\n    };\n\n    if (lines !== 'vertical') {\n        for (let r = 0; r < ry; r++) {\n            for (let c2 = 0; c2 < cols; c2++) {\n                const x1 = -w \/ 2 + c2 * sx;\n                const x2 = x1 + sx;\n                const y = -h \/ 2 + r * sy;\n                push(x1 + sx * half, y, x2 - sx * half, y, r * cx + c2);\n            }\n        }\n    }\n\n    if (lines !== 'horizontal') {\n        for (let c2 = 0; c2 < cx; c2++) {\n            for (let r = 0; r < rows; r++) {\n                const y1 = -h \/ 2 + r * sy;\n                const y2 = y1 + sy;\n                const x = -w \/ 2 + c2 * sx;\n                push(x, y1 + sy * half, x, y2 - sy * half, r * cx + c2);\n            }\n        }\n    }\n\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));\n    geo.setAttribute('color', new THREE.BufferAttribute(col, 3));\n\n    return { geo, pos, basePos };\n}\n\n\/\/ CONTOUR \u2014 draws horizontal lines only at fixed Z thresholds (resampled each frame)\n\/\/ We build a flat placeholder geo; indices are rebuilt each frame as Z changes.\n\/\/ For performance we use a fixed vertex pool and swap positions.\nfunction buildContourPlaceholder(\n    cols: number,\n    rows: number,\n    w: number,\n    h: number,\n    _stops: THREE.Color[],\n    _levels: number,\n): { geo: THREE.BufferGeometry; vtxGrid: Float32Array } {\n    \/\/ Max line segments = rows * cols * 4 (at most 4 crossing per cell edge), generous upper bound\n    const maxSegs = cols * rows * 4 * 2;\n    const pos = new Float32Array(maxSegs * 3);\n    const col = new Float32Array(maxSegs * 3);\n    const geo = new THREE.BufferGeometry();\n    geo.setAttribute(\n        'position',\n        new THREE.BufferAttribute(pos, 3).setUsage(THREE.DynamicDrawUsage),\n    );\n    geo.setAttribute(\n        'color',\n        new THREE.BufferAttribute(col, 3).setUsage(THREE.DynamicDrawUsage),\n    );\n    geo.setDrawRange(0, 0);\n    const vtxGrid = makeVertexGrid(cols, rows, w, h);\n\n    return { geo, vtxGrid };\n}\n\n\/\/ SOLID \u2014 PlaneGeometry + MeshPhongMaterial with lighting\nfunction buildSolid(\n    cols: number,\n    rows: number,\n    w: number,\n    h: number,\n    stops: THREE.Color[],\n): { geo: THREE.PlaneGeometry; pos: Float32Array } {\n    const geo = new THREE.PlaneGeometry(w, h, cols, rows);\n    const count = geo.attributes.position.count;\n    geo.setAttribute(\n        'color',\n        new THREE.BufferAttribute(makeColorBuffer(count, stops), 3),\n    );\n    const pos = geo.attributes.position.array as Float32Array;\n\n    return { geo, pos };\n}\n\n\/\/ ---------------------------------------------------------------------------\n\/\/ Component\n\/\/ ---------------------------------------------------------------------------\n\nconst WavesThree = ({\n    className,\n    style = 'grid',\n    lines = 'both',\n    colors,\n    cameraPosition = { x: 0, y: 0, z: 10 },\n    planeWidth = 80,\n    planeHeight = 40,\n    segmentsX = 60,\n    segmentsY = 30,\n    speed = 1,\n    amplitude = 1.5,\n    frequency = 0.3,\n    opacity = 0.6,\n    paused = false,\n    mouseInfluence = 2,\n    mouseRotation = 0.1,\n    dotSize = 3,\n    dotSizeMin = 1,\n    crossSize = 0.3,\n    dashRatio = 0.5,\n    contourLevels = 6,\n    maxPixelRatio = 2,\n    onReady,\n}: WavesThreeProps) => {\n    const containerRef = useRef<HTMLDivElement>(null);\n    const [size, setSize] = useState({ width: 0, height: 0 });\n\n    \/\/ Hot-update refs \u2014 no scene restart needed for these\n    const mouseRef = useRef({ x: 0, y: 0 });\n    const speedRef = useRef(speed);\n    const pausedRef = useRef(paused);\n    const amplitudeRef = useRef(amplitude);\n    const frequencyRef = useRef(frequency);\n    const mouseInfluenceRef = useRef(mouseInfluence);\n    const mouseRotationRef = useRef(mouseRotation);\n    const opacityRef = useRef(opacity);\n\n    useEffect(() => {\n        speedRef.current = speed;\n    }, [speed]);\n    useEffect(() => {\n        pausedRef.current = paused;\n    }, [paused]);\n    useEffect(() => {\n        amplitudeRef.current = amplitude;\n    }, [amplitude]);\n    useEffect(() => {\n        frequencyRef.current = frequency;\n    }, [frequency]);\n    useEffect(() => {\n        mouseInfluenceRef.current = mouseInfluence;\n    }, [mouseInfluence]);\n    useEffect(() => {\n        mouseRotationRef.current = mouseRotation;\n    }, [mouseRotation]);\n    useEffect(() => {\n        opacityRef.current = opacity;\n    }, [opacity]);\n\n    \/\/ Container size\n    useEffect(() => {\n        const el = containerRef.current;\n\n        if (!el) {\n            return;\n        }\n\n        const ro = new ResizeObserver((entries) => {\n            const r = entries[0].contentRect;\n            setSize({ width: r.width, height: r.height });\n        });\n        ro.observe(el);\n\n        return () => ro.disconnect();\n    }, []);\n\n    \/\/ Main scene\n    useEffect(() => {\n        const el = containerRef.current;\n\n        if (!el || size.width === 0 || size.height === 0) {\n            return;\n        }\n\n        \/\/ Scene & Camera\n        const scene = new THREE.Scene();\n        const camera = new THREE.PerspectiveCamera(\n            75,\n            size.width \/ size.height,\n            0.1,\n            1000,\n        );\n        camera.position.set(\n            cameraPosition.x,\n            cameraPosition.y,\n            cameraPosition.z,\n        );\n        camera.lookAt(0, 0, 0);\n\n        \/\/ Renderer\n        const renderer = new THREE.WebGLRenderer({\n            alpha: true,\n            antialias: true,\n        });\n        renderer.setPixelRatio(\n            Math.min(window.devicePixelRatio, maxPixelRatio),\n        );\n        renderer.setSize(size.width, size.height);\n        renderer.setClearColor(0x000000, 0);\n        el.appendChild(renderer.domElement);\n\n        \/\/ Colors\n        const isDark = document.documentElement.classList.contains('dark');\n        const rawColors = colors ?? (isDark ? DEFAULT_DARK : DEFAULT_LIGHT);\n        const colorStops = rawColors.map((c) => new THREE.Color(c));\n\n        \/\/ Per-style setup\n        let object3d: THREE.Object3D;\n        let geo: THREE.BufferGeometry;\n        let mat: THREE.Material;\n        let posBuf: Float32Array | null = null;\n        let baseBuf: Float32Array | null = null; \/\/ for dashes: stores XY reference\n        let posAttr: THREE.BufferAttribute | null = null;\n        let crossCenters: Float32Array | null = null;\n        let hexCentersBuf: Float32Array | null = null;\n        let hexPosBuf: Float32Array | null = null;\n        let contourVtxGrid: Float32Array | null = null;\n        const extraDispose: THREE.Material[] = [];\n        let lights: THREE.Light[] = [];\n\n        const cols = segmentsX;\n        const rows = segmentsY;\n\n        if (style === 'wireframe') {\n            const g = new THREE.PlaneGeometry(\n                planeWidth,\n                planeHeight,\n                cols,\n                rows,\n            );\n            g.setAttribute(\n                'color',\n                new THREE.BufferAttribute(\n                    makeColorBuffer(g.attributes.position.count, colorStops),\n                    3,\n                ),\n            );\n            const m = new THREE.MeshBasicMaterial({\n                vertexColors: true,\n                wireframe: true,\n                transparent: true,\n                opacity: opacityRef.current,\n            });\n            object3d = new THREE.Mesh(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            posBuf = posAttr.array as Float32Array;\n            geo = g;\n            mat = m;\n        } else if (style === 'grid') {\n            const { geo: g, pos } = buildGrid(\n                cols,\n                rows,\n                planeWidth,\n                planeHeight,\n                colorStops,\n                lines,\n            );\n            const m = new THREE.LineBasicMaterial({\n                vertexColors: true,\n                transparent: true,\n                opacity: opacityRef.current,\n            });\n            object3d = new THREE.LineSegments(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            posBuf = pos;\n            geo = g;\n            mat = m;\n        } else if (style === 'dots') {\n            const { geo: g, pos } = buildDots(\n                cols,\n                rows,\n                planeWidth,\n                planeHeight,\n                colorStops,\n            );\n            const m = makeRoundDotMaterial(dotSize * 2, opacityRef.current);\n            object3d = new THREE.Points(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            posBuf = pos;\n            geo = g;\n            mat = m;\n        } else if (style === 'dots-wave') {\n            const { geo: g, pos } = buildDots(\n                cols,\n                rows,\n                planeWidth,\n                planeHeight,\n                colorStops,\n            );\n            const m = makeRoundDotWaveMaterial(\n                dotSizeMin * 2,\n                dotSize * 2,\n                amplitude,\n                opacityRef.current,\n            );\n            object3d = new THREE.Points(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            posBuf = pos;\n            geo = g;\n            mat = m;\n        } else if (style === 'crosses') {\n            const {\n                geo: g,\n                centers,\n                pos,\n            } = buildCrosses(\n                cols,\n                rows,\n                planeWidth,\n                planeHeight,\n                colorStops,\n                crossSize,\n            );\n            const m = new THREE.LineBasicMaterial({\n                vertexColors: true,\n                transparent: true,\n                opacity: opacityRef.current,\n            });\n            object3d = new THREE.LineSegments(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            posBuf = pos;\n            crossCenters = centers;\n            geo = g;\n            mat = m;\n        } else if (style === 'diagonal-left' || style === 'diagonal-right') {\n            const dir = style === 'diagonal-left' ? 'left' : 'right';\n            const { geo: g, pos } = buildDiagonal(\n                cols,\n                rows,\n                planeWidth,\n                planeHeight,\n                colorStops,\n                dir,\n            );\n            const m = new THREE.LineBasicMaterial({\n                vertexColors: true,\n                transparent: true,\n                opacity: opacityRef.current,\n            });\n            object3d = new THREE.LineSegments(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            posBuf = pos;\n            geo = g;\n            mat = m;\n        } else if (style === 'zigzag') {\n            const { geo: g, pos } = buildZigzag(\n                cols,\n                rows,\n                planeWidth,\n                planeHeight,\n                colorStops,\n            );\n            const m = new THREE.LineBasicMaterial({\n                vertexColors: true,\n                transparent: true,\n                opacity: opacityRef.current,\n            });\n            object3d = new THREE.LineSegments(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            posBuf = pos;\n            geo = g;\n            mat = m;\n        } else if (style === 'hexagons') {\n            const {\n                geo: g,\n                pos,\n                hexCenters,\n            } = buildHexagons(cols, rows, planeWidth, planeHeight, colorStops);\n            const m = new THREE.LineBasicMaterial({\n                vertexColors: true,\n                transparent: true,\n                opacity: opacityRef.current,\n            });\n            object3d = new THREE.LineSegments(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            hexPosBuf = pos;\n            hexCentersBuf = hexCenters;\n            geo = g;\n            mat = m;\n        } else if (style === 'dashes') {\n            const {\n                geo: g,\n                pos,\n                basePos,\n            } = buildDashes(\n                cols,\n                rows,\n                planeWidth,\n                planeHeight,\n                colorStops,\n                lines,\n                dashRatio,\n            );\n            const m = new THREE.LineBasicMaterial({\n                vertexColors: true,\n                transparent: true,\n                opacity: opacityRef.current,\n            });\n            object3d = new THREE.LineSegments(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            posBuf = pos;\n            baseBuf = basePos;\n            geo = g;\n            mat = m;\n        } else if (style === 'contour') {\n            const { geo: g, vtxGrid } = buildContourPlaceholder(\n                cols,\n                rows,\n                planeWidth,\n                planeHeight,\n                colorStops,\n                contourLevels,\n            );\n            const m = new THREE.LineBasicMaterial({\n                vertexColors: true,\n                transparent: true,\n                opacity: opacityRef.current,\n            });\n            object3d = new THREE.LineSegments(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            contourVtxGrid = vtxGrid;\n            geo = g;\n            mat = m;\n        } else {\n            \/\/ solid\n            const { geo: g, pos } = buildSolid(\n                cols,\n                rows,\n                planeWidth,\n                planeHeight,\n                colorStops,\n            );\n            const m = new THREE.MeshPhongMaterial({\n                vertexColors: true,\n                transparent: true,\n                opacity: opacityRef.current,\n                side: THREE.DoubleSide,\n                shininess: 60,\n            });\n            const keyLight = new THREE.DirectionalLight(0xffffff, 1.2);\n            keyLight.position.set(5, 10, 7);\n            const fillLight = new THREE.AmbientLight(0xffffff, 0.4);\n            scene.add(keyLight, fillLight);\n            lights = [keyLight, fillLight];\n            object3d = new THREE.Mesh(g, m);\n            posAttr = g.attributes.position as THREE.BufferAttribute;\n            posBuf = pos;\n            geo = g;\n            mat = m;\n        }\n\n        scene.add(object3d);\n\n        \/\/ Event listeners\n        const handleResize = () => {\n            camera.aspect = el.clientWidth \/ el.clientHeight;\n            camera.updateProjectionMatrix();\n            renderer.setSize(el.clientWidth, el.clientHeight);\n        };\n        const handleMouse = (e: MouseEvent) => {\n            mouseRef.current.x = (e.clientX \/ window.innerWidth) * 2 - 1;\n            mouseRef.current.y = -(e.clientY \/ window.innerHeight) * 2 + 1;\n        };\n        window.addEventListener('resize', handleResize);\n        window.addEventListener('mousemove', handleMouse);\n\n        \/\/ Contour iso-line builder (marching squares, edge-interpolated)\n        const rebuildContour = (\n            vtxGrid: Float32Array,\n            zGrid: Float32Array,\n            thresholds: number[],\n            posAttrC: THREE.BufferAttribute,\n            colAttrC: THREE.BufferAttribute,\n        ) => {\n            const cx2 = cols + 1;\n            let ptr = 0;\n            const posArr = posAttrC.array as Float32Array;\n            const colArr = colAttrC.array as Float32Array;\n\n            for (const thresh of thresholds) {\n                const t = (thresh - (-amplitude - 1)) \/ ((amplitude + 1) * 2);\n                const clr = lerpPalette(t, colorStops);\n\n                for (let r = 0; r < rows; r++) {\n                    for (let c = 0; c < cols; c++) {\n                        const i00 = r * cx2 + c;\n                        const i10 = r * cx2 + c + 1;\n                        const i01 = (r + 1) * cx2 + c;\n                        const i11 = (r + 1) * cx2 + c + 1;\n\n                        const z00 = zGrid[i00];\n                        const z10 = zGrid[i10];\n                        const z01 = zGrid[i01];\n                        const z11 = zGrid[i11];\n\n                        const x00 = vtxGrid[i00 * 3];\n                        const y00 = vtxGrid[i00 * 3 + 1];\n                        const x10 = vtxGrid[i10 * 3];\n                        const y10 = vtxGrid[i10 * 3 + 1];\n                        const x01 = vtxGrid[i01 * 3];\n                        const y01 = vtxGrid[i01 * 3 + 1];\n                        const x11 = vtxGrid[i11 * 3];\n                        const y11 = vtxGrid[i11 * 3 + 1];\n\n                        \/\/ Collect edge crossing points\n                        const pts: [number, number, number][] = [];\n\n                        const cross = (\n                            zA: number,\n                            zB: number,\n                            xA: number,\n                            yA: number,\n                            _zA2: number,\n                            xB: number,\n                            yB: number,\n                            _zB2: number,\n                        ) => {\n                            if (zA < thresh !== zB < thresh) {\n                                const t2 = (thresh - zA) \/ (zB - zA);\n                                pts.push([\n                                    xA + (xB - xA) * t2,\n                                    yA + (yB - yA) * t2,\n                                    thresh,\n                                ]);\n                            }\n                        };\n                        cross(z00, z10, x00, y00, z00, x10, y10, z10); \/\/ bottom edge\n                        cross(z10, z11, x10, y10, z10, x11, y11, z11); \/\/ right edge\n                        cross(z01, z11, x01, y01, z01, x11, y11, z11); \/\/ top edge\n                        cross(z00, z01, x00, y00, z00, x01, y01, z01); \/\/ left edge\n\n                        if (pts.length >= 2 && ptr + 6 <= posArr.length) {\n                            for (let k = 0; k < 2; k++) {\n                                posArr[ptr] = pts[k][0];\n                                posArr[ptr + 1] = pts[k][1];\n                                posArr[ptr + 2] = pts[k][2];\n                                colArr[ptr] = clr.r;\n                                colArr[ptr + 1] = clr.g;\n                                colArr[ptr + 2] = clr.b;\n                                ptr += 3;\n                            }\n                        }\n                    }\n                }\n            }\n\n            posAttrC.needsUpdate = true;\n            colAttrC.needsUpdate = true;\n            (object3d as THREE.LineSegments).geometry.setDrawRange(0, ptr \/ 3);\n        };\n\n        \/\/ Z grid for contour (shared scratch)\n        const zGrid =\n            style === 'contour'\n                ? new Float32Array((cols + 1) * (rows + 1))\n                : null;\n\n        \/\/ Animation loop\n        let rafId: number;\n\n        const animate = () => {\n            rafId = requestAnimationFrame(animate);\n\n            \/\/ Sync opacity to all material types\n            if ((mat as any).opacity !== undefined) {\n                (mat as any).opacity = opacityRef.current;\n            }\n\n            if ((mat as any).uniforms?.uOpacity) {\n                (mat as any).uniforms.uOpacity.value = opacityRef.current;\n            }\n\n            if (!pausedRef.current) {\n                const time = performance.now() * 0.001 * speedRef.current;\n                const freq = frequencyRef.current;\n                const amp = amplitudeRef.current;\n                const mi = mouseInfluenceRef.current;\n                const mx = mouseRef.current.x;\n                const my = mouseRef.current.y;\n\n                if (style === 'crosses' && crossCenters && posAttr && posBuf) {\n                    const vtxCount = (cols + 1) * (rows + 1);\n\n                    for (let vi = 0; vi < vtxCount; vi++) {\n                        const bx = crossCenters[vi * 3];\n                        const by = crossCenters[vi * 3 + 1];\n                        const z = calcZ(bx, by, time, freq, amp, mx, my, mi);\n                        const b = vi * 12;\n                        posBuf[b + 2] = z;\n                        posBuf[b + 5] = z;\n                        posBuf[b + 8] = z;\n                        posBuf[b + 11] = z;\n                    }\n\n                    posAttr.needsUpdate = true;\n                } else if (\n                    style === 'hexagons' &&\n                    hexCentersBuf &&\n                    hexPosBuf &&\n                    posAttr\n                ) {\n                    const hexCount = hexCentersBuf.length \/ 3;\n\n                    for (let hi = 0; hi < hexCount; hi++) {\n                        const bx = hexCentersBuf[hi * 3];\n                        const by = hexCentersBuf[hi * 3 + 1];\n                        const z = calcZ(bx, by, time, freq, amp, mx, my, mi);\n                        \/\/ 6 edges \u00d7 2 pts = 12 endpoints per hex\n                        const base = hi * 6 * 6; \/\/ 6edges \u00d7 6floats\n\n                        for (let k = 0; k < 12; k++) {\n                            hexPosBuf[base + k * 3 + 2] = z;\n                        }\n                    }\n\n                    \/\/ Sync the slice used in geo\n                    const posA = geo.attributes\n                        .position as THREE.BufferAttribute;\n                    const arr = posA.array as Float32Array;\n                    arr.set(hexPosBuf.slice(0, arr.length));\n                    posA.needsUpdate = true;\n                } else if (style === 'dashes' && posBuf && baseBuf && posAttr) {\n                    const total = posBuf.length \/ 3;\n\n                    for (let i = 0; i < total; i++) {\n                        const x = baseBuf[i * 3];\n                        const y = baseBuf[i * 3 + 1];\n                        posBuf[i * 3 + 2] = calcZ(\n                            x,\n                            y,\n                            time,\n                            freq,\n                            amp,\n                            mx,\n                            my,\n                            mi,\n                        );\n                    }\n\n                    posAttr.needsUpdate = true;\n                } else if (\n                    style === 'contour' &&\n                    contourVtxGrid &&\n                    zGrid &&\n                    posAttr\n                ) {\n                    const vtxCount = (cols + 1) * (rows + 1);\n\n                    for (let i = 0; i < vtxCount; i++) {\n                        const x = contourVtxGrid[i * 3];\n                        const y = contourVtxGrid[i * 3 + 1];\n                        zGrid[i] = calcZ(x, y, time, freq, amp, mx, my, mi);\n                    }\n\n                    const thresholds: number[] = [];\n\n                    for (let l = 0; l < contourLevels; l++) {\n                        thresholds.push(\n                            -amp -\n                                1 +\n                                (l \/ (contourLevels - 1)) * (amp + 1) * 2,\n                        );\n                    }\n\n                    rebuildContour(\n                        contourVtxGrid,\n                        zGrid,\n                        thresholds,\n                        geo.attributes.position as THREE.BufferAttribute,\n                        geo.attributes.color as THREE.BufferAttribute,\n                    );\n                } else if (posBuf && posAttr) {\n                    \/\/ All other styles: simple per-vertex Z update\n                    const total = posBuf.length \/ 3;\n\n                    for (let i = 0; i < total; i++) {\n                        const x = posBuf[i * 3];\n                        const y = posBuf[i * 3 + 1];\n                        posBuf[i * 3 + 2] = calcZ(\n                            x,\n                            y,\n                            time,\n                            freq,\n                            amp,\n                            mx,\n                            my,\n                            mi,\n                        );\n                    }\n\n                    posAttr.needsUpdate = true;\n\n                    \/\/ Solid needs normals recomputed for correct lighting\n                    if (style === 'solid') {\n                        (geo as THREE.PlaneGeometry).computeVertexNormals();\n                    }\n                }\n\n                object3d.rotation.x = my * mouseRotationRef.current;\n                object3d.rotation.y = mx * mouseRotationRef.current;\n            }\n\n            renderer.render(scene, camera);\n        };\n\n        animate();\n        onReady?.();\n\n        \/\/ Cleanup\n        return () => {\n            cancelAnimationFrame(rafId);\n            window.removeEventListener('resize', handleResize);\n            window.removeEventListener('mousemove', handleMouse);\n            lights.forEach((l) => scene.remove(l));\n            scene.remove(object3d);\n            geo.dispose();\n            mat.dispose();\n            extraDispose.forEach((m2) => m2.dispose());\n            renderer.dispose();\n\n            if (el.contains(renderer.domElement)) {\n                el.removeChild(renderer.domElement);\n            }\n        };\n    }, [\n        size.width,\n        size.height,\n        style,\n        colors,\n        lines,\n        cameraPosition,\n        planeWidth,\n        planeHeight,\n        segmentsX,\n        segmentsY,\n        dotSize,\n        dotSizeMin,\n        crossSize,\n        dashRatio,\n        contourLevels,\n        maxPixelRatio,\n        onReady,\n    ]);\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(`pointer-events-none absolute inset-0`, className)}\n            aria-hidden=\"true\"\n        \/>\n    );\n};\n\nexport default WavesThree;\n"}],"meta":{"category":"canvas","version":"1.0.0"},"categories":["canvas"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"timeline-collapsible","type":"registry:ui","title":"Timeline Collapsible","description":"An interactive collapsible vertical timeline allowing accordion-style detail expansion.","author":"designbycode","dependencies":["motion","lucide-react"],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/timelines\/timeline-collapsible.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { motion, AnimatePresence } from 'motion\/react';\nimport {\n    ChevronDown,\n    Check,\n    Circle,\n    CheckCircle2,\n    PlayCircle,\n    HelpCircle,\n} from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\nimport { TimelineItem } from '.\/timeline-vertical';\nimport { Card } from '@\/components\/ui\/card';\n\ninterface TimelineCollapsibleProps extends React.HTMLAttributes<HTMLDivElement> {\n    items: TimelineItem[];\n    allowMultiple?: boolean;\n    defaultExpandedIds?: (string | number)[];\n}\n\nexport function TimelineCollapsible({\n    items,\n    allowMultiple = false,\n    defaultExpandedIds = [],\n    className,\n    ...props\n}: TimelineCollapsibleProps) {\n    const [expandedIds, setExpandedIds] = React.useState<\n        Record<string | number, boolean>\n    >(() => {\n        const initial: Record<string | number, boolean> = {};\n        defaultExpandedIds.forEach((id) => {\n            initial[id] = true;\n        });\n        return initial;\n    });\n\n    const toggleExpand = (id: string | number) => {\n        setExpandedIds((prev) => {\n            if (allowMultiple) {\n                return { ...prev, [id]: !prev[id] };\n            } else {\n                const isCurrentlyExpanded = prev[id];\n                const next: Record<string | number, boolean> = {};\n                if (!isCurrentlyExpanded) {\n                    next[id] = true;\n                }\n                return next;\n            }\n        });\n    };\n\n    return (\n        <div\n            className={cn('relative w-full max-w-4xl px-4 py-8', className)}\n            {...props}\n        >\n            {\/* Elegant Gradient Track Line *\/}\n            <div className=\"pointer-events-none absolute top-0 bottom-0 left-8 w-[2px] bg-linear-to-b from-primary\/80 via-primary\/30 to-border\/30\" \/>\n\n            <div className=\"flex flex-col gap-6\">\n                {items.map((item) => {\n                    const isExpanded = !!expandedIds[item.id];\n                    const isCompleted = item.status === 'completed';\n                    const isCurrent = item.status === 'current';\n\n                    \/\/ Status details styling\n                    const getStatusStyles = () => {\n                        if (isCompleted) {\n                            return {\n                                ring: 'border-primary bg-primary text-primary-foreground',\n                                labelBg:\n                                    'bg-chart-2\/10 text-chart-2 border-chart-2\/20',\n                                labelText: item.statusLabel || 'Completed',\n                                icon: <CheckCircle2 className=\"size-4\" \/>,\n                            };\n                        }\n                        if (isCurrent) {\n                            return {\n                                ring: 'border-primary ring-4 ring-primary\/20',\n                                labelBg:\n                                    'bg-primary\/10 text-primary border-primary\/20',\n                                labelText: item.statusLabel || 'In Progress',\n                                icon: (\n                                    <PlayCircle className=\"size-4 animate-pulse\" \/>\n                                ),\n                            };\n                        }\n                        return {\n                            ring: 'border-muted-foreground\/30 text-muted-foreground bg-muted\/40',\n                            labelBg:\n                                'bg-muted text-muted-foreground border-border',\n                            labelText: item.statusLabel || 'Planned',\n                            icon: <HelpCircle className=\"size-4\" \/>,\n                        };\n                    };\n\n                    const statusInfo = getStatusStyles();\n\n                    return (\n                        <div\n                            key={item.id}\n                            className=\"group\/row relative flex w-full justify-end text-left\"\n                        >\n                            {\/* Interactive Node Icon *\/}\n                            <button\n                                onClick={() => toggleExpand(item.id)}\n                                className={cn(\n                                    'absolute top-4 left-0 z-10 flex size-8 cursor-pointer items-center justify-center rounded-full border shadow-xs transition-all duration-300 hover:scale-105 active:scale-95',\n                                    statusInfo.ring,\n                                )}\n                            >\n                                {isCurrent && (\n                                    <span className=\"absolute inset-0 animate-ping rounded-full border border-primary opacity-75\" \/>\n                                )}\n                                {item.icon ? (\n                                    <div className=\"flex size-4 items-center justify-center [&_svg]:size-4\">\n                                        {item.icon}\n                                    <\/div>\n                                ) : (\n                                    <div className=\"size-2 rounded-full bg-current\" \/>\n                                )}\n                            <\/button>\n\n                            {\/* Expandable Premium Glassmorphic Content Card *\/}\n                            <div className=\"w-[calc(100%-4.5rem)]\">\n                                <Card\n                                    className={cn(\n                                        'group cursor-pointer bg-card\/60 p-5 shadow-xs backdrop-blur-md transition-all duration-300 hover:-translate-y-0.5 hover:border-primary\/20 hover:shadow-md',\n                                        isExpanded &&\n                                            'translate-y-0 border-primary\/30 bg-card\/90 shadow-md',\n                                    )}\n                                    onClick={() => toggleExpand(item.id)}\n                                >\n                                    {\/* Header Layout *\/}\n                                    <div className=\"flex items-start justify-between gap-4\">\n                                        <div className=\"flex flex-1 flex-col gap-2\">\n                                            {\/* Top badges bar *\/}\n                                            <div className=\"flex flex-wrap items-center gap-2\">\n                                                <span\n                                                    className={cn(\n                                                        'inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[10px] font-semibold tracking-wide uppercase',\n                                                        statusInfo.labelBg,\n                                                    )}\n                                                >\n                                                    {statusInfo.icon}\n                                                    {statusInfo.labelText}\n                                                <\/span>\n                                                {item.date && (\n                                                    <span className=\"text-[11px] font-medium text-muted-foreground\/80\">\n                                                        \u2022 {item.date}\n                                                    <\/span>\n                                                )}\n                                            <\/div>\n\n                                            {\/* Milestone Title *\/}\n                                            <h3 className=\"text-lg font-bold tracking-tight text-foreground transition-colors group-hover:text-primary\">\n                                                {item.title}\n                                            <\/h3>\n                                        <\/div>\n\n                                        {\/* Dropdown Chevron *\/}\n                                        <div className=\"flex size-7 items-center justify-center rounded-lg border border-transparent bg-muted\/40 text-muted-foreground transition-all group-hover:border-border\/60 group-hover:bg-muted\/80\">\n                                            <ChevronDown\n                                                className={cn(\n                                                    'size-4 transition-transform duration-200',\n                                                    isExpanded &&\n                                                        'rotate-180 text-primary',\n                                                )}\n                                            \/>\n                                        <\/div>\n                                    <\/div>\n\n                                    {\/* Expandable Content Area *\/}\n                                    <AnimatePresence initial={false}>\n                                        {isExpanded && (\n                                            <motion.div\n                                                initial={{\n                                                    height: 0,\n                                                    opacity: 0,\n                                                    marginTop: 0,\n                                                }}\n                                                animate={{\n                                                    height: 'auto',\n                                                    opacity: 1,\n                                                    marginTop: 16,\n                                                }}\n                                                exit={{\n                                                    height: 0,\n                                                    opacity: 0,\n                                                    marginTop: 0,\n                                                }}\n                                                transition={{\n                                                    duration: 0.25,\n                                                    ease: 'easeInOut',\n                                                }}\n                                                className=\"overflow-hidden border-t border-border\/50 pt-4\"\n                                                onClick={(e) =>\n                                                    e.stopPropagation()\n                                                } \/\/ Stop click toggle inside content\n                                            >\n                                                {\/* Description Text *\/}\n                                                {item.description && (\n                                                    <div className=\"text-sm leading-relaxed text-muted-foreground\">\n                                                        {item.description}\n                                                    <\/div>\n                                                )}\n\n                                                {\/* Sub-steps \/ Checklist (if provided) *\/}\n                                                {item.subtasks &&\n                                                    item.subtasks.length >\n                                                        0 && (\n                                                        <div className=\"mt-4 flex flex-col gap-2 rounded-lg border border-border\/40 bg-muted\/30 p-4\">\n                                                            <h4 className=\"text-[11px] font-bold tracking-wider text-muted-foreground\/80 uppercase\">\n                                                                Task\n                                                                Deliverables\n                                                            <\/h4>\n                                                            <div className=\"mt-2 flex flex-col gap-2\">\n                                                                {item.subtasks.map(\n                                                                    (\n                                                                        task,\n                                                                        i,\n                                                                    ) => (\n                                                                        <div\n                                                                            key={\n                                                                                i\n                                                                            }\n                                                                            className=\"flex items-center gap-2.5 text-xs text-muted-foreground\"\n                                                                        >\n                                                                            {task.completed ? (\n                                                                                <Check className=\"size-4 shrink-0 rounded-sm border border-chart-2\/20 bg-chart-2\/10 p-0.5 text-chart-2\" \/>\n                                                                            ) : (\n                                                                                <Circle className=\"size-4 shrink-0 text-muted-foreground\/40\" \/>\n                                                                            )}\n                                                                            <span\n                                                                                className={cn(\n                                                                                    task.completed &&\n                                                                                        'text-muted-foreground\/60 line-through',\n                                                                                )}\n                                                                            >\n                                                                                {\n                                                                                    task.title\n                                                                                }\n                                                                            <\/span>\n                                                                        <\/div>\n                                                                    ),\n                                                                )}\n                                                            <\/div>\n                                                        <\/div>\n                                                    )}\n\n                                                {\/* Tag list pills *\/}\n                                                {item.tags &&\n                                                    item.tags.length > 0 && (\n                                                        <div className=\"mt-4 flex flex-wrap gap-1.5\">\n                                                            {item.tags.map(\n                                                                (tag) => (\n                                                                    <span\n                                                                        key={\n                                                                            tag\n                                                                        }\n                                                                        className=\"rounded-md border border-border\/40 bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground\"\n                                                                    >\n                                                                        #{tag}\n                                                                    <\/span>\n                                                                ),\n                                                            )}\n                                                        <\/div>\n                                                    )}\n                                            <\/motion.div>\n                                        )}\n                                    <\/AnimatePresence>\n                                <\/Card>\n                            <\/div>\n                        <\/div>\n                    );\n                })}\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"timelines","version":"1.0.0"},"categories":["timelines"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"timeline-glow","type":"registry:ui","title":"Timeline Glow","description":"A premium modern vertical timeline featuring a glowing neon track line and backing card spotlights.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/timelines\/timeline-glow.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { TimelineItem } from '.\/timeline-vertical';\nimport { Card } from '@\/components\/ui\/card';\n\ninterface TimelineGlowProps extends React.HTMLAttributes<HTMLDivElement> {\n    items: TimelineItem[];\n    align?: 'left' | 'alternate';\n}\n\nexport function TimelineGlow({\n    items,\n    align = 'left',\n    className,\n    ...props\n}: TimelineGlowProps) {\n    return (\n        <div\n            className={cn('relative w-full max-w-4xl px-4 py-8', className)}\n            {...props}\n        >\n            {\/* Glowing Gradient Track Line *\/}\n            <div\n                className={cn(\n                    'pointer-events-none absolute top-0 bottom-0 w-0.5 bg-linear-to-b from-indigo-500 via-purple-500 to-pink-500 opacity-80',\n                    align === 'alternate'\n                        ? 'left-1\/2 -translate-x-1\/2'\n                        : 'left-8',\n                )}\n            \/>\n\n            <div className=\"flex flex-col gap-10\">\n                {items.map((item, index) => {\n                    const isEven = index % 2 === 0;\n                    const isCompleted = item.status === 'completed';\n                    const isCurrent = item.status === 'current';\n\n                    return (\n                        <div\n                            key={item.id}\n                            className={cn(\n                                'relative flex w-full',\n                                align === 'alternate'\n                                    ? isEven\n                                        ? 'justify-start text-right'\n                                        : 'justify-end text-left'\n                                    : 'justify-end text-left',\n                            )}\n                        >\n                            {\/* Glowing Node Circle *\/}\n                            <div\n                                className={cn(\n                                    'absolute top-1.5 z-10 flex size-8 items-center justify-center rounded-full border bg-background shadow-xs',\n                                    align === 'alternate'\n                                        ? 'left-1\/2 -translate-x-1\/2'\n                                        : 'left-0',\n                                    isCompleted &&\n                                        'border-purple-500 bg-linear-to-tr from-indigo-500 to-purple-500 text-white',\n                                    isCurrent &&\n                                        'border-pink-500 ring-2 ring-pink-500\/20',\n                                    !isCompleted &&\n                                        !isCurrent &&\n                                        'border-muted-foreground\/30 text-muted-foreground',\n                                )}\n                            >\n                                {\/* Backlight blur glow effect *\/}\n                                {(isCompleted || isCurrent) && (\n                                    <div\n                                        className={cn(\n                                            'absolute -inset-1 -z-10 animate-pulse rounded-full opacity-75 blur-xs',\n                                            isCompleted &&\n                                                'bg-linear-to-tr from-indigo-500 to-purple-500',\n                                            isCurrent && 'bg-pink-500',\n                                        )}\n                                    \/>\n                                )}\n\n                                {item.icon ? (\n                                    <div className=\"flex size-4 items-center justify-center [&_svg]:size-4\">\n                                        {item.icon}\n                                    <\/div>\n                                ) : (\n                                    <div\n                                        className={cn(\n                                            'size-2 rounded-full',\n                                            isCompleted && 'bg-white',\n                                            isCurrent &&\n                                                'animate-ping bg-pink-500',\n                                            !isCompleted &&\n                                                !isCurrent &&\n                                                'bg-muted-foreground\/40',\n                                        )}\n                                    \/>\n                                )}\n                            <\/div>\n\n                            {\/* Glowing Card Wrapper *\/}\n                            <div\n                                className={cn(\n                                    'w-[calc(100%-3rem)] md:w-[calc(50%-2rem)]',\n                                    align === 'alternate'\n                                        ? ''\n                                        : 'w-[calc(100%-4rem)]',\n                                )}\n                            >\n                                <Card className=\"group relative border-border bg-card p-5 shadow-xs transition-all duration-300 hover:border-purple-500\/30 hover:shadow-lg\">\n                                    {\/* Ambient card corner glow *\/}\n                                    <div className=\"pointer-events-none absolute inset-0 rounded-xl bg-linear-to-tr from-indigo-500\/0 via-purple-500\/0 to-pink-500\/0 opacity-0 transition-all duration-500 group-hover:from-indigo-500\/5 group-hover:via-purple-500\/5 group-hover:to-pink-500\/5 group-hover:opacity-100\" \/>\n\n                                    <div\n                                        className={cn(\n                                            'flex flex-col gap-1 md:flex-row md:items-baseline md:justify-between',\n                                            align === 'alternate' &&\n                                                isEven &&\n                                                'md:flex-row-reverse',\n                                        )}\n                                    >\n                                        <h3 className=\"text-base font-semibold text-foreground transition-colors group-hover:text-purple-500\">\n                                            {item.title}\n                                        <\/h3>\n                                        {item.date && (\n                                            <span className=\"text-xs font-medium text-muted-foreground\">\n                                                {item.date}\n                                            <\/span>\n                                        )}\n                                    <\/div>\n                                    {item.description && (\n                                        <div className=\"mt-2 text-sm leading-relaxed text-muted-foreground\">\n                                            {item.description}\n                                        <\/div>\n                                    )}\n                                <\/Card>\n                            <\/div>\n                        <\/div>\n                    );\n                })}\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"timelines","version":"1.0.0"},"categories":["timelines"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"timeline-horizontal","type":"registry:ui","title":"Timeline Horizontal","description":"A responsive horizontal stepper\/timeline progress tracker with connecting status lines.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/timelines\/timeline-horizontal.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { TimelineItem } from '.\/timeline-vertical';\n\ninterface TimelineHorizontalProps extends React.HTMLAttributes<HTMLDivElement> {\n    items: TimelineItem[];\n}\n\nexport function TimelineHorizontal({\n    items,\n    className,\n    ...props\n}: TimelineHorizontalProps) {\n    return (\n        <div\n            className={cn(\n                'relative w-full scrollbar-thin scrollbar-thumb-muted-foreground\/20 scrollbar-track-transparent overflow-x-auto pb-4',\n                className,\n            )}\n            {...props}\n        >\n            <div className=\"flex min-w-[640px] justify-between gap-4 px-6 py-6\">\n                {items.map((item, index) => {\n                    const isCompleted = item.status === 'completed';\n                    const isCurrent = item.status === 'current';\n                    const isLast = index === items.length - 1;\n\n                    return (\n                        <div\n                            key={item.id}\n                            className=\"relative flex flex-1 flex-col items-center\"\n                        >\n                            {\/* Connecting Line (drawn from the current node to the next one) *\/}\n                            {!isLast && (\n                                <div\n                                    className={cn(\n                                        'absolute top-5 right-[-50%] left-1\/2 z-0 h-0.5 bg-border',\n                                        isCompleted && 'bg-primary',\n                                    )}\n                                \/>\n                            )}\n\n                            {\/* Node Icon\/Dot *\/}\n                            <div\n                                className={cn(\n                                    'relative z-10 flex size-10 items-center justify-center rounded-full border bg-background shadow-xs transition-all',\n                                    isCompleted &&\n                                        'border-primary bg-primary text-primary-foreground',\n                                    isCurrent &&\n                                        'border-primary ring-4 ring-primary\/10',\n                                    !isCompleted &&\n                                        !isCurrent &&\n                                        'border-muted-foreground\/30 text-muted-foreground',\n                                )}\n                            >\n                                {item.icon ? (\n                                    <div className=\"flex size-4.5 items-center justify-center [&_svg]:size-4.5\">\n                                        {item.icon}\n                                    <\/div>\n                                ) : (\n                                    <span className=\"text-xs font-semibold\">\n                                        {index + 1}\n                                    <\/span>\n                                )}\n                            <\/div>\n\n                            {\/* Content *\/}\n                            <div className=\"mt-4 flex flex-col items-center px-2 text-center\">\n                                <h3 className=\"text-sm font-semibold text-foreground\">\n                                    {item.title}\n                                <\/h3>\n                                {item.date && (\n                                    <span className=\"mt-0.5 text-[11px] font-medium text-muted-foreground\">\n                                        {item.date}\n                                    <\/span>\n                                )}\n                                {item.description && (\n                                    <p className=\"mt-1 max-w-[160px] text-xs leading-relaxed text-muted-foreground\">\n                                        {item.description}\n                                    <\/p>\n                                )}\n                            <\/div>\n                        <\/div>\n                    );\n                })}\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"timelines","version":"1.0.0"},"categories":["timelines"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"timeline-motion","type":"registry:ui","title":"Timeline Motion","description":"An animated vertical timeline utilizing motion\/react to trigger scroll-linked entry transitions.","author":"designbycode","dependencies":["motion"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/timelines\/timeline-motion.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { motion } from 'motion\/react';\nimport { cn } from '@\/lib\/utils';\nimport { TimelineItem } from '.\/timeline-vertical';\n\ninterface TimelineMotionProps extends React.HTMLAttributes<HTMLDivElement> {\n    items: TimelineItem[];\n    align?: 'left' | 'alternate';\n}\n\nexport function TimelineMotion({\n    items,\n    align = 'left',\n    className,\n    ...props\n}: TimelineMotionProps) {\n    return (\n        <div\n            className={cn('relative w-full max-w-4xl px-4 py-8', className)}\n            {...props}\n        >\n            {\/* Animated Draw-in Track Line *\/}\n            <motion.div\n                initial={{ scaleY: 0 }}\n                whileInView={{ scaleY: 1 }}\n                viewport={{ once: true, margin: '-10% 0px' }}\n                transition={{ duration: 0.8, ease: 'easeOut' }}\n                className={cn(\n                    'pointer-events-none absolute top-0 bottom-0 w-0.5 origin-top bg-linear-to-b from-primary via-primary\/50 to-border',\n                    align === 'alternate'\n                        ? 'left-1\/2 -translate-x-1\/2'\n                        : 'left-8',\n                )}\n            \/>\n\n            <div className=\"flex flex-col gap-10\">\n                {items.map((item, index) => {\n                    const isEven = index % 2 === 0;\n                    const isCompleted = item.status === 'completed';\n                    const isCurrent = item.status === 'current';\n\n                    return (\n                        <div\n                            key={item.id}\n                            className={cn(\n                                'relative flex w-full',\n                                align === 'alternate'\n                                    ? isEven\n                                        ? 'justify-start text-right'\n                                        : 'justify-end text-left'\n                                    : 'justify-end text-left',\n                            )}\n                        >\n                            {\/* Animated Node Circle *\/}\n                            <motion.div\n                                initial={{ scale: 0, opacity: 0 }}\n                                whileInView={{ scale: 1, opacity: 1 }}\n                                viewport={{ once: true, margin: '-15% 0px' }}\n                                transition={{\n                                    type: 'spring',\n                                    stiffness: 200,\n                                    damping: 15,\n                                    delay: 0.1,\n                                }}\n                                className={cn(\n                                    'absolute top-1.5 z-10 flex size-8 items-center justify-center rounded-full border bg-background shadow-xs',\n                                    align === 'alternate'\n                                        ? 'left-1\/2 -translate-x-1\/2'\n                                        : 'left-0',\n                                    isCompleted &&\n                                        'border-primary bg-primary text-primary-foreground',\n                                    isCurrent &&\n                                        'border-primary ring-2 ring-primary\/20',\n                                    !isCompleted &&\n                                        !isCurrent &&\n                                        'border-muted-foreground\/30 text-muted-foreground',\n                                )}\n                            >\n                                {item.icon ? (\n                                    <div className=\"flex size-4 items-center justify-center [&_svg]:size-4\">\n                                        {item.icon}\n                                    <\/div>\n                                ) : (\n                                    <div\n                                        className={cn(\n                                            'size-2 rounded-full',\n                                            isCompleted &&\n                                                'bg-primary-foreground',\n                                            isCurrent &&\n                                                'animate-pulse bg-primary',\n                                            !isCompleted &&\n                                                !isCurrent &&\n                                                'bg-muted-foreground\/40',\n                                        )}\n                                    \/>\n                                )}\n                            <\/motion.div>\n\n                            {\/* Animated Content Card *\/}\n                            <motion.div\n                                initial={{\n                                    opacity: 0,\n                                    x:\n                                        align === 'alternate'\n                                            ? isEven\n                                                ? -30\n                                                : 30\n                                            : 30,\n                                }}\n                                whileInView={{ opacity: 1, x: 0 }}\n                                viewport={{ once: true, margin: '-15% 0px' }}\n                                transition={{ duration: 0.5, ease: 'easeOut' }}\n                                className={cn(\n                                    'w-[calc(100%-3rem)] md:w-[calc(50%-2rem)]',\n                                    align === 'alternate'\n                                        ? ''\n                                        : 'w-[calc(100%-4rem)]',\n                                )}\n                            >\n                                <div className=\"rounded-xl border border-border bg-card p-5 shadow-xs transition-all hover:border-primary\/20 hover:shadow-md\">\n                                    <div\n                                        className={cn(\n                                            'flex flex-col gap-1 md:flex-row md:items-baseline md:justify-between',\n                                            align === 'alternate' &&\n                                                isEven &&\n                                                'md:flex-row-reverse',\n                                        )}\n                                    >\n                                        <h3 className=\"text-base font-semibold text-foreground\">\n                                            {item.title}\n                                        <\/h3>\n                                        {item.date && (\n                                            <span className=\"text-xs font-medium text-muted-foreground\">\n                                                {item.date}\n                                            <\/span>\n                                        )}\n                                    <\/div>\n                                    {item.description && (\n                                        <div className=\"mt-2 text-sm leading-relaxed text-muted-foreground\">\n                                            {item.description}\n                                        <\/div>\n                                    )}\n                                <\/div>\n                            <\/motion.div>\n                        <\/div>\n                    );\n                })}\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"timelines","version":"1.0.0"},"categories":["timelines"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"timeline-vertical","type":"registry:ui","title":"Timeline Vertical","description":"A customizable vertical timeline component with options for alternating alignment and status indicators.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils","card"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/timelines\/timeline-vertical.tsx","type":"registry:ui","content":"import * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport { Card } from '@\/components\/ui\/card';\n\nexport interface TimelineItem {\n    id: string | number;\n    title: string;\n    description?: React.ReactNode;\n    date?: string;\n    icon?: React.ReactNode;\n    status?: 'completed' | 'current' | 'upcoming';\n    tags?: string[];\n    subtasks?: { title: string; completed: boolean }[];\n    statusLabel?: string;\n}\n\ninterface TimelineVerticalProps extends React.HTMLAttributes<HTMLDivElement> {\n    items: TimelineItem[];\n    align?: 'left' | 'alternate';\n}\n\nexport function TimelineVertical({\n    items,\n    align = 'left',\n    className,\n    ...props\n}: TimelineVerticalProps) {\n    return (\n        <div\n            className={cn('relative w-full max-w-4xl px-4 py-8', className)}\n            {...props}\n        >\n            {\/* Center\/Left Track Line *\/}\n            <div\n                className={cn(\n                    'pointer-events-none absolute top-0 bottom-0 w-0.5 bg-border',\n                    align === 'alternate'\n                        ? 'left-1\/2 -translate-x-1\/2'\n                        : 'left-8',\n                )}\n            \/>\n\n            <div className=\"flex flex-col gap-8\">\n                {items.map((item, index) => {\n                    const isEven = index % 2 === 0;\n                    const isCompleted = item.status === 'completed';\n                    const isCurrent = item.status === 'current';\n\n                    return (\n                        <div\n                            key={item.id}\n                            className={cn(\n                                'relative flex w-full',\n                                align === 'alternate'\n                                    ? isEven\n                                        ? 'justify-start text-right'\n                                        : 'justify-end text-left'\n                                    : 'justify-end text-left',\n                            )}\n                        >\n                            {\/* Node Point *\/}\n                            <div\n                                className={cn(\n                                    'absolute top-1.5 z-10 flex size-8 items-center justify-center rounded-full border bg-background shadow-xs transition-colors',\n                                    align === 'alternate'\n                                        ? 'left-1\/2 -translate-x-1\/2'\n                                        : 'left-0',\n                                    isCompleted &&\n                                        'border-primary bg-primary text-primary-foreground',\n                                    isCurrent &&\n                                        'border-primary ring-2 ring-primary\/20',\n                                    !isCompleted &&\n                                        !isCurrent &&\n                                        'border-muted-foreground\/30 text-muted-foreground',\n                                )}\n                            >\n                                {item.icon ? (\n                                    <div className=\"flex size-4 items-center justify-center [&_svg]:size-4\">\n                                        {item.icon}\n                                    <\/div>\n                                ) : (\n                                    <div\n                                        className={cn(\n                                            'size-2 rounded-full',\n                                            isCompleted &&\n                                                'bg-primary-foreground',\n                                            isCurrent &&\n                                                'animate-pulse bg-primary',\n                                            !isCompleted &&\n                                                !isCurrent &&\n                                                'bg-muted-foreground\/40',\n                                        )}\n                                    \/>\n                                )}\n                            <\/div>\n\n                            {\/* Content Card Wrapper *\/}\n                            <div\n                                className={cn(\n                                    'w-[calc(100%-3rem)] md:w-[calc(50%-2rem)]',\n                                    align === 'alternate'\n                                        ? ''\n                                        : 'w-[calc(100%-4rem)]',\n                                )}\n                            >\n                                <Card className=\"border-border bg-card p-5 shadow-xs transition-all hover:shadow-md\">\n                                    <div\n                                        className={cn(\n                                            'flex flex-col gap-1 md:flex-row md:items-baseline md:justify-between',\n                                            align === 'alternate' &&\n                                                isEven &&\n                                                'md:flex-row-reverse',\n                                        )}\n                                    >\n                                        <h3 className=\"text-base font-semibold text-foreground\">\n                                            {item.title}\n                                        <\/h3>\n                                        {item.date && (\n                                            <span className=\"text-xs font-medium text-muted-foreground\">\n                                                {item.date}\n                                            <\/span>\n                                        )}\n                                    <\/div>\n                                    {item.description && (\n                                        <div className=\"mt-2 text-sm leading-relaxed text-muted-foreground\">\n                                            {item.description}\n                                        <\/div>\n                                    )}\n                                <\/Card>\n                            <\/div>\n                        <\/div>\n                    );\n                })}\n            <\/div>\n        <\/div>\n    );\n}\n"}],"meta":{"category":"timelines","version":"1.0.0"},"categories":["timelines"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"badge-indicator","type":"registry:ui","title":"Badge Indicator","description":"A clean and customizable badge indicator component with optional Lucide icon support.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/typography\/badge-indicator.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport type { LucideIcon } from 'lucide-react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface BadgeIndicatorProps extends React.HTMLAttributes<HTMLSpanElement> {\n    icon?: LucideIcon;\n    children?: React.ReactNode;\n}\n\nconst BadgeIndicator = React.forwardRef<HTMLSpanElement, BadgeIndicatorProps>(\n    ({ icon: Icon, className, children, ...props }, ref) => {\n        return (\n            <span\n                ref={ref}\n                className={cn(\n                    'inline-flex items-center gap-1.5 rounded-full border border-primary\/20 bg-primary\/5 px-3 py-1 font-mono text-[10px] font-bold tracking-widest text-primary uppercase select-none',\n                    className,\n                )}\n                {...props}\n            >\n                {Icon && <Icon className=\"size-3 shrink-0 text-primary\/80\" \/>}\n                {children}\n            <\/span>\n        );\n    },\n);\n\nBadgeIndicator.displayName = 'BadgeIndicator';\n\nexport default BadgeIndicator;\nexport { BadgeIndicator };\n"}],"meta":{"category":"typography","version":"1.0.0"},"categories":["typography"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"heading-block","type":"registry:ui","title":"Heading Block","description":"A composite title heading block containing category badge, main title, and description.","author":"designbycode","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["utils","https:\/\/ui.test\/r\/badge-indicator.json","https:\/\/ui.test\/r\/heading.json","https:\/\/ui.test\/r\/paragraph.json"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/typography\/heading-block.tsx","type":"registry:ui","content":"'use client';\n\nimport type { LucideIcon } from 'lucide-react';\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\nimport BadgeIndicator from '@\/registry\/new-york\/components\/ui\/typography\/badge-indicator';\nimport { Heading } from '@\/registry\/new-york\/components\/ui\/typography\/heading';\nimport { Paragraph } from '@\/registry\/new-york\/components\/ui\/typography\/paragraph';\n\ntype HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport interface HeadingBlockProps {\n    className?: string;\n    badge?: {\n        text: string;\n        icon?: LucideIcon;\n        className?: string;\n    };\n    heading?: React.ReactNode;\n    headingLevel?: HeadingLevel;\n    headClassName?: string;\n    description?: React.ReactNode;\n    descriptionClassName?: string;\n    children?: React.ReactNode;\n    size?: 'default' | 'sm';\n}\n\nfunction HeadingBlock({\n    badge,\n    className,\n    heading,\n    headClassName,\n    headingLevel = 1,\n    description,\n    descriptionClassName,\n    children,\n    size = 'default',\n    ...props\n}: HeadingBlockProps) {\n    return (\n        <div\n            className={cn(\n                size === 'default' && 'mb-12 max-w-2xl space-y-4',\n                size === 'sm' && 'max-w-none space-y-3',\n                className,\n            )}\n            {...props}\n        >\n            {badge && (\n                <BadgeIndicator\n                    icon={badge.icon}\n                    className={cn('mb-1', badge.className)}\n                >\n                    {badge.text}\n                <\/BadgeIndicator>\n            )}\n            {heading && (\n                <Heading\n                    level={headingLevel}\n                    className={cn(\n                        'font-extrabold tracking-tight text-foreground',\n                        headClassName,\n                    )}\n                >\n                    {heading}\n                <\/Heading>\n            )}\n            {description && (\n                <Paragraph\n                    variant={size === 'default' ? 'lead' : 'muted'}\n                    className={cn('font-sans', descriptionClassName)}\n                >\n                    {description}\n                <\/Paragraph>\n            )}\n            {children}\n        <\/div>\n    );\n}\n\nexport default HeadingBlock;\nexport { HeadingBlock };\n"}],"meta":{"category":"typography","version":"1.0.0"},"categories":["typography"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"heading","type":"registry:ui","title":"Heading","description":"A structured typographic heading component supporting levels 1 to 6.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/typography\/heading.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport interface HeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {\n    level?: HeadingLevel;\n}\n\nconst headingStyles: Record<HeadingLevel, string> = {\n    1: 'scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl text-foreground',\n    2: 'scroll-m-20 border-b border-border\/30 pb-2 text-3xl font-semibold tracking-tight first:mt-0 text-foreground',\n    3: 'scroll-m-20 text-2xl font-semibold tracking-tight text-foreground',\n    4: 'scroll-m-20 text-xl font-semibold tracking-tight text-foreground',\n    5: 'scroll-m-20 text-lg font-semibold tracking-tight text-foreground',\n    6: 'scroll-m-20 text-base font-semibold tracking-tight text-foreground',\n};\n\nconst Heading = React.forwardRef<HTMLHeadingElement, HeadingProps>(\n    ({ level = 1, className, children, ...props }, ref) => {\n        const Tag = `h${level}` as const;\n\n        return (\n            <Tag\n                ref={ref}\n                className={cn(headingStyles[level], className)}\n                {...props}\n            >\n                {children}\n            <\/Tag>\n        );\n    },\n);\n\nHeading.displayName = 'Heading';\n\nexport { Heading };\n"}],"meta":{"category":"typography","version":"1.0.0"},"categories":["typography"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"paragraph","type":"registry:ui","title":"Paragraph","description":"A versatile paragraph text component supporting default, lead, and muted layout variants.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["utils"],"files":[{"path":"resources\/js\/registry\/new-york\/components\/ui\/typography\/paragraph.tsx","type":"registry:ui","content":"'use client';\n\nimport * as React from 'react';\nimport { cn } from '@\/lib\/utils';\n\nexport interface ParagraphProps extends React.HTMLAttributes<HTMLParagraphElement> {\n    variant?: 'default' | 'lead' | 'muted' | 'large' | 'small';\n}\n\nconst paragraphStyles = {\n    default: 'leading-7 [&:not(:first-child)]:mt-6 text-foreground\/80',\n    lead: 'text-xl text-muted-foreground font-light leading-relaxed',\n    muted: 'text-sm text-muted-foreground leading-normal',\n    large: 'text-lg font-semibold text-foreground',\n    small: 'text-sm font-medium leading-none text-foreground\/75',\n};\n\nconst Paragraph = React.forwardRef<HTMLParagraphElement, ParagraphProps>(\n    ({ variant = 'default', className, children, ...props }, ref) => {\n        return (\n            <p\n                ref={ref}\n                className={cn(paragraphStyles[variant], className)}\n                {...props}\n            >\n                {children}\n            <\/p>\n        );\n    },\n);\n\nParagraph.displayName = 'Paragraph';\n\nexport { Paragraph };\n"}],"meta":{"category":"typography","version":"1.0.0"},"categories":["typography"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"use-dark-mode","type":"registry:hook","title":"Use Dark Mode","description":"A React hook detecting and toggling light\/dark system color schemes.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":[],"files":[{"path":"resources\/js\/registry\/new-york\/hooks\/use-dark-mode.ts","type":"registry:hook","content":"import { useSyncExternalStore } from 'react';\n\nfunction getSnapshot(): boolean {\n    return document.documentElement.classList.contains('dark');\n}\n\nfunction getServerSnapshot(): boolean {\n    return false;\n}\n\nfunction subscribe(callback: () => void): () => void {\n    const observer = new MutationObserver(callback);\n\n    observer.observe(document.documentElement, {\n        attributes: true,\n        attributeFilter: ['class'],\n    });\n\n    return () => {\n        observer.disconnect();\n    };\n}\n\nfunction useDarkMode(): boolean {\n    return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\nexport default useDarkMode;\n"}],"meta":{"category":"hooks","version":"1.0.0"},"categories":["hooks"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"use-headroom","type":"registry:hook","title":"Use Headroom","description":"A React scroll hook enabling\/disabling visibility of nav headers based on scroll direction.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":[],"files":[{"path":"resources\/js\/registry\/new-york\/hooks\/use-headroom.ts","type":"registry:hook","content":"'use client';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface ToleranceConfig {\n    up: number;\n    down: number;\n}\n\nexport interface UseHeadroomOptions {\n    enabled?: boolean;\n    offset?: number;\n    tolerance?: number | ToleranceConfig;\n    scroller?: Element | null;\n}\n\n\/**\n * useHeadroom - A React hook that replicates headroom.js behavior.\n *\n * Returns an object with CSS class flags based on scroll direction and position,\n * plus a ref to attach to your header element (for scroll offset calculation).\n *\n * @param {Object} options\n * @param {boolean} [options.enabled=true]    - Enable\/disable the headroom behavior. When false, header is always pinned.\n * @param {number} [options.offset=0]        - Scroll distance (px) before the hook activates.\n * @param {number} [options.tolerance=0]     - Scroll delta (px) required to trigger a state change.\n *                                             Can also be { up: number, down: number }.\n * @param {Element|null} [options.scroller]  - Scrollable element to listen on (default: window).\n *\n * @returns {{\n *   ref: React.RefObject,   - Attach this to your header element.\n *   pinned: boolean,        - true when header should be visible (scroll up or at top).\n *   unpinned: boolean,      - true when header should be hidden (scroll down).\n *   top: boolean,          - true when at the very top (within offset).\n *   notTop: boolean,       - true when scrolled past offset.\n *   bottom: boolean,       - true when at the bottom of the page\/scroller.\n *   notBottom: boolean,    - true when not at the bottom.\n * }}\n *\n *\/\nfunction useHeadroom({\n    enabled = true,\n    offset = 0,\n    tolerance = 0,\n    scroller = null,\n}: UseHeadroomOptions = {}) {\n    const ref = useRef(null);\n\n    const getInitialState = useCallback(\n        () => ({\n            pinned: true,\n            unpinned: false,\n            top: true,\n            notTop: false,\n            bottom: false,\n            notBottom: true,\n        }),\n        [],\n    );\n\n    const [state, setState] = useState(getInitialState);\n\n    \/\/ Normalize tolerance into { up, down }\n    const getTolerance = useCallback((): ToleranceConfig => {\n        if (typeof tolerance === 'number') {\n            return { up: tolerance, down: tolerance };\n        }\n\n        return tolerance;\n    }, [tolerance]);\n\n    useEffect(() => {\n        if (!enabled) {\n            return;\n        }\n\n        const scrollEl = scroller ?? window;\n\n        const getScrollY = () =>\n            scrollEl instanceof Element\n                ? scrollEl.scrollTop\n                : (window.scrollY ?? window.pageYOffset);\n\n        const getScrollHeight = () =>\n            scrollEl instanceof Element\n                ? scrollEl.scrollHeight\n                : document.documentElement.scrollHeight;\n\n        const getClientHeight = () =>\n            scrollEl instanceof Element\n                ? scrollEl.clientHeight\n                : window.innerHeight;\n\n        let lastScrollY = getScrollY();\n        let ticking = false;\n\n        const update = () => {\n            const currentScrollY = getScrollY();\n            const scrollHeight = getScrollHeight();\n            const clientHeight = getClientHeight();\n            const tolerances = getTolerance();\n\n            const isTop = currentScrollY <= offset;\n            const isBottom = currentScrollY + clientHeight >= scrollHeight - 1;\n            const delta = currentScrollY - lastScrollY;\n            const scrollingDown = delta > 0;\n            const scrollingUp = delta < 0;\n\n            \/\/ Determine pin\/unpin only when tolerance is exceeded\n            setState((prev) => {\n                let pinned = prev.pinned;\n\n                if (isTop) {\n                    \/\/ Always pin at the top\n                    pinned = true;\n                } else if (\n                    scrollingDown &&\n                    Math.abs(delta) >= tolerances.down\n                ) {\n                    pinned = false;\n                } else if (scrollingUp && Math.abs(delta) >= tolerances.up) {\n                    pinned = true;\n                }\n\n                return {\n                    pinned,\n                    unpinned: !pinned,\n                    top: isTop,\n                    notTop: !isTop,\n                    bottom: isBottom,\n                    notBottom: !isBottom,\n                };\n            });\n\n            lastScrollY = currentScrollY;\n            ticking = false;\n        };\n\n        const onScroll = () => {\n            if (!ticking) {\n                requestAnimationFrame(update);\n                ticking = true;\n            }\n        };\n\n        scrollEl.addEventListener('scroll', onScroll, { passive: true });\n\n        \/\/ Run once on mount to set initial state\n        update();\n\n        return () => {\n            scrollEl.removeEventListener('scroll', onScroll);\n        };\n    }, [enabled, offset, getTolerance, scroller]);\n\n    return { ref, ...state };\n}\n\nexport default useHeadroom;\n"}],"meta":{"category":"hooks","version":"1.0.0"},"categories":["hooks"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"use-hover","type":"registry:hook","title":"Use Hover","description":"A ref-bound React hover hook managing mouse entrance and exit event states.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":[],"files":[{"path":"resources\/js\/registry\/new-york\/hooks\/use-hover.tsx","type":"registry:hook","content":"'use client';\nimport { useCallback, useState } from 'react';\n\nexport function useHover() {\n    const [isHovered, setIsHovered] = useState(false);\n\n    const hoverRef = useCallback((node: HTMLElement | null) => {\n        if (!node) {\n            return;\n        }\n\n        node.onmouseenter = () => setIsHovered(true);\n        node.onmouseleave = () => setIsHovered(false);\n    }, []);\n\n    return { isHovered, hoverRef };\n}\n"}],"meta":{"category":"hooks","version":"1.0.0"},"categories":["hooks"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"use-pixel-canvas","type":"registry:hook","title":"Use Pixel Canvas","description":"A helper hook handling pixel drawing mathematics for the Pixel Canvas component.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":["https:\/\/ui.test\/r\/pixel-canvas-helper.json"],"files":[{"path":"resources\/js\/registry\/new-york\/hooks\/use-pixel-canvas.ts","type":"registry:hook","content":"'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type {\n    AnimationDirection,\n    PixelConfig,\n    PixelState,\n} from '@\/registry\/new-york\/lib\/pixel-canvas-helper';\nimport {\n    calculateDelay,\n    createPixelState,\n    defaultPixelConfig,\n    drawPixel,\n    updatePixelAppear,\n    updatePixelDisappear,\n} from '@\/registry\/new-york\/lib\/pixel-canvas-helper';\n\ninterface UsePixelCanvasOptions extends Partial<PixelConfig> {\n    \/**\n     * Controls whether animation runs continuously\n     * - When true: animation runs automatically and continuously\n     * - When false: animation only runs when triggered via JS or mouse\n     *\/\n    active?: boolean;\n    \/**\n     * Enable mouse interaction (hover triggers animation)\n     * - When true: mouseenter triggers appear, mouseleave triggers disappear\n     * - When false: mouse events are ignored\n     *\/\n    mouseActive?: boolean;\n    \/** @deprecated Use `active` instead. Auto-start animation on mount *\/\n    autoStart?: boolean;\n    \/** @deprecated Use `mouseActive` instead. Trigger animation on hover *\/\n    hoverTrigger?: boolean;\n}\n\ninterface UsePixelCanvasReturn {\n    canvasRef: React.RefObject<HTMLCanvasElement | null>;\n    containerRef: React.RefObject<HTMLDivElement | null>;\n    isAnimating: boolean;\n    triggerAppear: () => void;\n    triggerDisappear: () => void;\n    reset: () => void;\n}\n\nexport function usePixelCanvas(\n    options: UsePixelCanvasOptions = {},\n): UsePixelCanvasReturn {\n    const config: PixelConfig = { ...defaultPixelConfig, ...options };\n\n    \/\/ Handle both old and new prop names for backwards compatibility\n    const {\n        active,\n        mouseActive,\n        autoStart = false,\n        hoverTrigger = true,\n    } = options;\n\n    \/\/ New props take precedence over deprecated ones\n    const shouldAutoStart = active ?? autoStart;\n    const shouldReactToMouse = mouseActive ?? hoverTrigger;\n\n    const canvasRef = useRef<HTMLCanvasElement | null>(null);\n    const containerRef = useRef<HTMLDivElement | null>(null);\n    const pixelsRef = useRef<PixelState[]>([]);\n    const animationRef = useRef<number | null>(null);\n    const directionRef = useRef<AnimationDirection>('appear');\n    const isInitializedRef = useRef(false);\n    const activeRef = useRef(shouldAutoStart);\n    const [isAnimating, setIsAnimating] = useState(false);\n\n    const speedMultiplier = config.speed * 0.001;\n\n    \/\/ Keep activeRef in sync with prop\n    useEffect(() => {\n        activeRef.current = shouldAutoStart;\n    }, [shouldAutoStart]);\n\n    const initPixels = useCallback(() => {\n        const canvas = canvasRef.current;\n\n        if (!canvas) {\n            return;\n        }\n\n        const ctx = canvas.getContext('2d');\n\n        if (!ctx) {\n            return;\n        }\n\n        const rect = canvas.getBoundingClientRect();\n        const width = Math.floor(rect.width);\n        const height = Math.floor(rect.height);\n\n        if (width <= 0 || height <= 0) {\n            return;\n        }\n\n        \/\/ Set canvas size with device pixel ratio for crisp rendering\n        const dpr = Math.min(window.devicePixelRatio || 1, 2);\n        canvas.width = width * dpr;\n        canvas.height = height * dpr;\n        canvas.style.width = `${width}px`;\n        canvas.style.height = `${height}px`;\n        ctx.scale(dpr, dpr);\n\n        const pixels: PixelState[] = [];\n        const reducedMotion = window.matchMedia(\n            '(prefers-reduced-tabs: reduce)',\n        ).matches;\n\n        for (let x = 0; x < width; x += config.gap) {\n            for (let y = 0; y < height; y += config.gap) {\n                const color =\n                    config.colors[\n                        Math.floor(Math.random() * config.colors.length)\n                    ];\n                const delay = reducedMotion\n                    ? 0\n                    : calculateDelay(x, y, width, height, config.animationType);\n\n                pixels.push(\n                    createPixelState(\n                        x,\n                        y,\n                        color,\n                        delay,\n                        speedMultiplier,\n                        config.minSize,\n                        config.maxSize,\n                        width,\n                        height,\n                    ),\n                );\n            }\n        }\n\n        pixelsRef.current = pixels;\n        isInitializedRef.current = true;\n    }, [\n        config.gap,\n        config.colors,\n        config.animationType,\n        config.minSize,\n        config.maxSize,\n        speedMultiplier,\n    ]);\n\n    const animateRef = useRef<() => void>(() => {});\n\n    const animate = useCallback(() => {\n        const canvas = canvasRef.current;\n\n        if (!canvas) {\n            return;\n        }\n\n        const ctx = canvas.getContext('2d');\n\n        if (!ctx) {\n            return;\n        }\n\n        const dpr = Math.min(window.devicePixelRatio || 1, 2);\n        const width = canvas.width \/ dpr;\n        const height = canvas.height \/ dpr;\n\n        ctx.clearRect(0, 0, width, height);\n\n        let allIdle = true;\n        const direction = directionRef.current;\n\n        pixelsRef.current = pixelsRef.current.map((pixel) => {\n            let updated: PixelState;\n\n            if (direction === 'appear') {\n                updated = updatePixelAppear(pixel, config.shimmerIntensity);\n            } else {\n                updated = updatePixelDisappear(pixel);\n            }\n\n            \/\/ Draw pixel if it has size > 0 (clamp to prevent negative values)\n            const safeSize = Math.max(0, updated.size);\n\n            if (safeSize > 0.01) {\n                allIdle = false;\n                drawPixel(\n                    ctx,\n                    updated.x,\n                    updated.y,\n                    safeSize,\n                    config.maxSize,\n                    updated.color,\n                    config.shape,\n                );\n            } else if (!updated.isIdle) {\n                allIdle = false;\n            }\n\n            return updated;\n        });\n\n        \/\/ For disappear: stop when all pixels are gone\n        \/\/ For appear: never stop - keep shimmering\n        if (direction === 'disappear' && allIdle) {\n            setIsAnimating(false);\n\n            if (animationRef.current) {\n                cancelAnimationFrame(animationRef.current);\n                animationRef.current = null;\n            }\n\n            \/\/ Reset pixels for next appear animation\n            initPixels();\n\n            return;\n        }\n\n        animationRef.current = requestAnimationFrame(animateRef.current);\n    }, [config.shimmerIntensity, config.maxSize, config.shape, initPixels]);\n\n    useEffect(() => {\n        animateRef.current = animate;\n    }, [animate]);\n\n    const startAnimation = useCallback(\n        (direction: AnimationDirection) => {\n            \/\/ If disappearing, just change direction - don't reinit\n            if (direction === 'disappear') {\n                directionRef.current = direction;\n\n                if (!animationRef.current) {\n                    setIsAnimating(true);\n                    animationRef.current = requestAnimationFrame(animate);\n                }\n\n                return;\n            }\n\n            \/\/ For appear, always reset pixel states for fresh animation\n            initPixels();\n\n            directionRef.current = direction;\n            setIsAnimating(true);\n\n            if (animationRef.current) {\n                cancelAnimationFrame(animationRef.current);\n            }\n\n            animationRef.current = requestAnimationFrame(animate);\n        },\n        [animate, initPixels],\n    );\n\n    const triggerAppear = useCallback(() => {\n        startAnimation('appear');\n    }, [startAnimation]);\n\n    const triggerDisappear = useCallback(() => {\n        startAnimation('disappear');\n    }, [startAnimation]);\n\n    const reset = useCallback(() => {\n        if (animationRef.current) {\n            cancelAnimationFrame(animationRef.current);\n            animationRef.current = null;\n        }\n\n        setIsAnimating(false);\n        directionRef.current = 'appear';\n        initPixels();\n\n        const canvas = canvasRef.current;\n\n        if (canvas) {\n            const ctx = canvas.getContext('2d');\n\n            if (ctx) {\n                const dpr = Math.min(window.devicePixelRatio || 1, 2);\n                ctx.clearRect(0, 0, canvas.width \/ dpr, canvas.height \/ dpr);\n            }\n        }\n    }, [initPixels]);\n\n    \/\/ Initialize and handle resize\n    useEffect(() => {\n        initPixels();\n\n        const container = containerRef.current;\n\n        if (!container) {\n            return;\n        }\n\n        const resizeObserver = new ResizeObserver(() => {\n            initPixels();\n\n            \/\/ Restart animation if it was running and we're in active mode\n            if (activeRef.current && animationRef.current) {\n                triggerAppear();\n            }\n        });\n\n        resizeObserver.observe(container);\n\n        return () => {\n            resizeObserver.disconnect();\n\n            if (animationRef.current) {\n                cancelAnimationFrame(animationRef.current);\n            }\n        };\n    }, [initPixels, triggerAppear]);\n\n    \/\/ Handle mouse events\n    useEffect(() => {\n        if (!shouldReactToMouse) {\n            return;\n        }\n\n        const container = containerRef.current;\n\n        if (!container) {\n            return;\n        }\n\n        const handleMouseEnter = () => {\n            \/\/ Reset and start fresh appear animation\n            triggerAppear();\n        };\n\n        const handleMouseLeave = () => {\n            triggerDisappear();\n        };\n\n        container.addEventListener('mouseenter', handleMouseEnter);\n        container.addEventListener('mouseleave', handleMouseLeave);\n\n        if (!config.noFocus) {\n            container.addEventListener('focusin', handleMouseEnter);\n            container.addEventListener('focusout', handleMouseLeave);\n        }\n\n        return () => {\n            container.removeEventListener('mouseenter', handleMouseEnter);\n            container.removeEventListener('mouseleave', handleMouseLeave);\n            container.removeEventListener('focusin', handleMouseEnter);\n            container.removeEventListener('focusout', handleMouseLeave);\n        };\n    }, [shouldReactToMouse, config.noFocus, triggerAppear, triggerDisappear]);\n\n    \/\/ Handle active prop - continuous animation\n    useEffect(() => {\n        if (shouldAutoStart) {\n            \/\/ eslint-disable-next-line react-hooks\/set-state-in-effect\n            startAnimation('appear');\n        } else if (!shouldReactToMouse) {\n            \/\/ If neither active nor mouseActive, clear canvas\n            reset();\n        }\n    }, [shouldAutoStart, shouldReactToMouse, startAnimation, reset]);\n\n    return {\n        canvasRef,\n        containerRef,\n        isAnimating,\n        triggerAppear,\n        triggerDisappear,\n        reset,\n    };\n}\n"}],"meta":{"category":"hooks","version":"1.0.0"},"categories":["hooks"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"audio-context","type":"registry:lib","title":"Audio Context","description":"A browser Web Audio API manager providing playback nodes for the music player.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":[],"files":[{"path":"resources\/js\/registry\/new-york\/lib\/audio-context.ts","type":"registry:lib","content":"export interface Track {\n    id: string;\n    title: string;\n    artist: string;\n    album: string;\n    duration: number;\n    src: string;\n    coverUrl?: string;\n}\n\nexport interface Playlist {\n    id: string;\n    name: string;\n    tracks: Track[];\n    coverUrl?: string;\n}\n\nexport const sampleTracks: Track[] = [\n    {\n        id: '1',\n        title: 'Cold Steel Sheets',\n        artist: 'Iron & Oak',\n        album: 'Forged',\n        duration: 475,\n        src: '\/music\/cold-steel-sheets.mp3',\n        coverUrl:\n            'https:\/\/images.unsplash.com\/photo-1614149162883-504ce4d13909?w=400&h=400&fit=crop',\n    },\n    {\n        id: '2',\n        title: 'Laughter at the Gale',\n        artist: 'Storm Chaser',\n        album: 'Braving the Wind',\n        duration: 353,\n        src: '\/music\/laughter-at-the-gale.mp3',\n        coverUrl:\n            'https:\/\/images.unsplash.com\/photo-1557672172-298e090bd0f1?w=400&h=400&fit=crop',\n    },\n    {\n        id: '3',\n        title: 'Roses in the Sink',\n        artist: 'Violet Glass',\n        album: 'Fading Petals',\n        duration: 393,\n        src: '\/music\/roses-in-the-sink.mp3',\n        coverUrl:\n            'https:\/\/images.unsplash.com\/photo-1518837695005-2083093ee35b?w=400&h=400&fit=crop',\n    },\n    {\n        id: '4',\n        title: \"Storm Walker's Oath\",\n        artist: 'Thunder Pass',\n        album: 'The Reckoning',\n        duration: 462,\n        src: '\/music\/storm-walkers-oath.mp3',\n        coverUrl:\n            'https:\/\/images.unsplash.com\/photo-1549317661-bd32c8ce0db2?w=400&h=400&fit=crop',\n    },\n    {\n        id: '5',\n        title: 'The Empty Chair',\n        artist: 'Silent Hollow',\n        album: 'Left Behind',\n        duration: 259,\n        src: '\/music\/the-empty-chair.mp3',\n        coverUrl:\n            'https:\/\/images.unsplash.com\/photo-1462331940025-496dfbfc7564?w=400&h=400&fit=crop',\n    },\n];\n\nexport const samplePlaylists: Playlist[] = [\n    {\n        id: '1',\n        name: 'Chill Vibes',\n        tracks: [sampleTracks[0], sampleTracks[2], sampleTracks[4]],\n        coverUrl: sampleTracks[0].coverUrl,\n    },\n    {\n        id: '2',\n        name: 'Dark & Stormy',\n        tracks: [sampleTracks[1], sampleTracks[3]],\n        coverUrl: sampleTracks[1].coverUrl,\n    },\n    {\n        id: '3',\n        name: 'All Tracks',\n        tracks: sampleTracks,\n        coverUrl: sampleTracks[3].coverUrl,\n    },\n];\n\nexport type VisualizerStyle = 'bars' | 'wave' | 'circular' | 'particles';\n\nexport const formatTime = (seconds: number): string => {\n    const mins = Math.floor(seconds \/ 60);\n    const secs = Math.floor(seconds % 60);\n\n    return `${mins}:${secs.toString().padStart(2, '0')}`;\n};\n"}],"meta":{"category":"lib","version":"1.0.0"},"categories":["lib"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"glow-geometry","type":"registry:lib","title":"Glow Geometry","description":"A helper library managing mouse coordinate tracking for glow wrappers.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":[],"files":[{"path":"resources\/js\/registry\/new-york\/lib\/glow-geometry.ts","type":"registry:lib","content":"export interface Point {\n    x: number;\n    y: number;\n}\nexport interface Rect {\n    left: number;\n    right: number;\n    top: number;\n    bottom: number;\n}\n\nexport const isCircleOverlappingRect = (p: Point, r: number, rect: Rect) =>\n    p.x + r >= rect.left &&\n    p.x - r <= rect.right &&\n    p.y + r >= rect.top &&\n    p.y - r <= rect.bottom;\n\nexport const isPointInRect = (p: Point, rect: Rect) =>\n    p.x >= rect.left &&\n    p.x <= rect.right &&\n    p.y >= rect.top &&\n    p.y <= rect.bottom;\n\nexport const toElementSpace = (p: Point, rect: Rect): Point => ({\n    x: p.x - rect.left,\n    y: p.y - rect.top,\n});\n"}],"meta":{"category":"lib","version":"1.0.0"},"categories":["lib"]},{"$schema":"https:\/\/ui.shadcn.com\/schema\/registry-item.json","name":"pixel-canvas-helper","type":"registry:lib","title":"Pixel Canvas Helper","description":"A mathematical helper module driving pixel animations for the Pixel Canvas.","author":"designbycode","dependencies":[],"devDependencies":[],"registryDependencies":[],"files":[{"path":"resources\/js\/registry\/new-york\/lib\/pixel-canvas-helper.ts","type":"registry:lib","content":"export type PixelShape = 'square' | 'circle' | 'diamond' | 'star' | 'hexagon';\n\nexport type AnimationType =\n    'radial' | 'wave' | 'random' | 'diagonal' | 'spiral';\n\nexport type AnimationDirection = 'appear' | 'disappear';\n\nexport interface PixelConfig {\n    \/** Array of colors for pixels *\/\n    colors: string[];\n    \/** Gap between pixels in pixels *\/\n    gap: number;\n    \/** Animation speed (0-100) *\/\n    speed: number;\n    \/** Minimum pixel size *\/\n    minSize: number;\n    \/** Maximum pixel size *\/\n    maxSize: number;\n    \/** Shimmer intensity (0-1) *\/\n    shimmerIntensity: number;\n    \/** Shape of pixels *\/\n    shape: PixelShape;\n    \/** Animation pattern type *\/\n    animationType: AnimationType;\n    \/** Whether to disable focus events *\/\n    noFocus: boolean;\n}\n\nexport interface PixelState {\n    x: number;\n    y: number;\n    color: string;\n    size: number;\n    maxSize: number;\n    minSize: number;\n    speed: number;\n    delay: number;\n    sizeStep: number;\n    counter: number;\n    counterStep: number;\n    isIdle: boolean;\n    isReverse: boolean;\n    isShimmer: boolean;\n}\n\nexport const defaultPixelConfig: PixelConfig = {\n    colors: ['#f8fafc', '#f1f5f9', '#cbd5e1'],\n    gap: 6,\n    speed: 35,\n    minSize: 0.5,\n    maxSize: 2,\n    shimmerIntensity: 0.5,\n    shape: 'square',\n    animationType: 'radial',\n    noFocus: false,\n};\n\n\/\/ Preset color palettes\nexport const colorPresets = {\n    slate: ['#f8fafc', '#f1f5f9', '#cbd5e1'],\n    blue: ['#dbeafe', '#93c5fd', '#3b82f6'],\n    emerald: ['#d1fae5', '#6ee7b7', '#10b981'],\n    amber: ['#fef3c7', '#fcd34d', '#f59e0b'],\n    rose: ['#ffe4e6', '#fda4af', '#f43f5e'],\n    violet: ['#ede9fe', '#c4b5fd', '#8b5cf6'],\n    cyan: ['#cffafe', '#67e8f9', '#06b6d4'],\n    sunset: ['#fef3c7', '#fdba74', '#f97316'],\n    ocean: ['#cffafe', '#7dd3fc', '#0ea5e9'],\n    forest: ['#dcfce7', '#86efac', '#22c55e'],\n    neon: ['#f0fdf4', '#4ade80', '#22d3ee'],\n    midnight: ['#1e293b', '#334155', '#475569'],\n};\n\nexport function getRandomValue(min: number, max: number): number {\n    return Math.random() * (max - min) + min;\n}\n\nexport function clampValue(value: number, min: number, max: number): number {\n    return Math.min(Math.max(value, min), max);\n}\n\n\/** Maximum delay cap in milliseconds to ensure responsive animations *\/\nconst MAX_DELAY = 1200;\n\n\/**\n * Calculate delay based on animation type\n * All delays are capped at MAX_DELAY to ensure responsive animations\n *\/\nexport function calculateDelay(\n    x: number,\n    y: number,\n    canvasWidth: number,\n    canvasHeight: number,\n    animationType: AnimationType,\n): number {\n    let delay: number;\n\n    switch (animationType) {\n        case 'radial': {\n            const dx = x - canvasWidth \/ 2;\n            const dy = y - canvasHeight \/ 2;\n            delay = Math.sqrt(dx * dx + dy * dy);\n            break;\n        }\n        case 'wave': {\n            delay = x + y * 0.5;\n            break;\n        }\n        case 'random': {\n            delay =\n                Math.random() *\n                Math.min(MAX_DELAY, Math.max(canvasWidth, canvasHeight));\n            break;\n        }\n        case 'diagonal': {\n            delay = (x + y) * 0.7;\n            break;\n        }\n        case 'spiral': {\n            const dx = x - canvasWidth \/ 2;\n            const dy = y - canvasHeight \/ 2;\n            const angle = Math.atan2(dy, dx);\n            const distance = Math.sqrt(dx * dx + dy * dy);\n            delay = distance + angle * 50;\n            break;\n        }\n        default:\n            delay = 0;\n    }\n\n    \/\/ Normalize delay to be within 0 to MAX_DELAY range\n    const maxRawDelay = Math.sqrt(\n        canvasWidth * canvasWidth + canvasHeight * canvasHeight,\n    );\n    const normalizedDelay = (delay \/ maxRawDelay) * MAX_DELAY;\n\n    return Math.min(normalizedDelay, MAX_DELAY);\n}\n\n\/**\n * Draw pixel with specified shape\n *\/\nexport function drawPixel(\n    ctx: CanvasRenderingContext2D,\n    x: number,\n    y: number,\n    size: number,\n    maxSize: number,\n    color: string,\n    shape: PixelShape,\n): void {\n    \/\/ Ensure size is never negative\n    const safeSize = Math.max(0, size);\n\n    if (safeSize <= 0) {\n        return;\n    }\n\n    const centerOffset = maxSize * 0.5 - safeSize * 0.5;\n    const cx = x + centerOffset + safeSize \/ 2;\n    const cy = y + centerOffset + safeSize \/ 2;\n\n    ctx.fillStyle = color;\n\n    switch (shape) {\n        case 'square':\n            ctx.fillRect(\n                x + centerOffset,\n                y + centerOffset,\n                safeSize,\n                safeSize,\n            );\n            break;\n\n        case 'circle':\n            ctx.beginPath();\n            ctx.arc(cx, cy, safeSize \/ 2, 0, Math.PI * 2);\n            ctx.fill();\n            break;\n\n        case 'diamond':\n            ctx.beginPath();\n            ctx.moveTo(cx, cy - safeSize \/ 2);\n            ctx.lineTo(cx + safeSize \/ 2, cy);\n            ctx.lineTo(cx, cy + safeSize \/ 2);\n            ctx.lineTo(cx - safeSize \/ 2, cy);\n            ctx.closePath();\n            ctx.fill();\n            break;\n\n        case 'star': {\n            const spikes = 5;\n            const outerRadius = safeSize \/ 2;\n            const innerRadius = safeSize \/ 4;\n            ctx.beginPath();\n\n            for (let i = 0; i < spikes * 2; i++) {\n                const radius = i % 2 === 0 ? outerRadius : innerRadius;\n                const angle = (i * Math.PI) \/ spikes - Math.PI \/ 2;\n                const px = cx + Math.cos(angle) * radius;\n                const py = cy + Math.sin(angle) * radius;\n\n                if (i === 0) {\n                    ctx.moveTo(px, py);\n                } else {\n                    ctx.lineTo(px, py);\n                }\n            }\n\n            ctx.closePath();\n            ctx.fill();\n            break;\n        }\n\n        case 'hexagon': {\n            const sides = 6;\n            const radius = safeSize \/ 2;\n            ctx.beginPath();\n\n            for (let i = 0; i < sides; i++) {\n                const angle = (i * Math.PI * 2) \/ sides - Math.PI \/ 2;\n                const px = cx + Math.cos(angle) * radius;\n                const py = cy + Math.sin(angle) * radius;\n\n                if (i === 0) {\n                    ctx.moveTo(px, py);\n                } else {\n                    ctx.lineTo(px, py);\n                }\n            }\n\n            ctx.closePath();\n            ctx.fill();\n            break;\n        }\n    }\n}\n\n\/**\n * Create initial pixel state\n *\/\nexport function createPixelState(\n    x: number,\n    y: number,\n    color: string,\n    delay: number,\n    speed: number,\n    minSize: number,\n    maxSize: number,\n    canvasWidth: number,\n    canvasHeight: number,\n): PixelState {\n    return {\n        x,\n        y,\n        color,\n        size: 0,\n        maxSize: getRandomValue(minSize, maxSize),\n        minSize,\n        speed: getRandomValue(0.1, 0.9) * speed,\n        delay,\n        sizeStep: Math.random() * 0.4,\n        counter: 0,\n        counterStep: Math.random() * 4 + (canvasWidth + canvasHeight) * 0.01,\n        isIdle: false,\n        isReverse: false,\n        isShimmer: false,\n    };\n}\n\n\/**\n * Update pixel state for appear animation\n *\/\nexport function updatePixelAppear(\n    pixel: PixelState,\n    shimmerIntensity: number,\n): PixelState {\n    const updated = { ...pixel, isIdle: false };\n\n    if (updated.counter <= updated.delay) {\n        updated.counter += updated.counterStep;\n\n        return updated;\n    }\n\n    if (updated.size >= updated.maxSize) {\n        updated.isShimmer = true;\n    }\n\n    if (updated.isShimmer) {\n        return updatePixelShimmer(updated, shimmerIntensity);\n    } else {\n        updated.size += updated.sizeStep;\n    }\n\n    return updated;\n}\n\n\/**\n * Update pixel state for disappear animation\n *\/\nexport function updatePixelDisappear(pixel: PixelState): PixelState {\n    const updated = { ...pixel, isShimmer: false, counter: 0 };\n\n    if (updated.size <= 0) {\n        updated.isIdle = true;\n        updated.size = 0;\n\n        return updated;\n    }\n\n    updated.size = Math.max(0, updated.size - 0.1);\n\n    return updated;\n}\n\n\/**\n * Update pixel shimmer effect\n *\/\nexport function updatePixelShimmer(\n    pixel: PixelState,\n    intensity: number,\n): PixelState {\n    const updated = { ...pixel };\n    const shimmerSpeed = updated.speed * intensity;\n\n    \/\/ Ensure minSize is at least 0.1 to prevent negative sizes\n    const safeMinSize = Math.max(0.1, updated.minSize);\n\n    if (updated.size >= updated.maxSize) {\n        updated.isReverse = true;\n    } else if (updated.size <= safeMinSize) {\n        updated.isReverse = false;\n        updated.size = safeMinSize; \/\/ Ensure we don't go below minSize\n    }\n\n    if (updated.isReverse) {\n        updated.size -= shimmerSpeed;\n    } else {\n        updated.size += shimmerSpeed;\n    }\n\n    \/\/ Clamp size to prevent negative values and keep within bounds\n    updated.size = Math.max(\n        safeMinSize,\n        Math.min(updated.size, updated.maxSize * 1.2),\n    );\n\n    return updated;\n}\n"}],"meta":{"category":"lib","version":"1.0.0"},"categories":["lib"]}]}