projects section left to be done
Browse files- components/projects.tsx +90 -7
- components/ui/button.tsx +56 -0
- components/ui/card.tsx +79 -0
- package-lock.json +37 -3
- package.json +1 -0
components/projects.tsx
CHANGED
|
@@ -1,15 +1,98 @@
|
|
| 1 |
'use client'
|
| 2 |
import React from 'react'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
|
| 4 |
const Projects = () => {
|
| 5 |
return (
|
| 6 |
-
<
|
| 7 |
-
<div className=
|
| 8 |
-
<div>
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
</
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
)
|
| 14 |
}
|
| 15 |
|
|
|
|
| 1 |
'use client'
|
| 2 |
import React from 'react'
|
| 3 |
+
import Image from "next/image"
|
| 4 |
+
import Link from "next/link"
|
| 5 |
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
| 6 |
+
import { Button } from "@/components/ui/button"
|
| 7 |
+
import { ExternalLink } from 'lucide-react'
|
| 8 |
+
|
| 9 |
+
const projects = [
|
| 10 |
+
{
|
| 11 |
+
title: "ClearSkies",
|
| 12 |
+
description: "A weather information platform serving over 60 users from the college, improving access to accurate weather data. Built with React.js, OpenWeatherAPI, and MongoDB.",
|
| 13 |
+
demo: "https://clearskies-demo.com",
|
| 14 |
+
date: "February 2024",
|
| 15 |
+
image: "/placeholder.svg?height=400&width=600"
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
title: "Inspirus8",
|
| 19 |
+
description: "Official website for Inspirus 8, increasing event registration by 50%. Built using Next.js, Spline, and TailwindCSS for optimized performance and interactive 3D graphics.",
|
| 20 |
+
demo: "https://inspirus8.com",
|
| 21 |
+
date: "September 2024",
|
| 22 |
+
image: "/placeholder.svg?height=400&width=600"
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
title: "Land Records",
|
| 26 |
+
description: "A land records management system designed for over 100 users, reducing inquiry response time by 40%. Built with Next.js, TailwindCSS, and MySQL.",
|
| 27 |
+
demo: "https://landrecords-demo.com",
|
| 28 |
+
date: "November 2024",
|
| 29 |
+
image: "/placeholder.svg?height=400&width=600"
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
title: "Shadow's of Tomorrow",
|
| 33 |
+
description: "A 2D RPG Game developed using Godot 4 Game Engine, integrated with AWS services like AWS Lambda and AWS Bedrock.",
|
| 34 |
+
demo: "https://shadows-demo.com",
|
| 35 |
+
date: "January 2025",
|
| 36 |
+
image: "/placeholder.svg?height=400&width=600"
|
| 37 |
+
}
|
| 38 |
+
]
|
| 39 |
+
|
| 40 |
+
interface ProjectCardProps {
|
| 41 |
+
title: string
|
| 42 |
+
description: string
|
| 43 |
+
demo: string
|
| 44 |
+
date: string
|
| 45 |
+
image: string
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
const ProjectCard = ({ title, description, demo, date, image }: ProjectCardProps) => {
|
| 49 |
+
return (
|
| 50 |
+
<Card className="group relative overflow-hidden hover:shadow-xl transition-shadow duration-300 bg-secondary/10 border-secondary/30">
|
| 51 |
+
<div className="absolute inset-0 bg-gradient-to-r from-primary/10 to-accent/10 opacity-0 group-hover:opacity-100 transition-opacity" />
|
| 52 |
+
<CardHeader>
|
| 53 |
+
<CardTitle className="text-primary">{title}</CardTitle>
|
| 54 |
+
<CardDescription className="text-muted-foreground">{date}</CardDescription>
|
| 55 |
+
</CardHeader>
|
| 56 |
+
<CardContent>
|
| 57 |
+
<div className="relative h-48 mb-4 overflow-hidden rounded-lg">
|
| 58 |
+
<Image
|
| 59 |
+
src={image || "/placeholder.svg"}
|
| 60 |
+
alt={title}
|
| 61 |
+
fill
|
| 62 |
+
className="object-cover transition-transform duration-300 group-hover:scale-110"
|
| 63 |
+
/>
|
| 64 |
+
</div>
|
| 65 |
+
<p className="mb-4 text-muted-foreground">{description}</p>
|
| 66 |
+
<Button
|
| 67 |
+
asChild
|
| 68 |
+
className="bg-gradient-to-r from-primary via-accent to-secondary hover:opacity-90 transition-opacity text-white shadow-lg hover:shadow-xl"
|
| 69 |
+
>
|
| 70 |
+
<Link href={demo} target="_blank" className="flex items-center">
|
| 71 |
+
<span className="relative z-10">View Demo</span>
|
| 72 |
+
<ExternalLink className="ml-2 h-4 w-4 relative z-10" />
|
| 73 |
+
</Link>
|
| 74 |
+
</Button>
|
| 75 |
+
</CardContent>
|
| 76 |
+
</Card>
|
| 77 |
+
)
|
| 78 |
+
}
|
| 79 |
|
| 80 |
const Projects = () => {
|
| 81 |
return (
|
| 82 |
+
<section id="projects" className="py-24 lg:py-32 bg-gradient-to-b from-background to-secondary/10">
|
| 83 |
+
<div className="container">
|
| 84 |
+
<div className="mx-auto max-w-[980px]">
|
| 85 |
+
<h2 className="text-3xl font-bold tracking-tighter md:text-4xl text-center mb-12 text-primary">
|
| 86 |
+
Projects
|
| 87 |
+
</h2>
|
| 88 |
+
<div className="grid gap-6 md:grid-cols-2">
|
| 89 |
+
{projects.map((project) => (
|
| 90 |
+
<ProjectCard key={project.title} {...project} />
|
| 91 |
+
))}
|
| 92 |
+
</div>
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
</section>
|
| 96 |
)
|
| 97 |
}
|
| 98 |
|
components/ui/button.tsx
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from "react"
|
| 2 |
+
import { Slot } from "@radix-ui/react-slot"
|
| 3 |
+
import { cva, type VariantProps } from "class-variance-authority"
|
| 4 |
+
|
| 5 |
+
import { cn } from "@/lib/utils"
|
| 6 |
+
|
| 7 |
+
const buttonVariants = cva(
|
| 8 |
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
| 9 |
+
{
|
| 10 |
+
variants: {
|
| 11 |
+
variant: {
|
| 12 |
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
| 13 |
+
destructive:
|
| 14 |
+
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
| 15 |
+
outline:
|
| 16 |
+
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
| 17 |
+
secondary:
|
| 18 |
+
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
| 19 |
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
| 20 |
+
link: "text-primary underline-offset-4 hover:underline",
|
| 21 |
+
},
|
| 22 |
+
size: {
|
| 23 |
+
default: "h-10 px-4 py-2",
|
| 24 |
+
sm: "h-9 rounded-md px-3",
|
| 25 |
+
lg: "h-11 rounded-md px-8",
|
| 26 |
+
icon: "h-10 w-10",
|
| 27 |
+
},
|
| 28 |
+
},
|
| 29 |
+
defaultVariants: {
|
| 30 |
+
variant: "default",
|
| 31 |
+
size: "default",
|
| 32 |
+
},
|
| 33 |
+
}
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
+
export interface ButtonProps
|
| 37 |
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
| 38 |
+
VariantProps<typeof buttonVariants> {
|
| 39 |
+
asChild?: boolean
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
| 43 |
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
| 44 |
+
const Comp = asChild ? Slot : "button"
|
| 45 |
+
return (
|
| 46 |
+
<Comp
|
| 47 |
+
className={cn(buttonVariants({ variant, size, className }))}
|
| 48 |
+
ref={ref}
|
| 49 |
+
{...props}
|
| 50 |
+
/>
|
| 51 |
+
)
|
| 52 |
+
}
|
| 53 |
+
)
|
| 54 |
+
Button.displayName = "Button"
|
| 55 |
+
|
| 56 |
+
export { Button, buttonVariants }
|
components/ui/card.tsx
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from "react"
|
| 2 |
+
|
| 3 |
+
import { cn } from "@/lib/utils"
|
| 4 |
+
|
| 5 |
+
const Card = React.forwardRef<
|
| 6 |
+
HTMLDivElement,
|
| 7 |
+
React.HTMLAttributes<HTMLDivElement>
|
| 8 |
+
>(({ className, ...props }, ref) => (
|
| 9 |
+
<div
|
| 10 |
+
ref={ref}
|
| 11 |
+
className={cn(
|
| 12 |
+
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
| 13 |
+
className
|
| 14 |
+
)}
|
| 15 |
+
{...props}
|
| 16 |
+
/>
|
| 17 |
+
))
|
| 18 |
+
Card.displayName = "Card"
|
| 19 |
+
|
| 20 |
+
const CardHeader = React.forwardRef<
|
| 21 |
+
HTMLDivElement,
|
| 22 |
+
React.HTMLAttributes<HTMLDivElement>
|
| 23 |
+
>(({ className, ...props }, ref) => (
|
| 24 |
+
<div
|
| 25 |
+
ref={ref}
|
| 26 |
+
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
| 27 |
+
{...props}
|
| 28 |
+
/>
|
| 29 |
+
))
|
| 30 |
+
CardHeader.displayName = "CardHeader"
|
| 31 |
+
|
| 32 |
+
const CardTitle = React.forwardRef<
|
| 33 |
+
HTMLDivElement,
|
| 34 |
+
React.HTMLAttributes<HTMLDivElement>
|
| 35 |
+
>(({ className, ...props }, ref) => (
|
| 36 |
+
<div
|
| 37 |
+
ref={ref}
|
| 38 |
+
className={cn(
|
| 39 |
+
"text-2xl font-semibold leading-none tracking-tight",
|
| 40 |
+
className
|
| 41 |
+
)}
|
| 42 |
+
{...props}
|
| 43 |
+
/>
|
| 44 |
+
))
|
| 45 |
+
CardTitle.displayName = "CardTitle"
|
| 46 |
+
|
| 47 |
+
const CardDescription = React.forwardRef<
|
| 48 |
+
HTMLDivElement,
|
| 49 |
+
React.HTMLAttributes<HTMLDivElement>
|
| 50 |
+
>(({ className, ...props }, ref) => (
|
| 51 |
+
<div
|
| 52 |
+
ref={ref}
|
| 53 |
+
className={cn("text-sm text-muted-foreground", className)}
|
| 54 |
+
{...props}
|
| 55 |
+
/>
|
| 56 |
+
))
|
| 57 |
+
CardDescription.displayName = "CardDescription"
|
| 58 |
+
|
| 59 |
+
const CardContent = React.forwardRef<
|
| 60 |
+
HTMLDivElement,
|
| 61 |
+
React.HTMLAttributes<HTMLDivElement>
|
| 62 |
+
>(({ className, ...props }, ref) => (
|
| 63 |
+
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
| 64 |
+
))
|
| 65 |
+
CardContent.displayName = "CardContent"
|
| 66 |
+
|
| 67 |
+
const CardFooter = React.forwardRef<
|
| 68 |
+
HTMLDivElement,
|
| 69 |
+
React.HTMLAttributes<HTMLDivElement>
|
| 70 |
+
>(({ className, ...props }, ref) => (
|
| 71 |
+
<div
|
| 72 |
+
ref={ref}
|
| 73 |
+
className={cn("flex items-center p-6 pt-0", className)}
|
| 74 |
+
{...props}
|
| 75 |
+
/>
|
| 76 |
+
))
|
| 77 |
+
CardFooter.displayName = "CardFooter"
|
| 78 |
+
|
| 79 |
+
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
package-lock.json
CHANGED
|
@@ -8,6 +8,7 @@
|
|
| 8 |
"name": "reuben-fernandes",
|
| 9 |
"version": "0.1.0",
|
| 10 |
"dependencies": {
|
|
|
|
| 11 |
"class-variance-authority": "^0.7.1",
|
| 12 |
"clsx": "^2.1.1",
|
| 13 |
"framer-motion": "^11.18.1",
|
|
@@ -464,6 +465,39 @@
|
|
| 464 |
"node": ">=14"
|
| 465 |
}
|
| 466 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 467 |
"node_modules/@rtsao/scc": {
|
| 468 |
"version": "1.1.0",
|
| 469 |
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
|
@@ -515,14 +549,14 @@
|
|
| 515 |
"version": "15.7.14",
|
| 516 |
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
|
| 517 |
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
|
| 518 |
-
"
|
| 519 |
"license": "MIT"
|
| 520 |
},
|
| 521 |
"node_modules/@types/react": {
|
| 522 |
"version": "18.3.18",
|
| 523 |
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz",
|
| 524 |
"integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==",
|
| 525 |
-
"
|
| 526 |
"license": "MIT",
|
| 527 |
"dependencies": {
|
| 528 |
"@types/prop-types": "*",
|
|
@@ -1356,7 +1390,7 @@
|
|
| 1356 |
"version": "3.1.3",
|
| 1357 |
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
| 1358 |
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
| 1359 |
-
"
|
| 1360 |
"license": "MIT"
|
| 1361 |
},
|
| 1362 |
"node_modules/damerau-levenshtein": {
|
|
|
|
| 8 |
"name": "reuben-fernandes",
|
| 9 |
"version": "0.1.0",
|
| 10 |
"dependencies": {
|
| 11 |
+
"@radix-ui/react-slot": "^1.1.1",
|
| 12 |
"class-variance-authority": "^0.7.1",
|
| 13 |
"clsx": "^2.1.1",
|
| 14 |
"framer-motion": "^11.18.1",
|
|
|
|
| 465 |
"node": ">=14"
|
| 466 |
}
|
| 467 |
},
|
| 468 |
+
"node_modules/@radix-ui/react-compose-refs": {
|
| 469 |
+
"version": "1.1.1",
|
| 470 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
|
| 471 |
+
"integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
|
| 472 |
+
"license": "MIT",
|
| 473 |
+
"peerDependencies": {
|
| 474 |
+
"@types/react": "*",
|
| 475 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 476 |
+
},
|
| 477 |
+
"peerDependenciesMeta": {
|
| 478 |
+
"@types/react": {
|
| 479 |
+
"optional": true
|
| 480 |
+
}
|
| 481 |
+
}
|
| 482 |
+
},
|
| 483 |
+
"node_modules/@radix-ui/react-slot": {
|
| 484 |
+
"version": "1.1.1",
|
| 485 |
+
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz",
|
| 486 |
+
"integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==",
|
| 487 |
+
"license": "MIT",
|
| 488 |
+
"dependencies": {
|
| 489 |
+
"@radix-ui/react-compose-refs": "1.1.1"
|
| 490 |
+
},
|
| 491 |
+
"peerDependencies": {
|
| 492 |
+
"@types/react": "*",
|
| 493 |
+
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
| 494 |
+
},
|
| 495 |
+
"peerDependenciesMeta": {
|
| 496 |
+
"@types/react": {
|
| 497 |
+
"optional": true
|
| 498 |
+
}
|
| 499 |
+
}
|
| 500 |
+
},
|
| 501 |
"node_modules/@rtsao/scc": {
|
| 502 |
"version": "1.1.0",
|
| 503 |
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
|
|
|
| 549 |
"version": "15.7.14",
|
| 550 |
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
|
| 551 |
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
|
| 552 |
+
"devOptional": true,
|
| 553 |
"license": "MIT"
|
| 554 |
},
|
| 555 |
"node_modules/@types/react": {
|
| 556 |
"version": "18.3.18",
|
| 557 |
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz",
|
| 558 |
"integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==",
|
| 559 |
+
"devOptional": true,
|
| 560 |
"license": "MIT",
|
| 561 |
"dependencies": {
|
| 562 |
"@types/prop-types": "*",
|
|
|
|
| 1390 |
"version": "3.1.3",
|
| 1391 |
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
| 1392 |
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
| 1393 |
+
"devOptional": true,
|
| 1394 |
"license": "MIT"
|
| 1395 |
},
|
| 1396 |
"node_modules/damerau-levenshtein": {
|
package.json
CHANGED
|
@@ -9,6 +9,7 @@
|
|
| 9 |
"lint": "next lint"
|
| 10 |
},
|
| 11 |
"dependencies": {
|
|
|
|
| 12 |
"class-variance-authority": "^0.7.1",
|
| 13 |
"clsx": "^2.1.1",
|
| 14 |
"framer-motion": "^11.18.1",
|
|
|
|
| 9 |
"lint": "next lint"
|
| 10 |
},
|
| 11 |
"dependencies": {
|
| 12 |
+
"@radix-ui/react-slot": "^1.1.1",
|
| 13 |
"class-variance-authority": "^0.7.1",
|
| 14 |
"clsx": "^2.1.1",
|
| 15 |
"framer-motion": "^11.18.1",
|