Move the use-case index onto Learn so the pilot stories stay reachable, and make share images resolve on the host that serves the page.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
adilalloandCursor committed 2026-11-03 20:28:04 -07:00
1 parent 18abeb56dd
commit 9ea3f9fd0a
27 files changed
+656 -419

No files matched your search

@@ -22,10 +22,12 @@ const ContentContainerContainer = memo<ContentContainerProps>(
leadingImageSrc,
leadingImageAlt,
showLeadingImage: showLeadingImageProp = true,
showByline: showBylineProp = true,
}) => {
const size = sizeProp;
const tone = toneProp;
const showLeadingImage = showLeadingImageProp;
const showByline = showBylineProp;
const width =
widthProp ?? (size === "useCase" ? "100%" : "200px");
const onLight = tone === "onLight";
@@ -119,6 +121,7 @@ const ContentContainerContainer = memo<ContentContainerProps>(
iconImage={iconImage}
iconAlt={iconAlt}
showLeadingImage={showLeadingImage}
showByline={showByline}
containerClasses={containerClasses}
contentGapClasses={contentGapClasses}
textGapClasses={textGapClasses}
@@ -22,6 +22,8 @@ export interface ContentContainerProps {
leadingImageAlt?: string;
/** When false, omits the icon row above the title. Default true. */
showLeadingImage?: boolean;
/** When false, omits author and date. Default true. */
showByline?: boolean;
}
export interface ContentContainerViewProps {
@@ -32,6 +34,7 @@ export interface ContentContainerViewProps {
iconImage: string;
iconAlt: string;
showLeadingImage: boolean;
showByline: boolean;
containerClasses: string;
contentGapClasses: string;
textGapClasses: string;
@@ -8,6 +8,7 @@ function ContentContainerView({
iconImage,
iconAlt,
showLeadingImage,
showByline,
containerClasses,
contentGapClasses,
textGapClasses,
@@ -18,10 +19,7 @@ function ContentContainerView({
formattedDate,
}: ContentContainerViewProps) {
return (
<div
className={containerClasses}
style={size === "xs" ? {} : { width }}
>
<div className={containerClasses} style={size === "xs" ? {} : { width }}>
{/* Content Container - gap between icon and text */}
<div className={contentGapClasses}>
{showLeadingImage ? (
@@ -45,13 +43,12 @@ function ContentContainerView({
</div>
</div>
<div className="flex min-w-0 items-end gap-[var(--space-200)]">
{/* Author Name */}
<span className={authorClasses}>{post.frontmatter.author}</span>
{/* Date */}
<span className={dateClasses}>{formattedDate}</span>
</div>
{showByline ? (
<div className="flex min-w-0 items-end gap-[var(--space-200)]">
<span className={authorClasses}>{post.frontmatter.author}</span>
<span className={dateClasses}>{formattedDate}</span>
</div>
) : null}
</div>
);
}
@@ -20,6 +20,10 @@ const ContentThumbnailTemplateContainer = memo<ContentThumbnailTemplateProps>(
className = "",
variant: variantProp = "vertical",
sizing: sizingProp = "fluid",
href,
showByline = true,
showLeadingImage = true,
leadingImageAlt,
}) => {
const variant = variantProp;
const sizing = sizingProp;
@@ -70,6 +74,10 @@ const ContentThumbnailTemplateContainer = memo<ContentThumbnailTemplateProps>(
sizing={sizing}
backgroundImage={backgroundImage}
backgroundImageSmd={backgroundImageSmd}
href={href ?? `/blog/${post.slug}`}
showByline={showByline}
showLeadingImage={showLeadingImage}
leadingImageAlt={leadingImageAlt}
/>
);
},
@@ -20,6 +20,14 @@ export interface ContentThumbnailTemplateProps {
*/
sizing?: ContentThumbnailTemplateSizingValue;
slugOrder?: string[];
/** Overrides the default `/blog/[slug]` destination. */
href?: string;
/** Author and date. Learn hides these until byline dates are approved. */
showByline?: boolean;
/** Tag mark above the title. Decorative on catalog cards. */
showLeadingImage?: boolean;
/** Alt for the tag mark. Empty when the mark repeats the title. */
leadingImageAlt?: string;
}
export interface ContentThumbnailTemplateViewProps {
@@ -30,4 +38,8 @@ export interface ContentThumbnailTemplateViewProps {
backgroundImage: string;
/** Wide-viewport image source for variant="responsive" (≥smd). */
backgroundImageSmd?: string;
href: string;
showByline: boolean;
showLeadingImage: boolean;
leadingImageAlt?: string;
}
@@ -10,15 +10,16 @@ function ContentThumbnailTemplateView({
sizing,
backgroundImage,
backgroundImageSmd,
href,
showByline,
showLeadingImage,
leadingImageAlt,
}: ContentThumbnailTemplateViewProps) {
if (variant === "responsive") {
// Single card; <picture> swaps the orientation-specific image at smd
// (530px), aspect-ratio and content positioning switch via Tailwind.
return (
<Link
href={`/blog/${post.slug}`}
className={`group block w-full ${className}`}
>
<Link href={href} className={`group block w-full ${className}`}>
<div className="relative aspect-[320/225.5] w-full overflow-hidden smd:aspect-[260/390]">
<div className="absolute inset-0 z-0">
<picture>
@@ -37,7 +38,13 @@ function ContentThumbnailTemplateView({
</picture>
</div>
<div className="absolute left-[4.375%] top-[6.099%] z-20 w-[71.875%] max-h-[48%] overflow-hidden smd:left-[6.923%] smd:top-[4.615%] smd:w-[76.923%]">
<ContentContainer post={post} size="xs" />
<ContentContainer
post={post}
size="xs"
showByline={showByline}
showLeadingImage={showLeadingImage}
leadingImageAlt={leadingImageAlt}
/>
</div>
</div>
</Link>
@@ -47,10 +54,7 @@ function ContentThumbnailTemplateView({
if (variant === "vertical") {
if (sizing === "fixed") {
return (
<Link
href={`/blog/${post.slug}`}
className={`group block ${className}`}
>
<Link href={href} className={`group block ${className}`}>
<div className="relative h-[390px] w-[260px] overflow-hidden">
<div className="absolute inset-0 z-0">
{/* eslint-disable-next-line @next/next/no-img-element */}
@@ -61,7 +65,14 @@ function ContentThumbnailTemplateView({
/>
</div>
<div className="absolute left-[18px] top-[18px] z-20 w-[200px]">
<ContentContainer post={post} width="200px" size="xs" />
<ContentContainer
post={post}
width="200px"
size="xs"
showByline={showByline}
showLeadingImage={showLeadingImage}
leadingImageAlt={leadingImageAlt}
/>
</div>
</div>
</Link>
@@ -69,10 +80,7 @@ function ContentThumbnailTemplateView({
}
return (
<Link
href={`/blog/${post.slug}`}
className={`group block w-full ${className}`}
>
<Link href={href} className={`group block w-full ${className}`}>
<div className="relative aspect-[260/390] w-full overflow-hidden">
<div className="absolute inset-0 z-0">
{/* eslint-disable-next-line @next/next/no-img-element */}
@@ -83,7 +91,13 @@ function ContentThumbnailTemplateView({
/>
</div>
<div className="absolute left-[6.923%] top-[4.615%] z-20 w-[76.923%] max-h-[48%] overflow-hidden">
<ContentContainer post={post} size="xs" />
<ContentContainer
post={post}
size="xs"
showByline={showByline}
showLeadingImage={showLeadingImage}
leadingImageAlt={leadingImageAlt}
/>
</div>
</div>
</Link>
@@ -92,7 +106,7 @@ function ContentThumbnailTemplateView({
if (sizing === "fixed") {
return (
<Link href={`/blog/${post.slug}`} className={`group block ${className}`}>
<Link href={href} className={`group block ${className}`}>
<div className="relative h-[225.5px] w-[320px] overflow-hidden">
<div className="absolute inset-0 z-0">
{/* eslint-disable-next-line @next/next/no-img-element */}
@@ -103,7 +117,14 @@ function ContentThumbnailTemplateView({
/>
</div>
<div className="absolute left-[14px] top-[13.75px] z-20 w-[230px]">
<ContentContainer post={post} width="230px" size="xs" />
<ContentContainer
post={post}
width="230px"
size="xs"
showByline={showByline}
showLeadingImage={showLeadingImage}
leadingImageAlt={leadingImageAlt}
/>
</div>
</div>
</Link>
@@ -111,10 +132,7 @@ function ContentThumbnailTemplateView({
}
return (
<Link
href={`/blog/${post.slug}`}
className={`group block w-full ${className}`}
>
<Link href={href} className={`group block w-full ${className}`}>
<div className="relative aspect-[320/225.5] w-full overflow-hidden">
<div className="absolute inset-0 z-0">
{/* eslint-disable-next-line @next/next/no-img-element */}
@@ -125,7 +143,13 @@ function ContentThumbnailTemplateView({
/>
</div>
<div className="absolute left-[4.375%] top-[6.099%] z-20 w-[71.875%] max-h-[48%] overflow-hidden">
<ContentContainer post={post} size="xs" />
<ContentContainer
post={post}
size="xs"
showByline={showByline}
showLeadingImage={showLeadingImage}
leadingImageAlt={leadingImageAlt}
/>
</div>
</div>
</Link>
@@ -9,6 +9,8 @@ export interface FaqAccordionItem {
export interface FaqAccordionProps {
title: string;
items: FaqAccordionItem[];
/** In-page target, such as the Learn FAQ. */
id?: string;
size?: AccordionSizeValue;
/** Layout accordion size from `lg` (default **m**, Figma 22135-890258). */
lgSize?: AccordionSizeValue;
@@ -17,10 +17,12 @@ function FaqAccordionView({
lgSize,
xlSize,
headingId,
id,
className = "",
}: FaqAccordionViewProps) {
return (
<section
id={id}
aria-labelledby={headingId}
className={`bg-[var(--color-surface-default-secondary)] px-[var(--space-100)] py-[var(--space-800)] md:px-[var(--space-2400)] md:py-[var(--space-1800)] lg:px-[var(--space-4000)] lg:py-[var(--space-2400)] ${className}`.trim()}
>
@@ -40,6 +42,7 @@ function FaqAccordionView({
size={size}
lgSize={lgSize}
xlSize={xlSize}
defaultOpen={index === 0}
>
{item.answer}
</LayoutAccordion>