Cards
FeaturedProjectCard
Large portfolio card with a slow image zoom, eyebrow, oversized title and tags.
npx bezel-add add featured-project-cardpackages/ui/src/cards/FeaturedProjectCard.tsx · 73 lines
"use client";
type Props = {
title: string;
eyebrow?: string;
imageSrc: string;
imageAlt?: string;
href?: string;
tags?: string[];
alignRight?: boolean;
};
export function FeaturedProjectCard({
title,
eyebrow = "",
imageSrc,
imageAlt = "",
href = "#",
tags = [],
alignRight = false,
}: Props) {
return (
<>
<style>{`
.yui-feat-card { position: relative; }
.yui-feat-card a { display: block; text-decoration: none; color: inherit; }
.yui-feat-card a:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.yui-feat-img {
width: 100%; overflow: hidden; border-radius: 2rem;
aspect-ratio: 4/3; isolation: isolate;
}
.yui-feat-card--right .yui-feat-img { width: 70%; margin-left: auto; }
.yui-feat-img img {
width: 100%; height: 100%; object-fit: cover; display: block;
transition: transform 0.9s cubic-bezier(0.25,1,0.5,1);
}
.yui-feat-card:hover .yui-feat-img img { transform: scale(1.05); }
.yui-feat-info { margin-top: 2rem; }
.yui-feat-info--right { text-align: right; }
.yui-feat-eyebrow {
display: block; font-size: 0.8rem; letter-spacing: 0.15em; text-transform: uppercase;
opacity: 0.5; margin-bottom: 0.5rem;
}
.yui-feat-title {
font-size: clamp(3.5rem, 6vw, 8rem); font-weight: 600; line-height: 0.9;
letter-spacing: -0.04em; text-transform: uppercase; margin: 0 0 1.5rem;
}
.yui-feat-meta { display: flex; gap: 0.75rem; flex-wrap: wrap; }
.yui-feat-info--right .yui-feat-meta { justify-content: flex-end; }
.yui-feat-tag {
font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase;
padding: 0.25rem 0.75rem; border: 1px solid currentColor; border-radius: 999px; opacity: 0.5;
}
`}</style>
<article className={`yui-feat-card${alignRight ? " yui-feat-card--right" : ""}`}>
<a href={href}>
<div className="yui-feat-img">
<img src={imageSrc} alt={imageAlt} />
</div>
<div className={`yui-feat-info${alignRight ? " yui-feat-info--right" : ""}`}>
{eyebrow && <span className="yui-feat-eyebrow">{eyebrow}</span>}
<h2 className="yui-feat-title">{title}</h2>
{tags.length > 0 && (
<div className="yui-feat-meta">
{tags.map((t) => <span key={t} className="yui-feat-tag">{t}</span>)}
</div>
)}
</div>
</a>
</article>
</>
);
}