5 Commits

Author SHA1 Message Date
b233841e11 Merge version_6 into main
Merge version_6 into main
2026-02-26 22:12:43 +00:00
b6ed15c2cc Bob AI: Add inner shadow effect to images on hover in the about sect 2026-02-27 00:12:32 +02:00
7ece8f2861 Merge version_5 into main
Merge version_5 into main
2026-02-26 22:09:20 +00:00
56d41aa516 Bob AI: Add a 3D flip animation to the about section card on hover. 2026-02-27 00:09:10 +02:00
4f3efdc620 Merge version_4 into main
Merge version_4 into main
2026-02-26 22:06:29 +00:00

View File

@@ -1,5 +1,6 @@
"use client";
import { useState } from "react";
import MediaContent from "@/components/shared/MediaContent";
import TextBox from "@/components/Textbox";
import { cls } from "@/lib/utils";
@@ -32,6 +33,9 @@ interface MediaAboutProps {
mediaClassName?: string;
backgroundVideoSrc?: string;
backgroundVideoAriaLabel?: string;
backSideTitle?: string;
backSideDescription?: string;
enableFlip?: boolean;
}
const MediaAbout = ({
@@ -60,7 +64,11 @@ const MediaAbout = ({
mediaClassName = "",
backgroundVideoSrc,
backgroundVideoAriaLabel,
backSideTitle = "Learn More",
backSideDescription = "Discover additional details about our story and mission.",
enableFlip = false,
}: MediaAboutProps) => {
const [isFlipped, setIsFlipped] = useState(false);
return (
<section
@@ -69,35 +77,95 @@ const MediaAbout = ({
className={cls("relative", backgroundVideoSrc && "overflow-hidden")}
className={cls("relative py-20 w-full", useInvertedBackground && "bg-foreground", className)}
>
<div className={cls("relative w-content-width mx-auto aspect-auto min-h-70 md:aspect-video md:min-h-0 rounded-theme-capped overflow-hidden", mediaWrapperClassName)}>
<MediaContent
imageSrc={imageSrc}
videoSrc={videoSrc}
imageAlt={imageAlt}
videoAriaLabel={videoAriaLabel}
imageClassName={cls("w-full h-full object-cover", mediaClassName)}
/>
<div className="absolute inset-0 z-0 bg-background/40 backdrop-blur-xs pointer-events-none select-none rounded-theme-capped" />
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<div className="relative z-10 flex items-center justify-center h-full w-content-width p-5 md:w-45 mx-auto">
<TextBox
title={title}
description={description}
tag={tag}
tagIcon={tagIcon}
tagAnimation={tagAnimation}
buttons={buttons}
buttonAnimation={buttonAnimation}
className={cls("flex flex-col gap-3 md:gap-1", textBoxClassName)}
titleClassName={cls("text-6xl font-medium text-balance", titleClassName)}
descriptionClassName={cls("text-base md:text-lg leading-[1.2]", descriptionClassName)}
tagClassName={cls("px-3 py-1 text-sm rounded-theme card text-foreground inline-flex items-center gap-2 mb-3", tagClassName)}
buttonContainerClassName={cls("flex flex-wrap gap-4 max-md:justify-center mt-3", buttonContainerClassName)}
buttonClassName={buttonClassName}
buttonTextClassName={buttonTextClassName}
center={true}
<div
className={cls("relative w-content-width mx-auto aspect-auto min-h-70 md:aspect-video md:min-h-0 rounded-theme-capped overflow-hidden", mediaWrapperClassName)}
style={enableFlip ? {
perspective: "1000px",
cursor: "pointer",
} : undefined}
onMouseEnter={() => enableFlip && setIsFlipped(true)}
onMouseLeave={() => enableFlip && setIsFlipped(false)}
>
<div
style={enableFlip ? {
position: "relative",
width: "100%",
height: "100%",
transformStyle: "preserve-3d",
transform: isFlipped ? "rotateY(180deg)" : "rotateY(0deg)",
transition: "transform 0.6s ease-in-out",
} : undefined}
>
{/* Front side */}
<div
style={enableFlip ? {
position: "absolute",
width: "100%",
height: "100%",
backfaceVisibility: "hidden",
} : undefined}
className="group"
>
<MediaContent
imageSrc={imageSrc}
videoSrc={videoSrc}
imageAlt={imageAlt}
videoAriaLabel={videoAriaLabel}
imageClassName={cls("w-full h-full object-cover transition-shadow duration-300 group-hover:shadow-inner", mediaClassName)}
/>
<div className="absolute inset-0 z-0 bg-background/40 backdrop-blur-xs pointer-events-none select-none rounded-theme-capped" />
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<div className="relative z-10 flex items-center justify-center h-full w-content-width p-5 md:w-45 mx-auto">
<TextBox
title={title}
description={description}
tag={tag}
tagIcon={tagIcon}
tagAnimation={tagAnimation}
buttons={buttons}
buttonAnimation={buttonAnimation}
className={cls("flex flex-col gap-3 md:gap-1", textBoxClassName)}
titleClassName={cls("text-6xl font-medium text-balance", titleClassName)}
descriptionClassName={cls("text-base md:text-lg leading-[1.2]", descriptionClassName)}
tagClassName={cls("px-3 py-1 text-sm rounded-theme card text-foreground inline-flex items-center gap-2 mb-3", tagClassName)}
buttonContainerClassName={cls("flex flex-wrap gap-4 max-md:justify-center mt-3", buttonContainerClassName)}
buttonClassName={buttonClassName}
buttonTextClassName={buttonTextClassName}
center={true}
/>
</div>
</div>
</div>
{/* Back side */}
{enableFlip && (
<div
style={{
position: "absolute",
width: "100%",
height: "100%",
backfaceVisibility: "hidden",
transform: "rotateY(180deg)",
backgroundColor: useInvertedBackground ? "hsl(var(--background))" : "hsl(var(--foreground))",
}}
className="rounded-theme-capped"
>
<div className="absolute inset-0 z-0 bg-background/40 backdrop-blur-xs pointer-events-none select-none rounded-theme-capped" />
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<div className="relative z-10 flex items-center justify-center h-full w-content-width p-5 md:w-45 mx-auto">
<TextBox
title={backSideTitle}
description={backSideDescription}
className={cls("flex flex-col gap-3 md:gap-1", textBoxClassName)}
titleClassName={cls("text-4xl font-medium text-balance", titleClassName)}
descriptionClassName={cls("text-base md:text-lg leading-[1.2]", descriptionClassName)}
buttonContainerClassName={cls("flex flex-wrap gap-4 max-md:justify-center mt-3", buttonContainerClassName)}
center={true}
/>
</div>
</div>
</div>
)}
</div>
</div>
</section>