@contractspec/bundle.marketing 3.8.8 → 3.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/.turbo/turbo-build.log +73 -29
  2. package/CHANGELOG.md +63 -0
  3. package/dist/browser/components/templates/TemplateCard.js +83 -0
  4. package/dist/browser/components/templates/TemplateCommandDialog.js +110 -0
  5. package/dist/browser/components/templates/TemplatePreviewContent.js +96 -0
  6. package/dist/browser/components/templates/TemplatesBrowseControls.js +130 -0
  7. package/dist/browser/components/templates/TemplatesCatalogSection.js +307 -0
  8. package/dist/browser/components/templates/TemplatesClientPage.js +1020 -917
  9. package/dist/browser/components/templates/TemplatesHeroSection.js +87 -0
  10. package/dist/browser/components/templates/TemplatesNextStepsSection.js +126 -0
  11. package/dist/browser/components/templates/TemplatesOverlays.js +2874 -0
  12. package/dist/browser/components/templates/TemplatesPreviewModal.js +136 -126
  13. package/dist/browser/components/templates/index.js +1055 -952
  14. package/dist/browser/components/templates/template-catalog.js +83 -0
  15. package/dist/browser/components/templates/template-filters.js +99 -0
  16. package/dist/browser/components/templates/template-new.js +23 -0
  17. package/dist/browser/components/templates/template-preview.js +43 -0
  18. package/dist/browser/components/templates/template-source.js +19 -0
  19. package/dist/browser/components/templates/template-tag-visibility.js +40 -0
  20. package/dist/browser/components/templates/useTemplateBrowseState.js +191 -0
  21. package/dist/browser/index.js +1055 -952
  22. package/dist/components/templates/TemplateCard.d.ts +12 -0
  23. package/dist/components/templates/TemplateCard.js +78 -0
  24. package/dist/components/templates/TemplateCommandDialog.d.ts +6 -0
  25. package/dist/components/templates/TemplateCommandDialog.js +105 -0
  26. package/dist/components/templates/TemplatePreviewContent.d.ts +5 -0
  27. package/dist/components/templates/TemplatePreviewContent.js +91 -0
  28. package/dist/components/templates/TemplatesBrowseControls.d.ts +18 -0
  29. package/dist/components/templates/TemplatesBrowseControls.js +125 -0
  30. package/dist/components/templates/TemplatesCatalogSection.d.ts +17 -0
  31. package/dist/components/templates/TemplatesCatalogSection.js +302 -0
  32. package/dist/components/templates/TemplatesClientPage.js +1020 -917
  33. package/dist/components/templates/TemplatesHeroSection.d.ts +5 -0
  34. package/dist/components/templates/TemplatesHeroSection.js +82 -0
  35. package/dist/components/templates/TemplatesNextStepsSection.d.ts +1 -0
  36. package/dist/components/templates/TemplatesNextStepsSection.js +121 -0
  37. package/dist/components/templates/TemplatesOverlays.d.ts +10 -0
  38. package/dist/components/templates/TemplatesOverlays.js +2869 -0
  39. package/dist/components/templates/TemplatesPreviewModal.d.ts +3 -4
  40. package/dist/components/templates/TemplatesPreviewModal.js +136 -126
  41. package/dist/components/templates/index.js +1055 -952
  42. package/dist/components/templates/template-catalog.d.ts +28 -0
  43. package/dist/components/templates/template-catalog.js +78 -0
  44. package/dist/components/templates/template-catalog.test.d.ts +1 -0
  45. package/dist/components/templates/template-filters.d.ts +12 -0
  46. package/dist/components/templates/template-filters.js +94 -0
  47. package/dist/components/templates/template-new.d.ts +2 -0
  48. package/dist/components/templates/template-new.js +18 -0
  49. package/dist/components/templates/template-preview.d.ts +18 -0
  50. package/dist/components/templates/template-preview.js +38 -0
  51. package/dist/components/templates/template-source.d.ts +3 -0
  52. package/dist/components/templates/template-source.js +14 -0
  53. package/dist/components/templates/template-tag-visibility.d.ts +10 -0
  54. package/dist/components/templates/template-tag-visibility.js +35 -0
  55. package/dist/components/templates/useTemplateBrowseState.d.ts +22 -0
  56. package/dist/components/templates/useTemplateBrowseState.js +186 -0
  57. package/dist/index.js +1055 -952
  58. package/dist/node/components/templates/TemplateCard.js +78 -0
  59. package/dist/node/components/templates/TemplateCommandDialog.js +105 -0
  60. package/dist/node/components/templates/TemplatePreviewContent.js +91 -0
  61. package/dist/node/components/templates/TemplatesBrowseControls.js +125 -0
  62. package/dist/node/components/templates/TemplatesCatalogSection.js +302 -0
  63. package/dist/node/components/templates/TemplatesClientPage.js +1020 -917
  64. package/dist/node/components/templates/TemplatesHeroSection.js +82 -0
  65. package/dist/node/components/templates/TemplatesNextStepsSection.js +121 -0
  66. package/dist/node/components/templates/TemplatesOverlays.js +2869 -0
  67. package/dist/node/components/templates/TemplatesPreviewModal.js +136 -126
  68. package/dist/node/components/templates/index.js +1055 -952
  69. package/dist/node/components/templates/template-catalog.js +78 -0
  70. package/dist/node/components/templates/template-filters.js +94 -0
  71. package/dist/node/components/templates/template-new.js +18 -0
  72. package/dist/node/components/templates/template-preview.js +38 -0
  73. package/dist/node/components/templates/template-source.js +14 -0
  74. package/dist/node/components/templates/template-tag-visibility.js +35 -0
  75. package/dist/node/components/templates/useTemplateBrowseState.js +186 -0
  76. package/dist/node/index.js +1055 -952
  77. package/package.json +237 -26
  78. package/src/components/templates/TemplateCard.tsx +74 -0
  79. package/src/components/templates/TemplateCommandDialog.tsx +92 -0
  80. package/src/components/templates/TemplatePreviewContent.tsx +182 -0
  81. package/src/components/templates/TemplatesBrowseControls.tsx +144 -0
  82. package/src/components/templates/TemplatesCatalogSection.tsx +191 -0
  83. package/src/components/templates/TemplatesClientPage.tsx +85 -773
  84. package/src/components/templates/TemplatesHeroSection.tsx +41 -0
  85. package/src/components/templates/TemplatesNextStepsSection.tsx +80 -0
  86. package/src/components/templates/TemplatesOverlays.tsx +65 -0
  87. package/src/components/templates/TemplatesPreviewModal.tsx +19 -294
  88. package/src/components/templates/template-catalog.test.ts +162 -0
  89. package/src/components/templates/template-catalog.ts +140 -0
  90. package/src/components/templates/template-filters.ts +57 -0
  91. package/src/components/templates/template-new.ts +12 -0
  92. package/src/components/templates/template-preview.ts +57 -0
  93. package/src/components/templates/template-source.ts +13 -0
  94. package/src/components/templates/template-tag-visibility.ts +58 -0
  95. package/src/components/templates/useTemplateBrowseState.ts +101 -0
  96. package/.turbo/turbo-prebuild.log +0 -1
package/dist/index.js CHANGED
@@ -2561,989 +2561,1092 @@ function PricingThinkingModal({
2561
2561
  }, undefined, true, undefined, this)
2562
2562
  }, undefined, false, undefined, this);
2563
2563
  }
2564
- // src/components/templates/TemplatesPreviewModal.tsx
2565
- import { LoadingSpinner } from "@contractspec/lib.ui-kit-web/ui/atoms/LoadingSpinner";
2566
- import { Dialog as Dialog2, DialogContent as DialogContent2 } from "@contractspec/lib.ui-kit-web/ui/dialog";
2567
- import { ScrollArea } from "@contractspec/lib.ui-kit-web/ui/scroll-area";
2568
- import dynamic from "next/dynamic";
2569
- import { useMemo } from "react";
2564
+ // src/components/templates/TemplateCard.tsx
2570
2565
  import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
2571
2566
  "use client";
2572
- var TemplateShell = dynamic(() => import("@contractspec/lib.example-shared-ui").then((mod) => mod.TemplateShell), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2573
- var TodosTaskList = dynamic(() => import("@contractspec/bundle.library/components/templates/todos/TaskList").then((mod) => mod.TaskList), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2574
- var MessagingWorkspace = dynamic(() => import("@contractspec/bundle.library/components/templates/messaging/MessagingWorkspace").then((mod) => mod.MessagingWorkspace), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2575
- var RecipesExperience = dynamic(() => import("@contractspec/bundle.library/components/templates/recipes/RecipeList").then((mod) => mod.RecipeList), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2576
- var SaasDashboard = dynamic(() => import("@contractspec/example.saas-boilerplate").then((mod) => mod.SaasDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2577
- var CrmDashboard = dynamic(() => import("@contractspec/example.crm-pipeline").then((mod) => mod.CrmDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2578
- var DataGridShowcase = dynamic(() => import("@contractspec/example.data-grid-showcase/ui").then((mod) => mod.DataGridShowcase), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2579
- var VisualizationShowcase = dynamic(() => import("@contractspec/example.visualization-showcase/ui").then((mod) => mod.VisualizationShowcase), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2580
- var AgentDashboard = dynamic(() => import("@contractspec/example.agent-console/ui").then((mod) => mod.AgentDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2581
- var WorkflowDashboard = dynamic(() => import("@contractspec/example.workflow-system/ui").then((mod) => mod.WorkflowDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2582
- var MarketplaceDashboard = dynamic(() => import("@contractspec/example.marketplace/ui").then((mod) => mod.MarketplaceDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2583
- var IntegrationDashboard = dynamic(() => import("@contractspec/example.integration-hub/ui").then((mod) => mod.IntegrationDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2584
- var AnalyticsDashboard = dynamic(() => import("@contractspec/example.analytics-dashboard").then((mod) => mod.AnalyticsDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2585
- var AiChatAssistantDashboard = dynamic(() => import("@contractspec/example.ai-chat-assistant").then((mod) => mod.AiChatAssistantDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV11(LoadingSpinner, {}, undefined, false, undefined, this) });
2586
- var TemplatePreviewModal = ({
2587
- templateId,
2588
- onClose
2589
- }) => {
2590
- const previewComponent = useMemo(() => {
2591
- switch (templateId) {
2592
- case "todos-app":
2593
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2594
- title: "Starter tasks",
2595
- description: "Track work items with filters, priorities, and per-tenant data isolation.",
2596
- showSaveAction: false,
2597
- children: /* @__PURE__ */ jsxDEV11(TodosTaskList, {}, undefined, false, undefined, this)
2598
- }, undefined, false, undefined, this);
2599
- case "messaging-app":
2600
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2601
- title: "Messaging workspace",
2602
- description: "Realtime-ready messaging surface with optimistic delivery.",
2603
- showSaveAction: false,
2604
- children: /* @__PURE__ */ jsxDEV11(MessagingWorkspace, {}, undefined, false, undefined, this)
2605
- }, undefined, false, undefined, this);
2606
- case "recipe-app-i18n":
2607
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2608
- title: "Ceremony recipes",
2609
- description: "Switch locales and preview how rituals translate across teams.",
2610
- showSaveAction: false,
2611
- children: /* @__PURE__ */ jsxDEV11(RecipesExperience, {}, undefined, false, undefined, this)
2612
- }, undefined, false, undefined, this);
2613
- case "saas-boilerplate":
2614
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2615
- title: "SaaS Boilerplate",
2616
- description: "Multi-tenant organizations, projects, settings, and billing usage tracking.",
2617
- showSaveAction: false,
2618
- children: /* @__PURE__ */ jsxDEV11(SaasDashboard, {}, undefined, false, undefined, this)
2619
- }, undefined, false, undefined, this);
2620
- case "crm-pipeline":
2621
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2622
- title: "CRM Pipeline",
2623
- description: "Sales CRM with contacts, companies, deals, and pipeline stages.",
2624
- showSaveAction: false,
2625
- children: /* @__PURE__ */ jsxDEV11(CrmDashboard, {}, undefined, false, undefined, this)
2626
- }, undefined, false, undefined, this);
2627
- case "data-grid-showcase":
2628
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2629
- title: "Data Grid Showcase",
2630
- description: "Shared ContractSpec table primitives with client, server, and DataView-driven lanes.",
2631
- showSaveAction: false,
2632
- children: /* @__PURE__ */ jsxDEV11(DataGridShowcase, {}, undefined, false, undefined, this)
2633
- }, undefined, false, undefined, this);
2634
- case "visualization-showcase":
2635
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2636
- title: "Visualization Showcase",
2637
- description: "ContractSpec-owned chart primitives rendered through shared visualization contracts and design-system wrappers.",
2638
- showSaveAction: false,
2639
- children: /* @__PURE__ */ jsxDEV11(VisualizationShowcase, {}, undefined, false, undefined, this)
2640
- }, undefined, false, undefined, this);
2641
- case "agent-console":
2642
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2643
- title: "AI Agent Console",
2644
- description: "AI agent orchestration with tools, agents, runs, and execution logs.",
2645
- showSaveAction: false,
2646
- children: /* @__PURE__ */ jsxDEV11(AgentDashboard, {}, undefined, false, undefined, this)
2647
- }, undefined, false, undefined, this);
2648
- case "ai-chat-assistant":
2649
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2650
- title: "AI Chat Assistant",
2651
- description: "Focused assistant surface with reasoning, sources, suggestions, and MCP-aware tools.",
2652
- showSaveAction: false,
2653
- children: /* @__PURE__ */ jsxDEV11(AiChatAssistantDashboard, {}, undefined, false, undefined, this)
2654
- }, undefined, false, undefined, this);
2655
- case "workflow-system":
2656
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2657
- title: "Workflow System",
2658
- description: "Multi-step workflows with role-based approvals.",
2659
- showSaveAction: false,
2660
- children: /* @__PURE__ */ jsxDEV11(WorkflowDashboard, {}, undefined, false, undefined, this)
2661
- }, undefined, false, undefined, this);
2662
- case "marketplace":
2663
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2664
- title: "Marketplace",
2665
- description: "Two-sided marketplace with stores, products, and orders.",
2666
- showSaveAction: false,
2667
- children: /* @__PURE__ */ jsxDEV11(MarketplaceDashboard, {}, undefined, false, undefined, this)
2668
- }, undefined, false, undefined, this);
2669
- case "integration-hub":
2670
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2671
- title: "Integration Hub",
2672
- description: "Third-party integrations with sync and field mapping.",
2673
- showSaveAction: false,
2674
- children: /* @__PURE__ */ jsxDEV11(IntegrationDashboard, {}, undefined, false, undefined, this)
2675
- }, undefined, false, undefined, this);
2676
- case "analytics-dashboard":
2677
- return /* @__PURE__ */ jsxDEV11(TemplateShell, {
2678
- title: "Analytics Dashboard",
2679
- description: "Custom dashboards with widgets and queries.",
2680
- showSaveAction: false,
2681
- children: /* @__PURE__ */ jsxDEV11(AnalyticsDashboard, {}, undefined, false, undefined, this)
2682
- }, undefined, false, undefined, this);
2683
- case null:
2684
- return null;
2685
- default:
2686
- return null;
2687
- }
2688
- }, [templateId]);
2689
- return /* @__PURE__ */ jsxDEV11(Dialog2, {
2690
- open: !!previewComponent,
2691
- onOpenChange: onClose,
2692
- children: /* @__PURE__ */ jsxDEV11(DialogContent2, {
2693
- className: "mb-8 flex h-[calc(100vh-2rem)] min-w-[calc(100vw-2rem)] flex-col justify-between gap-0 p-0",
2694
- children: /* @__PURE__ */ jsxDEV11(ScrollArea, {
2695
- className: "flex flex-col justify-between overflow-hidden",
2696
- children: previewComponent
2697
- }, undefined, false, undefined, this)
2698
- }, undefined, false, undefined, this)
2699
- }, undefined, false, undefined, this);
2700
- };
2567
+ function TemplateCard({
2568
+ title,
2569
+ description,
2570
+ metaBadges,
2571
+ tags,
2572
+ featureList = [],
2573
+ isNew = false,
2574
+ previewAction,
2575
+ useAction
2576
+ }) {
2577
+ return /* @__PURE__ */ jsxDEV11("div", {
2578
+ className: "editorial-panel relative flex flex-col space-y-4 transition-colors hover:border-[color:rgb(162_79_42_/_0.55)]",
2579
+ children: [
2580
+ isNew ? /* @__PURE__ */ jsxDEV11("span", {
2581
+ className: "absolute top-4 right-4 rounded-full bg-[color:var(--success)] px-2.5 py-1 font-medium text-[11px] text-white uppercase",
2582
+ children: "New"
2583
+ }, undefined, false, undefined, this) : null,
2584
+ /* @__PURE__ */ jsxDEV11("div", {
2585
+ children: [
2586
+ /* @__PURE__ */ jsxDEV11("h3", {
2587
+ className: "font-serif text-2xl tracking-[-0.03em]",
2588
+ children: title
2589
+ }, undefined, false, undefined, this),
2590
+ /* @__PURE__ */ jsxDEV11("p", {
2591
+ className: "mt-1 text-muted-foreground text-sm",
2592
+ children: description
2593
+ }, undefined, false, undefined, this)
2594
+ ]
2595
+ }, undefined, true, undefined, this),
2596
+ /* @__PURE__ */ jsxDEV11("div", {
2597
+ className: "flex-1 space-y-3",
2598
+ children: [
2599
+ /* @__PURE__ */ jsxDEV11("div", {
2600
+ className: "flex flex-wrap gap-2",
2601
+ children: metaBadges.map((badge) => /* @__PURE__ */ jsxDEV11("span", {
2602
+ className: "rounded-full border border-border bg-background px-3 py-1 text-[11px] text-foreground",
2603
+ children: badge
2604
+ }, badge, false, undefined, this))
2605
+ }, undefined, false, undefined, this),
2606
+ featureList.length > 0 ? /* @__PURE__ */ jsxDEV11("p", {
2607
+ className: "text-muted-foreground text-xs",
2608
+ children: [
2609
+ /* @__PURE__ */ jsxDEV11("span", {
2610
+ className: "font-medium text-foreground",
2611
+ children: "Features:"
2612
+ }, undefined, false, undefined, this),
2613
+ " ",
2614
+ featureList.join(", ")
2615
+ ]
2616
+ }, undefined, true, undefined, this) : null,
2617
+ /* @__PURE__ */ jsxDEV11("div", {
2618
+ className: "flex flex-wrap gap-1",
2619
+ children: tags.map((tag) => /* @__PURE__ */ jsxDEV11("span", {
2620
+ className: "rounded-full border border-border bg-muted px-3 py-1 text-[11px] text-muted-foreground",
2621
+ children: tag
2622
+ }, tag, false, undefined, this))
2623
+ }, undefined, false, undefined, this)
2624
+ ]
2625
+ }, undefined, true, undefined, this),
2626
+ /* @__PURE__ */ jsxDEV11("div", {
2627
+ className: "flex gap-2 pt-4",
2628
+ children: [
2629
+ previewAction,
2630
+ useAction
2631
+ ]
2632
+ }, undefined, true, undefined, this)
2633
+ ]
2634
+ }, undefined, true, undefined, this);
2635
+ }
2701
2636
 
