@contractspec/bundle.marketing 3.7.5 → 3.7.7
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 +84 -84
- package/AGENTS.md +29 -21
- package/CHANGELOG.md +27 -0
- package/README.md +36 -49
- package/dist/browser/components/marketing/ChangelogPage.js +8 -8
- package/dist/browser/components/marketing/CofounderPage.js +167 -523
- package/dist/browser/components/marketing/ContactClient.js +200 -207
- package/dist/browser/components/marketing/ContributePage.js +211 -463
- package/dist/browser/components/marketing/DesignPartnerPage.js +165 -218
- package/dist/browser/components/marketing/LandingPage.js +464 -568
- package/dist/browser/components/marketing/PricingClient.js +213 -839
- package/dist/browser/components/marketing/ProductClientPage.js +265 -463
- package/dist/browser/components/marketing/index.js +2007 -3338
- package/dist/browser/components/marketing/pricing-thinking-modal.js +12 -12
- package/dist/browser/components/marketing/sections/AudienceSection.js +2 -2
- package/dist/browser/components/marketing/sections/CorePositioningSection.js +2 -2
- package/dist/browser/components/marketing/sections/CtaSection.js +3 -3
- package/dist/browser/components/marketing/sections/FearsSection.js +3 -3
- package/dist/browser/components/marketing/sections/HeroMarketingSection.js +6 -6
- package/dist/browser/components/marketing/sections/IconGridSection.js +2 -2
- package/dist/browser/components/marketing/sections/OutputsSection.js +2 -2
- package/dist/browser/components/marketing/sections/ProblemSection.js +2 -2
- package/dist/browser/components/marketing/sections/SolutionSection.js +2 -2
- package/dist/browser/components/marketing/sections/StepsSection.js +4 -4
- package/dist/browser/components/marketing/studio-signup-section.js +25 -41
- package/dist/browser/components/templates/TemplatesClientPage.js +2324 -3578
- package/dist/browser/components/templates/TemplatesPage.js +1 -1
- package/dist/browser/components/templates/TemplatesPreviewModal.js +3 -3
- package/dist/browser/components/templates/index.js +2361 -3615
- package/dist/browser/index.js +2363 -3617
- package/dist/browser/libs/email/client.js +1 -1
- package/dist/browser/libs/email/contact.js +1 -1
- package/dist/browser/libs/email/newsletter.js +1 -1
- package/dist/browser/libs/email/waitlist-application.js +1 -1
- package/dist/browser/libs/email/waitlist.js +1 -1
- package/dist/browser/registry/engine.js +2003 -3334
- package/dist/browser/registry/index.js +2003 -3334
- package/dist/browser/registry/registry-docs.js +2 -2
- package/dist/browser/registry/registry-landing.js +2007 -3338
- package/dist/browser/registry/registry.js +2003 -3334
- package/dist/browser/registry/utils.js +2003 -3334
- package/dist/components/marketing/ChangelogPage.js +8 -8
- package/dist/components/marketing/CofounderPage.js +167 -523
- package/dist/components/marketing/ContactClient.js +200 -207
- package/dist/components/marketing/ContributePage.d.ts +0 -2
- package/dist/components/marketing/ContributePage.js +211 -463
- package/dist/components/marketing/DesignPartnerPage.js +165 -218
- package/dist/components/marketing/LandingPage.js +464 -568
- package/dist/components/marketing/PricingClient.js +213 -839
- package/dist/components/marketing/ProductClientPage.js +265 -463
- package/dist/components/marketing/index.d.ts +5 -5
- package/dist/components/marketing/index.js +2007 -3338
- package/dist/components/marketing/pricing-thinking-modal.js +12 -12
- package/dist/components/marketing/sections/AudienceSection.js +2 -2
- package/dist/components/marketing/sections/CorePositioningSection.js +2 -2
- package/dist/components/marketing/sections/CtaSection.js +3 -3
- package/dist/components/marketing/sections/FearsSection.js +3 -3
- package/dist/components/marketing/sections/HeroMarketingSection.js +6 -6
- package/dist/components/marketing/sections/IconGridSection.d.ts +3 -3
- package/dist/components/marketing/sections/IconGridSection.js +2 -2
- package/dist/components/marketing/sections/OutputsSection.js +2 -2
- package/dist/components/marketing/sections/ProblemSection.js +2 -2
- package/dist/components/marketing/sections/SolutionSection.js +2 -2
- package/dist/components/marketing/sections/StepsSection.js +4 -4
- package/dist/components/marketing/studio-signup-section.js +25 -41
- package/dist/components/templates/TemplatesClientPage.js +2324 -3578
- package/dist/components/templates/TemplatesPage.js +1 -1
- package/dist/components/templates/TemplatesPreviewModal.js +3 -3
- package/dist/components/templates/index.js +2361 -3615
- package/dist/index.js +2363 -3617
- package/dist/libs/email/client.js +1 -1
- package/dist/libs/email/contact.js +1 -1
- package/dist/libs/email/newsletter.js +1 -1
- package/dist/libs/email/waitlist-application.js +1 -1
- package/dist/libs/email/waitlist.js +1 -1
- package/dist/node/components/marketing/ChangelogPage.js +8 -8
- package/dist/node/components/marketing/CofounderPage.js +167 -523
- package/dist/node/components/marketing/ContactClient.js +200 -207
- package/dist/node/components/marketing/ContributePage.js +211 -463
- package/dist/node/components/marketing/DesignPartnerPage.js +165 -218
- package/dist/node/components/marketing/LandingPage.js +464 -568
- package/dist/node/components/marketing/PricingClient.js +213 -839
- package/dist/node/components/marketing/ProductClientPage.js +265 -463
- package/dist/node/components/marketing/index.js +2007 -3338
- package/dist/node/components/marketing/pricing-thinking-modal.js +12 -12
- package/dist/node/components/marketing/sections/AudienceSection.js +2 -2
- package/dist/node/components/marketing/sections/CorePositioningSection.js +2 -2
- package/dist/node/components/marketing/sections/CtaSection.js +3 -3
- package/dist/node/components/marketing/sections/FearsSection.js +3 -3
- package/dist/node/components/marketing/sections/HeroMarketingSection.js +6 -6
- package/dist/node/components/marketing/sections/IconGridSection.js +2 -2
- package/dist/node/components/marketing/sections/OutputsSection.js +2 -2
- package/dist/node/components/marketing/sections/ProblemSection.js +2 -2
- package/dist/node/components/marketing/sections/SolutionSection.js +2 -2
- package/dist/node/components/marketing/sections/StepsSection.js +4 -4
- package/dist/node/components/marketing/studio-signup-section.js +25 -41
- package/dist/node/components/templates/TemplatesClientPage.js +2324 -3578
- package/dist/node/components/templates/TemplatesPage.js +1 -1
- package/dist/node/components/templates/TemplatesPreviewModal.js +3 -3
- package/dist/node/components/templates/index.js +2361 -3615
- package/dist/node/index.js +2363 -3617
- package/dist/node/libs/email/client.js +1 -1
- package/dist/node/libs/email/contact.js +1 -1
- package/dist/node/libs/email/newsletter.js +1 -1
- package/dist/node/libs/email/waitlist-application.js +1 -1
- package/dist/node/libs/email/waitlist.js +1 -1
- package/dist/node/registry/engine.js +2003 -3334
- package/dist/node/registry/index.js +2003 -3334
- package/dist/node/registry/registry-docs.js +2 -2
- package/dist/node/registry/registry-landing.js +2007 -3338
- package/dist/node/registry/registry.js +2003 -3334
- package/dist/node/registry/utils.js +2003 -3334
- package/dist/registry/engine.js +2003 -3334
- package/dist/registry/index.js +2003 -3334
- package/dist/registry/registry-docs.js +2 -2
- package/dist/registry/registry-landing.js +2007 -3338
- package/dist/registry/registry.js +2003 -3334
- package/dist/registry/utils.js +2003 -3334
- package/package.json +29 -29
- package/src/bundles/MarketingBundle.ts +273 -273
- package/src/components/marketing/ChangelogPage.tsx +72 -100
- package/src/components/marketing/CofounderPage.tsx +120 -384
- package/src/components/marketing/ContactClient.tsx +164 -154
- package/src/components/marketing/ContributePage.tsx +139 -313
- package/src/components/marketing/DesignPartnerPage.tsx +133 -171
- package/src/components/marketing/LandingPage.tsx +353 -25
- package/src/components/marketing/PricingClient.tsx +192 -437
- package/src/components/marketing/ProductClientPage.tsx +255 -377
- package/src/components/marketing/index.ts +5 -5
- package/src/components/marketing/pricing-thinking-modal.tsx +197 -197
- package/src/components/marketing/sections/AudienceSection.tsx +55 -56
- package/src/components/marketing/sections/CorePositioningSection.tsx +37 -37
- package/src/components/marketing/sections/CtaSection.tsx +49 -50
- package/src/components/marketing/sections/DevelopersSection.tsx +26 -27
- package/src/components/marketing/sections/FearsSection.tsx +36 -37
- package/src/components/marketing/sections/HeroMarketingSection.tsx +59 -59
- package/src/components/marketing/sections/IconGridSection.tsx +71 -71
- package/src/components/marketing/sections/OutputsSection.tsx +51 -52
- package/src/components/marketing/sections/ProblemSection.tsx +39 -40
- package/src/components/marketing/sections/SolutionSection.tsx +39 -40
- package/src/components/marketing/sections/StepsSection.tsx +47 -48
- package/src/components/marketing/studio-signup-section.tsx +39 -41
- package/src/components/templates/TemplatesClientPage.tsx +727 -685
- package/src/components/templates/TemplatesPage.tsx +110 -110
- package/src/components/templates/TemplatesPreviewModal.tsx +197 -198
- package/src/index.ts +4 -4
- package/src/libs/email/client.test.ts +81 -81
- package/src/libs/email/client.ts +111 -111
- package/src/libs/email/contact.ts +35 -35
- package/src/libs/email/newsletter.ts +46 -46
- package/src/libs/email/types.ts +29 -29
- package/src/libs/email/utils.ts +5 -5
- package/src/libs/email/waitlist-application.ts +72 -72
- package/src/libs/email/waitlist.ts +46 -46
- package/src/libs/pricing-examples.ts +12 -12
- package/src/registry/engine.ts +16 -16
- package/src/registry/factory.ts +57 -57
- package/src/registry/registry-docs.ts +656 -666
- package/src/registry/registry-landing.ts +94 -95
- package/src/registry/registry.ts +36 -37
- package/src/registry/types.ts +2 -2
- package/src/registry/utils.ts +56 -56
- package/tsconfig.json +11 -11
- package/tsdown.config.js +5 -5
|
@@ -1,391 +1,269 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import Link from '@contractspec/lib.ui-link';
|
|
4
3
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
analyticsEventNames,
|
|
5
|
+
captureAnalyticsEvent,
|
|
7
6
|
} from '@contractspec/bundle.library/libs/posthog/client';
|
|
8
7
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
ArrowRight,
|
|
9
|
+
Blocks,
|
|
10
|
+
Bot,
|
|
11
|
+
Braces,
|
|
12
|
+
Captions,
|
|
13
|
+
CheckCircle2,
|
|
14
|
+
ClipboardCheck,
|
|
15
|
+
Layers3,
|
|
16
|
+
ShieldCheck,
|
|
17
|
+
Sparkles,
|
|
19
18
|
} from 'lucide-react';
|
|
19
|
+
import Link from 'next/link';
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
21
|
+
const layers = [
|
|
22
|
+
{
|
|
23
|
+
name: 'Contracts and specs',
|
|
24
|
+
copy: 'The canonical product rules your team wants the system to keep respecting over time.',
|
|
25
|
+
icon: Braces,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'Generation and runtime bridges',
|
|
29
|
+
copy: 'The adapters that turn those rules into API, UI, data, event, MCP, and client-facing surfaces.',
|
|
30
|
+
icon: Layers3,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'Harness and proof workflows',
|
|
34
|
+
copy: 'The inspection, replay, evaluation, and evidence surfaces that tell you whether automation is safe.',
|
|
35
|
+
icon: ClipboardCheck,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'Studio operating product',
|
|
39
|
+
copy: 'The opinionated team workflow for running evidence, drafts, review, exports, and checks on top of the same foundation.',
|
|
40
|
+
icon: Sparkles,
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const comparison = [
|
|
45
|
+
{
|
|
46
|
+
label: 'OSS/Core',
|
|
47
|
+
points: [
|
|
48
|
+
'You want explicit contracts, safe regeneration, and standards-first outputs.',
|
|
49
|
+
'You need to stabilize an existing product incrementally.',
|
|
50
|
+
'You want the foundation without being forced into a hosted product loop.',
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
label: 'Studio',
|
|
55
|
+
points: [
|
|
56
|
+
'You want the operating surface for evidence, drafts, review, exports, and follow-up.',
|
|
57
|
+
'You want packaged workflows and coordination on top of the same contract system.',
|
|
58
|
+
'You want the product that absorbs more operational complexity for the team.',
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
const proofs = [
|
|
64
|
+
{
|
|
65
|
+
label: 'Explicit contracts, not inferred conventions',
|
|
66
|
+
icon: ShieldCheck,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
label: 'Standard outputs the team can own and change',
|
|
70
|
+
icon: Bot,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
label: 'Multi-surface consistency across API, UI, data, and tools',
|
|
74
|
+
icon: Blocks,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
label: 'Incremental adoption instead of rewrite-only adoption',
|
|
78
|
+
icon: Captions,
|
|
79
|
+
},
|
|
80
|
+
];
|
|
51
81
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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>
|
|
82
|
+
function trackInstall() {
|
|
83
|
+
captureAnalyticsEvent(analyticsEventNames.CTA_INSTALL_CLICK, {
|
|
84
|
+
surface: 'product-hero',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
108
87
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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>
|
|
88
|
+
function trackStudio() {
|
|
89
|
+
captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {
|
|
90
|
+
surface: 'product-hero',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const ProductClientPage = () => (
|
|
95
|
+
<main>
|
|
96
|
+
<section className="section-padding hero-gradient border-border/70 border-b">
|
|
97
|
+
<div className="editorial-shell grid gap-10 lg:grid-cols-[1.05fr_0.95fr]">
|
|
98
|
+
<div className="space-y-6">
|
|
99
|
+
<p className="editorial-kicker">Product overview</p>
|
|
100
|
+
<h1 className="editorial-title max-w-4xl">
|
|
101
|
+
An open system for keeping AI-native products coherent.
|
|
102
|
+
</h1>
|
|
103
|
+
<p className="editorial-subtitle">
|
|
104
|
+
ContractSpec is not one narrow generator. It is the explicit layer
|
|
105
|
+
that lets teams define system behavior, keep multiple surfaces
|
|
106
|
+
aligned, regenerate safely, and move into Studio when they want the
|
|
107
|
+
operating product.
|
|
108
|
+
</p>
|
|
109
|
+
<div className="flex flex-col gap-3 sm:flex-row">
|
|
110
|
+
<Link
|
|
111
|
+
href="/install"
|
|
112
|
+
className="btn-primary"
|
|
113
|
+
onClick={trackInstall}
|
|
114
|
+
>
|
|
115
|
+
Start with OSS <ArrowRight className="ml-2 h-4 w-4" />
|
|
116
|
+
</Link>
|
|
117
|
+
<Link
|
|
118
|
+
href="https://www.contractspec.studio"
|
|
119
|
+
className="btn-ghost"
|
|
120
|
+
onClick={trackStudio}
|
|
121
|
+
>
|
|
122
|
+
Explore Studio
|
|
123
|
+
</Link>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
<div className="editorial-panel space-y-5">
|
|
127
|
+
<p className="editorial-kicker">What the category really is</p>
|
|
128
|
+
<h2 className="editorial-panel-title">
|
|
129
|
+
Lead with the system, not just the generation step.
|
|
130
|
+
</h2>
|
|
131
|
+
<p className="text-muted-foreground text-sm leading-7">
|
|
132
|
+
Generation matters, but it is not the whole story. The real value is
|
|
133
|
+
that contracts, runtime adapters, proof surfaces, and the Studio
|
|
134
|
+
operating loop all remain legible as parts of the same product
|
|
135
|
+
system.
|
|
136
|
+
</p>
|
|
137
|
+
<div className="editorial-divider" />
|
|
138
|
+
<div className="grid gap-4 md:grid-cols-2">
|
|
139
|
+
<div className="rounded-[24px] border border-border/70 bg-muted/45 p-4">
|
|
140
|
+
<p className="editorial-label">Better umbrella</p>
|
|
141
|
+
<p className="mt-2 font-medium text-sm">
|
|
142
|
+
Open spec system for AI-native software
|
|
143
|
+
</p>
|
|
144
|
+
</div>
|
|
145
|
+
<div className="rounded-[24px] border border-border/70 bg-muted/45 p-4">
|
|
146
|
+
<p className="editorial-label">Where “compiler” belongs</p>
|
|
147
|
+
<p className="mt-2 font-medium text-sm">
|
|
148
|
+
Inside the technical proof, not as the whole company category
|
|
149
|
+
</p>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</section>
|
|
191
155
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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>
|
|
156
|
+
<section className="editorial-section">
|
|
157
|
+
<div className="editorial-shell space-y-8">
|
|
158
|
+
<div className="max-w-3xl space-y-4">
|
|
159
|
+
<p className="editorial-kicker">Architecture by layer</p>
|
|
160
|
+
<h2 className="font-serif text-4xl tracking-[-0.04em] md:text-5xl">
|
|
161
|
+
Each layer exists to keep the next one from drifting.
|
|
162
|
+
</h2>
|
|
163
|
+
<p className="editorial-copy">
|
|
164
|
+
The repo structure already tells the right story: lower layers
|
|
165
|
+
define explicit behavior, higher layers compose that behavior into
|
|
166
|
+
working surfaces, and apps stay thin.
|
|
167
|
+
</p>
|
|
168
|
+
</div>
|
|
169
|
+
<div className="grid gap-5 md:grid-cols-2 xl:grid-cols-4">
|
|
170
|
+
{layers.map((layer) => (
|
|
171
|
+
<div key={layer.name} className="editorial-panel">
|
|
172
|
+
<layer.icon className="h-5 w-5 text-[color:var(--rust)]" />
|
|
173
|
+
<h3 className="mt-5 font-serif text-2xl tracking-[-0.03em]">
|
|
174
|
+
{layer.name}
|
|
175
|
+
</h3>
|
|
176
|
+
<p className="mt-3 text-muted-foreground text-sm leading-7">
|
|
177
|
+
{layer.copy}
|
|
178
|
+
</p>
|
|
179
|
+
</div>
|
|
180
|
+
))}
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</section>
|
|
253
184
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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>
|
|
185
|
+
<section className="editorial-section bg-striped">
|
|
186
|
+
<div className="editorial-shell grid gap-8 lg:grid-cols-2">
|
|
187
|
+
{comparison.map((column) => (
|
|
188
|
+
<div key={column.label} className="editorial-panel">
|
|
189
|
+
<p className="editorial-kicker">{column.label}</p>
|
|
190
|
+
<h2 className="mt-3 font-serif text-3xl tracking-[-0.04em]">
|
|
191
|
+
{column.label === 'OSS/Core'
|
|
192
|
+
? 'Adopt the open foundation first'
|
|
193
|
+
: 'Add the operating product when the team is ready'}
|
|
194
|
+
</h2>
|
|
195
|
+
<ul className="editorial-list mt-6">
|
|
196
|
+
{column.points.map((point) => (
|
|
197
|
+
<li key={point}>
|
|
198
|
+
<CheckCircle2 className="mt-1.5 h-4 w-4 shrink-0 text-[color:var(--success)]" />
|
|
199
|
+
<span>{point}</span>
|
|
200
|
+
</li>
|
|
201
|
+
))}
|
|
202
|
+
</ul>
|
|
203
|
+
</div>
|
|
204
|
+
))}
|
|
205
|
+
</div>
|
|
206
|
+
</section>
|
|
326
207
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
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>
|
|
208
|
+
<section className="editorial-section">
|
|
209
|
+
<div className="editorial-shell grid gap-10 lg:grid-cols-[0.9fr_1.1fr]">
|
|
210
|
+
<div className="space-y-4">
|
|
211
|
+
<p className="editorial-kicker">Proof points</p>
|
|
212
|
+
<h2 className="font-serif text-4xl tracking-[-0.04em] md:text-5xl">
|
|
213
|
+
What should feel different after adoption.
|
|
214
|
+
</h2>
|
|
215
|
+
<p className="editorial-copy">
|
|
216
|
+
The point is not just faster output. The point is that regeneration,
|
|
217
|
+
refactoring, and agent behavior stop feeling opaque because the team
|
|
218
|
+
has an explicit layer it can inspect and trust.
|
|
219
|
+
</p>
|
|
220
|
+
</div>
|
|
221
|
+
<div className="grid gap-5 md:grid-cols-2">
|
|
222
|
+
{proofs.map((proof) => {
|
|
223
|
+
const Icon = proof.icon;
|
|
224
|
+
return (
|
|
225
|
+
<div key={proof.label} className="editorial-panel">
|
|
226
|
+
<Icon className="h-5 w-5 text-[color:var(--blue)]" />
|
|
227
|
+
<p className="mt-5 font-medium text-lg">{proof.label}</p>
|
|
228
|
+
</div>
|
|
229
|
+
);
|
|
230
|
+
})}
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
</section>
|
|
367
234
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
235
|
+
<section className="section-padding">
|
|
236
|
+
<div className="editorial-shell">
|
|
237
|
+
<div className="editorial-panel flex flex-col gap-8 rounded-[38px] border-dashed md:flex-row md:items-end md:justify-between">
|
|
238
|
+
<div className="max-w-3xl space-y-4">
|
|
239
|
+
<p className="editorial-kicker">Next step</p>
|
|
240
|
+
<h2 className="font-serif text-4xl tracking-[-0.04em] md:text-5xl">
|
|
241
|
+
Use the OSS layer when you want control. Use Studio when you want
|
|
242
|
+
the operating loop.
|
|
243
|
+
</h2>
|
|
244
|
+
<p className="editorial-copy">
|
|
245
|
+
That is the cleanest product split for both technical adopters and
|
|
246
|
+
teams buying the packaged surface later.
|
|
247
|
+
</p>
|
|
248
|
+
</div>
|
|
249
|
+
<div className="flex flex-col gap-3 sm:flex-row md:flex-col">
|
|
250
|
+
<Link
|
|
251
|
+
href="/install"
|
|
252
|
+
className="btn-primary"
|
|
253
|
+
onClick={trackInstall}
|
|
254
|
+
>
|
|
255
|
+
Start with OSS
|
|
256
|
+
</Link>
|
|
257
|
+
<Link
|
|
258
|
+
href="https://www.contractspec.studio"
|
|
259
|
+
className="btn-ghost"
|
|
260
|
+
onClick={trackStudio}
|
|
261
|
+
>
|
|
262
|
+
Explore Studio
|
|
263
|
+
</Link>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
</div>
|
|
267
|
+
</section>
|
|
268
|
+
</main>
|
|
391
269
|
);
|