Skip to content

Commit e251a50

Browse files
fix(ui): improve testimonial and mentorship section consistency
1 parent 1caf13e commit e251a50

5 files changed

Lines changed: 707 additions & 343 deletions

File tree

src/components/testimonials/TestimonialCard.tsx

Lines changed: 128 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { useEffect, useState } from "react";
22
import { motion } from "framer-motion";
3+
import { Quote } from "lucide-react";
34
import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar";
45
import { useSafeColorMode } from "../../utils/useSafeColorMode";
56

@@ -23,107 +24,145 @@ const TestimonialCard: React.FC<TestimonialCardProps> = ({
2324
gradient,
2425
borderColor,
2526
}) => {
26-
const { colorMode, isDark } = useSafeColorMode();
27+
const { isDark } = useSafeColorMode();
2728

28-
const getBackgroundStyle = () => {
29-
let colorStop = "";
30-
if (gradient === "bg-pink-100") {
31-
colorStop = "rgba(244, 194, 214, 0.35)"; // Pink
32-
} else if (gradient === "bg-purple-100") {
33-
colorStop = "rgba(191, 190, 255, 0.35)"; // Blue/Lavender
34-
} else {
35-
colorStop = "rgba(165, 243, 252, 0.35)"; // Cyan
36-
}
29+
// Map gradient prop to card visual variant
30+
const isAccent = gradient === "bg-purple-100";
31+
const isFeatured = gradient === "bg-pink-100";
3732

38-
return {
39-
background: `
40-
radial-gradient(
41-
ellipse 600px 500px at 10% 85%,
42-
${colorStop} 0%,
43-
rgba(255, 255, 255, 0) 70%
44-
),
45-
linear-gradient(
46-
135deg,
47-
rgba(255, 255, 255, 0.95) 0%,
48-
rgba(255, 255, 255, 0.9) 100%
49-
)
50-
`,
51-
backdropFilter: "blur(4px)",
52-
WebkitBackdropFilter: "blur(4px)",
53-
border: "1px solid rgba(200, 200, 220, 0.4)",
54-
};
33+
const getRole = () => {
34+
if (username === "VivienChen") return "Founder @ Toastie (BC Y24)";
35+
if (username === "DanielHan") return "Founder @ Unsloth AI (YC W24, BC Y24)";
36+
if (username === "EthanTrang") return "AI Engineer @ Relevance AI";
37+
return null;
5538
};
5639

57-
const [mounted, setMounted] = useState(false);
58-
useEffect(() => setMounted(true), []);
40+
const role = getRole();
41+
42+
// Card colors by variant
43+
const cardBg = isAccent
44+
? "linear-gradient(135deg, #4338ca 0%, #6d28d9 100%)"
45+
: isDark
46+
? "#0a0a0a"
47+
: "#ffffff";
48+
49+
const isInverted = isAccent || isDark;
50+
const textClr = isInverted ? "rgba(255,255,255,0.85)" : "rgba(17,24,39,0.78)";
51+
const nameClr = isInverted ? "#f1f5f9" : "#0f172a";
52+
const mutedClr = isAccent
53+
? "rgba(255,255,255,0.50)"
54+
: isDark
55+
? "rgba(148,163,184,0.55)"
56+
: "rgba(100,116,139,0.65)";
57+
const borderClr = isAccent
58+
? "rgba(255,255,255,0.10)"
59+
: isDark
60+
? "rgba(255,255,255,0.06)"
61+
: "rgba(0,0,0,0.07)";
62+
const quoteClr = isAccent
63+
? "rgba(255,255,255,0.12)"
64+
: isDark
65+
? "rgba(99,102,241,0.12)"
66+
: "rgba(99,102,241,0.08)";
5967

6068
return (
6169
<motion.div
62-
initial={mounted ? { opacity: 0, y: 20 } : false}
63-
animate={{ opacity: 1, y: 0 }}
64-
exit={{ opacity: 0, y: -20 }}
65-
whileHover={{ y: -8 }}
66-
transition={{ duration: 0.3 }}
67-
className={`group relative h-full w-full overflow-hidden rounded-3xl min-h-[550px] flex flex-col justify-between p-8`}
68-
style={getBackgroundStyle()}
70+
whileHover={{ scale: 1.035, y: -3 }}
71+
transition={{ type: "spring", stiffness: 400, damping: 25 }}
72+
className="relative flex flex-col justify-between overflow-hidden rounded-2xl p-5 flex-shrink-0 cursor-default select-none"
73+
style={{
74+
width: 320,
75+
minHeight: 180,
76+
background: cardBg,
77+
border: `1px solid ${borderClr}`,
78+
boxShadow: isDark
79+
? "0 2px 24px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.03)"
80+
: "0 2px 20px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04)",
81+
}}
6982
>
70-
{/* Subtle glossy overlay */}
71-
<div
72-
className="absolute inset-0 rounded-3xl pointer-events-none"
73-
style={{
74-
background: `linear-gradient(135deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0.2) 40%, transparent 70%)`,
75-
}}
76-
/>
77-
78-
{/* Soft shadow */}
79-
<div className="absolute inset-0 rounded-3xl pointer-events-none shadow-lg shadow-black/5" />
83+
{/* Grid pattern overlay for featured cards */}
84+
{isFeatured && (
85+
<div
86+
className="absolute inset-0 pointer-events-none"
87+
style={{
88+
backgroundImage:
89+
"linear-gradient(to right, rgba(79,79,79,0.14) 1px, transparent 1px), linear-gradient(to bottom, rgba(79,79,79,0.14) 1px, transparent 1px)",
90+
backgroundSize: "44px 48px",
91+
maskImage:
92+
"radial-gradient(ellipse 80% 50% at 50% 0%, #000 70%, transparent 110%)",
93+
WebkitMaskImage:
94+
"radial-gradient(ellipse 80% 50% at 50% 0%, #000 70%, transparent 110%)",
95+
}}
96+
/>
97+
)}
8098

81-
<div className="relative z-10 flex flex-col h-full">
82-
{/* Testimonial Quote - Top Section */}
83-
<div className="mb-12">
84-
<p className="text-2xl leading-relaxed font-semibold text-gray-900 tracking-tight">
85-
"{content.replace(/#\w+/g, '').trim()}"
86-
</p>
87-
</div>
88-
89-
{/* Avatar and Info - Bottom Section */}
90-
<div className="mt-auto">
91-
<div className="flex items-center gap-6">
92-
{/* Large Avatar with White Background */}
93-
<Avatar className="h-20 w-20 overflow-hidden rounded-full border-3 border-white shadow-md flex-shrink-0 bg-white">
94-
<AvatarImage src={avatar} className="h-full w-full object-cover scale-125" />
95-
<AvatarFallback className="text-white font-bold text-lg bg-gradient-to-br from-purple-400 to-pink-400">
96-
{name.charAt(0)}
97-
</AvatarFallback>
98-
</Avatar>
99+
{/* Quote icon top-right */}
100+
<div className="absolute top-5 right-5 pointer-events-none">
101+
<Quote
102+
size={28}
103+
style={{ color: quoteClr }}
104+
className="rotate-180"
105+
/>
106+
</div>
99107

100-
<div className="flex-1">
101-
<h3
102-
className="testimonial-author-name mb-1 text-xl font-bold leading-tight tracking-tight"
103-
style={{ color: "#111827", opacity: 1, WebkitTextFillColor: "#111827" }}
104-
>
105-
{name}
106-
</h3>
107-
{username !== "AryanGupta" && username !== "DonaldAnyamba" && (
108-
<p
109-
className="testimonial-author-role mb-3 text-sm font-medium"
110-
style={{ color: "#334155", opacity: 1, WebkitTextFillColor: "#334155" }}
111-
>
112-
{username === "VivienChen" ? "Founder @ Toastie (BC Y24)" :
113-
username === "DanielHan" ? "Founder @ Unsloth AI (YC W24, BC Y24)" :
114-
"AI Engineer @ Relevance AI"}
115-
</p>
116-
)}
108+
{/* Quote content */}
109+
<p
110+
className="relative z-10 text-[13px] leading-[1.65] flex-1 pr-8"
111+
style={{
112+
color: textClr,
113+
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, sans-serif",
114+
}}
115+
>
116+
&ldquo;{content.replace(/#\w+/g, "").trim()}&rdquo;
117+
</p>
117118

118-
<div
119-
className="flex items-center gap-3 text-xs"
120-
style={{ color: "#334155", opacity: 1, WebkitTextFillColor: "#334155" }}
121-
>
122-
<span className="font-medium">{date}</span>
123-
</div>
124-
</div>
125-
</div>
119+
{/* Author row */}
120+
<div
121+
className="relative z-10 flex items-center justify-between mt-3 pt-3"
122+
style={{ borderTop: `1px solid ${borderClr}` }}
123+
>
124+
<div className="min-w-0 flex-1 mr-3">
125+
<h3
126+
className="font-semibold text-[14px] leading-tight truncate"
127+
style={{
128+
color: nameClr,
129+
fontFamily: "'Inter', -apple-system, sans-serif",
130+
}}
131+
>
132+
{name}
133+
</h3>
134+
{role && (
135+
<p
136+
className="text-[12px] mt-0.5 truncate"
137+
style={{ color: mutedClr }}
138+
>
139+
{role}
140+
</p>
141+
)}
142+
<span
143+
className="text-[11px] mt-0.5 inline-block"
144+
style={{ color: mutedClr }}
145+
>
146+
{date}
147+
</span>
126148
</div>
149+
<Avatar
150+
className="h-9 w-9 rounded-lg overflow-hidden flex-shrink-0"
151+
style={{ border: `2px solid ${borderClr}` }}
152+
>
153+
<AvatarImage
154+
src={avatar}
155+
className="h-full w-full object-cover"
156+
/>
157+
<AvatarFallback
158+
className="text-white font-semibold text-sm rounded-xl"
159+
style={{
160+
background: "linear-gradient(135deg, #6366f1, #a855f7)",
161+
}}
162+
>
163+
{name.charAt(0)}
164+
</AvatarFallback>
165+
</Avatar>
127166
</div>
128167
</motion.div>
129168
);

0 commit comments

Comments
 (0)