{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hero-proof",
  "type": "registry:block",
  "title": "Proof-led hero",
  "description": "Oversized average rating and review count lead, with a pinned featured review, award chips and press quotes as text wordmarks.",
  "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",
    "https://storekit-eight.vercel.app/r/stars.json"
  ],
  "files": [
    {
      "path": "hero/hero-proof.tsx",
      "content": "\"use client\"\n\nimport { motion, useReducedMotion } from \"motion/react\"\nimport { Award, BadgeCheck } from \"lucide-react\"\nimport { cn } from \"@/components/storekit/lib/cn\"\nimport { useSkBlock } from \"@/components/storekit/lib/sk-analytics\"\nimport { Stars } from \"@/components/storekit/ui/stars\"\n\n/* Proof-led hero. The evidence is the headline: an oversized average\n   rating with stars and the verified review count, a featured review pinned\n   to the product image, award chips and a row of press quotes set as\n   wordmarks. The rating links to the reviews section. Publications render\n   as text so no third-party logos ship with the block; pass `logo` images\n   if you have the rights. Stacks proof first on mobile, then the image. */\n\nconst EASE = [0.23, 1, 0.32, 1] as const\n\ntype Cta = { label: string; href: string }\nexport type PressQuote = { outlet: string; quote: string; logo?: 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]\"\n\nconst PRESS: PressQuote[] = [\n  { outlet: \"The Daily Edit\", quote: \"The greens powder that finally tastes good.\" },\n  { outlet: \"Wellness Weekly\", quote: \"Best electrolyte of the year.\" },\n  { outlet: \"Morning Report\", quote: \"A routine you will actually keep.\" },\n]\n\nexport function HeroProof({\n  rating = 4.8,\n  count = 12400,\n  reviewsHref = \"#reviews\",\n  headline = \"Loved by 12,400 verified customers.\",\n  subcopy = \"Every review is from a confirmed order. Read the good, the bad and the photos.\",\n  primaryCta = { label: \"Shop best sellers\", href: \"#\" },\n  awards = [\"Best Greens 2026\", \"Clean Label Certified\"],\n  press = PRESS,\n  review = { quote: \"I have tried six greens powders. This is the only one I have reordered four times.\", author: \"Priya S.\", verified: true },\n  image = \"/placeholder.webp\",\n  imageAlt = \"\",\n  className,\n}: {\n  rating?: number\n  count?: number\n  reviewsHref?: string\n  headline?: string\n  subcopy?: string\n  primaryCta?: Cta\n  awards?: string[]\n  press?: PressQuote[]\n  review?: { quote: string; author: string; verified?: boolean } | null\n  image?: string\n  imageAlt?: string\n  className?: string\n}) {\n  const reduce = useReducedMotion()\n  const sk = useSkBlock(\"hero\", \"hero-proof\")\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 : 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 w-full max-w-6xl px-4 py-10 sm:px-8 sm:py-14\">\n        <div className=\"grid items-center gap-10 lg:grid-cols-[1.1fr_0.9fr] lg:gap-14\">\n          <div>\n            <motion.a\n              {...rise(0)}\n              href={reviewsHref}\n              onClick={() => sk.emit(\"interact\", \"rating\")}\n              aria-label={`Rated ${rating.toFixed(1)} out of 5 from ${count.toLocaleString(\"en-US\")} reviews. Read reviews.`}\n              className=\"group inline-flex flex-wrap items-end gap-x-4 gap-y-2 rounded-sk-card outline-none focus-visible:ring-2 focus-visible:ring-sk-accent focus-visible:ring-offset-4 focus-visible:ring-offset-sk-paper\"\n            >\n              <span aria-hidden className=\"font-sk-display font-semibold leading-[0.85] tracking-[-0.05em] tabular-nums\" style={{ fontSize: \"clamp(4.5rem, 12vw, 8.5rem)\" }}>\n                {rating.toFixed(1)}\n              </span>\n              <span aria-hidden className=\"mb-2 flex flex-col gap-1.5\">\n                <Stars value={rating} size={20} />\n                <span className=\"text-sm text-sk-muted underline decoration-sk-line underline-offset-4 transition-[text-decoration-color] group-hover:decoration-sk-ink\">\n                  {count.toLocaleString(\"en-US\")} verified reviews\n                </span>\n              </span>\n            </motion.a>\n            <motion.h1 {...rise(1)} className=\"mt-6 max-w-xl text-balance font-sk-display font-semibold leading-[1.1] tracking-[-0.02em]\" style={{ fontSize: \"clamp(1.6rem, 3vw, 2.4rem)\" }}>\n              {headline}\n            </motion.h1>\n            <motion.p {...rise(2)} className=\"mt-3 max-w-md text-[15px] leading-[1.55] text-sk-muted\">\n              {subcopy}\n            </motion.p>\n            <motion.div {...rise(3)} className=\"mt-7 flex flex-col gap-4 sm:flex-row sm:items-center\">\n              <a href={primaryCta.href} onClick={() => sk.emit(\"interact\", \"cta\")} className={PRIMARY}>\n                {primaryCta.label}\n              </a>\n              {awards.length ? (\n                <ul className=\"flex flex-wrap gap-2\">\n                  {awards.map((a) => (\n                    <li key={a} className=\"inline-flex items-center gap-1.5 rounded-sk-chip border border-sk-line px-3 py-1.5 text-[12px] font-medium\">\n                      <Award size={14} aria-hidden className=\"text-sk-accent\" />\n                      {a}\n                    </li>\n                  ))}\n                </ul>\n              ) : null}\n            </motion.div>\n          </div>\n\n          <motion.div\n            initial={{ opacity: 0, scale: reduce ? 1 : 0.97 }}\n            animate={{ opacity: 1, scale: 1 }}\n            transition={{ duration: 0.6, ease: EASE, delay: reduce ? 0 : 0.1 }}\n            className=\"relative pb-16 sm:pb-12\"\n          >\n            <div className=\"relative aspect-[4/3] overflow-hidden rounded-sk-card border border-sk-line bg-sk-surface lg:aspect-[4/5]\">\n              <img src={image} alt={imageAlt} className=\"absolute inset-0 h-full w-full object-cover\" />\n            </div>\n            {review ? (\n              <motion.figure\n                initial={{ opacity: 0, y: reduce ? 0 : 14 }}\n                animate={{ opacity: 1, y: 0 }}\n                transition={{ type: \"spring\", stiffness: 220, damping: 26, delay: reduce ? 0 : 0.35 }}\n                className=\"absolute bottom-0 left-3 right-3 rounded-sk-card border border-sk-line bg-sk-card p-4 shadow-[0_30px_60px_-30px_rgb(var(--sk-ink)/0.45)] sm:left-auto sm:right-[-12px] sm:w-[300px] lg:-left-10 lg:right-auto\"\n              >\n                <Stars value={5} size={13} />\n                <blockquote className=\"mt-2 text-[14px] leading-[1.45]\">{review.quote}</blockquote>\n                <figcaption className=\"mt-2.5 flex items-center gap-1.5 text-[12px] text-sk-muted\">\n                  <span className=\"font-medium text-sk-ink\">{review.author}</span>\n                  {review.verified ? (\n                    <>\n                      <BadgeCheck size={13} aria-hidden className=\"text-sk-savings\" />\n                      Verified buyer\n                    </>\n                  ) : null}\n                </figcaption>\n              </motion.figure>\n            ) : null}\n          </motion.div>\n        </div>\n\n        {press.length ? (\n          <motion.ul {...rise(4)} aria-label=\"As seen in\" className=\"mt-10 grid gap-px overflow-hidden rounded-sk-card border border-sk-line bg-sk-line sm:grid-cols-3\">\n            {press.slice(0, 3).map((p) => (\n              <li key={p.outlet} className=\"bg-sk-paper px-5 py-4\">\n                <figure>\n                  <blockquote className=\"text-[14px] leading-[1.45] text-sk-ink\">&ldquo;{p.quote}&rdquo;</blockquote>\n                  <figcaption className=\"mt-2\">\n                    {p.logo ? (\n                      <img src={p.logo} alt={p.outlet} className=\"h-5 w-auto opacity-70\" />\n                    ) : (\n                      <span className=\"font-sk-display text-[15px] font-semibold uppercase tracking-[0.08em] text-sk-muted\">{p.outlet}</span>\n                    )}\n                  </figcaption>\n                </figure>\n              </li>\n            ))}\n          </motion.ul>\n        ) : null}\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:block",
      "target": "components/storekit/hero/hero-proof.tsx"
    }
  ],
  "docs": "Only use real ratings, awards and press quotes you can cite.",
  "meta": {
    "section": "hero",
    "variant": "proof",
    "niche": [
      "any"
    ],
    "commerce": [
      "cta",
      "trust"
    ],
    "previewHeight": 700
  }
}