@contractspec/bundle.marketing 1.12.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.
Files changed (216) hide show
  1. package/.turbo/turbo-build$colon$types.log +1 -0
  2. package/.turbo/turbo-build.log +175 -0
  3. package/.turbo/turbo-lint.log +3 -0
  4. package/AGENTS.md +36 -0
  5. package/CHANGELOG.md +416 -0
  6. package/README.md +57 -0
  7. package/dist/components/marketing/ChangelogPage.d.ts +21 -0
  8. package/dist/components/marketing/ChangelogPage.d.ts.map +1 -0
  9. package/dist/components/marketing/ChangelogPage.js +65 -0
  10. package/dist/components/marketing/ChangelogPage.js.map +1 -0
  11. package/dist/components/marketing/CofounderPage.d.ts +7 -0
  12. package/dist/components/marketing/CofounderPage.d.ts.map +1 -0
  13. package/dist/components/marketing/CofounderPage.js +468 -0
  14. package/dist/components/marketing/CofounderPage.js.map +1 -0
  15. package/dist/components/marketing/ContactClient.d.ts +7 -0
  16. package/dist/components/marketing/ContactClient.d.ts.map +1 -0
  17. package/dist/components/marketing/ContactClient.js +158 -0
  18. package/dist/components/marketing/ContactClient.js.map +1 -0
  19. package/dist/components/marketing/ContributePage.d.ts +9 -0
  20. package/dist/components/marketing/ContributePage.d.ts.map +1 -0
  21. package/dist/components/marketing/ContributePage.js +362 -0
  22. package/dist/components/marketing/ContributePage.js.map +1 -0
  23. package/dist/components/marketing/DesignPartnerPage.d.ts +9 -0
  24. package/dist/components/marketing/DesignPartnerPage.d.ts.map +1 -0
  25. package/dist/components/marketing/DesignPartnerPage.js +215 -0
  26. package/dist/components/marketing/DesignPartnerPage.js.map +1 -0
  27. package/dist/components/marketing/LandingPage.d.ts +7 -0
  28. package/dist/components/marketing/LandingPage.d.ts.map +1 -0
  29. package/dist/components/marketing/LandingPage.js +38 -0
  30. package/dist/components/marketing/LandingPage.js.map +1 -0
  31. package/dist/components/marketing/PricingClient.d.ts +7 -0
  32. package/dist/components/marketing/PricingClient.d.ts.map +1 -0
  33. package/dist/components/marketing/PricingClient.js +521 -0
  34. package/dist/components/marketing/PricingClient.js.map +1 -0
  35. package/dist/components/marketing/ProductClientPage.d.ts +7 -0
  36. package/dist/components/marketing/ProductClientPage.d.ts.map +1 -0
  37. package/dist/components/marketing/ProductClientPage.js +460 -0
  38. package/dist/components/marketing/ProductClientPage.js.map +1 -0
  39. package/dist/components/marketing/index.d.ts +11 -0
  40. package/dist/components/marketing/index.js +12 -0
  41. package/dist/components/marketing/pricing-thinking-modal.d.ts +16 -0
  42. package/dist/components/marketing/pricing-thinking-modal.d.ts.map +1 -0
  43. package/dist/components/marketing/pricing-thinking-modal.js +202 -0
  44. package/dist/components/marketing/pricing-thinking-modal.js.map +1 -0
  45. package/dist/components/marketing/sections/AudienceSection.d.ts +7 -0
  46. package/dist/components/marketing/sections/AudienceSection.d.ts.map +1 -0
  47. package/dist/components/marketing/sections/AudienceSection.js +68 -0
  48. package/dist/components/marketing/sections/AudienceSection.js.map +1 -0
  49. package/dist/components/marketing/sections/CorePositioningSection.d.ts +7 -0
  50. package/dist/components/marketing/sections/CorePositioningSection.d.ts.map +1 -0
  51. package/dist/components/marketing/sections/CorePositioningSection.js +59 -0
  52. package/dist/components/marketing/sections/CorePositioningSection.js.map +1 -0
  53. package/dist/components/marketing/sections/CtaSection.d.ts +7 -0
  54. package/dist/components/marketing/sections/CtaSection.d.ts.map +1 -0
  55. package/dist/components/marketing/sections/CtaSection.js +54 -0
  56. package/dist/components/marketing/sections/CtaSection.js.map +1 -0
  57. package/dist/components/marketing/sections/DevelopersSection.d.ts +7 -0
  58. package/dist/components/marketing/sections/DevelopersSection.d.ts.map +1 -0
  59. package/dist/components/marketing/sections/DevelopersSection.js +45 -0
  60. package/dist/components/marketing/sections/DevelopersSection.js.map +1 -0
  61. package/dist/components/marketing/sections/FearsSection.d.ts +7 -0
  62. package/dist/components/marketing/sections/FearsSection.d.ts.map +1 -0
  63. package/dist/components/marketing/sections/FearsSection.js +48 -0
  64. package/dist/components/marketing/sections/FearsSection.js.map +1 -0
  65. package/dist/components/marketing/sections/HeroMarketingSection.d.ts +7 -0
  66. package/dist/components/marketing/sections/HeroMarketingSection.d.ts.map +1 -0
  67. package/dist/components/marketing/sections/HeroMarketingSection.js +77 -0
  68. package/dist/components/marketing/sections/HeroMarketingSection.js.map +1 -0
  69. package/dist/components/marketing/sections/IconGridSection.d.ts +45 -0
  70. package/dist/components/marketing/sections/IconGridSection.d.ts.map +1 -0
  71. package/dist/components/marketing/sections/IconGridSection.js +44 -0
  72. package/dist/components/marketing/sections/IconGridSection.js.map +1 -0
  73. package/dist/components/marketing/sections/OutputsSection.d.ts +7 -0
  74. package/dist/components/marketing/sections/OutputsSection.d.ts.map +1 -0
  75. package/dist/components/marketing/sections/OutputsSection.js +59 -0
  76. package/dist/components/marketing/sections/OutputsSection.js.map +1 -0
  77. package/dist/components/marketing/sections/ProblemSection.d.ts +7 -0
  78. package/dist/components/marketing/sections/ProblemSection.d.ts.map +1 -0
  79. package/dist/components/marketing/sections/ProblemSection.js +46 -0
  80. package/dist/components/marketing/sections/ProblemSection.js.map +1 -0
  81. package/dist/components/marketing/sections/SolutionSection.d.ts +7 -0
  82. package/dist/components/marketing/sections/SolutionSection.d.ts.map +1 -0
  83. package/dist/components/marketing/sections/SolutionSection.js +46 -0
  84. package/dist/components/marketing/sections/SolutionSection.js.map +1 -0
  85. package/dist/components/marketing/sections/StepsSection.d.ts +7 -0
  86. package/dist/components/marketing/sections/StepsSection.d.ts.map +1 -0
  87. package/dist/components/marketing/sections/StepsSection.js +52 -0
  88. package/dist/components/marketing/sections/StepsSection.js.map +1 -0
  89. package/dist/components/marketing/waitlist-section.d.ts +15 -0
  90. package/dist/components/marketing/waitlist-section.d.ts.map +1 -0
  91. package/dist/components/marketing/waitlist-section.js +578 -0
  92. package/dist/components/marketing/waitlist-section.js.map +1 -0
  93. package/dist/components/templates/TemplatesClientPage.d.ts +7 -0
  94. package/dist/components/templates/TemplatesClientPage.d.ts.map +1 -0
  95. package/dist/components/templates/TemplatesClientPage.js +625 -0
  96. package/dist/components/templates/TemplatesClientPage.js.map +1 -0
  97. package/dist/components/templates/TemplatesPage.d.ts +7 -0
  98. package/dist/components/templates/TemplatesPage.d.ts.map +1 -0
  99. package/dist/components/templates/TemplatesPage.js +125 -0
  100. package/dist/components/templates/TemplatesPage.js.map +1 -0
  101. package/dist/components/templates/TemplatesPreviewModal.d.ts +15 -0
  102. package/dist/components/templates/TemplatesPreviewModal.d.ts.map +1 -0
  103. package/dist/components/templates/TemplatesPreviewModal.js +137 -0
  104. package/dist/components/templates/TemplatesPreviewModal.js.map +1 -0
  105. package/dist/components/templates/index.d.ts +4 -0
  106. package/dist/components/templates/index.js +5 -0
  107. package/dist/index.d.ts +29 -0
  108. package/dist/index.js +28 -0
  109. package/dist/libs/email/client.d.ts +15 -0
  110. package/dist/libs/email/client.d.ts.map +1 -0
  111. package/dist/libs/email/client.js +113 -0
  112. package/dist/libs/email/client.js.map +1 -0
  113. package/dist/libs/email/contact.d.ts +7 -0
  114. package/dist/libs/email/contact.d.ts.map +1 -0
  115. package/dist/libs/email/contact.js +71 -0
  116. package/dist/libs/email/contact.js.map +1 -0
  117. package/dist/libs/email/newsletter.d.ts +7 -0
  118. package/dist/libs/email/newsletter.d.ts.map +1 -0
  119. package/dist/libs/email/newsletter.js +95 -0
  120. package/dist/libs/email/newsletter.js.map +1 -0
  121. package/dist/libs/email/types.d.ts +53 -0
  122. package/dist/libs/email/types.d.ts.map +1 -0
  123. package/dist/libs/email/types.js +1 -0
  124. package/dist/libs/email/utils.d.ts +6 -0
  125. package/dist/libs/email/utils.d.ts.map +1 -0
  126. package/dist/libs/email/utils.js +7 -0
  127. package/dist/libs/email/utils.js.map +1 -0
  128. package/dist/libs/email/waitlist-application.d.ts +7 -0
  129. package/dist/libs/email/waitlist-application.d.ts.map +1 -0
  130. package/dist/libs/email/waitlist-application.js +170 -0
  131. package/dist/libs/email/waitlist-application.js.map +1 -0
  132. package/dist/libs/email/waitlist.d.ts +7 -0
  133. package/dist/libs/email/waitlist.d.ts.map +1 -0
  134. package/dist/libs/email/waitlist.js +105 -0
  135. package/dist/libs/email/waitlist.js.map +1 -0
  136. package/dist/libs/pricing-examples.d.ts +22 -0
  137. package/dist/libs/pricing-examples.d.ts.map +1 -0
  138. package/dist/libs/pricing-examples.js +21 -0
  139. package/dist/libs/pricing-examples.js.map +1 -0
  140. package/dist/registry/engine.d.ts +17 -0
  141. package/dist/registry/engine.d.ts.map +1 -0
  142. package/dist/registry/engine.js +24 -0
  143. package/dist/registry/engine.js.map +1 -0
  144. package/dist/registry/factory.d.ts +64 -0
  145. package/dist/registry/factory.d.ts.map +1 -0
  146. package/dist/registry/factory.js +61 -0
  147. package/dist/registry/factory.js.map +1 -0
  148. package/dist/registry/index.d.ts +8 -0
  149. package/dist/registry/index.js +8 -0
  150. package/dist/registry/registry-docs.d.ts +15 -0
  151. package/dist/registry/registry-docs.d.ts.map +1 -0
  152. package/dist/registry/registry-docs.js +305 -0
  153. package/dist/registry/registry-docs.js.map +1 -0
  154. package/dist/registry/registry-landing.d.ts +19 -0
  155. package/dist/registry/registry-landing.d.ts.map +1 -0
  156. package/dist/registry/registry-landing.js +95 -0
  157. package/dist/registry/registry-landing.js.map +1 -0
  158. package/dist/registry/registry.d.ts +30 -0
  159. package/dist/registry/registry.d.ts.map +1 -0
  160. package/dist/registry/registry.js +61 -0
  161. package/dist/registry/registry.js.map +1 -0
  162. package/dist/registry/types.d.ts +19 -0
  163. package/dist/registry/types.d.ts.map +1 -0
  164. package/dist/registry/types.js +0 -0
  165. package/dist/registry/utils.d.ts +31 -0
  166. package/dist/registry/utils.d.ts.map +1 -0
  167. package/dist/registry/utils.js +54 -0
  168. package/dist/registry/utils.js.map +1 -0
  169. package/package.json +151 -0
  170. package/src/components/marketing/ChangelogPage.tsx +110 -0
  171. package/src/components/marketing/CofounderPage.tsx +409 -0
  172. package/src/components/marketing/ContactClient.tsx +174 -0
  173. package/src/components/marketing/ContributePage.tsx +319 -0
  174. package/src/components/marketing/DesignPartnerPage.tsx +181 -0
  175. package/src/components/marketing/LandingPage.tsx +30 -0
  176. package/src/components/marketing/PricingClient.tsx +446 -0
  177. package/src/components/marketing/ProductClientPage.tsx +391 -0
  178. package/src/components/marketing/index.ts +10 -0
  179. package/src/components/marketing/pricing-thinking-modal.tsx +224 -0
  180. package/src/components/marketing/sections/AudienceSection.tsx +66 -0
  181. package/src/components/marketing/sections/CorePositioningSection.tsx +44 -0
  182. package/src/components/marketing/sections/CtaSection.tsx +57 -0
  183. package/src/components/marketing/sections/DevelopersSection.tsx +38 -0
  184. package/src/components/marketing/sections/FearsSection.tsx +45 -0
  185. package/src/components/marketing/sections/HeroMarketingSection.tsx +73 -0
  186. package/src/components/marketing/sections/IconGridSection.tsx +91 -0
  187. package/src/components/marketing/sections/OutputsSection.tsx +59 -0
  188. package/src/components/marketing/sections/ProblemSection.tsx +47 -0
  189. package/src/components/marketing/sections/SolutionSection.tsx +47 -0
  190. package/src/components/marketing/sections/StepsSection.tsx +55 -0
  191. package/src/components/marketing/waitlist-section.tsx +606 -0
  192. package/src/components/templates/TemplatesClientPage.tsx +711 -0
  193. package/src/components/templates/TemplatesPage.tsx +129 -0
  194. package/src/components/templates/TemplatesPreviewModal.tsx +260 -0
  195. package/src/components/templates/index.ts +3 -0
  196. package/src/index.ts +15 -0
  197. package/src/libs/email/client.test.ts +107 -0
  198. package/src/libs/email/client.ts +146 -0
  199. package/src/libs/email/contact.ts +80 -0
  200. package/src/libs/email/newsletter.ts +108 -0
  201. package/src/libs/email/types.ts +59 -0
  202. package/src/libs/email/utils.ts +8 -0
  203. package/src/libs/email/waitlist-application.ts +192 -0
  204. package/src/libs/email/waitlist.ts +118 -0
  205. package/src/libs/pricing-examples.ts +19 -0
  206. package/src/registry/engine.ts +38 -0
  207. package/src/registry/factory.ts +110 -0
  208. package/src/registry/index.ts +7 -0
  209. package/src/registry/registry-docs.ts +843 -0
  210. package/src/registry/registry-landing.ts +118 -0
  211. package/src/registry/registry.ts +85 -0
  212. package/src/registry/types.ts +17 -0
  213. package/src/registry/utils.ts +99 -0
  214. package/tsconfig.json +13 -0
  215. package/tsconfig.tsbuildinfo +1 -0
  216. package/tsdown.config.js +10 -0
