@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.
Files changed (164) hide show
  1. package/.turbo/turbo-build.log +84 -84
  2. package/AGENTS.md +29 -21
  3. package/CHANGELOG.md +27 -0
  4. package/README.md +36 -49
  5. package/dist/browser/components/marketing/ChangelogPage.js +8 -8
  6. package/dist/browser/components/marketing/CofounderPage.js +167 -523
  7. package/dist/browser/components/marketing/ContactClient.js +200 -207
  8. package/dist/browser/components/marketing/ContributePage.js +211 -463
  9. package/dist/browser/components/marketing/DesignPartnerPage.js +165 -218
  10. package/dist/browser/components/marketing/LandingPage.js +464 -568
  11. package/dist/browser/components/marketing/PricingClient.js +213 -839
  12. package/dist/browser/components/marketing/ProductClientPage.js +265 -463
  13. package/dist/browser/components/marketing/index.js +2007 -3338
  14. package/dist/browser/components/marketing/pricing-thinking-modal.js +12 -12
  15. package/dist/browser/components/marketing/sections/AudienceSection.js +2 -2
  16. package/dist/browser/components/marketing/sections/CorePositioningSection.js +2 -2
  17. package/dist/browser/components/marketing/sections/CtaSection.js +3 -3
  18. package/dist/browser/components/marketing/sections/FearsSection.js +3 -3
  19. package/dist/browser/components/marketing/sections/HeroMarketingSection.js +6 -6
  20. package/dist/browser/components/marketing/sections/IconGridSection.js +2 -2
  21. package/dist/browser/components/marketing/sections/OutputsSection.js +2 -2
  22. package/dist/browser/components/marketing/sections/ProblemSection.js +2 -2
  23. package/dist/browser/components/marketing/sections/SolutionSection.js +2 -2
  24. package/dist/browser/components/marketing/sections/StepsSection.js +4 -4
  25. package/dist/browser/components/marketing/studio-signup-section.js +25 -41
  26. package/dist/browser/components/templates/TemplatesClientPage.js +2324 -3578
  27. package/dist/browser/components/templates/TemplatesPage.js +1 -1
  28. package/dist/browser/components/templates/TemplatesPreviewModal.js +3 -3
  29. package/dist/browser/components/templates/index.js +2361 -3615
  30. package/dist/browser/index.js +2363 -3617
  31. package/dist/browser/libs/email/client.js +1 -1
  32. package/dist/browser/libs/email/contact.js +1 -1
  33. package/dist/browser/libs/email/newsletter.js +1 -1
  34. package/dist/browser/libs/email/waitlist-application.js +1 -1
  35. package/dist/browser/libs/email/waitlist.js +1 -1
  36. package/dist/browser/registry/engine.js +2003 -3334
  37. package/dist/browser/registry/index.js +2003 -3334
  38. package/dist/browser/registry/registry-docs.js +2 -2
  39. package/dist/browser/registry/registry-landing.js +2007 -3338
  40. package/dist/browser/registry/registry.js +2003 -3334
  41. package/dist/browser/registry/utils.js +2003 -3334
  42. package/dist/components/marketing/ChangelogPage.js +8 -8
  43. package/dist/components/marketing/CofounderPage.js +167 -523
  44. package/dist/components/marketing/ContactClient.js +200 -207
  45. package/dist/components/marketing/ContributePage.d.ts +0 -2
  46. package/dist/components/marketing/ContributePage.js +211 -463
  47. package/dist/components/marketing/DesignPartnerPage.js +165 -218
  48. package/dist/components/marketing/LandingPage.js +464 -568
  49. package/dist/components/marketing/PricingClient.js +213 -839
  50. package/dist/components/marketing/ProductClientPage.js +265 -463
  51. package/dist/components/marketing/index.d.ts +5 -5
  52. package/dist/components/marketing/index.js +2007 -3338
  53. package/dist/components/marketing/pricing-thinking-modal.js +12 -12
  54. package/dist/components/marketing/sections/AudienceSection.js +2 -2
  55. package/dist/components/marketing/sections/CorePositioningSection.js +2 -2
  56. package/dist/components/marketing/sections/CtaSection.js +3 -3
  57. package/dist/components/marketing/sections/FearsSection.js +3 -3
  58. package/dist/components/marketing/sections/HeroMarketingSection.js +6 -6
  59. package/dist/components/marketing/sections/IconGridSection.d.ts +3 -3
  60. package/dist/components/marketing/sections/IconGridSection.js +2 -2
  61. package/dist/components/marketing/sections/OutputsSection.js +2 -2
  62. package/dist/components/marketing/sections/ProblemSection.js +2 -2
  63. package/dist/components/marketing/sections/SolutionSection.js +2 -2
  64. package/dist/components/marketing/sections/StepsSection.js +4 -4
  65. package/dist/components/marketing/studio-signup-section.js +25 -41
  66. package/dist/components/templates/TemplatesClientPage.js +2324 -3578
  67. package/dist/components/templates/TemplatesPage.js +1 -1
  68. package/dist/components/templates/TemplatesPreviewModal.js +3 -3
  69. package/dist/components/templates/index.js +2361 -3615
  70. package/dist/index.js +2363 -3617
  71. package/dist/libs/email/client.js +1 -1
  72. package/dist/libs/email/contact.js +1 -1
  73. package/dist/libs/email/newsletter.js +1 -1
  74. package/dist/libs/email/waitlist-application.js +1 -1
  75. package/dist/libs/email/waitlist.js +1 -1
  76. package/dist/node/components/marketing/ChangelogPage.js +8 -8
  77. package/dist/node/components/marketing/CofounderPage.js +167 -523
  78. package/dist/node/components/marketing/ContactClient.js +200 -207
  79. package/dist/node/components/marketing/ContributePage.js +211 -463
  80. package/dist/node/components/marketing/DesignPartnerPage.js +165 -218
  81. package/dist/node/components/marketing/LandingPage.js +464 -568
  82. package/dist/node/components/marketing/PricingClient.js +213 -839
  83. package/dist/node/components/marketing/ProductClientPage.js +265 -463
  84. package/dist/node/components/marketing/index.js +2007 -3338
  85. package/dist/node/components/marketing/pricing-thinking-modal.js +12 -12
  86. package/dist/node/components/marketing/sections/AudienceSection.js +2 -2
  87. package/dist/node/components/marketing/sections/CorePositioningSection.js +2 -2
  88. package/dist/node/components/marketing/sections/CtaSection.js +3 -3
  89. package/dist/node/components/marketing/sections/FearsSection.js +3 -3
  90. package/dist/node/components/marketing/sections/HeroMarketingSection.js +6 -6
  91. package/dist/node/components/marketing/sections/IconGridSection.js +2 -2
  92. package/dist/node/components/marketing/sections/OutputsSection.js +2 -2
  93. package/dist/node/components/marketing/sections/ProblemSection.js +2 -2
  94. package/dist/node/components/marketing/sections/SolutionSection.js +2 -2
  95. package/dist/node/components/marketing/sections/StepsSection.js +4 -4
  96. package/dist/node/components/marketing/studio-signup-section.js +25 -41
  97. package/dist/node/components/templates/TemplatesClientPage.js +2324 -3578
  98. package/dist/node/components/templates/TemplatesPage.js +1 -1
  99. package/dist/node/components/templates/TemplatesPreviewModal.js +3 -3
  100. package/dist/node/components/templates/index.js +2361 -3615
  101. package/dist/node/index.js +2363 -3617
  102. package/dist/node/libs/email/client.js +1 -1
  103. package/dist/node/libs/email/contact.js +1 -1
  104. package/dist/node/libs/email/newsletter.js +1 -1
  105. package/dist/node/libs/email/waitlist-application.js +1 -1
  106. package/dist/node/libs/email/waitlist.js +1 -1
  107. package/dist/node/registry/engine.js +2003 -3334
  108. package/dist/node/registry/index.js +2003 -3334
  109. package/dist/node/registry/registry-docs.js +2 -2
  110. package/dist/node/registry/registry-landing.js +2007 -3338
  111. package/dist/node/registry/registry.js +2003 -3334
  112. package/dist/node/registry/utils.js +2003 -3334
  113. package/dist/registry/engine.js +2003 -3334
  114. package/dist/registry/index.js +2003 -3334
  115. package/dist/registry/registry-docs.js +2 -2
  116. package/dist/registry/registry-landing.js +2007 -3338
  117. package/dist/registry/registry.js +2003 -3334
  118. package/dist/registry/utils.js +2003 -3334
  119. package/package.json +29 -29
  120. package/src/bundles/MarketingBundle.ts +273 -273
  121. package/src/components/marketing/ChangelogPage.tsx +72 -100
  122. package/src/components/marketing/CofounderPage.tsx +120 -384
  123. package/src/components/marketing/ContactClient.tsx +164 -154
  124. package/src/components/marketing/ContributePage.tsx +139 -313
  125. package/src/components/marketing/DesignPartnerPage.tsx +133 -171
  126. package/src/components/marketing/LandingPage.tsx +353 -25
  127. package/src/components/marketing/PricingClient.tsx +192 -437
  128. package/src/components/marketing/ProductClientPage.tsx +255 -377
  129. package/src/components/marketing/index.ts +5 -5
  130. package/src/components/marketing/pricing-thinking-modal.tsx +197 -197
  131. package/src/components/marketing/sections/AudienceSection.tsx +55 -56
  132. package/src/components/marketing/sections/CorePositioningSection.tsx +37 -37
  133. package/src/components/marketing/sections/CtaSection.tsx +49 -50
  134. package/src/components/marketing/sections/DevelopersSection.tsx +26 -27
  135. package/src/components/marketing/sections/FearsSection.tsx +36 -37
  136. package/src/components/marketing/sections/HeroMarketingSection.tsx +59 -59
  137. package/src/components/marketing/sections/IconGridSection.tsx +71 -71
  138. package/src/components/marketing/sections/OutputsSection.tsx +51 -52
  139. package/src/components/marketing/sections/ProblemSection.tsx +39 -40
  140. package/src/components/marketing/sections/SolutionSection.tsx +39 -40
  141. package/src/components/marketing/sections/StepsSection.tsx +47 -48
  142. package/src/components/marketing/studio-signup-section.tsx +39 -41
  143. package/src/components/templates/TemplatesClientPage.tsx +727 -685
  144. package/src/components/templates/TemplatesPage.tsx +110 -110
  145. package/src/components/templates/TemplatesPreviewModal.tsx +197 -198
  146. package/src/index.ts +4 -4
  147. package/src/libs/email/client.test.ts +81 -81
  148. package/src/libs/email/client.ts +111 -111
  149. package/src/libs/email/contact.ts +35 -35
  150. package/src/libs/email/newsletter.ts +46 -46
  151. package/src/libs/email/types.ts +29 -29
  152. package/src/libs/email/utils.ts +5 -5
  153. package/src/libs/email/waitlist-application.ts +72 -72
  154. package/src/libs/email/waitlist.ts +46 -46
  155. package/src/libs/pricing-examples.ts +12 -12
  156. package/src/registry/engine.ts +16 -16
  157. package/src/registry/factory.ts +57 -57
  158. package/src/registry/registry-docs.ts +656 -666
  159. package/src/registry/registry-landing.ts +94 -95
  160. package/src/registry/registry.ts +36 -37
  161. package/src/registry/types.ts +2 -2
  162. package/src/registry/utils.ts +56 -56
  163. package/tsconfig.json +11 -11
  164. 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
