{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "structured-hero-section", "type": "registry:ui", "title": "Structured Hero Section", "description": "A clean hero section with announcement pill, overlapping showcase cards, trusted-by logo strip, and dual CTAs.", "files": [ { "path": "registry/ruixenui/structured-hero-section.tsx", "content": "\"use client\";\n\nimport * as React from \"react\";\nimport Link from \"next/link\";\nimport { cn } from \"@/lib/utils\";\n\n/* ── types ───────────────────────────────────────────────────── */\n\ntype Action = { href: string; label: string };\n\ninterface ShowcaseCard {\n label?: string;\n imageSrcLight?: string;\n imageSrcDark?: string;\n}\n\ninterface TrustedBySection {\n heading?: string;\n action?: Action;\n logos: React.ReactNode[];\n}\n\nexport interface StructuredHeroSectionProps {\n /** Text shown inside the announcement pill */\n announcement?: string;\n /** Optional link rendered beside the announcement */\n announcementAction?: Action;\n /** Main headline */\n title: React.ReactNode;\n /** Subtitle / description text */\n description?: string;\n /** Primary CTA button */\n primaryAction?: Action;\n /** Secondary CTA button */\n secondaryAction?: Action;\n /** Showcase cards (up to 3) — simple gray placeholders */\n cards?: ShowcaseCard[];\n /** Trusted-by logo strip */\n trustedBy?: TrustedBySection;\n className?: string;\n}\n\n/* ── component ───────────────────────────────────────────────── */\n\nconst cardPositions = [\n \"left-0 z-[1]\",\n \"left-1/2 -translate-x-1/2 z-[2]\",\n \"right-0 z-[3]\",\n] as const;\n\nexport function StructuredHeroSection({\n announcement = \"New release available\",\n announcementAction,\n title,\n description,\n primaryAction,\n secondaryAction,\n cards,\n trustedBy,\n className,\n}: StructuredHeroSectionProps) {\n return (\n \n
\n
\n {/* ── announcement pill ────────────────────────────── */}\n
\n
\n {announcement}\n {announcementAction && (\n <>\n \n \n {announcementAction.label}\n \n \n )}\n
\n
\n\n {/* ── heading + description + CTAs ────────────────── */}\n
\n

\n {title}\n

\n\n {(description || primaryAction || secondaryAction) && (\n
\n {description && (\n

\n {description}\n

\n )}\n\n {(primaryAction || secondaryAction) && (\n
\n {primaryAction && (\n \n {primaryAction.label}\n \n )}\n {secondaryAction && (\n \n {secondaryAction.label}\n \n )}\n
\n )}\n
\n )}\n
\n
\n\n {/* ── overlapping showcase cards ──────────────────── */}\n {cards && cards.length > 0 && (\n
\n
\n {cards.slice(0, 3).map((card, idx) => (\n \n
\n
\n {card.imageSrcLight || card.imageSrcDark ? (\n
\n {card.imageSrcDark && (\n \n )}\n {card.imageSrcLight && (\n \n )}\n
\n ) : null}\n
\n
\n {card.label && (\n

\n {card.label}\n

\n )}\n
\n ))}\n\n {/* ── fade overlays ── */}\n
\n
\n
\n
\n )}\n\n {/* ── trusted-by logo strip ──────────────────────── */}\n {trustedBy && (\n
\n
\n
\n
\n

\n {trustedBy.heading ||\n \"Trusted by fast-growing companies around the world\"}\n

\n {trustedBy.action && (\n \n {trustedBy.action.label}\n \n )}\n
\n
\n {trustedBy.logos.map((logo, idx) => (\n \n {logo}\n
\n ))}\n
\n
\n
\n
\n )}\n
\n \n );\n}\n", "type": "registry:ui", "target": "components/ruixen/structured-hero-section.tsx" } ] }