@@ -0,0 +1,391 @@
1
+ 'use client';
2
+
3
+ import Link from '@contractspec/lib.ui-link';
4
+ import {
5
+ analyticsEventNames,
6
+ captureAnalyticsEvent,
7
+ } from '@contractspec/bundle.library/libs/posthog/client';
8
+ import {
9
+ CheckCircle,
10
+ ChevronRight,
11
+ Database,
12
+ FileCode,
13
+ GitBranch,
14
+ Layers,
15
+ RefreshCw,
16
+ Shield,
17
+ Unlock,
18
+ Zap,
19
+ } from 'lucide-react';
20
+
21
+ export const ProductClientPage = () => (
22
+ <main className="">
23
+ {/* Hero */}
24
+ <section className="section-padding hero-gradient relative">
25
+ <div className="mx-auto max-w-4xl space-y-6 text-center">
26
+ <h1 className="text-5xl leading-tight font-bold md:text-6xl">
27
+ Compiler for AI-coded systems
28
+ </h1>
29
+ <p className="text-muted-foreground mx-auto max-w-2xl text-lg">
30
+ Define contracts once. Generate consistent code across API, DB, UI,
31
+ and events. Regenerate safely anytime. No lock-in.
32
+ </p>
33
+ <div className="flex flex-col items-center justify-center gap-4 pt-4 sm:flex-row">
34
+ <Link
35
+ href="/install"
36
+ onClick={() =>
37
+ captureAnalyticsEvent(analyticsEventNames.CTA_INSTALL_CLICK, {
38
+ surface: 'product-hero',
39
+ })
40
+ }
41
+ className="btn-primary inline-flex items-center gap-2"
42
+ >
43
+ Install OSS Core <ChevronRight size={16} />
44
+ </Link>
45
+ <Link href="/pricing" className="btn-ghost">
46
+ View pricing
47
+ </Link>
48
+ </div>
49
+ </div>
50
+ </section>
51
+
52
+ {/* Multi-Surface Consistency */}
53
+ <section className="section-padding border-border border-b">
54
+ <div className="mx-auto max-w-4xl space-y-8">
55
+ <div className="space-y-4">
56
+ <div className="inline-flex items-center gap-2 rounded-full border border-blue-500/20 bg-blue-500/10 px-3 py-1">
57
+ <Layers size={16} className="text-blue-400" />
58
+ <span className="text-sm font-medium text-blue-300">
59
+ Multi-Surface Consistency
60
+ </span>
61
+ </div>
62
+ <h2 className="text-3xl font-bold md:text-4xl">
63
+ One contract, all surfaces in sync
64
+ </h2>
65
+ <p className="text-muted-foreground text-lg">
66
+ Stop chasing drift between your API, database, UI, and events. One
67
+ spec generates all outputs, guaranteed to stay consistent.
68
+ </p>
69
+ </div>
70
+ <div className="grid gap-6 md:grid-cols-2">
71
+ {[
72
+ {
73
+ title: 'REST & GraphQL API',
74
+ description:
75
+ 'Type-safe endpoints with validation. Standard Express, Hono, Elysia, or Apollo handlers.',
76
+ icon: Zap,
77
+ },
78
+ {
79
+ title: 'Database Schema',
80
+ description:
81
+ 'Prisma migrations and types generated from the same spec. Always in sync with your API.',
82
+ icon: Database,
83
+ },
84
+ {
85
+ title: 'UI Components',
86
+ description:
87
+ 'React forms and views derived from specs. Validation and types flow through automatically.',
88
+ icon: FileCode,
89
+ },
90
+ {
91
+ title: 'MCP Tools & Events',
92
+ description:
93
+ 'AI agent tool definitions and event schemas. Same contract, different surfaces.',
94
+ icon: GitBranch,
95
+ },
96
+ ].map((item, i) => (
97
+ <div key={i} className="card-subtle space-y-4 p-6">
98
+ <item.icon className="text-blue-400" size={24} />
99
+ <h3 className="text-lg font-bold">{item.title}</h3>
100
+ <p className="text-muted-foreground text-sm">
101
+ {item.description}
102
+ </p>
103
+ </div>
104
+ ))}
105
+ </div>
106
+ </div>
107
+ </section>
108
+
109
+ {/* Safe Regeneration */}
110
+ <section className="section-padding border-border bg-muted/20 border-b">
111
+ <div className="mx-auto max-w-4xl space-y-8">
112
+ <div className="space-y-4">
113
+ <div className="inline-flex items-center gap-2 rounded-full border border-emerald-500/20 bg-emerald-500/10 px-3 py-1">
114
+ <RefreshCw size={16} className="text-emerald-400" />
115
+ <span className="text-sm font-medium text-emerald-300">
116
+ Safe Regeneration
117
+ </span>
118
+ </div>
119
+ <h2 className="text-3xl font-bold md:text-4xl">
120
+ Regenerate anytime without fear
121
+ </h2>
122
+ <p className="text-muted-foreground text-lg">
123
+ Contracts enforce invariants. Breaking changes are caught at compile
124
+ time, not production. Regenerate with confidence.
125
+ </p>
126
+ </div>
127
+ <div className="grid gap-6 md:grid-cols-2">
128
+ <div className="card-subtle space-y-4 p-6">
129
+ <h3 className="font-bold">Spec-First Safety</h3>
130
+ <p className="text-muted-foreground text-sm">
131
+ AI agents read specs, not implementations. Generated code that
132
+ violates contracts gets flagged automatically.
133
+ </p>
134
+ <ul className="text-muted-foreground space-y-2 text-sm">
135
+ <li className="flex gap-3">
136
+ <CheckCircle
137
+ size={16}
138
+ className="mt-0.5 flex-shrink-0 text-emerald-400"
139
+ />
140
+ Type-safe from spec to runtime
141
+ </li>
142
+ <li className="flex gap-3">
143
+ <CheckCircle
144
+ size={16}
145
+ className="mt-0.5 flex-shrink-0 text-emerald-400"
146
+ />
147
+ Invariants enforced at compile time
148
+ </li>
149
+ <li className="flex gap-3">
150
+ <CheckCircle
151
+ size={16}
152
+ className="mt-0.5 flex-shrink-0 text-emerald-400"
153
+ />
154
+ Breaking changes detected early
155
+ </li>
156
+ </ul>
157
+ </div>
158
+ <div className="card-subtle space-y-4 p-6">
159
+ <h3 className="font-bold">Version Control Built-in</h3>
160
+ <p className="text-muted-foreground text-sm">
161
+ Every spec change is tracked. Roll back to any previous version.
162
+ Migrations are explicit and reversible.
163
+ </p>
164
+ <ul className="text-muted-foreground space-y-2 text-sm">
165
+ <li className="flex gap-3">
166
+ <CheckCircle
167
+ size={16}
168
+ className="mt-0.5 flex-shrink-0 text-emerald-400"
169
+ />
170
+ Git-native spec history
171
+ </li>
172
+ <li className="flex gap-3">
173
+ <CheckCircle
174
+ size={16}
175
+ className="mt-0.5 flex-shrink-0 text-emerald-400"
176
+ />
177
+ Explicit migration paths
178
+ </li>
179
+ <li className="flex gap-3">
180
+ <CheckCircle
181
+ size={16}
182
+ className="mt-0.5 flex-shrink-0 text-emerald-400"
183
+ />
184
+ One-click rollback
185
+ </li>
186
+ </ul>
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </section>
191
+
192
+ {/* Contract Enforcement */}
193
+ <section className="section-padding border-border border-b">
194
+ <div className="mx-auto max-w-4xl space-y-8">
195
+ <div className="space-y-4">
196
+ <div className="inline-flex items-center gap-2 rounded-full border border-violet-500/20 bg-violet-500/10 px-3 py-1">
197
+ <Shield size={16} className="text-violet-400" />
198
+ <span className="text-sm font-medium text-violet-300">
199
+ Contract Enforcement
200
+ </span>
201
+ </div>
202
+ <h2 className="text-3xl font-bold md:text-4xl">
203
+ AI governance that actually works
204
+ </h2>
205
+ <p className="text-muted-foreground text-lg">
206
+ Constrain what AI agents can change. Enforce contracts they must
207
+ respect. No more hallucinated refactors breaking your system.
208
+ </p>
209
+ </div>
210
+ <div className="card-subtle space-y-6 p-6">
211
+ <div className="space-y-4">
212
+ <h3 className="font-bold">How contract enforcement works</h3>
213
+ <p className="text-muted-foreground text-sm">
214
+ Contracts define what the system should do. AI-generated code that
215
+ violates these contracts is automatically flagged and rejected
216
+ before it can cause damage.
217
+ </p>
218
+ </div>
219
+ <div className="grid gap-4 md:grid-cols-3">
220
+ {[
221
+ {
222
+ title: 'Define',
223
+ description:
224
+ 'Write specs in TypeScript. Define inputs, outputs, and invariants.',
225
+ },
226
+ {
227
+ title: 'Generate',
228
+ description:
229
+ 'ContractSpec generates code across all surfaces from your specs.',
230
+ },
231
+ {
232
+ title: 'Enforce',
233
+ description:
234
+ "Any code that violates specs is flagged. AI agents can't break contracts.",
235
+ },
236
+ ].map((step, i) => (
237
+ <div key={i} className="space-y-2">
238
+ <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-violet-500/20">
239
+ <div className="text-sm font-bold text-violet-400">
240
+ {i + 1}
241
+ </div>
242
+ </div>
243
+ <h4 className="text-sm font-bold">{step.title}</h4>
244
+ <p className="text-muted-foreground text-xs">
245
+ {step.description}
246
+ </p>
247
+ </div>
248
+ ))}
249
+ </div>
250
+ </div>
251
+ </div>
252
+ </section>
253
+
254
+ {/* No Lock-in */}
255
+ <section className="section-padding border-border border-b bg-gradient-to-br from-violet-500/10 via-indigo-500/5 to-blue-500/5">
256
+ <div className="mx-auto max-w-4xl space-y-8">
257
+ <div className="space-y-4">
258
+ <div className="inline-flex items-center gap-2 rounded-full border border-pink-500/20 bg-pink-500/10 px-3 py-1">
259
+ <Unlock size={16} className="text-pink-400" />
260
+ <span className="text-sm font-medium text-pink-300">
261
+ No Lock-in
262
+ </span>
263
+ </div>
264
+ <h2 className="text-3xl font-bold md:text-4xl">
265
+ You own everything. Eject anytime.
266
+ </h2>
267
+ <p className="text-muted-foreground text-lg">
268
+ ContractSpec is a compiler, not a prison. The generated code is
269
+ yours: standard TypeScript, standard SQL, standard GraphQL.
270
+ </p>
271
+ </div>
272
+ <div className="grid gap-6 md:grid-cols-2">
273
+ <div className="card-subtle space-y-4 p-6">
274
+ <h3 className="text-lg font-bold">Standard Tech Output</h3>
275
+ <ul className="text-muted-foreground space-y-3 text-sm">
276
+ {[
277
+ 'TypeScript you can read and modify',
278
+ 'Prisma migrations you can run manually',
279
+ 'GraphQL schemas you can serve anywhere',
280
+ 'React components with no magic',
281
+ 'REST handlers that work with any framework',
282
+ ].map((item, i) => (
283
+ <li key={i} className="flex gap-3">
284
+ <CheckCircle
285
+ size={16}
286
+ className="mt-0.5 flex-shrink-0 text-pink-400"
287
+ />
288
+ {item}
289
+ </li>
290
+ ))}
291
+ </ul>
292
+ </div>
293
+ <div className="card-subtle space-y-4 p-6">
294
+ <h3 className="text-lg font-bold">No Proprietary Dependencies</h3>
295
+ <ul className="text-muted-foreground space-y-3 text-sm">
296
+ {[
297
+ 'No runtime library required',
298
+ 'No vendor-specific abstractions',
299
+ 'Works with your existing CI/CD',
300
+ 'Eject anytime, keep everything',
301
+ 'Open spec format',
302
+ ].map((item, i) => (
303
+ <li key={i} className="flex gap-3">
304
+ <CheckCircle
305
+ size={16}
306
+ className="mt-0.5 flex-shrink-0 text-pink-400"
307
+ />
308
+ {item}
309
+ </li>
310
+ ))}
311
+ </ul>
312
+ </div>
313
+ </div>
314
+ <div className="pt-4 text-center">
315
+ <p className="text-muted-foreground mb-4 text-sm">
316
+ Like TypeScript compiles to JavaScript, ContractSpec compiles to
317
+ standard code.
318
+ <br />
319
+ <span className="font-medium text-violet-400">
320
+ We're the compiler, not the prison.
321
+ </span>
322
+ </p>
323
+ </div>
324
+ </div>
325
+ </section>
326
+
327
+ {/* Incremental Adoption */}
328
+ <section className="section-padding border-border border-b">
329
+ <div className="mx-auto max-w-4xl space-y-8">
330
+ <h2 className="text-center text-3xl font-bold md:text-4xl">
331
+ Start small. Expand gradually.
332
+ </h2>
333
+ <p className="text-muted-foreground mx-auto max-w-2xl text-center text-lg">
334
+ You don't rewrite your app. You stabilize one module at a time. Start
335
+ with one endpoint, prove value, then expand.
336
+ </p>
337
+ <div className="grid gap-6 md:grid-cols-3">
338
+ {[
339
+ {
340
+ title: 'Day 1',
341
+ description:
342
+ 'Pick one API endpoint. Write a spec. See what gets generated.',
343
+ },
344
+ {
345
+ title: 'Week 1',
346
+ description:
347
+ 'Add a few more specs. Compare generated code to existing code.',
348
+ },
349
+ {
350
+ title: 'Month 1',
351
+ description:
352
+ 'Migrate a full module. Enjoy multi-surface consistency.',
353
+ },
354
+ ].map((item, i) => (
355
+ <div key={i} className="card-subtle space-y-4 p-6 text-center">
356
+ <div className="text-2xl font-bold text-violet-400">
357
+ {item.title}
358
+ </div>
359
+ <p className="text-muted-foreground text-sm">
360
+ {item.description}
361
+ </p>
362
+ </div>
363
+ ))}
364
+ </div>
365
+ </div>
366
+ </section>
367
+
368
+ {/* CTA */}
369
+ <section className="section-padding hero-gradient">
370
+ <div className="mx-auto max-w-4xl space-y-6 text-center">
371
+ <h2 className="text-3xl font-bold md:text-4xl">
372
+ Ready to stabilize your AI-generated code?
373
+ </h2>
374
+ <p className="text-muted-foreground text-lg">
375
+ Start with one module. No big-bang migration. No lock-in.
376
+ </p>
377
+ <div className="flex flex-col items-center justify-center gap-4 pt-4 sm:flex-row">
378
+ <Link
379
+ href="/install"
380
+ className="btn-primary inline-flex items-center gap-2"
381
+ >
382
+ Install OSS Core <ChevronRight size={16} />
383
+ </Link>
384
+ <Link href="/contact#waitlist" className="btn-ghost">
385
+ Join Studio Waitlist
386
+ </Link>
387
+ </div>
388
+ </div>
389
+ </section>
390
+ </main>
391
+ );
@@ -0,0 +1,10 @@
1
+ export { LandingPage } from './LandingPage';
2
+ export { ProductClientPage } from './ProductClientPage';
3
+ export { PricingClient } from './PricingClient';
4
+ export { ContactClient } from './ContactClient';
5
+ export { ChangelogPage } from './ChangelogPage';
6
+ export { CofounderPage } from './CofounderPage';
7
+ export { ContributePage } from './ContributePage';
8
+ export { DesignPartnerPage } from './DesignPartnerPage';
9
+ export { WaitlistSection } from './waitlist-section';
10
+ export { PricingThinkingModal } from './pricing-thinking-modal';
@@ -0,0 +1,224 @@
1
+ 'use client';
2
+
3
+ import { CheckCircle } from 'lucide-react';
4
+ import {
5
+ Dialog,
6
+ DialogContent,
7
+ DialogDescription,
8
+ DialogHeader,
9
+ DialogTitle,
10
+ } from '@contractspec/lib.ui-kit-web/ui/dialog';
11
+ import { Button } from '@contractspec/lib.design-system';
12
+ import { PRICING_EXAMPLES } from '../../libs/pricing-examples';
13
+
14
+ interface PricingTier {
15
+ tag: string;
16
+ title: string;
17
+ priceLine: string;
18
+ bullets: string[];
19
+ note: string;
20
+ }
21
+
22
+ interface UsageMetric {
23
+ name: string;
24
+ freeTier: string;
25
+ beyond: string;
26
+ }
27
+
28
+ const pricingTiers: PricingTier[] = [
29
+ {
30
+ tag: 'Planned',
31
+ title: 'Free',
32
+ priceLine: 'For hobbyists and pre-PMF teams',
33
+ bullets: [
34
+ '1 active project',
35
+ 'Small spec size',
36
+ `Example: ~${PRICING_EXAMPLES.free.regenerationsPerMonth} free regenerations per month`,
37
+ `Example: ~${PRICING_EXAMPLES.free.aiActionsPerMonth} free AI agent actions per month`,
38
+ 'Unlimited collaborators',
39
+ ],
40
+ note: 'Good enough to build and launch a real product before paying.',
41
+ },
42
+ {
43
+ tag: 'Planned',
44
+ title: 'Builder',
45
+ priceLine: 'Usage-based, for solo builders and small teams',
46
+ bullets: [
47
+ 'More projects',
48
+ `More monthly regenerations included (e.g. ${PRICING_EXAMPLES.builder.regenerationsPerMonthHint})`,
49
+ `More AI agent actions included (e.g. ${PRICING_EXAMPLES.builder.aiActionsPerMonthHint})`,
50
+ 'Pay-as-you-go for extra regenerations and AI',
51
+ 'Basic environments (dev / prod)',
52
+ ],
53
+ note: 'Pay for how fast and how often you evolve your system, not for seats.',
54
+ },
55
+ {
56
+ tag: 'Planned',
57
+ title: 'Team & Platform',
58
+ priceLine: 'For teams standardizing on ContractSpec',
59
+ bullets: [
60
+ 'Multiple projects and environments',
61
+ 'Higher regeneration and AI action limits',
62
+ 'Cheaper overages as you scale',
63
+ 'Advanced RBAC and governance',
64
+ 'SSO, audit trails, and longer retention',
65
+ ],
66
+ note: 'For platform teams using ContractSpec as infra for multiple apps.',
67
+ },
68
+ ];
69
+
70
+ const usageMetrics: UsageMetric[] = [
71
+ {
72
+ name: 'Regenerations',
73
+ freeTier: `Free tier: e.g. ~${PRICING_EXAMPLES.free.regenerationsPerMonth} regenerations / month`,
74
+ beyond: 'Beyond: pay per additional regeneration, with volume discounts.',
75
+ },
76
+ {
77
+ name: 'AI agent actions',
78
+ freeTier: `Free tier: e.g. ~${PRICING_EXAMPLES.free.aiActionsPerMonth} AI agent actions / month`,
79
+ beyond: 'Beyond: pay-as-you-go for extra AI usage.',
80
+ },
81
+ {
82
+ name: 'Projects',
83
+ freeTier: `Free tier: ${PRICING_EXAMPLES.free.projects} project`,
84
+ beyond:
85
+ 'Builder / Team: more projects included; extra projects available as you scale.',
86
+ },
87
+ ];
88
+
89
+ interface PricingThinkingModalProps {
90
+ open: boolean;
91
+ onOpenChange: (open: boolean) => void;
92
+ onApplyClick?: () => void;
93
+ }
94
+
95
+ export function PricingThinkingModal({
96
+ open,
97
+ onOpenChange,
98
+ onApplyClick,
99
+ }: PricingThinkingModalProps) {
100
+ return (
101
+ <Dialog open={open} onOpenChange={onOpenChange}>
102
+ <DialogContent className="max-h-[90vh] w-full overflow-y-auto md:max-w-5xl">
103
+ <DialogHeader>
104
+ <DialogTitle>Tentative pricing (work in progress)</DialogTitle>
105
+ <DialogDescription>
106
+ We're still in design-partner mode. This is a draft of how we expect
107
+ pricing to look once we open public access.
108
+ </DialogDescription>
109
+ </DialogHeader>
110
+
111
+ <div className="space-y-8">
112
+ {/* High-level tiers */}
113
+ <div className="space-y-4">
114
+ <div className="flex items-center gap-2">
115
+ <span className="text-muted-foreground text-xs font-medium">
116
+ Draft
117
+ </span>
118
+ <span className="text-muted-foreground text-xs">•</span>
119
+ <span className="text-muted-foreground text-xs">
120
+ Subject to change
121
+ </span>
122
+ </div>
123
+ <div className="grid gap-4 md:grid-cols-3">
124
+ {pricingTiers.map((tier) => (
125
+ <div
126
+ key={tier.title}
127
+ className="card-subtle relative space-y-4 p-6"
128
+ >
129
+ <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">
130
+ {tier.tag}
131
+ </div>
132
+ <div className="space-y-2 pt-2">
133
+ <h3 className="text-xl font-bold">{tier.title}</h3>
134
+ <p className="text-muted-foreground text-sm">
135
+ {tier.priceLine}
136
+ </p>
137
+ </div>
138
+ <ul className="space-y-2">
139
+ {tier.bullets.map((bullet, i) => (
140
+ <li
141
+ key={i}
142
+ className="text-muted-foreground flex gap-2 text-sm"
143
+ >
144
+ <CheckCircle
145
+ size={14}
146
+ className="mt-0.5 shrink-0 text-violet-400"
147
+ />
148
+ {bullet}
149
+ </li>
150
+ ))}
151
+ </ul>
152
+ <p className="text-muted-foreground text-xs italic">
153
+ {tier.note}
154
+ </p>
155
+ </div>
156
+ ))}
157
+ </div>
158
+ </div>
159
+
160
+ {/* Usage-based detail */}
161
+ <div className="border-border space-y-4 border-t pt-6">
162
+ <div>
163
+ <h3 className="text-lg font-bold">
164
+ Usage-based, with a generous free tier
165
+ </h3>
166
+ <p className="text-muted-foreground mt-2 text-sm">
167
+ Inspired by products like PostHog, we plan to keep a generous
168
+ free tier on all plans, then charge based on actual usage:
169
+ regenerations, AI agent actions, and the number of projects you
170
+ run on ContractSpec.
171
+ </p>
172
+ <p className="text-muted-foreground mt-3 text-xs italic">
173
+ Free tier limits are intentionally small but useful: enough to
174
+ try the agent and regenerate a real project, not enough to run a
175
+ full team's workload for free.
176
+ </p>
177
+ </div>
178
+ <div className="grid gap-4 md:grid-cols-3">
179
+ {usageMetrics.map((metric) => (
180
+ <div key={metric.name} className="card-subtle space-y-2 p-4">
181
+ <h4 className="text-sm font-semibold">{metric.name}</h4>
182
+ <p className="text-muted-foreground text-xs">
183
+ {metric.freeTier}
184
+ </p>
185
+ <p className="text-muted-foreground text-xs">
186
+ {metric.beyond}
187
+ </p>
188
+ </div>
189
+ ))}
190
+ </div>
191
+ </div>
192
+
193
+ {/* Footer / Disclaimer */}
194
+ <div className="border-border space-y-4 border-t pt-6">
195
+ <p className="text-muted-foreground text-xs">
196
+ These numbers are examples only. Final pricing and limits will
197
+ evolve as we learn from design partners.
198
+ </p>
199
+ <p className="text-muted-foreground text-xs">
200
+ This is a tentative pricing model. We're pre-PMF and pricing is
201
+ still in draft, subject to change based on what we learn.
202
+ </p>
203
+ <p className="text-muted-foreground text-xs">
204
+ Design partners get early access and a founding discount when paid
205
+ plans launch.
206
+ </p>
207
+ {onApplyClick && (
208
+ <Button
209
+ onClick={() => {
210
+ onOpenChange(false);
211
+ onApplyClick();
212
+ }}
213
+ className="w-full"
214
+ variant="outline"
215
+ >
216
+ Apply as a design partner
217
+ </Button>
218
+ )}
219
+ </div>
220
+ </div>
221
+ </DialogContent>
222
+ </Dialog>
223
+ );
224
+ }
@@ -0,0 +1,66 @@
1
+ import * as React from 'react';
2
+ import {
3
+ MarketingCard,
4
+ MarketingCardContent,
5
+ MarketingCardHeader,
6
+ MarketingCardTitle,
7
+ MarketingCardsSection,
8
+ } from '@contractspec/lib.design-system';
9
+ import { VStack } from '@contractspec/lib.ui-kit-web/ui/stack';
10
+ import { Muted, Small } from '@contractspec/lib.ui-kit-web/ui/typography';
11
+
12
+ const audiences = [
13
+ {
14
+ tier: 'Tier 1: Priority',
15
+ title: 'AI-Native Startups & Technical Founders',
16
+ 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.',
17
+ need: 'Need: A way to stabilize AI-generated code without rewriting it.',
18
+ },
19
+ {
20
+ tier: 'Tier 1: Priority',
21
+ title: 'Small Teams with AI-Generated Chaos',
22
+ 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.',
23
+ need: 'Need: Incremental stabilization, safe regeneration, contracts as guardrails.',
24
+ },
25
+ {
26
+ tier: 'Tier 2: Growth',
27
+ title: 'AI Dev Agencies',
28
+ body: 'Agencies building many projects for clients using AI-assisted development. Repeating the same patterns, inconsistent quality across projects, handoff nightmares.',
29
+ need: 'Need: Reusable templates, consistent contracts, professional handoff artifacts.',
30
+ },
31
+ {
32
+ tier: 'Tier 2: Growth',
33
+ title: 'Scaleups with Compliance Needs',
34
+ body: "Growing companies that need audit trails, API governance, or regulatory compliance. AI-generated code doesn't meet compliance requirements.",
35
+ need: 'Need: Governance layer, change tracking, contract enforcement.',
36
+ },
37
+ ];
38
+
39
+ export function AudienceSection() {
40
+ return (
41
+ <MarketingCardsSection
42
+ tone="default"
43
+ columns={2}
44
+ eyebrow="Who It's For"
45
+ title="Built for teams drowning in AI-generated code"
46
+ maxWidth="xl"
47
+ >
48
+ {audiences.map((item) => (
49
+ <MarketingCard key={item.title} tone="muted">
50
+ <MarketingCardHeader className="space-y-2">
51
+ <Small className="font-semibold text-blue-400">{item.tier}</Small>
52
+ <MarketingCardTitle className="text-xl">
53
+ {item.title}
54
+ </MarketingCardTitle>
55
+ </MarketingCardHeader>
56
+ <MarketingCardContent>
57
+ <VStack gap="sm">
58
+ <Muted className="text-sm leading-relaxed">{item.body}</Muted>
59
+ <Small className="font-medium text-violet-400">{item.need}</Small>
60
+ </VStack>
61
+ </MarketingCardContent>
62
+ </MarketingCard>
63
+ ))}
64
+ </MarketingCardsSection>
65
+ );
66
+ }