Skip to content

Commit 7e6da0b

Browse files
committed
hm🔥 landing updates add 3d workflow and ✅ Logos
1 parent 7d60547 commit 7e6da0b

24 files changed

+440
-33
lines changed

‎bun.lockb

53 KB
Binary file not shown.

‎components/chromoviz/about.tsx

+18-2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@ const team: TeamMember[] = [
8787
researchgate: "https://www.researchgate.net/profile/Ajay-Bhatia-5",
8888
scholar: "https://scholar.google.com"
8989
}
90+
},
91+
{
92+
name: "Dr. Lata Rani",
93+
role: "Scientist II, Genomics Facility | Hematological malignancies",
94+
bio: "Centralized Core Research Facility (CCRF), AIIMS, New Delhi | Specializing in genomics and molecular biology research",
95+
avatar: "bg-gradient-to-br from-violet-500 to-indigo-500",
96+
image: "https://scholar.googleusercontent.com/citations?view_op=medium_photo&user=oyhfOq4AAAAJ&citpid=2",
97+
links: {
98+
scholar: "https://scholar.google.com/citations?user=oyhfOq4AAAAJ&hl=en",
99+
}
90100
}
91101
];
92102

@@ -122,6 +132,12 @@ const teamMembers = [
122132
designation: "Data Analyst",
123133
image: team[4].image,
124134
},
135+
{
136+
id: 6,
137+
name: "Dr. Lata Rani",
138+
designation: "Scientist II, AIIMS",
139+
image: team[5].image,
140+
},
125141
];
126142