- analyticsEventNames,
5
- captureAnalyticsEvent,
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
- return (
12
- <MarketingSection
13
- tone="gradient"
14
- padding="comfortable"
15
- align="center"
16
- maxWidth="lg"
17
- >
18
- <VStack gap="md" align="center" className="text-center">
19
- <H2 className="text-4xl font-bold md:text-5xl">
20
- Ready to stabilize your codebase?
21
- </H2>
22
- <Lead className="text-muted-foreground text-lg">
23
- Start with one module. See the difference. Expand at your own pace.
24
- </Lead>
25
- <VStack
26
- as="div"
27
- gap="sm"
28
- align="center"
29
- className="pt-2 sm:flex sm:flex-row sm:flex-wrap sm:items-center sm:justify-center"
30
- >
31
- <ButtonLink
32
- href="https://www.contractspec.studio"
33
- onClick={() =>
34
- captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {
35
- surface: 'cta-section',
36
- })
37
- }
38
- >
39
- Try Studio
40
- </ButtonLink>
41
- <ButtonLink
42
- variant="ghost"
43
- href="/contact"
44
- onClick={() =>
45
- captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {
46
- surface: 'cta-section',
47
- variant: 'contact',
48
- })
49
- }
50
- >
51
- Book a call
52
- </ButtonLink>
53
- </VStack>
54
- </VStack>
55
- </MarketingSection>
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
- ButtonLink,
4
- MarketingComparisonSection,
2
+ ButtonLink,
3
+ MarketingComparisonSection,
5
4
  } from '@contractspec/lib.design-system';
