@contractspec/bundle.marketing 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +73 -73
- package/CHANGELOG.md +49 -0
- package/README.md +6 -1
- package/dist/browser/components/marketing/CofounderPage.js +2 -2
- package/dist/browser/components/marketing/ContactClient.js +57 -961
- package/dist/browser/components/marketing/DesignPartnerPage.js +2 -2
- package/dist/browser/components/marketing/LandingPage.js +6 -6
- package/dist/browser/components/marketing/PricingClient.js +107 -1127
- package/dist/browser/components/marketing/ProductClientPage.js +2 -2
- package/dist/browser/components/marketing/index.js +157 -1064
- package/dist/browser/components/marketing/pricing-thinking-modal.js +3 -3
- package/dist/browser/components/marketing/sections/CorePositioningSection.js +2 -2
- package/dist/browser/components/marketing/sections/CtaSection.js +2 -2
- package/dist/browser/components/marketing/sections/HeroMarketingSection.js +2 -2
- package/dist/browser/components/marketing/studio-signup-section.js +87 -0
- package/dist/browser/components/templates/TemplatesClientPage.js +175 -1082
- package/dist/browser/components/templates/index.js +181 -1088
- package/dist/browser/index.js +505 -1157
- package/dist/browser/registry/engine.js +158 -1080
- package/dist/browser/registry/index.js +158 -1080
- package/dist/browser/registry/registry-docs.js +2 -17
- package/dist/browser/registry/registry-landing.js +156 -1063
- package/dist/browser/registry/registry.js +158 -1080
- package/dist/browser/registry/utils.js +158 -1080
- package/dist/components/marketing/CofounderPage.js +2 -2
- package/dist/components/marketing/ContactClient.js +57 -961
- package/dist/components/marketing/DesignPartnerPage.js +2 -2
- package/dist/components/marketing/LandingPage.js +6 -6
- package/dist/components/marketing/PricingClient.js +107 -1127
- package/dist/components/marketing/ProductClientPage.js +2 -2
- package/dist/components/marketing/index.d.ts +1 -1
- package/dist/components/marketing/index.js +157 -1064
- package/dist/components/marketing/pricing-thinking-modal.js +3 -3
- package/dist/components/marketing/sections/CorePositioningSection.js +2 -2
- package/dist/components/marketing/sections/CtaSection.js +2 -2
- package/dist/components/marketing/sections/HeroMarketingSection.js +2 -2
- package/dist/components/marketing/studio-signup-section.d.ts +5 -0
- package/dist/components/marketing/studio-signup-section.js +82 -0
- package/dist/components/templates/TemplatesClientPage.js +175 -1082
- package/dist/components/templates/index.js +181 -1088
- package/dist/index.js +505 -1157
- package/dist/node/components/marketing/CofounderPage.js +2 -2
- package/dist/node/components/marketing/ContactClient.js +57 -961
- package/dist/node/components/marketing/DesignPartnerPage.js +2 -2
- package/dist/node/components/marketing/LandingPage.js +6 -6
- package/dist/node/components/marketing/PricingClient.js +107 -1127
- package/dist/node/components/marketing/ProductClientPage.js +2 -2
- package/dist/node/components/marketing/index.js +157 -1064
- package/dist/node/components/marketing/pricing-thinking-modal.js +3 -3
- package/dist/node/components/marketing/sections/CorePositioningSection.js +2 -2
- package/dist/node/components/marketing/sections/CtaSection.js +2 -2
- package/dist/node/components/marketing/sections/HeroMarketingSection.js +2 -2
- package/dist/node/components/marketing/studio-signup-section.js +82 -0
- package/dist/node/components/templates/TemplatesClientPage.js +175 -1082
- package/dist/node/components/templates/index.js +181 -1088
- package/dist/node/index.js +505 -1157
- package/dist/node/registry/engine.js +158 -1080
- package/dist/node/registry/index.js +158 -1080
- package/dist/node/registry/registry-docs.js +2 -17
- package/dist/node/registry/registry-landing.js +156 -1063
- package/dist/node/registry/registry.js +158 -1080
- package/dist/node/registry/utils.js +158 -1080
- package/dist/registry/engine.js +158 -1080
- package/dist/registry/index.js +158 -1080
- package/dist/registry/registry-docs.js +2 -17
- package/dist/registry/registry-landing.js +156 -1063
- package/dist/registry/registry.js +158 -1080
- package/dist/registry/utils.js +158 -1080
- package/package.json +34 -34
- package/src/components/marketing/CofounderPage.tsx +2 -2
- package/src/components/marketing/ContactClient.tsx +3 -3
- package/src/components/marketing/DesignPartnerPage.tsx +3 -3
- package/src/components/marketing/PricingClient.tsx +39 -38
- package/src/components/marketing/ProductClientPage.tsx +2 -2
- package/src/components/marketing/index.ts +1 -1
- package/src/components/marketing/pricing-thinking-modal.tsx +5 -5
- package/src/components/marketing/sections/CorePositioningSection.tsx +2 -2
- package/src/components/marketing/sections/CtaSection.tsx +2 -2
- package/src/components/marketing/sections/HeroMarketingSection.tsx +2 -2
- package/src/components/marketing/studio-signup-section.tsx +56 -0
- package/src/components/templates/TemplatesClientPage.tsx +12 -9
- package/src/registry/registry-docs.ts +0 -40
- package/dist/browser/components/marketing/waitlist-section.js +0 -1104
- package/dist/components/marketing/waitlist-section.d.ts +0 -7
- package/dist/components/marketing/waitlist-section.js +0 -1099
- package/dist/node/components/marketing/waitlist-section.js +0 -1099
- package/src/components/marketing/waitlist-section.tsx +0 -606
package/dist/index.js
CHANGED
|
@@ -171,7 +171,7 @@ function WhatExistsSection() {
|
|
|
171
171
|
"Solo founder, bootstrapped"
|
|
172
172
|
];
|
|
173
173
|
const planned = [
|
|
174
|
-
"
|
|
174
|
+
"ContractSpec Studio product-decision engine",
|
|
175
175
|
"Auto-evolution engine",
|
|
176
176
|
"Multi-tenant SaaS",
|
|
177
177
|
"Integration marketplace"
|
|
@@ -257,7 +257,7 @@ function RoleSection() {
|
|
|
257
257
|
const productDeliverables = [
|
|
258
258
|
"Ship UI/UX improvements weekly",
|
|
259
259
|
"Define specs based on user research",
|
|
260
|
-
"Own the
|
|
260
|
+
"Own the Studio product experience",
|
|
261
261
|
"Collaborate on architecture decisions"
|
|
262
262
|
];
|
|
263
263
|
return /* @__PURE__ */ jsxDEV2(MarketingSection, {
|
|
@@ -834,978 +834,76 @@ Submitted via ContractSpec contact form
|
|
|
834
834
|
return { success: true, text: "Message sent successfully!" };
|
|
835
835
|
};
|
|
836
836
|
|
|
837
|
-
// src/
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
Thanks for joining the ContractSpec waitlist. You're now in line for early access to:
|
|
860
|
-
|
|
861
|
-
\u2022 Stabilize your AI-generated code with ContractSpec
|
|
862
|
-
\u2022 Multi-surface consistency (API, DB, UI, events)
|
|
863
|
-
\u2022 Safe regeneration without breaking changes
|
|
864
|
-
\u2022 AI governance and contract enforcement
|
|
865
|
-
|
|
866
|
-
We'll notify you as soon as early access is available. In the meantime, you can:
|
|
867
|
-
|
|
868
|
-
\u2022 Check out our docs: https://contractspec.io/docs
|
|
869
|
-
\u2022 Follow our progress on GitHub
|
|
870
|
-
\u2022 Book a demo call to see ContractSpec in action
|
|
871
|
-
|
|
872
|
-
We're excited to have you on board!
|
|
873
|
-
|
|
874
|
-
---
|
|
875
|
-
ContractSpec Team
|
|
876
|
-
https://contractspec.io
|
|
877
|
-
|
|
878
|
-
To remove yourself from the waitlist, reply to this email with "remove"
|
|
879
|
-
`.trim();
|
|
880
|
-
const waitlistHtml = `
|
|
881
|
-
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
882
|
-
<h1 style="color: #8b5cf6;">You're on the waitlist!</h1>
|
|
883
|
-
<p>Thanks for joining the ContractSpec waitlist. You're now in line for early access to:</p>
|
|
884
|
-
<ul style="line-height: 1.8;">
|
|
885
|
-
<li>Stabilize your AI-generated code with ContractSpec</li>
|
|
886
|
-
<li>Multi-surface consistency (API, DB, UI, events)</li>
|
|
887
|
-
<li>Safe regeneration without breaking changes</li>
|
|
888
|
-
<li>AI governance and contract enforcement</li>
|
|
889
|
-
</ul>
|
|
890
|
-
<p>We'll notify you as soon as early access is available. In the meantime, you can:</p>
|
|
891
|
-
<ul style="line-height: 1.8;">
|
|
892
|
-
<li>Check out our <a href="https://contractspec.io/docs" style="color: #8b5cf6;">docs</a></li>
|
|
893
|
-
<li>Follow our progress on GitHub</li>
|
|
894
|
-
<li>Book a demo call to see ContractSpec in action</li>
|
|
895
|
-
</ul>
|
|
896
|
-
<p>We're excited to have you on board!</p>
|
|
897
|
-
<hr style="margin: 30px 0; border: none; border-top: 1px solid #e5e7eb;" />
|
|
898
|
-
<p style="color: #6b7280; font-size: 14px;">
|
|
899
|
-
ContractSpec Team<br />
|
|
900
|
-
<a href="https://contractspec.io" style="color: #8b5cf6;">contractspec.io</a>
|
|
901
|
-
</p>
|
|
902
|
-
<p style="color: #9ca3af; font-size: 12px;">
|
|
903
|
-
To remove yourself from the waitlist, reply to this email with "remove"
|
|
904
|
-
</p>
|
|
905
|
-
</div>
|
|
906
|
-
`;
|
|
907
|
-
const userSend = await sendEmail(configResult.config, {
|
|
908
|
-
to: [{ email }],
|
|
909
|
-
subject: "You're on the ContractSpec waitlist!",
|
|
910
|
-
text: waitlistText,
|
|
911
|
-
html: waitlistHtml,
|
|
912
|
-
context: "waitlist-welcome"
|
|
913
|
-
});
|
|
914
|
-
if (!userSend.success) {
|
|
915
|
-
return { success: false, text: WAITLIST_SEND_ERROR };
|
|
916
|
-
}
|
|
917
|
-
const teamNotificationText = `New waitlist signup from: ${email}`;
|
|
918
|
-
const teamNotificationHtml = `
|
|
919
|
-
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
920
|
-
<p style="margin: 0 0 8px;">New waitlist signup</p>
|
|
921
|
-
<p style="margin: 0;"><strong>Email:</strong> ${formatMultilineHtml(email)}</p>
|
|
922
|
-
</div>
|
|
923
|
-
`;
|
|
924
|
-
const teamSend = await sendEmail(configResult.config, {
|
|
925
|
-
to: [configResult.config.teamInbox],
|
|
926
|
-
subject: `New Waitlist Signup: ${email}`,
|
|
927
|
-
text: teamNotificationText,
|
|
928
|
-
html: teamNotificationHtml,
|
|
929
|
-
context: "waitlist-team-notification"
|
|
930
|
-
});
|
|
931
|
-
if (!teamSend.success) {
|
|
932
|
-
return { success: false, text: WAITLIST_SEND_ERROR };
|
|
933
|
-
}
|
|
934
|
-
return { success: true, text: "Successfully joined waitlist!" };
|
|
935
|
-
};
|
|
936
|
-
|
|
937
|
-
// src/libs/email/waitlist-application.ts
|
|
938
|
-
"use server";
|
|
939
|
-
var APPLICATION_MISSING_CONFIG = "Waitlist application service is not configured. Please try again later.";
|
|
940
|
-
var APPLICATION_SEND_ERROR = "Failed to submit application. Please try again later or contact us directly.";
|
|
941
|
-
var submitWaitlistApplication = async (formData) => {
|
|
942
|
-
const email = (formData.get("email") ?? "").toString().trim();
|
|
943
|
-
const name = (formData.get("name") ?? "").toString().trim();
|
|
944
|
-
const company = (formData.get("company") ?? "").toString().trim();
|
|
945
|
-
const role = (formData.get("role") ?? "").toString().trim();
|
|
946
|
-
const useCase = (formData.get("useCase") ?? "").toString().trim();
|
|
947
|
-
const currentStack = (formData.get("currentStack") ?? "").toString().trim();
|
|
948
|
-
const whatBuilding = (formData.get("whatBuilding") ?? "").toString().trim();
|
|
949
|
-
const whatSolving = (formData.get("whatSolving") ?? "").toString().trim();
|
|
950
|
-
const teamSize = (formData.get("teamSize") ?? "").toString().trim();
|
|
951
|
-
const timeline = (formData.get("timeline") ?? "").toString().trim();
|
|
952
|
-
const openToSessions = formData.get("openToSessions") === "on";
|
|
953
|
-
const okayWithCaseStudies = formData.get("okayWithCaseStudies") === "on";
|
|
954
|
-
if (!email || !email.includes("@")) {
|
|
955
|
-
return {
|
|
956
|
-
success: false,
|
|
957
|
-
text: "Please enter a valid email address."
|
|
958
|
-
};
|
|
959
|
-
}
|
|
960
|
-
if (!name || !whatBuilding || !whatSolving) {
|
|
961
|
-
return {
|
|
962
|
-
success: false,
|
|
963
|
-
text: "Please fill in all required fields."
|
|
964
|
-
};
|
|
965
|
-
}
|
|
966
|
-
const configResult = getEmailConfig();
|
|
967
|
-
if (!configResult.ok || !configResult.config) {
|
|
968
|
-
return {
|
|
969
|
-
success: false,
|
|
970
|
-
text: configResult.errorMessage ?? APPLICATION_MISSING_CONFIG
|
|
971
|
-
};
|
|
972
|
-
}
|
|
973
|
-
const applicantText = `
|
|
974
|
-
You're on the list.
|
|
975
|
-
|
|
976
|
-
Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.
|
|
977
|
-
|
|
978
|
-
What happens next:
|
|
979
|
-
\u2022 We review applications weekly
|
|
980
|
-
\u2022 If selected, we'll reach out via email to schedule an intro call
|
|
981
|
-
\u2022 During early access, you'll get hands-on support and influence over the roadmap
|
|
982
|
-
|
|
983
|
-
In the meantime:
|
|
984
|
-
\u2022 Check out our docs: https://contractspec.io/docs
|
|
985
|
-
\u2022 Book a demo call: https://contractspec.io/contact
|
|
986
|
-
|
|
987
|
-
We're excited about the possibility of working together!
|
|
988
|
-
|
|
989
|
-
---
|
|
990
|
-
ContractSpec Team
|
|
991
|
-
https://contractspec.io
|
|
992
|
-
`.trim();
|
|
993
|
-
const applicantHtml = `
|
|
994
|
-
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
995
|
-
<h1 style="color: #8b5cf6;">You're on the list.</h1>
|
|
996
|
-
<p>Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.</p>
|
|
997
|
-
<h2 style="color: #8b5cf6; margin-top: 24px;">What happens next:</h2>
|
|
998
|
-
<ul style="line-height: 1.8;">
|
|
999
|
-
<li>We review applications weekly</li>
|
|
1000
|
-
<li>If selected, we'll reach out via email to schedule an intro call</li>
|
|
1001
|
-
<li>During early access, you'll get hands-on support and influence over the roadmap</li>
|
|
1002
|
-
</ul>
|
|
1003
|
-
<h2 style="color: #8b5cf6; margin-top: 24px;">In the meantime:</h2>
|
|
1004
|
-
<ul style="line-height: 1.8;">
|
|
1005
|
-
<li>Check out our <a href="https://contractspec.io/docs" style="color: #8b5cf6;">docs</a></li>
|
|
1006
|
-
<li>Book a demo call: <a href="https://contractspec.io/contact" style="color: #8b5cf6;">contractspec.io/contact</a></li>
|
|
1007
|
-
</ul>
|
|
1008
|
-
<p>We're excited about the possibility of working together!</p>
|
|
1009
|
-
<hr style="margin: 30px 0; border: none; border-top: 1px solid #e5e7eb;" />
|
|
1010
|
-
<p style="color: #6b7280; font-size: 14px;">
|
|
1011
|
-
ContractSpec Team<br />
|
|
1012
|
-
<a href="https://contractspec.io" style="color: #8b5cf6;">contractspec.io</a>
|
|
1013
|
-
</p>
|
|
1014
|
-
</div>
|
|
1015
|
-
`;
|
|
1016
|
-
const applicantSend = await sendEmail(configResult.config, {
|
|
1017
|
-
to: [{ email }],
|
|
1018
|
-
subject: "You're on the ContractSpec design partner waitlist!",
|
|
1019
|
-
text: applicantText,
|
|
1020
|
-
html: applicantHtml,
|
|
1021
|
-
context: "waitlist-application-welcome"
|
|
1022
|
-
});
|
|
1023
|
-
if (!applicantSend.success) {
|
|
1024
|
-
return { success: false, text: APPLICATION_SEND_ERROR };
|
|
1025
|
-
}
|
|
1026
|
-
const preferencesText = `
|
|
1027
|
-
Open to 1:1 product/design sessions: ${openToSessions ? "Yes" : "No"}
|
|
1028
|
-
Okay with anonymized case studies: ${okayWithCaseStudies ? "Yes" : "No"}
|
|
1029
|
-
`.trim();
|
|
1030
|
-
const teamEmailText = `
|
|
1031
|
-
New Design Partner Waitlist Application
|
|
1032
|
-
|
|
1033
|
-
Contact Information:
|
|
1034
|
-
- Name: ${name}
|
|
1035
|
-
- Email: ${email}
|
|
1036
|
-
${company ? `- Company/Project: ${company}` : ""}
|
|
1037
|
-
${role ? `- Role: ${role}` : ""}
|
|
1038
|
-
|
|
1039
|
-
Application Details:
|
|
1040
|
-
- What are you building with AI today?
|
|
1041
|
-
${whatBuilding}
|
|
1042
|
-
|
|
1043
|
-
- What do you hope ContractSpec will solve for you?
|
|
1044
|
-
${whatSolving}
|
|
1045
|
-
|
|
1046
|
-
- Primary use case: ${useCase || "Not specified"}
|
|
1047
|
-
- Current stack: ${currentStack || "Not specified"}
|
|
1048
|
-
- Team Size: ${teamSize || "Not specified"}
|
|
1049
|
-
- Timeline: ${timeline || "Not specified"}
|
|
1050
|
-
|
|
1051
|
-
Preferences:
|
|
1052
|
-
- Open to 1:1 product/design sessions: ${openToSessions ? "Yes" : "No"}
|
|
1053
|
-
- Okay with anonymized case studies: ${okayWithCaseStudies ? "Yes" : "No"}
|
|
1054
|
-
|
|
1055
|
-
---
|
|
1056
|
-
Submitted via ContractSpec waitlist application form
|
|
1057
|
-
`.trim();
|
|
1058
|
-
const teamEmailHtml = `
|
|
1059
|
-
<div style="font-family: sans-serif; max-width: 720px; margin: 0 auto;">
|
|
1060
|
-
<h1 style="color: #8b5cf6;">New Design Partner Waitlist Application</h1>
|
|
1061
|
-
<h2 style="color: #8b5cf6; margin: 16px 0 8px;">Contact Information</h2>
|
|
1062
|
-
<ul style="padding-left: 16px; line-height: 1.6; margin: 0 0 16px;">
|
|
1063
|
-
<li>Name: ${escapeHtml(name)}</li>
|
|
1064
|
-
<li>Email: ${escapeHtml(email)}</li>
|
|
1065
|
-
${company ? `<li>Company/Project: ${escapeHtml(company)}</li>` : ""}
|
|
1066
|
-
${role ? `<li>Role: ${escapeHtml(role)}</li>` : ""}
|
|
1067
|
-
</ul>
|
|
1068
|
-
<h2 style="color: #8b5cf6; margin: 16px 0 8px;">Application Details</h2>
|
|
1069
|
-
<p style="margin: 0 0 8px; font-weight: 600;">What are you building with AI today?</p>
|
|
1070
|
-
<div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; white-space: pre-wrap; line-height: 1.6;">
|
|
1071
|
-
${formatMultilineHtml(whatBuilding)}
|
|
1072
|
-
</div>
|
|
1073
|
-
<p style="margin: 16px 0 8px; font-weight: 600;">What do you hope ContractSpec will solve for you?</p>
|
|
1074
|
-
<div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; white-space: pre-wrap; line-height: 1.6;">
|
|
1075
|
-
${formatMultilineHtml(whatSolving)}
|
|
1076
|
-
</div>
|
|
1077
|
-
<ul style="padding-left: 16px; line-height: 1.6; margin: 16px 0;">
|
|
1078
|
-
<li>Primary use case: ${escapeHtml(useCase || "Not specified")}</li>
|
|
1079
|
-
<li>Current stack: ${escapeHtml(currentStack || "Not specified")}</li>
|
|
1080
|
-
<li>Team Size: ${escapeHtml(teamSize || "Not specified")}</li>
|
|
1081
|
-
<li>Timeline: ${escapeHtml(timeline || "Not specified")}</li>
|
|
1082
|
-
</ul>
|
|
1083
|
-
<h2 style="color: #8b5cf6; margin: 16px 0 8px;">Preferences</h2>
|
|
1084
|
-
<div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; line-height: 1.6;">
|
|
1085
|
-
${formatMultilineHtml(preferencesText)}
|
|
1086
|
-
</div>
|
|
1087
|
-
<p style="color: #6b7280; font-size: 12px; margin-top: 20px;">Submitted via ContractSpec waitlist application form</p>
|
|
1088
|
-
</div>
|
|
1089
|
-
`;
|
|
1090
|
-
const teamSend = await sendEmail(configResult.config, {
|
|
1091
|
-
to: [configResult.config.teamInbox],
|
|
1092
|
-
subject: `New Design Partner Application: ${name} (${email})`,
|
|
1093
|
-
text: teamEmailText,
|
|
1094
|
-
html: teamEmailHtml,
|
|
1095
|
-
replyTo: email,
|
|
1096
|
-
context: "waitlist-application-team-notification"
|
|
1097
|
-
});
|
|
1098
|
-
if (!teamSend.success) {
|
|
1099
|
-
return { success: false, text: APPLICATION_SEND_ERROR };
|
|
1100
|
-
}
|
|
1101
|
-
return {
|
|
1102
|
-
success: true,
|
|
1103
|
-
text: "Application submitted successfully!"
|
|
1104
|
-
};
|
|
1105
|
-
};
|
|
1106
|
-
|
|
1107
|
-
// src/components/marketing/waitlist-section.tsx
|
|
1108
|
-
import { useEffect, useState } from "react";
|
|
1109
|
-
import { useForm } from "react-hook-form";
|
|
1110
|
-
import { zodResolver } from "@hookform/resolvers/zod";
|
|
1111
|
-
import z from "zod";
|
|
1112
|
-
import { AlertCircle, CheckCircle } from "lucide-react";
|
|
1113
|
-
import { Button } from "@contractspec/lib.design-system";
|
|
1114
|
-
import { Textarea } from "@contractspec/lib.design-system";
|
|
1115
|
-
import { Label } from "@contractspec/lib.ui-kit-web/ui/label";
|
|
1116
|
-
import {
|
|
1117
|
-
Select,
|
|
1118
|
-
SelectContent,
|
|
1119
|
-
SelectItem,
|
|
1120
|
-
SelectTrigger,
|
|
1121
|
-
SelectValue
|
|
1122
|
-
} from "@contractspec/lib.ui-kit-web/ui/select";
|
|
1123
|
-
import { Checkbox } from "@contractspec/lib.ui-kit-web/ui/checkbox";
|
|
1124
|
-
import { Switch } from "@contractspec/lib.ui-kit-web/ui/switch";
|
|
1125
|
-
import { Input } from "@contractspec/lib.design-system";
|
|
1126
|
-
import { jsxDEV as jsxDEV3, Fragment } from "react/jsx-dev-runtime";
|
|
1127
|
-
"use client";
|
|
1128
|
-
var simpleWaitlistSchema = z.object({
|
|
1129
|
-
email: z.email("Please enter a valid email address")
|
|
1130
|
-
});
|
|
1131
|
-
var designPartnerSchema = z.object({
|
|
1132
|
-
name: z.string().min(1, "Name is required"),
|
|
1133
|
-
email: z.email("Please enter a valid email address"),
|
|
1134
|
-
company: z.string().optional(),
|
|
1135
|
-
role: z.string().optional(),
|
|
1136
|
-
useCase: z.string().optional(),
|
|
1137
|
-
currentStack: z.string().optional(),
|
|
1138
|
-
whatBuilding: z.string().min(1, "Please tell us what you are building"),
|
|
1139
|
-
whatSolving: z.string().min(1, "Please tell us what ContractSpec will solve for you"),
|
|
1140
|
-
teamSize: z.string().optional(),
|
|
1141
|
-
timeline: z.string().optional(),
|
|
1142
|
-
openToSessions: z.boolean().default(false),
|
|
1143
|
-
okayWithCaseStudies: z.boolean().default(false)
|
|
1144
|
-
});
|
|
1145
|
-
function WaitlistSection({
|
|
1146
|
-
variant = "default",
|
|
1147
|
-
context = "pricing"
|
|
1148
|
-
}) {
|
|
1149
|
-
const [isDesignPartner, setIsDesignPartner] = useState(false);
|
|
1150
|
-
const [submitResult, setSubmitResult] = useState(null);
|
|
1151
|
-
const [isPending, setIsPending] = useState(false);
|
|
1152
|
-
const simpleForm = useForm({
|
|
1153
|
-
resolver: zodResolver(simpleWaitlistSchema),
|
|
1154
|
-
defaultValues: {
|
|
1155
|
-
email: ""
|
|
1156
|
-
}
|
|
1157
|
-
});
|
|
1158
|
-
const designPartnerForm = useForm({
|
|
1159
|
-
resolver: zodResolver(designPartnerSchema),
|
|
1160
|
-
defaultValues: {
|
|
1161
|
-
name: "",
|
|
1162
|
-
email: "",
|
|
1163
|
-
company: "",
|
|
1164
|
-
role: "",
|
|
1165
|
-
useCase: "",
|
|
1166
|
-
currentStack: "",
|
|
1167
|
-
whatBuilding: "",
|
|
1168
|
-
whatSolving: "",
|
|
1169
|
-
teamSize: "",
|
|
1170
|
-
timeline: "",
|
|
1171
|
-
openToSessions: false,
|
|
1172
|
-
okayWithCaseStudies: false
|
|
1173
|
-
}
|
|
1174
|
-
});
|
|
1175
|
-
const simpleEmail = simpleForm.watch("email");
|
|
1176
|
-
const designPartnerEmail = designPartnerForm.watch("email");
|
|
1177
|
-
useEffect(() => {
|
|
1178
|
-
const currentDesignPartnerEmail = designPartnerForm.getValues("email");
|
|
1179
|
-
if (simpleEmail && simpleEmail !== currentDesignPartnerEmail) {
|
|
1180
|
-
designPartnerForm.setValue("email", simpleEmail, { shouldDirty: false });
|
|
1181
|
-
}
|
|
1182
|
-
}, [simpleEmail, designPartnerForm]);
|
|
1183
|
-
useEffect(() => {
|
|
1184
|
-
const currentSimpleEmail = simpleForm.getValues("email");
|
|
1185
|
-
if (designPartnerEmail && designPartnerEmail !== currentSimpleEmail) {
|
|
1186
|
-
simpleForm.setValue("email", designPartnerEmail, { shouldDirty: false });
|
|
1187
|
-
}
|
|
1188
|
-
}, [designPartnerEmail, simpleForm]);
|
|
1189
|
-
const handleSimpleSubmit = async (data) => {
|
|
1190
|
-
setIsPending(true);
|
|
1191
|
-
setSubmitResult(null);
|
|
1192
|
-
try {
|
|
1193
|
-
const formData = new FormData;
|
|
1194
|
-
formData.set("email", data.email);
|
|
1195
|
-
const result = await joinWaitlist(formData);
|
|
1196
|
-
if (result.success) {
|
|
1197
|
-
setSubmitResult({
|
|
1198
|
-
success: true,
|
|
1199
|
-
text: "Thanks for joining the waitlist! Check your inbox for a confirmation."
|
|
1200
|
-
});
|
|
1201
|
-
simpleForm.reset();
|
|
1202
|
-
} else {
|
|
1203
|
-
setSubmitResult({
|
|
1204
|
-
success: false,
|
|
1205
|
-
text: result.text || "Failed to join waitlist. Please try again."
|
|
1206
|
-
});
|
|
1207
|
-
}
|
|
1208
|
-
} catch (_error) {
|
|
1209
|
-
setSubmitResult({
|
|
1210
|
-
success: false,
|
|
1211
|
-
text: "Failed to join waitlist. Please try again."
|
|
1212
|
-
});
|
|
1213
|
-
} finally {
|
|
1214
|
-
setIsPending(false);
|
|
1215
|
-
}
|
|
1216
|
-
};
|
|
1217
|
-
const handleDesignPartnerSubmit = async (data) => {
|
|
1218
|
-
setIsPending(true);
|
|
1219
|
-
setSubmitResult(null);
|
|
1220
|
-
try {
|
|
1221
|
-
const formData = new FormData;
|
|
1222
|
-
formData.set("email", data.email);
|
|
1223
|
-
formData.set("name", data.name);
|
|
1224
|
-
if (data.company)
|
|
1225
|
-
formData.set("company", data.company);
|
|
1226
|
-
if (data.role)
|
|
1227
|
-
formData.set("role", data.role);
|
|
1228
|
-
if (data.useCase)
|
|
1229
|
-
formData.set("useCase", data.useCase);
|
|
1230
|
-
if (data.currentStack)
|
|
1231
|
-
formData.set("currentStack", data.currentStack);
|
|
1232
|
-
formData.set("whatBuilding", data.whatBuilding);
|
|
1233
|
-
formData.set("whatSolving", data.whatSolving);
|
|
1234
|
-
if (data.teamSize)
|
|
1235
|
-
formData.set("teamSize", data.teamSize);
|
|
1236
|
-
if (data.timeline)
|
|
1237
|
-
formData.set("timeline", data.timeline);
|
|
1238
|
-
if (data.openToSessions)
|
|
1239
|
-
formData.set("openToSessions", "on");
|
|
1240
|
-
if (data.okayWithCaseStudies)
|
|
1241
|
-
formData.set("okayWithCaseStudies", "on");
|
|
1242
|
-
const result = await submitWaitlistApplication(formData);
|
|
1243
|
-
if (result.success) {
|
|
1244
|
-
setSubmitResult({
|
|
1245
|
-
success: true,
|
|
1246
|
-
text: "You're on the list. Thanks for applying. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally."
|
|
1247
|
-
});
|
|
1248
|
-
designPartnerForm.reset();
|
|
1249
|
-
} else {
|
|
1250
|
-
setSubmitResult({
|
|
1251
|
-
success: false,
|
|
1252
|
-
text: result.text || "Failed to submit application. Please try again."
|
|
1253
|
-
});
|
|
1254
|
-
}
|
|
1255
|
-
} catch (_error) {
|
|
1256
|
-
setSubmitResult({
|
|
1257
|
-
success: false,
|
|
1258
|
-
text: "Failed to submit application. Please try again."
|
|
1259
|
-
});
|
|
1260
|
-
} finally {
|
|
1261
|
-
setIsPending(false);
|
|
1262
|
-
}
|
|
1263
|
-
};
|
|
1264
|
-
const onSubmit = isDesignPartner ? designPartnerForm.handleSubmit(handleDesignPartnerSubmit) : simpleForm.handleSubmit(handleSimpleSubmit);
|
|
1265
|
-
const isCompact = variant === "compact";
|
|
1266
|
-
return /* @__PURE__ */ jsxDEV3("div", {
|
|
1267
|
-
id: "waitlist",
|
|
1268
|
-
className: isCompact ? "space-y-4" : "card-subtle space-y-6 p-8",
|
|
1269
|
-
children: [
|
|
1270
|
-
!isCompact && /* @__PURE__ */ jsxDEV3("div", {
|
|
1271
|
-
className: "space-y-4",
|
|
1272
|
-
children: [
|
|
1273
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1274
|
-
className: "inline-flex items-center gap-2 rounded-full border border-violet-500/20 bg-violet-500/10 px-3 py-1",
|
|
1275
|
-
children: /* @__PURE__ */ jsxDEV3("span", {
|
|
1276
|
-
className: "text-sm font-medium text-violet-300",
|
|
1277
|
-
children: isDesignPartner ? "Design Partner Waitlist" : "Join the Waitlist"
|
|
1278
|
-
}, undefined, false, undefined, this)
|
|
1279
|
-
}, undefined, false, undefined, this),
|
|
1280
|
-
/* @__PURE__ */ jsxDEV3("h2", {
|
|
1281
|
-
className: "text-2xl font-bold",
|
|
1282
|
-
children: isDesignPartner ? "Apply for early access to ContractSpec" : "Get early access to ContractSpec"
|
|
1283
|
-
}, undefined, false, undefined, this),
|
|
1284
|
-
/* @__PURE__ */ jsxDEV3("p", {
|
|
1285
|
-
className: "text-muted-foreground text-sm",
|
|
1286
|
-
children: isDesignPartner ? "Tell us what you're building. We'll prioritize teams where ContractSpec can have a big impact, and where we can learn the most." : "Join the waitlist to be notified when ContractSpec becomes available."
|
|
1287
|
-
}, undefined, false, undefined, this)
|
|
1288
|
-
]
|
|
1289
|
-
}, undefined, true, undefined, this),
|
|
1290
|
-
!isCompact && /* @__PURE__ */ jsxDEV3("div", {
|
|
1291
|
-
className: "border-border bg-muted/20 flex items-center justify-between gap-4 rounded-lg border p-4",
|
|
1292
|
-
children: [
|
|
1293
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1294
|
-
className: "space-y-1",
|
|
1295
|
-
children: [
|
|
1296
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1297
|
-
htmlFor: "design-partner-toggle",
|
|
1298
|
-
className: "text-sm font-medium",
|
|
1299
|
-
children: "Apply as a design partner"
|
|
1300
|
-
}, undefined, false, undefined, this),
|
|
1301
|
-
/* @__PURE__ */ jsxDEV3("p", {
|
|
1302
|
-
className: "text-muted-foreground text-xs",
|
|
1303
|
-
children: isDesignPartner ? "Get hands-on support, influence the roadmap, and founding discount" : "Get priority access, 1:1 onboarding, and help shape ContractSpec"
|
|
1304
|
-
}, undefined, false, undefined, this)
|
|
1305
|
-
]
|
|
1306
|
-
}, undefined, true, undefined, this),
|
|
1307
|
-
/* @__PURE__ */ jsxDEV3(Switch, {
|
|
1308
|
-
id: "design-partner-toggle",
|
|
1309
|
-
checked: isDesignPartner,
|
|
1310
|
-
onCheckedChange: setIsDesignPartner,
|
|
1311
|
-
disabled: isPending || submitResult?.success
|
|
1312
|
-
}, undefined, false, undefined, this)
|
|
1313
|
-
]
|
|
1314
|
-
}, undefined, true, undefined, this),
|
|
1315
|
-
!isCompact && isDesignPartner && /* @__PURE__ */ jsxDEV3("div", {
|
|
1316
|
-
className: "space-y-2",
|
|
1317
|
-
children: [
|
|
1318
|
-
/* @__PURE__ */ jsxDEV3("p", {
|
|
1319
|
-
className: "text-sm font-medium",
|
|
1320
|
-
children: "Benefits:"
|
|
1321
|
-
}, undefined, false, undefined, this),
|
|
1322
|
-
/* @__PURE__ */ jsxDEV3("ul", {
|
|
1323
|
-
className: "text-muted-foreground space-y-1 text-sm",
|
|
1324
|
-
children: [
|
|
1325
|
-
/* @__PURE__ */ jsxDEV3("li", {
|
|
1326
|
-
children: "\u2022 Early access to ContractSpec Studio"
|
|
1327
|
-
}, undefined, false, undefined, this),
|
|
1328
|
-
/* @__PURE__ */ jsxDEV3("li", {
|
|
1329
|
-
children: "\u2022 1:1 onboarding and architecture sessions"
|
|
1330
|
-
}, undefined, false, undefined, this),
|
|
1331
|
-
/* @__PURE__ */ jsxDEV3("li", {
|
|
1332
|
-
children: "\u2022 Priority support via direct channels"
|
|
1333
|
-
}, undefined, false, undefined, this),
|
|
1334
|
-
/* @__PURE__ */ jsxDEV3("li", {
|
|
1335
|
-
children: "\u2022 Influence over roadmap and features"
|
|
1336
|
-
}, undefined, false, undefined, this),
|
|
1337
|
-
/* @__PURE__ */ jsxDEV3("li", {
|
|
1338
|
-
children: "\u2022 Founding discount when paid plans launch"
|
|
1339
|
-
}, undefined, false, undefined, this)
|
|
1340
|
-
]
|
|
1341
|
-
}, undefined, true, undefined, this)
|
|
1342
|
-
]
|
|
1343
|
-
}, undefined, true, undefined, this),
|
|
1344
|
-
/* @__PURE__ */ jsxDEV3("form", {
|
|
1345
|
-
onSubmit,
|
|
1346
|
-
className: "space-y-4",
|
|
1347
|
-
children: [
|
|
1348
|
-
isDesignPartner ? /* @__PURE__ */ jsxDEV3(Fragment, {
|
|
1349
|
-
children: [
|
|
1350
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1351
|
-
className: "grid gap-4 md:grid-cols-2",
|
|
1352
|
-
children: [
|
|
1353
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1354
|
-
className: "space-y-2",
|
|
1355
|
-
children: [
|
|
1356
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1357
|
-
htmlFor: "waitlist-name",
|
|
1358
|
-
className: "text-sm font-medium",
|
|
1359
|
-
children: [
|
|
1360
|
-
"Name ",
|
|
1361
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
1362
|
-
className: "text-red-400",
|
|
1363
|
-
children: "*"
|
|
1364
|
-
}, undefined, false, undefined, this)
|
|
1365
|
-
]
|
|
1366
|
-
}, undefined, true, undefined, this),
|
|
1367
|
-
/* @__PURE__ */ jsxDEV3(Input, {
|
|
1368
|
-
id: "waitlist-name",
|
|
1369
|
-
...designPartnerForm.register("name"),
|
|
1370
|
-
type: "text",
|
|
1371
|
-
placeholder: "Your name",
|
|
1372
|
-
disabled: isPending || submitResult?.success
|
|
1373
|
-
}, undefined, false, undefined, this),
|
|
1374
|
-
designPartnerForm.formState.errors.name && /* @__PURE__ */ jsxDEV3("p", {
|
|
1375
|
-
className: "text-xs text-red-400",
|
|
1376
|
-
children: designPartnerForm.formState.errors.name.message
|
|
1377
|
-
}, undefined, false, undefined, this)
|
|
1378
|
-
]
|
|
1379
|
-
}, undefined, true, undefined, this),
|
|
1380
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1381
|
-
className: "space-y-2",
|
|
1382
|
-
children: [
|
|
1383
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1384
|
-
htmlFor: "waitlist-email",
|
|
1385
|
-
className: "text-sm font-medium",
|
|
1386
|
-
children: [
|
|
1387
|
-
"Email ",
|
|
1388
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
1389
|
-
className: "text-red-400",
|
|
1390
|
-
children: "*"
|
|
1391
|
-
}, undefined, false, undefined, this)
|
|
1392
|
-
]
|
|
1393
|
-
}, undefined, true, undefined, this),
|
|
1394
|
-
/* @__PURE__ */ jsxDEV3(Input, {
|
|
1395
|
-
id: "waitlist-email",
|
|
1396
|
-
...designPartnerForm.register("email"),
|
|
1397
|
-
type: "email",
|
|
1398
|
-
placeholder: "your@email.com",
|
|
1399
|
-
disabled: isPending || submitResult?.success
|
|
1400
|
-
}, undefined, false, undefined, this),
|
|
1401
|
-
designPartnerForm.formState.errors.email && /* @__PURE__ */ jsxDEV3("p", {
|
|
1402
|
-
className: "text-xs text-red-400",
|
|
1403
|
-
children: designPartnerForm.formState.errors.email.message
|
|
1404
|
-
}, undefined, false, undefined, this)
|
|
1405
|
-
]
|
|
1406
|
-
}, undefined, true, undefined, this)
|
|
1407
|
-
]
|
|
1408
|
-
}, undefined, true, undefined, this),
|
|
1409
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1410
|
-
className: "grid gap-4 md:grid-cols-2",
|
|
1411
|
-
children: [
|
|
1412
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1413
|
-
className: "space-y-2",
|
|
1414
|
-
children: [
|
|
1415
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1416
|
-
htmlFor: "waitlist-company",
|
|
1417
|
-
className: "text-sm font-medium",
|
|
1418
|
-
children: "Company / Project Name"
|
|
1419
|
-
}, undefined, false, undefined, this),
|
|
1420
|
-
/* @__PURE__ */ jsxDEV3(Input, {
|
|
1421
|
-
id: "waitlist-company",
|
|
1422
|
-
...designPartnerForm.register("company"),
|
|
1423
|
-
type: "text",
|
|
1424
|
-
placeholder: "Your company or project",
|
|
1425
|
-
disabled: isPending || submitResult?.success
|
|
1426
|
-
}, undefined, false, undefined, this)
|
|
1427
|
-
]
|
|
1428
|
-
}, undefined, true, undefined, this),
|
|
1429
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1430
|
-
className: "space-y-2",
|
|
1431
|
-
children: [
|
|
1432
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1433
|
-
htmlFor: "waitlist-role",
|
|
1434
|
-
className: "text-sm font-medium",
|
|
1435
|
-
children: "Role"
|
|
1436
|
-
}, undefined, false, undefined, this),
|
|
1437
|
-
/* @__PURE__ */ jsxDEV3(Select, {
|
|
1438
|
-
value: designPartnerForm.watch("role") || "",
|
|
1439
|
-
onValueChange: (value) => designPartnerForm.setValue("role", value),
|
|
1440
|
-
disabled: isPending || submitResult?.success,
|
|
1441
|
-
children: [
|
|
1442
|
-
/* @__PURE__ */ jsxDEV3(SelectTrigger, {
|
|
1443
|
-
id: "waitlist-role",
|
|
1444
|
-
className: "w-full",
|
|
1445
|
-
children: /* @__PURE__ */ jsxDEV3(SelectValue, {
|
|
1446
|
-
placeholder: "Select your role"
|
|
1447
|
-
}, undefined, false, undefined, this)
|
|
1448
|
-
}, undefined, false, undefined, this),
|
|
1449
|
-
/* @__PURE__ */ jsxDEV3(SelectContent, {
|
|
1450
|
-
children: [
|
|
1451
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1452
|
-
value: "founder",
|
|
1453
|
-
children: "Founder"
|
|
1454
|
-
}, undefined, false, undefined, this),
|
|
1455
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1456
|
-
value: "cto",
|
|
1457
|
-
children: "CTO"
|
|
1458
|
-
}, undefined, false, undefined, this),
|
|
1459
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1460
|
-
value: "lead-engineer",
|
|
1461
|
-
children: "Lead Engineer"
|
|
1462
|
-
}, undefined, false, undefined, this),
|
|
1463
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1464
|
-
value: "engineer",
|
|
1465
|
-
children: "Engineer"
|
|
1466
|
-
}, undefined, false, undefined, this),
|
|
1467
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1468
|
-
value: "product-manager",
|
|
1469
|
-
children: "Product Manager"
|
|
1470
|
-
}, undefined, false, undefined, this),
|
|
1471
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1472
|
-
value: "other",
|
|
1473
|
-
children: "Other"
|
|
1474
|
-
}, undefined, false, undefined, this)
|
|
1475
|
-
]
|
|
1476
|
-
}, undefined, true, undefined, this)
|
|
1477
|
-
]
|
|
1478
|
-
}, undefined, true, undefined, this)
|
|
1479
|
-
]
|
|
1480
|
-
}, undefined, true, undefined, this)
|
|
1481
|
-
]
|
|
1482
|
-
}, undefined, true, undefined, this),
|
|
1483
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1484
|
-
className: "grid gap-4 md:grid-cols-2",
|
|
1485
|
-
children: [
|
|
1486
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1487
|
-
className: "space-y-2",
|
|
1488
|
-
children: [
|
|
1489
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1490
|
-
htmlFor: "waitlist-use-case",
|
|
1491
|
-
className: "text-sm font-medium",
|
|
1492
|
-
children: "Primary use case"
|
|
1493
|
-
}, undefined, false, undefined, this),
|
|
1494
|
-
/* @__PURE__ */ jsxDEV3(Select, {
|
|
1495
|
-
value: designPartnerForm.watch("useCase") || "",
|
|
1496
|
-
onValueChange: (value) => designPartnerForm.setValue("useCase", value),
|
|
1497
|
-
disabled: isPending || submitResult?.success,
|
|
1498
|
-
children: [
|
|
1499
|
-
/* @__PURE__ */ jsxDEV3(SelectTrigger, {
|
|
1500
|
-
id: "waitlist-use-case",
|
|
1501
|
-
className: "w-full",
|
|
1502
|
-
children: /* @__PURE__ */ jsxDEV3(SelectValue, {
|
|
1503
|
-
placeholder: "Select a use case"
|
|
1504
|
-
}, undefined, false, undefined, this)
|
|
1505
|
-
}, undefined, false, undefined, this),
|
|
1506
|
-
/* @__PURE__ */ jsxDEV3(SelectContent, {
|
|
1507
|
-
children: [
|
|
1508
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1509
|
-
value: "api-platform",
|
|
1510
|
-
children: "API platform"
|
|
1511
|
-
}, undefined, false, undefined, this),
|
|
1512
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1513
|
-
value: "ai-ops",
|
|
1514
|
-
children: "AI operations"
|
|
1515
|
-
}, undefined, false, undefined, this),
|
|
1516
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1517
|
-
value: "integration-hub",
|
|
1518
|
-
children: "Integration hub"
|
|
1519
|
-
}, undefined, false, undefined, this),
|
|
1520
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1521
|
-
value: "internal-tools",
|
|
1522
|
-
children: "Internal tools"
|
|
1523
|
-
}, undefined, false, undefined, this),
|
|
1524
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1525
|
-
value: "data-pipelines",
|
|
1526
|
-
children: "Data pipelines"
|
|
1527
|
-
}, undefined, false, undefined, this),
|
|
1528
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1529
|
-
value: "other",
|
|
1530
|
-
children: "Other"
|
|
1531
|
-
}, undefined, false, undefined, this)
|
|
1532
|
-
]
|
|
1533
|
-
}, undefined, true, undefined, this)
|
|
1534
|
-
]
|
|
1535
|
-
}, undefined, true, undefined, this)
|
|
1536
|
-
]
|
|
1537
|
-
}, undefined, true, undefined, this),
|
|
1538
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1539
|
-
className: "space-y-2",
|
|
1540
|
-
children: [
|
|
1541
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1542
|
-
htmlFor: "waitlist-current-stack",
|
|
1543
|
-
className: "text-sm font-medium",
|
|
1544
|
-
children: "Current stack"
|
|
1545
|
-
}, undefined, false, undefined, this),
|
|
1546
|
-
/* @__PURE__ */ jsxDEV3(Input, {
|
|
1547
|
-
id: "waitlist-current-stack",
|
|
1548
|
-
...designPartnerForm.register("currentStack"),
|
|
1549
|
-
type: "text",
|
|
1550
|
-
placeholder: "e.g. Next.js, Postgres, OpenAPI",
|
|
1551
|
-
disabled: isPending || submitResult?.success
|
|
1552
|
-
}, undefined, false, undefined, this)
|
|
1553
|
-
]
|
|
1554
|
-
}, undefined, true, undefined, this)
|
|
1555
|
-
]
|
|
1556
|
-
}, undefined, true, undefined, this),
|
|
1557
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1558
|
-
className: "space-y-2",
|
|
1559
|
-
children: [
|
|
1560
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1561
|
-
htmlFor: "waitlist-what-building",
|
|
1562
|
-
className: "text-sm font-medium",
|
|
1563
|
-
children: [
|
|
1564
|
-
"What are you building with AI today?",
|
|
1565
|
-
" ",
|
|
1566
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
1567
|
-
className: "text-red-400",
|
|
1568
|
-
children: "*"
|
|
1569
|
-
}, undefined, false, undefined, this)
|
|
1570
|
-
]
|
|
1571
|
-
}, undefined, true, undefined, this),
|
|
1572
|
-
/* @__PURE__ */ jsxDEV3(Textarea, {
|
|
1573
|
-
id: "waitlist-what-building",
|
|
1574
|
-
...designPartnerForm.register("whatBuilding"),
|
|
1575
|
-
placeholder: "Tell us about your project...",
|
|
1576
|
-
disabled: isPending || submitResult?.success,
|
|
1577
|
-
rows: 4
|
|
1578
|
-
}, undefined, false, undefined, this),
|
|
1579
|
-
designPartnerForm.formState.errors.whatBuilding && /* @__PURE__ */ jsxDEV3("p", {
|
|
1580
|
-
className: "text-xs text-red-400",
|
|
1581
|
-
children: designPartnerForm.formState.errors.whatBuilding.message
|
|
1582
|
-
}, undefined, false, undefined, this)
|
|
1583
|
-
]
|
|
1584
|
-
}, undefined, true, undefined, this),
|
|
1585
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1586
|
-
className: "space-y-2",
|
|
1587
|
-
children: [
|
|
1588
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1589
|
-
htmlFor: "waitlist-what-solving",
|
|
1590
|
-
className: "text-sm font-medium",
|
|
1591
|
-
children: [
|
|
1592
|
-
"What do you hope ContractSpec will solve for you?",
|
|
1593
|
-
" ",
|
|
1594
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
1595
|
-
className: "text-red-400",
|
|
1596
|
-
children: "*"
|
|
1597
|
-
}, undefined, false, undefined, this)
|
|
1598
|
-
]
|
|
1599
|
-
}, undefined, true, undefined, this),
|
|
1600
|
-
/* @__PURE__ */ jsxDEV3(Textarea, {
|
|
1601
|
-
id: "waitlist-what-solving",
|
|
1602
|
-
...designPartnerForm.register("whatSolving"),
|
|
1603
|
-
placeholder: "What problems are you trying to solve?",
|
|
1604
|
-
disabled: isPending || submitResult?.success,
|
|
1605
|
-
rows: 4
|
|
1606
|
-
}, undefined, false, undefined, this),
|
|
1607
|
-
designPartnerForm.formState.errors.whatSolving && /* @__PURE__ */ jsxDEV3("p", {
|
|
1608
|
-
className: "text-xs text-red-400",
|
|
1609
|
-
children: designPartnerForm.formState.errors.whatSolving.message
|
|
1610
|
-
}, undefined, false, undefined, this)
|
|
1611
|
-
]
|
|
1612
|
-
}, undefined, true, undefined, this),
|
|
1613
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1614
|
-
className: "grid gap-4 md:grid-cols-2",
|
|
1615
|
-
children: [
|
|
1616
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1617
|
-
className: "space-y-2",
|
|
1618
|
-
children: [
|
|
1619
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1620
|
-
htmlFor: "waitlist-team-size",
|
|
1621
|
-
className: "text-sm font-medium",
|
|
1622
|
-
children: "Team Size"
|
|
1623
|
-
}, undefined, false, undefined, this),
|
|
1624
|
-
/* @__PURE__ */ jsxDEV3(Select, {
|
|
1625
|
-
value: designPartnerForm.watch("teamSize") || "",
|
|
1626
|
-
onValueChange: (value) => designPartnerForm.setValue("teamSize", value),
|
|
1627
|
-
disabled: isPending || submitResult?.success,
|
|
1628
|
-
children: [
|
|
1629
|
-
/* @__PURE__ */ jsxDEV3(SelectTrigger, {
|
|
1630
|
-
id: "waitlist-team-size",
|
|
1631
|
-
className: "w-full",
|
|
1632
|
-
children: /* @__PURE__ */ jsxDEV3(SelectValue, {
|
|
1633
|
-
placeholder: "Select team size"
|
|
1634
|
-
}, undefined, false, undefined, this)
|
|
1635
|
-
}, undefined, false, undefined, this),
|
|
1636
|
-
/* @__PURE__ */ jsxDEV3(SelectContent, {
|
|
1637
|
-
children: [
|
|
1638
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1639
|
-
value: "solo",
|
|
1640
|
-
children: "Solo"
|
|
1641
|
-
}, undefined, false, undefined, this),
|
|
1642
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1643
|
-
value: "2-5",
|
|
1644
|
-
children: "2-5"
|
|
1645
|
-
}, undefined, false, undefined, this),
|
|
1646
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1647
|
-
value: "6-20",
|
|
1648
|
-
children: "6-20"
|
|
1649
|
-
}, undefined, false, undefined, this),
|
|
1650
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1651
|
-
value: "20+",
|
|
1652
|
-
children: "20+"
|
|
1653
|
-
}, undefined, false, undefined, this)
|
|
1654
|
-
]
|
|
1655
|
-
}, undefined, true, undefined, this)
|
|
1656
|
-
]
|
|
1657
|
-
}, undefined, true, undefined, this)
|
|
1658
|
-
]
|
|
1659
|
-
}, undefined, true, undefined, this),
|
|
1660
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1661
|
-
className: "space-y-2",
|
|
1662
|
-
children: [
|
|
1663
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1664
|
-
htmlFor: "waitlist-timeline",
|
|
1665
|
-
className: "text-sm font-medium",
|
|
1666
|
-
children: "Timeline"
|
|
1667
|
-
}, undefined, false, undefined, this),
|
|
1668
|
-
/* @__PURE__ */ jsxDEV3(Select, {
|
|
1669
|
-
value: designPartnerForm.watch("timeline") || "",
|
|
1670
|
-
onValueChange: (value) => designPartnerForm.setValue("timeline", value),
|
|
1671
|
-
disabled: isPending || submitResult?.success,
|
|
1672
|
-
children: [
|
|
1673
|
-
/* @__PURE__ */ jsxDEV3(SelectTrigger, {
|
|
1674
|
-
id: "waitlist-timeline",
|
|
1675
|
-
className: "w-full",
|
|
1676
|
-
children: /* @__PURE__ */ jsxDEV3(SelectValue, {
|
|
1677
|
-
placeholder: "Select timeline"
|
|
1678
|
-
}, undefined, false, undefined, this)
|
|
1679
|
-
}, undefined, false, undefined, this),
|
|
1680
|
-
/* @__PURE__ */ jsxDEV3(SelectContent, {
|
|
1681
|
-
children: [
|
|
1682
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1683
|
-
value: "now",
|
|
1684
|
-
children: "Now"
|
|
1685
|
-
}, undefined, false, undefined, this),
|
|
1686
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1687
|
-
value: "1-3-months",
|
|
1688
|
-
children: "1-3 months"
|
|
1689
|
-
}, undefined, false, undefined, this),
|
|
1690
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1691
|
-
value: "3-6-months",
|
|
1692
|
-
children: "3-6 months"
|
|
1693
|
-
}, undefined, false, undefined, this),
|
|
1694
|
-
/* @__PURE__ */ jsxDEV3(SelectItem, {
|
|
1695
|
-
value: "exploring",
|
|
1696
|
-
children: "Exploring"
|
|
1697
|
-
}, undefined, false, undefined, this)
|
|
1698
|
-
]
|
|
1699
|
-
}, undefined, true, undefined, this)
|
|
1700
|
-
]
|
|
1701
|
-
}, undefined, true, undefined, this)
|
|
1702
|
-
]
|
|
1703
|
-
}, undefined, true, undefined, this)
|
|
1704
|
-
]
|
|
1705
|
-
}, undefined, true, undefined, this),
|
|
1706
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1707
|
-
className: "space-y-3",
|
|
1708
|
-
children: [
|
|
1709
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1710
|
-
className: "flex items-start gap-3",
|
|
1711
|
-
children: [
|
|
1712
|
-
/* @__PURE__ */ jsxDEV3(Checkbox, {
|
|
1713
|
-
id: "waitlist-open-to-sessions",
|
|
1714
|
-
checked: designPartnerForm.watch("openToSessions"),
|
|
1715
|
-
onCheckedChange: (checked) => designPartnerForm.setValue("openToSessions", checked === true),
|
|
1716
|
-
disabled: isPending || submitResult?.success
|
|
1717
|
-
}, undefined, false, undefined, this),
|
|
1718
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1719
|
-
htmlFor: "waitlist-open-to-sessions",
|
|
1720
|
-
className: "cursor-pointer text-sm leading-relaxed",
|
|
1721
|
-
children: "I'm open to 1:1 product/design sessions"
|
|
1722
|
-
}, undefined, false, undefined, this)
|
|
1723
|
-
]
|
|
1724
|
-
}, undefined, true, undefined, this),
|
|
1725
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
1726
|
-
className: "flex items-start gap-3",
|
|
1727
|
-
children: [
|
|
1728
|
-
/* @__PURE__ */ jsxDEV3(Checkbox, {
|
|
1729
|
-
id: "waitlist-case-studies",
|
|
1730
|
-
checked: designPartnerForm.watch("okayWithCaseStudies"),
|
|
1731
|
-
onCheckedChange: (checked) => designPartnerForm.setValue("okayWithCaseStudies", checked === true),
|
|
1732
|
-
disabled: isPending || submitResult?.success
|
|
1733
|
-
}, undefined, false, undefined, this),
|
|
1734
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1735
|
-
htmlFor: "waitlist-case-studies",
|
|
1736
|
-
className: "cursor-pointer text-sm leading-relaxed",
|
|
1737
|
-
children: "I'm okay with anonymized case studies about our usage"
|
|
1738
|
-
}, undefined, false, undefined, this)
|
|
1739
|
-
]
|
|
1740
|
-
}, undefined, true, undefined, this)
|
|
1741
|
-
]
|
|
1742
|
-
}, undefined, true, undefined, this)
|
|
1743
|
-
]
|
|
1744
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV3("div", {
|
|
1745
|
-
className: "space-y-2",
|
|
1746
|
-
children: [
|
|
1747
|
-
/* @__PURE__ */ jsxDEV3(Label, {
|
|
1748
|
-
htmlFor: "waitlist-email",
|
|
1749
|
-
className: "text-sm font-medium",
|
|
1750
|
-
children: [
|
|
1751
|
-
"Email ",
|
|
1752
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
1753
|
-
className: "text-red-400",
|
|
1754
|
-
children: "*"
|
|
1755
|
-
}, undefined, false, undefined, this)
|
|
1756
|
-
]
|
|
1757
|
-
}, undefined, true, undefined, this),
|
|
1758
|
-
/* @__PURE__ */ jsxDEV3(Input, {
|
|
1759
|
-
id: "waitlist-email",
|
|
1760
|
-
...simpleForm.register("email"),
|
|
1761
|
-
type: "email",
|
|
1762
|
-
placeholder: "your@email.com",
|
|
1763
|
-
disabled: isPending || submitResult?.success
|
|
1764
|
-
}, undefined, false, undefined, this),
|
|
1765
|
-
simpleForm.formState.errors.email && /* @__PURE__ */ jsxDEV3("p", {
|
|
1766
|
-
className: "text-xs text-red-400",
|
|
1767
|
-
children: simpleForm.formState.errors.email.message
|
|
1768
|
-
}, undefined, false, undefined, this)
|
|
1769
|
-
]
|
|
1770
|
-
}, undefined, true, undefined, this),
|
|
1771
|
-
submitResult && !isPending && /* @__PURE__ */ jsxDEV3("div", {
|
|
1772
|
-
className: `flex items-start gap-2 rounded-lg p-4 text-sm ${submitResult.success ? "border border-green-500/20 bg-green-500/10 text-green-400" : "border border-red-500/20 bg-red-500/10 text-red-400"}`,
|
|
837
|
+
// src/components/marketing/studio-signup-section.tsx
|
|
838
|
+
import Link from "next/link";
|
|
839
|
+
import { ArrowRight, Rocket as Rocket2 } from "lucide-react";
|
|
840
|
+
import { Button } from "@contractspec/lib.design-system";
|
|
841
|
+
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
842
|
+
"use client";
|
|
843
|
+
var studioUrl = "https://app.contractspec.studio";
|
|
844
|
+
var studioDocsUrl = "https://app.contractspec.studio/docs";
|
|
845
|
+
function StudioSignupSection({
|
|
846
|
+
variant = "default"
|
|
847
|
+
}) {
|
|
848
|
+
const isCompact = variant === "compact";
|
|
849
|
+
return /* @__PURE__ */ jsxDEV3("div", {
|
|
850
|
+
id: "studio-signup",
|
|
851
|
+
className: isCompact ? "space-y-4" : "card-subtle space-y-6 p-8",
|
|
852
|
+
children: [
|
|
853
|
+
/* @__PURE__ */ jsxDEV3("div", {
|
|
854
|
+
className: "space-y-4",
|
|
855
|
+
children: [
|
|
856
|
+
/* @__PURE__ */ jsxDEV3("div", {
|
|
857
|
+
className: "inline-flex items-center gap-2 rounded-full border border-violet-500/20 bg-violet-500/10 px-3 py-1",
|
|
1773
858
|
children: [
|
|
1774
|
-
|
|
1775
|
-
size:
|
|
1776
|
-
className: "
|
|
1777
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV3(AlertCircle, {
|
|
1778
|
-
size: 20,
|
|
1779
|
-
className: "mt-0.5 shrink-0"
|
|
859
|
+
/* @__PURE__ */ jsxDEV3(Rocket2, {
|
|
860
|
+
size: 14,
|
|
861
|
+
className: "text-violet-300"
|
|
1780
862
|
}, undefined, false, undefined, this),
|
|
1781
|
-
/* @__PURE__ */ jsxDEV3("
|
|
1782
|
-
className: "
|
|
1783
|
-
children:
|
|
1784
|
-
children: [
|
|
1785
|
-
/* @__PURE__ */ jsxDEV3("p", {
|
|
1786
|
-
className: "mb-1 font-semibold",
|
|
1787
|
-
children: "You're on the list."
|
|
1788
|
-
}, undefined, false, undefined, this),
|
|
1789
|
-
/* @__PURE__ */ jsxDEV3("p", {
|
|
1790
|
-
className: "text-sm",
|
|
1791
|
-
children: submitResult.text
|
|
1792
|
-
}, undefined, false, undefined, this)
|
|
1793
|
-
]
|
|
1794
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV3("p", {
|
|
1795
|
-
children: submitResult.text
|
|
1796
|
-
}, undefined, false, undefined, this)
|
|
863
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
864
|
+
className: "text-sm font-medium text-violet-300",
|
|
865
|
+
children: "ContractSpec Studio"
|
|
1797
866
|
}, undefined, false, undefined, this)
|
|
1798
867
|
]
|
|
1799
868
|
}, undefined, true, undefined, this),
|
|
1800
|
-
/* @__PURE__ */ jsxDEV3(
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
869
|
+
/* @__PURE__ */ jsxDEV3("h2", {
|
|
870
|
+
className: isCompact ? "text-xl font-bold" : "text-2xl font-bold",
|
|
871
|
+
children: "Try ContractSpec Studio"
|
|
872
|
+
}, undefined, false, undefined, this),
|
|
873
|
+
/* @__PURE__ */ jsxDEV3("p", {
|
|
874
|
+
className: "text-muted-foreground text-sm",
|
|
875
|
+
children: "The AI-powered product decision engine that turns product signals into spec-first deliverables."
|
|
1805
876
|
}, undefined, false, undefined, this),
|
|
1806
877
|
/* @__PURE__ */ jsxDEV3("p", {
|
|
1807
|
-
className: "text-muted-foreground text-
|
|
1808
|
-
children: "
|
|
878
|
+
className: "text-muted-foreground text-xs",
|
|
879
|
+
children: "Evidence -> Correlation -> Decision -> Change -> Export -> Check -> Notify -> Autopilot"
|
|
880
|
+
}, undefined, false, undefined, this)
|
|
881
|
+
]
|
|
882
|
+
}, undefined, true, undefined, this),
|
|
883
|
+
/* @__PURE__ */ jsxDEV3("div", {
|
|
884
|
+
className: "flex flex-col gap-3 sm:flex-row",
|
|
885
|
+
children: [
|
|
886
|
+
/* @__PURE__ */ jsxDEV3(Button, {
|
|
887
|
+
asChild: true,
|
|
888
|
+
className: "w-full sm:w-auto",
|
|
889
|
+
children: /* @__PURE__ */ jsxDEV3(Link, {
|
|
890
|
+
href: studioUrl,
|
|
891
|
+
children: [
|
|
892
|
+
"Get Started Free ",
|
|
893
|
+
/* @__PURE__ */ jsxDEV3(ArrowRight, {
|
|
894
|
+
className: "ml-2 h-4 w-4"
|
|
895
|
+
}, undefined, false, undefined, this)
|
|
896
|
+
]
|
|
897
|
+
}, undefined, true, undefined, this)
|
|
898
|
+
}, undefined, false, undefined, this),
|
|
899
|
+
/* @__PURE__ */ jsxDEV3(Button, {
|
|
900
|
+
asChild: true,
|
|
901
|
+
variant: "outline",
|
|
902
|
+
className: "w-full sm:w-auto",
|
|
903
|
+
children: /* @__PURE__ */ jsxDEV3(Link, {
|
|
904
|
+
href: studioDocsUrl,
|
|
905
|
+
children: "Read Studio Docs"
|
|
906
|
+
}, undefined, false, undefined, this)
|
|
1809
907
|
}, undefined, false, undefined, this)
|
|
1810
908
|
]
|
|
1811
909
|
}, undefined, true, undefined, this)
|
|
@@ -1818,14 +916,14 @@ import { useActionState } from "react";
|
|
|
1818
916
|
import {
|
|
1819
917
|
Calendar,
|
|
1820
918
|
MessageSquare as MessageSquare2,
|
|
1821
|
-
CheckCircle
|
|
1822
|
-
AlertCircle
|
|
919
|
+
CheckCircle,
|
|
920
|
+
AlertCircle
|
|
1823
921
|
} from "lucide-react";
|
|
1824
922
|
import {
|
|
1825
923
|
ActionForm,
|
|
1826
924
|
Button as Button2,
|
|
1827
|
-
Input
|
|
1828
|
-
Textarea
|
|
925
|
+
Input,
|
|
926
|
+
Textarea
|
|
1829
927
|
} from "@contractspec/lib.design-system";
|
|
1830
928
|
import { VStack as VStack2, HStack as HStack2 } from "@contractspec/lib.ui-kit-web/ui/stack";
|
|
1831
929
|
import {
|
|
@@ -1870,9 +968,7 @@ function ContactClient() {
|
|
|
1870
968
|
}, undefined, false, undefined, this)
|
|
1871
969
|
]
|
|
1872
970
|
}, undefined, true, undefined, this),
|
|
1873
|
-
/* @__PURE__ */ jsxDEV4(
|
|
1874
|
-
context: "contact"
|
|
1875
|
-
}, undefined, false, undefined, this),
|
|
971
|
+
/* @__PURE__ */ jsxDEV4(StudioSignupSection, {}, undefined, false, undefined, this),
|
|
1876
972
|
/* @__PURE__ */ jsxDEV4(VStack2, {
|
|
1877
973
|
className: "card-subtle gap-6 p-8",
|
|
1878
974
|
id: "call",
|
|
@@ -1949,7 +1045,7 @@ function ContactClient() {
|
|
|
1949
1045
|
className: "text-sm font-medium",
|
|
1950
1046
|
children: "Name"
|
|
1951
1047
|
}, undefined, false, undefined, this),
|
|
1952
|
-
/* @__PURE__ */ jsxDEV4(
|
|
1048
|
+
/* @__PURE__ */ jsxDEV4(Input, {
|
|
1953
1049
|
id: "contact-name",
|
|
1954
1050
|
name: "name",
|
|
1955
1051
|
type: "text",
|
|
@@ -1966,7 +1062,7 @@ function ContactClient() {
|
|
|
1966
1062
|
className: "text-sm font-medium",
|
|
1967
1063
|
children: "Email"
|
|
1968
1064
|
}, undefined, false, undefined, this),
|
|
1969
|
-
/* @__PURE__ */ jsxDEV4(
|
|
1065
|
+
/* @__PURE__ */ jsxDEV4(Input, {
|
|
1970
1066
|
id: "contact-email",
|
|
1971
1067
|
name: "email",
|
|
1972
1068
|
type: "email",
|
|
@@ -1984,7 +1080,7 @@ function ContactClient() {
|
|
|
1984
1080
|
className: "text-sm font-medium",
|
|
1985
1081
|
children: "Message"
|
|
1986
1082
|
}, undefined, false, undefined, this),
|
|
1987
|
-
/* @__PURE__ */ jsxDEV4(
|
|
1083
|
+
/* @__PURE__ */ jsxDEV4(Textarea, {
|
|
1988
1084
|
id: "contact-message",
|
|
1989
1085
|
name: "message",
|
|
1990
1086
|
placeholder: "Tell us what's on your mind...",
|
|
@@ -1997,9 +1093,9 @@ function ContactClient() {
|
|
|
1997
1093
|
contactResult && !contactPending && /* @__PURE__ */ jsxDEV4(HStack2, {
|
|
1998
1094
|
className: `items-center gap-2 rounded-lg p-3 text-sm ${contactResult.success ? "border border-green-500/20 bg-green-500/10 text-green-400" : "border border-red-500/20 bg-red-500/10 text-red-400"}`,
|
|
1999
1095
|
children: [
|
|
2000
|
-
contactResult.success ? /* @__PURE__ */ jsxDEV4(
|
|
1096
|
+
contactResult.success ? /* @__PURE__ */ jsxDEV4(CheckCircle, {
|
|
2001
1097
|
size: 16
|
|
2002
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV4(
|
|
1098
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV4(AlertCircle, {
|
|
2003
1099
|
size: 16
|
|
2004
1100
|
}, undefined, false, undefined, this),
|
|
2005
1101
|
/* @__PURE__ */ jsxDEV4(Small2, {
|
|
@@ -2500,13 +1596,13 @@ function ContributePage() {
|
|
|
2500
1596
|
}
|
|
2501
1597
|
|
|
2502
1598
|
// src/components/marketing/DesignPartnerPage.tsx
|
|
2503
|
-
import
|
|
1599
|
+
import Link2 from "next/link";
|
|
2504
1600
|
import { Button as Button3 } from "@contractspec/lib.design-system";
|
|
2505
1601
|
import {
|
|
2506
|
-
ArrowRight,
|
|
1602
|
+
ArrowRight as ArrowRight2,
|
|
2507
1603
|
BookOpen,
|
|
2508
1604
|
MessageSquare as MessageSquare3,
|
|
2509
|
-
Rocket as
|
|
1605
|
+
Rocket as Rocket3,
|
|
2510
1606
|
Users as Users2
|
|
2511
1607
|
} from "lucide-react";
|
|
2512
1608
|
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
@@ -2554,7 +1650,7 @@ function DesignPartnerPage() {
|
|
|
2554
1650
|
children: [
|
|
2555
1651
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
2556
1652
|
className: "border-primary/20 bg-primary/10 flex h-12 w-12 items-center justify-center rounded-lg border",
|
|
2557
|
-
children: /* @__PURE__ */ jsxDEV6(
|
|
1653
|
+
children: /* @__PURE__ */ jsxDEV6(Rocket3, {
|
|
2558
1654
|
className: "text-primary h-6 w-6"
|
|
2559
1655
|
}, undefined, false, undefined, this)
|
|
2560
1656
|
}, undefined, false, undefined, this),
|
|
@@ -2564,18 +1660,18 @@ function DesignPartnerPage() {
|
|
|
2564
1660
|
}, undefined, false, undefined, this),
|
|
2565
1661
|
/* @__PURE__ */ jsxDEV6("p", {
|
|
2566
1662
|
className: "text-muted-foreground",
|
|
2567
|
-
children: "Your account has been enabled with Design Partner privileges. Log in to
|
|
1663
|
+
children: "Your account has been enabled with Design Partner privileges. Log in to ContractSpec Studio to run the full loop from evidence to spec-first deliverables with your team."
|
|
2568
1664
|
}, undefined, false, undefined, this),
|
|
2569
1665
|
/* @__PURE__ */ jsxDEV6("div", {
|
|
2570
1666
|
className: "pt-2",
|
|
2571
1667
|
children: /* @__PURE__ */ jsxDEV6(Button3, {
|
|
2572
1668
|
asChild: true,
|
|
2573
1669
|
variant: "outline",
|
|
2574
|
-
children: /* @__PURE__ */ jsxDEV6(
|
|
2575
|
-
href: "https://
|
|
1670
|
+
children: /* @__PURE__ */ jsxDEV6(Link2, {
|
|
1671
|
+
href: "https://app.contractspec.studio",
|
|
2576
1672
|
children: [
|
|
2577
1673
|
"Launch Studio ",
|
|
2578
|
-
/* @__PURE__ */ jsxDEV6(
|
|
1674
|
+
/* @__PURE__ */ jsxDEV6(ArrowRight2, {
|
|
2579
1675
|
className: "ml-2 h-4 w-4"
|
|
2580
1676
|
}, undefined, false, undefined, this)
|
|
2581
1677
|
]
|
|
@@ -2606,12 +1702,12 @@ function DesignPartnerPage() {
|
|
|
2606
1702
|
children: /* @__PURE__ */ jsxDEV6(Button3, {
|
|
2607
1703
|
asChild: true,
|
|
2608
1704
|
variant: "outline",
|
|
2609
|
-
children: /* @__PURE__ */ jsxDEV6(
|
|
1705
|
+
children: /* @__PURE__ */ jsxDEV6(Link2, {
|
|
2610
1706
|
href: "mailto:partners@contractspec.io",
|
|
2611
1707
|
children: [
|
|
2612
1708
|
"Contact Partner Success",
|
|
2613
1709
|
" ",
|
|
2614
|
-
/* @__PURE__ */ jsxDEV6(
|
|
1710
|
+
/* @__PURE__ */ jsxDEV6(ArrowRight2, {
|
|
2615
1711
|
className: "ml-2 h-4 w-4"
|
|
2616
1712
|
}, undefined, false, undefined, this)
|
|
2617
1713
|
]
|
|
@@ -2642,11 +1738,11 @@ function DesignPartnerPage() {
|
|
|
2642
1738
|
children: /* @__PURE__ */ jsxDEV6(Button3, {
|
|
2643
1739
|
asChild: true,
|
|
2644
1740
|
variant: "outline",
|
|
2645
|
-
children: /* @__PURE__ */ jsxDEV6(
|
|
1741
|
+
children: /* @__PURE__ */ jsxDEV6(Link2, {
|
|
2646
1742
|
href: "/docs",
|
|
2647
1743
|
children: [
|
|
2648
1744
|
"Read the Docs ",
|
|
2649
|
-
/* @__PURE__ */ jsxDEV6(
|
|
1745
|
+
/* @__PURE__ */ jsxDEV6(ArrowRight2, {
|
|
2650
1746
|
className: "ml-2 h-4 w-4"
|
|
2651
1747
|
}, undefined, false, undefined, this)
|
|
2652
1748
|
]
|
|
@@ -2748,7 +1844,7 @@ function DesignPartnerPage() {
|
|
|
2748
1844
|
/* @__PURE__ */ jsxDEV6(Button3, {
|
|
2749
1845
|
asChild: true,
|
|
2750
1846
|
size: "lg",
|
|
2751
|
-
children: /* @__PURE__ */ jsxDEV6(
|
|
1847
|
+
children: /* @__PURE__ */ jsxDEV6(Link2, {
|
|
2752
1848
|
href: "mailto:partners@contractspec.io",
|
|
2753
1849
|
children: "Email the Founders"
|
|
2754
1850
|
}, undefined, false, undefined, this)
|
|
@@ -2815,11 +1911,11 @@ function HeroMarketingSection() {
|
|
|
2815
1911
|
}, undefined, true, undefined, this),
|
|
2816
1912
|
/* @__PURE__ */ jsxDEV7(ButtonLink2, {
|
|
2817
1913
|
variant: "ghost",
|
|
2818
|
-
href: "
|
|
1914
|
+
href: "https://app.contractspec.studio",
|
|
2819
1915
|
onClick: () => captureAnalyticsEvent(analyticsEventNames.CTA_STUDIO_CLICK, {
|
|
2820
1916
|
surface: "hero"
|
|
2821
1917
|
}),
|
|
2822
|
-
children: "
|
|
1918
|
+
children: "Try Studio"
|
|
2823
1919
|
}, undefined, false, undefined, this)
|
|
2824
1920
|
]
|
|
2825
1921
|
}, undefined, true, undefined, this),
|
|
@@ -2977,13 +2073,13 @@ function SolutionSection() {
|
|
|
2977
2073
|
}
|
|
2978
2074
|
|
|
2979
2075
|
// src/components/marketing/sections/FearsSection.tsx
|
|
2980
|
-
import { CheckCircle as
|
|
2076
|
+
import { CheckCircle as CheckCircle2, Code, Unlock, Zap } from "lucide-react";
|
|
2981
2077
|
import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
|
|
2982
2078
|
var fears = [
|
|
2983
2079
|
{
|
|
2984
2080
|
title: '"I already have an app"',
|
|
2985
2081
|
body: "ContractSpec works with existing codebases. You don't start over \u2014 you stabilize incrementally, one module at a time. Start with one API endpoint, one data model, one contract.",
|
|
2986
|
-
icon:
|
|
2082
|
+
icon: CheckCircle2
|
|
2987
2083
|
},
|
|
2988
2084
|
{
|
|
2989
2085
|
title: '"Vendor lock-in / losing ownership"',
|
|
@@ -3060,9 +2156,9 @@ function CorePositioningSection() {
|
|
|
3060
2156
|
className: "pt-2 sm:flex sm:flex-row sm:flex-wrap sm:items-center sm:justify-center",
|
|
3061
2157
|
children: [
|
|
3062
2158
|
/* @__PURE__ */ jsxDEV12(ButtonLink3, {
|
|
3063
|
-
href: "
|
|
2159
|
+
href: "https://app.contractspec.studio",
|
|
3064
2160
|
children: [
|
|
3065
|
-
"
|
|
2161
|
+
"Try Studio ",
|
|
3066
2162
|
/* @__PURE__ */ jsxDEV12(ChevronRight2, {
|
|
3067
2163
|
size: 16
|
|
3068
2164
|
}, undefined, false, undefined, this)
|
|
@@ -3334,11 +2430,11 @@ function CtaSection() {
|
|
|
3334
2430
|
className: "pt-2 sm:flex sm:flex-row sm:flex-wrap sm:items-center sm:justify-center",
|
|
3335
2431
|
children: [
|
|
3336
2432
|
/* @__PURE__ */ jsxDEV17(ButtonLink5, {
|
|
3337
|
-
href: "
|
|
2433
|
+
href: "https://app.contractspec.studio",
|
|
3338
2434
|
onClick: () => captureAnalyticsEvent2(analyticsEventNames2.CTA_STUDIO_CLICK, {
|
|
3339
2435
|
surface: "cta-section"
|
|
3340
2436
|
}),
|
|
3341
|
-
children: "
|
|
2437
|
+
children: "Try Studio"
|
|
3342
2438
|
}, undefined, false, undefined, this),
|
|
3343
2439
|
/* @__PURE__ */ jsxDEV17(ButtonLink5, {
|
|
3344
2440
|
variant: "ghost",
|
|
@@ -3396,7 +2492,7 @@ var PRICING_EXAMPLES = {
|
|
|
3396
2492
|
};
|
|
3397
2493
|
|
|
3398
2494
|
// src/components/marketing/pricing-thinking-modal.tsx
|
|
3399
|
-
import { CheckCircle as
|
|
2495
|
+
import { CheckCircle as CheckCircle3 } from "lucide-react";
|
|
3400
2496
|
import {
|
|
3401
2497
|
Dialog,
|
|
3402
2498
|
DialogContent,
|
|
@@ -3482,7 +2578,7 @@ function PricingThinkingModal({
|
|
|
3482
2578
|
children: "Tentative pricing (work in progress)"
|
|
3483
2579
|
}, undefined, false, undefined, this),
|
|
3484
2580
|
/* @__PURE__ */ jsxDEV19(DialogDescription, {
|
|
3485
|
-
children: "
|
|
2581
|
+
children: "ContractSpec Studio is live. This is a draft of how paid plans are expected to evolve as usage grows."
|
|
3486
2582
|
}, undefined, false, undefined, this)
|
|
3487
2583
|
]
|
|
3488
2584
|
}, undefined, true, undefined, this),
|
|
@@ -3536,7 +2632,7 @@ function PricingThinkingModal({
|
|
|
3536
2632
|
children: tier.bullets.map((bullet, i) => /* @__PURE__ */ jsxDEV19("li", {
|
|
3537
2633
|
className: "text-muted-foreground flex gap-2 text-sm",
|
|
3538
2634
|
children: [
|
|
3539
|
-
/* @__PURE__ */ jsxDEV19(
|
|
2635
|
+
/* @__PURE__ */ jsxDEV19(CheckCircle3, {
|
|
3540
2636
|
size: 14,
|
|
3541
2637
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3542
2638
|
}, undefined, false, undefined, this),
|
|
@@ -3607,7 +2703,7 @@ function PricingThinkingModal({
|
|
|
3607
2703
|
}, undefined, false, undefined, this),
|
|
3608
2704
|
/* @__PURE__ */ jsxDEV19("p", {
|
|
3609
2705
|
className: "text-muted-foreground text-xs",
|
|
3610
|
-
children: "Design partners get
|
|
2706
|
+
children: "Design partners get priority onboarding and partner incentives as paid plans launch."
|
|
3611
2707
|
}, undefined, false, undefined, this),
|
|
3612
2708
|
onApplyClick && /* @__PURE__ */ jsxDEV19(Button4, {
|
|
3613
2709
|
onClick: () => {
|
|
@@ -3616,7 +2712,7 @@ function PricingThinkingModal({
|
|
|
3616
2712
|
},
|
|
3617
2713
|
className: "w-full",
|
|
3618
2714
|
variant: "outline",
|
|
3619
|
-
children: "
|
|
2715
|
+
children: "Try Studio"
|
|
3620
2716
|
}, undefined, false, undefined, this)
|
|
3621
2717
|
]
|
|
3622
2718
|
}, undefined, true, undefined, this)
|
|
@@ -3628,23 +2724,23 @@ function PricingThinkingModal({
|
|
|
3628
2724
|
}
|
|
3629
2725
|
|
|
3630
2726
|
// src/components/marketing/PricingClient.tsx
|
|
3631
|
-
import { useState
|
|
3632
|
-
import
|
|
3633
|
-
import { CheckCircle as
|
|
2727
|
+
import { useState } from "react";
|
|
2728
|
+
import Link3 from "next/link";
|
|
2729
|
+
import { CheckCircle as CheckCircle4, ChevronDown, ChevronRight as ChevronRight3 } from "lucide-react";
|
|
3634
2730
|
import { jsxDEV as jsxDEV20 } from "react/jsx-dev-runtime";
|
|
3635
2731
|
"use client";
|
|
3636
2732
|
var faqs = [
|
|
3637
2733
|
{
|
|
3638
|
-
question: "Can I
|
|
3639
|
-
answer: "
|
|
2734
|
+
question: "Can I use ContractSpec Studio today?",
|
|
2735
|
+
answer: "Yes. ContractSpec Studio is live at app.contractspec.studio. Start with the free tier and upgrade as paid plans roll out."
|
|
3640
2736
|
},
|
|
3641
2737
|
{
|
|
3642
2738
|
question: "What will you charge for later?",
|
|
3643
|
-
answer: "
|
|
2739
|
+
answer: "Pricing is evolving toward usage: regenerations, AI agent actions, and active projects. A generous free tier will remain so smaller teams and experiments can thrive."
|
|
3644
2740
|
},
|
|
3645
2741
|
{
|
|
3646
2742
|
question: "What do I get as a design partner?",
|
|
3647
|
-
answer: "Direct collaboration on
|
|
2743
|
+
answer: "Direct collaboration on roadmap priorities, hands-on onboarding, and priority support. You also help shape Studio workflows before broad rollout."
|
|
3648
2744
|
},
|
|
3649
2745
|
{
|
|
3650
2746
|
question: "Will you ever charge per seat?",
|
|
@@ -3652,13 +2748,10 @@ var faqs = [
|
|
|
3652
2748
|
}
|
|
3653
2749
|
];
|
|
3654
2750
|
function PricingClient() {
|
|
3655
|
-
const [openFaq, setOpenFaq] =
|
|
3656
|
-
const [pricingModalOpen, setPricingModalOpen] =
|
|
3657
|
-
const
|
|
3658
|
-
|
|
3659
|
-
if (waitlistElement) {
|
|
3660
|
-
waitlistElement.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
3661
|
-
}
|
|
2751
|
+
const [openFaq, setOpenFaq] = useState(null);
|
|
2752
|
+
const [pricingModalOpen, setPricingModalOpen] = useState(false);
|
|
2753
|
+
const openStudio = () => {
|
|
2754
|
+
window.open("https://app.contractspec.studio", "_blank", "noopener,noreferrer");
|
|
3662
2755
|
};
|
|
3663
2756
|
return /* @__PURE__ */ jsxDEV20("main", {
|
|
3664
2757
|
className: "",
|
|
@@ -3674,12 +2767,12 @@ function PricingClient() {
|
|
|
3674
2767
|
}, undefined, false, undefined, this),
|
|
3675
2768
|
/* @__PURE__ */ jsxDEV20("p", {
|
|
3676
2769
|
className: "text-muted-foreground mx-auto max-w-2xl text-lg",
|
|
3677
|
-
children: "ContractSpec Core (the OSS compiler) is and always will be free. ContractSpec Studio
|
|
2770
|
+
children: "ContractSpec Core (the OSS compiler) is and always will be free. ContractSpec Studio is live, with paid plans rolling out progressively."
|
|
3678
2771
|
}, undefined, false, undefined, this),
|
|
3679
2772
|
/* @__PURE__ */ jsxDEV20("div", {
|
|
3680
2773
|
className: "flex flex-col items-center justify-center gap-4 pt-4 sm:flex-row",
|
|
3681
2774
|
children: [
|
|
3682
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2775
|
+
/* @__PURE__ */ jsxDEV20(Link3, {
|
|
3683
2776
|
href: "/install",
|
|
3684
2777
|
className: "btn-primary inline-flex items-center gap-2",
|
|
3685
2778
|
children: [
|
|
@@ -3689,10 +2782,10 @@ function PricingClient() {
|
|
|
3689
2782
|
}, undefined, false, undefined, this)
|
|
3690
2783
|
]
|
|
3691
2784
|
}, undefined, true, undefined, this),
|
|
3692
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3693
|
-
|
|
2785
|
+
/* @__PURE__ */ jsxDEV20(Link3, {
|
|
2786
|
+
href: "https://app.contractspec.studio",
|
|
3694
2787
|
className: "btn-ghost inline-flex items-center gap-2",
|
|
3695
|
-
children: "
|
|
2788
|
+
children: "Try Studio Free"
|
|
3696
2789
|
}, undefined, false, undefined, this)
|
|
3697
2790
|
]
|
|
3698
2791
|
}, undefined, true, undefined, this)
|
|
@@ -3735,17 +2828,17 @@ function PricingClient() {
|
|
|
3735
2828
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3736
2829
|
className: "flex gap-2",
|
|
3737
2830
|
children: [
|
|
3738
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2831
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3739
2832
|
size: 16,
|
|
3740
2833
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3741
2834
|
}, undefined, false, undefined, this),
|
|
3742
|
-
"
|
|
2835
|
+
"Priority access to new Studio capabilities"
|
|
3743
2836
|
]
|
|
3744
2837
|
}, undefined, true, undefined, this),
|
|
3745
2838
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3746
2839
|
className: "flex gap-2",
|
|
3747
2840
|
children: [
|
|
3748
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2841
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3749
2842
|
size: 16,
|
|
3750
2843
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3751
2844
|
}, undefined, false, undefined, this),
|
|
@@ -3755,7 +2848,7 @@ function PricingClient() {
|
|
|
3755
2848
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3756
2849
|
className: "flex gap-2",
|
|
3757
2850
|
children: [
|
|
3758
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2851
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3759
2852
|
size: 16,
|
|
3760
2853
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3761
2854
|
}, undefined, false, undefined, this),
|
|
@@ -3765,29 +2858,29 @@ function PricingClient() {
|
|
|
3765
2858
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3766
2859
|
className: "flex gap-2",
|
|
3767
2860
|
children: [
|
|
3768
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2861
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3769
2862
|
size: 16,
|
|
3770
2863
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3771
2864
|
}, undefined, false, undefined, this),
|
|
3772
|
-
"Priority support
|
|
2865
|
+
"Priority support through direct channels"
|
|
3773
2866
|
]
|
|
3774
2867
|
}, undefined, true, undefined, this),
|
|
3775
2868
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3776
2869
|
className: "flex gap-2",
|
|
3777
2870
|
children: [
|
|
3778
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2871
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3779
2872
|
size: 16,
|
|
3780
2873
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3781
2874
|
}, undefined, false, undefined, this),
|
|
3782
|
-
"
|
|
2875
|
+
"Pricing input and partner incentives"
|
|
3783
2876
|
]
|
|
3784
2877
|
}, undefined, true, undefined, this)
|
|
3785
2878
|
]
|
|
3786
2879
|
}, undefined, true, undefined, this),
|
|
3787
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3788
|
-
|
|
2880
|
+
/* @__PURE__ */ jsxDEV20(Link3, {
|
|
2881
|
+
href: "/design-partner",
|
|
3789
2882
|
className: "btn-primary w-full md:w-auto",
|
|
3790
|
-
children: "Apply
|
|
2883
|
+
children: "Apply as a design partner"
|
|
3791
2884
|
}, undefined, false, undefined, this)
|
|
3792
2885
|
]
|
|
3793
2886
|
}, undefined, true, undefined, this)
|
|
@@ -3843,7 +2936,7 @@ function PricingClient() {
|
|
|
3843
2936
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3844
2937
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
3845
2938
|
children: [
|
|
3846
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2939
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3847
2940
|
size: 16,
|
|
3848
2941
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3849
2942
|
}, undefined, false, undefined, this),
|
|
@@ -3853,7 +2946,7 @@ function PricingClient() {
|
|
|
3853
2946
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3854
2947
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
3855
2948
|
children: [
|
|
3856
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2949
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3857
2950
|
size: 16,
|
|
3858
2951
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3859
2952
|
}, undefined, false, undefined, this),
|
|
@@ -3863,7 +2956,7 @@ function PricingClient() {
|
|
|
3863
2956
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3864
2957
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
3865
2958
|
children: [
|
|
3866
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2959
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3867
2960
|
size: 16,
|
|
3868
2961
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3869
2962
|
}, undefined, false, undefined, this),
|
|
@@ -3873,7 +2966,7 @@ function PricingClient() {
|
|
|
3873
2966
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3874
2967
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
3875
2968
|
children: [
|
|
3876
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2969
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3877
2970
|
size: 16,
|
|
3878
2971
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3879
2972
|
}, undefined, false, undefined, this),
|
|
@@ -3884,7 +2977,7 @@ function PricingClient() {
|
|
|
3884
2977
|
}, undefined, true, undefined, this)
|
|
3885
2978
|
]
|
|
3886
2979
|
}, undefined, true, undefined, this),
|
|
3887
|
-
/* @__PURE__ */ jsxDEV20(
|
|
2980
|
+
/* @__PURE__ */ jsxDEV20(Link3, {
|
|
3888
2981
|
href: "/install",
|
|
3889
2982
|
className: "btn-ghost w-full",
|
|
3890
2983
|
children: "Install now"
|
|
@@ -3896,7 +2989,7 @@ function PricingClient() {
|
|
|
3896
2989
|
children: [
|
|
3897
2990
|
/* @__PURE__ */ jsxDEV20("div", {
|
|
3898
2991
|
className: "absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-violet-500 px-3 py-1 text-xs font-medium text-white",
|
|
3899
|
-
children: "
|
|
2992
|
+
children: "Live program"
|
|
3900
2993
|
}, undefined, false, undefined, this),
|
|
3901
2994
|
/* @__PURE__ */ jsxDEV20("div", {
|
|
3902
2995
|
className: "space-y-2",
|
|
@@ -3910,11 +3003,11 @@ function PricingClient() {
|
|
|
3910
3003
|
children: [
|
|
3911
3004
|
/* @__PURE__ */ jsxDEV20("div", {
|
|
3912
3005
|
className: "text-2xl font-bold",
|
|
3913
|
-
children: "
|
|
3006
|
+
children: "Invite-based"
|
|
3914
3007
|
}, undefined, false, undefined, this),
|
|
3915
3008
|
/* @__PURE__ */ jsxDEV20("p", {
|
|
3916
3009
|
className: "text-muted-foreground text-xs",
|
|
3917
|
-
children: "
|
|
3010
|
+
children: "Built for teams shaping the next Studio capabilities"
|
|
3918
3011
|
}, undefined, false, undefined, this)
|
|
3919
3012
|
]
|
|
3920
3013
|
}, undefined, true, undefined, this)
|
|
@@ -3926,47 +3019,47 @@ function PricingClient() {
|
|
|
3926
3019
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3927
3020
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
3928
3021
|
children: [
|
|
3929
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3022
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3930
3023
|
size: 16,
|
|
3931
3024
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3932
3025
|
}, undefined, false, undefined, this),
|
|
3933
|
-
"Use ContractSpec Studio for real projects
|
|
3026
|
+
"Use ContractSpec Studio for real projects"
|
|
3934
3027
|
]
|
|
3935
3028
|
}, undefined, true, undefined, this),
|
|
3936
3029
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3937
3030
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
3938
3031
|
children: [
|
|
3939
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3032
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3940
3033
|
size: 16,
|
|
3941
3034
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3942
3035
|
}, undefined, false, undefined, this),
|
|
3943
|
-
"Work directly with the
|
|
3036
|
+
"Work directly with the team on architecture and workflow design"
|
|
3944
3037
|
]
|
|
3945
3038
|
}, undefined, true, undefined, this),
|
|
3946
3039
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3947
3040
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
3948
3041
|
children: [
|
|
3949
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3042
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3950
3043
|
size: 16,
|
|
3951
3044
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3952
3045
|
}, undefined, false, undefined, this),
|
|
3953
|
-
|
|
3046
|
+
"Access to partner-only previews and feedback loops"
|
|
3954
3047
|
]
|
|
3955
3048
|
}, undefined, true, undefined, this),
|
|
3956
3049
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
3957
3050
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
3958
3051
|
children: [
|
|
3959
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3052
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
3960
3053
|
size: 16,
|
|
3961
3054
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
3962
3055
|
}, undefined, false, undefined, this),
|
|
3963
|
-
"Priority support
|
|
3056
|
+
"Priority support and roadmap influence"
|
|
3964
3057
|
]
|
|
3965
3058
|
}, undefined, true, undefined, this)
|
|
3966
3059
|
]
|
|
3967
3060
|
}, undefined, true, undefined, this),
|
|
3968
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3969
|
-
|
|
3061
|
+
/* @__PURE__ */ jsxDEV20(Link3, {
|
|
3062
|
+
href: "/design-partner",
|
|
3970
3063
|
className: "btn-primary w-full",
|
|
3971
3064
|
children: "Apply as a design partner"
|
|
3972
3065
|
}, undefined, false, undefined, this)
|
|
@@ -4019,7 +3112,7 @@ function PricingClient() {
|
|
|
4019
3112
|
/* @__PURE__ */ jsxDEV20("button", {
|
|
4020
3113
|
disabled: true,
|
|
4021
3114
|
className: "btn-ghost w-full cursor-not-allowed opacity-50",
|
|
4022
|
-
children: "Available after
|
|
3115
|
+
children: "Available after pricing rollout"
|
|
4023
3116
|
}, undefined, false, undefined, this)
|
|
4024
3117
|
]
|
|
4025
3118
|
}, undefined, true, undefined, this),
|
|
@@ -4056,7 +3149,7 @@ function PricingClient() {
|
|
|
4056
3149
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
4057
3150
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
4058
3151
|
children: [
|
|
4059
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3152
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
4060
3153
|
size: 16,
|
|
4061
3154
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
4062
3155
|
}, undefined, false, undefined, this),
|
|
@@ -4066,7 +3159,7 @@ function PricingClient() {
|
|
|
4066
3159
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
4067
3160
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
4068
3161
|
children: [
|
|
4069
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3162
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
4070
3163
|
size: 16,
|
|
4071
3164
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
4072
3165
|
}, undefined, false, undefined, this),
|
|
@@ -4076,7 +3169,7 @@ function PricingClient() {
|
|
|
4076
3169
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
4077
3170
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
4078
3171
|
children: [
|
|
4079
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3172
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
4080
3173
|
size: 16,
|
|
4081
3174
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
4082
3175
|
}, undefined, false, undefined, this),
|
|
@@ -4086,7 +3179,7 @@ function PricingClient() {
|
|
|
4086
3179
|
/* @__PURE__ */ jsxDEV20("li", {
|
|
4087
3180
|
className: "text-muted-foreground flex gap-3 text-sm",
|
|
4088
3181
|
children: [
|
|
4089
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3182
|
+
/* @__PURE__ */ jsxDEV20(CheckCircle4, {
|
|
4090
3183
|
size: 16,
|
|
4091
3184
|
className: "mt-0.5 shrink-0 text-violet-400"
|
|
4092
3185
|
}, undefined, false, undefined, this),
|
|
@@ -4095,7 +3188,7 @@ function PricingClient() {
|
|
|
4095
3188
|
}, undefined, true, undefined, this)
|
|
4096
3189
|
]
|
|
4097
3190
|
}, undefined, true, undefined, this),
|
|
4098
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3191
|
+
/* @__PURE__ */ jsxDEV20(Link3, {
|
|
4099
3192
|
href: "/contact",
|
|
4100
3193
|
className: "btn-ghost w-full",
|
|
4101
3194
|
children: "Talk to us"
|
|
@@ -4116,7 +3209,7 @@ function PricingClient() {
|
|
|
4116
3209
|
children: [
|
|
4117
3210
|
/* @__PURE__ */ jsxDEV20("h2", {
|
|
4118
3211
|
className: "text-3xl font-bold",
|
|
4119
|
-
children: "How ContractSpec pricing
|
|
3212
|
+
children: "How ContractSpec pricing works now and next"
|
|
4120
3213
|
}, undefined, false, undefined, this),
|
|
4121
3214
|
/* @__PURE__ */ jsxDEV20("p", {
|
|
4122
3215
|
className: "text-muted-foreground mx-auto max-w-2xl text-lg",
|
|
@@ -4221,7 +3314,7 @@ function PricingClient() {
|
|
|
4221
3314
|
className: "text-muted-foreground mb-2 text-sm",
|
|
4222
3315
|
children: "Still unsure?"
|
|
4223
3316
|
}, undefined, false, undefined, this),
|
|
4224
|
-
/* @__PURE__ */ jsxDEV20(
|
|
3317
|
+
/* @__PURE__ */ jsxDEV20(Link3, {
|
|
4225
3318
|
href: "/contact",
|
|
4226
3319
|
className: "text-sm font-medium text-violet-400 hover:text-violet-300",
|
|
4227
3320
|
children: "Contact us \u2192"
|
|
@@ -4235,26 +3328,26 @@ function PricingClient() {
|
|
|
4235
3328
|
className: "section-padding hero-gradient",
|
|
4236
3329
|
children: /* @__PURE__ */ jsxDEV20("div", {
|
|
4237
3330
|
className: "mx-auto max-w-4xl",
|
|
4238
|
-
children: /* @__PURE__ */ jsxDEV20(
|
|
3331
|
+
children: /* @__PURE__ */ jsxDEV20(StudioSignupSection, {}, undefined, false, undefined, this)
|
|
4239
3332
|
}, undefined, false, undefined, this)
|
|
4240
3333
|
}, undefined, false, undefined, this),
|
|
4241
3334
|
/* @__PURE__ */ jsxDEV20(PricingThinkingModal, {
|
|
4242
3335
|
open: pricingModalOpen,
|
|
4243
3336
|
onOpenChange: setPricingModalOpen,
|
|
4244
|
-
onApplyClick:
|
|
3337
|
+
onApplyClick: openStudio
|
|
4245
3338
|
}, undefined, false, undefined, this)
|
|
4246
3339
|
]
|
|
4247
3340
|
}, undefined, true, undefined, this);
|
|
4248
3341
|
}
|
|
4249
3342
|
|
|
4250
3343
|
// src/components/marketing/ProductClientPage.tsx
|
|
4251
|
-
import
|
|
3344
|
+
import Link4 from "@contractspec/lib.ui-link";
|
|
4252
3345
|
import {
|
|
4253
3346
|
analyticsEventNames as analyticsEventNames3,
|
|
4254
3347
|
captureAnalyticsEvent as captureAnalyticsEvent3
|
|
4255
3348
|
} from "@contractspec/bundle.library/libs/posthog/client";
|
|
4256
3349
|
import {
|
|
4257
|
-
CheckCircle as
|
|
3350
|
+
CheckCircle as CheckCircle5,
|
|
4258
3351
|
ChevronRight as ChevronRight4,
|
|
4259
3352
|
Database,
|
|
4260
3353
|
FileCode as FileCode2,
|
|
@@ -4286,7 +3379,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4286
3379
|
/* @__PURE__ */ jsxDEV21("div", {
|
|
4287
3380
|
className: "flex flex-col items-center justify-center gap-4 pt-4 sm:flex-row",
|
|
4288
3381
|
children: [
|
|
4289
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3382
|
+
/* @__PURE__ */ jsxDEV21(Link4, {
|
|
4290
3383
|
href: "/install",
|
|
4291
3384
|
onClick: () => captureAnalyticsEvent3(analyticsEventNames3.CTA_INSTALL_CLICK, {
|
|
4292
3385
|
surface: "product-hero"
|
|
@@ -4299,7 +3392,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4299
3392
|
}, undefined, false, undefined, this)
|
|
4300
3393
|
]
|
|
4301
3394
|
}, undefined, true, undefined, this),
|
|
4302
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3395
|
+
/* @__PURE__ */ jsxDEV21(Link4, {
|
|
4303
3396
|
href: "/pricing",
|
|
4304
3397
|
className: "btn-ghost",
|
|
4305
3398
|
children: "View pricing"
|
|
@@ -4435,7 +3528,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4435
3528
|
/* @__PURE__ */ jsxDEV21("li", {
|
|
4436
3529
|
className: "flex gap-3",
|
|
4437
3530
|
children: [
|
|
4438
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3531
|
+
/* @__PURE__ */ jsxDEV21(CheckCircle5, {
|
|
4439
3532
|
size: 16,
|
|
4440
3533
|
className: "mt-0.5 flex-shrink-0 text-emerald-400"
|
|
4441
3534
|
}, undefined, false, undefined, this),
|
|
@@ -4445,7 +3538,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4445
3538
|
/* @__PURE__ */ jsxDEV21("li", {
|
|
4446
3539
|
className: "flex gap-3",
|
|
4447
3540
|
children: [
|
|
4448
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3541
|
+
/* @__PURE__ */ jsxDEV21(CheckCircle5, {
|
|
4449
3542
|
size: 16,
|
|
4450
3543
|
className: "mt-0.5 flex-shrink-0 text-emerald-400"
|
|
4451
3544
|
}, undefined, false, undefined, this),
|
|
@@ -4455,7 +3548,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4455
3548
|
/* @__PURE__ */ jsxDEV21("li", {
|
|
4456
3549
|
className: "flex gap-3",
|
|
4457
3550
|
children: [
|
|
4458
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3551
|
+
/* @__PURE__ */ jsxDEV21(CheckCircle5, {
|
|
4459
3552
|
size: 16,
|
|
4460
3553
|
className: "mt-0.5 flex-shrink-0 text-emerald-400"
|
|
4461
3554
|
}, undefined, false, undefined, this),
|
|
@@ -4483,7 +3576,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4483
3576
|
/* @__PURE__ */ jsxDEV21("li", {
|
|
4484
3577
|
className: "flex gap-3",
|
|
4485
3578
|
children: [
|
|
4486
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3579
|
+
/* @__PURE__ */ jsxDEV21(CheckCircle5, {
|
|
4487
3580
|
size: 16,
|
|
4488
3581
|
className: "mt-0.5 flex-shrink-0 text-emerald-400"
|
|
4489
3582
|
}, undefined, false, undefined, this),
|
|
@@ -4493,7 +3586,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4493
3586
|
/* @__PURE__ */ jsxDEV21("li", {
|
|
4494
3587
|
className: "flex gap-3",
|
|
4495
3588
|
children: [
|
|
4496
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3589
|
+
/* @__PURE__ */ jsxDEV21(CheckCircle5, {
|
|
4497
3590
|
size: 16,
|
|
4498
3591
|
className: "mt-0.5 flex-shrink-0 text-emerald-400"
|
|
4499
3592
|
}, undefined, false, undefined, this),
|
|
@@ -4503,7 +3596,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4503
3596
|
/* @__PURE__ */ jsxDEV21("li", {
|
|
4504
3597
|
className: "flex gap-3",
|
|
4505
3598
|
children: [
|
|
4506
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3599
|
+
/* @__PURE__ */ jsxDEV21(CheckCircle5, {
|
|
4507
3600
|
size: 16,
|
|
4508
3601
|
className: "mt-0.5 flex-shrink-0 text-emerald-400"
|
|
4509
3602
|
}, undefined, false, undefined, this),
|
|
@@ -4659,7 +3752,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4659
3752
|
].map((item, i) => /* @__PURE__ */ jsxDEV21("li", {
|
|
4660
3753
|
className: "flex gap-3",
|
|
4661
3754
|
children: [
|
|
4662
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3755
|
+
/* @__PURE__ */ jsxDEV21(CheckCircle5, {
|
|
4663
3756
|
size: 16,
|
|
4664
3757
|
className: "mt-0.5 flex-shrink-0 text-pink-400"
|
|
4665
3758
|
}, undefined, false, undefined, this),
|
|
@@ -4687,7 +3780,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4687
3780
|
].map((item, i) => /* @__PURE__ */ jsxDEV21("li", {
|
|
4688
3781
|
className: "flex gap-3",
|
|
4689
3782
|
children: [
|
|
4690
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3783
|
+
/* @__PURE__ */ jsxDEV21(CheckCircle5, {
|
|
4691
3784
|
size: 16,
|
|
4692
3785
|
className: "mt-0.5 flex-shrink-0 text-pink-400"
|
|
4693
3786
|
}, undefined, false, undefined, this),
|
|
@@ -4777,7 +3870,7 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4777
3870
|
/* @__PURE__ */ jsxDEV21("div", {
|
|
4778
3871
|
className: "flex flex-col items-center justify-center gap-4 pt-4 sm:flex-row",
|
|
4779
3872
|
children: [
|
|
4780
|
-
/* @__PURE__ */ jsxDEV21(
|
|
3873
|
+
/* @__PURE__ */ jsxDEV21(Link4, {
|
|
4781
3874
|
href: "/install",
|
|
4782
3875
|
className: "btn-primary inline-flex items-center gap-2",
|
|
4783
3876
|
children: [
|
|
@@ -4787,10 +3880,10 @@ var ProductClientPage = () => /* @__PURE__ */ jsxDEV21("main", {
|
|
|
4787
3880
|
}, undefined, false, undefined, this)
|
|
4788
3881
|
]
|
|
4789
3882
|
}, undefined, true, undefined, this),
|
|
4790
|
-
/* @__PURE__ */ jsxDEV21(
|
|
4791
|
-
href: "
|
|
3883
|
+
/* @__PURE__ */ jsxDEV21(Link4, {
|
|
3884
|
+
href: "https://app.contractspec.studio",
|
|
4792
3885
|
className: "btn-ghost",
|
|
4793
|
-
children: "
|
|
3886
|
+
children: "Try Studio"
|
|
4794
3887
|
}, undefined, false, undefined, this)
|
|
4795
3888
|
]
|
|
4796
3889
|
}, undefined, true, undefined, this)
|
|
@@ -4914,10 +4007,10 @@ var TemplatePreviewModal = ({
|
|
|
4914
4007
|
};
|
|
4915
4008
|
|
|
4916
4009
|
// src/components/templates/TemplatesClientPage.tsx
|
|
4917
|
-
import { useState as
|
|
4010
|
+
import { useState as useState2 } from "react";
|
|
4918
4011
|
import { Search } from "lucide-react";
|
|
4919
4012
|
import { cn } from "@contractspec/lib.ui-kit-core/utils";
|
|
4920
|
-
import
|
|
4013
|
+
import Link5 from "next/link";
|
|
4921
4014
|
import { useRegistryTemplates } from "@contractspec/lib.example-shared-ui";
|
|
4922
4015
|
import { getTemplate } from "@contractspec/module.examples";
|
|
4923
4016
|
import {
|
|
@@ -5127,12 +4220,12 @@ var allTags = [
|
|
|
5127
4220
|
"Platform"
|
|
5128
4221
|
];
|
|
5129
4222
|
var TemplatesPage = () => {
|
|
5130
|
-
const [selectedTag, setSelectedTag] =
|
|
5131
|
-
const [search, setSearch] =
|
|
5132
|
-
const [preview, setPreview] =
|
|
5133
|
-
const [
|
|
5134
|
-
const [source, setSource] =
|
|
5135
|
-
const [selectedTemplateForCommand, setSelectedTemplateForCommand] =
|
|
4223
|
+
const [selectedTag, setSelectedTag] = useState2(null);
|
|
4224
|
+
const [search, setSearch] = useState2("");
|
|
4225
|
+
const [preview, setPreview] = useState2(null);
|
|
4226
|
+
const [studioSignupModalOpen, setStudioSignupModalOpen] = useState2(false);
|
|
4227
|
+
const [source, setSource] = useState2("local");
|
|
4228
|
+
const [selectedTemplateForCommand, setSelectedTemplateForCommand] = useState2(null);
|
|
5136
4229
|
const { data: registryTemplates = [], isLoading: registryLoading } = useRegistryTemplates();
|
|
5137
4230
|
const filtered = templates.filter((t) => {
|
|
5138
4231
|
const matchTag = !selectedTag || t.tags.includes(selectedTag);
|
|
@@ -5473,7 +4566,7 @@ var TemplatesPage = () => {
|
|
|
5473
4566
|
className: "text-muted-foreground text-sm",
|
|
5474
4567
|
children: "Connect Stripe to any template for payment processing, subscriptions, and invoicing. Type-safe and policy-enforced."
|
|
5475
4568
|
}, undefined, false, undefined, this),
|
|
5476
|
-
/* @__PURE__ */ jsxDEV23(
|
|
4569
|
+
/* @__PURE__ */ jsxDEV23(Link5, {
|
|
5477
4570
|
href: "/docs/integrations/stripe",
|
|
5478
4571
|
className: "inline-flex items-center gap-1 text-sm text-violet-400 hover:text-violet-300",
|
|
5479
4572
|
children: "Learn more \u2192"
|
|
@@ -5495,7 +4588,7 @@ var TemplatesPage = () => {
|
|
|
5495
4588
|
className: "text-muted-foreground text-sm",
|
|
5496
4589
|
children: "Send transactional emails via Postmark or Resend. Process inbound emails with Gmail API. SMS via Twilio."
|
|
5497
4590
|
}, undefined, false, undefined, this),
|
|
5498
|
-
/* @__PURE__ */ jsxDEV23(
|
|
4591
|
+
/* @__PURE__ */ jsxDEV23(Link5, {
|
|
5499
4592
|
href: "/docs/integrations",
|
|
5500
4593
|
className: "inline-flex items-center gap-1 text-sm text-violet-400 hover:text-violet-300",
|
|
5501
4594
|
children: "View integrations \u2192"
|
|
@@ -5517,7 +4610,7 @@ var TemplatesPage = () => {
|
|
|
5517
4610
|
className: "text-muted-foreground text-sm",
|
|
5518
4611
|
children: "Power templates with OpenAI, vector search via Qdrant, and structured knowledge spaces for context-aware workflows."
|
|
5519
4612
|
}, undefined, false, undefined, this),
|
|
5520
|
-
/* @__PURE__ */ jsxDEV23(
|
|
4613
|
+
/* @__PURE__ */ jsxDEV23(Link5, {
|
|
5521
4614
|
href: "/docs/knowledge",
|
|
5522
4615
|
className: "inline-flex items-center gap-1 text-sm text-violet-400 hover:text-violet-300",
|
|
5523
4616
|
children: "Learn about knowledge \u2192"
|
|
@@ -5533,7 +4626,7 @@ var TemplatesPage = () => {
|
|
|
5533
4626
|
className: "text-muted-foreground mb-4 text-sm",
|
|
5534
4627
|
children: "All integrations are configured per-tenant with automatic health checks and credential rotation."
|
|
5535
4628
|
}, undefined, false, undefined, this),
|
|
5536
|
-
/* @__PURE__ */ jsxDEV23(
|
|
4629
|
+
/* @__PURE__ */ jsxDEV23(Link5, {
|
|
5537
4630
|
href: "/docs/architecture",
|
|
5538
4631
|
className: "btn-primary",
|
|
5539
4632
|
children: "View Architecture"
|
|
@@ -5552,22 +4645,22 @@ var TemplatesPage = () => {
|
|
|
5552
4645
|
}
|
|
5553
4646
|
}, undefined, false, undefined, this),
|
|
5554
4647
|
/* @__PURE__ */ jsxDEV23(Dialog3, {
|
|
5555
|
-
open:
|
|
5556
|
-
onOpenChange:
|
|
4648
|
+
open: studioSignupModalOpen,
|
|
4649
|
+
onOpenChange: setStudioSignupModalOpen,
|
|
5557
4650
|
children: /* @__PURE__ */ jsxDEV23(DialogContent3, {
|
|
5558
4651
|
className: "max-h-[90vh] max-w-2xl overflow-y-auto",
|
|
5559
4652
|
children: [
|
|
5560
4653
|
/* @__PURE__ */ jsxDEV23(DialogHeader2, {
|
|
5561
4654
|
children: [
|
|
5562
4655
|
/* @__PURE__ */ jsxDEV23(DialogTitle2, {
|
|
5563
|
-
children: "
|
|
4656
|
+
children: "Deploy in Studio"
|
|
5564
4657
|
}, undefined, false, undefined, this),
|
|
5565
4658
|
/* @__PURE__ */ jsxDEV23(DialogDescription2, {
|
|
5566
|
-
children: "
|
|
4659
|
+
children: "Deploy templates in ContractSpec Studio and run the full evidence-to-spec loop with your team."
|
|
5567
4660
|
}, undefined, false, undefined, this)
|
|
5568
4661
|
]
|
|
5569
4662
|
}, undefined, true, undefined, this),
|
|
5570
|
-
/* @__PURE__ */ jsxDEV23(
|
|
4663
|
+
/* @__PURE__ */ jsxDEV23(StudioSignupSection, {
|
|
5571
4664
|
variant: "compact"
|
|
5572
4665
|
}, undefined, false, undefined, this)
|
|
5573
4666
|
]
|
|
@@ -5640,9 +4733,9 @@ var TemplatesPage = () => {
|
|
|
5640
4733
|
templateId: commandId
|
|
5641
4734
|
});
|
|
5642
4735
|
setSelectedTemplateForCommand(null);
|
|
5643
|
-
|
|
4736
|
+
setStudioSignupModalOpen(true);
|
|
5644
4737
|
},
|
|
5645
|
-
children: "Deploy to Studio
|
|
4738
|
+
children: "Deploy to Studio"
|
|
5646
4739
|
}, undefined, false, undefined, this)
|
|
5647
4740
|
]
|
|
5648
4741
|
}, undefined, true, undefined, this)
|
|
@@ -5654,11 +4747,11 @@ var TemplatesPage = () => {
|
|
|
5654
4747
|
};
|
|
5655
4748
|
|
|
5656
4749
|
// src/components/templates/TemplatesPage.tsx
|
|
5657
|
-
import { useMemo as useMemo2, useState as
|
|
4750
|
+
import { useMemo as useMemo2, useState as useState3 } from "react";
|
|
5658
4751
|
import {
|
|
5659
4752
|
Button as Button5,
|
|
5660
4753
|
ButtonLink as ButtonLink6,
|
|
5661
|
-
Input as
|
|
4754
|
+
Input as Input2,
|
|
5662
4755
|
MarketingCard as MarketingCard2,
|
|
5663
4756
|
MarketingCardContent as MarketingCardContent2,
|
|
5664
4757
|
MarketingCardDescription,
|
|
@@ -5668,7 +4761,7 @@ import {
|
|
|
5668
4761
|
} from "@contractspec/lib.design-system";
|
|
5669
4762
|
import { HStack as HStack4, VStack as VStack8 } from "@contractspec/lib.ui-kit-web/ui/stack";
|
|
5670
4763
|
import { listTemplates } from "@contractspec/module.examples";
|
|
5671
|
-
import { jsxDEV as jsxDEV24, Fragment
|
|
4764
|
+
import { jsxDEV as jsxDEV24, Fragment } from "react/jsx-dev-runtime";
|
|
5672
4765
|
"use client";
|
|
5673
4766
|
function matchesQuery(t, query) {
|
|
5674
4767
|
const q = query.trim().toLowerCase();
|
|
@@ -5678,10 +4771,10 @@ function matchesQuery(t, query) {
|
|
|
5678
4771
|
return hay.includes(q);
|
|
5679
4772
|
}
|
|
5680
4773
|
function TemplatesMarketingPage() {
|
|
5681
|
-
const [query, setQuery] =
|
|
4774
|
+
const [query, setQuery] = useState3("");
|
|
5682
4775
|
const templates2 = useMemo2(() => listTemplates(), []);
|
|
5683
4776
|
const filtered = useMemo2(() => templates2.filter((t) => matchesQuery(t, query)), [templates2, query]);
|
|
5684
|
-
return /* @__PURE__ */ jsxDEV24(
|
|
4777
|
+
return /* @__PURE__ */ jsxDEV24(Fragment, {
|
|
5685
4778
|
children: [
|
|
5686
4779
|
/* @__PURE__ */ jsxDEV24(MarketingSection5, {
|
|
5687
4780
|
tone: "default",
|
|
@@ -5736,7 +4829,7 @@ function TemplatesMarketingPage() {
|
|
|
5736
4829
|
align: "center",
|
|
5737
4830
|
justify: "between",
|
|
5738
4831
|
wrap: "wrap",
|
|
5739
|
-
children: /* @__PURE__ */ jsxDEV24(
|
|
4832
|
+
children: /* @__PURE__ */ jsxDEV24(Input2, {
|
|
5740
4833
|
"aria-label": "Search templates and examples",
|
|
5741
4834
|
placeholder: "Search templates and examples\u2026",
|
|
5742
4835
|
value: query,
|
|
@@ -5821,9 +4914,99 @@ function ButtonLinkToSandbox({ templateId }) {
|
|
|
5821
4914
|
}
|
|
5822
4915
|
// src/libs/email/newsletter.ts
|
|
5823
4916
|
"use server";
|
|
5824
|
-
var NEWSLETTER_MISSING_CONFIG = "Newsletter service is not configured. Please try again later.";
|
|
5825
|
-
var NEWSLETTER_SEND_ERROR = "Failed to subscribe. Please try again later or contact us directly.";
|
|
5826
|
-
var subscribeToNewsletter = async (formData) => {
|
|
4917
|
+
var NEWSLETTER_MISSING_CONFIG = "Newsletter service is not configured. Please try again later.";
|
|
4918
|
+
var NEWSLETTER_SEND_ERROR = "Failed to subscribe. Please try again later or contact us directly.";
|
|
4919
|
+
var subscribeToNewsletter = async (formData) => {
|
|
4920
|
+
const email = (formData.get("email") ?? "").toString().trim();
|
|
4921
|
+
if (!email || !email.includes("@")) {
|
|
4922
|
+
return {
|
|
4923
|
+
success: false,
|
|
4924
|
+
text: "Please enter a valid email address."
|
|
4925
|
+
};
|
|
4926
|
+
}
|
|
4927
|
+
const configResult = getEmailConfig();
|
|
4928
|
+
if (!configResult.ok || !configResult.config) {
|
|
4929
|
+
return {
|
|
4930
|
+
success: false,
|
|
4931
|
+
text: configResult.errorMessage ?? NEWSLETTER_MISSING_CONFIG
|
|
4932
|
+
};
|
|
4933
|
+
}
|
|
4934
|
+
const welcomeText = `
|
|
4935
|
+
Welcome to ContractSpec!
|
|
4936
|
+
|
|
4937
|
+
Thanks for subscribing to our newsletter. You'll receive updates on:
|
|
4938
|
+
|
|
4939
|
+
\u2022 New integrations (Stripe, OpenAI, Qdrant, and more)
|
|
4940
|
+
\u2022 Product features and improvements
|
|
4941
|
+
\u2022 New templates and examples
|
|
4942
|
+
\u2022 Architecture insights and best practices
|
|
4943
|
+
\u2022 Documentation updates
|
|
4944
|
+
|
|
4945
|
+
Stay tuned for exciting updates!
|
|
4946
|
+
|
|
4947
|
+
---
|
|
4948
|
+
ContractSpec Team
|
|
4949
|
+
https://contractspec.io
|
|
4950
|
+
|
|
4951
|
+
Unsubscribe: Reply to this email with "unsubscribe"
|
|
4952
|
+
`.trim();
|
|
4953
|
+
const welcomeHtml = `
|
|
4954
|
+
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
4955
|
+
<h1 style="color: #8b5cf6;">Welcome to ContractSpec!</h1>
|
|
4956
|
+
<p>Thanks for subscribing to our newsletter. You'll receive updates on:</p>
|
|
4957
|
+
<ul style="line-height: 1.8;">
|
|
4958
|
+
<li>New integrations (Stripe, OpenAI, Qdrant, and more)</li>
|
|
4959
|
+
<li>Product features and improvements</li>
|
|
4960
|
+
<li>New templates and examples</li>
|
|
4961
|
+
<li>Architecture insights and best practices</li>
|
|
4962
|
+
<li>Documentation updates</li>
|
|
4963
|
+
</ul>
|
|
4964
|
+
<p>Stay tuned for exciting updates!</p>
|
|
4965
|
+
<hr style="margin: 30px 0; border: none; border-top: 1px solid #e5e7eb;" />
|
|
4966
|
+
<p style="color: #6b7280; font-size: 14px;">
|
|
4967
|
+
ContractSpec Team<br />
|
|
4968
|
+
<a href="https://contractspec.io" style="color: #8b5cf6;">contractspec.io</a>
|
|
4969
|
+
</p>
|
|
4970
|
+
<p style="color: #9ca3af; font-size: 12px;">
|
|
4971
|
+
To unsubscribe, reply to this email with "unsubscribe"
|
|
4972
|
+
</p>
|
|
4973
|
+
</div>
|
|
4974
|
+
`;
|
|
4975
|
+
const userSend = await sendEmail(configResult.config, {
|
|
4976
|
+
to: [{ email }],
|
|
4977
|
+
subject: "Welcome to ContractSpec Newsletter",
|
|
4978
|
+
text: welcomeText,
|
|
4979
|
+
html: welcomeHtml,
|
|
4980
|
+
context: "newsletter-welcome"
|
|
4981
|
+
});
|
|
4982
|
+
if (!userSend.success) {
|
|
4983
|
+
return { success: false, text: NEWSLETTER_SEND_ERROR };
|
|
4984
|
+
}
|
|
4985
|
+
const teamNotificationText = `New newsletter subscription from: ${email}`;
|
|
4986
|
+
const teamNotificationHtml = `
|
|
4987
|
+
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
4988
|
+
<p style="margin: 0 0 8px;">New newsletter subscription</p>
|
|
4989
|
+
<p style="margin: 0;"><strong>Email:</strong> ${formatMultilineHtml(email)}</p>
|
|
4990
|
+
</div>
|
|
4991
|
+
`;
|
|
4992
|
+
const teamSend = await sendEmail(configResult.config, {
|
|
4993
|
+
to: [configResult.config.teamInbox],
|
|
4994
|
+
subject: `New Newsletter Subscription: ${email}`,
|
|
4995
|
+
text: teamNotificationText,
|
|
4996
|
+
html: teamNotificationHtml,
|
|
4997
|
+
context: "newsletter-team-notification"
|
|
4998
|
+
});
|
|
4999
|
+
if (!teamSend.success) {
|
|
5000
|
+
return { success: false, text: NEWSLETTER_SEND_ERROR };
|
|
5001
|
+
}
|
|
5002
|
+
return { success: true, text: "Successfully subscribed!" };
|
|
5003
|
+
};
|
|
5004
|
+
|
|
5005
|
+
// src/libs/email/waitlist.ts
|
|
5006
|
+
"use server";
|
|
5007
|
+
var WAITLIST_MISSING_CONFIG = "Waitlist service is not configured. Please try again later.";
|
|
5008
|
+
var WAITLIST_SEND_ERROR = "Failed to join waitlist. Please try again later or contact us directly.";
|
|
5009
|
+
var joinWaitlist = async (formData) => {
|
|
5827
5010
|
const email = (formData.get("email") ?? "").toString().trim();
|
|
5828
5011
|
if (!email || !email.includes("@")) {
|
|
5829
5012
|
return {
|
|
@@ -5835,78 +5018,258 @@ var subscribeToNewsletter = async (formData) => {
|
|
|
5835
5018
|
if (!configResult.ok || !configResult.config) {
|
|
5836
5019
|
return {
|
|
5837
5020
|
success: false,
|
|
5838
|
-
text: configResult.errorMessage ??
|
|
5021
|
+
text: configResult.errorMessage ?? WAITLIST_MISSING_CONFIG
|
|
5839
5022
|
};
|
|
5840
5023
|
}
|
|
5841
|
-
const
|
|
5842
|
-
|
|
5024
|
+
const waitlistText = `
|
|
5025
|
+
You're on the waitlist!
|
|
5843
5026
|
|
|
5844
|
-
Thanks for
|
|
5027
|
+
Thanks for joining the ContractSpec waitlist. You're now in line for early access to:
|
|
5845
5028
|
|
|
5846
|
-
\u2022
|
|
5847
|
-
\u2022
|
|
5848
|
-
\u2022
|
|
5849
|
-
\u2022
|
|
5850
|
-
\u2022 Documentation updates
|
|
5029
|
+
\u2022 Stabilize your AI-generated code with ContractSpec
|
|
5030
|
+
\u2022 Multi-surface consistency (API, DB, UI, events)
|
|
5031
|
+
\u2022 Safe regeneration without breaking changes
|
|
5032
|
+
\u2022 AI governance and contract enforcement
|
|
5851
5033
|
|
|
5852
|
-
|
|
5034
|
+
We'll notify you as soon as early access is available. In the meantime, you can:
|
|
5035
|
+
|
|
5036
|
+
\u2022 Check out our docs: https://contractspec.io/docs
|
|
5037
|
+
\u2022 Follow our progress on GitHub
|
|
5038
|
+
\u2022 Book a demo call to see ContractSpec in action
|
|
5039
|
+
|
|
5040
|
+
We're excited to have you on board!
|
|
5853
5041
|
|
|
5854
5042
|
---
|
|
5855
5043
|
ContractSpec Team
|
|
5856
5044
|
https://contractspec.io
|
|
5857
5045
|
|
|
5858
|
-
|
|
5046
|
+
To remove yourself from the waitlist, reply to this email with "remove"
|
|
5859
5047
|
`.trim();
|
|
5860
|
-
const
|
|
5048
|
+
const waitlistHtml = `
|
|
5861
5049
|
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
5862
|
-
<h1 style="color: #8b5cf6;">
|
|
5863
|
-
<p>Thanks for
|
|
5050
|
+
<h1 style="color: #8b5cf6;">You're on the waitlist!</h1>
|
|
5051
|
+
<p>Thanks for joining the ContractSpec waitlist. You're now in line for early access to:</p>
|
|
5864
5052
|
<ul style="line-height: 1.8;">
|
|
5865
|
-
<li>
|
|
5866
|
-
<li>
|
|
5867
|
-
<li>
|
|
5868
|
-
<li>
|
|
5869
|
-
<li>Documentation updates</li>
|
|
5053
|
+
<li>Stabilize your AI-generated code with ContractSpec</li>
|
|
5054
|
+
<li>Multi-surface consistency (API, DB, UI, events)</li>
|
|
5055
|
+
<li>Safe regeneration without breaking changes</li>
|
|
5056
|
+
<li>AI governance and contract enforcement</li>
|
|
5870
5057
|
</ul>
|
|
5871
|
-
<p>
|
|
5058
|
+
<p>We'll notify you as soon as early access is available. In the meantime, you can:</p>
|
|
5059
|
+
<ul style="line-height: 1.8;">
|
|
5060
|
+
<li>Check out our <a href="https://contractspec.io/docs" style="color: #8b5cf6;">docs</a></li>
|
|
5061
|
+
<li>Follow our progress on GitHub</li>
|
|
5062
|
+
<li>Book a demo call to see ContractSpec in action</li>
|
|
5063
|
+
</ul>
|
|
5064
|
+
<p>We're excited to have you on board!</p>
|
|
5872
5065
|
<hr style="margin: 30px 0; border: none; border-top: 1px solid #e5e7eb;" />
|
|
5873
5066
|
<p style="color: #6b7280; font-size: 14px;">
|
|
5874
5067
|
ContractSpec Team<br />
|
|
5875
5068
|
<a href="https://contractspec.io" style="color: #8b5cf6;">contractspec.io</a>
|
|
5876
5069
|
</p>
|
|
5877
5070
|
<p style="color: #9ca3af; font-size: 12px;">
|
|
5878
|
-
To
|
|
5071
|
+
To remove yourself from the waitlist, reply to this email with "remove"
|
|
5879
5072
|
</p>
|
|
5880
5073
|
</div>
|
|
5881
5074
|
`;
|
|
5882
5075
|
const userSend = await sendEmail(configResult.config, {
|
|
5883
5076
|
to: [{ email }],
|
|
5884
|
-
subject: "
|
|
5885
|
-
text:
|
|
5886
|
-
html:
|
|
5887
|
-
context: "
|
|
5077
|
+
subject: "You're on the ContractSpec waitlist!",
|
|
5078
|
+
text: waitlistText,
|
|
5079
|
+
html: waitlistHtml,
|
|
5080
|
+
context: "waitlist-welcome"
|
|
5888
5081
|
});
|
|
5889
5082
|
if (!userSend.success) {
|
|
5890
|
-
return { success: false, text:
|
|
5083
|
+
return { success: false, text: WAITLIST_SEND_ERROR };
|
|
5891
5084
|
}
|
|
5892
|
-
const teamNotificationText = `New
|
|
5085
|
+
const teamNotificationText = `New waitlist signup from: ${email}`;
|
|
5893
5086
|
const teamNotificationHtml = `
|
|
5894
5087
|
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
5895
|
-
<p style="margin: 0 0 8px;">New
|
|
5088
|
+
<p style="margin: 0 0 8px;">New waitlist signup</p>
|
|
5896
5089
|
<p style="margin: 0;"><strong>Email:</strong> ${formatMultilineHtml(email)}</p>
|
|
5897
5090
|
</div>
|
|
5898
5091
|
`;
|
|
5899
5092
|
const teamSend = await sendEmail(configResult.config, {
|
|
5900
5093
|
to: [configResult.config.teamInbox],
|
|
5901
|
-
subject: `New
|
|
5094
|
+
subject: `New Waitlist Signup: ${email}`,
|
|
5902
5095
|
text: teamNotificationText,
|
|
5903
5096
|
html: teamNotificationHtml,
|
|
5904
|
-
context: "
|
|
5097
|
+
context: "waitlist-team-notification"
|
|
5905
5098
|
});
|
|
5906
5099
|
if (!teamSend.success) {
|
|
5907
|
-
return { success: false, text:
|
|
5100
|
+
return { success: false, text: WAITLIST_SEND_ERROR };
|
|
5908
5101
|
}
|
|
5909
|
-
return { success: true, text: "Successfully
|
|
5102
|
+
return { success: true, text: "Successfully joined waitlist!" };
|
|
5103
|
+
};
|
|
5104
|
+
|
|
5105
|
+
// src/libs/email/waitlist-application.ts
|
|
5106
|
+
"use server";
|
|
5107
|
+
var APPLICATION_MISSING_CONFIG = "Waitlist application service is not configured. Please try again later.";
|
|
5108
|
+
var APPLICATION_SEND_ERROR = "Failed to submit application. Please try again later or contact us directly.";
|
|
5109
|
+
var submitWaitlistApplication = async (formData) => {
|
|
5110
|
+
const email = (formData.get("email") ?? "").toString().trim();
|
|
5111
|
+
const name = (formData.get("name") ?? "").toString().trim();
|
|
5112
|
+
const company = (formData.get("company") ?? "").toString().trim();
|
|
5113
|
+
const role = (formData.get("role") ?? "").toString().trim();
|
|
5114
|
+
const useCase = (formData.get("useCase") ?? "").toString().trim();
|
|
5115
|
+
const currentStack = (formData.get("currentStack") ?? "").toString().trim();
|
|
5116
|
+
const whatBuilding = (formData.get("whatBuilding") ?? "").toString().trim();
|
|
5117
|
+
const whatSolving = (formData.get("whatSolving") ?? "").toString().trim();
|
|
5118
|
+
const teamSize = (formData.get("teamSize") ?? "").toString().trim();
|
|
5119
|
+
const timeline = (formData.get("timeline") ?? "").toString().trim();
|
|
5120
|
+
const openToSessions = formData.get("openToSessions") === "on";
|
|
5121
|
+
const okayWithCaseStudies = formData.get("okayWithCaseStudies") === "on";
|
|
5122
|
+
if (!email || !email.includes("@")) {
|
|
5123
|
+
return {
|
|
5124
|
+
success: false,
|
|
5125
|
+
text: "Please enter a valid email address."
|
|
5126
|
+
};
|
|
5127
|
+
}
|
|
5128
|
+
if (!name || !whatBuilding || !whatSolving) {
|
|
5129
|
+
return {
|
|
5130
|
+
success: false,
|
|
5131
|
+
text: "Please fill in all required fields."
|
|
5132
|
+
};
|
|
5133
|
+
}
|
|
5134
|
+
const configResult = getEmailConfig();
|
|
5135
|
+
if (!configResult.ok || !configResult.config) {
|
|
5136
|
+
return {
|
|
5137
|
+
success: false,
|
|
5138
|
+
text: configResult.errorMessage ?? APPLICATION_MISSING_CONFIG
|
|
5139
|
+
};
|
|
5140
|
+
}
|
|
5141
|
+
const applicantText = `
|
|
5142
|
+
You're on the list.
|
|
5143
|
+
|
|
5144
|
+
Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.
|
|
5145
|
+
|
|
5146
|
+
What happens next:
|
|
5147
|
+
\u2022 We review applications weekly
|
|
5148
|
+
\u2022 If selected, we'll reach out via email to schedule an intro call
|
|
5149
|
+
\u2022 During early access, you'll get hands-on support and influence over the roadmap
|
|
5150
|
+
|
|
5151
|
+
In the meantime:
|
|
5152
|
+
\u2022 Check out our docs: https://contractspec.io/docs
|
|
5153
|
+
\u2022 Book a demo call: https://contractspec.io/contact
|
|
5154
|
+
|
|
5155
|
+
We're excited about the possibility of working together!
|
|
5156
|
+
|
|
5157
|
+
---
|
|
5158
|
+
ContractSpec Team
|
|
5159
|
+
https://contractspec.io
|
|
5160
|
+
`.trim();
|
|
5161
|
+
const applicantHtml = `
|
|
5162
|
+
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
5163
|
+
<h1 style="color: #8b5cf6;">You're on the list.</h1>
|
|
5164
|
+
<p>Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.</p>
|
|
5165
|
+
<h2 style="color: #8b5cf6; margin-top: 24px;">What happens next:</h2>
|
|
5166
|
+
<ul style="line-height: 1.8;">
|
|
5167
|
+
<li>We review applications weekly</li>
|
|
5168
|
+
<li>If selected, we'll reach out via email to schedule an intro call</li>
|
|
5169
|
+
<li>During early access, you'll get hands-on support and influence over the roadmap</li>
|
|
5170
|
+
</ul>
|
|
5171
|
+
<h2 style="color: #8b5cf6; margin-top: 24px;">In the meantime:</h2>
|
|
5172
|
+
<ul style="line-height: 1.8;">
|
|
5173
|
+
<li>Check out our <a href="https://contractspec.io/docs" style="color: #8b5cf6;">docs</a></li>
|
|
5174
|
+
<li>Book a demo call: <a href="https://contractspec.io/contact" style="color: #8b5cf6;">contractspec.io/contact</a></li>
|
|
5175
|
+
</ul>
|
|
5176
|
+
<p>We're excited about the possibility of working together!</p>
|
|
5177
|
+
<hr style="margin: 30px 0; border: none; border-top: 1px solid #e5e7eb;" />
|
|
5178
|
+
<p style="color: #6b7280; font-size: 14px;">
|
|
5179
|
+
ContractSpec Team<br />
|
|
5180
|
+
<a href="https://contractspec.io" style="color: #8b5cf6;">contractspec.io</a>
|
|
5181
|
+
</p>
|
|
5182
|
+
</div>
|
|
5183
|
+
`;
|
|
5184
|
+
const applicantSend = await sendEmail(configResult.config, {
|
|
5185
|
+
to: [{ email }],
|
|
5186
|
+
subject: "You're on the ContractSpec design partner waitlist!",
|
|
5187
|
+
text: applicantText,
|
|
5188
|
+
html: applicantHtml,
|
|
5189
|
+
context: "waitlist-application-welcome"
|
|
5190
|
+
});
|
|
5191
|
+
if (!applicantSend.success) {
|
|
5192
|
+
return { success: false, text: APPLICATION_SEND_ERROR };
|
|
5193
|
+
}
|
|
5194
|
+
const preferencesText = `
|
|
5195
|
+
Open to 1:1 product/design sessions: ${openToSessions ? "Yes" : "No"}
|
|
5196
|
+
Okay with anonymized case studies: ${okayWithCaseStudies ? "Yes" : "No"}
|
|
5197
|
+
`.trim();
|
|
5198
|
+
const teamEmailText = `
|
|
5199
|
+
New Design Partner Waitlist Application
|
|
5200
|
+
|
|
5201
|
+
Contact Information:
|
|
5202
|
+
- Name: ${name}
|
|
5203
|
+
- Email: ${email}
|
|
5204
|
+
${company ? `- Company/Project: ${company}` : ""}
|
|
5205
|
+
${role ? `- Role: ${role}` : ""}
|
|
5206
|
+
|
|
5207
|
+
Application Details:
|
|
5208
|
+
- What are you building with AI today?
|
|
5209
|
+
${whatBuilding}
|
|
5210
|
+
|
|
5211
|
+
- What do you hope ContractSpec will solve for you?
|
|
5212
|
+
${whatSolving}
|
|
5213
|
+
|
|
5214
|
+
- Primary use case: ${useCase || "Not specified"}
|
|
5215
|
+
- Current stack: ${currentStack || "Not specified"}
|
|
5216
|
+
- Team Size: ${teamSize || "Not specified"}
|
|
5217
|
+
- Timeline: ${timeline || "Not specified"}
|
|
5218
|
+
|
|
5219
|
+
Preferences:
|
|
5220
|
+
- Open to 1:1 product/design sessions: ${openToSessions ? "Yes" : "No"}
|
|
5221
|
+
- Okay with anonymized case studies: ${okayWithCaseStudies ? "Yes" : "No"}
|
|
5222
|
+
|
|
5223
|
+
---
|
|
5224
|
+
Submitted via ContractSpec waitlist application form
|
|
5225
|
+
`.trim();
|
|
5226
|
+
const teamEmailHtml = `
|
|
5227
|
+
<div style="font-family: sans-serif; max-width: 720px; margin: 0 auto;">
|
|
5228
|
+
<h1 style="color: #8b5cf6;">New Design Partner Waitlist Application</h1>
|
|
5229
|
+
<h2 style="color: #8b5cf6; margin: 16px 0 8px;">Contact Information</h2>
|
|
5230
|
+
<ul style="padding-left: 16px; line-height: 1.6; margin: 0 0 16px;">
|
|
5231
|
+
<li>Name: ${escapeHtml(name)}</li>
|
|
5232
|
+
<li>Email: ${escapeHtml(email)}</li>
|
|
5233
|
+
${company ? `<li>Company/Project: ${escapeHtml(company)}</li>` : ""}
|
|
5234
|
+
${role ? `<li>Role: ${escapeHtml(role)}</li>` : ""}
|
|
5235
|
+
</ul>
|
|
5236
|
+
<h2 style="color: #8b5cf6; margin: 16px 0 8px;">Application Details</h2>
|
|
5237
|
+
<p style="margin: 0 0 8px; font-weight: 600;">What are you building with AI today?</p>
|
|
5238
|
+
<div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; white-space: pre-wrap; line-height: 1.6;">
|
|
5239
|
+
${formatMultilineHtml(whatBuilding)}
|
|
5240
|
+
</div>
|
|
5241
|
+
<p style="margin: 16px 0 8px; font-weight: 600;">What do you hope ContractSpec will solve for you?</p>
|
|
5242
|
+
<div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; white-space: pre-wrap; line-height: 1.6;">
|
|
5243
|
+
${formatMultilineHtml(whatSolving)}
|
|
5244
|
+
</div>
|
|
5245
|
+
<ul style="padding-left: 16px; line-height: 1.6; margin: 16px 0;">
|
|
5246
|
+
<li>Primary use case: ${escapeHtml(useCase || "Not specified")}</li>
|
|
5247
|
+
<li>Current stack: ${escapeHtml(currentStack || "Not specified")}</li>
|
|
5248
|
+
<li>Team Size: ${escapeHtml(teamSize || "Not specified")}</li>
|
|
5249
|
+
<li>Timeline: ${escapeHtml(timeline || "Not specified")}</li>
|
|
5250
|
+
</ul>
|
|
5251
|
+
<h2 style="color: #8b5cf6; margin: 16px 0 8px;">Preferences</h2>
|
|
5252
|
+
<div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; line-height: 1.6;">
|
|
5253
|
+
${formatMultilineHtml(preferencesText)}
|
|
5254
|
+
</div>
|
|
5255
|
+
<p style="color: #6b7280; font-size: 12px; margin-top: 20px;">Submitted via ContractSpec waitlist application form</p>
|
|
5256
|
+
</div>
|
|
5257
|
+
`;
|
|
5258
|
+
const teamSend = await sendEmail(configResult.config, {
|
|
5259
|
+
to: [configResult.config.teamInbox],
|
|
5260
|
+
subject: `New Design Partner Application: ${name} (${email})`,
|
|
5261
|
+
text: teamEmailText,
|
|
5262
|
+
html: teamEmailHtml,
|
|
5263
|
+
replyTo: email,
|
|
5264
|
+
context: "waitlist-application-team-notification"
|
|
5265
|
+
});
|
|
5266
|
+
if (!teamSend.success) {
|
|
5267
|
+
return { success: false, text: APPLICATION_SEND_ERROR };
|
|
5268
|
+
}
|
|
5269
|
+
return {
|
|
5270
|
+
success: true,
|
|
5271
|
+
text: "Application submitted successfully!"
|
|
5272
|
+
};
|
|
5910
5273
|
};
|
|
5911
5274
|
|
|
5912
5275
|
// src/registry/factory.ts
|
|
@@ -6032,12 +5395,7 @@ import { SpecsOverlaysPage } from "@contractspec/bundle.library/components/docs/
|
|
|
6032
5395
|
import { SpecsOverviewPage } from "@contractspec/bundle.library/components/docs/specs/SpecsOverviewPage";
|
|
6033
5396
|
import { SpecsPolicyPage } from "@contractspec/bundle.library/components/docs/specs/SpecsPolicyPage";
|
|
6034
5397
|
import { SpecsWorkflowsPage } from "@contractspec/bundle.library/components/docs/specs/SpecsWorkflowsPage";
|
|
6035
|
-
import { StudioBYOKPage } from "@contractspec/bundle.library/components/docs/studio/StudioBYOKPage";
|
|
6036
|
-
import { StudioDeploymentsPage } from "@contractspec/bundle.library/components/docs/studio/StudioDeploymentsPage";
|
|
6037
|
-
import { StudioGettingStartedPage } from "@contractspec/bundle.library/components/docs/studio/StudioGettingStartedPage";
|
|
6038
|
-
import { StudioIntegrationsPage } from "@contractspec/bundle.library/components/docs/studio/StudioIntegrationsPage";
|
|
6039
5398
|
import { StudioOverviewPage } from "@contractspec/bundle.library/components/docs/studio/StudioOverviewPage";
|
|
6040
|
-
import { StudioVisualBuilderPage } from "@contractspec/bundle.library/components/docs/studio/StudioVisualBuilderPage";
|
|
6041
5399
|
import { DocsIndexPage } from "@contractspec/bundle.library/components/docs/DocsIndexPage";
|
|
6042
5400
|
var docsComponentMap = {
|
|
6043
5401
|
DocsIndexPage,
|
|
@@ -6126,12 +5484,7 @@ var docsComponentMap = {
|
|
|
6126
5484
|
OpsAutoEvolutionPage,
|
|
6127
5485
|
OpsDistributedTracingPage,
|
|
6128
5486
|
ManifestoPage,
|
|
6129
|
-
StudioOverviewPage
|
|
6130
|
-
StudioGettingStartedPage,
|
|
6131
|
-
StudioVisualBuilderPage,
|
|
6132
|
-
StudioIntegrationsPage,
|
|
6133
|
-
StudioDeploymentsPage,
|
|
6134
|
-
StudioBYOKPage
|
|
5487
|
+
StudioOverviewPage
|
|
6135
5488
|
};
|
|
6136
5489
|
function docsEntry(route, key, componentKey, description) {
|
|
6137
5490
|
return [
|
|
@@ -6233,12 +5586,7 @@ var docsPresentations = [
|
|
|
6233
5586
|
docsEntry("/docs/ops/auto-evolution", "web-landing.docs.ops.auto-evolution", "OpsAutoEvolutionPage", "ContractSpec auto-evolution operations"),
|
|
6234
5587
|
docsEntry("/docs/ops/distributed-tracing", "web-landing.docs.ops.distributed-tracing", "OpsDistributedTracingPage", "ContractSpec distributed tracing"),
|
|
6235
5588
|
docsEntry("/docs/manifesto", "web-landing.docs.manifesto", "ManifestoPage", "ContractSpec manifesto"),
|
|
6236
|
-
docsEntry("/docs/studio", "web-landing.docs.studio.overview", "StudioOverviewPage", "ContractSpec Studio overview")
|
|
6237
|
-
docsEntry("/docs/studio/getting-started", "web-landing.docs.studio.getting-started", "StudioGettingStartedPage", "ContractSpec Studio getting started"),
|
|
6238
|
-
docsEntry("/docs/studio/visual-builder", "web-landing.docs.studio.visual-builder", "StudioVisualBuilderPage", "ContractSpec Studio visual builder"),
|
|
6239
|
-
docsEntry("/docs/studio/integrations", "web-landing.docs.studio.integrations", "StudioIntegrationsPage", "ContractSpec Studio integrations"),
|
|
6240
|
-
docsEntry("/docs/studio/deployments", "web-landing.docs.studio.deployments", "StudioDeploymentsPage", "ContractSpec Studio deployments"),
|
|
6241
|
-
docsEntry("/docs/studio/byok", "web-landing.docs.studio.byok", "StudioBYOKPage", "ContractSpec Studio BYOK")
|
|
5589
|
+
docsEntry("/docs/studio", "web-landing.docs.studio.overview", "StudioOverviewPage", "ContractSpec Studio overview")
|
|
6242
5590
|
];
|
|
6243
5591
|
|
|
6244
5592
|
// src/registry/registry-landing.ts
|
|
@@ -6459,10 +5807,10 @@ export {
|
|
|
6459
5807
|
createComponentPresentation,
|
|
6460
5808
|
componentMap,
|
|
6461
5809
|
aiChatProviders,
|
|
6462
|
-
WaitlistSection,
|
|
6463
5810
|
TemplatesPage,
|
|
6464
5811
|
TemplatesMarketingPage,
|
|
6465
5812
|
TemplatePreviewModal,
|
|
5813
|
+
StudioSignupSection,
|
|
6466
5814
|
ProductClientPage,
|
|
6467
5815
|
PricingThinkingModal,
|
|
6468
5816
|
PricingClient,
|