diff --git a/app/(admin)/_components/header.tsx b/app/(admin)/_components/header.tsx
new file mode 100644
index 0000000..7bc7ac6
--- /dev/null
+++ b/app/(admin)/_components/header.tsx
@@ -0,0 +1,211 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+import { usePathname, useRouter } from "next/navigation";
+import { Button } from "@/components/ui/button";
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@/components/ui/popover";
+import {
+ Inbox,
+ Calendar,
+ LayoutGrid,
+ Heart,
+ UserCog,
+ Bell,
+ Settings,
+ LogOut,
+} from "lucide-react";
+
+export function Header() {
+ const pathname = usePathname();
+ const router = useRouter();
+ const [notificationsOpen, setNotificationsOpen] = useState(false);
+ const [userMenuOpen, setUserMenuOpen] = useState(false);
+
+ // Mock notifications data
+ const notifications = [
+ {
+ id: 1,
+ title: "New appointment scheduled",
+ message: "John Smith booked an appointment for tomorrow",
+ time: "2 hours ago",
+ type: "info",
+ read: false,
+ },
+ {
+ id: 2,
+ title: "Payment received",
+ message: "Payment of $150 received from Jane Doe",
+ time: "5 hours ago",
+ type: "success",
+ read: false,
+ },
+ ];
+
+ const unreadCount = notifications.filter((n) => !n.read).length;
+
+ return (
+
+
+
+ {/* Logo */}
+
+
+
+
+
Attune Heart
+
+
+ {/* Navigation Links */}
+
+
+
+ Dashboard
+
+
+
+ Book Appointment
+
+
+
+ {/* Right Side Actions */}
+
+
+
+
+
+ {unreadCount > 0 && (
+
+ )}
+
+
+
+ {/* Thumbtack Design at Top Right */}
+
+
+
Notifications
+ {unreadCount > 0 && (
+
+ {unreadCount} new
+
+ )}
+
+
+ {notifications.length === 0 ? (
+
+ ) : (
+
+ {notifications.map((notification) => {
+ return (
+
+
+
+
+ {notification.title}
+
+ {!notification.read && (
+
+ )}
+
+
+ {notification.message}
+
+
+ {notification.time}
+
+
+
+ );
+ })}
+
+ )}
+
+
+ setNotificationsOpen(false)}
+ className="block w-full text-center text-sm font-medium text-rose-600 hover:text-rose-700 hover:underline transition-colors"
+ >
+ View all notifications
+
+
+
+
+
+
+
+
+
+
+
+ {/* Thumbtack Design at Top Right */}
+
+
+ {
+ setUserMenuOpen(false);
+ // Add settings navigation here
+ }}
+ className="w-full flex items-center gap-3 px-4 py-3 justify-start hover:bg-gray-50 transition-colors cursor-pointer"
+ >
+
+ Settings
+
+ {
+ setUserMenuOpen(false);
+ router.push("/");
+ }}
+ className="w-full flex items-center gap-3 px-4 py-3 justify-start hover:bg-gray-50 transition-colors cursor-pointer"
+ >
+
+ Logout
+
+
+
+
+
+
+
+
+ );
+}
+
diff --git a/app/(admin)/_components/notifications.tsx b/app/(admin)/_components/notifications.tsx
new file mode 100644
index 0000000..835fe03
--- /dev/null
+++ b/app/(admin)/_components/notifications.tsx
@@ -0,0 +1,174 @@
+"use client";
+
+import { useState } from "react";
+import { Button } from "@/components/ui/button";
+import {
+ Bell,
+ X,
+ CheckCircle,
+ AlertCircle,
+ Info,
+ Calendar,
+ Clock,
+} from "lucide-react";
+import { cn } from "@/lib/utils";
+
+export interface Notification {
+ id: string;
+ type: "success" | "warning" | "info" | "appointment";
+ title: string;
+ message: string;
+ time: string;
+ read: boolean;
+}
+
+interface NotificationsProps {
+ notifications: Notification[];
+ onMarkAsRead?: (id: string) => void;
+ onDismiss?: (id: string) => void;
+ onMarkAllAsRead?: () => void;
+}
+
+export function Notifications({
+ notifications,
+ onMarkAsRead,
+ onDismiss,
+ onMarkAllAsRead,
+}: NotificationsProps) {
+ const unreadCount = notifications.filter((n) => !n.read).length;
+
+ const getIcon = (type: Notification["type"]) => {
+ switch (type) {
+ case "success":
+ return ;
+ case "warning":
+ return ;
+ case "info":
+ return ;
+ case "appointment":
+ return ;
+ }
+ };
+
+ const getBgColor = (type: Notification["type"]) => {
+ switch (type) {
+ case "success":
+ return "bg-[#4A90A4]/10 border-[#4A90A4]/30";
+ case "warning":
+ return "bg-rose-100 border-rose-300";
+ case "info":
+ return "bg-pink-50 border-pink-200";
+ case "appointment":
+ return "bg-gradient-to-br from-rose-50 to-pink-50 border-rose-300";
+ }
+ };
+
+ return (
+
+ {/* Header */}
+
+
+
+
Notifications
+ {unreadCount > 0 && (
+
+ {unreadCount}
+
+ )}
+
+ {unreadCount > 0 && onMarkAllAsRead && (
+
+ Mark all as read
+
+ )}
+
+
+ {/* Notifications List */}
+
+ {notifications.length === 0 ? (
+
+ ) : (
+ notifications.map((notification) => (
+
+
+
{getIcon(notification.type)}
+
+
+
+
+ {notification.title}
+
+
{notification.message}
+
+
+ {notification.time}
+
+
+
+ {!notification.read && onMarkAsRead && (
+ onMarkAsRead(notification.id)}
+ className="h-7 w-7"
+ >
+
+
+ )}
+ {onDismiss && (
+ onDismiss(notification.id)}
+ className="h-7 w-7"
+ >
+
+
+ )}
+
+
+
+
+
+ ))
+ )}
+
+
+ );
+}
+
+// Notification Bell Component for Header
+export function NotificationBell({
+ count,
+ onClick,
+}: {
+ count: number;
+ onClick: () => void;
+}) {
+ return (
+
+
+ {count > 0 && (
+
+ {count > 9 ? "9+" : count}
+
+ )}
+
+ );
+}
+
diff --git a/app/(admin)/_components/side-nav.tsx b/app/(admin)/_components/side-nav.tsx
new file mode 100644
index 0000000..47fade1
--- /dev/null
+++ b/app/(admin)/_components/side-nav.tsx
@@ -0,0 +1,164 @@
+"use client";
+
+import React, { useState, useEffect } from "react";
+import { usePathname, useRouter } from "next/navigation";
+import Link from "next/link";
+import { Button } from "@/components/ui/button";
+import {
+ LayoutGrid,
+ Calendar,
+ Settings,
+ LogOut,
+ Menu,
+ X,
+ Heart,
+} from "lucide-react";
+
+const navItems = [
+ { label: "Dashboard", icon: LayoutGrid, href: "/dashboard" },
+ { label: "Book Appointment", icon: Calendar, href: "/booking" },
+];
+
+export default function SideNav() {
+ const [open, setOpen] = useState(false);
+ const pathname = usePathname();
+ const router = useRouter();
+
+ const getActiveIndex = () => {
+ return navItems.findIndex((item) => pathname?.includes(item.href)) ?? -1;
+ };
+
+ // Handle body scroll when mobile menu is open
+ useEffect(() => {
+ if (open) {
+ document.body.classList.add("menu-open");
+ } else {
+ document.body.classList.remove("menu-open");
+ }
+ return () => {
+ document.body.classList.remove("menu-open");
+ };
+ }, [open]);
+
+ return (
+ <>
+ {/* Mobile Top Bar */}
+
+
+
+
+
+
Attune Heart Therapy
+
+
setOpen((v) => !v)}
+ aria-label="Open menu"
+ >
+ {open ? : }
+
+
+
+ {/* Mobile Drawer Overlay */}
+ setOpen(false)}
+ />
+
+ {/* Side Navigation */}
+
+ {/* Logo Section */}
+
+
+
+
+ {/* Navigation Items */}
+
+ {navItems.map((item, idx) => {
+ const Icon = item.icon;
+ const isActive = idx === getActiveIndex();
+
+ return (
+
+ {isActive && (
+
+ )}
+ setOpen(false)}
+ className={`group flex items-center gap-2 py-2.5 pl-3 md:pl-3 pr-3 md:pr-3 transition-colors duration-200 focus:outline-none w-[90%] md:w-[90%] ml-1 md:ml-2 cursor-pointer justify-start ${
+ isActive
+ ? "bg-linear-to-r from-rose-500 to-pink-600 text-white border border-rose-500 rounded-[5px] shadow-sm"
+ : "bg-transparent text-gray-600 hover:bg-rose-50 hover:text-rose-600 rounded-lg"
+ }`}
+ style={isActive ? { height: 40 } : {}}
+ >
+
+
+ {item.label}
+
+
+
+ );
+ })}
+
+ {/* Bottom Actions */}
+
+ setOpen(false)}
+ className="group flex items-center gap-2 py-2.5 pl-3 md:pl-3 pr-3 md:pr-3 transition-colors duration-200 w-[90%] md:w-[90%] ml-1 md:ml-2 cursor-pointer justify-start text-gray-600 hover:bg-gray-50 hover:text-gray-900 rounded-lg"
+ >
+
+
+ Settings
+
+
+ {
+ setOpen(false);
+ router.push("/");
+ }}
+ className="group flex items-center gap-2 py-2.5 pl-3 md:pl-3 pr-3 md:pr-3 transition-colors duration-200 w-[90%] md:w-[90%] ml-1 md:ml-2 cursor-pointer justify-start text-gray-600 hover:bg-gray-50 hover:text-gray-900 rounded-lg"
+ >
+
+
+ Logout
+
+
+
+
+
+ >
+ );
+}
+
diff --git a/app/(admin)/booking/page.tsx b/app/(admin)/booking/page.tsx
new file mode 100644
index 0000000..4954381
--- /dev/null
+++ b/app/(admin)/booking/page.tsx
@@ -0,0 +1,325 @@
+"use client";
+
+import { useState, useEffect } from "react";
+import {
+ Calendar,
+ Clock,
+ User,
+ Video,
+ FileText,
+ MoreVertical,
+} from "lucide-react";
+
+interface User {
+ ID: number;
+ CreatedAt?: string;
+ UpdatedAt?: string;
+ DeletedAt?: string | null;
+ first_name: string;
+ last_name: string;
+ email: string;
+ phone: string;
+ location: string;
+ date_of_birth?: string;
+ is_admin?: boolean;
+ bookings?: null;
+}
+
+interface Booking {
+ ID: number;
+ CreatedAt: string;
+ UpdatedAt: string;
+ DeletedAt: string | null;
+ user_id: number;
+ user: User;
+ scheduled_at: string;
+ duration: number;
+ status: string;
+ jitsi_room_id: string;
+ jitsi_room_url: string;
+ payment_id: string;
+ payment_status: string;
+ amount: number;
+ notes: string;
+}
+
+interface BookingsResponse {
+ bookings: Booking[];
+ limit: number;
+ offset: number;
+ total: number;
+}
+
+export default function Booking() {
+ const [bookings, setBookings] = useState
([]);
+ const [loading, setLoading] = useState(true);
+ const [searchTerm, setSearchTerm] = useState("");
+
+ useEffect(() => {
+ // Simulate API call
+ const fetchBookings = async () => {
+ setLoading(true);
+ await new Promise((resolve) => setTimeout(resolve, 500));
+
+ // Mock API response
+ const mockData: BookingsResponse = {
+ bookings: [
+ {
+ ID: 1,
+ CreatedAt: "2025-11-06T11:33:45.704633Z",
+ UpdatedAt: "2025-11-06T11:33:45.707543Z",
+ DeletedAt: null,
+ user_id: 3,
+ user: {
+ ID: 3,
+ CreatedAt: "2025-11-06T10:43:01.299311Z",
+ UpdatedAt: "2025-11-06T10:43:48.427284Z",
+ DeletedAt: null,
+ first_name: "John",
+ last_name: "Smith",
+ email: "john.doe@example.com",
+ phone: "+1234567891",
+ location: "Los Angeles, CA",
+ date_of_birth: "0001-01-01T00:00:00Z",
+ is_admin: true,
+ bookings: null,
+ },
+ scheduled_at: "2025-11-07T10:00:00Z",
+ duration: 60,
+ status: "scheduled",
+ jitsi_room_id: "booking-1-1762428825-22c92ced2870c17c",
+ jitsi_room_url:
+ "https://meet.jit.si/booking-1-1762428825-22c92ced2870c17c",
+ payment_id: "",
+ payment_status: "pending",
+ amount: 52,
+ notes: "Initial consultation session",
+ },
+ ],
+ limit: 50,
+ offset: 0,
+ total: 1,
+ };
+
+ setBookings(mockData.bookings);
+ setLoading(false);
+ };
+
+ fetchBookings();
+ }, []);
+
+ const formatDate = (dateString: string) => {
+ const date = new Date(dateString);
+ return date.toLocaleDateString("en-US", {
+ month: "short",
+ day: "numeric",
+ year: "numeric",
+ });
+ };
+
+ const formatTime = (dateString: string) => {
+ const date = new Date(dateString);
+ return date.toLocaleTimeString("en-US", {
+ hour: "numeric",
+ minute: "2-digit",
+ hour12: true,
+ });
+ };
+
+ const getStatusColor = (status: string) => {
+ switch (status.toLowerCase()) {
+ case "scheduled":
+ return "bg-blue-100 text-blue-700";
+ case "completed":
+ return "bg-green-100 text-green-700";
+ case "cancelled":
+ return "bg-red-100 text-red-700";
+ case "pending":
+ return "bg-yellow-100 text-yellow-700";
+ default:
+ return "bg-gray-100 text-gray-700";
+ }
+ };
+
+ const getPaymentStatusColor = (status: string) => {
+ switch (status.toLowerCase()) {
+ case "paid":
+ return "bg-green-100 text-green-700";
+ case "pending":
+ return "bg-yellow-100 text-yellow-700";
+ case "failed":
+ return "bg-red-100 text-red-700";
+ default:
+ return "bg-gray-100 text-gray-700";
+ }
+ };
+
+ const filteredBookings = bookings.filter(
+ (booking) =>
+ booking.user.first_name
+ .toLowerCase()
+ .includes(searchTerm.toLowerCase()) ||
+ booking.user.last_name
+ .toLowerCase()
+ .includes(searchTerm.toLowerCase()) ||
+ booking.user.email.toLowerCase().includes(searchTerm.toLowerCase())
+ );
+
+ return (
+
+
+ {/* Main Content */}
+
+ {/* Page Header */}
+
+
+
+ Bookings
+
+
+ Manage and view all appointment bookings
+
+
+
+ + New Booking
+
+
+
+ {loading ? (
+
+ ) : filteredBookings.length === 0 ? (
+
+
+
No bookings found
+
+ {searchTerm
+ ? "Try adjusting your search terms"
+ : "Create a new booking to get started"}
+
+
+ ) : (
+
+
+
+
+
+
+ Patient
+
+
+ Date & Time
+
+
+ Duration
+
+
+ Status
+
+
+ Payment
+
+
+ Amount
+
+
+ Actions
+
+
+
+
+ {filteredBookings.map((booking) => (
+
+
+
+
+
+
+
+
+ {booking.user.first_name} {booking.user.last_name}
+
+
+ {booking.user.email}
+
+
+ {formatDate(booking.scheduled_at)}
+
+
+
+
+
+
+ {formatDate(booking.scheduled_at)}
+
+
+
+ {formatTime(booking.scheduled_at)}
+
+
+
+ {booking.duration} min
+
+
+
+ {booking.status}
+
+
+
+
+ {booking.payment_status}
+
+
+
+ ${booking.amount}
+
+
+
+ {booking.jitsi_room_url && (
+
+
+
+ )}
+ {booking.notes && (
+
+
+
+ )}
+
+
+
+
+
+
+ ))}
+
+
+
+
+ )}
+
+
+ );
+}
+
diff --git a/app/(admin)/dashboard/page.tsx b/app/(admin)/dashboard/page.tsx
new file mode 100644
index 0000000..b1e9cf7
--- /dev/null
+++ b/app/(admin)/dashboard/page.tsx
@@ -0,0 +1,207 @@
+"use client";
+
+import { useState, useEffect } from "react";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select";
+import {
+ Users,
+ UserCheck,
+ Calendar,
+ CalendarCheck,
+ CalendarX,
+ DollarSign,
+ TrendingUp,
+ ArrowUpRight,
+ ArrowDownRight,
+} from "lucide-react";
+
+interface DashboardStats {
+ total_users: number;
+ active_users: number;
+ total_bookings: number;
+ upcoming_bookings: number;
+ completed_bookings: number;
+ cancelled_bookings: number;
+ total_revenue: number;
+ monthly_revenue: number;
+}
+
+export default function Dashboard() {
+ const [stats, setStats] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [timePeriod, setTimePeriod] = useState("last_month");
+
+ useEffect(() => {
+ // Simulate API call
+ const fetchStats = async () => {
+ setLoading(true);
+ // Simulate network delay
+ await new Promise((resolve) => setTimeout(resolve, 500));
+
+ // Mock API response
+ const mockData: DashboardStats = {
+ total_users: 3,
+ active_users: 3,
+ total_bookings: 6,
+ upcoming_bookings: 6,
+ completed_bookings: 0,
+ cancelled_bookings: 0,
+ total_revenue: 0,
+ monthly_revenue: 0,
+ };
+
+ setStats(mockData);
+ setLoading(false);
+ };
+
+ fetchStats();
+ }, []);
+
+ const statCards = [
+ {
+ title: "Total Users",
+ value: stats?.total_users ?? 0,
+ icon: Users,
+ trend: "+12%",
+ trendUp: true,
+ },
+ {
+ title: "Active Users",
+ value: stats?.active_users ?? 0,
+ icon: UserCheck,
+ trend: "+8%",
+ trendUp: true,
+ },
+ {
+ title: "Total Bookings",
+ value: stats?.total_bookings ?? 0,
+ icon: Calendar,
+ trend: "+24%",
+ trendUp: true,
+ },
+ {
+ title: "Upcoming Bookings",
+ value: stats?.upcoming_bookings ?? 0,
+ icon: CalendarCheck,
+ trend: "+6",
+ trendUp: true,
+ },
+ {
+ title: "Completed Bookings",
+ value: stats?.completed_bookings ?? 0,
+ icon: CalendarCheck,
+ trend: "0%",
+ trendUp: true,
+ },
+ {
+ title: "Cancelled Bookings",
+ value: stats?.cancelled_bookings ?? 0,
+ icon: CalendarX,
+ trend: "0%",
+ trendUp: false,
+ },
+ {
+ title: "Total Revenue",
+ value: `$${stats?.total_revenue.toLocaleString() ?? 0}`,
+ icon: DollarSign,
+ trend: "+18%",
+ trendUp: true,
+ },
+ {
+ title: "Monthly Revenue",
+ value: `$${stats?.monthly_revenue.toLocaleString() ?? 0}`,
+ icon: TrendingUp,
+ trend: "+32%",
+ trendUp: true,
+ },
+ ];
+
+
+ return (
+
+
+ {/* Main Content */}
+
+ {/* Welcome Section */}
+
+
+
+ Welcome Back! Hammond
+
+
+ Here's an overview of your practice today
+
+
+
+
+
+
+
+ Last Week
+ Last Month
+ Last Year
+
+
+
+
+ {loading ? (
+
+ ) : (
+ <>
+ {/* Stats Grid */}
+
+ {statCards.map((card, index) => {
+ const Icon = card.icon;
+ return (
+
+
+
+
+
+
+ {card.trendUp ? (
+
+ ) : (
+
+ )}
+
{card.trend}
+
+
+
+
+
+ {card.title}
+
+
+ {card.value}
+
+
+ vs last month
+
+
+
+ );
+ })}
+
+
+ >
+ )}
+
+
+ );
+}
+
diff --git a/app/(admin)/layout.tsx b/app/(admin)/layout.tsx
new file mode 100644
index 0000000..4cd0095
--- /dev/null
+++ b/app/(admin)/layout.tsx
@@ -0,0 +1,12 @@
+import { Header } from "./_components/header";
+
+export default function AdminLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/app/(admin)/notifications/page.tsx b/app/(admin)/notifications/page.tsx
new file mode 100644
index 0000000..fa65682
--- /dev/null
+++ b/app/(admin)/notifications/page.tsx
@@ -0,0 +1,121 @@
+"use client";
+
+import { useState } from "react";
+import { Bell } from "lucide-react";
+
+interface Notification {
+ id: string;
+ title: string;
+ message: string;
+ time: string;
+ read: boolean;
+}
+
+export default function NotificationsPage() {
+ const [notifications, setNotifications] = useState([
+ {
+ id: "1",
+ title: "New appointment scheduled",
+ message: "John Smith booked an appointment for tomorrow",
+ time: "2 hours ago",
+ read: false,
+ },
+ {
+ id: "2",
+ title: "Payment received",
+ message: "Payment of $150 received from Jane Doe",
+ time: "5 hours ago",
+ read: false,
+ },
+ {
+ id: "3",
+ title: "Appointment Reminder",
+ message: "You have an appointment in 30 minutes with Emily Davis",
+ time: "3 hours ago",
+ read: false,
+ },
+ {
+ id: "4",
+ title: "New Message",
+ message: "You received a new message from John Smith",
+ time: "5 hours ago",
+ read: true,
+ },
+ {
+ id: "5",
+ title: "Appointment Cancelled",
+ message: "Robert Wilson cancelled his appointment scheduled for tomorrow",
+ time: "1 day ago",
+ read: true,
+ },
+ ]);
+
+ const unreadCount = notifications.filter((n) => !n.read).length;
+
+ return (
+
+ {/* Main Content */}
+
+ {/* Page Header */}
+
+
+
+
+ Notifications
+
+ {unreadCount > 0 && (
+
+ {unreadCount} new
+
+ )}
+
+
+
+ {/* Notifications List */}
+
+ {notifications.length === 0 ? (
+
+ ) : (
+
+ {notifications.map((notification) => {
+ return (
+
+
+
+
+ {notification.title}
+
+ {!notification.read && (
+
+ )}
+
+
+ {notification.message}
+
+
+ {notification.time}
+
+
+
+ );
+ })}
+
+ )}
+
+
+
+ );
+}
+
diff --git a/app/(auth)/layout.tsx b/app/(auth)/layout.tsx
new file mode 100644
index 0000000..937e74a
--- /dev/null
+++ b/app/(auth)/layout.tsx
@@ -0,0 +1,7 @@
+export default function AuthLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ )
+}
\ No newline at end of file
diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx
new file mode 100644
index 0000000..e500604
--- /dev/null
+++ b/app/(auth)/login/page.tsx
@@ -0,0 +1,145 @@
+"use client";
+
+import { useState } from "react";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Heart, Eye, EyeOff, X } from "lucide-react";
+import Link from "next/link";
+import Image from "next/image";
+import { useRouter } from "next/navigation";
+
+export default function Login() {
+ const [showPassword, setShowPassword] = useState(false);
+ const [rememberMe, setRememberMe] = useState(false);
+ const router = useRouter();
+
+ return (
+
+ {/* Background Image */}
+
+
+ {/* Overlay for better readability */}
+
+
+
+ {/* Branding - Top Left */}
+
+
+ Attune Heart Therapy
+
+
+
+
+ {/* Centered White Card - Login Form */}
+
+ {/* Close Button */}
+
router.back()}
+ variant="ghost"
+ size="icon"
+ className="ml-auto mb-6 w-8 h-8 rounded-full"
+ aria-label="Close"
+ >
+
+
+ {/* Heading */}
+
+ Welcome back
+
+
+ {/* Sign Up Prompt */}
+
+ New to Attune Heart Therapy?{" "}
+
+ Sign up
+
+
+
+ {/* Login Form */}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/globals.css b/app/globals.css
index a2dc41e..9f48bd2 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1,26 +1,94 @@
@import "tailwindcss";
+@import "tw-animate-css";
:root {
- --background: #ffffff;
- --foreground: #171717;
-}
-
-@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
+ --foreground-rgb: 0, 0, 0;
+ --background-start-rgb: 214, 219, 220;
+ --background-end-rgb: 255, 255, 255;
}
@media (prefers-color-scheme: dark) {
:root {
- --background: #0a0a0a;
- --foreground: #ededed;
+ --foreground-rgb: 255, 255, 255;
+ --background-start-rgb: 0, 0, 0;
+ --background-end-rgb: 0, 0, 0;
}
}
-body {
- background: var(--background);
- color: var(--foreground);
- font-family: Arial, Helvetica, sans-serif;
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 0 0% 3.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 0 0% 3.9%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 0 0% 3.9%;
+ --primary: 0 0% 9%;
+ --primary-foreground: 0 0% 98%;
+ --secondary: 0 0% 96.1%;
+ --secondary-foreground: 0 0% 9%;
+ --muted: 0 0% 96.1%;
+ --muted-foreground: 0 0% 45.1%;
+ --accent: 0 0% 96.1%;
+ --accent-foreground: 0 0% 9%;
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 0 0% 98%;
+ --border: 0 0% 89.8%;
+ --input: 0 0% 89.8%;
+ --ring: 0 0% 3.9%;
+ --chart-1: 12 76% 61%;
+ --chart-2: 173 58% 39%;
+ --chart-3: 197 37% 24%;
+ --chart-4: 43 74% 66%;
+ --chart-5: 27 87% 67%;
+ --radius: 0.5rem;
+ }
+ .dark {
+ --background: 0 0% 3.9%;
+ --foreground: 0 0% 98%;
+ --card: 0 0% 3.9%;
+ --card-foreground: 0 0% 98%;
+ --popover: 0 0% 3.9%;
+ --popover-foreground: 0 0% 98%;
+ --primary: 0 0% 98%;
+ --primary-foreground: 0 0% 9%;
+ --secondary: 0 0% 14.9%;
+ --secondary-foreground: 0 0% 98%;
+ --muted: 0 0% 14.9%;
+ --muted-foreground: 0 0% 63.9%;
+ --accent: 0 0% 14.9%;
+ --accent-foreground: 0 0% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 0 0% 98%;
+ --border: 0 0% 14.9%;
+ --input: 0 0% 14.9%;
+ --ring: 0 0% 83.1%;
+ --chart-1: 220 70% 50%;
+ --chart-2: 160 60% 45%;
+ --chart-3: 30 80% 55%;
+ --chart-4: 280 65% 60%;
+ --chart-5: 340 75% 55%;
+ }
+}
+
+@layer base {
+ * {
+ border-color: hsl(var(--border));
+ }
+ body {
+ background-color: #ffffff;
+ color: hsl(var(--foreground));
+ }
+ html.dark body {
+ background-color: #1a1e26;
+ }
+ html {
+ scroll-behavior: smooth;
+ }
+}
+
+@layer utilities {
+ .text-balance {
+ text-wrap: balance;
+ }
}
diff --git a/app/layout.tsx b/app/layout.tsx
index f7fa87e..5b3bb9b 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,33 +1,28 @@
-import type { Metadata } from "next";
-import { Geist, Geist_Mono } from "next/font/google";
-import "./globals.css";
+import './globals.css';
+import type { Metadata } from 'next';
+import { Inter } from 'next/font/google';
+import { Providers } from './providers';
+import { Toaster } from '@/components/ui/toaster';
-const geistSans = Geist({
- variable: "--font-geist-sans",
- subsets: ["latin"],
-});
-
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
- subsets: ["latin"],
-});
+const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
+ title: 'Attune Heart Therapy | Nathalie Mac Guffie, LCSW | Miami, FL',
+ description: 'Compassionate, evidence-based therapy in Miami, FL. Licensed Clinical Social Worker offering anxiety, depression, trauma therapy and more.',
};
export default function RootLayout({
children,
-}: Readonly<{
+}: {
children: React.ReactNode;
-}>) {
+}) {
return (
-
-
- {children}
+
+
+
+ {children}
+
+
);
diff --git a/app/page.tsx b/app/page.tsx
index 295f8fd..273b8b5 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,65 +1,25 @@
-import Image from "next/image";
+import Section from "../components/Section";
+import { Footer } from "../components/Footer";
+import { HeroSection } from "@/components/Hero";
+import { About } from "@/components/About";
+import { Services } from "@/components/Services";
+import { ContactSection } from "@/components/ContactSection";
+import { Navbar } from "../components/Navbar";
+
export default function Home() {
return (
-
-
-
-
-
- To get started, edit the page.tsx file.
-
-
- Looking for a starting point or more instructions? Head over to{" "}
-
- Templates
- {" "}
- or the{" "}
-
- Learning
- {" "}
- center.
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/app/providers.tsx b/app/providers.tsx
new file mode 100644
index 0000000..9707b40
--- /dev/null
+++ b/app/providers.tsx
@@ -0,0 +1,13 @@
+"use client";
+
+import { ThemeProvider } from "../components/ThemeProvider";
+import { type ReactNode } from "react";
+
+export function Providers({ children }: { children: ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+
diff --git a/components.json b/components.json
new file mode 100644
index 0000000..b7b9791
--- /dev/null
+++ b/components.json
@@ -0,0 +1,22 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "new-york",
+ "rsc": true,
+ "tsx": true,
+ "tailwind": {
+ "config": "",
+ "css": "app/globals.css",
+ "baseColor": "neutral",
+ "cssVariables": true,
+ "prefix": ""
+ },
+ "iconLibrary": "lucide",
+ "aliases": {
+ "components": "@/components",
+ "utils": "@/lib/utils",
+ "ui": "@/components/ui",
+ "lib": "@/lib",
+ "hooks": "@/hooks"
+ },
+ "registries": {}
+}
diff --git a/components/About.tsx b/components/About.tsx
new file mode 100644
index 0000000..00c3d37
--- /dev/null
+++ b/components/About.tsx
@@ -0,0 +1,216 @@
+'use client';
+
+import { motion } from "framer-motion";
+import { useInView } from "framer-motion";
+import { useRef, useEffect, useState } from "react";
+import { Award, Heart, Users } from "lucide-react";
+
+export function About() {
+ const ref = useRef(null);
+ const isInView = useInView(ref, { once: true, margin: "-100px" });
+ const [isDark, setIsDark] = useState(false);
+
+ useEffect(() => {
+ const checkTheme = () => {
+ setIsDark(document.documentElement.classList.contains('dark'));
+ };
+
+ checkTheme();
+ const observer = new MutationObserver(checkTheme);
+ observer.observe(document.documentElement, {
+ attributes: true,
+ attributeFilter: ['class']
+ });
+
+ return () => observer.disconnect();
+ }, []);
+
+ const credentials = [
+ {
+ icon: Award,
+ title: "Licensed Mental Health Counselor (LMHC)",
+ description: "Florida licensed with 30 years of experience",
+ },
+ {
+ icon: Heart,
+ title: "Trauma-Focused Specialist",
+ description: "Certified in TF-CBT for trauma recovery",
+ },
+ {
+ icon: Users,
+ title: "Infant Mental Health & Play Therapy",
+ description: "Registered Play Therapist (RPT-S) and IMH Endorsement",
+ },
+ ];
+
+ return (
+
+ {/* Background Image */}
+
+
+ {/* Subtle overlay for readability - keeping background image clearly visible */}
+
+
+ {/* Very subtle gradient overlay */}
+ {!isDark && (
+
+ )}
+ {isDark && (
+
+ )}
+
+ {/* Subtle animated blobs */}
+
+
+
+
+
+
+
+
+ Meet Nathalie Mac-Guffie
+
+
+ A dedicated mental health professional specializing in helping children
+ under 10 and their families navigate trauma, emotional challenges, and
+ developmental needs.
+
+
+
+
+
+
+
+ My Approach
+
+
+ I provide person-centered guidance, following your child's lead while
+ drawing out their strengths and incorporating effective coping skills.
+ My interventions are relationship-based, creating a warm, non-judgmental
+ space for growth and healing.
+
+
+ Together, we'll set realistic, measurable, and achievable goals with
+ clear objectives tailored to your family's unique needs.
+
+
+
+
+
+ {credentials.map((cred, index) => {
+ const Icon = cred.icon;
+ return (
+
+
+
+
+
+
+
+ {cred.title}
+
+
+ {cred.description}
+
+
+
+
+ );
+ })}
+
+
+
+
+ );
+}
+
diff --git a/components/ContactSection.tsx b/components/ContactSection.tsx
new file mode 100644
index 0000000..dbbbeda
--- /dev/null
+++ b/components/ContactSection.tsx
@@ -0,0 +1,228 @@
+"use client";
+
+import { motion, useInView } from "framer-motion";
+import { useEffect, useRef, useState } from "react";
+import { Send } from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Textarea } from "@/components/ui/textarea";
+import { Card, CardContent } from "@/components/ui/card";
+import { toast } from "sonner";
+
+export function ContactSection() {
+ const ref = useRef(null);
+ const isInView = useInView(ref, { once: true, margin: "-100px" });
+ const [isDark, setIsDark] = useState(false);
+ const [formData, setFormData] = useState({
+ name: "",
+ email: "",
+ phone: "",
+ message: "",
+ });
+
+ // Sync with global theme class like Navbar/Hero/About
+ useEffect(() => {
+ const sync = () => setIsDark(document.documentElement.classList.contains("dark"));
+ sync();
+ const observer = new MutationObserver(sync);
+ observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
+ return () => observer.disconnect();
+ }, []);
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ toast("Message Received", {
+ description: "Thank you for reaching out. We'll get back to you soon!",
+ });
+ setFormData({ name: "", email: "", phone: "", message: "" });
+ };
+
+ return (
+
+ );
+}
diff --git a/components/DatePicker.tsx b/components/DatePicker.tsx
new file mode 100644
index 0000000..233e1cf
--- /dev/null
+++ b/components/DatePicker.tsx
@@ -0,0 +1,98 @@
+'use client';
+
+import * as React from 'react';
+
+import { Calendar as CalendarIcon } from 'lucide-react';
+
+import { format } from 'date-fns';
+
+import { cn } from '@/lib/utils';
+
+import { Button } from '@/components/ui/button';
+
+import { Calendar } from '@/components/ui/calendar';
+
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+
+interface DatePickerProps {
+ date: Date | undefined;
+ setDate: (date: Date | undefined) => void;
+ label?: string;
+}
+
+export function DatePicker({ date, setDate, label }: DatePickerProps) {
+ const [open, setOpen] = React.useState(false);
+
+ return (
+
+ {label && (
+
+ {label}
+
+ )}
+
+
+
+
+ {date ? format(date, 'PPP') : Pick a date }
+
+
+
+ {
+ setDate(selectedDate);
+ setOpen(false);
+ }}
+ initialFocus
+ classNames={{
+ months: "space-y-4",
+ month: "space-y-4",
+ caption: "flex justify-center pt-3 pb-5 relative items-center border-b border-gray-200 dark:border-gray-700 mb-4",
+ caption_label: "text-lg font-bold text-gray-800 dark:text-gray-100",
+ nav: "flex items-center justify-between absolute inset-0",
+ nav_button: cn(
+ "h-9 w-9 rounded-full bg-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 hover:bg-rose-50 dark:hover:bg-gray-600 hover:border-rose-300 dark:hover:border-rose-500 p-0 transition-all shadow-sm"
+ ),
+ nav_button_previous: "absolute left-0",
+ nav_button_next: "absolute right-0",
+ table: "w-full border-collapse space-y-3",
+ head_row: "flex mb-3",
+ head_cell: "text-gray-600 dark:text-gray-400 rounded-md w-11 font-semibold text-xs",
+ row: "flex w-full mt-2",
+ cell: cn(
+ "relative p-0 text-center text-sm focus-within:relative focus-within:z-20",
+ "[&>button]:h-11 [&>button]:w-11 [&>button]:p-0 [&>button]:font-semibold [&>button]:cursor-pointer [&>button]:rounded-full [&>button]:transition-all"
+ ),
+ day: cn(
+ "h-11 w-11 p-0 font-semibold aria-selected:opacity-100 hover:bg-rose-500 hover:text-white rounded-full transition-all cursor-pointer",
+ "hover:scale-110 active:scale-95 hover:shadow-md"
+ ),
+ day_selected:
+ "bg-rose-600 text-white hover:bg-rose-700 hover:text-white focus:bg-rose-600 focus:text-white font-bold shadow-xl scale-110 ring-4 ring-rose-200 dark:ring-rose-800",
+ day_today: "bg-blue-50 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400 font-bold border-2 border-blue-300 dark:border-blue-600",
+ day_outside: "text-gray-300 dark:text-gray-600 opacity-50",
+ day_disabled: "text-gray-200 dark:text-gray-700 opacity-30 cursor-not-allowed",
+ day_range_middle:
+ "aria-selected:bg-rose-100 dark:aria-selected:bg-rose-900/30 aria-selected:text-rose-700 dark:aria-selected:text-rose-300",
+ day_hidden: "invisible",
+ }}
+ />
+
+
+
+ );
+}
+
diff --git a/components/Footer.tsx b/components/Footer.tsx
new file mode 100644
index 0000000..56ed92b
--- /dev/null
+++ b/components/Footer.tsx
@@ -0,0 +1,181 @@
+'use client';
+
+import { motion } from "framer-motion";
+import { Heart, Mail, Phone, MapPin } from "lucide-react";
+import { useEffect, useState } from "react";
+
+export function Footer() {
+ const [isDark, setIsDark] = useState(false);
+
+ useEffect(() => {
+ const checkTheme = () => {
+ setIsDark(document.documentElement.classList.contains('dark'));
+ };
+
+ checkTheme();
+ const observer = new MutationObserver(checkTheme);
+ observer.observe(document.documentElement, {
+ attributes: true,
+ attributeFilter: ['class']
+ });
+
+ return () => observer.disconnect();
+ }, []);
+
+ const scrollToSection = (id: string) => {
+ const element = document.getElementById(id);
+ if (element) {
+ element.scrollIntoView({ behavior: "smooth" });
+ }
+ };
+
+ const quickLinks = [
+ { name: 'Home', href: '#home' },
+ { name: 'About', href: '#about' },
+ { name: 'Services', href: '#services' },
+ { name: 'Contact', href: '#contact' },
+ ];
+
+ return (
+
+ );
+}
diff --git a/components/Hero.tsx b/components/Hero.tsx
new file mode 100644
index 0000000..f2ee685
--- /dev/null
+++ b/components/Hero.tsx
@@ -0,0 +1,178 @@
+'use client';
+
+import { motion } from 'framer-motion';
+import { Button } from '@/components/ui/button';
+import { ArrowRight, Calendar } from 'lucide-react';
+import { useEffect, useState } from 'react';
+
+export function HeroSection() {
+ const [isDark, setIsDark] = useState(false);
+
+ useEffect(() => {
+ const checkTheme = () => {
+ setIsDark(document.documentElement.classList.contains('dark'));
+ };
+
+ checkTheme();
+ const observer = new MutationObserver(checkTheme);
+ observer.observe(document.documentElement, {
+ attributes: true,
+ attributeFilter: ['class']
+ });
+
+ return () => observer.disconnect();
+ }, []);
+
+ return (
+
+ {/* Background Image */}
+
+
+ {/* Subtle dark overlay for better text readability - keeping background image clearly visible */}
+
+
+ {/* Very subtle gradient overlay for warmth */}
+ {!isDark && (
+
+ )}
+ {isDark && (
+
+ )}
+
+ {/* Subtle animated blobs for depth */}
+
+
+
+
+
+
+
+
+
+
+ Welcome to Attune Heart Therapy
+
+
+
+ Nathalie Mac Guffie, LCSW
+
+
+
+ Compassionate, evidence-based therapy to help you heal, grow, and
+ thrive. Creating a safe space for your journey toward emotional
+ wellness.
+
+
+
+
+
+ Book Appointment
+
+
+
+ Learn More
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/components/Navbar.tsx b/components/Navbar.tsx
new file mode 100644
index 0000000..ce0b635
--- /dev/null
+++ b/components/Navbar.tsx
@@ -0,0 +1,94 @@
+'use client';
+
+import { motion } from "framer-motion";
+import { Button } from "@/components/ui/button";
+import { Heart } from "lucide-react";
+import { ThemeToggle } from "@/components/ThemeToggle";
+import { useEffect, useState } from "react";
+
+export function Navbar() {
+ const [isDark, setIsDark] = useState(false);
+
+ useEffect(() => {
+ const checkTheme = () => {
+ setIsDark(document.documentElement.classList.contains('dark'));
+ };
+
+ checkTheme();
+ const observer = new MutationObserver(checkTheme);
+ observer.observe(document.documentElement, {
+ attributes: true,
+ attributeFilter: ['class']
+ });
+
+ return () => observer.disconnect();
+ }, []);
+
+ const scrollToSection = (id: string) => {
+ const element = document.getElementById(id);
+ if (element) {
+ element.scrollIntoView({ behavior: "smooth" });
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+
+ Attune Heart Therapy
+
+
+
+
+ scrollToSection("about")}
+ className="text-sm font-medium hover:text-primary transition-colors cursor-pointer px-3 py-2 rounded-lg hover:bg-gray-100 dark:hover:bg-cyan-900/30"
+ >
+ About
+
+ scrollToSection("services")}
+ className="text-sm font-medium hover:text-primary transition-colors cursor-pointer px-3 py-2 rounded-lg hover:bg-gray-100 dark:hover:bg-cyan-900/30"
+ >
+ Services
+
+ scrollToSection("contact")}
+ className="text-sm font-medium hover:text-primary transition-colors cursor-pointer px-3 py-2 rounded-lg hover:bg-gray-100 dark:hover:bg-cyan-900/30"
+ >
+ Contact
+
+
+
+
+
+
+
+ );
+}
diff --git a/components/Section.tsx b/components/Section.tsx
new file mode 100644
index 0000000..caef6c9
--- /dev/null
+++ b/components/Section.tsx
@@ -0,0 +1,30 @@
+"use client";
+
+import { type ReactNode } from "react";
+
+type Props = {
+ id?: string;
+ title: string;
+ children: ReactNode;
+};
+
+export default function Section({ id, title, children }: Props) {
+ return (
+
+
+ {title}
+
+
+ {children}
+
+
+
+ );
+}
+
+
diff --git a/components/Services.tsx b/components/Services.tsx
new file mode 100644
index 0000000..176de53
--- /dev/null
+++ b/components/Services.tsx
@@ -0,0 +1,242 @@
+'use client';
+
+import { motion } from "framer-motion";
+import { useInView } from "framer-motion";
+import { useRef, useEffect, useState } from "react";
+import { Baby, Brain, HeartHandshake, Sparkles, Users2, Shield } from "lucide-react";
+
+export function Services() {
+ const ref = useRef(null);
+ const isInView = useInView(ref, { once: true, margin: "-100px" });
+ const [isDark, setIsDark] = useState(false);
+
+ useEffect(() => {
+ const checkTheme = () => {
+ setIsDark(document.documentElement.classList.contains('dark'));
+ };
+
+ checkTheme();
+ const observer = new MutationObserver(checkTheme);
+ observer.observe(document.documentElement, {
+ attributes: true,
+ attributeFilter: ['class']
+ });
+
+ return () => observer.disconnect();
+ }, []);
+
+ const services = [
+ {
+ icon: Brain,
+ title: "Trauma-Focused Therapy",
+ description: "Evidence-based TF-CBT to help children process and heal from traumatic experiences in a safe, supportive environment.",
+ backgroundImage: "https://images.unsplash.com/photo-1519494026892-80bbd2d6fd0d?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80",
+ },
+ {
+ icon: Sparkles,
+ title: "Play Therapy",
+ description: "Child-centered play therapy allowing children to express themselves naturally and build emotional regulation skills.",
+ backgroundImage: "https://images.unsplash.com/photo-1503454537195-1dcabb73ffb9?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80",
+ },
+ {
+ icon: Baby,
+ title: "Infant Mental Health",
+ description: "Specialized support for infants and toddlers, focusing on early attachment, developmental milestones, and caregiver relationships.",
+ backgroundImage: "https://images.unsplash.com/photo-1515488042361-ee00e0ddd4e4?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80",
+ },
+ {
+ icon: Users2,
+ title: "Dyadic Therapy",
+ description: "Strengthening parent-child relationships through interactive sessions that enhance communication and connection.",
+ backgroundImage: "https://images.unsplash.com/photo-1529156069898-49953e39b3ac?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80",
+ },
+ {
+ icon: HeartHandshake,
+ title: "Social-Emotional Support",
+ description: "Building emotional literacy and self-regulation skills to help children navigate relationships and challenges.",
+ backgroundImage: "https://images.unsplash.com/photo-1497486751825-1233686d5d80?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80",
+ },
+ {
+ icon: Shield,
+ title: "Relationship-Based Care",
+ description: "Fostering healing through nurturing therapeutic relationships and caregiver collaboration.",
+ backgroundImage: "https://images.unsplash.com/photo-1522202176988-66273c2fd55f?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80",
+ },
+ ];
+
+ return (
+
+ {/* Background Image */}
+
+
+ {/* Minimal overlay - allowing background image to show at near original opaqueness */}
+
+
+ {/* Very subtle gradient overlay */}
+ {!isDark && (
+
+ )}
+ {isDark && (
+
+ )}
+
+ {/* Subtle animated blobs */}
+
+
+
+
+
+
+
+
+ Specialized Services
+
+
+ Comprehensive, evidence-based therapeutic support for children and families
+
+
+
+
+ {services.map((service, index) => {
+ const Icon = service.icon;
+ return (
+
+ {/* Content */}
+
+
+
+
+
+ {service.title}
+
+
+ {service.description}
+
+
+
+ );
+ })}
+
+
+
+
+ Who I Work With
+
+
+
+ I specialize in working with children under the age of 10 who are
+ dealing with trauma, stressors, or social-emotional challenges and need understanding
+ and support.
+
+
+ The goal is to build a healthy foundation through nurturing relationships and
+ emotional literacy, helping children diminish distress and enhance self-regulation.
+
+
+
+
+
+ );
+}
+
+
diff --git a/components/ThemeProvider.tsx b/components/ThemeProvider.tsx
new file mode 100644
index 0000000..8545a13
--- /dev/null
+++ b/components/ThemeProvider.tsx
@@ -0,0 +1,57 @@
+"use client";
+
+import { createContext, useContext, useEffect, useMemo, useState } from "react";
+
+type Theme = "light" | "dark";
+
+type ThemeContextValue = {
+ theme: Theme;
+ setTheme: (t: Theme) => void;
+ toggleTheme: () => void;
+};
+
+const ThemeContext = createContext(undefined);
+
+export function useAppTheme() {
+ const ctx = useContext(ThemeContext);
+ if (!ctx) throw new Error("useAppTheme must be used within ThemeProvider");
+ return ctx;
+}
+
+export function ThemeProvider({ children }: { children: React.ReactNode }) {
+ const [theme, setThemeState] = useState("light");
+ const setTheme = (t: Theme) => setThemeState(t);
+
+ // Initialize from localStorage or system preference on mount
+ useEffect(() => {
+ const stored = typeof window !== "undefined" ? localStorage.getItem("theme") : null;
+ if (stored === "light" || stored === "dark") {
+ setThemeState(stored);
+ return;
+ }
+ const prefersDark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
+ setThemeState(prefersDark ? "dark" : "light");
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ // Apply class to and persist
+ useEffect(() => {
+ const root = document.documentElement;
+ if (theme === "dark") {
+ root.classList.add("dark");
+ } else {
+ root.classList.remove("dark");
+ }
+ localStorage.setItem("theme", theme);
+ }, [theme]);
+
+ const value = useMemo(() => ({
+ theme,
+ setTheme,
+ toggleTheme: () => setThemeState((t) => (t === "dark" ? "light" : "dark")),
+ }), [theme]);
+
+ return {children} ;
+}
+
+
diff --git a/components/ThemeToggle.tsx b/components/ThemeToggle.tsx
new file mode 100644
index 0000000..883c400
--- /dev/null
+++ b/components/ThemeToggle.tsx
@@ -0,0 +1,36 @@
+import { Moon, Sun } from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { useEffect, useState } from "react";
+
+export function ThemeToggle() {
+ const [theme, setTheme] = useState<"light" | "dark">("light");
+
+ useEffect(() => {
+ const savedTheme = localStorage.getItem("theme") as "light" | "dark" | null;
+ const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
+ const initialTheme = savedTheme || (prefersDark ? "dark" : "light");
+
+ setTheme(initialTheme);
+ document.documentElement.classList.toggle("dark", initialTheme === "dark");
+ }, []);
+
+ const toggleTheme = () => {
+ const newTheme = theme === "light" ? "dark" : "light";
+ setTheme(newTheme);
+ localStorage.setItem("theme", newTheme);
+ document.documentElement.classList.toggle("dark", newTheme === "dark");
+ };
+
+ return (
+
+
+
+
+ );
+}
diff --git a/components/ui/button.tsx b/components/ui/button.tsx
new file mode 100644
index 0000000..64ec63c
--- /dev/null
+++ b/components/ui/button.tsx
@@ -0,0 +1,60 @@
+import * as React from "react"
+import { Slot } from "@radix-ui/react-slot"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "@/lib/utils"
+
+const buttonVariants = cva(
+ "cursor-pointer inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ {
+ variants: {
+ variant: {
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
+ destructive:
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
+ outline:
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
+ secondary:
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ ghost:
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
+ icon: "size-9",
+ "icon-sm": "size-8",
+ "icon-lg": "size-10",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+function Button({
+ className,
+ variant,
+ size,
+ asChild = false,
+ ...props
+}: React.ComponentProps<"button"> &
+ VariantProps & {
+ asChild?: boolean
+ }) {
+ const Comp = asChild ? Slot : "button"
+
+ return (
+
+ )
+}
+
+export { Button, buttonVariants }
diff --git a/components/ui/calendar.tsx b/components/ui/calendar.tsx
new file mode 100644
index 0000000..6f304b5
--- /dev/null
+++ b/components/ui/calendar.tsx
@@ -0,0 +1,216 @@
+"use client"
+
+import * as React from "react"
+import {
+ ChevronDownIcon,
+ ChevronLeftIcon,
+ ChevronRightIcon,
+} from "lucide-react"
+import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
+
+import { cn } from "@/lib/utils"
+import { Button, buttonVariants } from "@/components/ui/button"
+
+function Calendar({
+ className,
+ classNames,
+ showOutsideDays = true,
+ captionLayout = "label",
+ buttonVariant = "ghost",
+ formatters,
+ components,
+ ...props
+}: React.ComponentProps & {
+ buttonVariant?: React.ComponentProps["variant"]
+}) {
+ const defaultClassNames = getDefaultClassNames()
+
+ return (
+ svg]:rotate-180`,
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
+ className
+ )}
+ captionLayout={captionLayout}
+ formatters={{
+ formatMonthDropdown: (date) =>
+ date.toLocaleString("default", { month: "short" }),
+ ...formatters,
+ }}
+ classNames={{
+ root: cn("w-fit", defaultClassNames.root),
+ months: cn(
+ "flex gap-4 flex-col md:flex-row relative",
+ defaultClassNames.months
+ ),
+ month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
+ nav: cn(
+ "flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
+ defaultClassNames.nav
+ ),
+ button_previous: cn(
+ buttonVariants({ variant: buttonVariant }),
+ "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
+ defaultClassNames.button_previous
+ ),
+ button_next: cn(
+ buttonVariants({ variant: buttonVariant }),
+ "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
+ defaultClassNames.button_next
+ ),
+ month_caption: cn(
+ "flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
+ defaultClassNames.month_caption
+ ),
+ dropdowns: cn(
+ "w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
+ defaultClassNames.dropdowns
+ ),
+ dropdown_root: cn(
+ "relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
+ defaultClassNames.dropdown_root
+ ),
+ dropdown: cn(
+ "absolute bg-popover inset-0 opacity-0",
+ defaultClassNames.dropdown
+ ),
+ caption_label: cn(
+ "select-none font-medium",
+ captionLayout === "label"
+ ? "text-sm"
+ : "rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5",
+ defaultClassNames.caption_label
+ ),
+ table: "w-full border-collapse",
+ weekdays: cn("flex", defaultClassNames.weekdays),
+ weekday: cn(
+ "text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none",
+ defaultClassNames.weekday
+ ),
+ week: cn("flex w-full mt-2", defaultClassNames.week),
+ week_number_header: cn(
+ "select-none w-(--cell-size)",
+ defaultClassNames.week_number_header
+ ),
+ week_number: cn(
+ "text-[0.8rem] select-none text-muted-foreground",
+ defaultClassNames.week_number
+ ),
+ day: cn(
+ "relative w-full h-full p-0 text-center [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none",
+ props.showWeekNumber
+ ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md"
+ : "[&:first-child[data-selected=true]_button]:rounded-l-md",
+ defaultClassNames.day
+ ),
+ range_start: cn(
+ "rounded-l-md bg-accent",
+ defaultClassNames.range_start
+ ),
+ range_middle: cn("rounded-none", defaultClassNames.range_middle),
+ range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
+ today: cn(
+ "bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
+ defaultClassNames.today
+ ),
+ outside: cn(
+ "text-muted-foreground aria-selected:text-muted-foreground",
+ defaultClassNames.outside
+ ),
+ disabled: cn(
+ "text-muted-foreground opacity-50",
+ defaultClassNames.disabled
+ ),
+ hidden: cn("invisible", defaultClassNames.hidden),
+ ...classNames,
+ }}
+ components={{
+ Root: ({ className, rootRef, ...props }) => {
+ return (
+
+ )
+ },
+ Chevron: ({ className, orientation, ...props }) => {
+ if (orientation === "left") {
+ return (
+
+ )
+ }
+
+ if (orientation === "right") {
+ return (
+
+ )
+ }
+
+ return (
+
+ )
+ },
+ DayButton: CalendarDayButton,
+ WeekNumber: ({ children, ...props }) => {
+ return (
+
+
+ {children}
+
+
+ )
+ },
+ ...components,
+ }}
+ {...props}
+ />
+ )
+}
+
+function CalendarDayButton({
+ className,
+ day,
+ modifiers,
+ ...props
+}: React.ComponentProps) {
+ const defaultClassNames = getDefaultClassNames()
+
+ const ref = React.useRef(null)
+ React.useEffect(() => {
+ if (modifiers.focused) ref.current?.focus()
+ }, [modifiers.focused])
+
+ return (
+ span]:text-xs [&>span]:opacity-70",
+ defaultClassNames.day,
+ className
+ )}
+ {...props}
+ />
+ )
+}
+
+export { Calendar, CalendarDayButton }
diff --git a/components/ui/card.tsx b/components/ui/card.tsx
new file mode 100644
index 0000000..681ad98
--- /dev/null
+++ b/components/ui/card.tsx
@@ -0,0 +1,92 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Card({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardAction({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardContent({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+export {
+ Card,
+ CardHeader,
+ CardFooter,
+ CardTitle,
+ CardAction,
+ CardDescription,
+ CardContent,
+}
diff --git a/components/ui/dropdown-menu.tsx b/components/ui/dropdown-menu.tsx
new file mode 100644
index 0000000..bbe6fb0
--- /dev/null
+++ b/components/ui/dropdown-menu.tsx
@@ -0,0 +1,257 @@
+"use client"
+
+import * as React from "react"
+import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
+import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+function DropdownMenu({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DropdownMenuPortal({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DropdownMenuTrigger({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DropdownMenuContent({
+ className,
+ sideOffset = 4,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+function DropdownMenuGroup({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DropdownMenuItem({
+ className,
+ inset,
+ variant = "default",
+ ...props
+}: React.ComponentProps & {
+ inset?: boolean
+ variant?: "default" | "destructive"
+}) {
+ return (
+
+ )
+}
+
+function DropdownMenuCheckboxItem({
+ className,
+ children,
+ checked,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+
+
+ {children}
+
+ )
+}
+
+function DropdownMenuRadioGroup({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DropdownMenuRadioItem({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+
+
+ {children}
+
+ )
+}
+
+function DropdownMenuLabel({
+ className,
+ inset,
+ ...props
+}: React.ComponentProps & {
+ inset?: boolean
+}) {
+ return (
+
+ )
+}
+
+function DropdownMenuSeparator({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DropdownMenuShortcut({
+ className,
+ ...props
+}: React.ComponentProps<"span">) {
+ return (
+
+ )
+}
+
+function DropdownMenuSub({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DropdownMenuSubTrigger({
+ className,
+ inset,
+ children,
+ ...props
+}: React.ComponentProps & {
+ inset?: boolean
+}) {
+ return (
+
+ {children}
+
+
+ )
+}
+
+function DropdownMenuSubContent({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ DropdownMenu,
+ DropdownMenuPortal,
+ DropdownMenuTrigger,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuLabel,
+ DropdownMenuItem,
+ DropdownMenuCheckboxItem,
+ DropdownMenuRadioGroup,
+ DropdownMenuRadioItem,
+ DropdownMenuSeparator,
+ DropdownMenuShortcut,
+ DropdownMenuSub,
+ DropdownMenuSubTrigger,
+ DropdownMenuSubContent,
+}
diff --git a/components/ui/input.tsx b/components/ui/input.tsx
new file mode 100644
index 0000000..8916905
--- /dev/null
+++ b/components/ui/input.tsx
@@ -0,0 +1,21 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Input({ className, type, ...props }: React.ComponentProps<"input">) {
+ return (
+
+ )
+}
+
+export { Input }
diff --git a/components/ui/popover.tsx b/components/ui/popover.tsx
new file mode 100644
index 0000000..01e468b
--- /dev/null
+++ b/components/ui/popover.tsx
@@ -0,0 +1,48 @@
+"use client"
+
+import * as React from "react"
+import * as PopoverPrimitive from "@radix-ui/react-popover"
+
+import { cn } from "@/lib/utils"
+
+function Popover({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function PopoverTrigger({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function PopoverContent({
+ className,
+ align = "center",
+ sideOffset = 4,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+function PopoverAnchor({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }
diff --git a/components/ui/select.tsx b/components/ui/select.tsx
new file mode 100644
index 0000000..25e5439
--- /dev/null
+++ b/components/ui/select.tsx
@@ -0,0 +1,187 @@
+"use client"
+
+import * as React from "react"
+import * as SelectPrimitive from "@radix-ui/react-select"
+import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+function Select({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function SelectGroup({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function SelectValue({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function SelectTrigger({
+ className,
+ size = "default",
+ children,
+ ...props
+}: React.ComponentProps & {
+ size?: "sm" | "default"
+}) {
+ return (
+
+ {children}
+
+
+
+
+ )
+}
+
+function SelectContent({
+ className,
+ children,
+ position = "popper",
+ align = "center",
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+ {children}
+
+
+
+
+ )
+}
+
+function SelectLabel({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function SelectItem({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+
+
+ {children}
+
+ )
+}
+
+function SelectSeparator({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function SelectScrollUpButton({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+function SelectScrollDownButton({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+export {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectLabel,
+ SelectScrollDownButton,
+ SelectScrollUpButton,
+ SelectSeparator,
+ SelectTrigger,
+ SelectValue,
+}
diff --git a/components/ui/sonner.tsx b/components/ui/sonner.tsx
new file mode 100644
index 0000000..9b20afe
--- /dev/null
+++ b/components/ui/sonner.tsx
@@ -0,0 +1,40 @@
+"use client"
+
+import {
+ CircleCheckIcon,
+ InfoIcon,
+ Loader2Icon,
+ OctagonXIcon,
+ TriangleAlertIcon,
+} from "lucide-react"
+import { useTheme } from "next-themes"
+import { Toaster as Sonner, type ToasterProps } from "sonner"
+
+const Toaster = ({ ...props }: ToasterProps) => {
+ const { theme = "system" } = useTheme()
+
+ return (
+ ,
+ info: ,
+ warning: ,
+ error: ,
+ loading: ,
+ }}
+ style={
+ {
+ "--normal-bg": "var(--popover)",
+ "--normal-text": "var(--popover-foreground)",
+ "--normal-border": "var(--border)",
+ "--border-radius": "var(--radius)",
+ } as React.CSSProperties
+ }
+ {...props}
+ />
+ )
+}
+
+export { Toaster }
diff --git a/components/ui/textarea.tsx b/components/ui/textarea.tsx
new file mode 100644
index 0000000..7f21b5e
--- /dev/null
+++ b/components/ui/textarea.tsx
@@ -0,0 +1,18 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
+ return (
+
+ )
+}
+
+export { Textarea }
diff --git a/components/ui/toaster.tsx b/components/ui/toaster.tsx
new file mode 100644
index 0000000..896a003
--- /dev/null
+++ b/components/ui/toaster.tsx
@@ -0,0 +1,9 @@
+"use client";
+
+// Simple toaster component - can be enhanced later with toast notifications
+export function Toaster() {
+ return null;
+}
+
+
+
diff --git a/lib/utils.ts b/lib/utils.ts
new file mode 100644
index 0000000..bd0c391
--- /dev/null
+++ b/lib/utils.ts
@@ -0,0 +1,6 @@
+import { clsx, type ClassValue } from "clsx"
+import { twMerge } from "tailwind-merge"
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs))
+}
diff --git a/next.config.ts b/next.config.ts
index e9ffa30..8d6cd13 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -1,7 +1,14 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
- /* config options here */
+ images: {
+ remotePatterns: [
+ {
+ protocol: 'https',
+ hostname: 'images.unsplash.com',
+ },
+ ],
+ },
};
export default nextConfig;
diff --git a/package.json b/package.json
index 08b55f9..3339ed1 100644
--- a/package.json
+++ b/package.json
@@ -8,22 +8,37 @@
"start": "next start",
"lint": "eslint"
},
- "engines": {
+ "engines": {
"node": ">=20.9.0"
},
"dependencies": {
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
+ "@radix-ui/react-popover": "^1.1.15",
+ "@radix-ui/react-select": "^2.2.6",
+ "@radix-ui/react-slot": "^1.2.4",
+ "class-variance-authority": "^0.7.1",
+ "clsx": "^2.1.1",
+ "date-fns": "^4.1.0",
+ "framer-motion": "^12.23.24",
+ "lucide-react": "^0.552.0",
+ "next": "16.0.1",
+ "next-themes": "^0.4.6",
"react": "19.2.0",
+ "react-day-picker": "^9.11.1",
"react-dom": "19.2.0",
- "next": "16.0.1"
+ "sonner": "^2.0.7",
+ "tailwind-merge": "^3.3.1"
},
"devDependencies": {
- "typescript": "^5",
+ "@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
- "@tailwindcss/postcss": "^4",
- "tailwindcss": "^4",
"eslint": "^9",
- "eslint-config-next": "16.0.1"
- }
+ "eslint-config-next": "16.0.1",
+ "tailwindcss": "^4",
+ "tw-animate-css": "^1.4.0",
+ "typescript": "^5"
+ },
+ "packageManager": "pnpm@10.12.3+sha512.467df2c586056165580ad6dfb54ceaad94c5a30f80893ebdec5a44c5aa73c205ae4a5bb9d5ed6bb84ea7c249ece786642bbb49d06a307df218d03da41c317417"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 64de4bb..80c05ee 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,15 +8,54 @@ importers:
.:
dependencies:
+ '@radix-ui/react-dropdown-menu':
+ specifier: ^2.1.16
+ version: 2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-popover':
+ specifier: ^1.1.15
+ version: 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-select':
+ specifier: ^2.2.6
+ version: 2.2.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-slot':
+ specifier: ^1.2.4
+ version: 1.2.4(@types/react@19.2.2)(react@19.2.0)
+ class-variance-authority:
+ specifier: ^0.7.1
+ version: 0.7.1
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
+ date-fns:
+ specifier: ^4.1.0
+ version: 4.1.0
+ framer-motion:
+ specifier: ^12.23.24
+ version: 12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ lucide-react:
+ specifier: ^0.552.0
+ version: 0.552.0(react@19.2.0)
next:
specifier: 16.0.1
version: 16.0.1(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ next-themes:
+ specifier: ^0.4.6
+ version: 0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
react:
specifier: 19.2.0
version: 19.2.0
+ react-day-picker:
+ specifier: ^9.11.1
+ version: 9.11.1(react@19.2.0)
react-dom:
specifier: 19.2.0
version: 19.2.0(react@19.2.0)
+ sonner:
+ specifier: ^2.0.7
+ version: 2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ tailwind-merge:
+ specifier: ^3.3.1
+ version: 3.3.1
devDependencies:
'@tailwindcss/postcss':
specifier: ^4
@@ -39,6 +78,9 @@ importers:
tailwindcss:
specifier: ^4
version: 4.1.16
+ tw-animate-css:
+ specifier: ^1.4.0
+ version: 1.4.0
typescript:
specifier: ^5
version: 5.9.3
@@ -116,6 +158,9 @@ packages:
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
engines: {node: '>=6.9.0'}
+ '@date-fns/tz@1.4.1':
+ resolution: {integrity: sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==}
+
'@emnapi/core@1.7.0':
resolution: {integrity: sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==}
@@ -163,6 +208,21 @@ packages:
resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@floating-ui/core@1.7.3':
+ resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==}
+
+ '@floating-ui/dom@1.7.4':
+ resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==}
+
+ '@floating-ui/react-dom@2.1.6':
+ resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+
+ '@floating-ui/utils@0.2.10':
+ resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
+
'@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'}
@@ -394,6 +454,332 @@ packages:
resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
engines: {node: '>=12.4.0'}
+ '@radix-ui/number@1.1.1':
+ resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==}
+
+ '@radix-ui/primitive@1.1.3':
+ resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==}
+
+ '@radix-ui/react-arrow@1.1.7':
+ resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-collection@1.1.7':
+ resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-compose-refs@1.1.2':
+ resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-context@1.1.2':
+ resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-direction@1.1.1':
+ resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-dismissable-layer@1.1.11':
+ resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-dropdown-menu@2.1.16':
+ resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-focus-guards@1.1.3':
+ resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-focus-scope@1.1.7':
+ resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-id@1.1.1':
+ resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-menu@2.1.16':
+ resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-popover@1.1.15':
+ resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-popper@1.2.8':
+ resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-portal@1.1.9':
+ resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-presence@1.1.5':
+ resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-primitive@2.1.3':
+ resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-roving-focus@1.1.11':
+ resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-select@2.2.6':
+ resolution: {integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-slot@1.2.3':
+ resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-slot@1.2.4':
+ resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-callback-ref@1.1.1':
+ resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-controllable-state@1.2.2':
+ resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-effect-event@0.0.2':
+ resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-escape-keydown@1.1.1':
+ resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-layout-effect@1.1.1':
+ resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-previous@1.1.1':
+ resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-rect@1.1.1':
+ resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-size@1.1.1':
+ resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-visually-hidden@1.2.3':
+ resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/rect@1.1.1':
+ resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
+
'@rtsao/scc@1.1.0':
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
@@ -685,6 +1071,10 @@ packages:
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ aria-hidden@1.2.6:
+ resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
+ engines: {node: '>=10'}
+
aria-query@5.3.2:
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
engines: {node: '>= 0.4'}
@@ -785,9 +1175,16 @@ packages:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
+ class-variance-authority@0.7.1:
+ resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
+
client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
@@ -823,6 +1220,12 @@ packages:
resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
engines: {node: '>= 0.4'}
+ date-fns-jalali@4.1.0-0:
+ resolution: {integrity: sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==}
+
+ date-fns@4.1.0:
+ resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
+
debug@3.2.7:
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
peerDependencies:
@@ -855,6 +1258,9 @@ packages:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
+ detect-node-es@1.1.0:
+ resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
+
doctrine@2.1.0:
resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
engines: {node: '>=0.10.0'}
@@ -1081,6 +1487,20 @@ packages:
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
engines: {node: '>= 0.4'}
+ framer-motion@12.23.24:
+ resolution: {integrity: sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w==}
+ peerDependencies:
+ '@emotion/is-prop-valid': '*'
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@emotion/is-prop-valid':
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
@@ -1103,6 +1523,10 @@ packages:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
+ get-nonce@1.0.1:
+ resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
+ engines: {node: '>=6'}
+
get-proto@1.0.1:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
@@ -1446,6 +1870,11 @@ packages:
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+ lucide-react@0.552.0:
+ resolution: {integrity: sha512-g9WCjmfwqbexSnZE+2cl21PCfXOcqnGeWeMTNAOGEfpPbm/ZF4YIq77Z8qWrxbu660EKuLB4nSLggoKnCb+isw==}
+ peerDependencies:
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
@@ -1471,6 +1900,12 @@ packages:
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+ motion-dom@12.23.23:
+ resolution: {integrity: sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==}
+
+ motion-utils@12.23.6:
+ resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==}
+
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@@ -1487,6 +1922,12 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+ next-themes@0.4.6:
+ resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==}
+ peerDependencies:
+ react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
+
next@16.0.1:
resolution: {integrity: sha512-e9RLSssZwd35p7/vOa+hoDFggUZIUbZhIUSLZuETCwrCVvxOs87NamoUzT+vbcNAL8Ld9GobBnWOA6SbV/arOw==}
engines: {node: '>=20.9.0'}
@@ -1611,6 +2052,12 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ react-day-picker@9.11.1:
+ resolution: {integrity: sha512-l3ub6o8NlchqIjPKrRFUCkTUEq6KwemQlfv3XZzzwpUeGwmDJ+0u0Upmt38hJyd7D/vn2dQoOoLV/qAp0o3uUw==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ react: '>=16.8.0'
+
react-dom@19.2.0:
resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==}
peerDependencies:
@@ -1619,6 +2066,36 @@ packages:
react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+ react-remove-scroll-bar@2.3.8:
+ resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-remove-scroll@2.7.1:
+ resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-style-singleton@2.2.3:
+ resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
react@19.2.0:
resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==}
engines: {node: '>=0.10.0'}
@@ -1718,6 +2195,12 @@ packages:
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
engines: {node: '>= 0.4'}
+ sonner@2.0.7:
+ resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
@@ -1781,6 +2264,9 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
+ tailwind-merge@3.3.1:
+ resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==}
+
tailwindcss@4.1.16:
resolution: {integrity: sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==}
@@ -1808,6 +2294,9 @@ packages:
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+ tw-animate-css@1.4.0:
+ resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==}
+
type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
@@ -1859,6 +2348,26 @@ packages:
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ use-callback-ref@1.3.3:
+ resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-sidecar@1.1.3:
+ resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
which-boxed-primitive@1.1.1:
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
engines: {node: '>= 0.4'}
@@ -2004,6 +2513,8 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
+ '@date-fns/tz@1.4.1': {}
+
'@emnapi/core@1.7.0':
dependencies:
'@emnapi/wasi-threads': 1.1.0
@@ -2066,6 +2577,23 @@ snapshots:
'@eslint/core': 0.17.0
levn: 0.4.1
+ '@floating-ui/core@1.7.3':
+ dependencies:
+ '@floating-ui/utils': 0.2.10
+
+ '@floating-ui/dom@1.7.4':
+ dependencies:
+ '@floating-ui/core': 1.7.3
+ '@floating-ui/utils': 0.2.10
+
+ '@floating-ui/react-dom@2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@floating-ui/dom': 1.7.4
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+
+ '@floating-ui/utils@0.2.10': {}
+
'@humanfs/core@0.19.1': {}
'@humanfs/node@0.16.7':
@@ -2236,6 +2764,322 @@ snapshots:
'@nolyfill/is-core-module@1.0.39': {}
+ '@radix-ui/number@1.1.1': {}
+
+ '@radix-ui/primitive@1.1.3': {}
+
+ '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-context@1.1.2(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-direction@1.1.1(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-id@1.1.1(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ aria-hidden: 1.2.6
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ react-remove-scroll: 2.7.1(@types/react@19.2.2)(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.2.0)
+ aria-hidden: 1.2.6
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ react-remove-scroll: 2.7.1(@types/react@19.2.2)(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@floating-ui/react-dom': 2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/rect': 1.1.1
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/number': 1.1.1
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ aria-hidden: 1.2.6
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ react-remove-scroll: 2.7.1(@types/react@19.2.2)(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/react-slot@1.2.3(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-slot@1.2.4(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.2)(react@19.2.0)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ '@radix-ui/rect': 1.1.1
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-use-size@1.1.1(@types/react@19.2.2)(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0)
+ react: 19.2.0
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+ '@types/react-dom': 19.2.2(@types/react@19.2.2)
+
+ '@radix-ui/rect@1.1.1': {}
+
'@rtsao/scc@1.1.0': {}
'@swc/helpers@0.5.15':
@@ -2505,6 +3349,10 @@ snapshots:
argparse@2.0.1: {}
+ aria-hidden@1.2.6:
+ dependencies:
+ tslib: 2.8.1
+
aria-query@5.3.2: {}
array-buffer-byte-length@1.0.2:
@@ -2637,8 +3485,14 @@ snapshots:
ansi-styles: 4.3.0
supports-color: 7.2.0
+ class-variance-authority@0.7.1:
+ dependencies:
+ clsx: 2.1.1
+
client-only@0.0.1: {}
+ clsx@2.1.1: {}
+
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
@@ -2677,6 +3531,10 @@ snapshots:
es-errors: 1.3.0
is-data-view: 1.0.2
+ date-fns-jalali@4.1.0-0: {}
+
+ date-fns@4.1.0: {}
+
debug@3.2.7:
dependencies:
ms: 2.1.3
@@ -2701,6 +3559,8 @@ snapshots:
detect-libc@2.1.2: {}
+ detect-node-es@1.1.0: {}
+
doctrine@2.1.0:
dependencies:
esutils: 2.0.3
@@ -3082,6 +3942,15 @@ snapshots:
dependencies:
is-callable: 1.2.7
+ framer-motion@12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
+ dependencies:
+ motion-dom: 12.23.23
+ motion-utils: 12.23.6
+ tslib: 2.8.1
+ optionalDependencies:
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+
function-bind@1.1.2: {}
function.prototype.name@1.1.8:
@@ -3112,6 +3981,8 @@ snapshots:
hasown: 2.0.2
math-intrinsics: 1.1.0
+ get-nonce@1.0.1: {}
+
get-proto@1.0.1:
dependencies:
dunder-proto: 1.0.1
@@ -3427,6 +4298,10 @@ snapshots:
dependencies:
yallist: 3.1.1
+ lucide-react@0.552.0(react@19.2.0):
+ dependencies:
+ react: 19.2.0
+
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -3450,6 +4325,12 @@ snapshots:
minimist@1.2.8: {}
+ motion-dom@12.23.23:
+ dependencies:
+ motion-utils: 12.23.6
+
+ motion-utils@12.23.6: {}
+
ms@2.1.3: {}
nanoid@3.3.11: {}
@@ -3458,6 +4339,11 @@ snapshots:
natural-compare@1.4.0: {}
+ next-themes@0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
+ dependencies:
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+
next@16.0.1(@babel/core@7.28.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
dependencies:
'@next/env': 16.0.1
@@ -3590,6 +4476,13 @@ snapshots:
queue-microtask@1.2.3: {}
+ react-day-picker@9.11.1(react@19.2.0):
+ dependencies:
+ '@date-fns/tz': 1.4.1
+ date-fns: 4.1.0
+ date-fns-jalali: 4.1.0-0
+ react: 19.2.0
+
react-dom@19.2.0(react@19.2.0):
dependencies:
react: 19.2.0
@@ -3597,6 +4490,33 @@ snapshots:
react-is@16.13.1: {}
+ react-remove-scroll-bar@2.3.8(@types/react@19.2.2)(react@19.2.0):
+ dependencies:
+ react: 19.2.0
+ react-style-singleton: 2.2.3(@types/react@19.2.2)(react@19.2.0)
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ react-remove-scroll@2.7.1(@types/react@19.2.2)(react@19.2.0):
+ dependencies:
+ react: 19.2.0
+ react-remove-scroll-bar: 2.3.8(@types/react@19.2.2)(react@19.2.0)
+ react-style-singleton: 2.2.3(@types/react@19.2.2)(react@19.2.0)
+ tslib: 2.8.1
+ use-callback-ref: 1.3.3(@types/react@19.2.2)(react@19.2.0)
+ use-sidecar: 1.1.3(@types/react@19.2.2)(react@19.2.0)
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ react-style-singleton@2.2.3(@types/react@19.2.2)(react@19.2.0):
+ dependencies:
+ get-nonce: 1.0.1
+ react: 19.2.0
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.2.2
+
react@19.2.0: {}
reflect.getprototypeof@1.0.10:
@@ -3752,6 +4672,11 @@ snapshots:
side-channel-map: 1.0.1
side-channel-weakmap: 1.0.2
+ sonner@2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
+ dependencies:
+ react: 19.2.0
+ react-dom: 19.2.0(react@19.2.0)
+
source-map-js@1.2.1: {}
stable-hash@0.0.5: {}
@@ -3828,6 +4753,8 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
+ tailwind-merge@3.3.1: {}
+
tailwindcss@4.1.16: {}
tapable@2.3.0: {}
@@ -3854,6 +4781,8 @@ snapshots:
tslib@2.8.1: {}
+ tw-animate-css@1.4.0: {}
+
type-check@0.4.0:
dependencies:
prelude-ls: 1.2.1
@@ -3947,6 +4876,21 @@ snapshots:
dependencies:
punycode: 2.3.1
+ use-callback-ref@1.3.3(@types/react@19.2.2)(react@19.2.0):
+ dependencies:
+ react: 19.2.0
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.2.2
+
+ use-sidecar@1.1.3(@types/react@19.2.2)(react@19.2.0):
+ dependencies:
+ detect-node-es: 1.1.0
+ react: 19.2.0
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.2.2
+
which-boxed-primitive@1.1.1:
dependencies:
is-bigint: 1.1.0
diff --git a/public/3786819.jpg b/public/3786819.jpg
new file mode 100644
index 0000000..cdb4bcc
Binary files /dev/null and b/public/3786819.jpg differ
diff --git a/public/doctors.png b/public/doctors.png
new file mode 100644
index 0000000..c8e4281
Binary files /dev/null and b/public/doctors.png differ
diff --git a/public/hshot.jpeg b/public/hshot.jpeg
new file mode 100644
index 0000000..d3f3552
Binary files /dev/null and b/public/hshot.jpeg differ
diff --git a/public/large.jpeg b/public/large.jpeg
new file mode 100644
index 0000000..d933158
Binary files /dev/null and b/public/large.jpeg differ
diff --git a/public/mmmfil.jpeg b/public/mmmfil.jpeg
new file mode 100644
index 0000000..c56648b
Binary files /dev/null and b/public/mmmfil.jpeg differ