127143
const fadeIn = {
@@ -242,7 +258,7 @@ export function AboutSheet({ children }: { children?: React.ReactNode }) {
242258
<Separator className="my-4" />
243259

244260
{/* Team Members */}
245-
{[team[0], team[2], team[3], team[4]].map((member) => (
261+
{[team[0], team[2], team[3], team[4], team[5]].map((member) => (
246262
<motion.div
247263
key={member.name}
248264
variants={fadeIn}
@@ -324,7 +340,7 @@ export function AboutSheet({ children }: { children?: React.ReactNode }) {
324340
<motion.div variants={fadeIn}>
325341
<h3 className="text-lg font-semibold mb-2">Citation</h3>
326342
<code className="block text-sm bg-muted p-4 rounded-md">
327-
Pruthi, P., Narayan, J., Agarwal, P., Shukla, N., & Bhatia, A. (2024). CHITRA: Chromosome Interactive Tool for Rearrangement Analysis. CSIR-IGIB.
343+
Pruthi, P., Narayan, J., Agarwal, P., Shukla, N., Bhatia, A., & Rani, L. (2025). CHITRA: Chromosome Interactive Tool for Rearrangement Analysis. CSIR-IGIB.
328344
</code>
329345
</motion.div>
330346
</div>

‎components/homepage/hero-section.tsx

+100-10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ import {
2424
import { DataFlowDiagram } from "./data-flow-diagram";
2525
import AnimatedText from '../ui/animated-text';
2626
import HyperText from '../ui/hyper-text';
27+
import { MagicCard } from "@/components/ui/magic-card";
28+
import Image from "next/image";
29+
import { Marquee } from "../ui/marquee";
30+
import { GradientBentoCard } from "@/components/ui/gradient-bento-card";
31+
import { ICraftPlayer, ICraftPlayerInstance, AnimationType } from "@icraft/player-react";
32+
import { WorkflowAnimation } from "./workflow-animation";
2733

2834
const videos = [
2935
{
@@ -56,6 +62,7 @@ export default function HeroSection() {
5662
const [isLoading, setIsLoading] = useState(false);
5763
const [isGithubHovered, setIsGithubHovered] = useState(false);
5864
const [fullscreenVideo, setFullscreenVideo] = useState<{id: string, src: string} | null>(null);
65+
const playerRef = useRef<ICraftPlayerInstance>(null);
5966

6067
const handleGetStarted = async () => {
6168
setIsLoading(true);
@@ -69,7 +76,7 @@ export default function HeroSection() {
6976
};
7077

7178
return (
72-
<section className="relative min-h-screen w-full overflow-hidden">
79+
<section className="relative w-full overflow-hidden">
7380
<Particles
7481
className="fixed inset-0 -z-10"
7582
quantity={100}
@@ -79,7 +86,7 @@ export default function HeroSection() {
7986
size={1.2}
8087
/>
8188

82-
<div className="relative z-10 flex min-h-screen w-full items-start xs:items-center justify-center py-8 xs:py-0">
89+
<div className="relative z-10 flex w-full items-center justify-center py-8">
8390
<div className="container mx-auto px-2 xs:px-4">
8491
<div className="grid items-center gap-4 xs:gap-8 xl:grid-cols-[0.7fr,1.3fr] xl:gap-20">
8592
<div className="flex flex-col items-center text-center xl:items-start xl:text-left">
@@ -209,8 +216,7 @@ export default function HeroSection() {
209216
<motion.div
210217
className={cn(
211218
"relative w-full aspect-[3/2] xs:aspect-[4/3] sm:aspect-[16/10] xl:aspect-[16/9] 2xl:aspect-[2/1] cursor-none",
212-
"mt-4 sm:mt-6 xl:mt-0",
213-
"mb-0 md:mb-8"
219+
"mt-4 sm:mt-6 xl:mt-0"
214220
)}
215221
initial={{ opacity: 0, scale: 0.95 }}
216222
animate={{ opacity: 1, scale: 1 }}
@@ -296,6 +302,96 @@ export default function HeroSection() {
296302
</div>
297303
</div>
298304

305+
{/* New Workflow Section */}
306+
<div className="relative z-10 py-12 bg-white/5 backdrop-blur-sm">
307+
<div className="container mx-auto px-4">
308+
<h2 className="text-3xl font-bold text-center mb-8">
309+
<HyperText
310+
text="Workflow & Features"
311+
className="text-right"
312+
duration={1000}
313+
/>
314+
</h2>
315+
<div className="grid lg:grid-cols-2 gap-8 items-start">
316+
{/* iPlayer Container */}
317+
<div className="relative aspect-square w-full rounded-2xl overflow-hidden border border-white/20">
318+
<WorkflowAnimation />
319+
</div>
320+
321+
{/* Workflow Description */}
322+
<div className="space-y-6">
323+
<div className="bg-white/5 backdrop-blur-sm rounded-xl p-6 border border-white/10">
324+
<h3 className="text-xl font-semibold mb-4">Input Requirements</h3>
325+
<div className="space-y-3">
326+
<h4 className="font-medium text-blue-400">Required Files (CSV)</h4>
327+
<ul className="list-disc list-inside space-y-2 text-sm text-muted-foreground">
328+
<li>Synteny data with pairwise synteny blocks</li>
329+
<li>Species data with genome information</li>
330+
<li>Reference chromosome size data</li>
331+
</ul>
332+
333+
<h4 className="font-medium text-blue-400 mt-4">Optional Files</h4>
334+
<ul className="list-disc list-inside space-y-2 text-sm text-muted-foreground">
335+
<li>Gene annotations</li>
336+
<li>Breakpoint data</li>
337+
</ul>
338+
</div>
339+
</div>
340+
341+
<div className="bg-white/5 backdrop-blur-sm rounded-xl p-6 border border-white/10">
342+
<h3 className="text-xl font-semibold mb-4">Visualization Options</h3>
343+
<div className="grid grid-cols-2 gap-4">
344+
<div className="space-y-2">
345+
<h4 className="font-medium text-purple-400">Linear View</h4>
346+
<ul className="list-disc list-inside text-sm text-muted-foreground">
347+
<li>Interactive ribbons</li>
348+
<li>Customizable colors</li>
349+
<li>Strand filtering</li>
350+
<li>Breakpoint mapping</li>
351+
</ul>
352+
</div>
353+
<div className="space-y-2">
354+
<h4 className="font-medium text-emerald-400">Chord Map</h4>
355+
<ul className="list-disc list-inside text-sm text-muted-foreground">
356+
<li>Circular visualization</li>
357+
<li>Detailed block info</li>
358+
<li>Gene annotations</li>
359+
<li>Interactive filtering</li>
360+
</ul>
361+
</div>
362+
</div>
363+
</div>
364+
365+
<div className="flex gap-4">
366+
<Link
367+
href="https://chitra-eta.vercel.app/docs"
368+
target="_blank"
369+
className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-blue-500/10 hover:bg-blue-500/20 text-blue-400 text-sm transition-colors"
370+
>
371+
<ArrowRight className="h-4 w-4" />
372+
Documentation
373+
</Link>
374+
<Link
375+
href="https://github.com/pranjalpruthi/CHITRA"
376+
target="_blank"
377+
className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-zinc-500/10 hover:bg-zinc-500/20 text-zinc-400 text-sm transition-colors"
378+
>
379+
<Github className="h-4 w-4" />
380+
Source Code
381+
</Link>
382+
</div>
383+
</div>
384+
</div>
385+
</div>
386+
</div>
387+
388+
{/* DataFlowDiagram section */}
389+
<div className="mt-2 hidden md:block">
390+
<div className="container mx-auto px-4">
391+
<DataFlowDiagram />
392+
</div>
393+
</div>
394+
299395
<Dialog open={!!fullscreenVideo} onOpenChange={() => setFullscreenVideo(null)}>
300396
<DialogContent className="max-w-[95vw] max-h-[95vh] p-0 overflow-hidden">
301397
{fullscreenVideo && (
@@ -309,12 +405,6 @@ export default function HeroSection() {
309405
)}
310406
</DialogContent>
311407
</Dialog>
312-
313-
<div className="mt-0 hidden md:block">
314-
<div className="container mx-auto px-4">
315-
<DataFlowDiagram />
316-
</div>
317-
</div>
318408
</section>
319409
);
320410
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {
2+
ICraftPlayer,
3+
ICraftPlayerInstance,
4+
CameraBar
5+
} from "@icraft/player-react";
6+
import React, { useRef } from "react";
7+
8+
const style = {
9+
width: "100%",
10+
height: "100%",
11+
position: "relative" as const,
12+
overflow: "hidden" as const,
13+
};
14+
15+
const cameraBarStyle = {
16+
left: "initial",
17+
transform: "translateX(0%)",
18+
bottom: "10px",
19+
right: "10px",
20+
background: "rgba(0, 0, 0, 0.2)",
21+
borderRadius: "8px",
22+
padding: "4px",
23+
};
24+
25+
export const WorkflowAnimation = () => {
26+
const playerRef = useRef<ICraftPlayerInstance>(null);
27+
28+
return (
29+
<div className="relative aspect-square w-full rounded-2xl overflow-hidden border border-white/20">
30+
<ICraftPlayer
31+
src="/assets/logos/workflow/chitra.iplayer"
32+
ref={playerRef}
33+
addons={
34+
<CameraBar
35+
style={cameraBarStyle}
36+
/>
37+
}
38+
/>
39+
</div>
40+
);
41+
};

‎components/ui/magic-card.tsx

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
"use client";
2+
3+
import { motion, useMotionTemplate, useMotionValue } from "motion/react";
4+
import React, { useCallback, useEffect, useRef } from "react";
5+
6+
import { cn } from "@/lib/utils";
7+
8+
interface MagicCardProps extends React.HTMLAttributes<HTMLDivElement> {
9+
gradientSize?: number;
10+
gradientColor?: string;
11+
gradientOpacity?: number;
12+
gradientFrom?: string;
13+
gradientTo?: string;
14+
}
15+
16+
export function MagicCard({
17+
children,
18+
className,
19+
gradientSize = 200,
20+
gradientColor = "#262626",
21+
gradientOpacity = 0.8,
22+
gradientFrom = "#9E7AFF",
23+
gradientTo = "#FE8BBB",
24+
}: MagicCardProps) {
25+
const cardRef = useRef<HTMLDivElement>(null);
26+
const mouseX = useMotionValue(-gradientSize);
27+
const mouseY = useMotionValue(-gradientSize);
28+
29+
const handleMouseMove = useCallback(
30+
(e: MouseEvent) => {
31+
if (cardRef.current) {
32+
const { left, top } = cardRef.current.getBoundingClientRect();
33+
const clientX = e.clientX;
34+
const clientY = e.clientY;
35+
mouseX.set(clientX - left);
36+
mouseY.set(clientY - top);
37+
}
38+
},
39+
[mouseX, mouseY],
40+
);
41+
42+
const handleMouseOut = useCallback(
43+
(e: MouseEvent) => {
44+
if (!e.relatedTarget) {
45+
document.removeEventListener("mousemove", handleMouseMove);
46+
mouseX.set(-gradientSize);
47+
mouseY.set(-gradientSize);
48+
}
49+
},
50+
[handleMouseMove, mouseX, gradientSize, mouseY],
51+
);
52+
53+
const handleMouseEnter = useCallback(() => {
54+
document.addEventListener("mousemove", handleMouseMove);
55+
mouseX.set(-gradientSize);
56+
mouseY.set(-gradientSize);
57+
}, [handleMouseMove, mouseX, gradientSize, mouseY]);
58+
59+
useEffect(() => {
60+
document.addEventListener("mousemove", handleMouseMove);
61+
document.addEventListener("mouseout", handleMouseOut);
62+
document.addEventListener("mouseenter", handleMouseEnter);
63+
64+
return () => {
65+
document.removeEventListener("mousemove", handleMouseMove);
66+
document.removeEventListener("mouseout", handleMouseOut);
67+
document.removeEventListener("mouseenter", handleMouseEnter);
68+
};
69+
}, [handleMouseEnter, handleMouseMove, handleMouseOut]);
70+
71+
useEffect(() => {
72+
mouseX.set(-gradientSize);
73+
mouseY.set(-gradientSize);
74+
}, [gradientSize, mouseX, mouseY]);
75+
76+
return (
77+
<div
78+
ref={cardRef}
79+
className={cn("group relative flex size-full rounded-xl", className)}
80+
>
81+
<div className="absolute inset-px z-10 rounded-xl bg-background" />
82+
<div className="relative z-30">{children}</div>
83+
<motion.div
84+
className="pointer-events-none absolute inset-px z-10 rounded-xl opacity-0 transition-opacity duration-300 group-hover:opacity-100"
85+
style={{
86+
background: useMotionTemplate`
87+
radial-gradient(${gradientSize}px circle at ${mouseX}px ${mouseY}px, ${gradientColor}, transparent 100%)
88+
`,
89+
opacity: gradientOpacity,
90+
}}
91+
/>
92+
<motion.div
93+
className="pointer-events-none absolute inset-0 rounded-xl bg-border duration-300 group-hover:opacity-100"
94+
style={{
95+
background: useMotionTemplate`
96+
radial-gradient(${gradientSize}px circle at ${mouseX}px ${mouseY}px,
97+
${gradientFrom},
98+
${gradientTo},
99+
hsl(var(--border)) 100%
100+
)
101+
`,
102+
}}
103+
/>
104+
</div>
105+
);
106+
}

0 commit comments

Comments
 (0)