{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "seo-audit-checklist",
  "title": "Seo Audit Checklist",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/seo-audit-checklist/SeoAuditChecklist.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  AlertCircle,\n  AlertTriangle,\n  Check,\n  CheckCircle2,\n  Code2,\n  Copy,\n  FileDown,\n  FileText,\n  Globe,\n  Heading1,\n  Info,\n  Lock,\n  Monitor,\n  RefreshCw,\n  Search,\n  Share2,\n  ShieldCheck,\n  Smartphone,\n  Zap,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Progress } from '@/components/ui/progress'\nimport { Separator } from '@/components/ui/separator'\n\nexport type CheckStatus = 'pass' | 'warning' | 'fail' | 'info'\n\nexport interface SeoCheckItem {\n  id: string\n  title: string\n  description: string\n  status: CheckStatus\n  value?: string\n  recommendation?: string\n  tag?: string\n}\n\nexport interface SeoCategory {\n  id: string\n  name: string\n  icon: 'meta' | 'headings' | 'opengraph' | 'technical'\n  score: number\n  checks: SeoCheckItem[]\n}\n\nexport interface CoreVitalMetric {\n  name: string\n  label: string\n  value: string\n  status: 'good' | 'needs-improvement' | 'poor'\n  target: string\n}\n\nexport interface SeoAuditChecklistProps {\n  url?: string\n  score?: number\n  lastAudited?: string\n  titleTag?: string\n  metaDescription?: string\n  h1Tag?: string\n  ogImageUrl?: string\n  categories?: SeoCategory[]\n  vitals?: CoreVitalMetric[]\n  className?: string\n}\n\nconst defaultVitals: CoreVitalMetric[] = [\n  { name: 'LCP', label: 'Largest Contentful Paint', value: '1.2s', status: 'good', target: '≤ 2.5s' },\n  { name: 'FID', label: 'First Input Delay', value: '12ms', status: 'good', target: '≤ 100ms' },\n  { name: 'CLS', label: 'Cumulative Layout Shift', value: '0.01', status: 'good', target: '≤ 0.1' },\n]\n\nconst defaultCategories: SeoCategory[] = [\n  {\n    id: 'meta-tags',\n    name: 'Title & Meta Description',\n    icon: 'meta',\n    score: 100,\n    checks: [\n      {\n        id: 'title-length',\n        title: 'Title Tag Length & Structure',\n        description: 'Page title is 58 characters (optimal range: 50–60 characters). Fully visible in 98% of SERPs.',\n        status: 'pass',\n        value: 'UIPKGE — Dual-Framework UI Registry for Vue & React',\n        tag: '58 / 60 chars',\n      },\n      {\n        id: 'meta-desc',\n        title: 'Meta Description Length',\n        description:\n          'Meta description is 152 characters (optimal range: 140–160 characters). Rich keyword density without truncation.',\n        status: 'pass',\n        value:\n          'Explore high-quality, copy-paste Vue and React UI components and blocks built with Tailwind CSS v4, Reka UI, and Lucide icons.',\n        tag: '152 / 160 chars',\n      },\n      {\n        id: 'canonical-url',\n        title: 'Canonical URL Tag',\n        description: 'Self-referencing canonical URL tag prevents duplicate content indexing across query variants.',\n        status: 'pass',\n        value: '<link rel=\"canonical\" href=\"https://uipkge.dev/vue/components\" />',\n        tag: 'Present',\n      },\n      {\n        id: 'meta-robots',\n        title: 'Meta Robots Directives',\n        description: 'Directives instruct crawlers to index the document and follow embedded hyperlinks.',\n        status: 'pass',\n        value: 'index, follow, max-image-preview:large, max-snippet:-1',\n        tag: 'Index, Follow',\n      },\n    ],\n  },\n  {\n    id: 'headings',\n    name: 'Heading Hierarchy & Structure',\n    icon: 'headings',\n    score: 100,\n    checks: [\n      {\n        id: 'h1-presence',\n        title: 'Single Primary H1 Tag',\n        description: 'Exactly 1 H1 tag detected containing target search terms and establishing clear topic authority.',\n        status: 'pass',\n        value: '<h1>UIPKGE Component & Block Registry</h1>',\n        tag: '1 H1 Tag',\n      },\n      {\n        id: 'h2-distribution',\n        title: 'H2 Section Organization',\n        description: '6 H2 tags logically divide major categories (Primitives, Blocks, Forms, Marketing, Feedback).',\n        status: 'pass',\n        value: '6 H2 tags · 0 skipped levels',\n        tag: '6 H2 Tags',\n      },\n      {\n        id: 'h3-nesting',\n        title: 'H3 Subsection Hierarchy',\n        description: '12 H3 tags cleanly nested under parent H2 sections without skipping hierarchical levels.',\n        status: 'pass',\n        value: '12 H3 tags · Valid tree hierarchy',\n        tag: '12 H3 Tags',\n      },\n      {\n        id: 'content-depth',\n        title: 'Content Word Count & Substance',\n        description: '1,840 words detected with strong semantic depth for component discovery.',\n        status: 'pass',\n        value: '1,840 words · 4.2 min read',\n        tag: 'Substantial',\n      },\n    ],\n  },\n  {\n    id: 'opengraph',\n    name: 'OpenGraph & Social Share Cards',\n    icon: 'opengraph',\n    score: 100,\n    checks: [\n      {\n        id: 'og-title-desc',\n        title: 'OpenGraph Title & Description',\n        description: 'Social graph tags are present and optimized for display across Twitter/X, LinkedIn, and Discord.',\n        status: 'pass',\n        value: 'og:title, og:description, og:type, og:url configured',\n        tag: 'Configured',\n      },\n      {\n        id: 'og-image',\n        title: 'OpenGraph Social Banner Image',\n        description:\n          '1200 × 630px high-resolution banner image detected with crisp aspect ratio (1.91:1) and fast CDN delivery.',\n        status: 'pass',\n        value: 'https://uipkge.dev/og/components.png (1200x630 · 84 KB)',\n        tag: '1200x630 px',\n      },\n      {\n        id: 'twitter-card',\n        title: 'Twitter / X Card Format',\n        description: 'Card format explicitly set to summary_large_image for maximal feed visibility.',\n        status: 'pass',\n        value: 'twitter:card = summary_large_image',\n        tag: 'Large Image',\n      },\n    ],\n  },\n  {\n    id: 'technical',\n    name: 'Performance, Images & Technical SEO',\n    icon: 'technical',\n    score: 85,\n    checks: [\n      {\n        id: 'image-alt-tags',\n        title: 'Image Alt Attributes',\n        description:\n          'All 24 embedded images contain meaningful, non-empty alt text attributes for accessibility and image search.',\n        status: 'pass',\n        value: '24 / 24 images with valid alt text (100%)',\n        tag: '24 / 24 Pass',\n      },\n      {\n        id: 'broken-links',\n        title: 'Crawlable Hyperlinks & 404 Errors',\n        description: 'Crawled 142 internal and external links. 0 broken links or redirect loops detected.',\n        status: 'pass',\n        value: '142 links verified · 0 errors',\n        tag: '0 Broken',\n      },\n      {\n        id: 'ssl-security',\n        title: 'SSL / HTTPS & Security Headers',\n        description: 'Valid TLS 1.3 certificate with HSTS header enabled and automatic HTTP-to-HTTPS redirect.',\n        status: 'pass',\n        value: 'TLS 1.3 · HSTS Active · HTTP/2 Supported',\n        tag: 'Secure',\n      },\n      {\n        id: 'schema-markup',\n        title: 'Schema.org Structured Data',\n        description:\n          'No SoftwareApplication or Product JSON-LD schema detected. Structured data enables rich Google SERP snippet features.',\n        status: 'warning',\n        value: 'Missing schema.org/SoftwareApplication microdata',\n        recommendation:\n          'Add JSON-LD script tag with SoftwareApplication schema to qualify for rich snippet search results.',\n        tag: 'Missing Schema',\n      },\n    ],\n  },\n]\n\nexport function SeoAuditChecklist({\n  url = 'https://uipkge.dev/vue/components',\n  score = 94,\n  lastAudited = 'Audit completed in 640ms · Cached 2m ago',\n  titleTag = 'UIPKGE — Dual-Framework UI Registry for Vue & React',\n  metaDescription = 'Explore high-quality, copy-paste Vue and React UI components and blocks built with Tailwind CSS v4, Reka UI, and Lucide icons. Unbundled registry with full source code ownership.',\n  categories = defaultCategories,\n  className,\n}: SeoAuditChecklistProps) {\n  const [currentUrl, setCurrentUrl] = React.useState(url)\n  const [isAuditing, setIsAuditing] = React.useState(false)\n  const [copiedSchema, setCopiedSchema] = React.useState(false)\n  const [copiedUrl, setCopiedUrl] = React.useState(false)\n  const [reportDownloaded, setReportDownloaded] = React.useState(false)\n  const [previewDevice, setPreviewDevice] = React.useState<'desktop' | 'mobile'>('desktop')\n  const [activeStatusFilter, setActiveStatusFilter] = React.useState<'all' | 'pass' | 'warning'>('all')\n\n  const allChecks = React.useMemo(() => categories.flatMap((cat) => cat.checks), [categories])\n  const passCount = React.useMemo(() => allChecks.filter((c) => c.status === 'pass').length, [allChecks])\n  const warningCount = React.useMemo(() => allChecks.filter((c) => c.status === 'warning').length, [allChecks])\n  const totalCount = allChecks.length\n\n  const filteredCategories = React.useMemo(() => {\n    if (activeStatusFilter === 'all') return categories\n    return categories\n      .map((cat) => ({\n        ...cat,\n        checks: cat.checks.filter((check) => check.status === activeStatusFilter),\n      }))\n      .filter((cat) => cat.checks.length > 0)\n  }, [categories, activeStatusFilter])\n\n  const handleReaudit = () => {\n    setIsAuditing(true)\n    setTimeout(() => {\n      setIsAuditing(false)\n    }, 500)\n  }\n\n  const handleCopySchema = () => {\n    setCopiedSchema(true)\n    setTimeout(() => {\n      setCopiedSchema(false)\n    }, 1800)\n  }\n\n  const handleCopyUrl = () => {\n    setCopiedUrl(true)\n    setTimeout(() => {\n      setCopiedUrl(false)\n    }, 1800)\n  }\n\n  const handleDownloadReport = () => {\n    setReportDownloaded(true)\n    setTimeout(() => {\n      setReportDownloaded(false)\n    }, 2000)\n  }\n\n  return (\n    <div className={cn('w-full space-y-6', className)} data-slot=\"seo-audit-checklist\">\n      {/* Header & Audit Control Center */}\n      <Card className=\"border-border bg-card shadow-xs\">\n        <CardContent className=\"p-5 sm:p-6\">\n          <div className=\"flex flex-col gap-5 lg:flex-row lg:items-center lg:justify-between\">\n            {/* Left: Target URL & Score */}\n            <div className=\"space-y-3\">\n              <div className=\"flex flex-wrap items-center gap-3\">\n                <div className=\"border-success/30 bg-success/10 text-success flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-semibold\">\n                  <span className=\"relative flex size-2\">\n                    <span className=\"bg-success absolute inline-flex h-full w-full rounded-full opacity-75\" />\n                    <span className=\"bg-success relative inline-flex size-2 rounded-full\" />\n                  </span>\n                  <span className=\"font-mono tabular-nums\">{score} / 100</span>\n                  <span>·</span>\n                  <span>Healthy Score</span>\n                </div>\n                <Badge wrap variant=\"outline\" className=\"gap-1 text-xs font-normal\">\n                  <Globe className=\"text-muted-foreground size-3\" />\n                  HTTP 200 OK\n                </Badge>\n                <Badge wrap variant=\"outline\" className=\"gap-1 text-xs font-normal\">\n                  <ShieldCheck className=\"text-success size-3\" />\n                  Indexable\n                </Badge>\n              </div>\n\n              <div>\n                <h1 className=\"text-foreground text-lg font-bold tracking-tight sm:text-xl\">\n                  On-Page SEO Analyzer & Snippet Simulator\n                </h1>\n                <p className=\"text-muted-foreground text-xs\">{lastAudited}</p>\n              </div>\n            </div>\n\n            {/* Right: Action Buttons */}\n            <div className=\"flex flex-wrap items-center gap-2.5 sm:self-start lg:self-center\">\n              <Button\n                variant=\"outline\"\n                size=\"sm\"\n                className=\"h-9 gap-1.5 text-xs shadow-xs\"\n                disabled={isAuditing}\n                onClick={handleReaudit}\n              >\n                <RefreshCw className={cn('size-3.5', isAuditing && 'animate-spin')} />\n                <span>Re-audit URL</span>\n              </Button>\n\n              <Button\n                aria-label=\"Download attachment\"\n                size=\"sm\"\n                className=\"h-9 gap-1.5 text-xs font-medium shadow-xs\"\n                onClick={handleDownloadReport}\n              >\n                {!reportDownloaded ? <FileDown className=\"size-3.5\" /> : <Check className=\"text-success size-3.5\" />}\n                <span>{reportDownloaded ? 'Report Exported!' : 'Download SEO Report'}</span>\n              </Button>\n            </div>\n          </div>\n\n          <Separator className=\"my-4\" />\n\n          {/* URL Input Strip */}\n          <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n            <div className=\"relative flex-1\">\n              <div className=\"text-muted-foreground pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3\">\n                <Search className=\"size-4\" />\n              </div>\n              <Input\n                type=\"url\"\n                value={currentUrl}\n                onChange={(e) => setCurrentUrl(e.target.value)}\n                placeholder=\"https://yourdomain.com/path\"\n                className=\"h-9 w-full rounded-md pr-24 pl-9 font-mono text-xs shadow-xs\"\n                onKeyDown={(e) => {\n                  if (e.key === 'Enter') handleReaudit()\n                }}\n              />\n              <button\n                type=\"button\"\n                className=\"text-muted-foreground hover:text-foreground absolute inset-y-0 right-0 flex min-h-6 items-center pr-3 text-xs transition-colors\"\n                onClick={handleCopyUrl}\n              >\n                {copiedUrl ? <Check className=\"text-success size-3.5\" /> : <Copy className=\"size-3.5\" />}\n                <span className=\"ml-1 text-xs\">{copiedUrl ? 'Copied' : 'Copy'}</span>\n              </button>\n            </div>\n            <Button\n              size=\"sm\"\n              variant=\"secondary\"\n              className=\"h-9 shrink-0 px-4 text-xs font-medium\"\n              disabled={isAuditing}\n              onClick={handleReaudit}\n            >\n              <Search className=\"text-primary mr-1.5 size-3.5\" />\n              Analyze Page\n            </Button>\n          </div>\n        </CardContent>\n      </Card>\n\n      {/* 4 Core SEO Pillar Metric Cards */}\n      <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n        {/* Pillar 1: Meta Tags & Snippet */}\n        <Card className=\"border-border bg-card shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Meta Tags & Snippet</CardTitle>\n            <div className=\"border-border/60 bg-muted/60 text-muted-foreground flex size-7 items-center justify-center rounded-md border\">\n              <FileText className=\"text-success size-3.5\" />\n            </div>\n          </CardHeader>\n          <CardContent className=\"space-y-2\">\n            <div className=\"flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5\">\n              <div className=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">100% Pass</div>\n              <Badge wrap variant=\"success\" className=\"text-xs font-medium\">\n                Optimal\n              </Badge>\n            </div>\n            <div className=\"space-y-1.5\">\n              <Progress value={100} className=\"bg-success/20 [&>div]:bg-success h-1.5 w-full\" />\n              <p className=\"text-muted-foreground text-xs\">Title & description optimized</p>\n            </div>\n            <div className=\"border-border/50 text-muted-foreground flex items-center justify-between border-t pt-2 font-mono text-xs\">\n              <span>58 chars title</span>\n              <span>·</span>\n              <span>152 chars desc</span>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* Pillar 2: Core Web Vitals */}\n        <Card className=\"border-border bg-card shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Core Web Vitals</CardTitle>\n            <div className=\"border-border/60 bg-muted/60 text-muted-foreground flex size-7 items-center justify-center rounded-md border\">\n              <Zap className=\"text-success size-3.5\" />\n            </div>\n          </CardHeader>\n          <CardContent className=\"space-y-2\">\n            <div className=\"flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5\">\n              <div className=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">Good</div>\n              <Badge wrap variant=\"success\" className=\"text-xs font-medium\">\n                98/100\n              </Badge>\n            </div>\n            <div className=\"space-y-1.5\">\n              <Progress value={98} className=\"bg-success/20 [&>div]:bg-success h-1.5 w-full\" />\n              <p className=\"text-muted-foreground text-xs\">LCP 1.2s · FID 12ms · CLS 0.01</p>\n            </div>\n            <div className=\"border-border/50 text-muted-foreground flex items-center justify-between border-t pt-2 font-mono text-xs\">\n              <span>Chrome UX Report</span>\n              <span>·</span>\n              <span className=\"text-success\">Passed</span>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* Pillar 3: Mobile Usability */}\n        <Card className=\"border-border bg-card shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Mobile Usability</CardTitle>\n            <div className=\"border-border/60 bg-muted/60 text-muted-foreground flex size-7 items-center justify-center rounded-md border\">\n              <Smartphone className=\"text-success size-3.5\" />\n            </div>\n          </CardHeader>\n          <CardContent className=\"space-y-2\">\n            <div className=\"flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5\">\n              <div className=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">100% Pass</div>\n              <Badge wrap variant=\"success\" className=\"text-xs font-medium\">\n                Valid\n              </Badge>\n            </div>\n            <div className=\"space-y-1.5\">\n              <Progress value={100} className=\"bg-success/20 [&>div]:bg-success h-1.5 w-full\" />\n              <p className=\"text-muted-foreground text-xs\">Touch targets & viewport valid</p>\n            </div>\n            <div className=\"border-border/50 text-muted-foreground flex items-center justify-between border-t pt-2 font-mono text-xs\">\n              <span>48px tap targets</span>\n              <span>·</span>\n              <span>0 horizontal scroll</span>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* Pillar 4: Indexability & Crawl */}\n        <Card className=\"border-border bg-card shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Indexability & Crawl</CardTitle>\n            <div className=\"border-border/60 bg-muted/60 text-muted-foreground flex size-7 items-center justify-center rounded-md border\">\n              <ShieldCheck className=\"text-success size-3.5\" />\n            </div>\n          </CardHeader>\n          <CardContent className=\"space-y-2\">\n            <div className=\"flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5\">\n              <div className=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">Valid</div>\n              <Badge wrap variant=\"success\" className=\"text-xs font-medium\">\n                Indexed\n              </Badge>\n            </div>\n            <div className=\"space-y-1.5\">\n              <Progress value={95} className=\"bg-success/20 [&>div]:bg-success h-1.5 w-full\" />\n              <p className=\"text-muted-foreground text-xs\">Canonical URL present & sitemap verified</p>\n            </div>\n            <div className=\"border-border/50 text-muted-foreground flex items-center justify-between border-t pt-2 font-mono text-xs\">\n              <span>robots.txt allowed</span>\n              <span>·</span>\n              <span>sitemap.xml</span>\n            </div>\n          </CardContent>\n        </Card>\n      </div>\n\n      {/* Google Search Result Snippet Preview Simulator */}\n      <Card className=\"border-border bg-card shadow-xs\">\n        <CardHeader className=\"flex flex-col gap-3 pb-4 sm:flex-row sm:items-center sm:justify-between\">\n          <div>\n            <div className=\"flex items-center gap-2\">\n              <CardTitle className=\"text-base font-semibold\">Google Search Result Snippet Preview</CardTitle>\n              <Badge wrap variant=\"outline\" className=\"gap-1 text-xs font-normal\">\n                <Search className=\"text-primary size-3\" />\n                Live SERP Simulator\n              </Badge>\n            </div>\n            <CardDescription className=\"text-xs\">\n              Simulate how your meta tags, title, and URL render in Google SERPs on desktop vs. mobile.\n            </CardDescription>\n          </div>\n\n          {/* Desktop / Mobile View Switcher */}\n          <div className=\"border-border bg-muted/50 flex items-center rounded-lg border p-0.5\">\n            <button\n              type=\"button\"\n              className={cn(\n                'flex min-h-6 items-center gap-1.5 rounded-md px-3 py-1 text-xs font-medium transition-colors',\n                previewDevice === 'desktop'\n                  ? 'bg-background text-foreground shadow-xs'\n                  : 'text-muted-foreground hover:text-foreground',\n              )}\n              onClick={() => setPreviewDevice('desktop')}\n            >\n              <Monitor className=\"size-3.5\" />\n              <span>Desktop</span>\n            </button>\n            <button\n              type=\"button\"\n              className={cn(\n                'flex min-h-6 items-center gap-1.5 rounded-md px-3 py-1 text-xs font-medium transition-colors',\n                previewDevice === 'mobile'\n                  ? 'bg-background text-foreground shadow-xs'\n                  : 'text-muted-foreground hover:text-foreground',\n              )}\n              onClick={() => setPreviewDevice('mobile')}\n            >\n              <Smartphone className=\"size-3.5\" />\n              <span>Mobile</span>\n            </button>\n          </div>\n        </CardHeader>\n\n        <CardContent className=\"space-y-4\">\n          {/* Mock Google SERP Result Box */}\n          <div\n            className={cn(\n              'border-border/80 bg-background mx-auto rounded-xl border p-4 shadow-xs transition-colors duration-200 sm:p-5',\n              previewDevice === 'mobile' ? 'border-border max-w-md' : 'w-full',\n            )}\n          >\n            {/* Google Result Header / Breadcrumb */}\n            <div className=\"flex items-center gap-2.5 pb-1.5\">\n              <div className=\"border-border bg-muted text-foreground flex size-7 shrink-0 items-center justify-center rounded-full border text-xs font-bold\">\n                ⚡\n              </div>\n              <div className=\"min-w-0 flex-1\">\n                <div className=\"text-foreground flex items-center gap-1.5 text-xs\">\n                  <span className=\"font-medium\">uipkge.dev</span>\n                  <span className=\"text-muted-foreground\">›</span>\n                  <span className=\"text-muted-foreground truncate\">vue › components</span>\n                </div>\n                <p className=\"text-muted-foreground truncate font-mono text-xs\">{url}</p>\n              </div>\n            </div>\n\n            {/* Google SERP Title */}\n            <div className=\"space-y-1 pt-1\">\n              <a\n                href=\"#\"\n                className=\"text-info text-info block text-base leading-snug font-medium hover:underline sm:text-lg\"\n                onClick={(e) => e.preventDefault()}\n              >\n                {titleTag}\n              </a>\n\n              {/* Google Snippet Description with highlighted keywords */}\n              <p className=\"text-muted-foreground text-xs leading-relaxed sm:text-sm\">\n                <span className=\"text-muted-foreground/90 font-medium\">Aug 20, 2026 — </span>\n                Explore high-quality, copy-paste <strong className=\"text-foreground font-semibold\">Vue</strong> and{' '}\n                <strong className=\"text-foreground font-semibold\">React</strong>{' '}\n                <strong className=\"text-foreground font-semibold\">UI components</strong> and blocks built with{' '}\n                <strong className=\"text-foreground font-semibold\">Tailwind CSS v4</strong>, Reka UI, and Lucide icons.\n                Unbundled registry with full source code ownership.\n              </p>\n            </div>\n\n            {/* Google Rich Snippet Badges */}\n            <div className=\"border-border/40 mt-3 flex flex-wrap items-center gap-2 border-t pt-2.5\">\n              <Badge wrap variant=\"secondary\" className=\"text-xs font-normal\">\n                ★ 4.9 · 1.4k GitHub Stars\n              </Badge>\n              <Badge wrap variant=\"outline\" className=\"text-xs font-normal\">\n                Free & Open Source\n              </Badge>\n              <Badge wrap variant=\"outline\" className=\"text-xs font-normal\">\n                Vue 3.5 + React 19\n              </Badge>\n            </div>\n          </div>\n\n          {/* Snippet Metrics Character / Pixel Budget Strip */}\n          <div className=\"border-border/80 bg-muted/30 grid grid-cols-1 gap-3 rounded-lg border p-3 sm:grid-cols-3\">\n            <div className=\"min-w-0 space-y-1\">\n              <div className=\"flex items-center justify-between text-xs\">\n                <span className=\"text-muted-foreground\">Title Tag Budget:</span>\n                <span className=\"text-foreground font-mono font-semibold tabular-nums\">58 / 60 chars</span>\n              </div>\n              <Progress value={(58 / 60) * 100} className=\"bg-success/20 [&>div]:bg-success h-1.5 w-full\" />\n              <p className=\"text-success text-xs\">Optimal (485px / 600px max SERP width)</p>\n            </div>\n\n            <div className=\"min-w-0 space-y-1\">\n              <div className=\"flex items-center justify-between text-xs\">\n                <span className=\"text-muted-foreground\">Meta Description:</span>\n                <span className=\"text-foreground font-mono font-semibold tabular-nums\">152 / 160 chars</span>\n              </div>\n              <Progress value={(152 / 160) * 100} className=\"bg-success/20 [&>div]:bg-success h-1.5 w-full\" />\n              <p className=\"text-success text-xs\">Optimal (890px / 960px max SERP width)</p>\n            </div>\n\n            <div className=\"flex flex-col justify-between space-y-1\">\n              <div className=\"flex items-center justify-between text-xs\">\n                <span className=\"text-muted-foreground\">Truncation Risk:</span>\n                <Badge wrap variant=\"success\" className=\"px-1.5 py-0 text-xs\">\n                  0% Truncation\n                </Badge>\n              </div>\n              <p className=\"text-muted-foreground text-xs\">Fully visible on both desktop & mobile Google viewports.</p>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n\n      {/* Actionable Recommendation Callout Banner */}\n      <Card className=\"border-warning/30 bg-warning/10 shadow-xs\">\n        <CardContent className=\"p-5\">\n          <div className=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n            <div className=\"flex items-start gap-3\">\n              <div className=\"border-warning/30 bg-warning/20 text-warning mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-lg border\">\n                <AlertTriangle className=\"size-4\" />\n              </div>\n              <div className=\"space-y-1.5\">\n                <div className=\"flex flex-wrap items-center gap-2\">\n                  <h3 className=\"text-foreground text-sm font-semibold\">\n                    Actionable Recommendation: Add Schema.org JSON-LD Structured Data\n                  </h3>\n                  <Badge wrap variant=\"warning\" className=\"text-xs\">\n                    High Impact\n                  </Badge>\n                </div>\n                <p className=\"text-muted-foreground text-xs leading-relaxed\">\n                  Adding{' '}\n                  <code className=\"border-border bg-background/80 text-foreground rounded border px-1 py-0.5 font-mono text-xs\">\n                    SoftwareApplication\n                  </code>{' '}\n                  or{' '}\n                  <code className=\"border-border bg-background/80 text-foreground rounded border px-1 py-0.5 font-mono text-xs\">\n                    TechArticle\n                  </code>{' '}\n                  structured data enables Google Rich Snippets, rating stars, and knowledge graph carousels.\n                </p>\n\n                {/* Inline Code Preview */}\n                <div className=\"border-border/80 bg-background/90 text-foreground mt-2 rounded-md border p-3 font-mono text-xs\">\n                  <div className=\"text-muted-foreground flex items-center justify-between pb-1.5\">\n                    <span className=\"text-xs\">Recommended JSON-LD Block</span>\n                    <button\n                      type=\"button\"\n                      className=\"text-muted-foreground hover:text-foreground flex min-h-6 items-center gap-1 text-xs transition-colors\"\n                      onClick={handleCopySchema}\n                    >\n                      {copiedSchema ? <Check className=\"text-success size-3\" /> : <Copy className=\"size-3\" />}\n                      <span>{copiedSchema ? 'Copied' : 'Copy JSON-LD'}</span>\n                    </button>\n                  </div>\n                  <pre className=\"text-muted-foreground overflow-x-auto text-xs leading-snug\">\n                    <code>{`{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"SoftwareApplication\",\n  \"name\": \"UIPKGE\",\n  \"applicationCategory\": \"DeveloperApplication\",\n  \"operatingSystem\": \"Web\",\n  \"offers\": { \"@type\": \"Offer\", \"price\": \"0\", \"priceCurrency\": \"USD\" }\n}`}</code>\n                  </pre>\n                </div>\n              </div>\n            </div>\n\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              className=\"shrink-0 gap-1.5 text-xs shadow-xs\"\n              onClick={handleCopySchema}\n            >\n              <Code2 className=\"size-3.5\" />\n              <span>Copy Schema Snippet</span>\n            </Button>\n          </div>\n        </CardContent>\n      </Card>\n\n      {/* Audit Checklist Grouped Accordion Section */}\n      <div className=\"space-y-4\">\n        <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n          <div>\n            <h2 className=\"text-foreground text-sm font-semibold tracking-tight\">Detailed On-Page Audit Checklist</h2>\n            <p className=\"text-muted-foreground text-xs\">\n              Complete verification of on-page meta tags, heading semantics, social cards, and technical crawlability.\n            </p>\n          </div>\n\n          {/* Filter Tabs */}\n          <div className=\"flex items-center gap-1.5\">\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              className={cn(\n                'h-8 px-2.5 text-xs',\n                activeStatusFilter === 'all' ? 'bg-muted text-foreground font-medium' : 'text-muted-foreground',\n              )}\n              onClick={() => setActiveStatusFilter('all')}\n            >\n              All Checks ({totalCount})\n            </Button>\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              className={cn(\n                'h-8 px-2.5 text-xs',\n                activeStatusFilter === 'pass' ? 'bg-muted text-success font-medium' : 'text-muted-foreground',\n              )}\n              onClick={() => setActiveStatusFilter('pass')}\n            >\n              Passed ({passCount})\n            </Button>\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              className={cn(\n                'h-8 px-2.5 text-xs',\n                activeStatusFilter === 'warning' ? 'bg-muted text-warning font-medium' : 'text-muted-foreground',\n              )}\n              onClick={() => setActiveStatusFilter('warning')}\n            >\n              Warnings ({warningCount})\n            </Button>\n          </div>\n        </div>\n\n        {/* Accordion List */}\n        <Accordion\n          type=\"multiple\"\n          defaultValue={['meta-tags', 'headings', 'opengraph', 'technical']}\n          className=\"space-y-3\"\n        >\n          {filteredCategories.map((category) => (\n            <AccordionItem\n              key={category.id}\n              value={category.id}\n              className=\"border-border bg-card overflow-hidden rounded-lg border shadow-xs\"\n            >\n              <AccordionTrigger className=\"px-5 py-4 hover:no-underline\">\n                <div className=\"flex w-full flex-wrap items-center justify-between gap-3 pr-2 text-left\">\n                  <div className=\"flex items-center gap-3\">\n                    <div className=\"border-border/60 bg-muted/60 text-muted-foreground flex size-8 shrink-0 items-center justify-center rounded-md border\">\n                      {category.icon === 'meta' && <FileText className=\"size-4\" />}\n                      {category.icon === 'headings' && <Heading1 className=\"size-4\" />}\n                      {category.icon === 'opengraph' && <Share2 className=\"size-4\" />}\n                      {category.icon === 'technical' && <Lock className=\"size-4\" />}\n                    </div>\n                    <div>\n                      <span className=\"text-foreground text-sm font-semibold\">{category.name}</span>\n                      <p className=\"text-muted-foreground text-xs\">\n                        {category.checks.filter((c) => c.status === 'pass').length} of {category.checks.length} tests\n                        passing\n                      </p>\n                    </div>\n                  </div>\n\n                  <div className=\"flex items-center gap-2.5\">\n                    <Badge\n                      wrap\n                      variant={category.score === 100 ? 'success' : 'warning'}\n                      className=\"text-xs font-semibold tabular-nums\"\n                    >\n                      {category.score}% Score\n                    </Badge>\n                  </div>\n                </div>\n              </AccordionTrigger>\n\n              <AccordionContent className=\"px-5 pt-0 pb-5\">\n                <div className=\"divide-border/60 border-border/60 divide-y border-t\">\n                  {category.checks.map((check) => (\n                    <div key={check.id} className=\"space-y-2 py-3.5 first:pt-4 last:pb-1\">\n                      <div className=\"flex flex-col gap-1.5 sm:flex-row sm:items-start sm:justify-between sm:gap-3\">\n                        <div className=\"min-w-0 space-y-1\">\n                          <div className=\"flex items-center gap-2\">\n                            {check.status === 'pass' && <CheckCircle2 className=\"text-success size-4 shrink-0\" />}\n                            {check.status === 'warning' && <AlertTriangle className=\"text-warning size-4 shrink-0\" />}\n                            {check.status === 'fail' && <AlertCircle className=\"text-destructive size-4 shrink-0\" />}\n                            <h4 className=\"text-foreground text-xs font-semibold sm:text-sm\">{check.title}</h4>\n                          </div>\n                          <p className=\"text-muted-foreground pl-6 text-xs leading-relaxed\">{check.description}</p>\n                        </div>\n\n                        <div className=\"flex flex-wrap items-center gap-2 pl-6 sm:pl-0\">\n                          {check.tag && (\n                            <Badge wrap variant=\"outline\" className=\"font-mono text-xs font-normal\">\n                              {check.tag}\n                            </Badge>\n                          )}\n                          <Badge\n                            wrap\n                            variant={\n                              check.status === 'pass'\n                                ? 'success'\n                                : check.status === 'warning'\n                                  ? 'warning'\n                                  : 'destructive'\n                            }\n                            className=\"text-xs font-medium capitalize\"\n                          >\n                            {check.status}\n                          </Badge>\n                        </div>\n                      </div>\n\n                      {/* Code / Value Inspector Box */}\n                      {check.value && (\n                        <div className=\"border-border/70 bg-muted/40 text-foreground ml-6 rounded-md border px-3 py-2 font-mono text-xs\">\n                          <span className=\"text-xs break-all\">{check.value}</span>\n                        </div>\n                      )}\n\n                      {/* Recommendation Callout */}\n                      {check.recommendation && (\n                        <div className=\"border-warning/30 bg-warning/10 text-warning ml-6 flex items-start gap-2 rounded-md border p-2.5 text-xs\">\n                          <Info className=\"text-warning size-4 shrink-0\" />\n                          <p className=\"text-xs leading-relaxed\">{check.recommendation}</p>\n                        </div>\n                      )}\n                    </div>\n                  ))}\n                </div>\n              </AccordionContent>\n            </AccordionItem>\n          ))}\n        </Accordion>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/SeoAuditChecklist.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/accordion.json",
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/progress.json",
    "https://uipkge.dev/r/react/separator.json"
  ],
  "description": "Ahrefs and SEMrush style on-page SEO analyzer, meta tag auditor, Google SERP snippet preview simulator, heading hierarchy validator, and Core Web Vitals checklist.",
  "categories": [
    "marketing",
    "dashboard"
  ]
}