@contractspec/bundle.marketing 1.12.0 → 1.14.0
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.
- package/.turbo/turbo-build.log +146 -175
- package/.turbo/turbo-prebuild.log +1 -0
- package/CHANGELOG.md +57 -0
- package/dist/browser/components/marketing/ChangelogPage.js +92 -0
- package/dist/browser/components/marketing/CofounderPage.js +581 -0
- package/dist/browser/components/marketing/ContactClient.js +1379 -0
- package/dist/browser/components/marketing/ContributePage.js +487 -0
- package/dist/browser/components/marketing/DesignPartnerPage.js +272 -0
- package/dist/browser/components/marketing/LandingPage.js +629 -0
- package/dist/browser/components/marketing/PricingClient.js +1972 -0
- package/dist/browser/components/marketing/ProductClientPage.js +563 -0
- package/dist/browser/components/marketing/index.js +4818 -0
- package/dist/browser/components/marketing/pricing-thinking-modal.js +258 -0
- package/dist/browser/components/marketing/sections/AudienceSection.js +90 -0
- package/dist/browser/components/marketing/sections/CorePositioningSection.js +72 -0
- package/dist/browser/components/marketing/sections/CtaSection.js +67 -0
- package/dist/browser/components/marketing/sections/DevelopersSection.js +50 -0
- package/dist/browser/components/marketing/sections/FearsSection.js +105 -0
- package/dist/browser/components/marketing/sections/HeroMarketingSection.js +93 -0
- package/dist/browser/components/marketing/sections/IconGridSection.js +63 -0
- package/dist/browser/components/marketing/sections/OutputsSection.js +116 -0
- package/dist/browser/components/marketing/sections/ProblemSection.js +103 -0
- package/dist/browser/components/marketing/sections/SolutionSection.js +103 -0
- package/dist/browser/components/marketing/sections/StepsSection.js +109 -0
- package/dist/browser/components/marketing/waitlist-section.js +1104 -0
- package/dist/browser/components/templates/TemplatesClientPage.js +5662 -0
- package/dist/browser/components/templates/TemplatesPage.js +177 -0
- package/dist/browser/components/templates/TemplatesPreviewModal.js +124 -0
- package/dist/browser/components/templates/index.js +5831 -0
- package/dist/browser/index.js +6485 -0
- package/dist/browser/libs/email/client.js +122 -0
- package/dist/browser/libs/email/contact.js +190 -0
- package/dist/browser/libs/email/newsletter.js +215 -0
- package/dist/browser/libs/email/types.js +2 -0
- package/dist/browser/libs/email/utils.js +16 -0
- package/dist/browser/libs/email/waitlist-application.js +295 -0
- package/dist/browser/libs/email/waitlist.js +225 -0
- package/dist/browser/libs/pricing-examples.js +26 -0
- package/dist/browser/registry/engine.js +5293 -0
- package/dist/browser/registry/factory.js +52 -0
- package/dist/browser/registry/index.js +5358 -0
- package/dist/browser/registry/registry-docs.js +343 -0
- package/dist/browser/registry/registry-landing.js +4937 -0
- package/dist/browser/registry/registry.js +5279 -0
- package/dist/browser/registry/types.js +0 -0
- package/dist/browser/registry/utils.js +5340 -0
- package/dist/components/marketing/ChangelogPage.d.ts +11 -17
- package/dist/components/marketing/ChangelogPage.d.ts.map +1 -1
- package/dist/components/marketing/ChangelogPage.js +84 -62
- package/dist/components/marketing/CofounderPage.d.ts +1 -6
- package/dist/components/marketing/CofounderPage.d.ts.map +1 -1
- package/dist/components/marketing/CofounderPage.js +544 -436
- package/dist/components/marketing/ContactClient.d.ts +1 -6
- package/dist/components/marketing/ContactClient.d.ts.map +1 -1
- package/dist/components/marketing/ContactClient.js +1371 -155
- package/dist/components/marketing/ContributePage.d.ts +3 -8
- package/dist/components/marketing/ContributePage.d.ts.map +1 -1
- package/dist/components/marketing/ContributePage.js +478 -358
- package/dist/components/marketing/DesignPartnerPage.d.ts +3 -8
- package/dist/components/marketing/DesignPartnerPage.d.ts.map +1 -1
- package/dist/components/marketing/DesignPartnerPage.js +263 -211
- package/dist/components/marketing/LandingPage.d.ts +1 -6
- package/dist/components/marketing/LandingPage.d.ts.map +1 -1
- package/dist/components/marketing/LandingPage.js +623 -37
- package/dist/components/marketing/PricingClient.d.ts +1 -6
- package/dist/components/marketing/PricingClient.d.ts.map +1 -1
- package/dist/components/marketing/PricingClient.js +1962 -516
- package/dist/components/marketing/ProductClientPage.d.ts +1 -6
- package/dist/components/marketing/ProductClientPage.d.ts.map +1 -1
- package/dist/components/marketing/ProductClientPage.js +556 -458
- package/dist/components/marketing/index.d.ts +11 -11
- package/dist/components/marketing/index.d.ts.map +1 -0
- package/dist/components/marketing/index.js +4813 -12
- package/dist/components/marketing/pricing-thinking-modal.d.ts +5 -13
- package/dist/components/marketing/pricing-thinking-modal.d.ts.map +1 -1
- package/dist/components/marketing/pricing-thinking-modal.js +248 -197
- package/dist/components/marketing/sections/AudienceSection.d.ts +1 -6
- package/dist/components/marketing/sections/AudienceSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/AudienceSection.js +80 -63
- package/dist/components/marketing/sections/CorePositioningSection.d.ts +1 -6
- package/dist/components/marketing/sections/CorePositioningSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/CorePositioningSection.js +62 -54
- package/dist/components/marketing/sections/CtaSection.d.ts +1 -6
- package/dist/components/marketing/sections/CtaSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/CtaSection.js +58 -50
- package/dist/components/marketing/sections/DevelopersSection.d.ts +1 -6
- package/dist/components/marketing/sections/DevelopersSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/DevelopersSection.js +40 -40
- package/dist/components/marketing/sections/FearsSection.d.ts +1 -6
- package/dist/components/marketing/sections/FearsSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/FearsSection.js +96 -44
- package/dist/components/marketing/sections/HeroMarketingSection.d.ts +1 -6
- package/dist/components/marketing/sections/HeroMarketingSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/HeroMarketingSection.js +82 -71
- package/dist/components/marketing/sections/IconGridSection.d.ts +25 -39
- package/dist/components/marketing/sections/IconGridSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/IconGridSection.js +55 -41
- package/dist/components/marketing/sections/OutputsSection.d.ts +1 -6
- package/dist/components/marketing/sections/OutputsSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/OutputsSection.js +107 -55
- package/dist/components/marketing/sections/ProblemSection.d.ts +1 -6
- package/dist/components/marketing/sections/ProblemSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/ProblemSection.js +94 -42
- package/dist/components/marketing/sections/SolutionSection.d.ts +1 -6
- package/dist/components/marketing/sections/SolutionSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/SolutionSection.js +94 -42
- package/dist/components/marketing/sections/StepsSection.d.ts +1 -6
- package/dist/components/marketing/sections/StepsSection.d.ts.map +1 -1
- package/dist/components/marketing/sections/StepsSection.js +100 -48
- package/dist/components/marketing/waitlist-section.d.ts +5 -12
- package/dist/components/marketing/waitlist-section.d.ts.map +1 -1
- package/dist/components/marketing/waitlist-section.js +1089 -568
- package/dist/components/templates/TemplatesClientPage.d.ts +1 -6
- package/dist/components/templates/TemplatesClientPage.d.ts.map +1 -1
- package/dist/components/templates/TemplatesClientPage.js +5649 -617
- package/dist/components/templates/TemplatesPage.d.ts +1 -6
- package/dist/components/templates/TemplatesPage.d.ts.map +1 -1
- package/dist/components/templates/TemplatesPage.js +163 -116
- package/dist/components/templates/TemplatesPreviewModal.d.ts +5 -12
- package/dist/components/templates/TemplatesPreviewModal.d.ts.map +1 -1
- package/dist/components/templates/TemplatesPreviewModal.js +113 -131
- package/dist/components/templates/index.d.ts +4 -4
- package/dist/components/templates/index.d.ts.map +1 -0
- package/dist/components/templates/index.js +5825 -4
- package/dist/index.d.ts +9 -29
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6480 -28
- package/dist/libs/email/client.d.ts +9 -12
- package/dist/libs/email/client.d.ts.map +1 -1
- package/dist/libs/email/client.js +109 -105
- package/dist/libs/email/client.test.d.ts +2 -0
- package/dist/libs/email/client.test.d.ts.map +1 -0
- package/dist/libs/email/contact.d.ts +2 -6
- package/dist/libs/email/contact.d.ts.map +1 -1
- package/dist/libs/email/contact.js +155 -41
- package/dist/libs/email/newsletter.d.ts +2 -6
- package/dist/libs/email/newsletter.d.ts.map +1 -1
- package/dist/libs/email/newsletter.js +169 -54
- package/dist/libs/email/types.d.ts +48 -52
- package/dist/libs/email/types.d.ts.map +1 -1
- package/dist/libs/email/types.js +3 -1
- package/dist/libs/email/utils.d.ts +2 -5
- package/dist/libs/email/utils.d.ts.map +1 -1
- package/dist/libs/email/utils.js +10 -6
- package/dist/libs/email/waitlist-application.d.ts +2 -6
- package/dist/libs/email/waitlist-application.d.ts.map +1 -1
- package/dist/libs/email/waitlist-application.js +191 -71
- package/dist/libs/email/waitlist.d.ts +2 -6
- package/dist/libs/email/waitlist.d.ts.map +1 -1
- package/dist/libs/email/waitlist.js +171 -56
- package/dist/libs/pricing-examples.d.ts +13 -16
- package/dist/libs/pricing-examples.d.ts.map +1 -1
- package/dist/libs/pricing-examples.js +20 -20
- package/dist/node/components/marketing/ChangelogPage.js +87 -0
- package/dist/node/components/marketing/CofounderPage.js +576 -0
- package/dist/node/components/marketing/ContactClient.js +1374 -0
- package/dist/node/components/marketing/ContributePage.js +482 -0
- package/dist/node/components/marketing/DesignPartnerPage.js +267 -0
- package/dist/node/components/marketing/LandingPage.js +624 -0
- package/dist/node/components/marketing/PricingClient.js +1967 -0
- package/dist/node/components/marketing/ProductClientPage.js +558 -0
- package/dist/node/components/marketing/index.js +4813 -0
- package/dist/node/components/marketing/pricing-thinking-modal.js +253 -0
- package/dist/node/components/marketing/sections/AudienceSection.js +85 -0
- package/dist/node/components/marketing/sections/CorePositioningSection.js +67 -0
- package/dist/node/components/marketing/sections/CtaSection.js +62 -0
- package/dist/node/components/marketing/sections/DevelopersSection.js +45 -0
- package/dist/node/components/marketing/sections/FearsSection.js +100 -0
- package/dist/node/components/marketing/sections/HeroMarketingSection.js +88 -0
- package/dist/node/components/marketing/sections/IconGridSection.js +58 -0
- package/dist/node/components/marketing/sections/OutputsSection.js +111 -0
- package/dist/node/components/marketing/sections/ProblemSection.js +98 -0
- package/dist/node/components/marketing/sections/SolutionSection.js +98 -0
- package/dist/node/components/marketing/sections/StepsSection.js +104 -0
- package/dist/node/components/marketing/waitlist-section.js +1099 -0
- package/dist/node/components/templates/TemplatesClientPage.js +5657 -0
- package/dist/node/components/templates/TemplatesPage.js +172 -0
- package/dist/node/components/templates/TemplatesPreviewModal.js +119 -0
- package/dist/node/components/templates/index.js +5826 -0
- package/dist/node/index.js +6480 -0
- package/dist/node/libs/email/client.js +117 -0
- package/dist/node/libs/email/contact.js +185 -0
- package/dist/node/libs/email/newsletter.js +210 -0
- package/dist/node/libs/email/types.js +2 -0
- package/dist/node/libs/email/utils.js +11 -0
- package/dist/node/libs/email/waitlist-application.js +290 -0
- package/dist/node/libs/email/waitlist.js +220 -0
- package/dist/node/libs/pricing-examples.js +21 -0
- package/dist/node/registry/engine.js +5288 -0
- package/dist/node/registry/factory.js +47 -0
- package/dist/node/registry/index.js +5353 -0
- package/dist/node/registry/registry-docs.js +338 -0
- package/dist/node/registry/registry-landing.js +4932 -0
- package/dist/node/registry/registry.js +5274 -0
- package/dist/node/registry/types.js +0 -0
- package/dist/node/registry/utils.js +5335 -0
- package/dist/registry/engine.d.ts +4 -8
- package/dist/registry/engine.d.ts.map +1 -1
- package/dist/registry/engine.js +5287 -23
- package/dist/registry/factory.d.ts +30 -34
- package/dist/registry/factory.d.ts.map +1 -1
- package/dist/registry/factory.js +42 -56
- package/dist/registry/index.d.ts +8 -8
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +5353 -8
- package/dist/registry/registry-docs.d.ts +4 -8
- package/dist/registry/registry-docs.d.ts.map +1 -1
- package/dist/registry/registry-docs.js +242 -209
- package/dist/registry/registry-landing.d.ts +5 -9
- package/dist/registry/registry-landing.d.ts.map +1 -1
- package/dist/registry/registry-landing.js +4930 -93
- package/dist/registry/registry.d.ts +7 -11
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +5262 -49
- package/dist/registry/types.d.ts +6 -10
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry/types.js +1 -0
- package/dist/registry/utils.d.ts +10 -14
- package/dist/registry/utils.d.ts.map +1 -1
- package/dist/registry/utils.js +5330 -49
- package/package.json +355 -73
- package/tsdown.config.js +1 -2
- package/.turbo/turbo-build$colon$types.log +0 -1
- package/.turbo/turbo-lint.log +0 -3
- package/dist/components/marketing/ChangelogPage.js.map +0 -1
- package/dist/components/marketing/CofounderPage.js.map +0 -1
- package/dist/components/marketing/ContactClient.js.map +0 -1
- package/dist/components/marketing/ContributePage.js.map +0 -1
- package/dist/components/marketing/DesignPartnerPage.js.map +0 -1
- package/dist/components/marketing/LandingPage.js.map +0 -1
- package/dist/components/marketing/PricingClient.js.map +0 -1
- package/dist/components/marketing/ProductClientPage.js.map +0 -1
- package/dist/components/marketing/pricing-thinking-modal.js.map +0 -1
- package/dist/components/marketing/sections/AudienceSection.js.map +0 -1
- package/dist/components/marketing/sections/CorePositioningSection.js.map +0 -1
- package/dist/components/marketing/sections/CtaSection.js.map +0 -1
- package/dist/components/marketing/sections/DevelopersSection.js.map +0 -1
- package/dist/components/marketing/sections/FearsSection.js.map +0 -1
- package/dist/components/marketing/sections/HeroMarketingSection.js.map +0 -1
- package/dist/components/marketing/sections/IconGridSection.js.map +0 -1
- package/dist/components/marketing/sections/OutputsSection.js.map +0 -1
- package/dist/components/marketing/sections/ProblemSection.js.map +0 -1
- package/dist/components/marketing/sections/SolutionSection.js.map +0 -1
- package/dist/components/marketing/sections/StepsSection.js.map +0 -1
- package/dist/components/marketing/waitlist-section.js.map +0 -1
- package/dist/components/templates/TemplatesClientPage.js.map +0 -1
- package/dist/components/templates/TemplatesPage.js.map +0 -1
- package/dist/components/templates/TemplatesPreviewModal.js.map +0 -1
- package/dist/libs/email/client.js.map +0 -1
- package/dist/libs/email/contact.js.map +0 -1
- package/dist/libs/email/newsletter.js.map +0 -1
- package/dist/libs/email/utils.js.map +0 -1
- package/dist/libs/email/waitlist-application.js.map +0 -1
- package/dist/libs/email/waitlist.js.map +0 -1
- package/dist/libs/pricing-examples.js.map +0 -1
- package/dist/registry/engine.js.map +0 -1
- package/dist/registry/factory.js.map +0 -1
- package/dist/registry/registry-docs.js.map +0 -1
- package/dist/registry/registry-landing.js.map +0 -1
- package/dist/registry/registry.js.map +0 -1
- package/dist/registry/utils.js.map +0 -1
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ContributePage.js","names":[],"sources":["../../../src/components/marketing/ContributePage.tsx"],"sourcesContent":["import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: 'Contribute to ContractSpec',\n description:\n 'Join the ContractSpec open-source community. Report issues, improve docs, build integrations, and help shape the future of spec-first development.',\n openGraph: {\n title: 'Contribute to ContractSpec',\n description:\n 'Get started contributing in under 3 minutes. Docs, examples, integrations, and more.',\n url: 'https://contractspec.io/contribute',\n },\n alternates: {\n canonical: 'https://contractspec.io/contribute',\n },\n};\n\nexport function ContributePage() {\n return (\n <main className=\"flex grow flex-col items-center justify-center\">\n <section className=\"section-padding\">\n <div className=\"prose prose-invert mx-auto max-w-2xl\">\n <h1 className=\"mb-8 text-4xl font-bold\">\n Contribute to ContractSpec\n </h1>\n\n {/* Quick Start Box */}\n <div className=\"not-prose border-border bg-muted/30 mb-12 rounded-lg border p-6\">\n <h2 className=\"text-foreground mb-4 text-xl font-bold\">\n ⚡ Quick Start — 3 Minutes to Your First Contribution\n </h2>\n <ol className=\"text-muted-foreground list-inside list-decimal space-y-2\">\n <li>\n Read the{' '}\n <a\n href=\"https://github.com/contractspec/contractspec/blob/main/CONTRIBUTING.md\"\n className=\"text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n CONTRIBUTING guide\n </a>\n </li>\n <li>\n Pick a{' '}\n <a\n href=\"https://github.com/contractspec/contractspec/labels/good%20first%20issue\"\n className=\"text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n good first issue\n </a>{' '}\n or{' '}\n <a\n href=\"https://github.com/contractspec/contractspec/labels/help%20wanted\"\n className=\"text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n help wanted\n </a>{' '}\n label\n </li>\n <li>Open a draft PR early — we'll guide you from there</li>\n </ol>\n </div>\n\n {/* Why Open Source */}\n <section className=\"mb-10 space-y-4\">\n <h2 className=\"text-foreground text-2xl font-bold\">\n Why Open Source?\n </h2>\n <ul className=\"text-muted-foreground list-inside list-disc space-y-2\">\n <li>\n <strong>Transparency:</strong> You can see exactly how your code\n is compiled and deployed\n </li>\n <li>\n <strong>Trust:</strong> No black boxes — audit the compiler that\n shapes your AI-generated code\n </li>\n <li>\n <strong>Faster ecosystem:</strong> Community contributions\n accelerate adoption and surface real-world edge cases\n </li>\n <li>\n <strong>Community review:</strong> More eyes catch more bugs,\n and better patterns emerge\n </li>\n <li>\n <strong>No lock-in:</strong> You own your code. The spec is\n portable.\n </li>\n </ul>\n </section>\n\n {/* Where to Contribute */}\n <section className=\"mb-10 space-y-4\">\n <h2 className=\"text-foreground text-2xl font-bold\">\n Where to Contribute\n </h2>\n <ul className=\"text-muted-foreground list-inside list-disc space-y-2\">\n <li>\n <a\n href=\"https://github.com/contractspec\"\n className=\"text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n GitHub Organization\n </a>{' '}\n — All repos live here\n </li>\n <li>\n <a\n href=\"https://github.com/contractspec/contractspec\"\n className=\"text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Main Repository\n </a>{' '}\n — Core compiler and specs\n </li>\n <li>\n <a\n href=\"https://github.com/contractspec/contractspec/discussions\"\n className=\"text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Discussions\n </a>{' '}\n — Questions, ideas, and RFCs\n </li>\n </ul>\n </section>\n\n {/* Contribution Types */}\n <section className=\"mb-10 space-y-4\">\n <h2 className=\"text-foreground text-2xl font-bold\">\n Ways to Contribute\n </h2>\n <div className=\"text-muted-foreground space-y-3\">\n <p>\n <strong className=\"text-foreground\">📄 Documentation:</strong>{' '}\n Fix typos, improve explanations, add missing guides\n </p>\n <p>\n <strong className=\"text-foreground\">\n 📦 Examples & Templates:\n </strong>{' '}\n Build real-world specs for common use cases\n </p>\n <p>\n <strong className=\"text-foreground\">\n 🔌 Integrations & Adapters:\n </strong>{' '}\n Connect ContractSpec to frameworks, databases, and tools\n </p>\n <p>\n <strong className=\"text-foreground\">🐛 Bug Reports:</strong>{' '}\n File issues with clear reproduction steps — minimal cases help\n the most\n </p>\n <p>\n <strong className=\"text-foreground\">\n 🔒 Security Reports:\n </strong>{' '}\n Found a vulnerability? See{' '}\n <a href=\"#security\" className=\"text-primary hover:underline\">\n Security\n </a>{' '}\n below\n </p>\n </div>\n </section>\n\n {/* Quality Bar */}\n <section className=\"mb-10 space-y-4\">\n <h2 className=\"text-foreground text-2xl font-bold\">Quality Bar</h2>\n <p className=\"text-muted-foreground\">\n We keep the bar high so the codebase stays maintainable. Every PR\n should:\n </p>\n <ul className=\"text-muted-foreground list-inside list-disc space-y-2\">\n <li>\n <strong>Include tests</strong> — Unit tests for logic,\n integration tests for adapters\n </li>\n <li>\n <strong>Be fully typed</strong> — No <code>any</code>. Strict\n TypeScript only.\n </li>\n <li>\n <strong>Stay small</strong> — One concern per PR. Easier to\n review, faster to merge.\n </li>\n <li>\n <strong>Use clear commit messages</strong> — Describe _what_ and\n _why_, not just _how_\n </li>\n </ul>\n <div className=\"bg-muted/20 mt-4 rounded-md p-4\">\n <h3 className=\"text-foreground mb-2 font-semibold\">\n Spec-First Mindset\n </h3>\n <p className=\"text-muted-foreground text-sm\">\n ContractSpec exists to enforce contracts between humans, AI, and\n code. When contributing, think spec-first: define the behavior\n before the implementation. A well-defined spec makes changes\n safe to regenerate and easy to validate.\n </p>\n </div>\n </section>\n\n {/* Governance */}\n <section className=\"mb-10 space-y-4\">\n <h2 className=\"text-foreground text-2xl font-bold\">\n Governance & Decision Making\n </h2>\n <p className=\"text-muted-foreground\">\n ContractSpec uses a{' '}\n <strong className=\"text-foreground\">\n founder-led maintainer model\n </strong>\n :\n </p>\n <ul className=\"text-muted-foreground list-inside list-disc space-y-2\">\n <li>\n The founder has final say on significant decisions — for now\n </li>\n <li>All reasoning is shared publicly in issues or PRs</li>\n <li>\n Community input shapes direction; we don't merge in silence\n </li>\n <li>\n This model may evolve as the project matures and trusted\n maintainers emerge\n </li>\n </ul>\n </section>\n\n {/* Security */}\n <section className=\"mb-10 space-y-4\" id=\"security\">\n <h2 className=\"text-foreground text-2xl font-bold\">Security</h2>\n <p className=\"text-muted-foreground\">\n If you discover a security vulnerability, please{' '}\n <strong className=\"text-foreground\">do not</strong> open a public\n issue.\n </p>\n <p className=\"text-muted-foreground\">\n Instead, email us at{' '}\n <a\n href=\"mailto:security@contractspec.io\"\n className=\"text-primary hover:underline\"\n >\n security@contractspec.io\n </a>{' '}\n with:\n </p>\n <ul className=\"text-muted-foreground list-inside list-disc space-y-2\">\n <li>A clear description of the vulnerability</li>\n <li>Steps to reproduce</li>\n <li>Potential impact</li>\n </ul>\n <p className=\"text-muted-foreground\">\n We'll acknowledge within 48 hours and work with you to coordinate\n disclosure.\n </p>\n </section>\n\n {/* Code of Conduct */}\n <section className=\"mb-10 space-y-4\">\n <h2 className=\"text-foreground text-2xl font-bold\">\n Code of Conduct\n </h2>\n <p className=\"text-muted-foreground\">\n We expect all contributors to follow our{' '}\n <a\n href=\"https://github.com/contractspec/contractspec/blob/main/CODE_OF_CONDUCT.md\"\n className=\"text-primary hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Code of Conduct\n </a>\n . Be respectful, constructive, and assume good intent.\n </p>\n </section>\n\n {/* Go Deeper */}\n <section className=\"border-border mt-12 space-y-4 border-t pt-8\">\n <h2 className=\"text-foreground text-2xl font-bold\">\n Want to Go Deeper?\n </h2>\n <p className=\"text-muted-foreground\">\n If you're considering a long-term commitment to ContractSpec —\n reviewing PRs regularly, shaping roadmap, mentoring new\n contributors — we'd love to talk.\n </p>\n <p className=\"text-muted-foreground\">\n This isn't a job offer. It's an invitation to help build something\n meaningful together. Reach out at{' '}\n <a\n href=\"mailto:maintainers@contractspec.io\"\n className=\"text-primary hover:underline\"\n >\n maintainers@contractspec.io\n </a>{' '}\n and tell us what you'd bring to the table.\n </p>\n </section>\n </div>\n </section>\n </main>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DesignPartnerPage.js","names":[],"sources":["../../../src/components/marketing/DesignPartnerPage.tsx"],"sourcesContent":["import type { Metadata } from 'next';\nimport Link from 'next/link';\nimport { Button } from '@contractspec/lib.design-system';\nimport {\n ArrowRight,\n BookOpen,\n MessageSquare,\n Rocket,\n Users,\n} from 'lucide-react';\n\nexport const metadata: Metadata = {\n title: 'Design Partner Getting Started | ContractSpec',\n description: 'Onboarding and resources for ContractSpec Design Partners.',\n};\n\nexport function DesignPartnerPage() {\n return (\n <main className=\"flex grow flex-col\">\n {/* Hero Section */}\n <section className=\"section-padding relative overflow-hidden\">\n <div className=\"container mx-auto max-w-5xl\">\n <div className=\"mb-12 max-w-3xl\">\n <h1 className=\"mb-6 text-4xl font-bold tracking-tight sm:text-5xl\">\n Welcome, Design Partner\n </h1>\n <p className=\"text-muted-foreground text-xl leading-relaxed\">\n We're thrilled to have you on board. As a Design Partner, you play\n a critical role in shaping the future of ContractSpec. This hub\n contains everything you need to get started, collaborate with us,\n and build your first specifications.\n </p>\n </div>\n </div>\n </section>\n\n {/* Steps Section */}\n <section className=\"section-padding bg-white/5\">\n <div className=\"container mx-auto max-w-5xl\">\n <h2 className=\"mb-12 text-3xl font-bold\">Getting Started</h2>\n\n <div className=\"grid gap-12 md:grid-cols-2\">\n {/* Step 1: Access */}\n <div className=\"space-y-4\">\n <div className=\"border-primary/20 bg-primary/10 flex h-12 w-12 items-center justify-center rounded-lg border\">\n <Rocket className=\"text-primary h-6 w-6\" />\n </div>\n <h3 className=\"text-xl font-semibold\">1. Access the Studio</h3>\n <p className=\"text-muted-foreground\">\n Your account has been enabled with Design Partner privileges.\n Log in to the Studio to start exploring the latest features\n before they're public.\n </p>\n <div className=\"pt-2\">\n <Button asChild variant=\"outline\">\n <Link href=\"https://www.contractspec.studio\">\n Launch Studio <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Link>\n </Button>\n </div>\n </div>\n\n {/* Step 2: Communication */}\n <div className=\"space-y-4\">\n <div className=\"border-primary/20 bg-primary/10 flex h-12 w-12 items-center justify-center rounded-lg border\">\n <MessageSquare className=\"text-primary h-6 w-6\" />\n </div>\n <h3 className=\"text-xl font-semibold\">\n 2. Join the Conversation\n </h3>\n <p className=\"text-muted-foreground\">\n We've set up a dedicated private channel for real-time feedback\n and support. Connect with our engineering team and other\n partners.\n </p>\n <div className=\"pt-2\">\n <Button asChild variant=\"outline\">\n <Link href=\"mailto:partners@contractspec.io\">\n Contact Partner Success{' '}\n <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Link>\n </Button>\n </div>\n </div>\n\n {/* Step 3: Documentation */}\n <div className=\"space-y-4\">\n <div className=\"border-primary/20 bg-primary/10 flex h-12 w-12 items-center justify-center rounded-lg border\">\n <BookOpen className=\"text-primary h-6 w-6\" />\n </div>\n <h3 className=\"text-xl font-semibold\">\n 3. Explore Documentation\n </h3>\n <p className=\"text-muted-foreground\">\n Dive deep into the core concepts, API references, and\n architecture guides. Our docs are evolving, and your feedback\n helps us improve them.\n </p>\n <div className=\"pt-2\">\n <Button asChild variant=\"outline\">\n <Link href=\"/docs\">\n Read the Docs <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Link>\n </Button>\n </div>\n </div>\n\n {/* Step 4: Sync */}\n <div className=\"space-y-4\">\n <div className=\"border-primary/20 bg-primary/10 flex h-12 w-12 items-center justify-center rounded-lg border\">\n <Users className=\"text-primary h-6 w-6\" />\n </div>\n <h3 className=\"text-xl font-semibold\">4. Partner Syncs</h3>\n <p className=\"text-muted-foreground\">\n We schedule bi-weekly syncs to review your progress, blockers,\n and feature requests. Check your calendar invite for the next\n session.\n </p>\n </div>\n </div>\n </div>\n </section>\n\n {/* Expectations / FAQ */}\n <section className=\"section-padding\">\n <div className=\"container mx-auto max-w-3xl\">\n <h2 className=\"mb-8 text-3xl font-bold\">What to Expect</h2>\n\n <div className=\"space-y-8\">\n <div>\n <h3 className=\"mb-2 text-xl font-semibold\">\n Fast Iteration Cycles\n </h3>\n <p className=\"text-muted-foreground\">\n We ship updates frequently. You might see UI changes or new\n capabilities appear weekly. We'll do our best to communicate\n breaking changes in advance.\n </p>\n </div>\n\n <div>\n <h3 className=\"mb-2 text-xl font-semibold\">\n Direct Engineering Access\n </h3>\n <p className=\"text-muted-foreground\">\n You're not talking to support agents; you're talking to the\n builders. Your feedback goes directly into the issue tracker.\n </p>\n </div>\n\n <div>\n <h3 className=\"mb-2 text-xl font-semibold\">Input on Roadmap</h3>\n <p className=\"text-muted-foreground\">\n Design Partners influence priority. If a feature enables a\n critical use case for you, let us know—we often reshuffle our\n sprint to accommodate partner needs.\n </p>\n </div>\n </div>\n </div>\n </section>\n\n {/* Footer CTA */}\n <section className=\"section-padding border-t border-white/10\">\n <div className=\"container mx-auto max-w-3xl text-center\">\n <h2 className=\"mb-4 text-3xl font-bold\">\n Have a question right now?\n </h2>\n <p className=\"text-muted-foreground mb-8\">\n Don't hesitate to reach out. We are here to help you succeed.\n </p>\n <Button asChild size=\"lg\">\n <Link href=\"mailto:partners@contractspec.io\">\n Email the Founders\n </Link>\n </Button>\n </div>\n </section>\n </main>\n );\n}\n"],"mappings":";;;;;;AAWA,MAAa,WAAqB;CAChC,OAAO;CACP,aAAa;CACd;AAED,SAAgB,oBAAoB;AAClC,QACE,qBAAC;EAAK,WAAU;;GAEd,oBAAC;IAAQ,WAAU;cACjB,oBAAC;KAAI,WAAU;eACb,qBAAC;MAAI,WAAU;iBACb,oBAAC;OAAG,WAAU;iBAAqD;QAE9D,EACL,oBAAC;OAAE,WAAU;iBAAgD;QAKzD;OACA;MACF;KACE;GAGV,oBAAC;IAAQ,WAAU;cACjB,qBAAC;KAAI,WAAU;gBACb,oBAAC;MAAG,WAAU;gBAA2B;OAAoB,EAE7D,qBAAC;MAAI,WAAU;;OAEb,qBAAC;QAAI,WAAU;;SACb,oBAAC;UAAI,WAAU;oBACb,oBAAC,UAAO,WAAU,yBAAyB;WACvC;SACN,oBAAC;UAAG,WAAU;oBAAwB;WAAyB;SAC/D,oBAAC;UAAE,WAAU;oBAAwB;WAIjC;SACJ,oBAAC;UAAI,WAAU;oBACb,oBAAC;WAAO;WAAQ,SAAQ;qBACtB,qBAAC;YAAK,MAAK;uBAAkC,kBAC7B,oBAAC,cAAW,WAAU,iBAAiB;aAChD;YACA;WACL;;SACF;OAGN,qBAAC;QAAI,WAAU;;SACb,oBAAC;UAAI,WAAU;oBACb,oBAAC,iBAAc,WAAU,yBAAyB;WAC9C;SACN,oBAAC;UAAG,WAAU;oBAAwB;WAEjC;SACL,oBAAC;UAAE,WAAU;oBAAwB;WAIjC;SACJ,oBAAC;UAAI,WAAU;oBACb,oBAAC;WAAO;WAAQ,SAAQ;qBACtB,qBAAC;YAAK,MAAK;;aAAkC;aACnB;aACxB,oBAAC,cAAW,WAAU,iBAAiB;;aAClC;YACA;WACL;;SACF;OAGN,qBAAC;QAAI,WAAU;;SACb,oBAAC;UAAI,WAAU;oBACb,oBAAC,YAAS,WAAU,yBAAyB;WACzC;SACN,oBAAC;UAAG,WAAU;oBAAwB;WAEjC;SACL,oBAAC;UAAE,WAAU;oBAAwB;WAIjC;SACJ,oBAAC;UAAI,WAAU;oBACb,oBAAC;WAAO;WAAQ,SAAQ;qBACtB,qBAAC;YAAK,MAAK;uBAAQ,kBACH,oBAAC,cAAW,WAAU,iBAAiB;aAChD;YACA;WACL;;SACF;OAGN,qBAAC;QAAI,WAAU;;SACb,oBAAC;UAAI,WAAU;oBACb,oBAAC,SAAM,WAAU,yBAAyB;WACtC;SACN,oBAAC;UAAG,WAAU;oBAAwB;WAAqB;SAC3D,oBAAC;UAAE,WAAU;oBAAwB;WAIjC;;SACA;;OACF;MACF;KACE;GAGV,oBAAC;IAAQ,WAAU;cACjB,qBAAC;KAAI,WAAU;gBACb,oBAAC;MAAG,WAAU;gBAA0B;OAAmB,EAE3D,qBAAC;MAAI,WAAU;;OACb,qBAAC,oBACC,oBAAC;QAAG,WAAU;kBAA6B;SAEtC,EACL,oBAAC;QAAE,WAAU;kBAAwB;SAIjC,IACA;OAEN,qBAAC,oBACC,oBAAC;QAAG,WAAU;kBAA6B;SAEtC,EACL,oBAAC;QAAE,WAAU;kBAAwB;SAGjC,IACA;OAEN,qBAAC,oBACC,oBAAC;QAAG,WAAU;kBAA6B;SAAqB,EAChE,oBAAC;QAAE,WAAU;kBAAwB;SAIjC,IACA;;OACF;MACF;KACE;GAGV,oBAAC;IAAQ,WAAU;cACjB,qBAAC;KAAI,WAAU;;MACb,oBAAC;OAAG,WAAU;iBAA0B;QAEnC;MACL,oBAAC;OAAE,WAAU;iBAA6B;QAEtC;MACJ,oBAAC;OAAO;OAAQ,MAAK;iBACnB,oBAAC;QAAK,MAAK;kBAAkC;SAEtC;QACA;;MACL;KACE;;GACL"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LandingPage.js","names":[],"sources":["../../../src/components/marketing/LandingPage.tsx"],"sourcesContent":["'use client';\n\nimport { VStack } from '@contractspec/lib.ui-kit-web/ui/stack';\nimport { HeroMarketingSection } from './sections/HeroMarketingSection';\nimport { ProblemSection } from './sections/ProblemSection';\nimport { SolutionSection } from './sections/SolutionSection';\nimport { FearsSection } from './sections/FearsSection';\nimport { CorePositioningSection } from './sections/CorePositioningSection';\nimport { AudienceSection } from './sections/AudienceSection';\nimport { OutputsSection } from './sections/OutputsSection';\nimport { StepsSection } from './sections/StepsSection';\nimport { DevelopersSection } from './sections/DevelopersSection';\nimport { CtaSection } from './sections/CtaSection';\n\nexport function LandingPage() {\n return (\n <VStack as=\"main\" gap=\"none\">\n <HeroMarketingSection />\n <ProblemSection />\n <SolutionSection />\n <FearsSection />\n <CorePositioningSection />\n <AudienceSection />\n <OutputsSection />\n <StepsSection />\n <DevelopersSection />\n <CtaSection />\n </VStack>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAcA,SAAgB,cAAc;AAC5B,QACE,qBAAC;EAAO,IAAG;EAAO,KAAI;;GACpB,oBAAC,yBAAuB;GACxB,oBAAC,mBAAiB;GAClB,oBAAC,oBAAkB;GACnB,oBAAC,iBAAe;GAChB,oBAAC,2BAAyB;GAC1B,oBAAC,oBAAkB;GACnB,oBAAC,mBAAiB;GAClB,oBAAC,iBAAe;GAChB,oBAAC,sBAAoB;GACrB,oBAAC,eAAa;;GACP"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PricingClient.js","names":[],"sources":["../../../src/components/marketing/PricingClient.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport Link from 'next/link';\nimport { CheckCircle, ChevronDown, ChevronRight } from 'lucide-react';\n\nimport { WaitlistSection } from './waitlist-section';\nimport { PricingThinkingModal } from './pricing-thinking-modal';\n\ninterface FAQ {\n question: string;\n answer: string;\n}\n\nconst faqs: FAQ[] = [\n {\n question: 'Can I pay for ContractSpec today?',\n answer:\n \"Not yet. We're pre-PMF and working closely with a small set of design partners. They get full access during early access and will be first to move onto paid plans once we're confident in the value and stability.\",\n },\n {\n question: 'What will you charge for later?',\n answer:\n 'Our plan is to charge based on usage: regenerations, AI agent actions, and number of active projects. A generous free tier will stay available so smaller teams and experiments can thrive.',\n },\n {\n question: 'What do I get as a design partner?',\n answer:\n 'Direct collaboration on features, priority onboarding, and a founding discount when paid plans launch. You also shape how ContractSpec works for teams like yours.',\n },\n {\n question: 'Will you ever charge per seat?',\n answer:\n 'No. We want everyone in your team to use ContractSpec without friction. Pricing is tied to how much of your system we help you maintain, not how many teammates you invite.',\n },\n];\n\nexport function PricingClient() {\n const [openFaq, setOpenFaq] = useState<number | null>(null);\n const [pricingModalOpen, setPricingModalOpen] = useState(false);\n\n const scrollToWaitlist = () => {\n const waitlistElement = document.getElementById('waitlist');\n if (waitlistElement) {\n waitlistElement.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n };\n\n return (\n <main className=\"\">\n {/* Hero */}\n <section className=\"section-padding hero-gradient relative\">\n <div className=\"mx-auto max-w-4xl space-y-6 text-center\">\n <h1 className=\"text-5xl leading-tight font-bold md:text-6xl\">\n Transparent, usage-based pricing – after we earn it.\n </h1>\n <p className=\"text-muted-foreground mx-auto max-w-2xl text-lg\">\n ContractSpec Core (the OSS compiler) is and always will be free.\n ContractSpec Studio (the managed platform) is in early access.\n </p>\n <div className=\"flex flex-col items-center justify-center gap-4 pt-4 sm:flex-row\">\n <Link\n href=\"/install\"\n className=\"btn-primary inline-flex items-center gap-2\"\n >\n Install OSS Core <ChevronRight size={16} />\n </Link>\n <button\n onClick={scrollToWaitlist}\n className=\"btn-ghost inline-flex items-center gap-2\"\n >\n Join Studio waitlist\n </button>\n </div>\n </div>\n </section>\n\n {/* Design-Partner Highlight Strip */}\n <section className=\"section-padding border-border border-b\">\n <div className=\"mx-auto max-w-6xl\">\n <div className=\"card-subtle flex flex-col gap-6 p-8 md:flex-row md:items-center\">\n <div className=\"flex-1 space-y-4\">\n <div className=\"inline-flex items-center gap-2 rounded-full border border-violet-500/20 bg-violet-500/10 px-3 py-1\">\n <span className=\"text-sm font-medium text-violet-300\">\n Now accepting design partners\n </span>\n </div>\n <h2 className=\"text-2xl font-bold\">\n Help us design the compiler for AI-native software.\n </h2>\n <p className=\"text-muted-foreground text-sm\">\n We work closely with a small group of teams building serious\n products with AI. You bring real-world complexity, we bring the\n spec-first engine and a lot of attention.\n </p>\n </div>\n <div className=\"flex-1 space-y-4\">\n <ul className=\"text-muted-foreground space-y-2 text-sm\">\n <li className=\"flex gap-2\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Early access to ContractSpec Studio\n </li>\n <li className=\"flex gap-2\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Hands-on onboarding and architecture help\n </li>\n <li className=\"flex gap-2\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Influence over roadmap and features\n </li>\n <li className=\"flex gap-2\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Priority support during early access\n </li>\n <li className=\"flex gap-2\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Founding discount when paid plans launch\n </li>\n </ul>\n <button\n onClick={scrollToWaitlist}\n className=\"btn-primary w-full md:w-auto\"\n >\n Apply to the waitlist\n </button>\n </div>\n </div>\n </div>\n </section>\n\n {/* Future Pricing Tiers */}\n <section className=\"section-padding border-border border-b\">\n <div className=\"mx-auto max-w-6xl\">\n <div className=\"grid gap-6 md:grid-cols-3\">\n {/* OSS Core (Forever Free) */}\n <div className=\"card-subtle col-span-3 space-y-6 border-violet-500/20 p-6\">\n <div className=\"absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-violet-500 px-3 py-1 text-xs font-medium text-white\">\n <div className=\"text-1xl font-bold\">Free Forever</div>\n <p className=\"text-muted-foreground text-xs\">\n Apache 2.0 / MIT License\n </p>\n </div>\n <div className=\"flex flex-row justify-around\">\n <div className=\"w-1/2\">\n <div className=\"space-y-2\">\n <h2 className=\"text-2xl font-bold\">OSS Core</h2>\n </div>\n <p className=\"text-muted-foreground text-sm\">\n The complete spec-first compiler. Generate API, DB, and UI\n code locally.\n </p>\n </div>\n <ul className=\"space-y-3\">\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Unlimited local regenerations\n </li>\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n All standard generators included\n </li>\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Run in your own CI/CD\n </li>\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Community support\n </li>\n </ul>\n </div>\n <Link href=\"/install\" className=\"btn-ghost w-full\">\n Install now\n </Link>\n </div>\n\n {/* Design Partner (Current) */}\n <div className=\"card-subtle relative space-y-6 bg-violet-500/5 p-6 ring-2 ring-violet-500\">\n <div className=\"absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-violet-500 px-3 py-1 text-xs font-medium text-white\">\n Current\n </div>\n <div className=\"space-y-2\">\n <h2 className=\"text-2xl font-bold\">Design Partner</h2>\n <div className=\"space-y-1\">\n <div className=\"text-2xl font-bold\">\n Free during early access\n </div>\n <p className=\"text-muted-foreground text-xs\">\n Founding discount when paid plans launch\n </p>\n </div>\n </div>\n <ul className=\"space-y-3\">\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Use ContractSpec Studio for real projects during early access\n </li>\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Work directly with the founder on architecture & use cases\n </li>\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Reasonable \"fair use\" limits on regenerations and AI credits\n </li>\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Priority support & feedback loops\n </li>\n </ul>\n <button onClick={scrollToWaitlist} className=\"btn-primary w-full\">\n Apply as a design partner\n </button>\n </div>\n\n {/* Builder (Coming Soon) */}\n <div className=\"card-subtle relative space-y-6 p-6\">\n <div className=\"bg-muted border-border absolute -top-3 left-1/2 -translate-x-1/2 rounded-full border px-3 py-1 text-xs font-medium\">\n Coming soon\n </div>\n <div className=\"space-y-2\">\n <h2 className=\"text-2xl font-bold\">Builder</h2>\n <div className=\"space-y-1\">\n <div className=\"text-2xl font-bold\">\n Usage-based, for solo builders and small teams\n </div>\n </div>\n </div>\n <p className=\"text-muted-foreground text-sm\">\n Pay only for what you regenerate and the AI you consume. No\n seat-based pricing, and a generous free tier for experiments.\n </p>\n <ul className=\"space-y-2\">\n <li className=\"text-muted-foreground text-sm\">1–3 projects</li>\n <li className=\"text-muted-foreground text-sm\">\n Generous monthly free regenerations\n </li>\n <li className=\"text-muted-foreground text-sm\">\n Pay-as-you-go beyond the free tier\n </li>\n </ul>\n <button\n disabled\n className=\"btn-ghost w-full cursor-not-allowed opacity-50\"\n >\n Available after public launch\n </button>\n </div>\n\n {/* Team / Enterprise (Coming Soon) */}\n <div className=\"card-subtle relative space-y-6 p-6\">\n <div className=\"bg-muted border-border absolute -top-3 left-1/2 -translate-x-1/2 rounded-full border px-3 py-1 text-xs font-medium\">\n Coming soon\n </div>\n <div className=\"space-y-2\">\n <h2 className=\"text-2xl font-bold\">Team & Platform</h2>\n <div className=\"space-y-1\">\n <div className=\"text-2xl font-bold\">\n Custom, for teams standardizing on ContractSpec\n </div>\n </div>\n </div>\n <p className=\"text-muted-foreground text-sm\">\n For teams running multiple apps or platforms on ContractSpec,\n with stricter governance, data, and compliance needs.\n </p>\n <ul className=\"space-y-3\">\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Multiple projects and environments\n </li>\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Advanced RBAC and policy packs\n </li>\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n SSO, audit trails, and longer retention\n </li>\n <li className=\"text-muted-foreground flex gap-3 text-sm\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n Priority support & SLAs\n </li>\n </ul>\n <Link href=\"/contact\" className=\"btn-ghost w-full\">\n Talk to us\n </Link>\n </div>\n </div>\n </div>\n </section>\n\n {/* How Pricing Will Work */}\n <section className=\"section-padding border-border bg-muted/20 border-b\">\n <div className=\"mx-auto max-w-4xl space-y-8\">\n <div className=\"space-y-4 text-center\">\n <h2 className=\"text-3xl font-bold\">\n How ContractSpec pricing will work\n </h2>\n <p className=\"text-muted-foreground mx-auto max-w-2xl text-lg\">\n We charge based on how much of your stack we help you maintain,\n not how many people click around in the UI.\n </p>\n </div>\n <div className=\"grid gap-6 md:grid-cols-3\">\n <div className=\"card-subtle space-y-3 p-6\">\n <h3 className=\"font-bold\">Generous free tier</h3>\n <p className=\"text-muted-foreground text-sm\">\n One serious project, small spec, and enough monthly\n regenerations to ship something real.\n </p>\n </div>\n <div className=\"card-subtle space-y-3 p-6\">\n <h3 className=\"font-bold\">Usage-based beyond free</h3>\n <p className=\"text-muted-foreground text-sm\">\n You pay for regenerations and AI agent actions, not per-seat.\n The more your system evolves via ContractSpec, the more you pay.\n </p>\n </div>\n <div className=\"card-subtle space-y-3 p-6\">\n <h3 className=\"font-bold\">No lock-in</h3>\n <p className=\"text-muted-foreground text-sm\">\n Generated code is standard, readable, and exportable. If you\n leave, your app keeps running.\n </p>\n </div>\n </div>\n <div className=\"pt-6 text-center\">\n <button\n onClick={() => setPricingModalOpen(true)}\n className=\"btn-ghost\"\n >\n View our tentative pricing model\n </button>\n </div>\n </div>\n </section>\n\n {/* FAQ */}\n <section className=\"section-padding border-border border-b\">\n <div className=\"mx-auto max-w-3xl space-y-8\">\n <h2 className=\"text-center text-3xl font-bold\">\n Frequently asked questions\n </h2>\n <div className=\"space-y-4\">\n {faqs.map((faq, i) => (\n <div key={i} className=\"card-subtle overflow-hidden\">\n <button\n onClick={() => setOpenFaq(openFaq === i ? null : i)}\n className=\"flex w-full items-center justify-between p-6 text-left\"\n >\n <span className=\"font-medium\">{faq.question}</span>\n <ChevronDown\n size={20}\n className={`text-muted-foreground transition-transform ${\n openFaq === i ? 'rotate-180' : ''\n }`}\n />\n </button>\n {openFaq === i && (\n <div className=\"text-muted-foreground px-6 pb-6 text-sm\">\n {faq.answer}\n </div>\n )}\n </div>\n ))}\n </div>\n <div className=\"pt-4 text-center\">\n <p className=\"text-muted-foreground mb-2 text-sm\">Still unsure?</p>\n <Link\n href=\"/contact\"\n className=\"text-sm font-medium text-violet-400 hover:text-violet-300\"\n >\n Contact us →\n </Link>\n </div>\n </div>\n </section>\n\n {/* Waitlist Section */}\n <section className=\"section-padding hero-gradient\">\n <div className=\"mx-auto max-w-4xl\">\n <WaitlistSection />\n </div>\n </section>\n\n {/* Pricing Thinking Modal */}\n <PricingThinkingModal\n open={pricingModalOpen}\n onOpenChange={setPricingModalOpen}\n onApplyClick={scrollToWaitlist}\n />\n </main>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductClientPage.js","names":[],"sources":["../../../src/components/marketing/ProductClientPage.tsx"],"sourcesContent":["'use client';\n\nimport Link from '@contractspec/lib.ui-link';\nimport {\n analyticsEventNames,\n captureAnalyticsEvent,\n} from '@contractspec/bundle.library/libs/posthog/client';\nimport {\n CheckCircle,\n ChevronRight,\n Database,\n FileCode,\n GitBranch,\n Layers,\n RefreshCw,\n Shield,\n Unlock,\n Zap,\n} from 'lucide-react';\n\nexport const ProductClientPage = () => (\n <main className=\"\">\n {/* Hero */}\n <section className=\"section-padding hero-gradient relative\">\n <div className=\"mx-auto max-w-4xl space-y-6 text-center\">\n <h1 className=\"text-5xl leading-tight font-bold md:text-6xl\">\n Compiler for AI-coded systems\n </h1>\n <p className=\"text-muted-foreground mx-auto max-w-2xl text-lg\">\n Define contracts once. Generate consistent code across API, DB, UI,\n and events. Regenerate safely anytime. No lock-in.\n </p>\n <div className=\"flex flex-col items-center justify-center gap-4 pt-4 sm:flex-row\">\n <Link\n href=\"/install\"\n onClick={() =>\n captureAnalyticsEvent(analyticsEventNames.CTA_INSTALL_CLICK, {\n surface: 'product-hero',\n })\n }\n className=\"btn-primary inline-flex items-center gap-2\"\n >\n Install OSS Core <ChevronRight size={16} />\n </Link>\n <Link href=\"/pricing\" className=\"btn-ghost\">\n View pricing\n </Link>\n </div>\n </div>\n </section>\n\n {/* Multi-Surface Consistency */}\n <section className=\"section-padding border-border border-b\">\n <div className=\"mx-auto max-w-4xl space-y-8\">\n <div className=\"space-y-4\">\n <div className=\"inline-flex items-center gap-2 rounded-full border border-blue-500/20 bg-blue-500/10 px-3 py-1\">\n <Layers size={16} className=\"text-blue-400\" />\n <span className=\"text-sm font-medium text-blue-300\">\n Multi-Surface Consistency\n </span>\n </div>\n <h2 className=\"text-3xl font-bold md:text-4xl\">\n One contract, all surfaces in sync\n </h2>\n <p className=\"text-muted-foreground text-lg\">\n Stop chasing drift between your API, database, UI, and events. One\n spec generates all outputs, guaranteed to stay consistent.\n </p>\n </div>\n <div className=\"grid gap-6 md:grid-cols-2\">\n {[\n {\n title: 'REST & GraphQL API',\n description:\n 'Type-safe endpoints with validation. Standard Express, Hono, Elysia, or Apollo handlers.',\n icon: Zap,\n },\n {\n title: 'Database Schema',\n description:\n 'Prisma migrations and types generated from the same spec. Always in sync with your API.',\n icon: Database,\n },\n {\n title: 'UI Components',\n description:\n 'React forms and views derived from specs. Validation and types flow through automatically.',\n icon: FileCode,\n },\n {\n title: 'MCP Tools & Events',\n description:\n 'AI agent tool definitions and event schemas. Same contract, different surfaces.',\n icon: GitBranch,\n },\n ].map((item, i) => (\n <div key={i} className=\"card-subtle space-y-4 p-6\">\n <item.icon className=\"text-blue-400\" size={24} />\n <h3 className=\"text-lg font-bold\">{item.title}</h3>\n <p className=\"text-muted-foreground text-sm\">\n {item.description}\n </p>\n </div>\n ))}\n </div>\n </div>\n </section>\n\n {/* Safe Regeneration */}\n <section className=\"section-padding border-border bg-muted/20 border-b\">\n <div className=\"mx-auto max-w-4xl space-y-8\">\n <div className=\"space-y-4\">\n <div className=\"inline-flex items-center gap-2 rounded-full border border-emerald-500/20 bg-emerald-500/10 px-3 py-1\">\n <RefreshCw size={16} className=\"text-emerald-400\" />\n <span className=\"text-sm font-medium text-emerald-300\">\n Safe Regeneration\n </span>\n </div>\n <h2 className=\"text-3xl font-bold md:text-4xl\">\n Regenerate anytime without fear\n </h2>\n <p className=\"text-muted-foreground text-lg\">\n Contracts enforce invariants. Breaking changes are caught at compile\n time, not production. Regenerate with confidence.\n </p>\n </div>\n <div className=\"grid gap-6 md:grid-cols-2\">\n <div className=\"card-subtle space-y-4 p-6\">\n <h3 className=\"font-bold\">Spec-First Safety</h3>\n <p className=\"text-muted-foreground text-sm\">\n AI agents read specs, not implementations. Generated code that\n violates contracts gets flagged automatically.\n </p>\n <ul className=\"text-muted-foreground space-y-2 text-sm\">\n <li className=\"flex gap-3\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 flex-shrink-0 text-emerald-400\"\n />\n Type-safe from spec to runtime\n </li>\n <li className=\"flex gap-3\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 flex-shrink-0 text-emerald-400\"\n />\n Invariants enforced at compile time\n </li>\n <li className=\"flex gap-3\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 flex-shrink-0 text-emerald-400\"\n />\n Breaking changes detected early\n </li>\n </ul>\n </div>\n <div className=\"card-subtle space-y-4 p-6\">\n <h3 className=\"font-bold\">Version Control Built-in</h3>\n <p className=\"text-muted-foreground text-sm\">\n Every spec change is tracked. Roll back to any previous version.\n Migrations are explicit and reversible.\n </p>\n <ul className=\"text-muted-foreground space-y-2 text-sm\">\n <li className=\"flex gap-3\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 flex-shrink-0 text-emerald-400\"\n />\n Git-native spec history\n </li>\n <li className=\"flex gap-3\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 flex-shrink-0 text-emerald-400\"\n />\n Explicit migration paths\n </li>\n <li className=\"flex gap-3\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 flex-shrink-0 text-emerald-400\"\n />\n One-click rollback\n </li>\n </ul>\n </div>\n </div>\n </div>\n </section>\n\n {/* Contract Enforcement */}\n <section className=\"section-padding border-border border-b\">\n <div className=\"mx-auto max-w-4xl space-y-8\">\n <div className=\"space-y-4\">\n <div className=\"inline-flex items-center gap-2 rounded-full border border-violet-500/20 bg-violet-500/10 px-3 py-1\">\n <Shield size={16} className=\"text-violet-400\" />\n <span className=\"text-sm font-medium text-violet-300\">\n Contract Enforcement\n </span>\n </div>\n <h2 className=\"text-3xl font-bold md:text-4xl\">\n AI governance that actually works\n </h2>\n <p className=\"text-muted-foreground text-lg\">\n Constrain what AI agents can change. Enforce contracts they must\n respect. No more hallucinated refactors breaking your system.\n </p>\n </div>\n <div className=\"card-subtle space-y-6 p-6\">\n <div className=\"space-y-4\">\n <h3 className=\"font-bold\">How contract enforcement works</h3>\n <p className=\"text-muted-foreground text-sm\">\n Contracts define what the system should do. AI-generated code that\n violates these contracts is automatically flagged and rejected\n before it can cause damage.\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n {[\n {\n title: 'Define',\n description:\n 'Write specs in TypeScript. Define inputs, outputs, and invariants.',\n },\n {\n title: 'Generate',\n description:\n 'ContractSpec generates code across all surfaces from your specs.',\n },\n {\n title: 'Enforce',\n description:\n \"Any code that violates specs is flagged. AI agents can't break contracts.\",\n },\n ].map((step, i) => (\n <div key={i} className=\"space-y-2\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-lg bg-violet-500/20\">\n <div className=\"text-sm font-bold text-violet-400\">\n {i + 1}\n </div>\n </div>\n <h4 className=\"text-sm font-bold\">{step.title}</h4>\n <p className=\"text-muted-foreground text-xs\">\n {step.description}\n </p>\n </div>\n ))}\n </div>\n </div>\n </div>\n </section>\n\n {/* No Lock-in */}\n <section className=\"section-padding border-border border-b bg-gradient-to-br from-violet-500/10 via-indigo-500/5 to-blue-500/5\">\n <div className=\"mx-auto max-w-4xl space-y-8\">\n <div className=\"space-y-4\">\n <div className=\"inline-flex items-center gap-2 rounded-full border border-pink-500/20 bg-pink-500/10 px-3 py-1\">\n <Unlock size={16} className=\"text-pink-400\" />\n <span className=\"text-sm font-medium text-pink-300\">\n No Lock-in\n </span>\n </div>\n <h2 className=\"text-3xl font-bold md:text-4xl\">\n You own everything. Eject anytime.\n </h2>\n <p className=\"text-muted-foreground text-lg\">\n ContractSpec is a compiler, not a prison. The generated code is\n yours: standard TypeScript, standard SQL, standard GraphQL.\n </p>\n </div>\n <div className=\"grid gap-6 md:grid-cols-2\">\n <div className=\"card-subtle space-y-4 p-6\">\n <h3 className=\"text-lg font-bold\">Standard Tech Output</h3>\n <ul className=\"text-muted-foreground space-y-3 text-sm\">\n {[\n 'TypeScript you can read and modify',\n 'Prisma migrations you can run manually',\n 'GraphQL schemas you can serve anywhere',\n 'React components with no magic',\n 'REST handlers that work with any framework',\n ].map((item, i) => (\n <li key={i} className=\"flex gap-3\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 flex-shrink-0 text-pink-400\"\n />\n {item}\n </li>\n ))}\n </ul>\n </div>\n <div className=\"card-subtle space-y-4 p-6\">\n <h3 className=\"text-lg font-bold\">No Proprietary Dependencies</h3>\n <ul className=\"text-muted-foreground space-y-3 text-sm\">\n {[\n 'No runtime library required',\n 'No vendor-specific abstractions',\n 'Works with your existing CI/CD',\n 'Eject anytime, keep everything',\n 'Open spec format',\n ].map((item, i) => (\n <li key={i} className=\"flex gap-3\">\n <CheckCircle\n size={16}\n className=\"mt-0.5 flex-shrink-0 text-pink-400\"\n />\n {item}\n </li>\n ))}\n </ul>\n </div>\n </div>\n <div className=\"pt-4 text-center\">\n <p className=\"text-muted-foreground mb-4 text-sm\">\n Like TypeScript compiles to JavaScript, ContractSpec compiles to\n standard code.\n <br />\n <span className=\"font-medium text-violet-400\">\n We're the compiler, not the prison.\n </span>\n </p>\n </div>\n </div>\n </section>\n\n {/* Incremental Adoption */}\n <section className=\"section-padding border-border border-b\">\n <div className=\"mx-auto max-w-4xl space-y-8\">\n <h2 className=\"text-center text-3xl font-bold md:text-4xl\">\n Start small. Expand gradually.\n </h2>\n <p className=\"text-muted-foreground mx-auto max-w-2xl text-center text-lg\">\n You don't rewrite your app. You stabilize one module at a time. Start\n with one endpoint, prove value, then expand.\n </p>\n <div className=\"grid gap-6 md:grid-cols-3\">\n {[\n {\n title: 'Day 1',\n description:\n 'Pick one API endpoint. Write a spec. See what gets generated.',\n },\n {\n title: 'Week 1',\n description:\n 'Add a few more specs. Compare generated code to existing code.',\n },\n {\n title: 'Month 1',\n description:\n 'Migrate a full module. Enjoy multi-surface consistency.',\n },\n ].map((item, i) => (\n <div key={i} className=\"card-subtle space-y-4 p-6 text-center\">\n <div className=\"text-2xl font-bold text-violet-400\">\n {item.title}\n </div>\n <p className=\"text-muted-foreground text-sm\">\n {item.description}\n </p>\n </div>\n ))}\n </div>\n </div>\n </section>\n\n {/* CTA */}\n <section className=\"section-padding hero-gradient\">\n <div className=\"mx-auto max-w-4xl space-y-6 text-center\">\n <h2 className=\"text-3xl font-bold md:text-4xl\">\n Ready to stabilize your AI-generated code?\n </h2>\n <p className=\"text-muted-foreground text-lg\">\n Start with one module. No big-bang migration. No lock-in.\n </p>\n <div className=\"flex flex-col items-center justify-center gap-4 pt-4 sm:flex-row\">\n <Link\n href=\"/install\"\n className=\"btn-primary inline-flex items-center gap-2\"\n >\n Install OSS Core <ChevronRight size={16} />\n </Link>\n <Link href=\"/contact#waitlist\" className=\"btn-ghost\">\n Join Studio Waitlist\n </Link>\n </div>\n </div>\n </section>\n </main>\n);\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pricing-thinking-modal.js","names":[],"sources":["../../../src/components/marketing/pricing-thinking-modal.tsx"],"sourcesContent":["'use client';\n\nimport { CheckCircle } from 'lucide-react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@contractspec/lib.ui-kit-web/ui/dialog';\nimport { Button } from '@contractspec/lib.design-system';\nimport { PRICING_EXAMPLES } from '../../libs/pricing-examples';\n\ninterface PricingTier {\n tag: string;\n title: string;\n priceLine: string;\n bullets: string[];\n note: string;\n}\n\ninterface UsageMetric {\n name: string;\n freeTier: string;\n beyond: string;\n}\n\nconst pricingTiers: PricingTier[] = [\n {\n tag: 'Planned',\n title: 'Free',\n priceLine: 'For hobbyists and pre-PMF teams',\n bullets: [\n '1 active project',\n 'Small spec size',\n `Example: ~${PRICING_EXAMPLES.free.regenerationsPerMonth} free regenerations per month`,\n `Example: ~${PRICING_EXAMPLES.free.aiActionsPerMonth} free AI agent actions per month`,\n 'Unlimited collaborators',\n ],\n note: 'Good enough to build and launch a real product before paying.',\n },\n {\n tag: 'Planned',\n title: 'Builder',\n priceLine: 'Usage-based, for solo builders and small teams',\n bullets: [\n 'More projects',\n `More monthly regenerations included (e.g. ${PRICING_EXAMPLES.builder.regenerationsPerMonthHint})`,\n `More AI agent actions included (e.g. ${PRICING_EXAMPLES.builder.aiActionsPerMonthHint})`,\n 'Pay-as-you-go for extra regenerations and AI',\n 'Basic environments (dev / prod)',\n ],\n note: 'Pay for how fast and how often you evolve your system, not for seats.',\n },\n {\n tag: 'Planned',\n title: 'Team & Platform',\n priceLine: 'For teams standardizing on ContractSpec',\n bullets: [\n 'Multiple projects and environments',\n 'Higher regeneration and AI action limits',\n 'Cheaper overages as you scale',\n 'Advanced RBAC and governance',\n 'SSO, audit trails, and longer retention',\n ],\n note: 'For platform teams using ContractSpec as infra for multiple apps.',\n },\n];\n\nconst usageMetrics: UsageMetric[] = [\n {\n name: 'Regenerations',\n freeTier: `Free tier: e.g. ~${PRICING_EXAMPLES.free.regenerationsPerMonth} regenerations / month`,\n beyond: 'Beyond: pay per additional regeneration, with volume discounts.',\n },\n {\n name: 'AI agent actions',\n freeTier: `Free tier: e.g. ~${PRICING_EXAMPLES.free.aiActionsPerMonth} AI agent actions / month`,\n beyond: 'Beyond: pay-as-you-go for extra AI usage.',\n },\n {\n name: 'Projects',\n freeTier: `Free tier: ${PRICING_EXAMPLES.free.projects} project`,\n beyond:\n 'Builder / Team: more projects included; extra projects available as you scale.',\n },\n];\n\ninterface PricingThinkingModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onApplyClick?: () => void;\n}\n\nexport function PricingThinkingModal({\n open,\n onOpenChange,\n onApplyClick,\n}: PricingThinkingModalProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-h-[90vh] w-full overflow-y-auto md:max-w-5xl\">\n <DialogHeader>\n <DialogTitle>Tentative pricing (work in progress)</DialogTitle>\n <DialogDescription>\n We're still in design-partner mode. This is a draft of how we expect\n pricing to look once we open public access.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-8\">\n {/* High-level tiers */}\n <div className=\"space-y-4\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-xs font-medium\">\n Draft\n </span>\n <span className=\"text-muted-foreground text-xs\">•</span>\n <span className=\"text-muted-foreground text-xs\">\n Subject to change\n </span>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n {pricingTiers.map((tier) => (\n <div\n key={tier.title}\n className=\"card-subtle relative space-y-4 p-6\"\n >\n <div className=\"bg-muted border-border absolute -top-2 left-1/2 -translate-x-1/2 rounded-full border px-2 py-0.5 text-xs font-medium\">\n {tier.tag}\n </div>\n <div className=\"space-y-2 pt-2\">\n <h3 className=\"text-xl font-bold\">{tier.title}</h3>\n <p className=\"text-muted-foreground text-sm\">\n {tier.priceLine}\n </p>\n </div>\n <ul className=\"space-y-2\">\n {tier.bullets.map((bullet, i) => (\n <li\n key={i}\n className=\"text-muted-foreground flex gap-2 text-sm\"\n >\n <CheckCircle\n size={14}\n className=\"mt-0.5 shrink-0 text-violet-400\"\n />\n {bullet}\n </li>\n ))}\n </ul>\n <p className=\"text-muted-foreground text-xs italic\">\n {tier.note}\n </p>\n </div>\n ))}\n </div>\n </div>\n\n {/* Usage-based detail */}\n <div className=\"border-border space-y-4 border-t pt-6\">\n <div>\n <h3 className=\"text-lg font-bold\">\n Usage-based, with a generous free tier\n </h3>\n <p className=\"text-muted-foreground mt-2 text-sm\">\n Inspired by products like PostHog, we plan to keep a generous\n free tier on all plans, then charge based on actual usage:\n regenerations, AI agent actions, and the number of projects you\n run on ContractSpec.\n </p>\n <p className=\"text-muted-foreground mt-3 text-xs italic\">\n Free tier limits are intentionally small but useful: enough to\n try the agent and regenerate a real project, not enough to run a\n full team's workload for free.\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n {usageMetrics.map((metric) => (\n <div key={metric.name} className=\"card-subtle space-y-2 p-4\">\n <h4 className=\"text-sm font-semibold\">{metric.name}</h4>\n <p className=\"text-muted-foreground text-xs\">\n {metric.freeTier}\n </p>\n <p className=\"text-muted-foreground text-xs\">\n {metric.beyond}\n </p>\n </div>\n ))}\n </div>\n </div>\n\n {/* Footer / Disclaimer */}\n <div className=\"border-border space-y-4 border-t pt-6\">\n <p className=\"text-muted-foreground text-xs\">\n These numbers are examples only. Final pricing and limits will\n evolve as we learn from design partners.\n </p>\n <p className=\"text-muted-foreground text-xs\">\n This is a tentative pricing model. We're pre-PMF and pricing is\n still in draft, subject to change based on what we learn.\n </p>\n <p className=\"text-muted-foreground text-xs\">\n Design partners get early access and a founding discount when paid\n plans launch.\n </p>\n {onApplyClick && (\n <Button\n onClick={() => {\n onOpenChange(false);\n onApplyClick();\n }}\n className=\"w-full\"\n variant=\"outline\"\n >\n Apply as a design partner\n </Button>\n )}\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":";;;;;;;;;AA2BA,MAAM,eAA8B;CAClC;EACE,KAAK;EACL,OAAO;EACP,WAAW;EACX,SAAS;GACP;GACA;GACA,aAAa,iBAAiB,KAAK,sBAAsB;GACzD,aAAa,iBAAiB,KAAK,kBAAkB;GACrD;GACD;EACD,MAAM;EACP;CACD;EACE,KAAK;EACL,OAAO;EACP,WAAW;EACX,SAAS;GACP;GACA,6CAA6C,iBAAiB,QAAQ,0BAA0B;GAChG,wCAAwC,iBAAiB,QAAQ,sBAAsB;GACvF;GACA;GACD;EACD,MAAM;EACP;CACD;EACE,KAAK;EACL,OAAO;EACP,WAAW;EACX,SAAS;GACP;GACA;GACA;GACA;GACA;GACD;EACD,MAAM;EACP;CACF;AAED,MAAM,eAA8B;CAClC;EACE,MAAM;EACN,UAAU,oBAAoB,iBAAiB,KAAK,sBAAsB;EAC1E,QAAQ;EACT;CACD;EACE,MAAM;EACN,UAAU,oBAAoB,iBAAiB,KAAK,kBAAkB;EACtE,QAAQ;EACT;CACD;EACE,MAAM;EACN,UAAU,cAAc,iBAAiB,KAAK,SAAS;EACvD,QACE;EACH;CACF;AAQD,SAAgB,qBAAqB,EACnC,MACA,cACA,gBAC4B;AAC5B,QACE,oBAAC;EAAa;EAAoB;YAChC,qBAAC;GAAc,WAAU;cACvB,qBAAC,2BACC,oBAAC,yBAAY,yCAAkD,EAC/D,oBAAC,+BAAkB,qHAGC,IACP,EAEf,qBAAC;IAAI,WAAU;;KAEb,qBAAC;MAAI,WAAU;iBACb,qBAAC;OAAI,WAAU;;QACb,oBAAC;SAAK,WAAU;mBAA4C;UAErD;QACP,oBAAC;SAAK,WAAU;mBAAgC;UAAQ;QACxD,oBAAC;SAAK,WAAU;mBAAgC;UAEzC;;QACH,EACN,oBAAC;OAAI,WAAU;iBACZ,aAAa,KAAK,SACjB,qBAAC;QAEC,WAAU;;SAEV,oBAAC;UAAI,WAAU;oBACZ,KAAK;WACF;SACN,qBAAC;UAAI,WAAU;qBACb,oBAAC;WAAG,WAAU;qBAAqB,KAAK;YAAW,EACnD,oBAAC;WAAE,WAAU;qBACV,KAAK;YACJ;WACA;SACN,oBAAC;UAAG,WAAU;oBACX,KAAK,QAAQ,KAAK,QAAQ,MACzB,qBAAC;WAEC,WAAU;sBAEV,oBAAC;YACC,MAAM;YACN,WAAU;aACV,EACD;aAPI,EAQF,CACL;WACC;SACL,oBAAC;UAAE,WAAU;oBACV,KAAK;WACJ;;UA5BC,KAAK,MA6BN,CACN;QACE;OACF;KAGN,qBAAC;MAAI,WAAU;iBACb,qBAAC;OACC,oBAAC;QAAG,WAAU;kBAAoB;SAE7B;OACL,oBAAC;QAAE,WAAU;kBAAqC;SAK9C;OACJ,oBAAC;QAAE,WAAU;kBAA4C;SAIrD;UACA,EACN,oBAAC;OAAI,WAAU;iBACZ,aAAa,KAAK,WACjB,qBAAC;QAAsB,WAAU;;SAC/B,oBAAC;UAAG,WAAU;oBAAyB,OAAO;WAAU;SACxD,oBAAC;UAAE,WAAU;oBACV,OAAO;WACN;SACJ,oBAAC;UAAE,WAAU;oBACV,OAAO;WACN;;UAPI,OAAO,KAQX,CACN;QACE;OACF;KAGN,qBAAC;MAAI,WAAU;;OACb,oBAAC;QAAE,WAAU;kBAAgC;SAGzC;OACJ,oBAAC;QAAE,WAAU;kBAAgC;SAGzC;OACJ,oBAAC;QAAE,WAAU;kBAAgC;SAGzC;OACH,gBACC,oBAAC;QACC,eAAe;AACb,sBAAa,MAAM;AACnB,uBAAc;;QAEhB,WAAU;QACV,SAAQ;kBACT;SAEQ;;OAEP;;KACF;IACQ;GACT"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AudienceSection.js","names":[],"sources":["../../../../src/components/marketing/sections/AudienceSection.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n MarketingCard,\n MarketingCardContent,\n MarketingCardHeader,\n MarketingCardTitle,\n MarketingCardsSection,\n} from '@contractspec/lib.design-system';\nimport { VStack } from '@contractspec/lib.ui-kit-web/ui/stack';\nimport { Muted, Small } from '@contractspec/lib.ui-kit-web/ui/typography';\n\nconst audiences = [\n {\n tier: 'Tier 1: Priority',\n title: 'AI-Native Startups & Technical Founders',\n body: 'Solo founders or small teams using Cursor, Copilot, Claude, or AI agents heavily. Messy AI-generated backends and frontends, inconsistent APIs, code that is hard to refactor.',\n need: 'Need: A way to stabilize AI-generated code without rewriting it.',\n },\n {\n tier: 'Tier 1: Priority',\n title: 'Small Teams with AI-Generated Chaos',\n body: '2-10 person teams that shipped fast with AI and now have tech debt. Multiple surfaces out of sync, no source of truth, afraid to touch AI-generated code.',\n need: 'Need: Incremental stabilization, safe regeneration, contracts as guardrails.',\n },\n {\n tier: 'Tier 2: Growth',\n title: 'AI Dev Agencies',\n body: 'Agencies building many projects for clients using AI-assisted development. Repeating the same patterns, inconsistent quality across projects, handoff nightmares.',\n need: 'Need: Reusable templates, consistent contracts, professional handoff artifacts.',\n },\n {\n tier: 'Tier 2: Growth',\n title: 'Scaleups with Compliance Needs',\n body: \"Growing companies that need audit trails, API governance, or regulatory compliance. AI-generated code doesn't meet compliance requirements.\",\n need: 'Need: Governance layer, change tracking, contract enforcement.',\n },\n];\n\nexport function AudienceSection() {\n return (\n <MarketingCardsSection\n tone=\"default\"\n columns={2}\n eyebrow=\"Who It's For\"\n title=\"Built for teams drowning in AI-generated code\"\n maxWidth=\"xl\"\n >\n {audiences.map((item) => (\n <MarketingCard key={item.title} tone=\"muted\">\n <MarketingCardHeader className=\"space-y-2\">\n <Small className=\"font-semibold text-blue-400\">{item.tier}</Small>\n <MarketingCardTitle className=\"text-xl\">\n {item.title}\n </MarketingCardTitle>\n </MarketingCardHeader>\n <MarketingCardContent>\n <VStack gap=\"sm\">\n <Muted className=\"text-sm leading-relaxed\">{item.body}</Muted>\n <Small className=\"font-medium text-violet-400\">{item.need}</Small>\n </VStack>\n </MarketingCardContent>\n </MarketingCard>\n ))}\n </MarketingCardsSection>\n );\n}\n"],"mappings":";;;;;;;AAWA,MAAM,YAAY;CAChB;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,MAAM;EACP;CACD;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,MAAM;EACP;CACD;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,MAAM;EACP;CACD;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,MAAM;EACP;CACF;AAED,SAAgB,kBAAkB;AAChC,QACE,oBAAC;EACC,MAAK;EACL,SAAS;EACT,SAAQ;EACR,OAAM;EACN,UAAS;YAER,UAAU,KAAK,SACd,qBAAC;GAA+B,MAAK;cACnC,qBAAC;IAAoB,WAAU;eAC7B,oBAAC;KAAM,WAAU;eAA+B,KAAK;MAAa,EAClE,oBAAC;KAAmB,WAAU;eAC3B,KAAK;MACa;KACD,EACtB,oBAAC,kCACC,qBAAC;IAAO,KAAI;eACV,oBAAC;KAAM,WAAU;eAA2B,KAAK;MAAa,EAC9D,oBAAC;KAAM,WAAU;eAA+B,KAAK;MAAa;KAC3D,GACY;KAZL,KAAK,MAaT,CAChB;GACoB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CorePositioningSection.js","names":[],"sources":["../../../../src/components/marketing/sections/CorePositioningSection.tsx"],"sourcesContent":["import * as React from 'react';\nimport { MarketingSection, ButtonLink } from '@contractspec/lib.design-system';\nimport { VStack } from '@contractspec/lib.ui-kit-web/ui/stack';\nimport { H2, Lead, Small } from '@contractspec/lib.ui-kit-web/ui/typography';\nimport { ChevronRight } from 'lucide-react';\n\nexport function CorePositioningSection() {\n return (\n <MarketingSection\n tone=\"gradient\"\n padding=\"comfortable\"\n align=\"center\"\n maxWidth=\"lg\"\n >\n <VStack gap=\"md\" align=\"center\">\n <H2 className=\"text-center text-3xl font-bold md:text-4xl\">\n You keep your app.\n <br />\n We stabilize it, one module at a time.\n </H2>\n <Lead className=\"text-center\">\n You own the code. It's standard tech.\n <br />\n <Small className=\"font-semibold text-violet-400\">\n We're the compiler, not the prison.\n </Small>\n </Lead>\n <VStack\n as=\"div\"\n gap=\"sm\"\n align=\"center\"\n className=\"pt-2 sm:flex sm:flex-row sm:flex-wrap sm:items-center sm:justify-center\"\n >\n <ButtonLink href=\"/pricing#waitlist\">\n Join waitlist <ChevronRight size={16} />\n </ButtonLink>\n <ButtonLink variant=\"ghost\" href=\"/contact\">\n Book a call\n </ButtonLink>\n </VStack>\n </VStack>\n </MarketingSection>\n );\n}\n"],"mappings":";;;;;;;;AAMA,SAAgB,yBAAyB;AACvC,QACE,oBAAC;EACC,MAAK;EACL,SAAQ;EACR,OAAM;EACN,UAAS;YAET,qBAAC;GAAO,KAAI;GAAK,OAAM;;IACrB,qBAAC;KAAG,WAAU;;MAA6C;MAEzD,oBAAC,SAAK;;;MAEH;IACL,qBAAC;KAAK,WAAU;;MAAc;MAE5B,oBAAC,SAAK;MACN,oBAAC;OAAM,WAAU;iBAAgC;QAEzC;;MACH;IACP,qBAAC;KACC,IAAG;KACH,KAAI;KACJ,OAAM;KACN,WAAU;gBAEV,qBAAC;MAAW,MAAK;iBAAoB,kBACrB,oBAAC,gBAAa,MAAM,KAAM;OAC7B,EACb,oBAAC;MAAW,SAAQ;MAAQ,MAAK;gBAAW;OAE/B;MACN;;IACF;GACQ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CtaSection.js","names":[],"sources":["../../../../src/components/marketing/sections/CtaSection.tsx"],"sourcesContent":["import * as React from 'react';\nimport { MarketingSection, ButtonLink } from '@contractspec/lib.design-system';\nimport {\n analyticsEventNames,\n captureAnalyticsEvent,\n} from '@contractspec/bundle.library/libs/posthog/client';\nimport { VStack } from '@contractspec/lib.ui-kit-web/ui/stack';\nimport { H2, Lead } from '@contractspec/lib.ui-kit-web/ui/typography';\n\nexport function CtaSection() {\n return (\n <MarketingSection\n tone=\"gradient\"\n padding=\"comfortable\"\n align=\"center\"\n maxWidth=\"lg\"\n >\n <VStack gap=\"md\" align=\"center\" className=\"text-center\">\n <H2 className=\"text-4xl font-bold md:text-5xl\">\n Ready to stabilize your codebase?\n </H2>\n <Lead className=\"text-muted-foreground text-lg\">\n Start with one module. See the difference. Expand at your own pace.\n </Lead>\n <VStack\n as=\"div\"\n gap=\"sm\"\n align=\"center\"\n className=\"pt-2 sm:flex sm:flex-row sm:flex-wrap sm:items-center sm:justify-center\"\n >\n <ButtonLink\n href=\"/pricing#waitlist\"\n onClick={() =>\n captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {\n surface: 'cta-section',\n })\n }\n >\n Join waitlist\n </ButtonLink>\n <ButtonLink\n variant=\"ghost\"\n href=\"/contact\"\n onClick={() =>\n captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {\n surface: 'cta-section',\n variant: 'contact',\n })\n }\n >\n Book a call\n </ButtonLink>\n </VStack>\n </VStack>\n </MarketingSection>\n );\n}\n"],"mappings":";;;;;;;;AASA,SAAgB,aAAa;AAC3B,QACE,oBAAC;EACC,MAAK;EACL,SAAQ;EACR,OAAM;EACN,UAAS;YAET,qBAAC;GAAO,KAAI;GAAK,OAAM;GAAS,WAAU;;IACxC,oBAAC;KAAG,WAAU;eAAiC;MAE1C;IACL,oBAAC;KAAK,WAAU;eAAgC;MAEzC;IACP,qBAAC;KACC,IAAG;KACH,KAAI;KACJ,OAAM;KACN,WAAU;gBAEV,oBAAC;MACC,MAAK;MACL,eACE,sBAAsB,oBAAoB,kBAAkB,EAC1D,SAAS,eACV,CAAC;gBAEL;OAEY,EACb,oBAAC;MACC,SAAQ;MACR,MAAK;MACL,eACE,sBAAsB,oBAAoB,kBAAkB;OAC1D,SAAS;OACT,SAAS;OACV,CAAC;gBAEL;OAEY;MACN;;IACF;GACQ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DevelopersSection.js","names":[],"sources":["../../../../src/components/marketing/sections/DevelopersSection.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n ButtonLink,\n MarketingComparisonSection,\n} from '@contractspec/lib.design-system';\n\nconst standardTech = [\n 'TypeScript & Zod — schemas you already know',\n 'Prisma — standard database access',\n 'GraphQL or REST — your choice',\n 'React or any UI framework',\n 'Bun, Node, Deno — all supported',\n];\n\nconst noMagic = [\n 'Generated code is readable & modifiable',\n 'No proprietary runtime dependencies',\n 'Eject anytime, keep everything',\n 'Works with your existing CI/CD',\n 'Open spec format',\n];\n\nexport function DevelopersSection() {\n return (\n <MarketingComparisonSection\n tone=\"muted\"\n title=\"Built for developers\"\n padding=\"comfortable\"\n left={{ title: 'Standard Tech Stack', items: standardTech }}\n right={{ title: 'No Magic, No Lock-in', items: noMagic }}\n subtitle={\n <ButtonLink href=\"/docs\">\n Read the docs <span aria-hidden>→</span>\n </ButtonLink>\n }\n />\n );\n}\n"],"mappings":";;;;;AAMA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACD;AAED,MAAM,UAAU;CACd;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,oBAAoB;AAClC,QACE,oBAAC;EACC,MAAK;EACL,OAAM;EACN,SAAQ;EACR,MAAM;GAAE,OAAO;GAAuB,OAAO;GAAc;EAC3D,OAAO;GAAE,OAAO;GAAwB,OAAO;GAAS;EACxD,UACE,qBAAC;GAAW,MAAK;cAAQ,kBACT,oBAAC;IAAK;cAAY;KAAQ;IAC7B;GAEf"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FearsSection.js","names":[],"sources":["../../../../src/components/marketing/sections/FearsSection.tsx"],"sourcesContent":["import * as React from 'react';\nimport { CheckCircle, Code, Unlock, Zap } from 'lucide-react';\nimport { IconGridSection } from './IconGridSection';\n\nconst fears = [\n {\n title: '\"I already have an app\"',\n body: \"ContractSpec works with existing codebases. You don't start over — you stabilize incrementally, one module at a time. Start with one API endpoint, one data model, one contract.\",\n icon: CheckCircle,\n },\n {\n title: '\"Vendor lock-in / losing ownership\"',\n body: \"You own the generated code. It's standard TypeScript, standard SQL, standard GraphQL. ContractSpec is a compiler — like TypeScript itself. You can eject anytime.\",\n icon: Unlock,\n },\n {\n title: '\"Adoption cost / learning curve\"',\n body: 'Specs are just TypeScript. If you can write z.object({ name: z.string() }), you can write a ContractSpec. No new language, no magic DSL, no YAML.',\n icon: Code,\n },\n {\n title: '\"Forced migrations / magical runtime\"',\n body: \"ContractSpec generates plain code you can read, debug, and modify. There's no proprietary runtime. Migrations are explicit, reversible, and in your control.\",\n icon: Zap,\n },\n];\n\nexport function FearsSection() {\n return (\n <IconGridSection\n tone=\"muted\"\n columns={2}\n eyebrow=\"We Get It\"\n title=\"Your fears, addressed\"\n subtitle=\"We know what you're thinking. Here's why those concerns don't apply to ContractSpec.\"\n iconRole=\"support\"\n items={fears.map((item) => ({\n icon: item.icon,\n title: item.title,\n description: item.body,\n iconClassName: 'text-violet-400',\n }))}\n />\n );\n}\n"],"mappings":";;;;;;AAIA,MAAM,QAAQ;CACZ;EACE,OAAO;EACP,MAAM;EACN,MAAM;EACP;CACD;EACE,OAAO;EACP,MAAM;EACN,MAAM;EACP;CACD;EACE,OAAO;EACP,MAAM;EACN,MAAM;EACP;CACD;EACE,OAAO;EACP,MAAM;EACN,MAAM;EACP;CACF;AAED,SAAgB,eAAe;AAC7B,QACE,oBAAC;EACC,MAAK;EACL,SAAS;EACT,SAAQ;EACR,OAAM;EACN,UAAS;EACT,UAAS;EACT,OAAO,MAAM,KAAK,UAAU;GAC1B,MAAM,KAAK;GACX,OAAO,KAAK;GACZ,aAAa,KAAK;GAClB,eAAe;GAChB,EAAE;GACH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HeroMarketingSection.js","names":[],"sources":["../../../../src/components/marketing/sections/HeroMarketingSection.tsx"],"sourcesContent":["'use client';\n\nimport { ButtonLink, MarketingSection } from '@contractspec/lib.design-system';\nimport {\n analyticsEventNames,\n captureAnalyticsEvent,\n} from '@contractspec/bundle.library/libs/posthog/client';\nimport { Box, HStack, VStack } from '@contractspec/lib.ui-kit-web/ui/stack';\nimport { H1, Lead, Small } from '@contractspec/lib.ui-kit-web/ui/typography';\nimport { ChevronRight } from 'lucide-react';\n\nconst heroChips = ['Multi-Surface Sync', 'No Lock-in', 'Standard Tech'];\n\nexport function HeroMarketingSection() {\n return (\n <MarketingSection tone=\"gradient\" padding=\"spacious\" align=\"center\">\n <VStack gap=\"lg\" align=\"center\" className=\"text-center\">\n <Box\n as=\"div\"\n role=\"presentation\"\n className=\"bg-muted text-muted-foreground inline-flex items-center rounded-full px-3 py-1 text-xs font-medium tracking-wider uppercase\"\n >\n Open Source Core\n </Box>\n <H1 className=\"text-4xl leading-tight font-bold text-balance md:text-5xl\">\n Stabilize your AI-generated code\n </H1>\n <Lead className=\"text-muted-foreground text-lg text-balance md:text-xl\">\n ContractSpec is the compiler that keeps AI-written software coherent,\n safe, and regenerable. You keep your app. You own the code. One module\n at a time.\n </Lead>\n\n <HStack gap=\"md\" justify=\"center\" wrap=\"wrap\">\n <ButtonLink\n href=\"/install\"\n onClick={() =>\n captureAnalyticsEvent(analyticsEventNames.CTA_INSTALL_CLICK, {\n surface: 'hero',\n })\n }\n >\n Install OSS <ChevronRight size={16} />\n </ButtonLink>\n <ButtonLink\n variant=\"ghost\"\n href=\"/contact#waitlist\"\n onClick={() =>\n captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {\n surface: 'hero',\n })\n }\n >\n Join Studio Waitlist\n </ButtonLink>\n </HStack>\n\n <HStack gap=\"sm\" justify=\"center\" wrap=\"wrap\" className=\"pt-2\">\n {heroChips.map((chip) => (\n <Box\n key={chip}\n as=\"div\"\n role=\"presentation\"\n className=\"border-border text-foreground inline-flex items-center rounded-full border px-3 py-1 text-sm\"\n >\n <Small className=\"font-medium\">{chip}</Small>\n </Box>\n ))}\n </HStack>\n </VStack>\n </MarketingSection>\n );\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAM,YAAY;CAAC;CAAsB;CAAc;CAAgB;AAEvE,SAAgB,uBAAuB;AACrC,QACE,oBAAC;EAAiB,MAAK;EAAW,SAAQ;EAAW,OAAM;YACzD,qBAAC;GAAO,KAAI;GAAK,OAAM;GAAS,WAAU;;IACxC,oBAAC;KACC,IAAG;KACH,MAAK;KACL,WAAU;eACX;MAEK;IACN,oBAAC;KAAG,WAAU;eAA4D;MAErE;IACL,oBAAC;KAAK,WAAU;eAAwD;MAIjE;IAEP,qBAAC;KAAO,KAAI;KAAK,SAAQ;KAAS,MAAK;gBACrC,qBAAC;MACC,MAAK;MACL,eACE,sBAAsB,oBAAoB,mBAAmB,EAC3D,SAAS,QACV,CAAC;iBAEL,gBACa,oBAAC,gBAAa,MAAM,KAAM;OAC3B,EACb,oBAAC;MACC,SAAQ;MACR,MAAK;MACL,eACE,sBAAsB,oBAAoB,kBAAkB,EAC1D,SAAS,QACV,CAAC;gBAEL;OAEY;MACN;IAET,oBAAC;KAAO,KAAI;KAAK,SAAQ;KAAS,MAAK;KAAO,WAAU;eACrD,UAAU,KAAK,SACd,oBAAC;MAEC,IAAG;MACH,MAAK;MACL,WAAU;gBAEV,oBAAC;OAAM,WAAU;iBAAe;QAAa;QALxC,KAMD,CACN;MACK;;IACF;GACQ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IconGridSection.js","names":[],"sources":["../../../../src/components/marketing/sections/IconGridSection.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n MarketingCardsSection,\n MarketingIconCard,\n type MarketingCardTone,\n type MarketingSectionPadding,\n type MarketingSectionTone,\n} from '@contractspec/lib.design-system';\nimport { Muted } from '@contractspec/lib.ui-kit-web/ui/typography';\n\ntype IconComponent = React.ComponentType<{ className?: string; size?: number }>;\n\nexport interface IconGridItem {\n icon: IconComponent;\n title: string;\n description: string;\n iconClassName?: string;\n tone?: MarketingCardTone;\n}\n\ninterface IconGridSectionProps {\n eyebrow?: string;\n title: string;\n subtitle?: string;\n items: IconGridItem[];\n tone?: MarketingSectionTone;\n padding?: MarketingSectionPadding;\n columns?: 2 | 3 | 4;\n iconRole?: IconGridSectionRole;\n}\n\nconst itemVariants = cva('', {\n variants: {\n iconRole: {\n iconFirst: '',\n listing: 'items-start',\n support: 'items-start',\n },\n },\n defaultVariants: { iconRole: 'iconFirst' },\n});\n\nexport type IconGridSectionRole = VariantProps<typeof itemVariants>['iconRole'];\n\nexport function IconGridSection({\n eyebrow,\n title,\n subtitle,\n items,\n tone = 'default',\n padding,\n columns = 3,\n iconRole = 'iconFirst',\n}: IconGridSectionProps) {\n return (\n <MarketingCardsSection\n tone={tone}\n padding={padding}\n eyebrow={\n eyebrow ? (\n <Muted className=\"text-xs font-semibold tracking-[0.2em] uppercase\">\n {eyebrow}\n </Muted>\n ) : null\n }\n title={title}\n subtitle={subtitle ? <Muted className=\"text-lg\">{subtitle}</Muted> : null}\n columns={columns}\n >\n {items.map((card) => (\n <MarketingIconCard\n key={card.title}\n icon={card.icon}\n title={card.title}\n description={card.description}\n tone={card.tone}\n iconClassName={card.iconClassName}\n variant={\n iconRole === 'listing'\n ? 'listing'\n : iconRole === 'support'\n ? 'support'\n : 'iconFirst'\n }\n className={itemVariants({ iconRole })}\n />\n ))}\n </MarketingCardsSection>\n );\n}\n"],"mappings":";;;;;;;AAgCA,MAAM,eAAe,IAAI,IAAI;CAC3B,UAAU,EACR,UAAU;EACR,WAAW;EACX,SAAS;EACT,SAAS;EACV,EACF;CACD,iBAAiB,EAAE,UAAU,aAAa;CAC3C,CAAC;AAIF,SAAgB,gBAAgB,EAC9B,SACA,OACA,UACA,OACA,OAAO,WACP,SACA,UAAU,GACV,WAAW,eACY;AACvB,QACE,oBAAC;EACO;EACG;EACT,SACE,UACE,oBAAC;GAAM,WAAU;aACd;IACK,GACN;EAEC;EACP,UAAU,WAAW,oBAAC;GAAM,WAAU;aAAW;IAAiB,GAAG;EAC5D;YAER,MAAM,KAAK,SACV,oBAAC;GAEC,MAAM,KAAK;GACX,OAAO,KAAK;GACZ,aAAa,KAAK;GAClB,MAAM,KAAK;GACX,eAAe,KAAK;GACpB,SACE,aAAa,YACT,YACA,aAAa,YACX,YACA;GAER,WAAW,aAAa,EAAE,UAAU,CAAC;KAbhC,KAAK,MAcV,CACF;GACoB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"OutputsSection.js","names":[],"sources":["../../../../src/components/marketing/sections/OutputsSection.tsx"],"sourcesContent":["import * as React from 'react';\nimport { IconGridSection } from './IconGridSection';\n\nconst outputs = [\n {\n title: 'REST API',\n description:\n 'Type-safe endpoints with validation. Standard Express/Hono/Elysia handlers.',\n icon: '🔌',\n },\n {\n title: 'GraphQL Schema',\n description:\n 'Automatically generated resolvers. Standard Pothos/Apollo output.',\n icon: '📊',\n },\n {\n title: 'Database Schema',\n description: 'Prisma migrations and types. Standard SQL underneath.',\n icon: '🗄️',\n },\n {\n title: 'MCP Tools',\n description:\n 'AI agent tool definitions. Works with Claude, GPT, and any MCP client.',\n icon: '🤖',\n },\n {\n title: 'Client SDKs',\n description: 'Type-safe API clients. Standard fetch/axios underneath.',\n icon: '📦',\n },\n {\n title: 'UI Components',\n description: 'React forms and views from specs. Standard JSX output.',\n icon: '🎨',\n },\n];\n\nexport function OutputsSection() {\n return (\n <IconGridSection\n tone=\"muted\"\n columns={3}\n title=\"What ContractSpec generates\"\n subtitle=\"One contract, multiple outputs. All in sync. All standard tech.\"\n iconRole=\"iconFirst\"\n items={outputs.map((item) => ({\n icon: () => (\n <span aria-hidden className=\"text-3xl\">\n {item.icon}\n </span>\n ),\n title: item.title,\n description: item.description,\n }))}\n />\n );\n}\n"],"mappings":";;;;;AAGA,MAAM,UAAU;CACd;EACE,OAAO;EACP,aACE;EACF,MAAM;EACP;CACD;EACE,OAAO;EACP,aACE;EACF,MAAM;EACP;CACD;EACE,OAAO;EACP,aAAa;EACb,MAAM;EACP;CACD;EACE,OAAO;EACP,aACE;EACF,MAAM;EACP;CACD;EACE,OAAO;EACP,aAAa;EACb,MAAM;EACP;CACD;EACE,OAAO;EACP,aAAa;EACb,MAAM;EACP;CACF;AAED,SAAgB,iBAAiB;AAC/B,QACE,oBAAC;EACC,MAAK;EACL,SAAS;EACT,OAAM;EACN,UAAS;EACT,UAAS;EACT,OAAO,QAAQ,KAAK,UAAU;GAC5B,YACE,oBAAC;IAAK;IAAY,WAAU;cACzB,KAAK;KACD;GAET,OAAO,KAAK;GACZ,aAAa,KAAK;GACnB,EAAE;GACH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProblemSection.js","names":[],"sources":["../../../../src/components/marketing/sections/ProblemSection.tsx"],"sourcesContent":["import * as React from 'react';\nimport { IconGridSection, type IconGridItem } from './IconGridSection';\nimport { AlertTriangle, Layers, RefreshCw, XCircle } from 'lucide-react';\n\nconst problemItems: IconGridItem[] = [\n {\n icon: AlertTriangle,\n title: \"Can't enforce invariants\",\n description:\n 'AI-generated code drifts from business rules over time. No source of truth means no safety.',\n iconClassName: 'text-red-400',\n },\n {\n icon: Layers,\n title: 'Multi-surface chaos',\n description:\n 'API, DB, UI, and events get out of sync. One change breaks three surfaces.',\n iconClassName: 'text-orange-400',\n },\n {\n icon: RefreshCw,\n title: 'Hallucinated refactors',\n description:\n 'AI \"improvements\" introduce subtle bugs and break contracts you didn’t know existed.',\n iconClassName: 'text-amber-400',\n },\n {\n icon: XCircle,\n title: 'Unmaintainable spaghetti',\n description:\n 'Teams ship fast initially, then spend months untangling AI-generated chaos.',\n iconClassName: 'text-red-400',\n },\n];\n\nexport function ProblemSection() {\n return (\n <IconGridSection\n tone=\"muted\"\n columns={4}\n eyebrow=\"The Problem\"\n title=\"AI agents write code fast. Then the chaos begins.\"\n subtitle='In 2025, \"vibe coding\" and AI agents generate enormous amounts of code. But they have critical limitations that destroy long-term maintainability.'\n items={problemItems}\n />\n );\n}\n"],"mappings":";;;;;;AAIA,MAAM,eAA+B;CACnC;EACE,MAAM;EACN,OAAO;EACP,aACE;EACF,eAAe;EAChB;CACD;EACE,MAAM;EACN,OAAO;EACP,aACE;EACF,eAAe;EAChB;CACD;EACE,MAAM;EACN,OAAO;EACP,aACE;EACF,eAAe;EAChB;CACD;EACE,MAAM;EACN,OAAO;EACP,aACE;EACF,eAAe;EAChB;CACF;AAED,SAAgB,iBAAiB;AAC/B,QACE,oBAAC;EACC,MAAK;EACL,SAAS;EACT,SAAQ;EACR,OAAM;EACN,UAAS;EACT,OAAO;GACP"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SolutionSection.js","names":[],"sources":["../../../../src/components/marketing/sections/SolutionSection.tsx"],"sourcesContent":["import * as React from 'react';\nimport { IconGridSection, type IconGridItem } from './IconGridSection';\nimport { FileCode, Layers, RefreshCw, Shield } from 'lucide-react';\n\nconst solutionItems: IconGridItem[] = [\n {\n icon: FileCode,\n title: 'Canonical Source of Truth',\n description:\n 'Contracts define what the system should do, not just what it does. AI agents read specs, not implementations.',\n iconClassName: 'text-emerald-400',\n },\n {\n icon: Layers,\n title: 'Multi-Surface Consistency',\n description:\n 'One spec generates API, DB, UI, events, and MCP tools. All surfaces stay in sync because they share the same source.',\n iconClassName: 'text-blue-400',\n },\n {\n icon: RefreshCw,\n title: 'Safe Regeneration',\n description:\n 'Regenerate code anytime without fear. Specs enforce invariants. Breaking changes caught at compile time.',\n iconClassName: 'text-violet-400',\n },\n {\n icon: Shield,\n title: 'AI Governance',\n description:\n 'Constrain what AI agents can change. Enforce contracts they must respect. Flag violations automatically.',\n iconClassName: 'text-pink-400',\n },\n];\n\nexport function SolutionSection() {\n return (\n <IconGridSection\n tone=\"default\"\n columns={4}\n eyebrow=\"The Solution\"\n title=\"ContractSpec: The safety layer for AI-coded systems\"\n subtitle=\"Define contracts once. Generate consistent code across all surfaces. Regenerate safely anytime. No lock-in.\"\n items={solutionItems}\n />\n );\n}\n"],"mappings":";;;;;;AAIA,MAAM,gBAAgC;CACpC;EACE,MAAM;EACN,OAAO;EACP,aACE;EACF,eAAe;EAChB;CACD;EACE,MAAM;EACN,OAAO;EACP,aACE;EACF,eAAe;EAChB;CACD;EACE,MAAM;EACN,OAAO;EACP,aACE;EACF,eAAe;EAChB;CACD;EACE,MAAM;EACN,OAAO;EACP,aACE;EACF,eAAe;EAChB;CACF;AAED,SAAgB,kBAAkB;AAChC,QACE,oBAAC;EACC,MAAK;EACL,SAAS;EACT,SAAQ;EACR,OAAM;EACN,UAAS;EACT,OAAO;GACP"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StepsSection.js","names":[],"sources":["../../../../src/components/marketing/sections/StepsSection.tsx"],"sourcesContent":["import * as React from 'react';\nimport { IconGridSection } from './IconGridSection';\n\nconst steps = [\n {\n step: 1,\n title: 'Pick one module',\n description:\n 'Start with one API endpoint, one entity, one surface. No big-bang migration.',\n },\n {\n step: 2,\n title: 'Define the contract',\n description:\n 'Write a spec in TypeScript. Just types and Zod schemas you already know.',\n },\n {\n step: 3,\n title: 'Generate & compare',\n description:\n 'See what ContractSpec generates. Compare to your existing code. Keep what works.',\n },\n {\n step: 4,\n title: 'Expand gradually',\n description:\n 'Add more contracts as you see value. No pressure. No lock-in. Your pace.',\n },\n];\n\nexport function StepsSection() {\n return (\n <IconGridSection\n tone=\"default\"\n columns={4}\n title=\"How incremental adoption works\"\n padding=\"comfortable\"\n iconRole=\"listing\"\n items={steps.map((item) => ({\n icon: ({ className }) => (\n <div\n className={`bg-primary/15 flex h-10 w-10 items-center justify-center rounded-lg ${className ?? ''}`}\n >\n <span className=\"text-primary text-sm font-semibold\">\n {item.step}\n </span>\n </div>\n ),\n title: item.title,\n description: item.description,\n tone: 'muted',\n }))}\n />\n );\n}\n"],"mappings":";;;;;AAGA,MAAM,QAAQ;CACZ;EACE,MAAM;EACN,OAAO;EACP,aACE;EACH;CACD;EACE,MAAM;EACN,OAAO;EACP,aACE;EACH;CACD;EACE,MAAM;EACN,OAAO;EACP,aACE;EACH;CACD;EACE,MAAM;EACN,OAAO;EACP,aACE;EACH;CACF;AAED,SAAgB,eAAe;AAC7B,QACE,oBAAC;EACC,MAAK;EACL,SAAS;EACT,OAAM;EACN,SAAQ;EACR,UAAS;EACT,OAAO,MAAM,KAAK,UAAU;GAC1B,OAAO,EAAE,gBACP,oBAAC;IACC,WAAW,uEAAuE,aAAa;cAE/F,oBAAC;KAAK,WAAU;eACb,KAAK;MACD;KACH;GAER,OAAO,KAAK;GACZ,aAAa,KAAK;GAClB,MAAM;GACP,EAAE;GACH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"waitlist-section.js","names":[],"sources":["../../../src/components/marketing/waitlist-section.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport z from 'zod';\nimport { AlertCircle, CheckCircle } from 'lucide-react';\nimport { joinWaitlist } from '../../libs/email/waitlist';\nimport { submitWaitlistApplication } from '../../libs/email/waitlist-application';\nimport { Button } from '@contractspec/lib.design-system';\nimport { Textarea } from '@contractspec/lib.design-system';\nimport { Label } from '@contractspec/lib.ui-kit-web/ui/label';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@contractspec/lib.ui-kit-web/ui/select';\nimport { Checkbox } from '@contractspec/lib.ui-kit-web/ui/checkbox';\nimport { Switch } from '@contractspec/lib.ui-kit-web/ui/switch';\nimport { Input } from '@contractspec/lib.design-system';\n\ninterface WaitlistSectionProps {\n variant?: 'default' | 'compact';\n context?: 'pricing' | 'contact';\n scrollToId?: string;\n}\n\n// Zod schemas\nconst simpleWaitlistSchema = z.object({\n email: z.email('Please enter a valid email address'),\n});\n\nconst designPartnerSchema = z.object({\n name: z.string().min(1, 'Name is required'),\n email: z.email('Please enter a valid email address'),\n company: z.string().optional(),\n role: z.string().optional(),\n useCase: z.string().optional(),\n currentStack: z.string().optional(),\n whatBuilding: z.string().min(1, 'Please tell us what you are building'),\n whatSolving: z\n .string()\n .min(1, 'Please tell us what ContractSpec will solve for you'),\n teamSize: z.string().optional(),\n timeline: z.string().optional(),\n openToSessions: z.boolean().default(false),\n okayWithCaseStudies: z.boolean().default(false),\n});\n\ntype SimpleWaitlistFormData = z.infer<typeof simpleWaitlistSchema>;\ntype DesignPartnerFormData = z.infer<typeof designPartnerSchema>;\n\nexport function WaitlistSection({\n variant = 'default',\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n context = 'pricing',\n}: WaitlistSectionProps) {\n const [isDesignPartner, setIsDesignPartner] = useState(false);\n const [submitResult, setSubmitResult] = useState<{\n success: boolean;\n text: string;\n } | null>(null);\n const [isPending, setIsPending] = useState(false);\n\n // Simple waitlist form\n const simpleForm = useForm<SimpleWaitlistFormData>({\n resolver: zodResolver(simpleWaitlistSchema),\n defaultValues: {\n email: '',\n },\n });\n\n // Design partner form\n const designPartnerForm = useForm({\n resolver: zodResolver<\n z.input<typeof designPartnerSchema>,\n unknown,\n z.output<typeof designPartnerSchema>\n >(designPartnerSchema),\n defaultValues: {\n name: '',\n email: '',\n company: '',\n role: '',\n useCase: '',\n currentStack: '',\n whatBuilding: '',\n whatSolving: '',\n teamSize: '',\n timeline: '',\n openToSessions: false,\n okayWithCaseStudies: false,\n },\n });\n\n // Sync email between forms\n const simpleEmail = simpleForm.watch('email');\n const designPartnerEmail = designPartnerForm.watch('email');\n\n // Sync from simple form to design partner form\n useEffect(() => {\n const currentDesignPartnerEmail = designPartnerForm.getValues('email');\n if (simpleEmail && simpleEmail !== currentDesignPartnerEmail) {\n designPartnerForm.setValue('email', simpleEmail, { shouldDirty: false });\n }\n }, [simpleEmail, designPartnerForm]);\n\n // Sync from design partner form to simple form\n useEffect(() => {\n const currentSimpleEmail = simpleForm.getValues('email');\n if (designPartnerEmail && designPartnerEmail !== currentSimpleEmail) {\n simpleForm.setValue('email', designPartnerEmail, { shouldDirty: false });\n }\n }, [designPartnerEmail, simpleForm]);\n\n const handleSimpleSubmit = async (data: SimpleWaitlistFormData) => {\n setIsPending(true);\n setSubmitResult(null);\n\n try {\n const formData = new FormData();\n formData.set('email', data.email);\n\n const result = await joinWaitlist(formData);\n\n if (result.success) {\n setSubmitResult({\n success: true,\n text: 'Thanks for joining the waitlist! Check your inbox for a confirmation.',\n });\n simpleForm.reset();\n } else {\n setSubmitResult({\n success: false,\n text: result.text || 'Failed to join waitlist. Please try again.',\n });\n }\n } catch (_error) {\n setSubmitResult({\n success: false,\n text: 'Failed to join waitlist. Please try again.',\n });\n } finally {\n setIsPending(false);\n }\n };\n\n const handleDesignPartnerSubmit = async (data: DesignPartnerFormData) => {\n setIsPending(true);\n setSubmitResult(null);\n\n try {\n const formData = new FormData();\n formData.set('email', data.email);\n formData.set('name', data.name);\n if (data.company) formData.set('company', data.company);\n if (data.role) formData.set('role', data.role);\n if (data.useCase) formData.set('useCase', data.useCase);\n if (data.currentStack) formData.set('currentStack', data.currentStack);\n formData.set('whatBuilding', data.whatBuilding);\n formData.set('whatSolving', data.whatSolving);\n if (data.teamSize) formData.set('teamSize', data.teamSize);\n if (data.timeline) formData.set('timeline', data.timeline);\n if (data.openToSessions) formData.set('openToSessions', 'on');\n if (data.okayWithCaseStudies) formData.set('okayWithCaseStudies', 'on');\n\n const result = await submitWaitlistApplication(formData);\n\n if (result.success) {\n setSubmitResult({\n success: true,\n text: \"You're on the list. Thanks for applying. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.\",\n });\n designPartnerForm.reset();\n } else {\n setSubmitResult({\n success: false,\n text:\n result.text || 'Failed to submit application. Please try again.',\n });\n }\n } catch (_error) {\n setSubmitResult({\n success: false,\n text: 'Failed to submit application. Please try again.',\n });\n } finally {\n setIsPending(false);\n }\n };\n\n const onSubmit = isDesignPartner\n ? designPartnerForm.handleSubmit(handleDesignPartnerSubmit)\n : simpleForm.handleSubmit(handleSimpleSubmit);\n\n const isCompact = variant === 'compact';\n\n return (\n <div\n id=\"waitlist\"\n className={isCompact ? 'space-y-4' : 'card-subtle space-y-6 p-8'}\n >\n {!isCompact && (\n <div className=\"space-y-4\">\n <div className=\"inline-flex items-center gap-2 rounded-full border border-violet-500/20 bg-violet-500/10 px-3 py-1\">\n <span className=\"text-sm font-medium text-violet-300\">\n {isDesignPartner\n ? 'Design Partner Waitlist'\n : 'Join the Waitlist'}\n </span>\n </div>\n <h2 className=\"text-2xl font-bold\">\n {isDesignPartner\n ? 'Apply for early access to ContractSpec'\n : 'Get early access to ContractSpec'}\n </h2>\n <p className=\"text-muted-foreground text-sm\">\n {isDesignPartner\n ? \"Tell us what you're building. We'll prioritize teams where ContractSpec can have a big impact, and where we can learn the most.\"\n : 'Join the waitlist to be notified when ContractSpec becomes available.'}\n </p>\n </div>\n )}\n\n {!isCompact && (\n <div className=\"border-border bg-muted/20 flex items-center justify-between gap-4 rounded-lg border p-4\">\n <div className=\"space-y-1\">\n <Label\n htmlFor=\"design-partner-toggle\"\n className=\"text-sm font-medium\"\n >\n Apply as a design partner\n </Label>\n <p className=\"text-muted-foreground text-xs\">\n {isDesignPartner\n ? 'Get hands-on support, influence the roadmap, and founding discount'\n : 'Get priority access, 1:1 onboarding, and help shape ContractSpec'}\n </p>\n </div>\n <Switch\n id=\"design-partner-toggle\"\n checked={isDesignPartner}\n onCheckedChange={setIsDesignPartner}\n disabled={isPending || submitResult?.success}\n />\n </div>\n )}\n\n {!isCompact && isDesignPartner && (\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">Benefits:</p>\n <ul className=\"text-muted-foreground space-y-1 text-sm\">\n <li>• Early access to ContractSpec Studio</li>\n <li>• 1:1 onboarding and architecture sessions</li>\n <li>• Priority support via direct channels</li>\n <li>• Influence over roadmap and features</li>\n <li>• Founding discount when paid plans launch</li>\n </ul>\n </div>\n )}\n\n <form onSubmit={onSubmit} className=\"space-y-4\">\n {isDesignPartner ? (\n <>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"waitlist-name\" className=\"text-sm font-medium\">\n Name <span className=\"text-red-400\">*</span>\n </Label>\n <Input\n id=\"waitlist-name\"\n {...designPartnerForm.register('name')}\n type=\"text\"\n placeholder=\"Your name\"\n disabled={isPending || submitResult?.success}\n />\n {designPartnerForm.formState.errors.name && (\n <p className=\"text-xs text-red-400\">\n {designPartnerForm.formState.errors.name.message}\n </p>\n )}\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"waitlist-email\" className=\"text-sm font-medium\">\n Email <span className=\"text-red-400\">*</span>\n </Label>\n <Input\n id=\"waitlist-email\"\n {...designPartnerForm.register('email')}\n type=\"email\"\n placeholder=\"your@email.com\"\n disabled={isPending || submitResult?.success}\n />\n {designPartnerForm.formState.errors.email && (\n <p className=\"text-xs text-red-400\">\n {designPartnerForm.formState.errors.email.message}\n </p>\n )}\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label\n htmlFor=\"waitlist-company\"\n className=\"text-sm font-medium\"\n >\n Company / Project Name\n </Label>\n <Input\n id=\"waitlist-company\"\n {...designPartnerForm.register('company')}\n type=\"text\"\n placeholder=\"Your company or project\"\n disabled={isPending || submitResult?.success}\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"waitlist-role\" className=\"text-sm font-medium\">\n Role\n </Label>\n <Select\n value={designPartnerForm.watch('role') || ''}\n onValueChange={(value) =>\n designPartnerForm.setValue('role', value)\n }\n disabled={isPending || submitResult?.success}\n >\n <SelectTrigger id=\"waitlist-role\" className=\"w-full\">\n <SelectValue placeholder=\"Select your role\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"founder\">Founder</SelectItem>\n <SelectItem value=\"cto\">CTO</SelectItem>\n <SelectItem value=\"lead-engineer\">Lead Engineer</SelectItem>\n <SelectItem value=\"engineer\">Engineer</SelectItem>\n <SelectItem value=\"product-manager\">\n Product Manager\n </SelectItem>\n <SelectItem value=\"other\">Other</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label\n htmlFor=\"waitlist-use-case\"\n className=\"text-sm font-medium\"\n >\n Primary use case\n </Label>\n <Select\n value={designPartnerForm.watch('useCase') || ''}\n onValueChange={(value) =>\n designPartnerForm.setValue('useCase', value)\n }\n disabled={isPending || submitResult?.success}\n >\n <SelectTrigger id=\"waitlist-use-case\" className=\"w-full\">\n <SelectValue placeholder=\"Select a use case\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"api-platform\">API platform</SelectItem>\n <SelectItem value=\"ai-ops\">AI operations</SelectItem>\n <SelectItem value=\"integration-hub\">\n Integration hub\n </SelectItem>\n <SelectItem value=\"internal-tools\">\n Internal tools\n </SelectItem>\n <SelectItem value=\"data-pipelines\">\n Data pipelines\n </SelectItem>\n <SelectItem value=\"other\">Other</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-2\">\n <Label\n htmlFor=\"waitlist-current-stack\"\n className=\"text-sm font-medium\"\n >\n Current stack\n </Label>\n <Input\n id=\"waitlist-current-stack\"\n {...designPartnerForm.register('currentStack')}\n type=\"text\"\n placeholder=\"e.g. Next.js, Postgres, OpenAPI\"\n disabled={isPending || submitResult?.success}\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label\n htmlFor=\"waitlist-what-building\"\n className=\"text-sm font-medium\"\n >\n What are you building with AI today?{' '}\n <span className=\"text-red-400\">*</span>\n </Label>\n <Textarea\n id=\"waitlist-what-building\"\n {...designPartnerForm.register('whatBuilding')}\n placeholder=\"Tell us about your project...\"\n disabled={isPending || submitResult?.success}\n rows={4}\n />\n {designPartnerForm.formState.errors.whatBuilding && (\n <p className=\"text-xs text-red-400\">\n {designPartnerForm.formState.errors.whatBuilding.message}\n </p>\n )}\n </div>\n\n <div className=\"space-y-2\">\n <Label\n htmlFor=\"waitlist-what-solving\"\n className=\"text-sm font-medium\"\n >\n What do you hope ContractSpec will solve for you?{' '}\n <span className=\"text-red-400\">*</span>\n </Label>\n <Textarea\n id=\"waitlist-what-solving\"\n {...designPartnerForm.register('whatSolving')}\n placeholder=\"What problems are you trying to solve?\"\n disabled={isPending || submitResult?.success}\n rows={4}\n />\n {designPartnerForm.formState.errors.whatSolving && (\n <p className=\"text-xs text-red-400\">\n {designPartnerForm.formState.errors.whatSolving.message}\n </p>\n )}\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label\n htmlFor=\"waitlist-team-size\"\n className=\"text-sm font-medium\"\n >\n Team Size\n </Label>\n <Select\n value={designPartnerForm.watch('teamSize') || ''}\n onValueChange={(value) =>\n designPartnerForm.setValue('teamSize', value)\n }\n disabled={isPending || submitResult?.success}\n >\n <SelectTrigger id=\"waitlist-team-size\" className=\"w-full\">\n <SelectValue placeholder=\"Select team size\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"solo\">Solo</SelectItem>\n <SelectItem value=\"2-5\">2-5</SelectItem>\n <SelectItem value=\"6-20\">6-20</SelectItem>\n <SelectItem value=\"20+\">20+</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-2\">\n <Label\n htmlFor=\"waitlist-timeline\"\n className=\"text-sm font-medium\"\n >\n Timeline\n </Label>\n <Select\n value={designPartnerForm.watch('timeline') || ''}\n onValueChange={(value) =>\n designPartnerForm.setValue('timeline', value)\n }\n disabled={isPending || submitResult?.success}\n >\n <SelectTrigger id=\"waitlist-timeline\" className=\"w-full\">\n <SelectValue placeholder=\"Select timeline\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"now\">Now</SelectItem>\n <SelectItem value=\"1-3-months\">1-3 months</SelectItem>\n <SelectItem value=\"3-6-months\">3-6 months</SelectItem>\n <SelectItem value=\"exploring\">Exploring</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"space-y-3\">\n <div className=\"flex items-start gap-3\">\n <Checkbox\n id=\"waitlist-open-to-sessions\"\n checked={designPartnerForm.watch('openToSessions')}\n onCheckedChange={(checked) =>\n designPartnerForm.setValue(\n 'openToSessions',\n checked === true\n )\n }\n disabled={isPending || submitResult?.success}\n />\n <Label\n htmlFor=\"waitlist-open-to-sessions\"\n className=\"cursor-pointer text-sm leading-relaxed\"\n >\n I'm open to 1:1 product/design sessions\n </Label>\n </div>\n\n <div className=\"flex items-start gap-3\">\n <Checkbox\n id=\"waitlist-case-studies\"\n checked={designPartnerForm.watch('okayWithCaseStudies')}\n onCheckedChange={(checked) =>\n designPartnerForm.setValue(\n 'okayWithCaseStudies',\n checked === true\n )\n }\n disabled={isPending || submitResult?.success}\n />\n <Label\n htmlFor=\"waitlist-case-studies\"\n className=\"cursor-pointer text-sm leading-relaxed\"\n >\n I'm okay with anonymized case studies about our usage\n </Label>\n </div>\n </div>\n </>\n ) : (\n <div className=\"space-y-2\">\n <Label htmlFor=\"waitlist-email\" className=\"text-sm font-medium\">\n Email <span className=\"text-red-400\">*</span>\n </Label>\n <Input\n id=\"waitlist-email\"\n {...simpleForm.register('email')}\n type=\"email\"\n placeholder=\"your@email.com\"\n disabled={isPending || submitResult?.success}\n />\n {simpleForm.formState.errors.email && (\n <p className=\"text-xs text-red-400\">\n {simpleForm.formState.errors.email.message}\n </p>\n )}\n </div>\n )}\n\n {submitResult && !isPending && (\n <div\n className={`flex items-start gap-2 rounded-lg p-4 text-sm ${\n submitResult.success\n ? 'border border-green-500/20 bg-green-500/10 text-green-400'\n : 'border border-red-500/20 bg-red-500/10 text-red-400'\n }`}\n >\n {submitResult.success ? (\n <CheckCircle size={20} className=\"mt-0.5 shrink-0\" />\n ) : (\n <AlertCircle size={20} className=\"mt-0.5 shrink-0\" />\n )}\n <div className=\"flex-1\">\n {submitResult.success ? (\n <>\n <p className=\"mb-1 font-semibold\">You're on the list.</p>\n <p className=\"text-sm\">{submitResult.text}</p>\n </>\n ) : (\n <p>{submitResult.text}</p>\n )}\n </div>\n </div>\n )}\n\n <Button\n type=\"submit\"\n disabled={isPending || submitResult?.success}\n className=\"w-full\"\n >\n {isPending\n ? 'Submitting...'\n : isDesignPartner\n ? 'Apply to the waitlist'\n : 'Join waitlist'}\n </Button>\n\n <p className=\"text-muted-foreground text-center text-xs\">\n No spam. We'll only email you about ContractSpec and your application.\n </p>\n </form>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TemplatesClientPage.js","names":[],"sources":["../../../src/components/templates/TemplatesClientPage.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { Search } from 'lucide-react';\nimport { cn } from '@contractspec/lib.ui-kit-core/utils';\nimport Link from 'next/link';\nimport type {\n RegistryTemplate,\n TemplateId,\n} from '@contractspec/lib.example-shared-ui';\nimport { useRegistryTemplates } from '@contractspec/lib.example-shared-ui';\nimport { getTemplate } from '@contractspec/module.examples';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@contractspec/lib.ui-kit-web/ui/tooltip';\nimport {\n analyticsEventNames,\n captureAnalyticsEvent,\n} from '@contractspec/bundle.library/libs/posthog/client';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@contractspec/lib.ui-kit-web/ui/dialog';\nimport { WaitlistSection } from '../marketing';\nimport { TemplatePreviewModal } from './TemplatesPreviewModal';\n\nconst templates = [\n {\n id: 'minimal-example',\n templateId: 'todos-app' as TemplateId,\n title: 'Minimal Example',\n description:\n 'A minimal template to get you running in minutes. Perfect for exploring the engine.',\n tags: ['Getting Started'],\n capabilities: 'Basic Forms, Auth',\n isStarter: true,\n previewUrl: '/sandbox?template=minimal-example',\n docsUrl: '/docs/getting-started/hello-world',\n },\n // ============================================\n // Phase 1 Examples (using cross-cutting modules)\n // ============================================\n {\n id: 'saas-boilerplate',\n templateId: 'saas-boilerplate' as TemplateId,\n title: 'SaaS Boilerplate',\n description:\n 'Complete SaaS foundation with multi-tenant orgs, projects, settings, and billing usage.',\n tags: ['Getting Started', 'SaaS', 'Business'],\n capabilities: 'Multi-tenancy, RBAC, Projects, Billing',\n isNew: true,\n previewUrl: '/sandbox?template=saas-boilerplate',\n docsUrl: '/docs/templates/saas-boilerplate',\n },\n {\n id: 'crm-pipeline',\n templateId: 'crm-pipeline' as TemplateId,\n title: 'CRM Pipeline',\n description:\n 'Sales CRM with contacts, companies, deals, pipeline stages, and task management.',\n tags: ['CRM', 'Business'],\n capabilities: 'Contacts, Deals, Pipelines, Tasks',\n isNew: true,\n previewUrl: '/sandbox?template=crm-pipeline',\n docsUrl: '/docs/templates/crm-pipeline',\n },\n {\n id: 'agent-console',\n templateId: 'agent-console' as TemplateId,\n title: 'AI Agent Console',\n description:\n 'AI agent orchestration platform with tools, agents, runs, and execution logs.',\n tags: ['AI', 'Ops'],\n capabilities: 'Tools, Agents, Runs, Metrics',\n isNew: true,\n previewUrl: '/sandbox?template=agent-console',\n docsUrl: '/docs/templates/agent-console',\n },\n // ============================================\n // Phase 2-4 Examples\n // ============================================\n {\n id: 'workflow-system',\n templateId: 'workflow-system' as TemplateId,\n title: 'Workflow / Approval System',\n description:\n 'Multi-step workflows with role-based approvals and state transitions.',\n tags: ['Business', 'Ops'],\n capabilities: 'Workflows, Approvals, State Machine',\n isNew: true,\n previewUrl: '/sandbox?template=workflow-system',\n docsUrl: '/docs/templates/workflow-system',\n },\n {\n id: 'marketplace',\n templateId: 'marketplace' as TemplateId,\n title: 'Marketplace',\n description:\n 'Two-sided marketplace with stores, products, orders, and payouts.',\n tags: ['Business', 'Payments'],\n capabilities: 'Stores, Products, Orders, Payouts',\n isNew: true,\n previewUrl: '/sandbox?template=marketplace',\n docsUrl: '/docs/templates/marketplace',\n },\n {\n id: 'integration-hub',\n templateId: 'integration-hub' as TemplateId,\n title: 'Integration Hub',\n description:\n 'Third-party integrations with connections, sync configs, and field mapping.',\n tags: ['Ops', 'AI'],\n capabilities: 'Integrations, Connections, Sync',\n isNew: true,\n previewUrl: '/sandbox?template=integration-hub',\n docsUrl: '/docs/templates/integration-hub',\n },\n // ============================================\n // Learning Journeys\n // ============================================\n {\n id: 'learning-journey-studio-onboarding',\n templateId: 'learning-journey-studio-onboarding' as TemplateId,\n title: 'Learning Journey — Studio Getting Started',\n description:\n 'First 30 minutes in Studio: choose template, edit spec, regenerate, playground, evolution.',\n tags: ['Learning', 'Onboarding'],\n capabilities: 'Spec-first onboarding, XP/streak, progress widget',\n isNew: true,\n previewUrl: '/sandbox?template=learning-journey-studio-onboarding',\n docsUrl: '/docs/templates/learning-journey-studio-onboarding',\n },\n {\n id: 'learning-journey-platform-tour',\n templateId: 'learning-journey-platform-tour' as TemplateId,\n title: 'Learning Journey — Platform Primitives Tour',\n description:\n 'Touch identity, audit, notifications, jobs, flags, files, metering once with guided steps.',\n tags: ['Learning', 'Platform'],\n capabilities: 'Cross-module tour with event-driven completion',\n isNew: true,\n previewUrl: '/sandbox?template=learning-journey-platform-tour',\n docsUrl: '/docs/templates/learning-journey-platform-tour',\n },\n {\n id: 'learning-journey-crm-onboarding',\n templateId: 'learning-journey-crm-onboarding' as TemplateId,\n title: 'Learning Journey — CRM First Win',\n description:\n 'Get to first closed-won deal: pipeline, contact/company, deal, stages, follow-up.',\n tags: ['Learning', 'CRM'],\n capabilities: 'CRM onboarding with XP/streak/badge',\n isNew: true,\n previewUrl: '/sandbox?template=learning-journey-crm-onboarding',\n docsUrl: '/docs/templates/learning-journey-crm-onboarding',\n },\n {\n id: 'analytics-dashboard',\n templateId: 'analytics-dashboard' as TemplateId,\n title: 'Analytics Dashboard',\n description:\n 'Custom dashboards with widgets, saved queries, and real-time visualization.',\n tags: ['Business', 'Ops'],\n capabilities: 'Dashboards, Widgets, Queries',\n isNew: true,\n previewUrl: '/sandbox?template=analytics-dashboard',\n docsUrl: '/docs/templates/analytics-dashboard',\n },\n // ============================================\n // Classic Templates\n // ============================================\n {\n id: 'plumber-ops',\n templateId: 'messaging-app' as TemplateId,\n title: 'Plumber Ops',\n description:\n 'Complete workflow: Quotes → Deposit → Job → Invoice → Payment. Policy-enforced approvals.',\n tags: ['Trades', 'Payments'],\n capabilities: 'Quotes, Jobs, Invoicing, Payments',\n previewUrl: '/sandbox?template=plumber-ops',\n docsUrl: '/docs/specs/workflows',\n },\n {\n id: 'coliving-management',\n templateId: 'recipe-app-i18n' as TemplateId,\n title: 'Coliving Management',\n description:\n 'Coliving management: Onboarding, chores, shared wallet. Multi-party approvals built-in.',\n tags: ['Coliving', 'Finance'],\n capabilities: 'Tasks, Approvals, Payments',\n previewUrl: '/sandbox?template=coliving-management',\n docsUrl: '/docs/specs/workflows',\n },\n {\n id: 'chores-allowance',\n templateId: 'todos-app' as TemplateId,\n title: 'Chores & Allowance',\n description:\n 'Family task management with approval workflows. Teach financial accountability safely.',\n tags: ['Family', 'Ops'],\n capabilities: 'Tasks, Approvals, Notifications',\n previewUrl: '/sandbox?template=chores-allowance',\n docsUrl: '/docs/specs/workflows',\n },\n {\n id: 'service-dispatch',\n templateId: 'messaging-app' as TemplateId,\n title: 'Service Dispatch',\n description:\n 'Field service scheduling, routing, and invoicing. Real-time coordination with policy gates.',\n tags: ['Ops', 'Trades'],\n capabilities: 'Scheduling, Maps, Invoicing',\n previewUrl: '/sandbox?template=service-dispatch',\n docsUrl: '/docs/specs/workflows',\n },\n {\n id: 'content-review',\n templateId: 'todos-app' as TemplateId,\n title: 'Content Review',\n description:\n 'Multi-stage approval workflow for content. Audit trail for every decision.',\n tags: ['Ops'],\n capabilities: 'Workflows, Approvals, Comments',\n previewUrl: '/sandbox?template=content-review',\n docsUrl: '/docs/specs/workflows',\n },\n];\ntype LocalTemplate = (typeof templates)[number];\n\nconst allTags = [\n 'Getting Started',\n 'SaaS',\n 'Business',\n 'CRM',\n 'AI',\n 'Trades',\n 'Coliving',\n 'Family',\n 'Ops',\n 'Payments',\n 'Learning',\n 'Platform',\n];\n\nexport const TemplatesPage = () => {\n const [selectedTag, setSelectedTag] = useState<string | null>(null);\n const [search, setSearch] = useState('');\n const [preview, setPreview] = useState<TemplateId | null>(null);\n const [waitlistModalOpen, setWaitlistModalOpen] = useState(false);\n const [source, setSource] = useState<'local' | 'registry'>('local');\n const [selectedTemplateForCommand, setSelectedTemplateForCommand] = useState<\n RegistryTemplate | LocalTemplate | null\n >(null);\n\n const { data: registryTemplates = [], isLoading: registryLoading } =\n useRegistryTemplates();\n\n const filtered = templates.filter((t) => {\n const matchTag = !selectedTag || t.tags.includes(selectedTag);\n const matchSearch =\n !search ||\n t.title.toLowerCase().includes(search.toLowerCase()) ||\n t.description.toLowerCase().includes(search.toLowerCase());\n return matchTag && matchSearch;\n });\n\n const commandId = selectedTemplateForCommand\n ? 'templateId' in selectedTemplateForCommand\n ? selectedTemplateForCommand.templateId\n : selectedTemplateForCommand.id\n : '';\n\n return (\n <TooltipProvider>\n <main className=\"\">\n {/* Hero */}\n <section className=\"section-padding hero-gradient border-border relative border-b\">\n <div className=\"mx-auto max-w-4xl space-y-6 text-center\">\n <h1 className=\"text-5xl leading-tight font-bold md:text-6xl\">\n Recipe templates\n </h1>\n <p className=\"text-muted-foreground text-lg\">\n Ready-to-use, customizable recipes. Policies built in. One-click\n deploy.\n </p>\n </div>\n </section>\n\n {/* Search & Filter */}\n <section className=\"section-padding border-border border-b\">\n <div className=\"mx-auto max-w-6xl space-y-6\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"text-muted-foreground text-sm\">Source:</div>\n <div className=\"flex gap-2\">\n <button\n onClick={() => setSource('local')}\n className={cn(\n 'rounded-full px-4 py-2 text-sm font-medium transition-colors',\n {\n 'bg-violet-500 text-white': source === 'local',\n 'bg-card border-border hover:bg-card/80 border':\n source !== 'local',\n }\n )}\n aria-pressed={source === 'local'}\n >\n Local\n </button>\n <button\n onClick={() => setSource('registry')}\n className={cn(\n 'rounded-full px-4 py-2 text-sm font-medium transition-colors',\n {\n 'bg-violet-500 text-white': source === 'registry',\n 'bg-card border-border hover:bg-card/80 border':\n source !== 'registry',\n }\n )}\n aria-pressed={source === 'registry'}\n >\n Community\n </button>\n </div>\n </div>\n <div className=\"relative\">\n <Search\n className=\"text-muted-foreground absolute top-3 left-3\"\n size={20}\n />\n <input\n type=\"text\"\n placeholder=\"Search templates...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"bg-card border-border w-full rounded-lg border py-3 pr-4 pl-10 focus:ring-2 focus:ring-violet-500 focus:outline-none\"\n aria-label=\"Search templates\"\n />\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <button\n onClick={() => setSelectedTag(null)}\n className={`rounded-full px-4 py-2 text-sm font-medium transition-colors ${\n selectedTag === null\n ? 'bg-violet-500 text-white'\n : 'bg-card border-border hover:bg-card/80 border'\n }`}\n aria-pressed={selectedTag === null}\n >\n All\n </button>\n {allTags.map((tag) => (\n <button\n key={tag}\n onClick={() => setSelectedTag(tag)}\n className={cn(\n `rounded-full px-4 py-2 text-sm font-medium transition-colors`,\n {\n 'bg-violet-500 text-white': selectedTag === tag,\n 'bg-card border-border hover:bg-card/80 border':\n selectedTag !== tag,\n }\n )}\n aria-pressed={selectedTag === tag}\n >\n {tag}\n </button>\n ))}\n </div>\n </div>\n </section>\n\n {/* Templates Grid */}\n <section className=\"section-padding\">\n <div className=\"mx-auto max-w-6xl\">\n {source === 'registry' ? (\n registryLoading ? (\n <div className=\"py-12 text-center\">\n <p className=\"text-muted-foreground\">\n Loading community templates…\n </p>\n </div>\n ) : registryTemplates.length === 0 ? (\n <div className=\"py-12 text-center\">\n <p className=\"text-muted-foreground\">\n No community templates found (configure\n `NEXT_PUBLIC_CONTRACTSPEC_REGISTRY_URL`).\n </p>\n </div>\n ) : (\n <div className=\"grid gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {registryTemplates.map((t) => (\n <div\n key={t.id}\n className=\"card-subtle relative flex flex-col space-y-4 p-6 transition-colors hover:border-violet-500/50\"\n >\n <div>\n <h3 className=\"text-lg font-bold\">{t.name}</h3>\n <p className=\"text-muted-foreground mt-1 text-sm\">\n {t.description}\n </p>\n </div>\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex flex-wrap gap-1\">\n {t.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded border border-violet-500/20 bg-violet-500/10 px-2 py-1 text-xs text-violet-300\"\n >\n {tag}\n </span>\n ))}\n </div>\n </div>\n <div className=\"flex gap-2 pt-4\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n className=\"btn-ghost flex-1 text-center text-xs\"\n onClick={() => {\n const local = getTemplate(t.id as TemplateId);\n if (!local) {\n setSelectedTemplateForCommand(t);\n return;\n }\n setPreview(t.id as TemplateId);\n }}\n >\n Preview\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <p>Preview this template (if available locally)</p>\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n className=\"btn-primary flex-1 text-center text-xs\"\n onClick={() => {\n captureAnalyticsEvent(\n analyticsEventNames.EXAMPLE_REPO_OPEN,\n {\n surface: 'templates',\n templateId: t.id,\n source: 'registry',\n }\n );\n setSelectedTemplateForCommand(t);\n }}\n >\n Use Template\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <p>Get CLI command</p>\n </TooltipContent>\n </Tooltip>\n </div>\n </div>\n ))}\n </div>\n )\n ) : filtered.length === 0 ? (\n <div className=\"py-12 text-center\">\n <p className=\"text-muted-foreground\">\n No templates match your filters. Try a different search.\n </p>\n </div>\n ) : (\n <div className=\"grid gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {filtered.map((template, i) => (\n <div\n key={i}\n className=\"card-subtle relative flex flex-col space-y-4 p-6 transition-colors hover:border-violet-500/50\"\n >\n {'isNew' in template && template.isNew && (\n <span className=\"absolute top-3 right-3 rounded-full bg-green-500 px-2 py-0.5 text-xs font-semibold text-white\">\n New\n </span>\n )}\n <div>\n <h3 className=\"text-lg font-bold\">{template.title}</h3>\n <p className=\"text-muted-foreground mt-1 text-sm\">\n {template.description}\n </p>\n </div>\n <div className=\"flex-1 space-y-2\">\n <p className=\"text-muted-foreground text-xs\">\n <span className=\"text-foreground font-medium\">\n Capabilities:\n </span>{' '}\n {template.capabilities}\n </p>\n <div className=\"flex flex-wrap gap-1\">\n {template.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded border border-violet-500/20 bg-violet-500/10 px-2 py-1 text-xs text-violet-300\"\n >\n {tag}\n </span>\n ))}\n </div>\n </div>\n <div className=\"flex gap-2 pt-4\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n className=\"btn-ghost flex-1 text-center text-xs\"\n onClick={() => setPreview(template.templateId)}\n >\n Preview\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <p>Preview this template in a modal</p>\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n className=\"btn-primary flex-1 text-center text-xs\"\n onClick={() => {\n captureAnalyticsEvent(\n analyticsEventNames.EXAMPLE_REPO_OPEN,\n {\n surface: 'templates',\n templateId: template.templateId,\n source: 'local',\n }\n );\n setSelectedTemplateForCommand(template);\n }}\n >\n Use Template\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <p>Get CLI command</p>\n </TooltipContent>\n </Tooltip>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n </section>\n\n {/* Extend with Integrations & Knowledge */}\n <section className=\"section-padding border-border bg-striped border-t\">\n <div className=\"mx-auto max-w-6xl space-y-8\">\n <div className=\"space-y-4 text-center\">\n <h2 className=\"text-3xl font-bold md:text-4xl\">\n Extend templates with integrations & knowledge\n </h2>\n <p className=\"text-muted-foreground mx-auto max-w-2xl\">\n Every template can be enhanced with built-in integrations and\n knowledge spaces. Add payments, email, AI, and structured\n knowledge without writing integration code.\n </p>\n </div>\n <div className=\"grid gap-6 md:grid-cols-3\">\n <div className=\"card-subtle space-y-4 p-6\">\n <div className=\"text-3xl\">💳</div>\n <h3 className=\"font-bold\">Add Payments</h3>\n <p className=\"text-muted-foreground text-sm\">\n Connect Stripe to any template for payment processing,\n subscriptions, and invoicing. Type-safe and policy-enforced.\n </p>\n <Link\n href=\"/docs/integrations/stripe\"\n className=\"inline-flex items-center gap-1 text-sm text-violet-400 hover:text-violet-300\"\n >\n Learn more →\n </Link>\n </div>\n <div className=\"card-subtle space-y-4 p-6\">\n <div className=\"text-3xl\">📧</div>\n <h3 className=\"font-bold\">Add Notifications</h3>\n <p className=\"text-muted-foreground text-sm\">\n Send transactional emails via Postmark or Resend. Process\n inbound emails with Gmail API. SMS via Twilio.\n </p>\n <Link\n href=\"/docs/integrations\"\n className=\"inline-flex items-center gap-1 text-sm text-violet-400 hover:text-violet-300\"\n >\n View integrations →\n </Link>\n </div>\n <div className=\"card-subtle space-y-4 p-6\">\n <div className=\"text-3xl\">🧠</div>\n <h3 className=\"font-bold\">Add AI & Knowledge</h3>\n <p className=\"text-muted-foreground text-sm\">\n Power templates with OpenAI, vector search via Qdrant, and\n structured knowledge spaces for context-aware workflows.\n </p>\n <Link\n href=\"/docs/knowledge\"\n className=\"inline-flex items-center gap-1 text-sm text-violet-400 hover:text-violet-300\"\n >\n Learn about knowledge →\n </Link>\n </div>\n </div>\n <div className=\"pt-4 text-center\">\n <p className=\"text-muted-foreground mb-4 text-sm\">\n All integrations are configured per-tenant with automatic health\n checks and credential rotation.\n </p>\n <Link href=\"/docs/architecture\" className=\"btn-primary\">\n View Architecture\n </Link>\n </div>\n </div>\n </section>\n </main>\n\n {/*{preview ? (*/}\n <TemplatePreviewModal\n templateId={preview}\n onClose={() => {\n setPreview(null);\n }}\n />\n {/*) : null}*/}\n\n <Dialog open={waitlistModalOpen} onOpenChange={setWaitlistModalOpen}>\n <DialogContent className=\"max-h-[90vh] max-w-2xl overflow-y-auto\">\n <DialogHeader>\n <DialogTitle>Early Access Required</DialogTitle>\n <DialogDescription>\n ContractSpec Studio is in early access. Join the waitlist to\n deploy projects to our managed cloud.\n </DialogDescription>\n </DialogHeader>\n <WaitlistSection variant=\"compact\" />\n </DialogContent>\n </Dialog>\n\n <Dialog\n open={!!selectedTemplateForCommand}\n onOpenChange={() => setSelectedTemplateForCommand(null)}\n >\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>Use this template</DialogTitle>\n <DialogDescription>\n Initialize a new project with this template using the CLI.\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4 pt-4\">\n <div className=\"rounded-md border border-zinc-800 bg-zinc-950 p-4 font-mono text-sm text-zinc-50\">\n npx contractspec init --template {commandId}\n </div>\n <div className=\"flex gap-2\">\n <button\n className=\"btn-secondary w-full\"\n onClick={() => {\n navigator.clipboard.writeText(\n `npx contractspec init --template ${commandId}`\n );\n captureAnalyticsEvent(\n analyticsEventNames.COPY_COMMAND_CLICK,\n {\n surface: 'templates',\n templateId: commandId,\n filename: 'templates-cli',\n }\n );\n }}\n >\n Copy Command\n </button>\n </div>\n <div className=\"relative\">\n <div className=\"absolute inset-0 flex items-center\">\n <span className=\"border-border w-full border-t\" />\n </div>\n <div className=\"relative flex justify-center text-xs uppercase\">\n <span className=\"bg-background text-muted-foreground px-2\">\n Or\n </span>\n </div>\n </div>\n <button\n className=\"btn-ghost w-full text-sm\"\n onClick={() => {\n captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {\n surface: 'templates',\n templateId: commandId,\n });\n setSelectedTemplateForCommand(null);\n setWaitlistModalOpen(true);\n }}\n >\n Deploy to Studio (Waitlist)\n </button>\n </div>\n </DialogContent>\n </Dialog>\n </TooltipProvider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TemplatesPage.js","names":[],"sources":["../../../src/components/templates/TemplatesPage.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo, useState } from 'react';\nimport {\n Button,\n ButtonLink,\n Input,\n MarketingCard,\n MarketingCardContent,\n MarketingCardDescription,\n MarketingCardHeader,\n MarketingCardTitle,\n MarketingSection,\n} from '@contractspec/lib.design-system';\nimport { HStack, VStack } from '@contractspec/lib.ui-kit-web/ui/stack';\nimport { listTemplates } from '@contractspec/module.examples';\nimport type { TemplateDefinition } from '@contractspec/lib.example-shared-ui';\n\nfunction matchesQuery(t: TemplateDefinition, query: string): boolean {\n const q = query.trim().toLowerCase();\n if (!q) return true;\n const hay =\n `${t.id} ${t.name} ${t.description} ${t.tags.join(' ')}`.toLowerCase();\n return hay.includes(q);\n}\n\nexport function TemplatesMarketingPage() {\n const [query, setQuery] = useState('');\n\n const templates = useMemo(() => listTemplates(), []);\n const filtered = useMemo(\n () => templates.filter((t) => matchesQuery(t, query)),\n [templates, query]\n );\n\n return (\n <>\n <MarketingSection tone=\"default\">\n <VStack as=\"header\" gap=\"lg\" align=\"center\">\n <VStack gap=\"sm\" align=\"center\">\n <ButtonLink href=\"/docs\" variant=\"ghost\">\n Docs\n </ButtonLink>\n <ButtonLink href=\"/sandbox\" variant=\"ghost\">\n Open Sandbox\n </ButtonLink>\n </VStack>\n <VStack gap=\"sm\" align=\"center\">\n <ButtonLink href=\"/templates\" variant=\"default\">\n Templates\n </ButtonLink>\n </VStack>\n </VStack>\n </MarketingSection>\n\n <MarketingSection tone=\"muted\">\n <VStack gap=\"lg\">\n <VStack gap=\"sm\">\n <ButtonLink href=\"/templates\" variant=\"ghost\">\n Browse all examples\n </ButtonLink>\n </VStack>\n <HStack gap=\"md\" align=\"center\" justify=\"between\" wrap=\"wrap\">\n <Input\n aria-label=\"Search templates and examples\"\n placeholder=\"Search templates and examples…\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n </HStack>\n </VStack>\n </MarketingSection>\n\n <MarketingSection tone=\"default\">\n <VStack gap=\"lg\">\n <HStack gap=\"md\" wrap=\"wrap\">\n {filtered.map((t) => (\n <MarketingCard\n key={t.id}\n className=\"w-full md:w-[calc(50%-0.75rem)] lg:w-[calc(33.333%-1rem)]\"\n >\n <MarketingCardHeader>\n <MarketingCardTitle>\n {t.icon} {t.name}\n </MarketingCardTitle>\n <MarketingCardDescription>\n {t.description}\n </MarketingCardDescription>\n </MarketingCardHeader>\n <MarketingCardContent>\n <VStack gap=\"md\">\n <HStack gap=\"sm\" wrap=\"wrap\">\n {t.tags.slice(0, 6).map((tag: string) => (\n <ButtonLink\n key={`${t.id}-${tag}`}\n href={`/templates?tag=${encodeURIComponent(tag)}`}\n variant=\"ghost\"\n >\n {tag}\n </ButtonLink>\n ))}\n </HStack>\n <HStack gap=\"sm\" justify=\"between\" wrap=\"wrap\">\n <ButtonLinkToSandbox templateId={t.id} />\n <Button variant=\"outline\" onClick={() => void 0} disabled>\n Install to Studio (soon)\n </Button>\n </HStack>\n </VStack>\n </MarketingCardContent>\n </MarketingCard>\n ))}\n </HStack>\n </VStack>\n </MarketingSection>\n </>\n );\n}\n\nfunction ButtonLinkToSandbox({ templateId }: { templateId: string }) {\n return (\n <ButtonLink\n href={`/sandbox?template=${encodeURIComponent(templateId)}`}\n variant=\"default\"\n >\n Preview\n </ButtonLink>\n );\n}\n"],"mappings":";;;;;;;;;AAkBA,SAAS,aAAa,GAAuB,OAAwB;CACnE,MAAM,IAAI,MAAM,MAAM,CAAC,aAAa;AACpC,KAAI,CAAC,EAAG,QAAO;AAGf,QADE,GAAG,EAAE,GAAG,GAAG,EAAE,KAAK,GAAG,EAAE,YAAY,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,aAAa,CAC7D,SAAS,EAAE;;AAGxB,SAAgB,yBAAyB;CACvC,MAAM,CAAC,OAAO,YAAY,SAAS,GAAG;CAEtC,MAAM,YAAY,cAAc,eAAe,EAAE,EAAE,CAAC;CACpD,MAAM,WAAW,cACT,UAAU,QAAQ,MAAM,aAAa,GAAG,MAAM,CAAC,EACrD,CAAC,WAAW,MAAM,CACnB;AAED,QACE;EACE,oBAAC;GAAiB,MAAK;aACrB,qBAAC;IAAO,IAAG;IAAS,KAAI;IAAK,OAAM;eACjC,qBAAC;KAAO,KAAI;KAAK,OAAM;gBACrB,oBAAC;MAAW,MAAK;MAAQ,SAAQ;gBAAQ;OAE5B,EACb,oBAAC;MAAW,MAAK;MAAW,SAAQ;gBAAQ;OAE/B;MACN,EACT,oBAAC;KAAO,KAAI;KAAK,OAAM;eACrB,oBAAC;MAAW,MAAK;MAAa,SAAQ;gBAAU;OAEnC;MACN;KACF;IACQ;EAEnB,oBAAC;GAAiB,MAAK;aACrB,qBAAC;IAAO,KAAI;eACV,oBAAC;KAAO,KAAI;eACV,oBAAC;MAAW,MAAK;MAAa,SAAQ;gBAAQ;OAEjC;MACN,EACT,oBAAC;KAAO,KAAI;KAAK,OAAM;KAAS,SAAQ;KAAU,MAAK;eACrD,oBAAC;MACC,cAAW;MACX,aAAY;MACZ,OAAO;MACP,WAAW,MAAM,SAAS,EAAE,OAAO,MAAM;OACzC;MACK;KACF;IACQ;EAEnB,oBAAC;GAAiB,MAAK;aACrB,oBAAC;IAAO,KAAI;cACV,oBAAC;KAAO,KAAI;KAAK,MAAK;eACnB,SAAS,KAAK,MACb,qBAAC;MAEC,WAAU;iBAEV,qBAAC,kCACC,qBAAC;OACE,EAAE;OAAK;OAAE,EAAE;UACO,EACrB,oBAAC,sCACE,EAAE,cACsB,IACP,EACtB,oBAAC,kCACC,qBAAC;OAAO,KAAI;kBACV,oBAAC;QAAO,KAAI;QAAK,MAAK;kBACnB,EAAE,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,QACvB,oBAAC;SAEC,MAAM,kBAAkB,mBAAmB,IAAI;SAC/C,SAAQ;mBAEP;WAJI,GAAG,EAAE,GAAG,GAAG,MAKL,CACb;SACK,EACT,qBAAC;QAAO,KAAI;QAAK,SAAQ;QAAU,MAAK;mBACtC,oBAAC,uBAAoB,YAAY,EAAE,KAAM,EACzC,oBAAC;SAAO,SAAQ;SAAU,eAAe,KAAK;SAAG;mBAAS;UAEjD;SACF;QACF,GACY;QA/BlB,EAAE,GAgCO,CAChB;MACK;KACF;IACQ;KAClB;;AAIP,SAAS,oBAAoB,EAAE,cAAsC;AACnE,QACE,oBAAC;EACC,MAAM,qBAAqB,mBAAmB,WAAW;EACzD,SAAQ;YACT;GAEY"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TemplatesPreviewModal.js","names":[],"sources":["../../../src/components/templates/TemplatesPreviewModal.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\n\nimport dynamic from 'next/dynamic';\nimport { Dialog, DialogContent } from '@contractspec/lib.ui-kit-web/ui/dialog';\nimport { ScrollArea } from '@contractspec/lib.ui-kit-web/ui/scroll-area';\nimport { LoadingSpinner } from '@contractspec/lib.ui-kit-web/ui/atoms/LoadingSpinner';\nimport type { TemplateId } from '@contractspec/lib.example-shared-ui';\n\n// Dynamically import template components with ssr: false\nconst TemplateShell = dynamic(\n () =>\n import('@contractspec/lib.example-shared-ui').then(\n (mod) => mod.TemplateShell\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\nconst TodosTaskList = dynamic(\n () =>\n import('@contractspec/bundle.library/components/templates/todos/TaskList').then(\n (mod) => mod.TaskList\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\nconst MessagingWorkspace = dynamic(\n () =>\n import('@contractspec/bundle.library/components/templates/messaging/MessagingWorkspace').then(\n (mod) => mod.MessagingWorkspace\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\nconst RecipesExperience = dynamic(\n () =>\n import('@contractspec/bundle.library/components/templates/recipes/RecipeList').then(\n (mod) => mod.RecipeList\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\nconst SaasDashboard = dynamic(\n () =>\n import('@contractspec/example.saas-boilerplate').then(\n (mod) => mod.SaasDashboard\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\nconst CrmDashboard = dynamic(\n () =>\n import('@contractspec/example.crm-pipeline').then(\n (mod) => mod.CrmDashboard\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\nconst AgentDashboard = dynamic(\n () =>\n import('@contractspec/example.agent-console/ui').then(\n (mod) => mod.AgentDashboard\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\nconst WorkflowDashboard = dynamic(\n () =>\n import('@contractspec/example.workflow-system/ui').then(\n (mod) => mod.WorkflowDashboard\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\nconst MarketplaceDashboard = dynamic(\n () =>\n import('@contractspec/example.marketplace/ui').then(\n (mod) => mod.MarketplaceDashboard\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\nconst IntegrationDashboard = dynamic(\n () =>\n import('@contractspec/example.integration-hub/ui').then(\n (mod) => mod.IntegrationDashboard\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\nconst AnalyticsDashboard = dynamic(\n () =>\n import('@contractspec/example.analytics-dashboard').then(\n (mod) => mod.AnalyticsDashboard\n ),\n { ssr: false, loading: () => <LoadingSpinner /> }\n);\n\ninterface TemplatePreviewModalProps {\n templateId: TemplateId | null;\n onClose: () => void;\n}\n//\n// return (\n// <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/70 px-4 py-10\">\n// <div className=\"bg-background relative h-full max-h-[90vh] w-full max-w-5xl overflow-y-auto rounded-3xl p-6 shadow-2xl\">\n// <button\n// type=\"button\"\n// className=\"btn-ghost absolute top-4 right-4 text-sm\"\n// onClick={onClose}\n// >\n// Close\n// </button>\n// {previewComponent}\n// </div>\n// </div>\n// );\n// };\n\nexport const TemplatePreviewModal = ({\n templateId,\n onClose,\n}: TemplatePreviewModalProps) => {\n const previewComponent = useMemo(() => {\n switch (templateId) {\n case 'todos-app':\n return (\n <TemplateShell\n title=\"Starter tasks\"\n description=\"Track work items with filters, priorities, and per-tenant data isolation.\"\n showSaveAction={false}\n >\n <TodosTaskList />\n </TemplateShell>\n );\n case 'messaging-app':\n return (\n <TemplateShell\n title=\"Messaging workspace\"\n description=\"Realtime-ready messaging surface with optimistic delivery.\"\n showSaveAction={false}\n >\n <MessagingWorkspace />\n </TemplateShell>\n );\n case 'recipe-app-i18n':\n return (\n <TemplateShell\n title=\"Ceremony recipes\"\n description=\"Switch locales and preview how rituals translate across teams.\"\n showSaveAction={false}\n >\n <RecipesExperience />\n </TemplateShell>\n );\n case 'saas-boilerplate':\n return (\n <TemplateShell\n title=\"SaaS Boilerplate\"\n description=\"Multi-tenant organizations, projects, settings, and billing usage tracking.\"\n showSaveAction={false}\n >\n <SaasDashboard />\n </TemplateShell>\n );\n case 'crm-pipeline':\n return (\n <TemplateShell\n title=\"CRM Pipeline\"\n description=\"Sales CRM with contacts, companies, deals, and pipeline stages.\"\n showSaveAction={false}\n >\n <CrmDashboard />\n </TemplateShell>\n );\n case 'agent-console':\n return (\n <TemplateShell\n title=\"AI Agent Console\"\n description=\"AI agent orchestration with tools, agents, runs, and execution logs.\"\n showSaveAction={false}\n >\n <AgentDashboard />\n </TemplateShell>\n );\n case 'workflow-system':\n return (\n <TemplateShell\n title=\"Workflow System\"\n description=\"Multi-step workflows with role-based approvals.\"\n showSaveAction={false}\n >\n <WorkflowDashboard />\n </TemplateShell>\n );\n case 'marketplace':\n return (\n <TemplateShell\n title=\"Marketplace\"\n description=\"Two-sided marketplace with stores, products, and orders.\"\n showSaveAction={false}\n >\n <MarketplaceDashboard />\n </TemplateShell>\n );\n case 'integration-hub':\n return (\n <TemplateShell\n title=\"Integration Hub\"\n description=\"Third-party integrations with sync and field mapping.\"\n showSaveAction={false}\n >\n <IntegrationDashboard />\n </TemplateShell>\n );\n case 'analytics-dashboard':\n return (\n <TemplateShell\n title=\"Analytics Dashboard\"\n description=\"Custom dashboards with widgets and queries.\"\n showSaveAction={false}\n >\n <AnalyticsDashboard />\n </TemplateShell>\n );\n case null:\n return null;\n default:\n return null;\n }\n }, [templateId]);\n\n return (\n <Dialog open={!!previewComponent} onOpenChange={onClose}>\n {/*<DialogTrigger asChild>*/}\n {/* <Button variant=\"outline\">Fullscreen Dialog</Button>*/}\n {/*</DialogTrigger>*/}\n <DialogContent className=\"mb-8 flex h-[calc(100vh-2rem)] min-w-[calc(100vw-2rem)] flex-col justify-between gap-0 p-0\">\n <ScrollArea className=\"flex flex-col justify-between overflow-hidden\">\n {/*<DialogHeader className=\"contents space-y-0 text-left\">*/}\n {/* <DialogTitle className=\"px-6 pt-6\">Product Information</DialogTitle>*/}\n {/* <DialogDescription asChild>*/}\n {/* </DialogDescription>*/}\n {/*</DialogHeader>*/}\n {previewComponent}\n </ScrollArea>\n {/*<DialogFooter className=\"px-6 pb-6 sm:justify-end\">*/}\n {/* <DialogClose asChild>*/}\n {/* <Button variant=\"outline\">*/}\n {/* <ChevronLeftIcon />*/}\n {/* Back*/}\n {/* </Button>*/}\n {/* </DialogClose>*/}\n {/* <Button type=\"button\">Read More</Button>*/}\n {/*</DialogFooter>*/}\n </DialogContent>\n </Dialog>\n );\n};\n"],"mappings":"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"}
|