2702
- // src/components/templates/TemplatesClientPage.tsx
2637
+ // src/components/templates/TemplateCommandDialog.tsx
2703
2638
  import {
2704
2639
  analyticsEventNames as analyticsEventNames2,
2705
2640
  captureAnalyticsEvent as captureAnalyticsEvent2
2706
2641
  } from "@contractspec/bundle.library/libs/posthog/client";
2707
- import { useRegistryTemplates } from "@contractspec/lib.example-shared-ui";
2708
- import { cn } from "@contractspec/lib.ui-kit-core/utils";
2709
2642
  import {
2710
- Dialog as Dialog3,
2711
- DialogContent as DialogContent3,
2643
+ Dialog as Dialog2,
2644
+ DialogContent as DialogContent2,
2712
2645
  DialogDescription as DialogDescription2,
2713
2646
  DialogHeader as DialogHeader2,
2714
2647
  DialogTitle as DialogTitle2
2715
2648
  } from "@contractspec/lib.ui-kit-web/ui/dialog";
2716
- import {
2717
- Tooltip,
2718
- TooltipContent,
2719
- TooltipProvider,
2720
- TooltipTrigger
2721
- } from "@contractspec/lib.ui-kit-web/ui/tooltip";
2722
- import { getTemplate } from "@contractspec/module.examples";
2723
- import { Search } from "lucide-react";
2724
- import Link8 from "next/link";
2725
- import { useState as useState2 } from "react";
2726
2649
  import { jsxDEV as jsxDEV12 } from "react/jsx-dev-runtime";
2727
2650
  "use client";
