@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.
Files changed (163) hide show
  1. package/.turbo/turbo-build.log +84 -84
  2. package/AGENTS.md +29 -21
  3. package/README.md +36 -49
  4. package/dist/browser/components/marketing/ChangelogPage.js +8 -8
  5. package/dist/browser/components/marketing/CofounderPage.js +167 -523
  6. package/dist/browser/components/marketing/ContactClient.js +200 -207
  7. package/dist/browser/components/marketing/ContributePage.js +211 -463
  8. package/dist/browser/components/marketing/DesignPartnerPage.js +165 -218
  9. package/dist/browser/components/marketing/LandingPage.js +464 -568
  10. package/dist/browser/components/marketing/PricingClient.js +213 -839
  11. package/dist/browser/components/marketing/ProductClientPage.js +265 -463
  12. package/dist/browser/components/marketing/index.js +2007 -3338
  13. package/dist/browser/components/marketing/pricing-thinking-modal.js +12 -12
  14. package/dist/browser/components/marketing/sections/AudienceSection.js +2 -2
  15. package/dist/browser/components/marketing/sections/CorePositioningSection.js +2 -2
  16. package/dist/browser/components/marketing/sections/CtaSection.js +3 -3
  17. package/dist/browser/components/marketing/sections/FearsSection.js +3 -3
  18. package/dist/browser/components/marketing/sections/HeroMarketingSection.js +6 -6
  19. package/dist/browser/components/marketing/sections/IconGridSection.js +2 -2
  20. package/dist/browser/components/marketing/sections/OutputsSection.js +2 -2
  21. package/dist/browser/components/marketing/sections/ProblemSection.js +2 -2
  22. package/dist/browser/components/marketing/sections/SolutionSection.js +2 -2
  23. package/dist/browser/components/marketing/sections/StepsSection.js +4 -4
  24. package/dist/browser/components/marketing/studio-signup-section.js +25 -41
  25. package/dist/browser/components/templates/TemplatesClientPage.js +2324 -3578
  26. package/dist/browser/components/templates/TemplatesPage.js +1 -1
  27. package/dist/browser/components/templates/TemplatesPreviewModal.js +3 -3
  28. package/dist/browser/components/templates/index.js +2361 -3615
  29. package/dist/browser/index.js +2363 -3617
  30. package/dist/browser/libs/email/client.js +1 -1
  31. package/dist/browser/libs/email/contact.js +1 -1
  32. package/dist/browser/libs/email/newsletter.js +1 -1
  33. package/dist/browser/libs/email/waitlist-application.js +1 -1
  34. package/dist/browser/libs/email/waitlist.js +1 -1
  35. package/dist/browser/registry/engine.js +2003 -3334
  36. package/dist/browser/registry/index.js +2003 -3334
  37. package/dist/browser/registry/registry-docs.js +2 -2
  38. package/dist/browser/registry/registry-landing.js +2007 -3338
  39. package/dist/browser/registry/registry.js +2003 -3334
  40. package/dist/browser/registry/utils.js +2003 -3334
  41. package/dist/components/marketing/ChangelogPage.js +8 -8
  42. package/dist/components/marketing/CofounderPage.js +167 -523
  43. package/dist/components/marketing/ContactClient.js +200 -207
  44. package/dist/components/marketing/ContributePage.d.ts +0 -2
  45. package/dist/components/marketing/ContributePage.js +211 -463
  46. package/dist/components/marketing/DesignPartnerPage.js +165 -218
  47. package/dist/components/marketing/LandingPage.js +464 -568
  48. package/dist/components/marketing/PricingClient.js +213 -839
  49. package/dist/components/marketing/ProductClientPage.js +265 -463
  50. package/dist/components/marketing/index.d.ts +5 -5
  51. package/dist/components/marketing/index.js +2007 -3338
  52. package/dist/components/marketing/pricing-thinking-modal.js +12 -12
  53. package/dist/components/marketing/sections/AudienceSection.js +2 -2
  54. package/dist/components/marketing/sections/CorePositioningSection.js +2 -2
  55. package/dist/components/marketing/sections/CtaSection.js +3 -3
  56. package/dist/components/marketing/sections/FearsSection.js +3 -3
  57. package/dist/components/marketing/sections/HeroMarketingSection.js +6 -6
  58. package/dist/components/marketing/sections/IconGridSection.d.ts +3 -3
  59. package/dist/components/marketing/sections/IconGridSection.js +2 -2
  60. package/dist/components/marketing/sections/OutputsSection.js +2 -2
  61. package/dist/components/marketing/sections/ProblemSection.js +2 -2
  62. package/dist/components/marketing/sections/SolutionSection.js +2 -2
  63. package/dist/components/marketing/sections/StepsSection.js +4 -4
  64. package/dist/components/marketing/studio-signup-section.js +25 -41
  65. package/dist/components/templates/TemplatesClientPage.js +2324 -3578
  66. package/dist/components/templates/TemplatesPage.js +1 -1
  67. package/dist/components/templates/TemplatesPreviewModal.js +3 -3
  68. package/dist/components/templates/index.js +2361 -3615
  69. package/dist/index.js +2363 -3617
  70. package/dist/libs/email/client.js +1 -1
  71. package/dist/libs/email/contact.js +1 -1
  72. package/dist/libs/email/newsletter.js +1 -1
  73. package/dist/libs/email/waitlist-application.js +1 -1
  74. package/dist/libs/email/waitlist.js +1 -1
  75. package/dist/node/components/marketing/ChangelogPage.js +8 -8
  76. package/dist/node/components/marketing/CofounderPage.js +167 -523
  77. package/dist/node/components/marketing/ContactClient.js +200 -207
  78. package/dist/node/components/marketing/ContributePage.js +211 -463
  79. package/dist/node/components/marketing/DesignPartnerPage.js +165 -218
  80. package/dist/node/components/marketing/LandingPage.js +464 -568
  81. package/dist/node/components/marketing/PricingClient.js +213 -839
  82. package/dist/node/components/marketing/ProductClientPage.js +265 -463
  83. package/dist/node/components/marketing/index.js +2007 -3338
  84. package/dist/node/components/marketing/pricing-thinking-modal.js +12 -12
  85. package/dist/node/components/marketing/sections/AudienceSection.js +2 -2
  86. package/dist/node/components/marketing/sections/CorePositioningSection.js +2 -2
  87. package/dist/node/components/marketing/sections/CtaSection.js +3 -3
  88. package/dist/node/components/marketing/sections/FearsSection.js +3 -3
  89. package/dist/node/components/marketing/sections/HeroMarketingSection.js +6 -6
  90. package/dist/node/components/marketing/sections/IconGridSection.js +2 -2
  91. package/dist/node/components/marketing/sections/OutputsSection.js +2 -2
  92. package/dist/node/components/marketing/sections/ProblemSection.js +2 -2
  93. package/dist/node/components/marketing/sections/SolutionSection.js +2 -2
  94. package/dist/node/components/marketing/sections/StepsSection.js +4 -4
  95. package/dist/node/components/marketing/studio-signup-section.js +25 -41
  96. package/dist/node/components/templates/TemplatesClientPage.js +2324 -3578
  97. package/dist/node/components/templates/TemplatesPage.js +1 -1
  98. package/dist/node/components/templates/TemplatesPreviewModal.js +3 -3
  99. package/dist/node/components/templates/index.js +2361 -3615
  100. package/dist/node/index.js +2363 -3617
  101. package/dist/node/libs/email/client.js +1 -1
  102. package/dist/node/libs/email/contact.js +1 -1
  103. package/dist/node/libs/email/newsletter.js +1 -1
  104. package/dist/node/libs/email/waitlist-application.js +1 -1
  105. package/dist/node/libs/email/waitlist.js +1 -1
  106. package/dist/node/registry/engine.js +2003 -3334
  107. package/dist/node/registry/index.js +2003 -3334
  108. package/dist/node/registry/registry-docs.js +2 -2
  109. package/dist/node/registry/registry-landing.js +2007 -3338
  110. package/dist/node/registry/registry.js +2003 -3334
  111. package/dist/node/registry/utils.js +2003 -3334
  112. package/dist/registry/engine.js +2003 -3334
  113. package/dist/registry/index.js +2003 -3334
  114. package/dist/registry/registry-docs.js +2 -2
  115. package/dist/registry/registry-landing.js +2007 -3338
  116. package/dist/registry/registry.js +2003 -3334
  117. package/dist/registry/utils.js +2003 -3334
  118. package/package.json +22 -22
  119. package/src/bundles/MarketingBundle.ts +273 -273
  120. package/src/components/marketing/ChangelogPage.tsx +72 -100
  121. package/src/components/marketing/CofounderPage.tsx +120 -384
  122. package/src/components/marketing/ContactClient.tsx +164 -154
  123. package/src/components/marketing/ContributePage.tsx +139 -313
  124. package/src/components/marketing/DesignPartnerPage.tsx +133 -171
  125. package/src/components/marketing/LandingPage.tsx +353 -25
  126. package/src/components/marketing/PricingClient.tsx +192 -437
  127. package/src/components/marketing/ProductClientPage.tsx +255 -377
  128. package/src/components/marketing/index.ts +5 -5
  129. package/src/components/marketing/pricing-thinking-modal.tsx +197 -197
  130. package/src/components/marketing/sections/AudienceSection.tsx +55 -56
  131. package/src/components/marketing/sections/CorePositioningSection.tsx +37 -37
  132. package/src/components/marketing/sections/CtaSection.tsx +49 -50
  133. package/src/components/marketing/sections/DevelopersSection.tsx +26 -27
  134. package/src/components/marketing/sections/FearsSection.tsx +36 -37
  135. package/src/components/marketing/sections/HeroMarketingSection.tsx +59 -59
  136. package/src/components/marketing/sections/IconGridSection.tsx +71 -71
  137. package/src/components/marketing/sections/OutputsSection.tsx +51 -52
  138. package/src/components/marketing/sections/ProblemSection.tsx +39 -40
  139. package/src/components/marketing/sections/SolutionSection.tsx +39 -40
  140. package/src/components/marketing/sections/StepsSection.tsx +47 -48
  141. package/src/components/marketing/studio-signup-section.tsx +39 -41
  142. package/src/components/templates/TemplatesClientPage.tsx +727 -685
  143. package/src/components/templates/TemplatesPage.tsx +110 -110
  144. package/src/components/templates/TemplatesPreviewModal.tsx +197 -198
  145. package/src/index.ts +4 -4
  146. package/src/libs/email/client.test.ts +81 -81
  147. package/src/libs/email/client.ts +111 -111
  148. package/src/libs/email/contact.ts +35 -35
  149. package/src/libs/email/newsletter.ts +46 -46
  150. package/src/libs/email/types.ts +29 -29
  151. package/src/libs/email/utils.ts +5 -5
  152. package/src/libs/email/waitlist-application.ts +72 -72
  153. package/src/libs/email/waitlist.ts +46 -46
  154. package/src/libs/pricing-examples.ts +12 -12
  155. package/src/registry/engine.ts +16 -16
  156. package/src/registry/factory.ts +57 -57
  157. package/src/registry/registry-docs.ts +656 -666
  158. package/src/registry/registry-landing.ts +94 -95
  159. package/src/registry/registry.ts +36 -37
  160. package/src/registry/types.ts +2 -2
  161. package/src/registry/utils.ts +56 -56
  162. package/tsconfig.json +11 -11
  163. 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
  }