65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import * as React from "react"
|
|
|
|
import { cn } from "@/lib/utils"
|
|
|
|
type InfoStripItem = {
|
|
/** self-contained visual (asset-kit render / icon) */
|
|
media: React.ReactNode
|
|
eyebrow: React.ReactNode
|
|
title: React.ReactNode
|
|
}
|
|
|
|
/**
|
|
* Wide white strip directly under a hero: hairline-divided columns (2 up on
|
|
* mobile, 3 from `sm`, 5 from `lg`), each a glass render over a teal eyebrow
|
|
* and a navy title. Dividers are drawn per column for the current layout so
|
|
* they stay inset from the card's padding.
|
|
*/
|
|
function InfoStrip({
|
|
items,
|
|
className,
|
|
}: {
|
|
items: InfoStripItem[]
|
|
className?: string
|
|
}) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"grid grid-cols-2 rounded-3xl border border-border bg-card p-2 shadow-card sm:grid-cols-3 sm:p-3 lg:grid-cols-5",
|
|
className
|
|
)}
|
|
>
|
|
{items.map((item, i) => (
|
|
<div
|
|
key={i}
|
|
className={cn(
|
|
"flex flex-col items-center px-3 py-4 text-center sm:px-4",
|
|
/* dividers for the 2-up layout … */
|
|
i % 2 !== 0 ? "border-l border-border" : "border-l-0",
|
|
i >= 2 ? "border-t border-border" : "border-t-0",
|
|
/* … the 3-up layout … */
|
|
i % 3 !== 0 ? "sm:border-l" : "sm:border-l-0",
|
|
i >= 3 ? "sm:border-t" : "sm:border-t-0",
|
|
/* … and the 5-up layout */
|
|
i % 5 !== 0 ? "lg:border-l" : "lg:border-l-0",
|
|
"lg:border-t-0"
|
|
)}
|
|
>
|
|
<span className="flex h-14 items-center justify-center">
|
|
{item.media}
|
|
</span>
|
|
<p className="mt-3 text-[0.625rem] font-bold tracking-[0.14em] text-primary uppercase">
|
|
{item.eyebrow}
|
|
</p>
|
|
<div className="mt-1.5 text-xs leading-snug font-semibold text-balance text-navy/75 sm:text-[0.8125rem]">
|
|
{item.title}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export { InfoStrip }
|
|
export type { InfoStripItem }
|