2728
- var templates = [
2729
- {
2730
- id: "minimal-example",
2731
- templateId: "todos-app",
2732
- title: "Minimal Example",
2733
- description: "A minimal template to get you running in minutes. Perfect for exploring the engine.",
2734
- tags: ["Getting Started"],
2735
- capabilities: "Basic Forms, Auth",
2736
- isStarter: true,
2737
- previewUrl: "/sandbox?template=minimal-example",
2738
- docsUrl: "/docs/getting-started/hello-world"
2739
- },
2740
- {
2741
- id: "saas-boilerplate",
2742
- templateId: "saas-boilerplate",
2651
+ function TemplateCommandDialog({
2652
+ templateId,
2653
+ onClose,
2654
+ onDeployStudio
2655
+ }) {
2656
+ const command = templateId ? `npx contractspec init --template ${templateId}` : "";
2657
+ return /* @__PURE__ */ jsxDEV12(Dialog2, {
2658
+ open: !!templateId,
2659
+ onOpenChange: (open) => !open && onClose(),
2660
+ children: /* @__PURE__ */ jsxDEV12(DialogContent2, {
2661
+ className: "max-w-md",
2662
+ children: [
2663
+ /* @__PURE__ */ jsxDEV12(DialogHeader2, {
2664
+ children: [
2665
+ /* @__PURE__ */ jsxDEV12(DialogTitle2, {
2666
+ children: "Use this template"
2667
+ }, undefined, false, undefined, this),
2668
+ /* @__PURE__ */ jsxDEV12(DialogDescription2, {
2669
+ children: "Initialize a new project with this template using the CLI."
2670
+ }, undefined, false, undefined, this)
2671
+ ]
2672
+ }, undefined, true, undefined, this),
2673
+ /* @__PURE__ */ jsxDEV12("div", {
2674
+ className: "space-y-4 pt-4",
2675
+ children: [
2676
+ /* @__PURE__ */ jsxDEV12("div", {
2677
+ className: "rounded-md border border-zinc-800 bg-zinc-950 p-4 font-mono text-sm text-zinc-50",
2678
+ children: command
2679
+ }, undefined, false, undefined, this),
2680
+ /* @__PURE__ */ jsxDEV12("div", {
2681
+ className: "flex gap-2",
2682
+ children: /* @__PURE__ */ jsxDEV12("button", {
2683
+ className: "btn-secondary w-full",
2684
+ onClick: () => {
2685
+ if (!templateId) {
2686
+ return;
2687
+ }
2688
+ navigator.clipboard.writeText(command);
2689
+ captureAnalyticsEvent2(analyticsEventNames2.COPY_COMMAND_CLICK, {
2690
+ surface: "templates",
2691
+ templateId,
2692
+ filename: "templates-cli"
2693
+ });
2694
+ },
2695
+ children: "Copy Command"
2696
+ }, undefined, false, undefined, this)
2697
+ }, undefined, false, undefined, this),
2698
+ /* @__PURE__ */ jsxDEV12("div", {
2699
+ className: "relative",
2700
+ children: [
2701
+ /* @__PURE__ */ jsxDEV12("div", {
2702
+ className: "absolute inset-0 flex items-center",
2703
+ children: /* @__PURE__ */ jsxDEV12("span", {
2704
+ className: "w-full border-border border-t"
2705
+ }, undefined, false, undefined, this)
2706
+ }, undefined, false, undefined, this),
2707
+ /* @__PURE__ */ jsxDEV12("div", {
2708
+ className: "relative flex justify-center text-xs uppercase",
2709
+ children: /* @__PURE__ */ jsxDEV12("span", {
2710
+ className: "bg-background px-2 text-muted-foreground",
2711
+ children: "Or"
2712
+ }, undefined, false, undefined, this)
2713
+ }, undefined, false, undefined, this)
2714
+ ]
2715
+ }, undefined, true, undefined, this),
2716
+ /* @__PURE__ */ jsxDEV12("button", {
2717
+ className: "btn-ghost w-full text-sm",
2718
+ onClick: () => {
2719
+ if (!templateId) {
2720
+ return;
2721
+ }
2722
+ captureAnalyticsEvent2(analyticsEventNames2.CTA_STUDIO_CLICK, {
2723
+ surface: "templates",
2724
+ templateId
2725
+ });
2726
+ onDeployStudio();
2727
+ },
2728
+ children: "Deploy to Studio"
2729
+ }, undefined, false, undefined, this)
2730
+ ]
2731
+ }, undefined, true, undefined, this)
2732
+ ]
2733
+ }, undefined, true, undefined, this)
2734
+ }, undefined, false, undefined, this);
2735
+ }
2736
+
2737
+ // src/components/templates/TemplatePreviewContent.tsx
2738
+ import {
2739
+ TemplateShell
2740
+ } from "@contractspec/lib.example-shared-ui";
2741
+ import { LoadingSpinner } from "@contractspec/lib.ui-kit-web/ui/atoms/LoadingSpinner";
2742
+ import dynamic from "next/dynamic";
2743
+ import { jsxDEV as jsxDEV13 } from "react/jsx-dev-runtime";
2744
+ "use client";
2745
+ var SaasDashboard = dynamic(() => import("@contractspec/example.saas-boilerplate").then((module) => module.SaasDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2746
+ var CrmDashboard = dynamic(() => import("@contractspec/example.crm-pipeline").then((module) => module.CrmDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2747
+ var DataGridShowcase = dynamic(() => import("@contractspec/example.data-grid-showcase/ui").then((module) => module.DataGridShowcase), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2748
+ var VisualizationShowcase = dynamic(() => import("@contractspec/example.visualization-showcase/ui").then((module) => module.VisualizationShowcase), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2749
+ var AgentDashboard = dynamic(() => import("@contractspec/example.agent-console/ui").then((module) => module.AgentDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2750
+ var AiChatAssistantDashboard = dynamic(() => import("@contractspec/example.ai-chat-assistant").then((module) => module.AiChatAssistantDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2751
+ var WorkflowDashboard = dynamic(() => import("@contractspec/example.workflow-system/ui").then((module) => module.WorkflowDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2752
+ var MarketplaceDashboard = dynamic(() => import("@contractspec/example.marketplace/ui").then((module) => module.MarketplaceDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2753
+ var IntegrationDashboard = dynamic(() => import("@contractspec/example.integration-hub/ui").then((module) => module.IntegrationDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2754
+ var AnalyticsDashboard = dynamic(() => import("@contractspec/example.analytics-dashboard").then((module) => module.AnalyticsDashboard), { ssr: false, loading: () => /* @__PURE__ */ jsxDEV13(LoadingSpinner, {}, undefined, false, undefined, this) });
2755
+ var PREVIEW_DEFINITIONS = {
2756
+ "saas-boilerplate": {
2743
2757
  title: "SaaS Boilerplate",
2744
- description: "Complete SaaS foundation with multi-tenant orgs, projects, settings, and billing usage.",
2745
- tags: ["Getting Started", "SaaS", "Business"],
2746
- capabilities: "Multi-tenancy, RBAC, Projects, Billing",
2747
- isNew: true,
2748
- previewUrl: "/sandbox?template=saas-boilerplate",
2749
- docsUrl: "/docs/templates/saas-boilerplate"
2758
+ description: "Multi-tenant organizations, projects, settings, and billing usage tracking.",
2759
+ component: SaasDashboard
2750
2760
  },
2751
- {
2752
- id: "crm-pipeline",
2753
- templateId: "crm-pipeline",
2761
+ "crm-pipeline": {
2754
2762
  title: "CRM Pipeline",
2755
- description: "Sales CRM with contacts, companies, deals, pipeline stages, and task management.",
2756
- tags: ["CRM", "Business"],
2757
- capabilities: "Contacts, Deals, Pipelines, Tasks",
2758
- isNew: true,
2759
- previewUrl: "/sandbox?template=crm-pipeline",
2760
- docsUrl: "/docs/templates/crm-pipeline"
2763
+ description: "Sales CRM with contacts, companies, deals, and pipeline stages.",
2764
+ component: CrmDashboard
2761
2765
  },
2762
- {
2763
- id: "data-grid-showcase",
2764
- templateId: "data-grid-showcase",
2766
+ "data-grid-showcase": {
2765
2767
  title: "Data Grid Showcase",
2766
- description: "Focused example for ContractSpec headless tables across client, server, and DataView-driven lanes.",
2767
- tags: ["Ops", "Business"],
2768
- capabilities: "Tables, Sorting, Pagination, Column Controls",
2769
- isNew: true,
2770
- previewUrl: "/sandbox?template=data-grid-showcase",
2771
- docsUrl: "/docs/examples/data-grid-showcase"
2768
+ description: "Shared ContractSpec table primitives with client, server, and DataView-driven lanes.",
2769
+ component: DataGridShowcase
2772
2770
  },
2773
- {
2774
- id: "visualization-showcase",
2775
- templateId: "visualization-showcase",
2771
+ "visualization-showcase": {
2776
2772
  title: "Visualization Showcase",
2777
- description: "Canonical ContractSpec example for chart primitives, shared visualization contracts, and opinionated dashboard blocks.",
2778
- tags: ["Ops", "Visualization"],
2779
- capabilities: "Metrics, Charts, Timelines, Comparisons",
2780
- isNew: true,
2781
- previewUrl: "/sandbox?template=visualization-showcase",
2782
- docsUrl: "/docs/examples/visualization-showcase"
2773
+ description: "ContractSpec-owned chart primitives rendered through shared visualization contracts and design-system wrappers.",
2774
+ component: VisualizationShowcase
2783
2775
  },
2784
- {
2785
- id: "agent-console",
2786
- templateId: "agent-console",
2776
+ "agent-console": {
2787
2777
  title: "AI Agent Console",
2788
- description: "AI agent orchestration platform with tools, agents, runs, and execution logs.",
2789
- tags: ["AI", "Ops"],
2790
- capabilities: "Tools, Agents, Runs, Metrics",
2791
- isNew: true,
2792
- previewUrl: "/sandbox?template=agent-console",
2793
- docsUrl: "/docs/examples/agent-console"
2778
+ description: "AI agent orchestration with tools, agents, runs, and execution logs.",
2779
+ component: AgentDashboard
2794
2780
  },
2795
- {
2796
- id: "ai-chat-assistant",
2797
- templateId: "ai-chat-assistant",
2781
+ "ai-chat-assistant": {
2798
2782
  title: "AI Chat Assistant",
2799
- description: "Focused assistant template with reasoning, sources, suggestions, and MCP-aware tooling.",
2800
- tags: ["AI", "Ops"],
2801
- capabilities: "Chat UX, Sources, Suggestions, MCP",
2802
- isNew: true,
2803
- previewUrl: "/sandbox?template=ai-chat-assistant",
2804
- docsUrl: "/docs/examples/ai-chat-assistant"
2783
+ description: "Focused assistant surface with reasoning, sources, suggestions, and MCP-aware tools.",
2784
+ component: AiChatAssistantDashboard
2805
2785
  },
2806
- {
2807
- id: "workflow-system",
2808
- templateId: "workflow-system",
2809
- title: "Workflow / Approval System",
2810
- description: "Multi-step workflows with role-based approvals and state transitions.",
2811
- tags: ["Business", "Ops"],
2812
- capabilities: "Workflows, Approvals, State Machine",
2813
- isNew: true,
2814
- previewUrl: "/sandbox?template=workflow-system",
2815
- docsUrl: "/docs/examples/workflow-system"
2786
+ "workflow-system": {
2787
+ title: "Workflow System",
2788
+ description: "Multi-step workflows with role-based approvals.",
2789
+ component: WorkflowDashboard
2816
2790
  },
2817
- {
2818
- id: "marketplace",
2819
- templateId: "marketplace",
2791
+ marketplace: {
2820
2792
  title: "Marketplace",
2821
2793
  description: "Two-sided marketplace with stores, products, orders, and payouts.",
2822
- tags: ["Business", "Payments"],
2823
- capabilities: "Stores, Products, Orders, Payouts",
2824
- isNew: true,
2825
- previewUrl: "/sandbox?template=marketplace",
2826
- docsUrl: "/docs/templates/marketplace"
2794
+ component: MarketplaceDashboard
2827
2795
  },
2828
- {
2829
- id: "integration-hub",
2830
- templateId: "integration-hub",
2796
+ "integration-hub": {
2831
2797
  title: "Integration Hub",
2832
2798
  description: "Third-party integrations with connections, sync configs, and field mapping.",
2833
- tags: ["Ops", "AI"],
2834
- capabilities: "Integrations, Connections, Sync",
2835
- isNew: true,
2836
- previewUrl: "/sandbox?template=integration-hub",
2837
- docsUrl: "/docs/templates/integration-hub"
2799
+ component: IntegrationDashboard
2838
2800
  },
2839
- {
2840
- id: "learning-journey-studio-onboarding",
2841
- templateId: "learning-journey-studio-onboarding",
2842
- title: "Learning Journey \u2014 Studio Getting Started",
2843
- description: "First 30 minutes in Studio: choose template, edit spec, regenerate, playground, evolution.",
2844
- tags: ["Learning", "Onboarding"],
2845
- capabilities: "Spec-first onboarding, XP/streak, progress widget",
2846
- isNew: true,
2847
- previewUrl: "/sandbox?template=learning-journey-studio-onboarding",
2848
- docsUrl: "/docs/templates/learning-journey-studio-onboarding"
2849
- },
2850
- {
2851
- id: "learning-journey-platform-tour",
2852
- templateId: "learning-journey-platform-tour",
2853
- title: "Learning Journey \u2014 Platform Primitives Tour",
2854
- description: "Touch identity, audit, notifications, jobs, flags, files, metering once with guided steps.",
2855
- tags: ["Learning", "Platform"],
2856
- capabilities: "Cross-module tour with event-driven completion",
2857
- isNew: true,
2858
- previewUrl: "/sandbox?template=learning-journey-platform-tour",
2859
- docsUrl: "/docs/templates/learning-journey-platform-tour"
2860
- },
2861
- {
2862
- id: "learning-journey-crm-onboarding",
2863
- templateId: "learning-journey-crm-onboarding",
2864
- title: "Learning Journey \u2014 CRM First Win",
2865
- description: "Get to first closed-won deal: pipeline, contact/company, deal, stages, follow-up.",
2866
- tags: ["Learning", "CRM"],
2867
- capabilities: "CRM onboarding with XP/streak/badge",
2868
- isNew: true,
2869
- previewUrl: "/sandbox?template=learning-journey-crm-onboarding",
2870
- docsUrl: "/docs/templates/learning-journey-crm-onboarding"
2871
- },
2872
- {
2873
- id: "analytics-dashboard",
2874
- templateId: "analytics-dashboard",
2801
+ "analytics-dashboard": {
2875
2802
  title: "Analytics Dashboard",
2876
- description: "Custom dashboards with widgets, saved queries, and real-time visualization.",
2877
- tags: ["Business", "Ops"],
2878
- capabilities: "Dashboards, Widgets, Queries",
2879
- isNew: true,
2880
- previewUrl: "/sandbox?template=analytics-dashboard",
2881
- docsUrl: "/docs/templates/analytics-dashboard"
2882
- },
2883
- {
2884
- id: "plumber-ops",
2885
- templateId: "messaging-app",
2886
- title: "Plumber Ops",
2887
- description: "Complete workflow: Quotes \u2192 Deposit \u2192 Job \u2192 Invoice \u2192 Payment. Policy-enforced approvals.",
2888
- tags: ["Trades", "Payments"],
2889
- capabilities: "Quotes, Jobs, Invoicing, Payments",
2890
- previewUrl: "/sandbox?template=plumber-ops",
2891
- docsUrl: "/docs/specs/workflows"
2892
- },
2893
- {
2894
- id: "coliving-management",
2895
- templateId: "recipe-app-i18n",
2896
- title: "Coliving Management",
2897
- description: "Coliving management: Onboarding, chores, shared wallet. Multi-party approvals built-in.",
2898
- tags: ["Coliving", "Finance"],
2899
- capabilities: "Tasks, Approvals, Payments",
2900
- previewUrl: "/sandbox?template=coliving-management",
2901
- docsUrl: "/docs/specs/workflows"
2902
- },
2903
- {
2904
- id: "chores-allowance",
2905
- templateId: "todos-app",
2906
- title: "Chores & Allowance",
2907
- description: "Family task management with approval workflows. Teach financial accountability safely.",
2908
- tags: ["Family", "Ops"],
2909
- capabilities: "Tasks, Approvals, Notifications",
2910
- previewUrl: "/sandbox?template=chores-allowance",
2911
- docsUrl: "/docs/specs/workflows"
2912
- },
2913
- {
2914
- id: "service-dispatch",
2915
- templateId: "messaging-app",
2916
- title: "Service Dispatch",
2917
- description: "Field service scheduling, routing, and invoicing. Real-time coordination with policy gates.",
2918
- tags: ["Ops", "Trades"],
2919
- capabilities: "Scheduling, Maps, Invoicing",
2920
- previewUrl: "/sandbox?template=service-dispatch",
2921
- docsUrl: "/docs/specs/workflows"
2922
- },
2923
- {
2924
- id: "content-review",
2925
- templateId: "todos-app",
2926
- title: "Content Review",
2927
- description: "Multi-stage approval workflow for content. Audit trail for every decision.",
2928
- tags: ["Ops"],
2929
- capabilities: "Workflows, Approvals, Comments",
2930
- previewUrl: "/sandbox?template=content-review",
2931
- docsUrl: "/docs/specs/workflows"
2803
+ description: "Custom dashboards with widgets and queries.",
2804
+ component: AnalyticsDashboard
2932
2805
  }
2933
- ];
2934
- var allTags = [
2935
- "Getting Started",
2936
- "SaaS",
2937
- "Business",
2938
- "CRM",
2939
- "AI",
2940
- "Trades",
2941
- "Coliving",
2942
- "Family",
2943
- "Ops",
2944
- "Payments",
2945
- "Learning",
2946
- "Platform"
2947
- ];
2948
- var TemplatesPage = () => {
2949
- const [selectedTag, setSelectedTag] = useState2(null);
2950
- const [search, setSearch] = useState2("");
2951
- const [preview, setPreview] = useState2(null);
2952
- const [studioSignupModalOpen, setStudioSignupModalOpen] = useState2(false);
2953
- const [source, setSource] = useState2("local");
2954
- const [selectedTemplateForCommand, setSelectedTemplateForCommand] = useState2(null);
2955
- const { data: registryTemplates = [], isLoading: registryLoading } = useRegistryTemplates();
2956
- const filtered = templates.filter((t) => {
2957
- const matchTag = !selectedTag || t.tags.includes(selectedTag);
2958
- const matchSearch = !search || t.title.toLowerCase().includes(search.toLowerCase()) || t.description.toLowerCase().includes(search.toLowerCase());
2959
- return matchTag && matchSearch;
2960
- });
2961
- const commandId = selectedTemplateForCommand ? "templateId" in selectedTemplateForCommand ? selectedTemplateForCommand.templateId : selectedTemplateForCommand.id : "";
2962
- return /* @__PURE__ */ jsxDEV12(TooltipProvider, {
2963
- children: [
2964
- /* @__PURE__ */ jsxDEV12("main", {
2965
- children: [
2966
- /* @__PURE__ */ jsxDEV12("section", {
2967
- className: "section-padding hero-gradient border-border/70 border-b",
2968
- children: /* @__PURE__ */ jsxDEV12("div", {
2969
- className: "editorial-shell space-y-8",
2806
+ };
2807
+ function TemplatePreviewContent({
2808
+ templateId
2809
+ }) {
2810
+ const preview = PREVIEW_DEFINITIONS[templateId];
2811
+ if (!preview) {
2812
+ return null;
2813
+ }
2814
+ const PreviewComponent = preview.component;
2815
+ return /* @__PURE__ */ jsxDEV13(TemplateShell, {
2816
+ title: preview.title,
2817
+ description: preview.description,
2818
+ showSaveAction: false,
2819
+ children: /* @__PURE__ */ jsxDEV13(PreviewComponent, {}, undefined, false, undefined, this)
2820
+ }, undefined, false, undefined, this);
2821
+ }
2822
+
2823
+ // src/components/templates/TemplatesBrowseControls.tsx
2824
+ import { cn } from "@contractspec/lib.ui-kit-core/utils";
2825
+ import { Search } from "lucide-react";
2826
+ import { jsxDEV as jsxDEV14 } from "react/jsx-dev-runtime";
2827
+ "use client";
2828
+ function TemplatesBrowseControls({
2829
+ registryConfigured,
2830
+ availableSources,
2831
+ source,
2832
+ onSourceChange,
2833
+ search,
2834
+ onSearchChange,
2835
+ selectedTag,
2836
+ onTagChange,
2837
+ showTagFilters,
2838
+ visibleTagFacets,
2839
+ hiddenTagFacets,
2840
+ showAllTags,
2841
+ onShowAllTagsChange
2842
+ }) {
2843
+ return /* @__PURE__ */ jsxDEV14("section", {
2844
+ className: "editorial-section",
2845
+ children: /* @__PURE__ */ jsxDEV14("div", {
2846
+ className: "editorial-shell space-y-6",
2847
+ children: [
2848
+ /* @__PURE__ */ jsxDEV14("div", {
2849
+ className: "flex flex-col gap-6 lg:flex-row lg:items-end lg:justify-between",
2850
+ children: [
2851
+ /* @__PURE__ */ jsxDEV14("div", {
2852
+ className: "max-w-3xl space-y-3",
2970
2853
  children: [
2971
- /* @__PURE__ */ jsxDEV12("div", {
2972
- className: "max-w-4xl space-y-5",
2973
- children: [
2974
- /* @__PURE__ */ jsxDEV12("p", {
2975
- className: "editorial-kicker",
2976
- children: "Proof through real scenarios"
2977
- }, undefined, false, undefined, this),
2978
- /* @__PURE__ */ jsxDEV12("h1", {
2979
- className: "editorial-title",
2980
- children: "Templates that show the open system in practice."
2981
- }, undefined, false, undefined, this),
2982
- /* @__PURE__ */ jsxDEV12("p", {
2983
- className: "editorial-subtitle",
2984
- children: "These scenarios are the fastest way to understand ContractSpec: explicit contracts, aligned surfaces, and an adoption path from OSS exploration into Studio deployment."
2985
- }, undefined, false, undefined, this)
2986
- ]
2987
- }, undefined, true, undefined, this),
2988
- /* @__PURE__ */ jsxDEV12("div", {
2989
- className: "editorial-proof-strip",
2990
- children: [
2991
- /* @__PURE__ */ jsxDEV12("div", {
2992
- className: "editorial-stat",
2993
- children: [
2994
- /* @__PURE__ */ jsxDEV12("span", {
2995
- className: "editorial-stat-value",
2996
- children: templates.length
2997
- }, undefined, false, undefined, this),
2998
- /* @__PURE__ */ jsxDEV12("span", {
2999
- className: "editorial-label",
3000
- children: "curated scenarios"
3001
- }, undefined, false, undefined, this)
3002
- ]
3003
- }, undefined, true, undefined, this),
3004
- /* @__PURE__ */ jsxDEV12("div", {
3005
- className: "editorial-stat",
3006
- children: [
3007
- /* @__PURE__ */ jsxDEV12("span", {
3008
- className: "editorial-stat-value",
3009
- children: "2"
3010
- }, undefined, false, undefined, this),
3011
- /* @__PURE__ */ jsxDEV12("span", {
3012
- className: "editorial-label",
3013
- children: "entry paths"
3014
- }, undefined, false, undefined, this)
3015
- ]
3016
- }, undefined, true, undefined, this),
3017
- /* @__PURE__ */ jsxDEV12("div", {
3018
- className: "editorial-stat",
3019
- children: [
3020
- /* @__PURE__ */ jsxDEV12("span", {
3021
- className: "editorial-stat-value",
3022
- children: "OSS"
3023
- }, undefined, false, undefined, this),
3024
- /* @__PURE__ */ jsxDEV12("span", {
3025
- className: "editorial-label",
3026
- children: "first, Studio second"
3027
- }, undefined, false, undefined, this)
3028
- ]
3029
- }, undefined, true, undefined, this)
3030
- ]
3031
- }, undefined, true, undefined, this)
2854
+ /* @__PURE__ */ jsxDEV14("p", {
2855
+ className: "editorial-kicker",
2856
+ children: "Browse by source"
2857
+ }, undefined, false, undefined, this),
2858
+ /* @__PURE__ */ jsxDEV14("h2", {
2859
+ className: "font-serif text-4xl tracking-[-0.04em]",
2860
+ children: "Use local scenarios for core proof, then scan the community."
2861
+ }, undefined, false, undefined, this),
2862
+ /* @__PURE__ */ jsxDEV14("p", {
2863
+ className: "text-muted-foreground text-sm leading-7",
2864
+ children: registryConfigured ? "Local templates show the official adoption path. Community templates show where the ecosystem is pushing the system next." : "Local templates show the official adoption path. Community browsing appears automatically when a registry URL is configured."
2865
+ }, undefined, false, undefined, this)
3032
2866
  ]
3033
- }, undefined, true, undefined, this)
3034
- }, undefined, false, undefined, this),
3035
- /* @__PURE__ */ jsxDEV12("section", {
3036
- className: "editorial-section",
3037
- children: /* @__PURE__ */ jsxDEV12("div", {
3038
- className: "editorial-shell space-y-6",
2867
+ }, undefined, true, undefined, this),
2868
+ registryConfigured ? /* @__PURE__ */ jsxDEV14("div", {
2869
+ className: "flex gap-2",
2870
+ children: availableSources.map((option) => /* @__PURE__ */ jsxDEV14("button", {
2871
+ onClick: () => onSourceChange(option),
2872
+ className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
2873
+ "bg-primary text-primary-foreground": source === option,
2874
+ "border border-border bg-card hover:bg-card/80": source !== option
2875
+ }),
2876
+ "aria-pressed": source === option,
2877
+ children: option === "local" ? "Local" : "Community"
2878
+ }, option, false, undefined, this))
2879
+ }, undefined, false, undefined, this) : null
2880
+ ]
2881
+ }, undefined, true, undefined, this),
2882
+ /* @__PURE__ */ jsxDEV14("div", {
2883
+ className: "editorial-panel space-y-5",
2884
+ children: [
2885
+ /* @__PURE__ */ jsxDEV14("div", {
2886
+ className: "relative",
3039
2887
  children: [
3040
- /* @__PURE__ */ jsxDEV12("div", {
3041
- className: "flex flex-col gap-6 lg:flex-row lg:items-end lg:justify-between",
3042
- children: [
3043
- /* @__PURE__ */ jsxDEV12("div", {
3044
- className: "max-w-3xl space-y-3",
3045
- children: [
3046
- /* @__PURE__ */ jsxDEV12("p", {
3047
- className: "editorial-kicker",
3048
- children: "Browse by source"
3049
- }, undefined, false, undefined, this),
3050
- /* @__PURE__ */ jsxDEV12("h2", {
3051
- className: "font-serif text-4xl tracking-[-0.04em]",
3052
- children: "Use local scenarios for core proof, then scan the community."
3053
- }, undefined, false, undefined, this),
3054
- /* @__PURE__ */ jsxDEV12("p", {
3055
- className: "text-muted-foreground text-sm leading-7",
3056
- children: "Local templates show the official adoption path. Community templates show where the ecosystem is pushing the system next."
3057
- }, undefined, false, undefined, this)
3058
- ]
3059
- }, undefined, true, undefined, this),
3060
- /* @__PURE__ */ jsxDEV12("div", {
3061
- className: "flex gap-2",
3062
- children: [
3063
- /* @__PURE__ */ jsxDEV12("button", {
3064
- onClick: () => setSource("local"),
3065
- className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
3066
- "bg-primary text-primary-foreground": source === "local",
3067
- "border border-border bg-card hover:bg-card/80": source !== "local"
3068
- }),
3069
- "aria-pressed": source === "local",
3070
- children: "Local"
3071
- }, undefined, false, undefined, this),
3072
- /* @__PURE__ */ jsxDEV12("button", {
3073
- onClick: () => setSource("registry"),
3074
- className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
3075
- "bg-primary text-primary-foreground": source === "registry",
3076
- "border border-border bg-card hover:bg-card/80": source !== "registry"
3077
- }),
3078
- "aria-pressed": source === "registry",
3079
- children: "Community"
3080
- }, undefined, false, undefined, this)
3081
- ]
3082
- }, undefined, true, undefined, this)
3083
- ]
3084
- }, undefined, true, undefined, this),
3085
- /* @__PURE__ */ jsxDEV12("div", {
3086
- className: "editorial-panel space-y-5",
3087
- children: [
3088
- /* @__PURE__ */ jsxDEV12("div", {
3089
- className: "relative",
3090
- children: [
3091
- /* @__PURE__ */ jsxDEV12(Search, {
3092
- className: "absolute top-3.5 left-4 text-muted-foreground",
3093
- size: 18
3094
- }, undefined, false, undefined, this),
3095
- /* @__PURE__ */ jsxDEV12("input", {
3096
- type: "text",
3097
- placeholder: "Search scenarios, industries, or capabilities",
3098
- value: search,
3099
- onChange: (e) => setSearch(e.target.value),
3100
- className: "w-full rounded-full border border-border bg-background px-12 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring",
3101
- "aria-label": "Search templates"
3102
- }, undefined, false, undefined, this)
3103
- ]
3104
- }, undefined, true, undefined, this),
3105
- /* @__PURE__ */ jsxDEV12("div", {
3106
- className: "flex flex-wrap gap-2",
3107
- children: [
3108
- /* @__PURE__ */ jsxDEV12("button", {
3109
- onClick: () => setSelectedTag(null),
3110
- className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
3111
- "bg-primary text-primary-foreground": selectedTag === null,
3112
- "border border-border bg-card hover:bg-card/80": selectedTag !== null
3113
- }),
3114
- "aria-pressed": selectedTag === null,
3115
- children: "All"
3116
- }, undefined, false, undefined, this),
3117
- allTags.map((tag) => /* @__PURE__ */ jsxDEV12("button", {
3118
- onClick: () => setSelectedTag(tag),
3119
- className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
3120
- "bg-primary text-primary-foreground": selectedTag === tag,
3121
- "border border-border bg-card hover:bg-card/80": selectedTag !== tag
3122
- }),
3123
- "aria-pressed": selectedTag === tag,
3124
- children: tag
3125
- }, tag, false, undefined, this))
3126
- ]
3127
- }, undefined, true, undefined, this)
3128
- ]
3129
- }, undefined, true, undefined, this)
3130
- ]
3131
- }, undefined, true, undefined, this)
3132
- }, undefined, false, undefined, this),
3133
- /* @__PURE__ */ jsxDEV12("section", {
3134
- className: "section-padding",
3135
- children: /* @__PURE__ */ jsxDEV12("div", {
3136
- className: "editorial-shell",
3137
- children: source === "registry" ? registryLoading ? /* @__PURE__ */ jsxDEV12("div", {
3138
- className: "py-12 text-center",
3139
- children: /* @__PURE__ */ jsxDEV12("p", {
3140
- className: "text-muted-foreground",
3141
- children: "Loading community templates\u2026"
3142
- }, undefined, false, undefined, this)
3143
- }, undefined, false, undefined, this) : registryTemplates.length === 0 ? /* @__PURE__ */ jsxDEV12("div", {
3144
- className: "py-12 text-center",
3145
- children: /* @__PURE__ */ jsxDEV12("p", {
3146
- className: "text-muted-foreground",
3147
- children: "No community templates found (configure `NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL`)."
3148
- }, undefined, false, undefined, this)
3149
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV12("div", {
3150
- className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
3151
- children: registryTemplates.map((t) => /* @__PURE__ */ jsxDEV12("div", {
3152
- className: "editorial-panel relative flex flex-col space-y-4 transition-colors hover:border-[color:rgb(162_79_42_/_0.55)]",
3153
- children: [
3154
- /* @__PURE__ */ jsxDEV12("div", {
3155
- children: [
3156
- /* @__PURE__ */ jsxDEV12("h3", {
3157
- className: "font-serif text-2xl tracking-[-0.03em]",
3158
- children: t.name
3159
- }, undefined, false, undefined, this),
3160
- /* @__PURE__ */ jsxDEV12("p", {
3161
- className: "mt-1 text-muted-foreground text-sm",
3162
- children: t.description
3163
- }, undefined, false, undefined, this)
3164
- ]
3165
- }, undefined, true, undefined, this),
3166
- /* @__PURE__ */ jsxDEV12("div", {
3167
- className: "flex-1 space-y-2",
3168
- children: /* @__PURE__ */ jsxDEV12("div", {
3169
- className: "flex flex-wrap gap-1",
3170
- children: t.tags.map((tag) => /* @__PURE__ */ jsxDEV12("span", {
3171
- className: "rounded-full border border-border bg-muted px-3 py-1 text-[11px] text-muted-foreground",
3172
- children: tag
3173
- }, tag, false, undefined, this))
3174
- }, undefined, false, undefined, this)
3175
- }, undefined, false, undefined, this),
3176
- /* @__PURE__ */ jsxDEV12("div", {
3177
- className: "flex gap-2 pt-4",
3178
- children: [
3179
- /* @__PURE__ */ jsxDEV12(Tooltip, {
3180
- children: [
3181
- /* @__PURE__ */ jsxDEV12(TooltipTrigger, {
3182
- asChild: true,
3183
- children: /* @__PURE__ */ jsxDEV12("button", {
3184
- className: "btn-ghost flex-1 text-center text-xs",
3185
- onClick: () => {
3186
- const local = getTemplate(t.id);
3187
- if (!local) {
3188
- setSelectedTemplateForCommand(t);
3189
- return;
3190
- }
3191
- setPreview(t.id);
3192
- },
3193
- children: "Preview"
3194
- }, undefined, false, undefined, this)
3195
- }, undefined, false, undefined, this),
3196
- /* @__PURE__ */ jsxDEV12(TooltipContent, {
3197
- children: /* @__PURE__ */ jsxDEV12("p", {
3198
- children: "Preview this template (if available locally)"
3199
- }, undefined, false, undefined, this)
3200
- }, undefined, false, undefined, this)
3201
- ]
3202
- }, undefined, true, undefined, this),
3203
- /* @__PURE__ */ jsxDEV12(Tooltip, {
3204
- children: [
3205
- /* @__PURE__ */ jsxDEV12(TooltipTrigger, {
3206
- asChild: true,
3207
- children: /* @__PURE__ */ jsxDEV12("button", {
3208
- className: "btn-primary flex-1 text-center text-xs",
3209
- onClick: () => {
3210
- captureAnalyticsEvent2(analyticsEventNames2.EXAMPLE_REPO_OPEN, {
3211
- surface: "templates",
3212
- templateId: t.id,
3213
- source: "registry"
3214
- });
3215
- setSelectedTemplateForCommand(t);
3216
- },
3217
- children: "Use Template"
3218
- }, undefined, false, undefined, this)
3219
- }, undefined, false, undefined, this),
3220
- /* @__PURE__ */ jsxDEV12(TooltipContent, {
3221
- children: /* @__PURE__ */ jsxDEV12("p", {
3222
- children: "Get CLI command"
3223
- }, undefined, false, undefined, this)
3224
- }, undefined, false, undefined, this)
3225
- ]
3226
- }, undefined, true, undefined, this)
3227
- ]
3228
- }, undefined, true, undefined, this)
3229
- ]
3230
- }, t.id, true, undefined, this))
3231
- }, undefined, false, undefined, this) : filtered.length === 0 ? /* @__PURE__ */ jsxDEV12("div", {
3232
- className: "py-12 text-center",
3233
- children: /* @__PURE__ */ jsxDEV12("p", {
3234
- className: "text-muted-foreground",
3235
- children: "No templates match your filters. Try a different search."
2888
+ /* @__PURE__ */ jsxDEV14(Search, {
2889
+ className: "absolute top-3.5 left-4 text-muted-foreground",
2890
+ size: 18
2891
+ }, undefined, false, undefined, this),
2892
+ /* @__PURE__ */ jsxDEV14("input", {
2893
+ type: "text",
2894
+ placeholder: "Search scenarios, industries, or tags",
2895
+ value: search,
2896
+ onChange: (event) => onSearchChange(event.target.value),
2897
+ className: "w-full rounded-full border border-border bg-background px-12 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring",
2898
+ "aria-label": "Search templates"
3236
2899
  }, undefined, false, undefined, this)
3237
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV12("div", {
3238
- className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
3239
- children: filtered.map((template, i) => /* @__PURE__ */ jsxDEV12("div", {
3240
- className: "editorial-panel relative flex flex-col space-y-4 transition-colors hover:border-[color:rgb(162_79_42_/_0.55)]",
3241
- children: [
3242
- "isNew" in template && template.isNew && /* @__PURE__ */ jsxDEV12("span", {
3243
- className: "absolute top-4 right-4 rounded-full bg-[color:var(--success)] px-2.5 py-1 font-medium text-[11px] text-white uppercase",
3244
- children: "New"
3245
- }, undefined, false, undefined, this),
3246
- /* @__PURE__ */ jsxDEV12("div", {
3247
- children: [
3248
- /* @__PURE__ */ jsxDEV12("h3", {
3249
- className: "font-serif text-2xl tracking-[-0.03em]",
3250
- children: template.title
3251
- }, undefined, false, undefined, this),
3252
- /* @__PURE__ */ jsxDEV12("p", {
3253
- className: "mt-1 text-muted-foreground text-sm",
3254
- children: template.description
3255
- }, undefined, false, undefined, this)
3256
- ]
3257
- }, undefined, true, undefined, this),
3258
- /* @__PURE__ */ jsxDEV12("div", {
3259
- className: "flex-1 space-y-2",
3260
- children: [
3261
- /* @__PURE__ */ jsxDEV12("p", {
3262
- className: "text-muted-foreground text-xs",
3263
- children: [
3264
- /* @__PURE__ */ jsxDEV12("span", {
3265
- className: "font-medium text-foreground",
3266
- children: "Capabilities:"
3267
- }, undefined, false, undefined, this),
3268
- " ",
3269
- template.capabilities
3270
- ]
3271
- }, undefined, true, undefined, this),
3272
- /* @__PURE__ */ jsxDEV12("div", {
3273
- className: "flex flex-wrap gap-1",
3274
- children: template.tags.map((tag) => /* @__PURE__ */ jsxDEV12("span", {
3275
- className: "rounded-full border border-border bg-muted px-3 py-1 text-[11px] text-muted-foreground",
3276
- children: tag
3277
- }, tag, false, undefined, this))
3278
- }, undefined, false, undefined, this)
3279
- ]
3280
- }, undefined, true, undefined, this),
3281
- /* @__PURE__ */ jsxDEV12("div", {
3282
- className: "flex gap-2 pt-4",
3283
- children: [
3284
- /* @__PURE__ */ jsxDEV12(Tooltip, {
3285
- children: [
3286
- /* @__PURE__ */ jsxDEV12(TooltipTrigger, {
3287
- asChild: true,
3288
- children: /* @__PURE__ */ jsxDEV12("button", {
3289
- className: "btn-ghost flex-1 text-center text-xs",
3290
- onClick: () => setPreview(template.templateId),
3291
- children: "Preview"
3292
- }, undefined, false, undefined, this)
3293
- }, undefined, false, undefined, this),
3294
- /* @__PURE__ */ jsxDEV12(TooltipContent, {
3295
- children: /* @__PURE__ */ jsxDEV12("p", {
3296
- children: "Preview this template in a modal"
3297
- }, undefined, false, undefined, this)
3298
- }, undefined, false, undefined, this)
3299
- ]
3300
- }, undefined, true, undefined, this),
3301
- /* @__PURE__ */ jsxDEV12(Tooltip, {
3302
- children: [
3303
- /* @__PURE__ */ jsxDEV12(TooltipTrigger, {
3304
- asChild: true,
3305
- children: /* @__PURE__ */ jsxDEV12("button", {
3306
- className: "btn-primary flex-1 text-center text-xs",
3307
- onClick: () => {
3308
- captureAnalyticsEvent2(analyticsEventNames2.EXAMPLE_REPO_OPEN, {
3309
- surface: "templates",
3310
- templateId: template.templateId,
3311
- source: "local"
3312
- });
3313
- setSelectedTemplateForCommand(template);
3314
- },
3315
- children: "Use Template"
3316
- }, undefined, false, undefined, this)
3317
- }, undefined, false, undefined, this),
3318
- /* @__PURE__ */ jsxDEV12(TooltipContent, {
3319
- children: /* @__PURE__ */ jsxDEV12("p", {
3320
- children: "Get CLI command"
3321
- }, undefined, false, undefined, this)
3322
- }, undefined, false, undefined, this)
3323
- ]
3324
- }, undefined, true, undefined, this)
3325
- ]
3326
- }, undefined, true, undefined, this)
3327
- ]
3328
- }, i, true, undefined, this))
3329
- }, undefined, false, undefined, this)
3330
- }, undefined, false, undefined, this)
3331
- }, undefined, false, undefined, this),
3332
- /* @__PURE__ */ jsxDEV12("section", {
3333
- className: "editorial-section bg-striped",
3334
- children: /* @__PURE__ */ jsxDEV12("div", {
3335
- className: "editorial-shell space-y-8",
2900
+ ]
2901
+ }, undefined, true, undefined, this),
2902
+ showTagFilters ? /* @__PURE__ */ jsxDEV14("div", {
2903
+ className: "space-y-3",
3336
2904
  children: [
3337
- /* @__PURE__ */ jsxDEV12("div", {
3338
- className: "max-w-3xl space-y-4",
2905
+ /* @__PURE__ */ jsxDEV14("div", {
2906
+ className: "flex flex-wrap gap-2",
3339
2907
  children: [
3340
- /* @__PURE__ */ jsxDEV12("p", {
3341
- className: "editorial-kicker",
3342
- children: "From template to real system"
3343
- }, undefined, false, undefined, this),
3344
- /* @__PURE__ */ jsxDEV12("h2", {
3345
- className: "font-serif text-4xl tracking-[-0.04em] md:text-5xl",
3346
- children: "Templates become useful when the system can absorb more context."
2908
+ /* @__PURE__ */ jsxDEV14("button", {
2909
+ onClick: () => onTagChange(null),
2910
+ className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
2911
+ "bg-primary text-primary-foreground": selectedTag === null,
2912
+ "border border-border bg-card hover:bg-card/80": selectedTag !== null
2913
+ }),
2914
+ "aria-pressed": selectedTag === null,
2915
+ children: "All"
3347
2916
  }, undefined, false, undefined, this),
3348
- /* @__PURE__ */ jsxDEV12("p", {
3349
- className: "editorial-copy",
3350
- children: "Use templates to prove the base flow, then layer integrations, knowledge, and runtime behavior on top without losing the same contract source."
3351
- }, undefined, false, undefined, this)
2917
+ visibleTagFacets.map((facet) => /* @__PURE__ */ jsxDEV14("button", {
2918
+ onClick: () => onTagChange(facet.tag),
2919
+ className: cn("rounded-full px-4 py-2 font-medium text-sm transition-colors", {
2920
+ "bg-primary text-primary-foreground": selectedTag === facet.tag,
2921
+ "border border-border bg-card hover:bg-card/80": selectedTag !== facet.tag
2922
+ }),
2923
+ "aria-pressed": selectedTag === facet.tag,
2924
+ children: facet.tag
2925
+ }, facet.tag, false, undefined, this))
3352
2926
  ]
3353
2927
  }, undefined, true, undefined, this),
3354
- /* @__PURE__ */ jsxDEV12("div", {
3355
- className: "grid gap-6 md:grid-cols-3",
3356
- children: [
3357
- /* @__PURE__ */ jsxDEV12("div", {
3358
- className: "editorial-panel space-y-4",
3359
- children: [
3360
- /* @__PURE__ */ jsxDEV12("div", {
3361
- className: "text-3xl",
3362
- children: "\uD83D\uDCB3"
3363
- }, undefined, false, undefined, this),
3364
- /* @__PURE__ */ jsxDEV12("h3", {
3365
- className: "font-serif text-2xl tracking-[-0.03em]",
3366
- children: "Add payments"
3367
- }, undefined, false, undefined, this),
3368
- /* @__PURE__ */ jsxDEV12("p", {
3369
- className: "text-muted-foreground text-sm",
3370
- children: "Connect Stripe to any template for payment processing, subscriptions, and invoicing. Type-safe and policy-enforced."
3371
- }, undefined, false, undefined, this),
3372
- /* @__PURE__ */ jsxDEV12(Link8, {
3373
- href: "/docs/integrations/stripe",
3374
- className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3375
- children: "Learn more \u2192"
3376
- }, undefined, false, undefined, this)
3377
- ]
3378
- }, undefined, true, undefined, this),
3379
- /* @__PURE__ */ jsxDEV12("div", {
3380
- className: "editorial-panel space-y-4",
3381
- children: [
3382
- /* @__PURE__ */ jsxDEV12("div", {
3383
- className: "text-3xl",
3384
- children: "\uD83D\uDCE7"
3385
- }, undefined, false, undefined, this),
3386
- /* @__PURE__ */ jsxDEV12("h3", {
3387
- className: "font-serif text-2xl tracking-[-0.03em]",
3388
- children: "Add notifications"
3389
- }, undefined, false, undefined, this),
3390
- /* @__PURE__ */ jsxDEV12("p", {
3391
- className: "text-muted-foreground text-sm",
3392
- children: "Send transactional emails via Postmark or Resend. Process inbound emails with Gmail API. SMS via Twilio."
3393
- }, undefined, false, undefined, this),
3394
- /* @__PURE__ */ jsxDEV12(Link8, {
3395
- href: "/docs/integrations",
3396
- className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3397
- children: "View integrations \u2192"
3398
- }, undefined, false, undefined, this)
3399
- ]
3400
- }, undefined, true, undefined, this),
3401
- /* @__PURE__ */ jsxDEV12("div", {
3402
- className: "editorial-panel space-y-4",
3403
- children: [
3404
- /* @__PURE__ */ jsxDEV12("div", {
3405
- className: "text-3xl",
3406
- children: "\uD83E\uDDE0"
3407
- }, undefined, false, undefined, this),
3408
- /* @__PURE__ */ jsxDEV12("h3", {
3409
- className: "font-serif text-2xl tracking-[-0.03em]",
3410
- children: "Add AI and knowledge"
3411
- }, undefined, false, undefined, this),
3412
- /* @__PURE__ */ jsxDEV12("p", {
3413
- className: "text-muted-foreground text-sm",
3414
- children: "Power templates with OpenAI, vector search via Qdrant, and structured knowledge spaces for context-aware workflows."
3415
- }, undefined, false, undefined, this),
3416
- /* @__PURE__ */ jsxDEV12(Link8, {
3417
- href: "/docs/knowledge",
3418
- className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3419
- children: "Learn about knowledge \u2192"
3420
- }, undefined, false, undefined, this)
3421
- ]
3422
- }, undefined, true, undefined, this)
3423
- ]
3424
- }, undefined, true, undefined, this),
3425
- /* @__PURE__ */ jsxDEV12("div", {
3426
- className: "pt-4 text-center",
3427
- children: [
3428
- /* @__PURE__ */ jsxDEV12("p", {
3429
- className: "mb-4 text-muted-foreground text-sm",
3430
- children: "All integrations are configured per-tenant with automatic health checks and credential rotation."
3431
- }, undefined, false, undefined, this),
3432
- /* @__PURE__ */ jsxDEV12(Link8, {
3433
- href: "/docs/architecture",
3434
- className: "btn-primary",
3435
- children: "View Architecture"
3436
- }, undefined, false, undefined, this)
3437
- ]
3438
- }, undefined, true, undefined, this)
2928
+ hiddenTagFacets.length > 0 || showAllTags ? /* @__PURE__ */ jsxDEV14("button", {
2929
+ type: "button",
2930
+ onClick: () => onShowAllTagsChange(!showAllTags),
2931
+ className: "text-muted-foreground text-sm transition-colors hover:text-foreground",
2932
+ children: showAllTags ? "Show fewer" : "More tags"
2933
+ }, undefined, false, undefined, this) : null
3439
2934
  ]
3440
- }, undefined, true, undefined, this)
3441
- }, undefined, false, undefined, this)
3442
- ]
3443
- }, undefined, true, undefined, this),
3444
- /* @__PURE__ */ jsxDEV12(TemplatePreviewModal, {
3445
- templateId: preview,
3446
- onClose: () => {
3447
- setPreview(null);
3448
- }
3449
- }, undefined, false, undefined, this),
3450
- /* @__PURE__ */ jsxDEV12(Dialog3, {
3451
- open: studioSignupModalOpen,
3452
- onOpenChange: setStudioSignupModalOpen,
3453
- children: /* @__PURE__ */ jsxDEV12(DialogContent3, {
3454
- className: "max-h-[90vh] max-w-2xl overflow-y-auto",
2935
+ }, undefined, true, undefined, this) : null
2936
+ ]
2937
+ }, undefined, true, undefined, this)
2938
+ ]
2939
+ }, undefined, true, undefined, this)
2940
+ }, undefined, false, undefined, this);
2941
+ }
2942
+
2943
+ // src/components/templates/template-new.ts
2944
+ var NEW_TEMPLATE_IDS = [
2945
+ "minimal",
2946
+ "messaging-agent-actions",
2947
+ "policy-safe-knowledge-assistant",
2948
+ "visualization-showcase"
2949
+ ];
2950
+ var NEW_TEMPLATE_ID_SET = new Set(NEW_TEMPLATE_IDS);
2951
+ function isNewTemplateId(templateId) {
2952
+ return NEW_TEMPLATE_ID_SET.has(templateId);
2953
+ }
2954
+
2955
+ // src/components/templates/template-catalog.ts
2956
+ import { listExamples, listTemplates } from "@contractspec/module.examples";
2957
+ var NEW_TEMPLATE_INDEX = new Map(NEW_TEMPLATE_IDS.map((templateId, index) => [templateId, index]));
2958
+ function buildLocalTemplateCatalog(examples = listExamples(), templates = listTemplates()) {
2959
+ const templatesById = new Map(templates.map((template) => [template.id, template]));
2960
+ return examples.filter((example) => example.meta.visibility === "public" && example.surfaces.templates).map((example) => {
2961
+ const template = templatesById.get(example.meta.key);
2962
+ const tags = Array.from(new Set(example.meta.tags.map((tag) => tag.trim()).filter(Boolean))).sort((left, right) => left.localeCompare(right));
2963
+ return {
2964
+ id: example.meta.key,
2965
+ title: example.meta.title ?? template?.name ?? example.meta.key,
2966
+ description: example.meta.summary ?? example.meta.description,
2967
+ tags,
2968
+ kind: example.meta.kind,
2969
+ stability: example.meta.stability,
2970
+ previewUrl: template?.preview?.demoUrl ?? `/sandbox?template=${encodeURIComponent(example.meta.key)}`,
2971
+ featureList: [...template?.features ?? []],
2972
+ sandboxModes: example.surfaces.sandbox.modes,
2973
+ renderTargets: [...template?.renderTargets ?? []],
2974
+ isNew: isNewTemplateId(example.meta.key),
2975
+ packageName: example.entrypoints.packageName
2976
+ };
2977
+ }).sort(compareLocalTemplateCatalogItems);
2978
+ }
2979
+ function matchesTemplateFilters(template, search, selectedTag) {
2980
+ return matchesTemplateSearch(template, search) && (selectedTag === null || template.tags.includes(selectedTag));
2981
+ }
2982
+ function matchesTemplateSearch(template, search) {
2983
+ const haystack = [
2984
+ template.title,
2985
+ template.description,
2986
+ template.tags.join(" ")
2987
+ ].join(" ").toLowerCase();
2988
+ const searchTokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
2989
+ return searchTokens.length === 0 || searchTokens.every((token) => haystack.includes(token));
2990
+ }
2991
+ function formatExampleKindLabel(kind) {
2992
+ return kind.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
2993
+ }
2994
+ function formatStabilityLabel(stability) {
2995
+ return stability.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
2996
+ }
2997
+ function compareLocalTemplateCatalogItems(left, right) {
2998
+ const leftNewIndex = NEW_TEMPLATE_INDEX.get(left.id);
2999
+ const rightNewIndex = NEW_TEMPLATE_INDEX.get(right.id);
3000
+ if (leftNewIndex !== undefined || rightNewIndex !== undefined) {
3001
+ if (leftNewIndex === undefined) {
3002
+ return 1;
3003
+ }
3004
+ if (rightNewIndex === undefined) {
3005
+ return -1;
3006
+ }
3007
+ return leftNewIndex - rightNewIndex;
3008
+ }
3009
+ return left.title.localeCompare(right.title);
3010
+ }
3011
+
3012
+ // src/components/templates/template-preview.ts
3013
+ var INLINE_TEMPLATE_PREVIEW_IDS = [
3014
+ "agent-console",
3015
+ "ai-chat-assistant",
3016
+ "analytics-dashboard",
3017
+ "crm-pipeline",
3018
+ "data-grid-showcase",
3019
+ "integration-hub",
3020
+ "marketplace",
3021
+ "saas-boilerplate",
3022
+ "visualization-showcase",
3023
+ "workflow-system"
3024
+ ];
3025
+ var INLINE_TEMPLATE_PREVIEW_SET = new Set(INLINE_TEMPLATE_PREVIEW_IDS);
3026
+ function supportsInlineTemplatePreview(templateId) {
3027
+ return INLINE_TEMPLATE_PREVIEW_SET.has(templateId);
3028
+ }
3029
+ function getLocalTemplatePreviewAction(template) {
3030
+ if (supportsInlineTemplatePreview(template.id)) {
3031
+ return { kind: "modal", templateId: template.id };
3032
+ }
3033
+ return { kind: "sandbox", href: template.previewUrl };
3034
+ }
3035
+ function getRegistryTemplatePreviewAction(template, localTemplate) {
3036
+ if (!localTemplate) {
3037
+ return { kind: "disabled" };
3038
+ }
3039
+ return getLocalTemplatePreviewAction(localTemplate);
3040
+ }
3041
+
3042
+ // src/components/templates/TemplatesCatalogSection.tsx
3043
+ import Link8 from "next/link";
3044
+ import { jsxDEV as jsxDEV15 } from "react/jsx-dev-runtime";
3045
+ "use client";
3046
+ function TemplatesCatalogSection({
3047
+ source,
3048
+ registryConfigured,
3049
+ registryLoading,
3050
+ registryHasTemplates,
3051
+ localTemplates,
3052
+ registryTemplates,
3053
+ localTemplateById,
3054
+ onPreview,
3055
+ onUseTemplate,
3056
+ hasSearch,
3057
+ selectedTag
3058
+ }) {
3059
+ const showRegistry = source === "registry" && registryConfigured;
3060
+ const emptyStateMessage = getEmptyStateMessage(hasSearch, selectedTag);
3061
+ return /* @__PURE__ */ jsxDEV15("section", {
3062
+ className: "section-padding",
3063
+ children: /* @__PURE__ */ jsxDEV15("div", {
3064
+ className: "editorial-shell",
3065
+ children: showRegistry ? registryLoading ? /* @__PURE__ */ jsxDEV15("div", {
3066
+ className: "py-12 text-center",
3067
+ children: /* @__PURE__ */ jsxDEV15("p", {
3068
+ className: "text-muted-foreground",
3069
+ children: "Loading community templates\u2026"
3070
+ }, undefined, false, undefined, this)
3071
+ }, undefined, false, undefined, this) : !registryHasTemplates ? /* @__PURE__ */ jsxDEV15("div", {
3072
+ className: "py-12 text-center",
3073
+ children: /* @__PURE__ */ jsxDEV15("p", {
3074
+ className: "text-muted-foreground",
3075
+ children: "No community templates found."
3076
+ }, undefined, false, undefined, this)
3077
+ }, undefined, false, undefined, this) : registryTemplates.length === 0 ? /* @__PURE__ */ jsxDEV15("div", {
3078
+ className: "py-12 text-center",
3079
+ children: /* @__PURE__ */ jsxDEV15("p", {
3080
+ className: "text-muted-foreground",
3081
+ children: emptyStateMessage
3082
+ }, undefined, false, undefined, this)
3083
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
3084
+ className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
3085
+ children: registryTemplates.map((template) => {
3086
+ const localTemplate = localTemplateById.get(template.id);
3087
+ const previewAction = getRegistryTemplatePreviewAction(template, localTemplate);
3088
+ return /* @__PURE__ */ jsxDEV15(TemplateCard, {
3089
+ title: template.name,
3090
+ description: template.description,
3091
+ metaBadges: ["Community"],
3092
+ tags: template.tags,
3093
+ previewAction: previewAction.kind === "modal" ? /* @__PURE__ */ jsxDEV15("button", {
3094
+ className: "btn-ghost flex-1 text-center text-xs",
3095
+ onClick: () => onPreview(template.id),
3096
+ children: "Preview"
3097
+ }, undefined, false, undefined, this) : previewAction.kind === "sandbox" ? /* @__PURE__ */ jsxDEV15(Link8, {
3098
+ href: previewAction.href,
3099
+ className: "btn-ghost flex-1 text-center text-xs",
3100
+ children: "Open Sandbox"
3101
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("button", {
3102
+ className: "btn-ghost flex-1 cursor-not-allowed text-center text-xs opacity-60",
3103
+ type: "button",
3104
+ disabled: true,
3105
+ children: "Preview Unavailable"
3106
+ }, undefined, false, undefined, this),
3107
+ useAction: /* @__PURE__ */ jsxDEV15("button", {
3108
+ className: "btn-primary flex-1 text-center text-xs",
3109
+ onClick: () => onUseTemplate(template.id, "registry"),
3110
+ children: "Use Template"
3111
+ }, undefined, false, undefined, this)
3112
+ }, template.id, false, undefined, this);
3113
+ })
3114
+ }, undefined, false, undefined, this) : localTemplates.length === 0 ? /* @__PURE__ */ jsxDEV15("div", {
3115
+ className: "py-12 text-center",
3116
+ children: /* @__PURE__ */ jsxDEV15("p", {
3117
+ className: "text-muted-foreground",
3118
+ children: emptyStateMessage
3119
+ }, undefined, false, undefined, this)
3120
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
3121
+ className: "grid gap-6 md:grid-cols-2 lg:grid-cols-3",
3122
+ children: localTemplates.map((template) => {
3123
+ const previewAction = getLocalTemplatePreviewAction(template);
3124
+ return /* @__PURE__ */ jsxDEV15(TemplateCard, {
3125
+ title: template.title,
3126
+ description: template.description,
3127
+ isNew: template.isNew,
3128
+ metaBadges: [
3129
+ formatExampleKindLabel(template.kind),
3130
+ formatStabilityLabel(template.stability)
3131
+ ],
3132
+ tags: template.tags,
3133
+ featureList: template.featureList,
3134
+ previewAction: previewAction.kind === "modal" ? /* @__PURE__ */ jsxDEV15("button", {
3135
+ className: "btn-ghost flex-1 text-center text-xs",
3136
+ onClick: () => onPreview(template.id),
3137
+ children: "Preview"
3138
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15(Link8, {
3139
+ href: previewAction.href,
3140
+ className: "btn-ghost flex-1 text-center text-xs",
3141
+ children: "Open Sandbox"
3142
+ }, undefined, false, undefined, this),
3143
+ useAction: /* @__PURE__ */ jsxDEV15("button", {
3144
+ className: "btn-primary flex-1 text-center text-xs",
3145
+ onClick: () => onUseTemplate(template.id, "local"),
3146
+ children: "Use Template"
3147
+ }, undefined, false, undefined, this)
3148
+ }, template.id, false, undefined, this);
3149
+ })
3150
+ }, undefined, false, undefined, this)
3151
+ }, undefined, false, undefined, this)
3152
+ }, undefined, false, undefined, this);
3153
+ }
3154
+ function getEmptyStateMessage(hasSearch, selectedTag) {
3155
+ if (selectedTag !== null && hasSearch) {
3156
+ return "No templates match this tag for the current search.";
3157
+ }
3158
+ if (selectedTag !== null) {
3159
+ return "No templates match this tag. Try another tag or reset filters.";
3160
+ }
3161
+ if (hasSearch) {
3162
+ return "No templates match your search. Try a different keyword.";
3163
+ }
3164
+ return "No templates match your filters. Try a different search.";
3165
+ }
3166
+
3167
+ // src/components/templates/TemplatesHeroSection.tsx
3168
+ import { jsxDEV as jsxDEV16 } from "react/jsx-dev-runtime";
3169
+ function TemplatesHeroSection({
3170
+ localTemplateCount,
3171
+ sourceCount
3172
+ }) {
3173
+ return /* @__PURE__ */ jsxDEV16("section", {
3174
+ className: "section-padding hero-gradient border-border/70 border-b",
3175
+ children: /* @__PURE__ */ jsxDEV16("div", {
3176
+ className: "editorial-shell space-y-8",
3177
+ children: [
3178
+ /* @__PURE__ */ jsxDEV16("div", {
3179
+ className: "max-w-4xl space-y-5",
3455
3180
  children: [
3456
- /* @__PURE__ */ jsxDEV12(DialogHeader2, {
3181
+ /* @__PURE__ */ jsxDEV16("p", {
3182
+ className: "editorial-kicker",
3183
+ children: "Proof through real scenarios"
3184
+ }, undefined, false, undefined, this),
3185
+ /* @__PURE__ */ jsxDEV16("h1", {
3186
+ className: "editorial-title",
3187
+ children: "Templates that show the open system in practice."
3188
+ }, undefined, false, undefined, this),
3189
+ /* @__PURE__ */ jsxDEV16("p", {
3190
+ className: "editorial-subtitle",
3191
+ children: "These scenarios are the fastest way to understand ContractSpec: explicit contracts, aligned surfaces, and an adoption path from OSS exploration into Studio deployment."
3192
+ }, undefined, false, undefined, this)
3193
+ ]
3194
+ }, undefined, true, undefined, this),
3195
+ /* @__PURE__ */ jsxDEV16("div", {
3196
+ className: "editorial-proof-strip",
3197
+ children: [
3198
+ /* @__PURE__ */ jsxDEV16("div", {
3199
+ className: "editorial-stat",
3457
3200
  children: [
3458
- /* @__PURE__ */ jsxDEV12(DialogTitle2, {
3459
- children: "Deploy in Studio"
3201
+ /* @__PURE__ */ jsxDEV16("span", {
3202
+ className: "editorial-stat-value",
3203
+ children: localTemplateCount
3460
3204
  }, undefined, false, undefined, this),
3461
- /* @__PURE__ */ jsxDEV12(DialogDescription2, {
3462
- children: "Deploy templates in ContractSpec Studio and run the full evidence-to-spec loop with your team."
3205
+ /* @__PURE__ */ jsxDEV16("span", {
3206
+ className: "editorial-label",
3207
+ children: "curated scenarios"
3463
3208
  }, undefined, false, undefined, this)
3464
3209
  ]
3465
3210
  }, undefined, true, undefined, this),
3466
- /* @__PURE__ */ jsxDEV12(StudioSignupSection, {
3467
- variant: "compact"
3468
- }, undefined, false, undefined, this)
3211
+ /* @__PURE__ */ jsxDEV16("div", {
3212
+ className: "editorial-stat",
3213
+ children: [
3214
+ /* @__PURE__ */ jsxDEV16("span", {
3215
+ className: "editorial-stat-value",
3216
+ children: sourceCount
3217
+ }, undefined, false, undefined, this),
3218
+ /* @__PURE__ */ jsxDEV16("span", {
3219
+ className: "editorial-label",
3220
+ children: "entry paths"
3221
+ }, undefined, false, undefined, this)
3222
+ ]
3223
+ }, undefined, true, undefined, this),
3224
+ /* @__PURE__ */ jsxDEV16("div", {
3225
+ className: "editorial-stat",
3226
+ children: [
3227
+ /* @__PURE__ */ jsxDEV16("span", {
3228
+ className: "editorial-stat-value",
3229
+ children: "OSS"
3230
+ }, undefined, false, undefined, this),
3231
+ /* @__PURE__ */ jsxDEV16("span", {
3232
+ className: "editorial-label",
3233
+ children: "first, Studio second"
3234
+ }, undefined, false, undefined, this)
3235
+ ]
3236
+ }, undefined, true, undefined, this)
3469
3237
  ]
3470
3238
  }, undefined, true, undefined, this)
3471
- }, undefined, false, undefined, this),
3472
- /* @__PURE__ */ jsxDEV12(Dialog3, {
3473
- open: !!selectedTemplateForCommand,
3474
- onOpenChange: () => setSelectedTemplateForCommand(null),
3475
- children: /* @__PURE__ */ jsxDEV12(DialogContent3, {
3476
- className: "max-w-md",
3239
+ ]
3240
+ }, undefined, true, undefined, this)
3241
+ }, undefined, false, undefined, this);
3242
+ }
3243
+
3244
+ // src/components/templates/TemplatesNextStepsSection.tsx
3245
+ import Link9 from "next/link";
3246
+ import { jsxDEV as jsxDEV17 } from "react/jsx-dev-runtime";
3247
+ function TemplatesNextStepsSection() {
3248
+ return /* @__PURE__ */ jsxDEV17("section", {
3249
+ className: "editorial-section bg-striped",
3250
+ children: /* @__PURE__ */ jsxDEV17("div", {
3251
+ className: "editorial-shell space-y-8",
3252
+ children: [
3253
+ /* @__PURE__ */ jsxDEV17("div", {
3254
+ className: "max-w-3xl space-y-4",
3255
+ children: [
3256
+ /* @__PURE__ */ jsxDEV17("p", {
3257
+ className: "editorial-kicker",
3258
+ children: "From template to real system"
3259
+ }, undefined, false, undefined, this),
3260
+ /* @__PURE__ */ jsxDEV17("h2", {
3261
+ className: "font-serif text-4xl tracking-[-0.04em] md:text-5xl",
3262
+ children: "Templates become useful when the system can absorb more context."
3263
+ }, undefined, false, undefined, this),
3264
+ /* @__PURE__ */ jsxDEV17("p", {
3265
+ className: "editorial-copy",
3266
+ children: "Use templates to prove the base flow, then layer integrations, knowledge, and runtime behavior on top without losing the same contract source."
3267
+ }, undefined, false, undefined, this)
3268
+ ]
3269
+ }, undefined, true, undefined, this),
3270
+ /* @__PURE__ */ jsxDEV17("div", {
3271
+ className: "grid gap-6 md:grid-cols-3",
3477
3272
  children: [
3478
- /* @__PURE__ */ jsxDEV12(DialogHeader2, {
3273
+ /* @__PURE__ */ jsxDEV17("div", {
3274
+ className: "editorial-panel space-y-4",
3479
3275
  children: [
3480
- /* @__PURE__ */ jsxDEV12(DialogTitle2, {
3481
- children: "Use this template"
3276
+ /* @__PURE__ */ jsxDEV17("div", {
3277
+ className: "text-3xl",
3278
+ children: "\uD83D\uDCB3"
3482
3279
  }, undefined, false, undefined, this),
3483
- /* @__PURE__ */ jsxDEV12(DialogDescription2, {
3484
- children: "Initialize a new project with this template using the CLI."
3280
+ /* @__PURE__ */ jsxDEV17("h3", {
3281
+ className: "font-serif text-2xl tracking-[-0.03em]",
3282
+ children: "Add payments"
3283
+ }, undefined, false, undefined, this),
3284
+ /* @__PURE__ */ jsxDEV17("p", {
3285
+ className: "text-muted-foreground text-sm",
3286
+ children: "Connect Stripe to any template for payment processing, subscriptions, and invoicing. Type-safe and policy-enforced."
3287
+ }, undefined, false, undefined, this),
3288
+ /* @__PURE__ */ jsxDEV17(Link9, {
3289
+ href: "/docs/integrations/stripe",
3290
+ className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3291
+ children: "Learn more \u2192"
3485
3292
  }, undefined, false, undefined, this)
3486
3293
  ]
3487
3294
  }, undefined, true, undefined, this),
3488
- /* @__PURE__ */ jsxDEV12("div", {
3489
- className: "space-y-4 pt-4",
3295
+ /* @__PURE__ */ jsxDEV17("div", {
3296
+ className: "editorial-panel space-y-4",
3490
3297
  children: [
3491
- /* @__PURE__ */ jsxDEV12("div", {
3492
- className: "rounded-md border border-zinc-800 bg-zinc-950 p-4 font-mono text-sm text-zinc-50",
3493
- children: [
3494
- "npx contractspec init --template ",
3495
- commandId
3496
- ]
3497
- }, undefined, true, undefined, this),
3498
- /* @__PURE__ */ jsxDEV12("div", {
3499
- className: "flex gap-2",
3500
- children: /* @__PURE__ */ jsxDEV12("button", {
3501
- className: "btn-secondary w-full",
3502
- onClick: () => {
3503
- navigator.clipboard.writeText(`npx contractspec init --template ${commandId}`);
3504
- captureAnalyticsEvent2(analyticsEventNames2.COPY_COMMAND_CLICK, {
3505
- surface: "templates",
3506
- templateId: commandId,
3507
- filename: "templates-cli"
3508
- });
3509
- },
3510
- children: "Copy Command"
3511
- }, undefined, false, undefined, this)
3298
+ /* @__PURE__ */ jsxDEV17("div", {
3299
+ className: "text-3xl",
3300
+ children: "\uD83D\uDCE7"
3512
3301
  }, undefined, false, undefined, this),
3513
- /* @__PURE__ */ jsxDEV12("div", {
3514
- className: "relative",
3515
- children: [
3516
- /* @__PURE__ */ jsxDEV12("div", {
3517
- className: "absolute inset-0 flex items-center",
3518
- children: /* @__PURE__ */ jsxDEV12("span", {
3519
- className: "w-full border-border border-t"
3520
- }, undefined, false, undefined, this)
3521
- }, undefined, false, undefined, this),
3522
- /* @__PURE__ */ jsxDEV12("div", {
3523
- className: "relative flex justify-center text-xs uppercase",
3524
- children: /* @__PURE__ */ jsxDEV12("span", {
3525
- className: "bg-background px-2 text-muted-foreground",
3526
- children: "Or"
3527
- }, undefined, false, undefined, this)
3528
- }, undefined, false, undefined, this)
3529
- ]
3530
- }, undefined, true, undefined, this),
3531
- /* @__PURE__ */ jsxDEV12("button", {
3532
- className: "btn-ghost w-full text-sm",
3533
- onClick: () => {
3534
- captureAnalyticsEvent2(analyticsEventNames2.CTA_STUDIO_CLICK, {
3535
- surface: "templates",
3536
- templateId: commandId
3537
- });
3538
- setSelectedTemplateForCommand(null);
3539
- setStudioSignupModalOpen(true);
3540
- },
3541
- children: "Deploy to Studio"
3302
+ /* @__PURE__ */ jsxDEV17("h3", {
3303
+ className: "font-serif text-2xl tracking-[-0.03em]",
3304
+ children: "Add notifications"
3305
+ }, undefined, false, undefined, this),
3306
+ /* @__PURE__ */ jsxDEV17("p", {
3307
+ className: "text-muted-foreground text-sm",
3308
+ children: "Send transactional emails via Postmark or Resend. Process inbound emails with Gmail API. SMS via Twilio."
3309
+ }, undefined, false, undefined, this),
3310
+ /* @__PURE__ */ jsxDEV17(Link9, {
3311
+ href: "/docs/integrations",
3312
+ className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3313
+ children: "View integrations \u2192"
3314
+ }, undefined, false, undefined, this)
3315
+ ]
3316
+ }, undefined, true, undefined, this),
3317
+ /* @__PURE__ */ jsxDEV17("div", {
3318
+ className: "editorial-panel space-y-4",
3319
+ children: [
3320
+ /* @__PURE__ */ jsxDEV17("div", {
3321
+ className: "text-3xl",
3322
+ children: "\uD83E\uDDE0"
3323
+ }, undefined, false, undefined, this),
3324
+ /* @__PURE__ */ jsxDEV17("h3", {
3325
+ className: "font-serif text-2xl tracking-[-0.03em]",
3326
+ children: "Add AI and knowledge"
3327
+ }, undefined, false, undefined, this),
3328
+ /* @__PURE__ */ jsxDEV17("p", {
3329
+ className: "text-muted-foreground text-sm",
3330
+ children: "Power templates with OpenAI, vector search via Qdrant, and structured knowledge spaces for context-aware workflows."
3331
+ }, undefined, false, undefined, this),
3332
+ /* @__PURE__ */ jsxDEV17(Link9, {
3333
+ href: "/docs/knowledge",
3334
+ className: "font-medium text-[color:var(--blue)] text-sm hover:opacity-80",
3335
+ children: "Learn about knowledge \u2192"
3542
3336
  }, undefined, false, undefined, this)
3543
3337
  ]
3544
3338
  }, undefined, true, undefined, this)
3545
3339
  ]
3340
+ }, undefined, true, undefined, this),
3341
+ /* @__PURE__ */ jsxDEV17("div", {
3342
+ className: "pt-4 text-center",
3343
+ children: [
3344
+ /* @__PURE__ */ jsxDEV17("p", {
3345
+ className: "mb-4 text-muted-foreground text-sm",
3346
+ children: "All integrations are configured per-tenant with automatic health checks and credential rotation."
3347
+ }, undefined, false, undefined, this),
3348
+ /* @__PURE__ */ jsxDEV17(Link9, {
3349
+ href: "/docs/architecture",
3350
+ className: "btn-primary",
3351
+ children: "View Architecture"
3352
+ }, undefined, false, undefined, this)
3353
+ ]
3546
3354
  }, undefined, true, undefined, this)
3355
+ ]
3356
+ }, undefined, true, undefined, this)
3357
+ }, undefined, false, undefined, this);
3358
+ }
3359
+
3360
+ // src/components/templates/TemplatesPreviewModal.tsx
3361
+ import { Dialog as Dialog3, DialogContent as DialogContent3 } from "@contractspec/lib.ui-kit-web/ui/dialog";
3362
+ import { ScrollArea } from "@contractspec/lib.ui-kit-web/ui/scroll-area";
3363
+ import { TemplateRuntimeProvider } from "@contractspec/module.examples";
3364
+ import { jsxDEV as jsxDEV18 } from "react/jsx-dev-runtime";
3365
+ "use client";
3366
+ function TemplatePreviewModal({
3367
+ templateId,
3368
+ onClose
3369
+ }) {
3370
+ if (!supportsInlineTemplatePreview(templateId)) {
3371
+ return null;
3372
+ }
3373
+ return /* @__PURE__ */ jsxDEV18(Dialog3, {
3374
+ open: true,
3375
+ onOpenChange: (open) => !open && onClose(),
3376
+ children: /* @__PURE__ */ jsxDEV18(DialogContent3, {
3377
+ className: "mb-8 flex h-[calc(100vh-2rem)] min-w-[calc(100vw-2rem)] flex-col justify-between gap-0 p-0",
3378
+ children: /* @__PURE__ */ jsxDEV18(ScrollArea, {
3379
+ className: "flex flex-col justify-between overflow-hidden",
3380
+ children: /* @__PURE__ */ jsxDEV18(TemplateRuntimeProvider, {
3381
+ templateId,
3382
+ projectId: `marketing-preview-${templateId}`,
3383
+ children: /* @__PURE__ */ jsxDEV18(TemplatePreviewContent, {
3384
+ templateId
3385
+ }, undefined, false, undefined, this)
3386
+ }, templateId, false, undefined, this)
3387
+ }, undefined, false, undefined, this)
3388
+ }, undefined, false, undefined, this)
3389
+ }, undefined, false, undefined, this);
3390
+ }
3391
+
3392
+ // src/components/templates/TemplatesOverlays.tsx
3393
+ import {
3394
+ Dialog as Dialog4,
3395
+ DialogContent as DialogContent4,
3396
+ DialogDescription as DialogDescription3,
3397
+ DialogHeader as DialogHeader3,
3398
+ DialogTitle as DialogTitle3
3399
+ } from "@contractspec/lib.ui-kit-web/ui/dialog";
3400
+ import { jsxDEV as jsxDEV19, Fragment } from "react/jsx-dev-runtime";
3401
+ "use client";
3402
+ function TemplatesOverlays({
3403
+ previewTemplateId,
3404
+ onPreviewClose,
3405
+ studioSignupModalOpen,
3406
+ onStudioSignupModalOpenChange,
3407
+ selectedTemplateId,
3408
+ onTemplateCommandClose,
3409
+ onDeployStudio
3410
+ }) {
3411
+ return /* @__PURE__ */ jsxDEV19(Fragment, {
3412
+ children: [
3413
+ previewTemplateId ? /* @__PURE__ */ jsxDEV19(TemplatePreviewModal, {
3414
+ templateId: previewTemplateId,
3415
+ onClose: onPreviewClose
3416
+ }, undefined, false, undefined, this) : null,
3417
+ /* @__PURE__ */ jsxDEV19(Dialog4, {
3418
+ open: studioSignupModalOpen,
3419
+ onOpenChange: onStudioSignupModalOpenChange,
3420
+ children: /* @__PURE__ */ jsxDEV19(DialogContent4, {
3421
+ className: "max-h-[90vh] max-w-2xl overflow-y-auto",
3422
+ children: [
3423
+ /* @__PURE__ */ jsxDEV19(DialogHeader3, {
3424
+ children: [
3425
+ /* @__PURE__ */ jsxDEV19(DialogTitle3, {
3426
+ children: "Deploy in Studio"
3427
+ }, undefined, false, undefined, this),
3428
+ /* @__PURE__ */ jsxDEV19(DialogDescription3, {
3429
+ children: "Deploy templates in ContractSpec Studio and run the full evidence-to-spec loop with your team."
3430
+ }, undefined, false, undefined, this)
3431
+ ]
3432
+ }, undefined, true, undefined, this),
3433
+ /* @__PURE__ */ jsxDEV19(StudioSignupSection, {
3434
+ variant: "compact"
3435
+ }, undefined, false, undefined, this)
3436
+ ]
3437
+ }, undefined, true, undefined, this)
3438
+ }, undefined, false, undefined, this),
3439
+ /* @__PURE__ */ jsxDEV19(TemplateCommandDialog, {
3440
+ templateId: selectedTemplateId,
3441
+ onClose: onTemplateCommandClose,
3442
+ onDeployStudio
3443
+ }, undefined, false, undefined, this)
3444
+ ]
3445
+ }, undefined, true, undefined, this);
3446
+ }
3447
+
3448
+ // src/components/templates/template-filters.ts
3449
+ function buildTemplateFilterState(templates, search, selectedTag, getCandidate) {
3450
+ const searchScopedTemplates = templates.filter((template) => matchesTemplateSearch(getCandidate(template), search));
3451
+ const finalTemplates = selectedTag === null ? searchScopedTemplates : searchScopedTemplates.filter((template) => getCandidate(template).tags.includes(selectedTag));
3452
+ return {
3453
+ searchScopedTemplates,
3454
+ finalTemplates,
3455
+ tagFacets: buildTemplateTagFacets(searchScopedTemplates, getCandidate)
3456
+ };
3457
+ }
3458
+ function buildTemplateTagFacets(templates, getCandidate) {
3459
+ const counts = new Map;
3460
+ for (const template of templates) {
3461
+ for (const tag of new Set(getCandidate(template).tags)) {
3462
+ counts.set(tag, (counts.get(tag) ?? 0) + 1);
3463
+ }
3464
+ }
3465
+ return [...counts.entries()].map(([tag, count]) => ({ tag, count })).sort((left, right) => right.count - left.count || left.tag.localeCompare(right.tag));
3466
+ }
3467
+
3468
+ // src/components/templates/template-source.ts
3469
+ function isRegistryConfigured(registryUrl) {
3470
+ return Boolean(registryUrl?.trim());
3471
+ }
3472
+ function getAvailableTemplateSources(registryUrl) {
3473
+ return isRegistryConfigured(registryUrl) ? ["local", "registry"] : ["local"];
3474
+ }
3475
+
3476
+ // src/components/templates/template-tag-visibility.ts
3477
+ var DEFAULT_VISIBLE_TEMPLATE_TAGS = 10;
3478
+ function getVisibleTemplateTagFacets(tagFacets, selectedTag, expanded, visibleCount = DEFAULT_VISIBLE_TEMPLATE_TAGS) {
3479
+ if (expanded) {
3480
+ return {
3481
+ visibleTagFacets: pinSelectedTagFacet(tagFacets, selectedTag),
3482
+ hiddenTagFacets: []
3483
+ };
3484
+ }
3485
+ const visibleTagFacets = pinSelectedTagFacet(tagFacets.slice(0, visibleCount), selectedTag, tagFacets);
3486
+ const visibleTags = new Set(visibleTagFacets.map((facet) => facet.tag));
3487
+ return {
3488
+ visibleTagFacets,
3489
+ hiddenTagFacets: tagFacets.filter((facet) => !visibleTags.has(facet.tag))
3490
+ };
3491
+ }
3492
+ function pinSelectedTagFacet(tagFacets, selectedTag, fallbackTagFacets = tagFacets) {
3493
+ if (selectedTag === null || tagFacets.some((facet) => facet.tag === selectedTag)) {
3494
+ return [...tagFacets];
3495
+ }
3496
+ return [
3497
+ ...tagFacets,
3498
+ fallbackTagFacets.find((facet) => facet.tag === selectedTag) ?? {
3499
+ tag: selectedTag,
3500
+ count: 0
3501
+ }
3502
+ ];
3503
+ }
3504
+
3505
+ // src/components/templates/useTemplateBrowseState.ts
3506
+ import { useRegistryTemplates } from "@contractspec/lib.example-shared-ui";
3507
+ import { useEffect, useMemo, useState as useState2 } from "react";
3508
+ "use client";
3509
+ var REGISTRY_URL = process.env.NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL;
3510
+ function useTemplateBrowseState() {
3511
+ const [selectedTag, setSelectedTag] = useState2(null);
3512
+ const [search, setSearch] = useState2("");
3513
+ const [source, setSource] = useState2("local");
3514
+ const [showAllTags, setShowAllTags] = useState2(false);
3515
+ const registryConfigured = isRegistryConfigured(REGISTRY_URL);
3516
+ const availableSources = getAvailableTemplateSources(REGISTRY_URL);
3517
+ const localTemplates = useMemo(() => buildLocalTemplateCatalog(), []);
3518
+ const localTemplateById = useMemo(() => new Map(localTemplates.map((template) => [template.id, template])), [localTemplates]);
3519
+ const { data: registryTemplates = [], isLoading: registryLoading } = useRegistryTemplates();
3520
+ const localFilterState = useMemo(() => buildTemplateFilterState(localTemplates, search, selectedTag, (template) => ({
3521
+ title: template.title,
3522
+ description: template.description,
3523
+ tags: template.tags
3524
+ })), [localTemplates, search, selectedTag]);
3525
+ const registryFilterState = useMemo(() => buildTemplateFilterState(registryTemplates, search, selectedTag, (template) => ({
3526
+ title: template.name,
3527
+ description: template.description,
3528
+ tags: template.tags
3529
+ })), [registryTemplates, search, selectedTag]);
3530
+ const activeFilterState = source === "registry" ? registryFilterState : localFilterState;
3531
+ const suppressTagRail = source === "registry" && (registryLoading || registryTemplates.length === 0);
3532
+ const { visibleTagFacets, hiddenTagFacets } = useMemo(() => getVisibleTemplateTagFacets(activeFilterState.tagFacets, selectedTag, showAllTags), [activeFilterState.tagFacets, selectedTag, showAllTags]);
3533
+ const showTagFilters = !suppressTagRail && (visibleTagFacets.length > 0 || hiddenTagFacets.length > 0);
3534
+ useEffect(() => {
3535
+ setShowAllTags(false);
3536
+ }, [search, showTagFilters, source]);
3537
+ return {
3538
+ selectedTag,
3539
+ setSelectedTag,
3540
+ search,
3541
+ setSearch,
3542
+ source,
3543
+ setSource,
3544
+ showAllTags,
3545
+ setShowAllTags,
3546
+ registryConfigured,
3547
+ availableSources,
3548
+ localTemplates,
3549
+ localTemplateById,
3550
+ registryTemplates,
3551
+ registryLoading,
3552
+ localFilterState,
3553
+ registryFilterState,
3554
+ visibleTagFacets,
3555
+ hiddenTagFacets,
3556
+ showTagFilters
3557
+ };
3558
+ }
3559
+
3560
+ // src/components/templates/TemplatesClientPage.tsx
3561
+ import {
3562
+ analyticsEventNames as analyticsEventNames3,
3563
+ captureAnalyticsEvent as captureAnalyticsEvent3
3564
+ } from "@contractspec/bundle.library/libs/posthog/client";
3565
+ import { useState as useState3 } from "react";
3566
+ import { jsxDEV as jsxDEV20, Fragment as Fragment2 } from "react/jsx-dev-runtime";
3567
+ "use client";
3568
+ var TemplatesPage = () => {
3569
+ const [previewTemplateId, setPreviewTemplateId] = useState3(null);
3570
+ const [studioSignupModalOpen, setStudioSignupModalOpen] = useState3(false);
3571
+ const [selectedTemplateId, setSelectedTemplateId] = useState3(null);
3572
+ const {
3573
+ selectedTag,
3574
+ setSelectedTag,
3575
+ search,
3576
+ setSearch,
3577
+ source,
3578
+ setSource,
3579
+ showAllTags,
3580
+ setShowAllTags,
3581
+ registryConfigured,
3582
+ availableSources,
3583
+ localTemplates,
3584
+ localTemplateById,
3585
+ registryTemplates,
3586
+ registryLoading,
3587
+ localFilterState,
3588
+ registryFilterState,
3589
+ visibleTagFacets,
3590
+ hiddenTagFacets,
3591
+ showTagFilters
3592
+ } = useTemplateBrowseState();
3593
+ return /* @__PURE__ */ jsxDEV20(Fragment2, {
3594
+ children: [
3595
+ /* @__PURE__ */ jsxDEV20("main", {
3596
+ children: [
3597
+ /* @__PURE__ */ jsxDEV20(TemplatesHeroSection, {
3598
+ localTemplateCount: localTemplates.length,
3599
+ sourceCount: availableSources.length
3600
+ }, undefined, false, undefined, this),
3601
+ /* @__PURE__ */ jsxDEV20(TemplatesBrowseControls, {
3602
+ registryConfigured,
3603
+ availableSources,
3604
+ source,
3605
+ onSourceChange: setSource,
3606
+ search,
3607
+ onSearchChange: setSearch,
3608
+ selectedTag,
3609
+ onTagChange: setSelectedTag,
3610
+ showTagFilters,
3611
+ visibleTagFacets,
3612
+ hiddenTagFacets,
3613
+ showAllTags,
3614
+ onShowAllTagsChange: setShowAllTags
3615
+ }, undefined, false, undefined, this),
3616
+ /* @__PURE__ */ jsxDEV20(TemplatesCatalogSection, {
3617
+ source,
3618
+ registryConfigured,
3619
+ registryLoading,
3620
+ registryHasTemplates: registryTemplates.length > 0,
3621
+ localTemplates: localFilterState.finalTemplates,
3622
+ registryTemplates: registryFilterState.finalTemplates,
3623
+ localTemplateById,
3624
+ onPreview: setPreviewTemplateId,
3625
+ onUseTemplate: (templateId, templateSource) => {
3626
+ captureAnalyticsEvent3(analyticsEventNames3.EXAMPLE_REPO_OPEN, {
3627
+ surface: "templates",
3628
+ templateId,
3629
+ source: templateSource
3630
+ });
3631
+ setSelectedTemplateId(templateId);
3632
+ },
3633
+ hasSearch: search.trim().length > 0,
3634
+ selectedTag
3635
+ }, undefined, false, undefined, this),
3636
+ /* @__PURE__ */ jsxDEV20(TemplatesNextStepsSection, {}, undefined, false, undefined, this)
3637
+ ]
3638
+ }, undefined, true, undefined, this),
3639
+ /* @__PURE__ */ jsxDEV20(TemplatesOverlays, {
3640
+ previewTemplateId,
3641
+ onPreviewClose: () => setPreviewTemplateId(null),
3642
+ studioSignupModalOpen,
3643
+ onStudioSignupModalOpenChange: setStudioSignupModalOpen,
3644
+ selectedTemplateId,
3645
+ onTemplateCommandClose: () => setSelectedTemplateId(null),
3646
+ onDeployStudio: () => {
3647
+ setSelectedTemplateId(null);
3648
+ setStudioSignupModalOpen(true);
3649
+ }
3547
3650
  }, undefined, false, undefined, this)
3548
3651
  ]
3549
3652
  }, undefined, true, undefined, this);
@@ -3562,9 +3665,9 @@ import {
3562
3665
  MarketingSection
3563
3666
  } from "@contractspec/lib.design-system";
3564
3667
  import { HStack, VStack } from "@contractspec/lib.ui-kit-web/ui/stack";
3565
- import { listTemplates } from "@contractspec/module.examples";
3566
- import { useMemo as useMemo2, useState as useState3 } from "react";
3567
- import { jsxDEV as jsxDEV13, Fragment } from "react/jsx-dev-runtime";
3668
+ import { listTemplates as listTemplates2 } from "@contractspec/module.examples";
3669
+ import { useMemo as useMemo2, useState as useState4 } from "react";
3670
+ import { jsxDEV as jsxDEV21, Fragment as Fragment3 } from "react/jsx-dev-runtime";
3568
3671
  "use client";
3569
3672
  function matchesQuery(t, query) {
3570
3673
  const q = query.trim().toLowerCase();
@@ -3574,38 +3677,38 @@ function matchesQuery(t, query) {
3574
3677
  return hay.includes(q);
3575
3678
  }
3576
3679
  function TemplatesMarketingPage() {
3577
- const [query, setQuery] = useState3("");
3578
- const templates2 = useMemo2(() => listTemplates(), []);
3579
- const filtered = useMemo2(() => templates2.filter((t) => matchesQuery(t, query)), [templates2, query]);
3580
- return /* @__PURE__ */ jsxDEV13(Fragment, {
3680
+ const [query, setQuery] = useState4("");
3681
+ const templates = useMemo2(() => listTemplates2(), []);
3682
+ const filtered = useMemo2(() => templates.filter((t) => matchesQuery(t, query)), [templates, query]);
3683
+ return /* @__PURE__ */ jsxDEV21(Fragment3, {
3581
3684
  children: [
3582
- /* @__PURE__ */ jsxDEV13(MarketingSection, {
3685
+ /* @__PURE__ */ jsxDEV21(MarketingSection, {
3583
3686
  tone: "default",
3584
- children: /* @__PURE__ */ jsxDEV13(VStack, {
3687
+ children: /* @__PURE__ */ jsxDEV21(VStack, {
3585
3688
  as: "header",
3586
3689
  gap: "lg",
3587
3690
  align: "center",
3588
3691
  children: [
3589
- /* @__PURE__ */ jsxDEV13(VStack, {
3692
+ /* @__PURE__ */ jsxDEV21(VStack, {
3590
3693
  gap: "sm",
3591
3694
  align: "center",
3592
3695
  children: [
3593
- /* @__PURE__ */ jsxDEV13(ButtonLink, {
3696
+ /* @__PURE__ */ jsxDEV21(ButtonLink, {
3594
3697
  href: "/docs",
3595
3698
  variant: "ghost",
3596
3699
  children: "Docs"
3597
3700
  }, undefined, false, undefined, this),
3598
- /* @__PURE__ */ jsxDEV13(ButtonLink, {
3701
+ /* @__PURE__ */ jsxDEV21(ButtonLink, {
3599
3702
  href: "/sandbox",
3600
3703
  variant: "ghost",
3601
3704
  children: "Open Sandbox"
3602
3705
  }, undefined, false, undefined, this)
3603
3706
  ]
3604
3707
  }, undefined, true, undefined, this),
3605
- /* @__PURE__ */ jsxDEV13(VStack, {
3708
+ /* @__PURE__ */ jsxDEV21(VStack, {
3606
3709
  gap: "sm",
3607
3710
  align: "center",
3608
- children: /* @__PURE__ */ jsxDEV13(ButtonLink, {
3711
+ children: /* @__PURE__ */ jsxDEV21(ButtonLink, {
3609
3712
  href: "/templates",
3610
3713
  variant: "default",
3611
3714
  children: "Templates"
@@ -3614,25 +3717,25 @@ function TemplatesMarketingPage() {
3614
3717
  ]
3615
3718
  }, undefined, true, undefined, this)
3616
3719
  }, undefined, false, undefined, this),
3617
- /* @__PURE__ */ jsxDEV13(MarketingSection, {
3720
+ /* @__PURE__ */ jsxDEV21(MarketingSection, {
3618
3721
  tone: "muted",
3619
- children: /* @__PURE__ */ jsxDEV13(VStack, {
3722
+ children: /* @__PURE__ */ jsxDEV21(VStack, {
3620
3723
  gap: "lg",
3621
3724
  children: [
3622
- /* @__PURE__ */ jsxDEV13(VStack, {
3725
+ /* @__PURE__ */ jsxDEV21(VStack, {
3623
3726
  gap: "sm",
3624
- children: /* @__PURE__ */ jsxDEV13(ButtonLink, {
3727
+ children: /* @__PURE__ */ jsxDEV21(ButtonLink, {
3625
3728
  href: "/templates",
3626
3729
  variant: "ghost",
3627
3730
  children: "Browse all examples"
3628
3731
  }, undefined, false, undefined, this)
3629
3732
  }, undefined, false, undefined, this),
3630
- /* @__PURE__ */ jsxDEV13(HStack, {
3733
+ /* @__PURE__ */ jsxDEV21(HStack, {
3631
3734
  gap: "md",
3632
3735
  align: "center",
3633
3736
  justify: "between",
3634
3737
  wrap: "wrap",
3635
- children: /* @__PURE__ */ jsxDEV13(Input2, {
3738
+ children: /* @__PURE__ */ jsxDEV21(Input2, {
3636
3739
  "aria-label": "Search templates and examples",
3637
3740
  placeholder: "Search templates and examples\u2026",
3638
3741
  value: query,
@@ -3642,52 +3745,52 @@ function TemplatesMarketingPage() {
3642
3745
  ]
3643
3746
  }, undefined, true, undefined, this)
3644
3747
  }, undefined, false, undefined, this),
3645
- /* @__PURE__ */ jsxDEV13(MarketingSection, {
3748
+ /* @__PURE__ */ jsxDEV21(MarketingSection, {
3646
3749
  tone: "default",
3647
- children: /* @__PURE__ */ jsxDEV13(VStack, {
3750
+ children: /* @__PURE__ */ jsxDEV21(VStack, {
3648
3751
  gap: "lg",
3649
- children: /* @__PURE__ */ jsxDEV13(HStack, {
3752
+ children: /* @__PURE__ */ jsxDEV21(HStack, {
3650
3753
  gap: "md",
3651
3754
  wrap: "wrap",
3652
- children: filtered.map((t) => /* @__PURE__ */ jsxDEV13(MarketingCard, {
3755
+ children: filtered.map((t) => /* @__PURE__ */ jsxDEV21(MarketingCard, {
3653
3756
  className: "w-full md:w-[calc(50%-0.75rem)] lg:w-[calc(33.333%-1rem)]",
3654
3757
  children: [
3655
- /* @__PURE__ */ jsxDEV13(MarketingCardHeader, {
3758
+ /* @__PURE__ */ jsxDEV21(MarketingCardHeader, {
3656
3759
  children: [
3657
- /* @__PURE__ */ jsxDEV13(MarketingCardTitle, {
3760
+ /* @__PURE__ */ jsxDEV21(MarketingCardTitle, {
3658
3761
  children: [
3659
3762
  t.icon,
3660
3763
  " ",
3661
3764
  t.name
3662
3765
  ]
3663
3766
  }, undefined, true, undefined, this),
3664
- /* @__PURE__ */ jsxDEV13(MarketingCardDescription, {
3767
+ /* @__PURE__ */ jsxDEV21(MarketingCardDescription, {
3665
3768
  children: t.description
3666
3769
  }, undefined, false, undefined, this)
3667
3770
  ]
3668
3771
  }, undefined, true, undefined, this),
3669
- /* @__PURE__ */ jsxDEV13(MarketingCardContent, {
3670
- children: /* @__PURE__ */ jsxDEV13(VStack, {
3772
+ /* @__PURE__ */ jsxDEV21(MarketingCardContent, {
3773
+ children: /* @__PURE__ */ jsxDEV21(VStack, {
3671
3774
  gap: "md",
3672
3775
  children: [
3673
- /* @__PURE__ */ jsxDEV13(HStack, {
3776
+ /* @__PURE__ */ jsxDEV21(HStack, {
3674
3777
  gap: "sm",
3675
3778
  wrap: "wrap",
3676
- children: t.tags.slice(0, 6).map((tag) => /* @__PURE__ */ jsxDEV13(ButtonLink, {
3779
+ children: t.tags.slice(0, 6).map((tag) => /* @__PURE__ */ jsxDEV21(ButtonLink, {
3677
3780
  href: `/templates?tag=${encodeURIComponent(tag)}`,
3678
3781
  variant: "ghost",
3679
3782
  children: tag
3680
3783
  }, `${t.id}-${tag}`, false, undefined, this))
3681
3784
  }, undefined, false, undefined, this),
3682
- /* @__PURE__ */ jsxDEV13(HStack, {
3785
+ /* @__PURE__ */ jsxDEV21(HStack, {
3683
3786
  gap: "sm",
3684
3787
  justify: "between",
3685
3788
  wrap: "wrap",
3686
3789
  children: [
3687
- /* @__PURE__ */ jsxDEV13(ButtonLinkToSandbox, {
3790
+ /* @__PURE__ */ jsxDEV21(ButtonLinkToSandbox, {
3688
3791
  templateId: t.id
3689
3792
  }, undefined, false, undefined, this),
3690
- /* @__PURE__ */ jsxDEV13(Button3, {
3793
+ /* @__PURE__ */ jsxDEV21(Button3, {
3691
3794
  variant: "outline",
3692
3795
  onClick: () => {
3693
3796
  return;
@@ -3709,7 +3812,7 @@ function TemplatesMarketingPage() {
3709
3812
  }, undefined, true, undefined, this);
3710
3813
  }
3711
3814
  function ButtonLinkToSandbox({ templateId }) {
3712
- return /* @__PURE__ */ jsxDEV13(ButtonLink, {
3815
+ return /* @__PURE__ */ jsxDEV21(ButtonLink, {
3713
3816
  href: `/sandbox?template=${encodeURIComponent(templateId)}`,
3714
3817
  variant: "default",
3715
3818
  children: "Preview"