@contractspec/bundle.marketing 3.7.6 → 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/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 +22 -22
- 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,57 +1,56 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { ButtonLink, MarketingSection } from '@contractspec/lib.design-system';
|
|
3
1
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
analyticsEventNames,
|
|
3
|
+
captureAnalyticsEvent,
|
|
6
4
|
} from '@contractspec/bundle.library/libs/posthog/client';
|
|
5
|
+
import { ButtonLink, MarketingSection } from '@contractspec/lib.design-system';
|
|
7
6
|
import { VStack } from '@contractspec/lib.ui-kit-web/ui/stack';
|
|
8
7
|
import { H2, Lead } from '@contractspec/lib.ui-kit-web/ui/typography';
|
|
9
8
|
|
|
10
9
|
export function CtaSection() {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
10
|
+
return (
|
|
11
|
+
<MarketingSection
|
|
12
|
+
tone="gradient"
|
|
13
|
+
padding="comfortable"
|
|
14
|
+
align="center"
|
|
15
|
+
maxWidth="lg"
|
|
16
|
+
>
|
|
17
|
+
<VStack gap="md" align="center" className="text-center">
|
|
18
|
+
<H2 className="font-bold text-4xl md:text-5xl">
|
|
19
|
+
Ready to stabilize your codebase?
|
|
20
|
+
</H2>
|
|
21
|
+
<Lead className="text-lg text-muted-foreground">
|
|
22
|
+
Start with one module. See the difference. Expand at your own pace.
|
|
23
|
+
</Lead>
|
|
24
|
+
<VStack
|
|
25
|
+
as="div"
|
|
26
|
+
gap="sm"
|
|
27
|
+
align="center"
|
|
28
|
+
className="pt-2 sm:flex sm:flex-row sm:flex-wrap sm:items-center sm:justify-center"
|
|
29
|
+
>
|
|
30
|
+
<ButtonLink
|
|
31
|
+
href="https://www.contractspec.studio"
|
|
32
|
+
onClick={() =>
|
|
33
|
+
captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {
|
|
34
|
+
surface: 'cta-section',
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
>
|
|
38
|
+
Try Studio
|
|
39
|
+
</ButtonLink>
|
|
40
|
+
<ButtonLink
|
|
41
|
+
variant="ghost"
|
|
42
|
+
href="/contact"
|
|
43
|
+
onClick={() =>
|
|
44
|
+
captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {
|
|
45
|
+
surface: 'cta-section',
|
|
46
|
+
variant: 'contact',
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
>
|
|
50
|
+
Book a call
|
|
51
|
+
</ButtonLink>
|
|
52
|
+
</VStack>
|
|
53
|
+
</VStack>
|
|
54
|
+
</MarketingSection>
|
|
55
|
+
);
|
|
57
56
|
}
|
|
@@ -1,38 +1,37 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
ButtonLink,
|
|
3
|
+
MarketingComparisonSection,
|
|
5
4
|
} from '@contractspec/lib.design-system';
|
|
6
5
|
|
|
7
6
|
const standardTech = [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
'TypeScript & Zod — schemas you already know',
|
|
8
|
+
'Prisma — standard database access',
|
|
9
|
+
'GraphQL or REST — your choice',
|
|
10
|
+
'React or any UI framework',
|
|
11
|
+
'Bun, Node, Deno — all supported',
|
|
13
12
|
];
|
|
14
13
|
|
|
15
14
|
const noMagic = [
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
'Generated code is readable & modifiable',
|
|
16
|
+
'No proprietary runtime dependencies',
|
|
17
|
+
'Eject anytime, keep everything',
|
|
18
|
+
'Works with your existing CI/CD',
|
|
19
|
+
'Open spec format',
|
|
21
20
|
];
|
|
22
21
|
|
|
23
22
|
export function DevelopersSection() {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
23
|
+
return (
|
|
24
|
+
<MarketingComparisonSection
|
|
25
|
+
tone="muted"
|
|
26
|
+
title="Built for developers"
|
|
27
|
+
padding="comfortable"
|
|
28
|
+
left={{ title: 'Standard Tech Stack', items: standardTech }}
|
|
29
|
+
right={{ title: 'No Magic, No Lock-in', items: noMagic }}
|
|
30
|
+
subtitle={
|
|
31
|
+
<ButtonLink href="/docs">
|
|
32
|
+
Read the docs <span aria-hidden>→</span>
|
|
33
|
+
</ButtonLink>
|
|
34
|
+
}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
38
37
|
}
|
|
@@ -1,45 +1,44 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
import { CheckCircle, Code, Unlock, Zap } from 'lucide-react';
|
|
3
2
|
import { IconGridSection } from './IconGridSection';
|
|
4
3
|
|
|
5
4
|
const fears = [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
5
|
+
{
|
|
6
|
+
title: '"I already have an app"',
|
|
7
|
+
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.",
|
|
8
|
+
icon: CheckCircle,
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
title: '"Vendor lock-in / losing ownership"',
|
|
12
|
+
body: "You own the generated code. It's standard TypeScript, standard SQL, standard GraphQL. ContractSpec stays open and ejectable, so you can leave with the parts you adopted anytime.",
|
|
13
|
+
icon: Unlock,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
title: '"Adoption cost / learning curve"',
|
|
17
|
+
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.',
|
|
18
|
+
icon: Code,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
title: '"Forced migrations / magical runtime"',
|
|
22
|
+
body: "ContractSpec generates plain code you can read, debug, and modify. There's no proprietary runtime. Migrations are explicit, reversible, and in your control.",
|
|
23
|
+
icon: Zap,
|
|
24
|
+
},
|
|
26
25
|
];
|
|
27
26
|
|
|
28
27
|
export function FearsSection() {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
28
|
+
return (
|
|
29
|
+
<IconGridSection
|
|
30
|
+
tone="muted"
|
|
31
|
+
columns={2}
|
|
32
|
+
eyebrow="We Get It"
|
|
33
|
+
title="Your fears, addressed"
|
|
34
|
+
subtitle="We know what you're thinking. Here's why those concerns don't apply to ContractSpec."
|
|
35
|
+
iconRole="support"
|
|
36
|
+
items={fears.map((item) => ({
|
|
37
|
+
icon: item.icon,
|
|
38
|
+
title: item.title,
|
|
39
|
+
description: item.body,
|
|
40
|
+
iconClassName: 'text-violet-400',
|
|
41
|
+
}))}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
45
44
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { ButtonLink, MarketingSection } from '@contractspec/lib.design-system';
|
|
4
3
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
analyticsEventNames,
|
|
5
|
+
captureAnalyticsEvent,
|
|
7
6
|
} from '@contractspec/bundle.library/libs/posthog/client';
|
|
7
|
+
import { ButtonLink, MarketingSection } from '@contractspec/lib.design-system';
|
|
8
8
|
import { Box, HStack, VStack } from '@contractspec/lib.ui-kit-web/ui/stack';
|
|
9
9
|
import { H1, Lead, Small } from '@contractspec/lib.ui-kit-web/ui/typography';
|
|
10
10
|
import { ChevronRight } from 'lucide-react';
|
|
@@ -12,62 +12,62 @@ import { ChevronRight } from 'lucide-react';
|
|
|
12
12
|
const heroChips = ['Multi-Surface Sync', 'No Lock-in', 'Standard Tech'];
|
|
13
13
|
|
|
14
14
|
export function HeroMarketingSection() {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
15
|
+
return (
|
|
16
|
+
<MarketingSection tone="gradient" padding="spacious" align="center">
|
|
17
|
+
<VStack gap="lg" align="center" className="text-center">
|
|
18
|
+
<Box
|
|
19
|
+
as="div"
|
|
20
|
+
role="presentation"
|
|
21
|
+
className="inline-flex items-center rounded-full bg-muted px-3 py-1 font-medium text-muted-foreground text-xs uppercase tracking-wider"
|
|
22
|
+
>
|
|
23
|
+
Open Source Core
|
|
24
|
+
</Box>
|
|
25
|
+
<H1 className="text-balance font-bold text-4xl leading-tight md:text-5xl">
|
|
26
|
+
Stabilize your AI-generated code
|
|
27
|
+
</H1>
|
|
28
|
+
<Lead className="text-balance text-lg text-muted-foreground md:text-xl">
|
|
29
|
+
ContractSpec is the open spec system that keeps AI-written software
|
|
30
|
+
coherent, safe, and regenerable. You keep your app. You own the code.
|
|
31
|
+
One module at a time.
|
|
32
|
+
</Lead>
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
34
|
+
<HStack gap="md" justify="center" wrap="wrap">
|
|
35
|
+
<ButtonLink
|
|
36
|
+
href="/install"
|
|
37
|
+
onClick={() =>
|
|
38
|
+
captureAnalyticsEvent(analyticsEventNames.CTA_INSTALL_CLICK, {
|
|
39
|
+
surface: 'hero',
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
>
|
|
43
|
+
Install OSS <ChevronRight size={16} />
|
|
44
|
+
</ButtonLink>
|
|
45
|
+
<ButtonLink
|
|
46
|
+
variant="ghost"
|
|
47
|
+
href="https://www.contractspec.studio"
|
|
48
|
+
onClick={() =>
|
|
49
|
+
captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {
|
|
50
|
+
surface: 'hero',
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
>
|
|
54
|
+
Try Studio
|
|
55
|
+
</ButtonLink>
|
|
56
|
+
</HStack>
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
58
|
+
<HStack gap="sm" justify="center" wrap="wrap" className="pt-2">
|
|
59
|
+
{heroChips.map((chip) => (
|
|
60
|
+
<Box
|
|
61
|
+
key={chip}
|
|
62
|
+
as="div"
|
|
63
|
+
role="presentation"
|
|
64
|
+
className="inline-flex items-center rounded-full border border-border px-3 py-1 text-foreground text-sm"
|
|
65
|
+
>
|
|
66
|
+
<Small className="font-medium">{chip}</Small>
|
|
67
|
+
</Box>
|
|
68
|
+
))}
|
|
69
|
+
</HStack>
|
|
70
|
+
</VStack>
|
|
71
|
+
</MarketingSection>
|
|
72
|
+
);
|
|
73
73
|
}
|
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
1
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
MarketingCardsSection,
|
|
3
|
+
type MarketingCardTone,
|
|
4
|
+
MarketingIconCard,
|
|
5
|
+
type MarketingSectionPadding,
|
|
6
|
+
type MarketingSectionTone,
|
|
9
7
|
} from '@contractspec/lib.design-system';
|
|
10
8
|
import { Muted } from '@contractspec/lib.ui-kit-web/ui/typography';
|
|
9
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
10
|
+
import * as React from 'react';
|
|
11
11
|
|
|
12
12
|
type IconComponent = React.ComponentType<{ className?: string; size?: number }>;
|
|
13
13
|
|
|
14
14
|
export interface IconGridItem {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
icon: IconComponent;
|
|
16
|
+
title: string;
|
|
17
|
+
description: string;
|
|
18
|
+
iconClassName?: string;
|
|
19
|
+
tone?: MarketingCardTone;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
interface IconGridSectionProps {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
eyebrow?: string;
|
|
24
|
+
title: string;
|
|
25
|
+
subtitle?: string;
|
|
26
|
+
items: IconGridItem[];
|
|
27
|
+
tone?: MarketingSectionTone;
|
|
28
|
+
padding?: MarketingSectionPadding;
|
|
29
|
+
columns?: 2 | 3 | 4;
|
|
30
|
+
iconRole?: IconGridSectionRole;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
const itemVariants = cva('', {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
variants: {
|
|
35
|
+
iconRole: {
|
|
36
|
+
iconFirst: '',
|
|
37
|
+
listing: 'items-start',
|
|
38
|
+
support: 'items-start',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
defaultVariants: { iconRole: 'iconFirst' },
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
export type IconGridSectionRole = VariantProps<typeof itemVariants>['iconRole'];
|
|
45
45
|
|
|
46
46
|
export function IconGridSection({
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
47
|
+
eyebrow,
|
|
48
|
+
title,
|
|
49
|
+
subtitle,
|
|
50
|
+
items,
|
|
51
|
+
tone = 'default',
|
|
52
|
+
padding,
|
|
53
|
+
columns = 3,
|
|
54
|
+
iconRole = 'iconFirst',
|
|
55
55
|
}: IconGridSectionProps) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
56
|
+
return (
|
|
57
|
+
<MarketingCardsSection
|
|
58
|
+
tone={tone}
|
|
59
|
+
padding={padding}
|
|
60
|
+
eyebrow={
|
|
61
|
+
eyebrow ? (
|
|
62
|
+
<Muted className="font-semibold text-xs uppercase tracking-[0.2em]">
|
|
63
|
+
{eyebrow}
|
|
64
|
+
</Muted>
|
|
65
|
+
) : null
|
|
66
|
+
}
|
|
67
|
+
title={title}
|
|
68
|
+
subtitle={subtitle ? <Muted className="text-lg">{subtitle}</Muted> : null}
|
|
69
|
+
columns={columns}
|
|
70
|
+
>
|
|
71
|
+
{items.map((card) => (
|
|
72
|
+
<MarketingIconCard
|
|
73
|
+
key={card.title}
|
|
74
|
+
icon={card.icon}
|
|
75
|
+
title={card.title}
|
|
76
|
+
description={card.description}
|
|
77
|
+
tone={card.tone}
|
|
78
|
+
iconClassName={card.iconClassName}
|
|
79
|
+
variant={
|
|
80
|
+
iconRole === 'listing'
|
|
81
|
+
? 'listing'
|
|
82
|
+
: iconRole === 'support'
|
|
83
|
+
? 'support'
|
|
84
|
+
: 'iconFirst'
|
|
85
|
+
}
|
|
86
|
+
className={itemVariants({ iconRole })}
|
|
87
|
+
/>
|
|
88
|
+
))}
|
|
89
|
+
</MarketingCardsSection>
|
|
90
|
+
);
|
|
91
91
|
}
|