-
+
+
LIMITED TIME
-
+
Ready to Showcase
-
+
Your Masterpiece?
-
+
Join hundreds of talented artists from SJEC in this creative
celebration. Submit your artwork and let the world vote for your
talent.
@@ -49,7 +43,7 @@ export default function CTA() {
VIEW RULES
@@ -61,11 +55,11 @@ export default function CTA() {
whileInView={{ opacity: 1 }}
viewport={{ once: true }}
transition={{ delay: 0.3 }}
- className="mt-12 inline-flex items-center gap-3 bg-zinc-100 px-6 py-3 rounded-full"
+ className="mt-12 inline-flex items-center gap-3 bg-zinc-900 border border-zinc-800 px-6 py-3 rounded-full"
>
-
- Submissions close on February 28, 2026
+
+ Submissions close on February 28, 2026
diff --git a/app/components/Categories.tsx b/app/components/Categories.tsx
index ad6a9c8..aac3cbe 100644
--- a/app/components/Categories.tsx
+++ b/app/components/Categories.tsx
@@ -1,60 +1,235 @@
"use client";
+import { useEffect, useRef } from "react";
import { motion } from "framer-motion";
-import { Palette, Monitor, FileImage, ArrowRight } from "lucide-react";
+import { Palette, Monitor, FileImage, ArrowRight, LucideIcon } from "lucide-react";
import Link from "next/link";
+import gsap from "gsap";
const categories = [
{
icon: Monitor,
title: "Digital Art",
description:
- "Create stunning digital masterpieces using any software of your choice. From illustrations to photo manipulations.",
+ "Create stunning digital masterpieces using any software of your choice.",
color: "from-violet-500 to-purple-600",
- bgColor: "bg-violet-50",
+ bgColor: "bg-violet-500",
},
{
icon: Palette,
title: "Paintings",
description:
- "Traditional paintings in any medium - oil, acrylic, watercolor. Capture the essence of classic artistry.",
+ "Traditional paintings in any medium - oil, acrylic, watercolor.",
color: "from-orange-500 to-red-500",
- bgColor: "bg-orange-50",
+ bgColor: "bg-orange-500",
},
{
icon: FileImage,
title: "Poster Making",
description:
- "Design impactful posters that communicate powerful messages. Blend creativity with purpose.",
+ "Design impactful posters that communicate powerful messages.",
color: "from-lime-500 to-green-500",
- bgColor: "bg-lime-50",
+ bgColor: "bg-lime-500",
},
];
-const containerVariants = {
- hidden: { opacity: 0 },
- visible: {
- opacity: 1,
- transition: {
- staggerChildren: 0.2,
- },
- },
-};
+// BounceCards Component for Category Cards
+interface CategoryCard {
+ icon: LucideIcon;
+ title: string;
+ description: string;
+ color: string;
+ bgColor: string;
+}
-const itemVariants = {
- hidden: { opacity: 0, y: 30 },
- visible: {
- opacity: 1,
- y: 0,
- transition: {
- duration: 0.6,
- },
- },
-};
+interface BounceCardsProps {
+ className?: string;
+ cards: CategoryCard[];
+ containerWidth?: number;
+ containerHeight?: number;
+ animationDelay?: number;
+ animationStagger?: number;
+ easeType?: string;
+ transformStyles?: string[];
+ enableHover?: boolean;
+}
+
+function BounceCards({
+ className = "",
+ cards,
+ containerWidth = 500,
+ containerHeight = 400,
+ animationDelay = 0.5,
+ animationStagger = 0.08,
+ easeType = "elastic.out(1, 0.8)",
+ transformStyles = [
+ "rotate(-8deg) translate(-200px)",
+ "rotate(0deg)",
+ "rotate(8deg) translate(200px)",
+ ],
+ enableHover = true,
+}: BounceCardsProps) {
+ const containerRef = useRef(null);
+
+ useEffect(() => {
+ const ctx = gsap.context(() => {
+ gsap.fromTo(
+ ".card",
+ { scale: 0 },
+ {
+ scale: 1,
+ stagger: animationStagger,
+ ease: easeType,
+ delay: animationDelay,
+ }
+ );
+ }, containerRef);
+ return () => ctx.revert();
+ }, [animationDelay, animationStagger, easeType]);
+
+ const getNoRotationTransform = (transformStr: string): string => {
+ const hasRotate = /rotate\([\s\S]*?\)/.test(transformStr);
+ if (hasRotate) {
+ return transformStr.replace(/rotate\([\s\S]*?\)/, "rotate(0deg)");
+ } else if (transformStr === "none") {
+ return "rotate(0deg)";
+ } else {
+ return `${transformStr} rotate(0deg)`;
+ }
+ };
+
+ const getPushedTransform = (
+ baseTransform: string,
+ offsetX: number
+ ): string => {
+ const translateRegex = /translate\(([-0-9.]+)px\)/;
+ const match = baseTransform.match(translateRegex);
+ if (match) {
+ const currentX = parseFloat(match[1]);
+ const newX = currentX + offsetX;
+ return baseTransform.replace(translateRegex, `translate(${newX}px)`);
+ } else {
+ return baseTransform === "none"
+ ? `translate(${offsetX}px)`
+ : `${baseTransform} translate(${offsetX}px)`;
+ }
+ };
+
+ const pushSiblings = (hoveredIdx: number) => {
+ const q = gsap.utils.selector(containerRef);
+ if (!enableHover || !containerRef.current) return;
+
+ cards.forEach((_, i) => {
+ const selector = q(`.card-${i}`);
+ gsap.killTweensOf(selector);
+
+ const baseTransform = transformStyles[i] || "none";
+
+ if (i === hoveredIdx) {
+ const noRotation = getNoRotationTransform(baseTransform);
+ gsap.to(selector, {
+ transform: noRotation,
+ zIndex: 10,
+ duration: 0.4,
+ ease: "back.out(1.4)",
+ overwrite: "auto",
+ });
+ } else {
+ const offsetX = i < hoveredIdx ? -80 : 80;
+ const pushedTransform = getPushedTransform(baseTransform, offsetX);
+
+ const distance = Math.abs(hoveredIdx - i);
+ const delay = distance * 0.05;
+
+ gsap.to(selector, {
+ transform: pushedTransform,
+ zIndex: 1,
+ duration: 0.4,
+ ease: "back.out(1.4)",
+ delay,
+ overwrite: "auto",
+ });
+ }
+ });
+ };
+
+ const resetSiblings = () => {
+ if (!enableHover || !containerRef.current) return;
+ const q = gsap.utils.selector(containerRef);
+
+ cards.forEach((_, i) => {
+ const selector = q(`.card-${i}`);
+ gsap.killTweensOf(selector);
+
+ const baseTransform = transformStyles[i] || "none";
+ gsap.to(selector, {
+ transform: baseTransform,
+ zIndex: cards.length - i,
+ duration: 0.4,
+ ease: "back.out(1.4)",
+ overwrite: "auto",
+ });
+ });
+ };
+
+ return (
+
+ {cards.map((card, idx) => (
+
pushSiblings(idx)}
+ onMouseLeave={resetSiblings}
+ >
+ {/* Icon */}
+
+
+
+
+ {/* Title */}
+
{card.title}
+
+ {/* Description */}
+
+ {card.description}
+
+
+ {/* Submit Link */}
+
+
+ ))}
+
+ );
+}
export default function Categories() {
+ const transformStyles = [
+ "rotate(-8deg) translate(-220px)",
+ "rotate(0deg)",
+ "rotate(8deg) translate(220px)",
+ ];
+
return (
-
+
{/* Section Header */}
CATEGORIES
-
+
Three Ways to
-
- {" "}
- Express
-
+ Express
-
+
Choose your canvas, unleash your creativity. Each category offers a
unique way to showcase your artistic vision.
- {/* Categories Grid */}
+ {/* BounceCards with Category Cards */}
- {categories.map((category) => (
-
- {/* Background Gradient on Hover */}
-
-
- {/* Icon */}
-
-
-
-
- {/* Content */}
-
- {category.title}
-
-
- {category.description}
-
-
- {/* Link */}
-
- Submit Now
-
-
-
- ))}
+
diff --git a/app/components/Hero.tsx b/app/components/Hero.tsx
index d5f1a19..bccbbad 100644
--- a/app/components/Hero.tsx
+++ b/app/components/Hero.tsx
@@ -14,10 +14,12 @@ function TileGrid() {
const handleMouseEnter = useCallback((index: number) => {
const tile = tilesRef.current[index];
if (tile) {
+ gsap.killTweensOf(tile);
gsap.to(tile, {
rotateY: 180,
- duration: 0.4,
- ease: "power2.out",
+ duration: 0.5,
+ ease: "power2.inOut",
+ overwrite: true,
});
}
}, []);
@@ -25,10 +27,12 @@ function TileGrid() {
const handleMouseLeave = useCallback((index: number) => {
const tile = tilesRef.current[index];
if (tile) {
+ gsap.killTweensOf(tile);
gsap.to(tile, {
rotateY: 0,
- duration: 0.4,
- ease: "power2.out",
+ duration: 0.5,
+ ease: "power2.inOut",
+ overwrite: true,
});
}
}, []);
@@ -53,7 +57,10 @@ function TileGrid() {
{ tilesRef.current[index] = el; }}
className="w-full h-full relative"
- style={{ transformStyle: "preserve-3d" }}
+ style={{
+ transformStyle: "preserve-3d",
+ willChange: "transform",
+ }}
>
{/* Front - Black */}
-
+
From canvas to screen, showcase your creativity and let your
artwork speak to the world.
-
+
+
+ {/* Scroll Indicator */}
+
-
- {/* Scroll Indicator - positioned above the marquee */}
-
{/* Bottom Marquee */}
diff --git a/next.config.ts b/next.config.ts
index e9ffa30..a9194aa 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;
From 7cb4de4fcc2acce8f8abcf3c9d3d9b9ba47c2d1c Mon Sep 17 00:00:00 2001
From: PlatyPuspus <23h46.shovin@sjec.ac.in>
Date: Sat, 21 Feb 2026 15:27:18 +0530
Subject: [PATCH 3/8] Fixed the color in the footer
---
app/components/Footer.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/components/Footer.tsx b/app/components/Footer.tsx
index d43601f..4fc7924 100644
--- a/app/components/Footer.tsx
+++ b/app/components/Footer.tsx
@@ -19,7 +19,7 @@ const footerLinks = {
export default function Footer() {
return (
-