{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "pricing-landing-hero", "type": "registry:ui", "title": "Pricing Landing Hero", "description": "A service-style landing hero with scattered preview cards, price block with strike-through, scarcity line, dual CTAs, and trusted-by strip.", "files": [ { "path": "registry/ruixenui/pricing-landing-hero.tsx", "content": "\"use client\";\n\nimport * as React from \"react\";\nimport Link from \"next/link\";\nimport { Battery, Signal, Wifi } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\n/* ── types ───────────────────────────────────────────────────── */\n\ntype Action = { href: string; label: string };\n\ninterface PriceBlock {\n /** Current price, e.g. \"$850\" */\n current: string;\n /** Original price shown with strike-through, e.g. \"$2,000\" */\n original?: string;\n}\n\ninterface TrustedBySection {\n heading?: string;\n logos: React.ReactNode[];\n}\n\ninterface PhoneSheetItem {\n title: string;\n description: string;\n}\n\ninterface PhoneMockupProps {\n /** Time shown in the status bar. */\n time?: string;\n /**\n * Items to cycle through inside the sheet. When more than one is provided\n * they crossfade automatically every `cycleMs` milliseconds.\n */\n items?: PhoneSheetItem[];\n /** Interval between item transitions (ms). */\n cycleMs?: number;\n}\n\nexport interface PricingLandingHeroProps {\n /** Main headline */\n title: React.ReactNode;\n /** Subtitle / description text */\n description?: string;\n /** Phone mockup shown above the headline */\n phone?: PhoneMockupProps;\n /** Price block shown between description and CTAs */\n price?: PriceBlock;\n /** Small availability / scarcity line above the CTAs */\n availability?: string;\n /** Primary CTA button (filled) */\n primaryAction?: Action;\n /** Secondary CTA button (outlined) */\n secondaryAction?: Action;\n /** Trusted-by logo strip */\n trustedBy?: TrustedBySection;\n className?: string;\n}\n\n/* ── phone mockup ────────────────────────────────────────────── */\n\nconst DEFAULT_ITEMS: PhoneSheetItem[] = [\n { title: \"Add a Title...\", description: \"Add a description...\" },\n];\n\nconst SPRING = \"cubic-bezier(0.22, 1, 0.36, 1)\";\n\nfunction SheetCardContent({ item }: { item: PhoneSheetItem }) {\n return (\n <>\n {/* Drag handle bar — part of each card, slides with it */}\n
\n\n {description}\n
\n )}\n\n {/* ── price block ──────────────────────────────────── */}\n {price && (\n{availability}
\n )}\n\n {/* ── CTAs ─────────────────────────────────────────── */}\n {(primaryAction || secondaryAction) && (\n\n {trustedBy.heading || \"Trusted by\"}\n
\n