{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "landing-template",
  "type": "registry:block",
  "title": "Landing Template",
  "description": "Marketing landing page surface. Composes Topbar + Hero + (optional) FeatureGrid + (optional) TestimonialGrid + (optional) PricingTable + (optional) FAQ + CTASection + Footer — each in its own SectionBoundary so the page streams section-by-section.",
  "author": "ofri-peretz <https://github.com/ofri-peretz>",
  "categories": [
    "marketing",
    "template"
  ],
  "dependencies": [],
  "registryDependencies": [
    "https://ds.interlace.tools/r/theme.json",
    "https://ds.interlace.tools/r/cn.json",
    "https://ds.interlace.tools/r/container.json",
    "https://ds.interlace.tools/r/footer.json",
    "https://ds.interlace.tools/r/section-boundary.json",
    "https://ds.interlace.tools/r/skeleton.json",
    "https://ds.interlace.tools/r/stack.json",
    "https://ds.interlace.tools/r/topbar.json"
  ],
  "files": [
    {
      "path": "registry/interlace-ui/templates/landing-template.tsx",
      "target": "components/ui/templates/landing-template.tsx",
      "type": "registry:block",
      "content": "import * as React from 'react';\n\n// @interlace/landing-template v1.2.0 — Interlace design system.\n// Docs, props and live preview: https://ds.interlace.tools/c/landing-template\n// What changed since: https://ds.interlace.tools/c/landing-template#history\n// Generated banner — keep it, the upgrade diff reads this version.\n\n/**\n * @interlace/ui — LandingTemplate\n *\n * Marketing landing page surface. Composes Topbar + Hero +\n * (optional) FeatureGrid + (optional) TestimonialGrid + (optional)\n * PricingTable + (optional) FAQ + CTASection + Footer — each in its own\n * SectionBoundary so the page streams section-by-section.\n *\n * Every section is optional via props; pass only what you need. The\n * Topbar + Footer are required (every landing page has them).\n *\n * ## MIN_VIEWPORT — 320\n */\n\nimport { cn } from '@/lib/utils';\nimport { SectionBoundary } from '@/components/ui/section-boundary';\nimport { Topbar } from '@/components/ui/patterns/topbar';\nimport { Footer } from '@/components/ui/patterns/footer';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { Stack } from '@/components/ui/stack';\nimport { Container } from '@/components/ui/container';\n\nexport const MIN_VIEWPORT = 320 as const;\n\ninterface LandingTemplateProps extends React.ComponentProps<'div'> {\n  /** Topbar props. */\n  topbar: React.ComponentProps<typeof Topbar>;\n  /** Hero section (consumer-supplied — pass the configured Hero pattern). */\n  hero: React.ReactNode;\n  /** Optional features section. */\n  features?: React.ReactNode;\n  /** Optional testimonials section. */\n  testimonials?: React.ReactNode;\n  /** Optional pricing section. */\n  pricing?: React.ReactNode;\n  /** Optional FAQ section. */\n  faq?: React.ReactNode;\n  /** Optional CTA section before the footer. */\n  cta?: React.ReactNode;\n  /** Footer props. */\n  footer: React.ComponentProps<typeof Footer>;\n  /** Extra arbitrary sections — rendered between hero and features. */\n  children?: React.ReactNode;\n}\n\nfunction LandingTemplate({\n  topbar,\n  hero,\n  features,\n  testimonials,\n  pricing,\n  faq,\n  cta,\n  footer,\n  children,\n  className,\n  ...props\n}: LandingTemplateProps) {\n  return (\n    <div\n      data-slot=\"landing-template\"\n      data-min-viewport={String(MIN_VIEWPORT)}\n      className={cn('bg-background text-foreground', className)}\n      {...props}\n    >\n      <Topbar {...topbar} />\n\n      {/* Every section below sits inside <main>, and it is not decoration.\n          Topbar emits <header>, Footer emits <footer>, and SectionBoundary\n          renders `display: contents` — so without this element the entire body\n          of the page was outside any landmark, and SkipLink had nothing to skip\n          TO. AuthorTemplate / TagTemplate / StatsTemplate already wrap; this is\n          the marketing page catching up. */}\n      <main id=\"main\">\n        <SectionBoundary name=\"landing-hero\" skeletonVariant=\"page-header\">\n          {hero}\n        </SectionBoundary>\n\n        {children}\n\n        {features ? (\n          <SectionBoundary\n            name=\"landing-features\"\n            skeletonVariant=\"article-card\"\n          >\n            {features}\n          </SectionBoundary>\n        ) : null}\n\n        {testimonials ? (\n          <SectionBoundary\n            name=\"landing-testimonials\"\n            skeletonVariant=\"article-card\"\n          >\n            {testimonials}\n          </SectionBoundary>\n        ) : null}\n\n        {pricing ? (\n          <SectionBoundary name=\"landing-pricing\" skeletonVariant=\"card\">\n            {pricing}\n          </SectionBoundary>\n        ) : null}\n\n        {faq ? (\n          <SectionBoundary name=\"landing-faq\" skeletonVariant=\"card\">\n            {faq}\n          </SectionBoundary>\n        ) : null}\n\n        {cta ? (\n          <SectionBoundary name=\"landing-cta\" skeletonVariant=\"card\">\n            {cta}\n          </SectionBoundary>\n        ) : null}\n      </main>\n\n      <Footer {...footer} />\n    </div>\n  );\n}\nLandingTemplate.displayName = 'LandingTemplate';\n\n/**\n * Page-level loading state — the full-page silhouette of\n * `<LandingTemplate>`, not a single rect. Rendered by the consumer while\n * the whole route's data is in flight (`loading.tsx` in Next.js), or as\n * a `<SectionBoundary skeleton={…}>` override.\n *\n * Shapes mirror the real layout so the swap is CLS-neutral (R23). One\n * `role=\"status\"` region for the page; inner skeletons pass\n * `label={null}` so screen readers hear one announcement, not ten.\n */\nfunction LandingTemplateSkeleton({\n  className,\n  ...props\n}: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"landing-template-skeleton\"\n      data-min-viewport={String(MIN_VIEWPORT)}\n      role=\"status\"\n      aria-busy=\"true\"\n      aria-label=\"Loading page…\"\n      className={cn('bg-background text-foreground', className)}\n      {...props}\n    >\n      <Skeleton\n        variant=\"rect\"\n        className=\"h-14 w-full rounded-none\"\n        label={null}\n      />\n      <Container size=\"content\">\n        <Stack gap=\"xl\" className=\"py-xl\">\n          <Skeleton variant=\"page-header\" label={null} />\n          <Skeleton variant=\"article-card\" count={3} label={null} />\n          <Skeleton variant=\"card\" count={2} label={null} />\n        </Stack>\n      </Container>\n    </div>\n  );\n}\nLandingTemplateSkeleton.displayName = 'LandingTemplateSkeleton';\nLandingTemplate.Skeleton = LandingTemplateSkeleton;\n\nexport { LandingTemplate };\nexport type { LandingTemplateProps };\n"
    }
  ],
  "meta": {
    "tier": "template",
    "client": false,
    "minViewport": 320,
    "loading": false,
    "version": "1.2.0",
    "since": "1.0.0"
  },
  "docs": "## @interlace/landing-template\n\nInstalled to `components/ui/templates/landing-template.tsx`.\n\n```tsx\nimport { /* … */ } from '@/components/ui/templates/landing-template';\n```\n\nProps, a11y contract, live preview and source: https://ds.interlace.tools/c/landing-template\n\nRequires the `@interlace/theme` CSS baseline (installed automatically as a registry dependency)."
}
