{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hero-endorsement",
  "type": "registry:block",
  "title": "Founder or creator endorsement hero",
  "description": "Portrait card with a product chip beside a large pull quote, name, role, credentials and an FTC disclosure line for paid partners.",
  "author": "StoreKit <hello@storekit.dev>",
  "categories": [
    "hero",
    "any"
  ],
  "dependencies": [
    "motion",
    "lucide-react"
  ],
  "registryDependencies": [
    "https://storekit-eight.vercel.app/r/cn.json",
    "https://storekit-eight.vercel.app/r/sk-analytics.json"
  ],
  "files": [
    {
      "path": "hero/hero-endorsement.tsx",
      "content": "\"use client\"\n\nimport { motion, useReducedMotion } from \"motion/react\"\nimport { Quote } from \"lucide-react\"\nimport { cn } from \"@/components/storekit/lib/cn\"\nimport { useSkBlock } from \"@/components/storekit/lib/sk-analytics\"\n\n/* Creator or founder endorsement hero. A portrait card on one side, a large\n   pull quote on the other, then the person's name, role and the credentials\n   that make the quote count. `kind` switches the small label between a\n   founder note and a creator or expert partner, and a disclosure line is\n   rendered for paid partnerships (FTC). The product they are holding links\n   from a chip pinned to the portrait. Stacks portrait first on mobile. */\n\nconst EASE = [0.23, 1, 0.32, 1] as const\n\ntype Cta = { label: string; href: string }\n\nconst PRIMARY =\n  \"sk-btn inline-flex min-h-12 items-center justify-center py-2.5 text-center leading-tight rounded-sk-btn bg-sk-accent px-7 text-[15px] font-medium text-sk-accent-ink outline-none transition-[filter,transform] duration-200 ease-sk-out hover:brightness-[1.06] focus-visible:ring-2 focus-visible:ring-sk-accent focus-visible:ring-offset-2 focus-visible:ring-offset-sk-paper active:scale-[0.97]\"\nconst SECONDARY =\n  \"sk-btn inline-flex min-h-12 items-center justify-center py-2.5 text-center leading-tight rounded-sk-btn border border-sk-line px-7 text-[15px] font-medium text-sk-ink outline-none transition-[background-color,transform] duration-200 ease-sk-out hover:bg-sk-ink/[0.04] focus-visible:ring-2 focus-visible:ring-sk-accent focus-visible:ring-offset-2 focus-visible:ring-offset-sk-paper active:scale-[0.97]\"\n\nexport function HeroEndorsement({\n  kind = \"founder\",\n  headline = \"Why we make it\",\n  portrait = \"/placeholder.webp\",\n  portraitAlt = \"\",\n  portraitFocus = \"center\",\n  quote = \"I built this because I wanted one thing in my morning I never had to think about. Every batch still crosses my desk before it ships.\",\n  name = \"Jordan Ellis\",\n  role = \"Founder\",\n  credentials = [\"Registered dietitian\", \"12 years in clinical nutrition\"],\n  product,\n  disclosure,\n  primaryCta = { label: \"Shop the routine\", href: \"#\" },\n  secondaryCta = { label: \"Read the full story\", href: \"#\" },\n  className,\n}: {\n  kind?: \"founder\" | \"creator\" | \"expert\"\n  /** Page heading for assistive tech; the quote is the visual headline. */\n  headline?: string\n  portrait?: string\n  portraitAlt?: string\n  portraitFocus?: string\n  quote?: string\n  name?: string\n  role?: string\n  credentials?: string[]\n  /** Product in the shot, shown as a chip on the portrait. */\n  product?: { title: string; image?: string; href: string }\n  /** Paid partnership or gifted product note. Required by the FTC for creator deals. */\n  disclosure?: string\n  primaryCta?: Cta\n  secondaryCta?: Cta\n  className?: string\n}) {\n  const reduce = useReducedMotion()\n  const sk = useSkBlock(\"hero\", \"hero-endorsement\")\n  const label = kind === \"founder\" ? \"A note from our founder\" : kind === \"expert\" ? \"Expert pick\" : \"Creator pick\"\n  const rise = (i: number) => ({\n    initial: { opacity: 0, y: reduce ? 0 : 8 },\n    animate: { opacity: 1, y: 0 },\n    transition: { duration: 0.5, ease: EASE, delay: reduce ? 0 : 0.12 + i * 0.07 },\n  })\n\n  return (\n    <section ref={sk.ref} {...sk.attrs} className={cn(\"bg-sk-paper text-sk-ink\", className)}>\n      <div className=\"mx-auto grid w-full max-w-6xl items-center gap-8 px-4 py-10 sm:px-8 sm:py-14 lg:grid-cols-[0.85fr_1.15fr] lg:gap-16 lg:py-16\">\n        <motion.figure\n          initial={{ opacity: 0, scale: reduce ? 1 : 0.97 }}\n          animate={{ opacity: 1, scale: 1 }}\n          transition={{ duration: 0.6, ease: EASE }}\n          className=\"relative mx-auto w-full max-w-[440px] lg:max-w-none\"\n        >\n          <div className=\"relative aspect-[4/5] overflow-hidden rounded-sk-card border border-sk-line bg-sk-surface\">\n            <img src={portrait} alt={portraitAlt} className=\"absolute inset-0 h-full w-full object-cover\" style={{ objectPosition: portraitFocus }} />\n          </div>\n          {product ? (\n            <a\n              href={product.href}\n              onClick={() => sk.emit(\"interact\", \"product_chip\")}\n              className=\"absolute -bottom-4 right-4 flex items-center gap-3 rounded-sk-card border border-sk-line bg-sk-card py-2 pl-2 pr-4 text-sk-ink shadow-[0_24px_48px_-24px_rgb(var(--sk-ink)/0.35)] outline-none transition-transform duration-300 ease-sk-out hover:-translate-y-0.5 focus-visible:ring-2 focus-visible:ring-sk-accent\"\n            >\n              {product.image ? <img src={product.image} alt=\"\" className=\"h-11 w-11 rounded-sk-chip bg-sk-surface object-cover\" /> : null}\n              <span className=\"flex flex-col leading-tight\">\n                <span className=\"font-sk-mono text-[10px] uppercase tracking-[0.14em] text-sk-muted\">In the shot</span>\n                <span className=\"text-sm font-medium\">{product.title}</span>\n              </span>\n            </a>\n          ) : null}\n        </motion.figure>\n\n        <div className=\"pt-4 lg:pt-0\">\n          <h1 className=\"sr-only\">{headline}</h1>\n          <motion.p {...rise(0)} className=\"font-sk-mono text-[11px] uppercase tracking-[0.14em] text-sk-muted\">\n            {label}\n          </motion.p>\n          <motion.blockquote {...rise(1)} className=\"relative mt-5\">\n            <Quote aria-hidden size={28} className=\"mb-3 text-sk-accent\" />\n            <p className=\"text-balance font-sk-display font-semibold leading-[1.15] tracking-[-0.015em]\" style={{ fontSize: \"clamp(1.6rem, 3.2vw, 2.6rem)\" }}>\n              {quote}\n            </p>\n          </motion.blockquote>\n          <motion.div {...rise(2)} className=\"mt-7 flex flex-col gap-1\">\n            <p className=\"text-base font-semibold\">{name}</p>\n            <p className=\"text-sm text-sk-muted\">{role}</p>\n            {credentials.length ? (\n              <ul className=\"mt-3 flex flex-wrap gap-2\">\n                {credentials.map((c) => (\n                  <li key={c} className=\"rounded-sk-chip border border-sk-line px-3 py-1 text-[12px] text-sk-muted\">\n                    {c}\n                  </li>\n                ))}\n              </ul>\n            ) : null}\n          </motion.div>\n          <motion.div {...rise(3)} className=\"mt-8 flex flex-col gap-3 sm:flex-row\">\n            <a href={primaryCta.href} onClick={() => sk.emit(\"interact\", \"cta\")} className={PRIMARY}>\n              {primaryCta.label}\n            </a>\n            <a href={secondaryCta.href} onClick={() => sk.emit(\"interact\", \"cta_secondary\")} className={SECONDARY}>\n              {secondaryCta.label}\n            </a>\n          </motion.div>\n          {disclosure ? <p className=\"mt-5 text-[12px] text-sk-muted\">{disclosure}</p> : null}\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:block",
      "target": "components/storekit/hero/hero-endorsement.tsx"
    }
  ],
  "docs": "Set `kind` to founder, creator or expert. Always pass `disclosure` for paid or gifted creator deals.",
  "meta": {
    "section": "hero",
    "variant": "endorsement",
    "niche": [
      "any"
    ],
    "commerce": [
      "cta"
    ],
    "previewHeight": 640
  }
}