{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sales-ai-hero",
  "type": "registry:ui",
  "title": "Sales AI Hero",
  "description": "A SaaS landing hero with floating announcement pill, oversized centered headline, paired square + landscape media tiles, and a divider-flanked trusted-by logo strip.",
  "dependencies": [
    "lucide-react"
  ],
  "files": [
    {
      "path": "registry/ruixenui/sales-ai-hero.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport Link from \"next/link\";\nimport { ArrowRight, Zap } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\n/* ── types ───────────────────────────────────────────────────── */\n\ninterface Announcement {\n  label: string;\n  href?: string;\n  /** Override the default lightning glyph */\n  icon?: React.ReactNode;\n}\n\ninterface LogoItem {\n  name: string;\n  /** Optional src for an <img> rendering. Omit to render `name` as text mark. */\n  src?: string;\n  /** Or supply fully custom JSX (e.g. an inline SVG wordmark) */\n  logo?: React.ReactNode;\n  href?: string;\n}\n\ninterface TrustedBy {\n  /** Headline text, supports inline markup via `highlight` slot below. */\n  prefix?: string;\n  /** Optional highlighted segment rendered bold next to `prefix`. */\n  highlight?: string;\n  /** Trailing text after the highlighted segment. */\n  suffix?: string;\n  logos: LogoItem[];\n}\n\nexport interface SalesAiHeroProps {\n  announcement?: Announcement;\n  title: React.ReactNode;\n  description?: React.ReactNode;\n  /** Content for the left (portrait) media tile. Falls back to a placeholder. */\n  leftMedia?: React.ReactNode;\n  /** Content for the right (landscape) media tile. Falls back to a placeholder. */\n  rightMedia?: React.ReactNode;\n  /** Trusted-by strip rendered below the media. Omit to hide. */\n  trustedBy?: TrustedBy;\n  className?: string;\n}\n\n/* ── pieces ──────────────────────────────────────────────────── */\n\nfunction AnnouncementPill({ announcement }: { announcement: Announcement }) {\n  const body = (\n    <>\n      <span className=\"inline-flex size-5 shrink-0 items-center justify-center rounded-full text-foreground\">\n        {announcement.icon ?? (\n          <Zap className=\"size-4 fill-foreground\" strokeWidth={0} />\n        )}\n      </span>\n      <span className=\"truncate\">{announcement.label}</span>\n      <span className=\"inline-flex size-6 shrink-0 items-center justify-center rounded-full bg-foreground text-background\">\n        <ArrowRight className=\"size-3.5\" strokeWidth={2.5} />\n      </span>\n    </>\n  );\n\n  const className = cn(\n    \"inline-flex h-11 max-w-full items-center gap-2.5 rounded-full bg-card pl-4 pr-1.5 text-sm font-medium text-foreground shadow-[0_1px_2px_rgba(0,0,0,0.04),0_8px_24px_-12px_rgba(0,0,0,0.18)] ring-1 ring-border/60 transition-colors\",\n    \"hover:bg-muted/60\",\n  );\n\n  return announcement.href ? (\n    <Link href={announcement.href} className={className}>\n      {body}\n    </Link>\n  ) : (\n    <div className={className}>{body}</div>\n  );\n}\n\nfunction MediaTile({\n  children,\n  aspect,\n  tone = \"muted\",\n  className,\n}: {\n  children?: React.ReactNode;\n  aspect: string;\n  tone?: \"muted\" | \"accent\";\n  className?: string;\n}) {\n  return (\n    <div\n      className={cn(\n        \"relative overflow-hidden rounded-2xl ring-1 ring-border/60\",\n        tone === \"muted\" ? \"bg-muted\" : \"bg-card\",\n        aspect,\n        className,\n      )}\n    >\n      {children ?? <DefaultPlaceholder tone={tone} />}\n    </div>\n  );\n}\n\nfunction DefaultPlaceholder({ tone }: { tone: \"muted\" | \"accent\" }) {\n  return (\n    <div\n      aria-hidden\n      className={cn(\n        \"absolute inset-0 flex items-center justify-center\",\n        tone === \"accent\" &&\n          \"bg-gradient-to-br from-primary/10 via-background to-primary/5\",\n      )}\n    >\n      <div className=\"flex flex-col items-center gap-2 text-muted-foreground/70\">\n        <div className=\"size-8 rounded-full bg-foreground/10\" />\n        <span className=\"text-xs font-medium uppercase tracking-wider\">\n          Replace media\n        </span>\n      </div>\n    </div>\n  );\n}\n\nfunction LogoMark({ item }: { item: LogoItem }) {\n  if (item.logo) return <>{item.logo}</>;\n  if (item.src) {\n    return (\n      // eslint-disable-next-line @next/next/no-img-element\n      <img\n        src={item.src}\n        alt={item.name}\n        className=\"h-6 w-auto opacity-80 [filter:brightness(0)_saturate(0)] dark:[filter:brightness(0)_invert(1)] md:h-7\"\n      />\n    );\n  }\n  return (\n    <span className=\"select-none whitespace-nowrap text-base font-semibold tracking-tight text-foreground/80 md:text-lg\">\n      {item.name}\n    </span>\n  );\n}\n\n/* ── component ───────────────────────────────────────────────── */\n\nexport function SalesAiHero({\n  announcement,\n  title,\n  description,\n  leftMedia,\n  rightMedia,\n  trustedBy,\n  className,\n}: SalesAiHeroProps) {\n  return (\n    <section\n      aria-label=\"Hero\"\n      className={cn(\"relative w-full overflow-hidden bg-background\", className)}\n    >\n      <div className=\"mx-auto w-full max-w-7xl px-6 pb-12 pt-16 md:pb-16 md:pt-24 lg:pb-20 lg:pt-28\">\n        {/* ── announcement pill ─────────────────────────── */}\n        {announcement && (\n          <div className=\"flex justify-center\">\n            <AnnouncementPill announcement={announcement} />\n          </div>\n        )}\n\n        {/* ── title ─────────────────────────────────────── */}\n        <h1\n          className={cn(\n            \"mx-auto max-w-5xl text-balance text-center font-semibold tracking-[-0.035em] text-foreground\",\n            \"text-[40px] leading-[1.05] sm:text-5xl md:text-6xl lg:text-[72px] xl:text-[80px]\",\n            announcement ? \"mt-8 md:mt-10\" : \"mt-0\",\n          )}\n        >\n          {title}\n        </h1>\n\n        {/* ── description ───────────────────────────────── */}\n        {description && (\n          <p className=\"mx-auto mt-5 max-w-xl text-balance text-center text-base text-muted-foreground md:mt-6 md:text-lg\">\n            {description}\n          </p>\n        )}\n\n        {/* ── media row ─────────────────────────────────── */}\n        <div className=\"mt-12 grid grid-cols-1 gap-4 sm:grid-cols-3 md:mt-16 md:gap-6\">\n          <MediaTile\n            aspect=\"aspect-[4/5] sm:aspect-auto sm:h-full\"\n            tone=\"muted\"\n          >\n            {leftMedia}\n          </MediaTile>\n          <MediaTile aspect=\"aspect-[5/3] sm:col-span-2\" tone=\"accent\">\n            {rightMedia}\n          </MediaTile>\n        </div>\n\n        {/* ── trusted-by ────────────────────────────────── */}\n        {trustedBy && (\n          <div className=\"mt-14 md:mt-20\">\n            <div className=\"flex items-center gap-6\">\n              <div className=\"h-px flex-1 bg-border\" />\n              <p className=\"text-center text-sm text-muted-foreground md:text-base\">\n                {trustedBy.prefix ?? \"Trusted By \"}\n                {trustedBy.highlight && (\n                  <span className=\"font-semibold text-foreground\">\n                    {trustedBy.highlight}\n                  </span>\n                )}\n                {trustedBy.suffix}\n              </p>\n              <div className=\"h-px flex-1 bg-border\" />\n            </div>\n\n            {trustedBy.logos.length > 0 && (\n              <div className=\"mt-8 flex flex-wrap items-center justify-center gap-x-6 gap-y-6 md:mt-10 md:gap-x-0\">\n                {trustedBy.logos.map((item, idx) => (\n                  <React.Fragment key={`${item.name}-${idx}`}>\n                    <div className=\"flex items-center justify-center md:px-10\">\n                      {item.href ? (\n                        <Link\n                          href={item.href}\n                          aria-label={item.name}\n                          className=\"inline-flex items-center\"\n                        >\n                          <LogoMark item={item} />\n                        </Link>\n                      ) : (\n                        <LogoMark item={item} />\n                      )}\n                    </div>\n                    {idx < trustedBy.logos.length - 1 && (\n                      <span\n                        aria-hidden\n                        className=\"hidden h-6 w-px bg-border md:inline-block\"\n                      />\n                    )}\n                  </React.Fragment>\n                ))}\n              </div>\n            )}\n          </div>\n        )}\n      </div>\n    </section>\n  );\n}\n\nexport default SalesAiHero;\n",
      "type": "registry:ui",
      "target": "components/ruixen/sales-ai-hero.tsx"
    }
  ]
}