6
5
 
7
6
  const standardTech = [
8
- 'TypeScript & Zod — schemas you already know',
9
- 'Prisma — standard database access',
10
- 'GraphQL or REST — your choice',
11
- 'React or any UI framework',
12
- 'Bun, Node, Deno — all supported',
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
- 'Generated code is readable & modifiable',
17
- 'No proprietary runtime dependencies',
18
- 'Eject anytime, keep everything',
19
- 'Works with your existing CI/CD',
20
- 'Open spec format',
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
- return (
25
- <MarketingComparisonSection
26
- tone="muted"
27
- title="Built for developers"
28
- padding="comfortable"
29
- left={{ title: 'Standard Tech Stack', items: standardTech }}
30
- right={{ title: 'No Magic, No Lock-in', items: noMagic }}
31
- subtitle={
32
- <ButtonLink href="/docs">
33
- Read the docs <span aria-hidden>→</span>
34
- </ButtonLink>
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
- title: '"I already have an app"',
8
- 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.",
9
- icon: CheckCircle,
10
- },
11
- {
12
- title: '"Vendor lock-in / losing ownership"',
13
- 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.",
14
- icon: Unlock,
15
- },
16
- {
17
- title: '"Adoption cost / learning curve"',
18
- 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.',
19
- icon: Code,
20
- },
21
- {
22
- title: '"Forced migrations / magical runtime"',
23
- body: "ContractSpec generates plain code you can read, debug, and modify. There's no proprietary runtime. Migrations are explicit, reversible, and in your control.",
24
- icon: Zap,
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
- return (
30
- <IconGridSection
31
- tone="muted"
32
- columns={2}
33
- eyebrow="We Get It"
34
- title="Your fears, addressed"
35
- subtitle="We know what you're thinking. Here's why those concerns don't apply to ContractSpec."
36
- iconRole="support"
37
- items={fears.map((item) => ({
38
- icon: item.icon,
39
- title: item.title,
40
- description: item.body,
41
- iconClassName: 'text-violet-400',
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
- analyticsEventNames,
6
- captureAnalyticsEvent,
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
- 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="bg-muted text-muted-foreground inline-flex items-center rounded-full px-3 py-1 text-xs font-medium tracking-wider uppercase"
22
- >
23
- Open Source Core
24
- </Box>
25
- <H1 className="text-4xl leading-tight font-bold text-balance md:text-5xl">
26
- Stabilize your AI-generated code
27
- </H1>
28
- <Lead className="text-muted-foreground text-lg text-balance md:text-xl">
29
- ContractSpec is the compiler that keeps AI-written software coherent,
30
- safe, and regenerable. You keep your app. You own the code. One module
31
- at a time.
32
- </Lead>
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
- <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>
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
- <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="border-border text-foreground inline-flex items-center rounded-full border px-3 py-1 text-sm"
65
- >
66
- <Small className="font-medium">{chip}</Small>
67
- </Box>
68
- ))}
69
- </HStack>
70
- </VStack>
71
- </MarketingSection>
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
- MarketingCardsSection,
5
- MarketingIconCard,
6
- type MarketingCardTone,
7
- type MarketingSectionPadding,
8
- type MarketingSectionTone,
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
- icon: IconComponent;
16
- title: string;
17
- description: string;
18
- iconClassName?: string;
19
- tone?: MarketingCardTone;
15
+ icon: IconComponent;
16
+ title: string;
17
+ description: string;
18
+ iconClassName?: string;
19
+ tone?: MarketingCardTone;
20
20
  }
21
21
 
22
22
  interface IconGridSectionProps {
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;
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
- variants: {
35
- iconRole: {
36
- iconFirst: '',
37
- listing: 'items-start',
38
- support: 'items-start',
39
- },
40
- },
41
- defaultVariants: { iconRole: 'iconFirst' },
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
- eyebrow,
48
- title,
49
- subtitle,
50
- items,
51
- tone = 'default',
52
- padding,
53
- columns = 3,
54
- iconRole = 'iconFirst',
47
+ eyebrow,
48
+ title,
49
+ subtitle,
50
+ items,
51
+ tone = 'default',
52
+ padding,
53
+ columns = 3,
54
+ iconRole = 'iconFirst',
55
55
  }: IconGridSectionProps) {
56
- return (
57
- <MarketingCardsSection
58
- tone={tone}
59
- padding={padding}
60
- eyebrow={
61
- eyebrow ? (
62
- <Muted className="text-xs font-semibold tracking-[0.2em] uppercase">
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
- );
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
  }