bandsbender's picture
Upload 348 files
21a686e verified
raw
history blame
11.9 kB
"use client";
import { animate, motion } from "motion/react";
import React, { useEffect, useState } from "react";
import { cn } from "@/lib/utils";
import { GoCopilot } from "react-icons/go";
export function FeatureBlockAnimatedCard() {
return (
<Card>
<CardSkeletonContainer>
<Skeleton />
</CardSkeletonContainer>
<CardTitle>Damn good card</CardTitle>
<CardDescription>
A card that showcases a set of tools that you use to create your
product.
</CardDescription>
</Card>
);
}
const Skeleton = () => {
const scale = [1, 1.1, 1];
const transform = ["translateY(0px)", "translateY(-4px)", "translateY(0px)"];
const sequence = [
[
".circle-1",
{
scale,
transform,
},
{ duration: 0.8 },
],
[
".circle-2",
{
scale,
transform,
},
{ duration: 0.8 },
],
[
".circle-3",
{
scale,
transform,
},
{ duration: 0.8 },
],
[
".circle-4",
{
scale,
transform,
},
{ duration: 0.8 },
],
[
".circle-5",
{
scale,
transform,
},
{ duration: 0.8 },
],
];
useEffect(() => {
animate(sequence, {
// @ts-ignore
repeat: Infinity,
repeatDelay: 1,
});
}, []);
return (
<div className="p-8 overflow-hidden h-full relative flex items-center justify-center">
<div className="flex flex-row flex-shrink-0 justify-center items-center gap-2">
<Container className="h-8 w-8 circle-1">
<ClaudeLogo className="h-4 w-4 " />
</Container>
<Container className="h-12 w-12 circle-2">
<GoCopilot className="h-6 w-6 dark:text-white" />
</Container>
<Container className="circle-3">
<OpenAILogo className="h-8 w-8 dark:text-white" />
</Container>
<Container className="h-12 w-12 circle-4">
<MetaIconOutline className="h-6 w-6 " />
</Container>
<Container className="h-8 w-8 circle-5">
<GeminiLogo className="h-4 w-4 " />
</Container>
</div>
<div className="h-40 w-px absolute top-20 m-auto z-40 bg-gradient-to-b from-transparent via-cyan-500 to-transparent animate-move">
<div className="w-10 h-32 top-1/2 -translate-y-1/2 absolute -left-10">
<Sparkles />
</div>
</div>
</div>
);
};
const Sparkles = () => {
const randomMove = () => Math.random() * 2 - 1;
const randomOpacity = () => Math.random();
const random = () => Math.random();
return (
<div className="absolute inset-0">
{[...Array(12)].map((_, i) => (
<motion.span
key={`star-${i}`}
animate={{
top: `calc(${random() * 100}% + ${randomMove()}px)`,
left: `calc(${random() * 100}% + ${randomMove()}px)`,
opacity: randomOpacity(),
scale: [1, 1.2, 0],
}}
transition={{
duration: random() * 2 + 4,
repeat: Infinity,
ease: "linear",
}}
style={{
position: "absolute",
top: `${random() * 100}%`,
left: `${random() * 100}%`,
width: `2px`,
height: `2px`,
borderRadius: "50%",
zIndex: 1,
}}
className="inline-block bg-black dark:bg-white"
></motion.span>
))}
</div>
);
};
export const Card = ({
className,
children,
}: {
className?: string;
children: React.ReactNode;
}) => {
return (
<div
className={cn(
"max-w-sm w-full mx-auto p-8 rounded-xl border border-[rgba(255,255,255,0.10)] dark:bg-[rgba(40,40,40,0.70)] bg-gray-100 shadow-[2px_4px_16px_0px_rgba(248,248,248,0.06)_inset] group",
className
)}
>
{children}
</div>
);
};
export const CardTitle = ({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) => {
return (
<h3
className={cn(
"text-lg font-semibold text-gray-800 dark:text-white py-2",
className
)}
>
{children}
</h3>
);
};
export const CardDescription = ({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) => {
return (
<p
className={cn(
"text-sm font-normal text-neutral-600 dark:text-neutral-400 max-w-sm",
className
)}
>
{children}
</p>
);
};
export const CardSkeletonContainer = ({
className,
children,
showGradient = true,
}: {
className?: string;
children: React.ReactNode;
showGradient?: boolean;
}) => {
return (
<div
className={cn(
"h-[15rem] md:h-[20rem] rounded-xl z-40",
className,
showGradient &&
"bg-neutral-300 dark:bg-[rgba(40,40,40,0.70)] [mask-image:radial-gradient(50%_50%_at_50%_50%,white_0%,transparent_100%)]"
)}
>
{children}
</div>
);
};
const Container = ({
className,
children,
}: {
className?: string;
children: React.ReactNode;
}) => {
return (
<div
className={cn(
`h-16 w-16 rounded-full flex items-center justify-center bg-[rgba(248,248,248,0.01)]
shadow-[0px_0px_8px_0px_rgba(248,248,248,0.25)_inset,0px_32px_24px_-16px_rgba(0,0,0,0.40)]
`,
className
)}
>
{children}
</div>
);
};
export const ClaudeLogo = ({ className }: { className?: string }) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
shapeRendering="geometricPrecision"
textRendering="geometricPrecision"
imageRendering="optimizeQuality"
fillRule="evenodd"
clipRule="evenodd"
viewBox="0 0 512 512"
className={className}
>
<rect fill="#CC9B7A" width="512" height="512" rx="104.187" ry="105.042" />
<path
fill="#1F1F1E"
fillRule="nonzero"
d="M318.663 149.787h-43.368l78.952 212.423 43.368.004-78.952-212.427zm-125.326 0l-78.952 212.427h44.255l15.932-44.608 82.846-.004 16.107 44.612h44.255l-79.126-212.427h-45.317zm-4.251 128.341l26.91-74.701 27.083 74.701h-53.993z"
/>
</svg>
);
};
export const OpenAILogo = ({ className }: { className?: string }) => {
return (
<svg
className={className}
width="28"
viewBox="0 0 28 28"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M26.153 11.46a6.888 6.888 0 0 0-.608-5.73 7.117 7.117 0 0 0-3.29-2.93 7.238 7.238 0 0 0-4.41-.454 7.065 7.065 0 0 0-2.41-1.742A7.15 7.15 0 0 0 12.514 0a7.216 7.216 0 0 0-4.217 1.346 7.061 7.061 0 0 0-2.603 3.539 7.12 7.12 0 0 0-2.734 1.188A7.012 7.012 0 0 0 .966 8.268a6.979 6.979 0 0 0 .88 8.273 6.89 6.89 0 0 0 .607 5.729 7.117 7.117 0 0 0 3.29 2.93 7.238 7.238 0 0 0 4.41.454 7.061 7.061 0 0 0 2.409 1.742c.92.404 1.916.61 2.923.604a7.215 7.215 0 0 0 4.22-1.345 7.06 7.06 0 0 0 2.605-3.543 7.116 7.116 0 0 0 2.734-1.187 7.01 7.01 0 0 0 1.993-2.196 6.978 6.978 0 0 0-.884-8.27Zm-10.61 14.71c-1.412 0-2.505-.428-3.46-1.215.043-.023.119-.064.168-.094l5.65-3.22a.911.911 0 0 0 .464-.793v-7.86l2.389 1.36a.087.087 0 0 1 .046.065v6.508c0 2.952-2.491 5.248-5.257 5.248ZM4.062 21.354a5.17 5.17 0 0 1-.635-3.516c.042.025.115.07.168.1l5.65 3.22a.928.928 0 0 0 .928 0l6.898-3.93v2.72a.083.083 0 0 1-.034.072l-5.711 3.255a5.386 5.386 0 0 1-4.035.522 5.315 5.315 0 0 1-3.23-2.443ZM2.573 9.184a5.283 5.283 0 0 1 2.768-2.301V13.515a.895.895 0 0 0 .464.793l6.897 3.93-2.388 1.36a.087.087 0 0 1-.08.008L4.52 16.349a5.262 5.262 0 0 1-2.475-3.185 5.192 5.192 0 0 1 .527-3.98Zm19.623 4.506-6.898-3.93 2.388-1.36a.087.087 0 0 1 .08-.008l5.713 3.255a5.28 5.28 0 0 1 2.054 2.118 5.19 5.19 0 0 1-.488 5.608 5.314 5.314 0 0 1-2.39 1.742v-6.633a.896.896 0 0 0-.459-.792Zm2.377-3.533a7.973 7.973 0 0 0-.168-.099l-5.65-3.22a.93.93 0 0 0-.928 0l-6.898 3.93V8.046a.083.083 0 0 1 .034-.072l5.712-3.251a5.375 5.375 0 0 1 5.698.241 5.262 5.262 0 0 1 1.865 2.28c.39.92.506 1.93.335 2.913ZM9.631 15.009l-2.39-1.36a.083.083 0 0 1-.046-.065V7.075c.001-.997.29-1.973.832-2.814a5.297 5.297 0 0 1 2.231-1.935 5.382 5.382 0 0 1 5.659.72 4.89 4.89 0 0 0-.168.093l-5.65 3.22a.913.913 0 0 0-.465.793l-.003 7.857Zm1.297-2.76L14 10.5l3.072 1.75v3.5L14 17.499l-3.072-1.75v-3.5Z"
fill="currentColor"
></path>
</svg>
);
};
export const GeminiLogo = ({ className }: { className?: string }) => {
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
className={className}
>
<path
d="M16 8.016A8.522 8.522 0 008.016 16h-.032A8.521 8.521 0 000 8.016v-.032A8.521 8.521 0 007.984 0h.032A8.522 8.522 0 0016 7.984v.032z"
fill="url(#prefix__paint0_radial_980_20147)"
/>
<defs>
<radialGradient
id="prefix__paint0_radial_980_20147"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(16.1326 5.4553 -43.70045 129.2322 1.588 6.503)"
>
<stop offset=".067" stop-color="#9168C0" />
<stop offset=".343" stop-color="#5684D1" />
<stop offset=".672" stop-color="#1BA1E3" />
</radialGradient>
</defs>
</svg>
);
};
export const MetaIconOutline = ({ className }: { className?: string }) => {
return (
<svg
id="Layer_1"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 287.56 191"
className={className}
>
<defs>
<linearGradient
id="linear-gradient"
x1="62.34"
y1="101.45"
x2="260.34"
y2="91.45"
gradientTransform="matrix(1, 0, 0, -1, 0, 192)"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="#0064e1" />
<stop offset="0.4" stop-color="#0064e1" />
<stop offset="0.83" stop-color="#0073ee" />
<stop offset="1" stop-color="#0082fb" />
</linearGradient>
<linearGradient
id="linear-gradient-2"
x1="41.42"
y1="53"
x2="41.42"
y2="126"
gradientTransform="matrix(1, 0, 0, -1, 0, 192)"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="#0082fb" />
<stop offset="1" stop-color="#0064e0" />
</linearGradient>
</defs>
<path
fill="#0081fb"
d="M31.06,126c0,11,2.41,19.41,5.56,24.51A19,19,0,0,0,53.19,160c8.1,0,15.51-2,29.79-21.76,11.44-15.83,24.92-38,34-52l15.36-23.6c10.67-16.39,23-34.61,37.18-47C181.07,5.6,193.54,0,206.09,0c21.07,0,41.14,12.21,56.5,35.11,16.81,25.08,25,56.67,25,89.27,0,19.38-3.82,33.62-10.32,44.87C271,180.13,258.72,191,238.13,191V160c17.63,0,22-16.2,22-34.74,0-26.42-6.16-55.74-19.73-76.69-9.63-14.86-22.11-23.94-35.84-23.94-14.85,0-26.8,11.2-40.23,31.17-7.14,10.61-14.47,23.54-22.7,38.13l-9.06,16c-18.2,32.27-22.81,39.62-31.91,51.75C84.74,183,71.12,191,53.19,191c-21.27,0-34.72-9.21-43-23.09C3.34,156.6,0,141.76,0,124.85Z"
/>
<path
fill="url(#linear-gradient)"
d="M24.49,37.3C38.73,15.35,59.28,0,82.85,0c13.65,0,27.22,4,41.39,15.61,15.5,12.65,32,33.48,52.63,67.81l7.39,12.32c17.84,29.72,28,45,33.93,52.22,7.64,9.26,13,12,19.94,12,17.63,0,22-16.2,22-34.74l27.4-.86c0,19.38-3.82,33.62-10.32,44.87C271,180.13,258.72,191,238.13,191c-12.8,0-24.14-2.78-36.68-14.61-9.64-9.08-20.91-25.21-29.58-39.71L146.08,93.6c-12.94-21.62-24.81-37.74-31.68-45C107,40.71,97.51,31.23,82.35,31.23c-12.27,0-22.69,8.61-31.41,21.78Z"
/>
<path
fill="url(#linear-gradient-2)"
d="M82.35,31.23c-12.27,0-22.69,8.61-31.41,21.78C38.61,71.62,31.06,99.34,31.06,126c0,11,2.41,19.41,5.56,24.51L10.14,167.91C3.34,156.6,0,141.76,0,124.85,0,94.1,8.44,62.05,24.49,37.3,38.73,15.35,59.28,0,82.85,0Z"
/>
</svg>
);
};