feat: glitter border on team/class cards, mobile-friendly class selector
- Animated gold border glitter effect on active team card and class image - Classes selector: 2-column grid on mobile (no scroll), list on desktop - Selector appears above detail on mobile (flex-col-reverse) - Compact selector items on mobile (icon + name only) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -283,6 +283,47 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== Team Card Glitter ===== */
|
||||||
|
|
||||||
|
@keyframes glitter-move {
|
||||||
|
0% {
|
||||||
|
background-position: 0% 0%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 200% 200%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.team-card-glitter {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animated gold border glow */
|
||||||
|
.team-card-glitter::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: -1px;
|
||||||
|
border-radius: inherit;
|
||||||
|
padding: 2px;
|
||||||
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
transparent 20%,
|
||||||
|
rgba(201, 169, 110, 0.6) 30%,
|
||||||
|
rgba(212, 184, 122, 1) 35%,
|
||||||
|
transparent 45%,
|
||||||
|
transparent 55%,
|
||||||
|
rgba(201, 169, 110, 0.5) 65%,
|
||||||
|
rgba(212, 184, 122, 0.9) 70%,
|
||||||
|
transparent 80%
|
||||||
|
);
|
||||||
|
background-size: 200% 200%;
|
||||||
|
animation: glitter-move 3s linear infinite;
|
||||||
|
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||||
|
mask-composite: exclude;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* ===== Section Divider ===== */
|
/* ===== Section Divider ===== */
|
||||||
|
|
||||||
.section-divider {
|
.section-divider {
|
||||||
@@ -331,4 +372,8 @@
|
|||||||
.glow-hover:hover {
|
.glow-hover:hover {
|
||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.team-card-glitter::before {
|
||||||
|
animation: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export function Classes() {
|
|||||||
<div>
|
<div>
|
||||||
{/* Hero image */}
|
{/* Hero image */}
|
||||||
{item.images && item.images[0] && (
|
{item.images && item.images[0] && (
|
||||||
<div className="relative aspect-[16/9] w-full overflow-hidden rounded-2xl">
|
<div className="team-card-glitter relative aspect-[16/9] w-full overflow-hidden rounded-2xl">
|
||||||
<Image
|
<Image
|
||||||
src={item.images[0]}
|
src={item.images[0]}
|
||||||
alt={item.name}
|
alt={item.name}
|
||||||
@@ -75,10 +75,10 @@ export function Classes() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
renderSelectorItem={(item, _i, isActive) => (
|
renderSelectorItem={(item, _i, isActive) => (
|
||||||
<div className="flex items-center gap-3 p-3">
|
<div className="flex items-center gap-2 px-3 py-2 lg:gap-3 lg:p-3">
|
||||||
{/* Icon */}
|
{/* Icon */}
|
||||||
<div
|
<div
|
||||||
className={`flex h-9 w-9 shrink-0 items-center justify-center rounded-lg transition-colors ${
|
className={`flex h-7 w-7 lg:h-9 lg:w-9 shrink-0 items-center justify-center rounded-lg transition-colors ${
|
||||||
isActive
|
isActive
|
||||||
? "bg-[#c9a96e]/20 text-[#d4b87a]"
|
? "bg-[#c9a96e]/20 text-[#d4b87a]"
|
||||||
: "bg-neutral-200/50 text-neutral-500 dark:bg-white/[0.06] dark:text-neutral-400"
|
: "bg-neutral-200/50 text-neutral-500 dark:bg-white/[0.06] dark:text-neutral-400"
|
||||||
@@ -88,7 +88,7 @@ export function Classes() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<p
|
<p
|
||||||
className={`text-sm font-semibold truncate transition-colors ${
|
className={`text-xs lg:text-sm font-semibold truncate transition-colors ${
|
||||||
isActive
|
isActive
|
||||||
? "text-[#c9a96e]"
|
? "text-[#c9a96e]"
|
||||||
: "text-neutral-700 dark:text-neutral-300"
|
: "text-neutral-700 dark:text-neutral-300"
|
||||||
@@ -96,7 +96,7 @@ export function Classes() {
|
|||||||
>
|
>
|
||||||
{item.name}
|
{item.name}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs text-neutral-500 dark:text-neutral-500 truncate">
|
<p className="hidden lg:block text-xs text-neutral-500 dark:text-neutral-500 truncate">
|
||||||
{item.description}
|
{item.description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ export function Team() {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={m.name}
|
key={m.name}
|
||||||
className="absolute bottom-0 overflow-hidden rounded-2xl border pointer-events-none"
|
className={`absolute bottom-0 overflow-hidden rounded-2xl border pointer-events-none ${style.isCenter ? "team-card-glitter" : ""}`}
|
||||||
style={{
|
style={{
|
||||||
width: style.width,
|
width: style.width,
|
||||||
height: style.height,
|
height: style.height,
|
||||||
@@ -221,8 +221,10 @@ export function Team() {
|
|||||||
zIndex: style.zIndex,
|
zIndex: style.zIndex,
|
||||||
transform: style.transform,
|
transform: style.transform,
|
||||||
filter: style.filter,
|
filter: style.filter,
|
||||||
borderColor: style.borderColor,
|
borderColor: style.isCenter ? "transparent" : style.borderColor,
|
||||||
boxShadow: style.boxShadow,
|
boxShadow: style.isCenter
|
||||||
|
? "0 0 40px rgba(201,169,110,0.15), 0 0 80px rgba(201,169,110,0.08)"
|
||||||
|
: style.boxShadow,
|
||||||
transition: style.transition,
|
transition: style.transition,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export function ShowcaseLayout<T>({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="flex flex-col gap-6 lg:flex-row lg:gap-8"
|
className="flex flex-col-reverse gap-6 lg:flex-row lg:gap-8"
|
||||||
onMouseEnter={handleMouseEnter}
|
onMouseEnter={handleMouseEnter}
|
||||||
onMouseLeave={handleMouseLeave}
|
onMouseLeave={handleMouseLeave}
|
||||||
>
|
>
|
||||||
@@ -131,14 +131,14 @@ export function ShowcaseLayout<T>({
|
|||||||
<div className="lg:w-[40%]">
|
<div className="lg:w-[40%]">
|
||||||
<div
|
<div
|
||||||
ref={selectorRef}
|
ref={selectorRef}
|
||||||
className="styled-scrollbar flex gap-3 overflow-x-auto pb-2 lg:max-h-[600px] lg:flex-col lg:overflow-y-auto lg:overflow-x-visible lg:pb-0 lg:pr-1"
|
className="grid grid-cols-2 gap-2 lg:grid-cols-1 lg:gap-3 lg:max-h-[600px] lg:overflow-y-auto lg:pr-1 styled-scrollbar"
|
||||||
>
|
>
|
||||||
{items.map((item, i) => (
|
{items.map((item, i) => (
|
||||||
<button
|
<button
|
||||||
key={i}
|
key={i}
|
||||||
ref={i === activeIndex ? activeItemRef : null}
|
ref={i === activeIndex ? activeItemRef : null}
|
||||||
onClick={() => onSelect(i)}
|
onClick={() => onSelect(i)}
|
||||||
className={`flex-shrink-0 cursor-pointer rounded-xl border-2 text-left transition-all duration-300 ${
|
className={`cursor-pointer rounded-xl border-2 text-left transition-all duration-300 ${
|
||||||
i === activeIndex
|
i === activeIndex
|
||||||
? "border-[#c9a96e]/60 bg-[#c9a96e]/10 dark:bg-[#c9a96e]/5"
|
? "border-[#c9a96e]/60 bg-[#c9a96e]/10 dark:bg-[#c9a96e]/5"
|
||||||
: "border-transparent bg-neutral-100 hover:bg-neutral-200 dark:bg-white/[0.03] dark:hover:bg-white/[0.06]"
|
: "border-transparent bg-neutral-100 hover:bg-neutral-200 dark:bg-white/[0.03] dark:hover:bg-white/[0.06]"
|
||||||
|
|||||||
Reference in New Issue
Block a user