@octaviaflow/core 3.1.0-beta.67 → 3.1.0-beta.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/dist/chunk-64R3BAO7.js +2755 -0
  2. package/dist/chunk-64R3BAO7.js.map +1 -0
  3. package/dist/chunk-7S3CSRRV.js +5700 -0
  4. package/dist/chunk-7S3CSRRV.js.map +1 -0
  5. package/dist/chunk-JMSZOWT2.js +2616 -0
  6. package/dist/chunk-JMSZOWT2.js.map +1 -0
  7. package/dist/chunk-KCA7V5VN.js +5752 -0
  8. package/dist/chunk-KCA7V5VN.js.map +1 -0
  9. package/dist/chunk-KQKD4Z4H.js +1682 -0
  10. package/dist/chunk-KQKD4Z4H.js.map +1 -0
  11. package/dist/chunk-KZP2MNBO.js +2516 -0
  12. package/dist/chunk-KZP2MNBO.js.map +1 -0
  13. package/dist/chunk-PWCRELX4.js +5700 -0
  14. package/dist/chunk-PWCRELX4.js.map +1 -0
  15. package/dist/chunk-S4LE4BFQ.js +5934 -0
  16. package/dist/chunk-S4LE4BFQ.js.map +1 -0
  17. package/dist/chunk-U5T63SPL.js +5695 -0
  18. package/dist/chunk-U5T63SPL.js.map +1 -0
  19. package/dist/chunk-X7YETDK7.js +107 -0
  20. package/dist/chunk-X7YETDK7.js.map +1 -0
  21. package/dist/chunk-YIPBLM3G.js +2698 -0
  22. package/dist/chunk-YIPBLM3G.js.map +1 -0
  23. package/dist/components/Tabs/Tabs.d.ts.map +1 -1
  24. package/dist/components/WorkflowShowcase/ShowcaseScene.d.ts +20 -0
  25. package/dist/components/WorkflowShowcase/ShowcaseScene.d.ts.map +1 -0
  26. package/dist/components/WorkflowShowcase/ShowcaseSignup.d.ts +14 -0
  27. package/dist/components/WorkflowShowcase/ShowcaseSignup.d.ts.map +1 -0
  28. package/dist/components/WorkflowShowcase/WorkflowShowcase.d.ts +48 -0
  29. package/dist/components/WorkflowShowcase/WorkflowShowcase.d.ts.map +1 -0
  30. package/dist/components/WorkflowShowcase/index.d.ts +3 -0
  31. package/dist/components/WorkflowShowcase/index.d.ts.map +1 -0
  32. package/dist/components/WorkflowShowcase/showcaseEngine.d.ts +102 -0
  33. package/dist/components/WorkflowShowcase/showcaseEngine.d.ts.map +1 -0
  34. package/dist/index.cjs +5 -0
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.js +18795 -25817
  37. package/dist/index.js.map +1 -1
  38. package/dist/marketing/components/AssistantTranscript/AssistantTranscript.d.ts +15 -0
  39. package/dist/marketing/components/AssistantTranscript/AssistantTranscript.d.ts.map +1 -0
  40. package/dist/marketing/components/BackedBy/BackedBy.d.ts +17 -0
  41. package/dist/marketing/components/BackedBy/BackedBy.d.ts.map +1 -0
  42. package/dist/marketing/components/BetaAccessForm/BetaAccessForm.d.ts +36 -0
  43. package/dist/marketing/components/BetaAccessForm/BetaAccessForm.d.ts.map +1 -0
  44. package/dist/marketing/components/BlogGrid/BlogGrid.d.ts +32 -0
  45. package/dist/marketing/components/BlogGrid/BlogGrid.d.ts.map +1 -0
  46. package/dist/marketing/components/ContactForm/ContactForm.d.ts +31 -0
  47. package/dist/marketing/components/ContactForm/ContactForm.d.ts.map +1 -0
  48. package/dist/marketing/components/CtaBanner/CtaBanner.d.ts +16 -0
  49. package/dist/marketing/components/CtaBanner/CtaBanner.d.ts.map +1 -0
  50. package/dist/marketing/components/FaqSection/FaqSection.d.ts +13 -0
  51. package/dist/marketing/components/FaqSection/FaqSection.d.ts.map +1 -0
  52. package/dist/marketing/components/FeatureGrid/FeatureGrid.d.ts +15 -0
  53. package/dist/marketing/components/FeatureGrid/FeatureGrid.d.ts.map +1 -0
  54. package/dist/marketing/components/IntegrationsFinder/IntegrationsFinder.d.ts +32 -0
  55. package/dist/marketing/components/IntegrationsFinder/IntegrationsFinder.d.ts.map +1 -0
  56. package/dist/marketing/components/IntegrationsWall/IntegrationsWall.d.ts +21 -0
  57. package/dist/marketing/components/IntegrationsWall/IntegrationsWall.d.ts.map +1 -0
  58. package/dist/marketing/components/LiveConsole/LiveConsole.d.ts +21 -0
  59. package/dist/marketing/components/LiveConsole/LiveConsole.d.ts.map +1 -0
  60. package/dist/marketing/components/LogoMarquee/LogoMarquee.d.ts +18 -0
  61. package/dist/marketing/components/LogoMarquee/LogoMarquee.d.ts.map +1 -0
  62. package/dist/marketing/components/MarketingFooter/MarketingFooter.d.ts +30 -0
  63. package/dist/marketing/components/MarketingFooter/MarketingFooter.d.ts.map +1 -0
  64. package/dist/marketing/components/MarketingHero/MarketingHero.d.ts +11 -0
  65. package/dist/marketing/components/MarketingHero/MarketingHero.d.ts.map +1 -0
  66. package/dist/marketing/components/MarketingNav/MarketingNav.d.ts +17 -0
  67. package/dist/marketing/components/MarketingNav/MarketingNav.d.ts.map +1 -0
  68. package/dist/marketing/components/MarketingSection/MarketingSection.d.ts +15 -0
  69. package/dist/marketing/components/MarketingSection/MarketingSection.d.ts.map +1 -0
  70. package/dist/marketing/components/PageHero/PageHero.d.ts +12 -0
  71. package/dist/marketing/components/PageHero/PageHero.d.ts.map +1 -0
  72. package/dist/marketing/components/PricingTiers/PricingTiers.d.ts +29 -0
  73. package/dist/marketing/components/PricingTiers/PricingTiers.d.ts.map +1 -0
  74. package/dist/marketing/components/StatBand/StatBand.d.ts +16 -0
  75. package/dist/marketing/components/StatBand/StatBand.d.ts.map +1 -0
  76. package/dist/marketing/components/TestimonialStrip/TestimonialStrip.d.ts +24 -0
  77. package/dist/marketing/components/TestimonialStrip/TestimonialStrip.d.ts.map +1 -0
  78. package/dist/marketing/components/WorkflowShowcase/ShowcaseScene.d.ts +22 -0
  79. package/dist/marketing/components/WorkflowShowcase/ShowcaseScene.d.ts.map +1 -0
  80. package/dist/marketing/components/WorkflowShowcase/ShowcaseSignup.d.ts +14 -0
  81. package/dist/marketing/components/WorkflowShowcase/ShowcaseSignup.d.ts.map +1 -0
  82. package/dist/marketing/components/WorkflowShowcase/WorkflowShowcase.d.ts +56 -0
  83. package/dist/marketing/components/WorkflowShowcase/WorkflowShowcase.d.ts.map +1 -0
  84. package/dist/marketing/components/WorkflowShowcase/index.d.ts +3 -0
  85. package/dist/marketing/components/WorkflowShowcase/index.d.ts.map +1 -0
  86. package/dist/marketing/components/WorkflowShowcase/showcaseEngine.d.ts +104 -0
  87. package/dist/marketing/components/WorkflowShowcase/showcaseEngine.d.ts.map +1 -0
  88. package/dist/marketing/glyphs.d.ts +20 -0
  89. package/dist/marketing/glyphs.d.ts.map +1 -0
  90. package/dist/marketing/index.d.ts +23 -0
  91. package/dist/marketing/index.d.ts.map +1 -0
  92. package/dist/marketing.cjs +6581 -0
  93. package/dist/marketing.cjs.map +1 -0
  94. package/dist/marketing.js +2602 -0
  95. package/dist/marketing.js.map +1 -0
  96. package/dist/styles.css +1 -1
  97. package/dist/workflow/components/HttpActionPanel/HttpActionPanel.d.ts +29 -0
  98. package/dist/workflow/components/HttpActionPanel/HttpActionPanel.d.ts.map +1 -0
  99. package/dist/workflow/components/HttpActionPanel/httpActionTypes.d.ts +135 -0
  100. package/dist/workflow/components/HttpActionPanel/httpActionTypes.d.ts.map +1 -0
  101. package/dist/workflow/index.d.ts +2 -0
  102. package/dist/workflow/index.d.ts.map +1 -1
  103. package/dist/workflow.cjs +6931 -271
  104. package/dist/workflow.cjs.map +1 -1
  105. package/dist/workflow.js +1591 -56
  106. package/dist/workflow.js.map +1 -1
  107. package/package.json +6 -1
@@ -0,0 +1,2602 @@
1
+ import {
2
+ BlogCard,
3
+ CountUp,
4
+ TestimonialCard,
5
+ Textarea
6
+ } from "./chunk-KQKD4Z4H.js";
7
+ import {
8
+ Accordion,
9
+ Button,
10
+ Input,
11
+ Select,
12
+ Spinner
13
+ } from "./chunk-64R3BAO7.js";
14
+ import {
15
+ cn
16
+ } from "./chunk-ZAUUGK2Y.js";
17
+
18
+ // src/marketing/components/AssistantTranscript/AssistantTranscript.tsx
19
+ import { jsx, jsxs } from "react/jsx-runtime";
20
+ function AssistantTranscript({
21
+ title = "OctaviaFlow AI Assistant",
22
+ turns,
23
+ userLabel = "you",
24
+ assistantLabel = "octavia",
25
+ className,
26
+ ...rest
27
+ }) {
28
+ return /* @__PURE__ */ jsxs("div", { ...rest, className: cn("ods-mkt-transcript", className), children: [
29
+ /* @__PURE__ */ jsx("div", { className: "ods-mkt-transcript__head", children: title }),
30
+ /* @__PURE__ */ jsx("div", { className: "ods-mkt-transcript__body", children: turns.map((turn) => /* @__PURE__ */ jsxs("div", { className: "ods-mkt-transcript__turn", children: [
31
+ /* @__PURE__ */ jsxs(
32
+ "span",
33
+ {
34
+ className: cn(
35
+ "ods-mkt-transcript__speaker",
36
+ `ods-mkt-transcript__speaker--${turn.speaker}`
37
+ ),
38
+ children: [
39
+ turn.speaker === "user" ? userLabel : assistantLabel,
40
+ " \u2192"
41
+ ]
42
+ }
43
+ ),
44
+ " ",
45
+ /* @__PURE__ */ jsx("span", { className: "ods-mkt-transcript__content", children: turn.content })
46
+ ] }, turn.id)) })
47
+ ] });
48
+ }
49
+
50
+ // src/marketing/components/BackedBy/BackedBy.tsx
51
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
52
+ function BackedBy({
53
+ items,
54
+ label = "Backed by",
55
+ note,
56
+ align = "center",
57
+ className,
58
+ ...rest
59
+ }) {
60
+ return /* @__PURE__ */ jsxs2(
61
+ "div",
62
+ {
63
+ ...rest,
64
+ className: cn("ods-mkt-backedby", align === "start" && "ods-mkt-backedby--start", className),
65
+ children: [
66
+ label && /* @__PURE__ */ jsx2("p", { className: "ods-mkt-backedby__label", children: label }),
67
+ /* @__PURE__ */ jsx2("div", { className: "ods-mkt-backedby__row", children: items.map((item) => /* @__PURE__ */ jsx2("span", { className: "ods-mkt-backedby__mark", title: item.name, children: item.icon ?? /* @__PURE__ */ jsx2("span", { className: "ods-mkt-backedby__wordmark", children: item.name }) }, item.id)) }),
68
+ note && /* @__PURE__ */ jsx2("p", { className: "ods-mkt-backedby__note", children: note })
69
+ ]
70
+ }
71
+ );
72
+ }
73
+
74
+ // src/marketing/components/BetaAccessForm/BetaAccessForm.tsx
75
+ import { useId, useState } from "react";
76
+
77
+ // src/marketing/components/WorkflowShowcase/showcaseEngine.ts
78
+ var SETTLED_PHASES = [
79
+ "done",
80
+ "signup",
81
+ "creating",
82
+ "welcome"
83
+ ];
84
+ var WORKFLOW_SHOWCASE_DEFAULT_CONNECTORS = [
85
+ { name: "Storefront", role: "source", aliases: ["store", "shop orders"] },
86
+ { name: "Payments", role: "source", aliases: ["payouts"] },
87
+ { name: "Orders DB", role: "source", aliases: ["orders database"] },
88
+ { name: "CRM", role: "source", aliases: ["crm leads"] },
89
+ { name: "Warehouse", role: "destination" },
90
+ { name: "Lakehouse", role: "destination" },
91
+ { name: "Campaigns", role: "action", aliases: ["campaign"] },
92
+ { name: "Team Chat", role: "notify", aliases: ["chat", "alert the team"] }
93
+ ];
94
+ var WORKFLOW_SHOWCASE_DEFAULT_EXAMPLES = [
95
+ {
96
+ id: "hourly-sync",
97
+ label: "Storefront orders \u2192 Warehouse, hourly",
98
+ prompt: "Sync Storefront orders to Warehouse every hour, alert sales in Team Chat"
99
+ },
100
+ {
101
+ id: "daily-load",
102
+ label: "Payments payouts \u2192 Lakehouse, daily",
103
+ prompt: "Load Payments payouts into Lakehouse daily"
104
+ },
105
+ {
106
+ id: "realtime-stream",
107
+ label: "Orders DB changes \u2192 Warehouse + Team Chat",
108
+ prompt: "Stream Orders DB changes to Warehouse in real-time and notify Team Chat"
109
+ }
110
+ ];
111
+ var WORKFLOW_SHOWCASE_DEFAULT_METRICS = [
112
+ { id: "throughput", value: 2341, buildingValue: 842, unit: "rows/min", label: "THROUGHPUT" },
113
+ {
114
+ id: "latency",
115
+ value: 0.8,
116
+ buildingValue: 1.1,
117
+ decimals: 1,
118
+ unit: "s latency",
119
+ label: "SYNC SPEED"
120
+ },
121
+ { id: "cost", value: 43, suffix: "%", label: "SAVED VS BASELINE", tone: "success" }
122
+ ];
123
+ var WORKFLOW_SHOWCASE_SCHEDULES = ["AUTO", "HOURLY", "DAILY", "REAL-TIME"];
124
+ var WORKFLOW_SHOWCASE_TRIGGERS = ["SCHEDULE", "WEBHOOK", "APP EVENT", "MANUAL"];
125
+ var WORKFLOW_SHOWCASE_DEFAULT_TILES = [
126
+ "ELT",
127
+ "CDC",
128
+ "LLM",
129
+ "RAG",
130
+ "HEAL",
131
+ "COST",
132
+ "IDP",
133
+ "VEC"
134
+ ];
135
+ function escapeRegExp(value) {
136
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
137
+ }
138
+ function mentionsOf(catalog) {
139
+ const out = [];
140
+ for (const connector of catalog) {
141
+ out.push({ connector, pattern: connector.name });
142
+ for (const alias of connector.aliases ?? []) out.push({ connector, pattern: alias });
143
+ }
144
+ return out.sort((a, b) => b.pattern.length - a.pattern.length);
145
+ }
146
+ function detectConnectors(prompt, catalog) {
147
+ const lower = prompt.toLowerCase();
148
+ return catalog.filter((c) => [c.name, ...c.aliases ?? []].some((p) => lower.includes(p.toLowerCase()))).map((c) => c.name);
149
+ }
150
+ function segmentPrompt(prompt, catalog) {
151
+ if (!prompt) return [];
152
+ const mentions = mentionsOf(catalog);
153
+ if (!mentions.length) return [{ text: prompt }];
154
+ const re = new RegExp(`(${mentions.map((m) => escapeRegExp(m.pattern)).join("|")})`, "gi");
155
+ const byPattern = new Map(mentions.map((m) => [m.pattern.toLowerCase(), m.connector]));
156
+ return prompt.split(re).filter((part) => part !== "").map((part) => {
157
+ const connector = byPattern.get(part.toLowerCase());
158
+ return connector ? { text: part, connector } : { text: part };
159
+ });
160
+ }
161
+ function scheduleFromPrompt(prompt) {
162
+ const t = prompt.toLowerCase();
163
+ if (/stream|real.?time|cdc/.test(t)) return "REAL-TIME";
164
+ if (/hour/.test(t)) return "HOURLY";
165
+ if (/dail|every day|nightly/.test(t)) return "DAILY";
166
+ return null;
167
+ }
168
+ var RIGHT_ORDER = {
169
+ source: -1,
170
+ destination: 0,
171
+ action: 1,
172
+ notify: 2
173
+ };
174
+ function resolvePlan(selected, detected, catalog) {
175
+ const byName = new Map(catalog.map((c) => [c.name, c]));
176
+ let names = [.../* @__PURE__ */ new Set([...selected, ...detected])].filter((n) => byName.has(n));
177
+ if (!names.length) {
178
+ const fallback = [
179
+ catalog.find((c) => c.role === "source"),
180
+ catalog.find((c) => c.role === "destination"),
181
+ catalog.find((c) => c.role === "notify")
182
+ ].filter((c) => Boolean(c));
183
+ names = fallback.map((c) => c.name);
184
+ }
185
+ const has = (predicate) => names.some((n) => {
186
+ const c = byName.get(n);
187
+ return Boolean(c && predicate(c));
188
+ });
189
+ if (!has((c) => c.role === "source")) {
190
+ const source = catalog.find((c) => c.role === "source");
191
+ if (source) names = [source.name, ...names];
192
+ }
193
+ if (!has((c) => c.role !== "source")) {
194
+ const sink = catalog.find((c) => c.role === "notify") ?? catalog.find((c) => c.role !== "source");
195
+ if (sink) names = [...names, sink.name];
196
+ }
197
+ const picked = catalog.filter((c) => names.includes(c.name));
198
+ const left = picked.filter((c) => c.role === "source");
199
+ const right = picked.filter((c) => c.role !== "source").sort((a, b) => RIGHT_ORDER[a.role] - RIGHT_ORDER[b.role]);
200
+ const all = [...left, ...right];
201
+ return { left, right, all, totalSteps: all.length + 1 };
202
+ }
203
+ function stepVerb(role) {
204
+ if (role === "notify") return "alert";
205
+ if (role === "action") return "trigger";
206
+ return "load";
207
+ }
208
+ function assembleSteps(plan) {
209
+ return [
210
+ ...plan.left.map((c) => `${c.name.toLowerCase()} extract`),
211
+ "schema map \xB7 14 fields",
212
+ ...plan.right.map((c) => `${c.name.toLowerCase()} ${stepVerb(c.role)}`)
213
+ ];
214
+ }
215
+ function buildActivity(args) {
216
+ const { phase, shown, plan, selected, status } = args;
217
+ const settled = SETTLED_PHASES.includes(phase);
218
+ const lines = [];
219
+ if (phase === "idle") {
220
+ if (!selected.length) {
221
+ lines.push({ id: "wait", text: "\u25B8 waiting for instructions\u2026", tone: "muted" });
222
+ lines.push({ id: "hint", text: "\xB7 type a request or pick apps", tone: "faint" });
223
+ }
224
+ for (const name of selected.slice(-6)) {
225
+ lines.push({ id: `sel-${name}`, text: `+ ${name.toLowerCase()} connected`, tone: "plain" });
226
+ }
227
+ return lines;
228
+ }
229
+ if (phase === "analyzing") {
230
+ for (const name of selected.slice(-4)) {
231
+ lines.push({ id: `sel-${name}`, text: `+ ${name.toLowerCase()} connected`, tone: "muted" });
232
+ }
233
+ lines.push({ id: "status", text: `\u27F3 ${status}`, tone: "active" });
234
+ return lines;
235
+ }
236
+ assembleSteps(plan).forEach((step, i) => {
237
+ if (settled || shown > i) lines.push({ id: `step-${i}`, text: `\u2713 ${step}`, tone: "done" });
238
+ else if (shown === i) lines.push({ id: `step-${i}`, text: `\u27F3 ${step}\u2026`, tone: "active" });
239
+ else lines.push({ id: `step-${i}`, text: `\xB7 ${step} queued`, tone: "muted" });
240
+ });
241
+ if (settled) lines.push({ id: "errors", text: "\u2713 error handling attached", tone: "done" });
242
+ return lines.slice(-8);
243
+ }
244
+ function slugify(value) {
245
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "your-team";
246
+ }
247
+ function isValidEmail(value) {
248
+ return /^\S+@\S+\.\S+$/.test(value.trim());
249
+ }
250
+
251
+ // src/marketing/components/BetaAccessForm/BetaAccessForm.tsx
252
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
253
+ function BetaAccessForm({
254
+ title = "Request early access",
255
+ subtitle = "CURRENTLY IN PRIVATE BETA \u2014 WE REVIEW ACCESS REQUESTS WEEKLY",
256
+ fields = "email",
257
+ appearance = "card",
258
+ teamSizes,
259
+ plans,
260
+ defaultPlan,
261
+ submitLabel = "Request access \u2192",
262
+ footnote = "NO CREDIT CARD \xB7 SSO & SELF-HOSTING AVAILABLE",
263
+ onSubmit,
264
+ successTitle = "Request received.",
265
+ successBody = "We review access requests weekly \u2014 you'll hear from us by email.",
266
+ disabled = false,
267
+ className
268
+ }) {
269
+ const uid = useId();
270
+ const [values, setValues] = useState({
271
+ email: "",
272
+ name: "",
273
+ company: "",
274
+ teamSize: "",
275
+ plan: defaultPlan ?? ""
276
+ });
277
+ const [phase, setPhase] = useState("idle");
278
+ const [error, setError] = useState(null);
279
+ const handleSubmit = async (event) => {
280
+ event.preventDefault();
281
+ if (phase === "submitting") return;
282
+ if (!isValidEmail(values.email)) {
283
+ setError("Please enter a valid work email.");
284
+ return;
285
+ }
286
+ if (fields === "full" && !values.name?.trim()) {
287
+ setError("Please enter your name.");
288
+ return;
289
+ }
290
+ if (fields === "full" && teamSizes?.length && !values.teamSize) {
291
+ setError("Please select your team size.");
292
+ return;
293
+ }
294
+ setError(null);
295
+ setPhase("submitting");
296
+ try {
297
+ await onSubmit?.(values);
298
+ setPhase("success");
299
+ } catch {
300
+ setError("Something went wrong \u2014 please try again.");
301
+ setPhase("idle");
302
+ }
303
+ };
304
+ const inline = appearance === "inline";
305
+ if (phase === "success") {
306
+ return /* @__PURE__ */ jsxs3(
307
+ "div",
308
+ {
309
+ className: cn(
310
+ "ods-mkt-access",
311
+ "ods-mkt-access--success",
312
+ inline && "ods-mkt-access--inline",
313
+ className
314
+ ),
315
+ role: "status",
316
+ children: [
317
+ /* @__PURE__ */ jsxs3("p", { className: "ods-mkt-access__success-mark", children: [
318
+ "\u2713 ",
319
+ successTitle
320
+ ] }),
321
+ /* @__PURE__ */ jsx3("p", { className: "ods-mkt-access__success-body", children: successBody })
322
+ ]
323
+ }
324
+ );
325
+ }
326
+ const busy = disabled || phase === "submitting";
327
+ return /* @__PURE__ */ jsxs3(
328
+ "form",
329
+ {
330
+ className: cn("ods-mkt-access", inline && "ods-mkt-access--inline", className),
331
+ onSubmit: handleSubmit,
332
+ noValidate: true,
333
+ children: [
334
+ /* @__PURE__ */ jsxs3("div", { className: "ods-mkt-access__head", children: [
335
+ /* @__PURE__ */ jsx3("h3", { className: "ods-mkt-access__title", children: title }),
336
+ subtitle && /* @__PURE__ */ jsx3("p", { className: "ods-mkt-access__subtitle", children: subtitle })
337
+ ] }),
338
+ /* @__PURE__ */ jsxs3(
339
+ "div",
340
+ {
341
+ className: cn(
342
+ "ods-mkt-access__fields",
343
+ fields === "full" && "ods-mkt-access__fields--full"
344
+ ),
345
+ children: [
346
+ fields === "full" && /* @__PURE__ */ jsxs3("div", { className: "ods-mkt-access__field", children: [
347
+ /* @__PURE__ */ jsx3("label", { className: "ods-mkt-access__label", htmlFor: `${uid}-name`, children: "Full name" }),
348
+ /* @__PURE__ */ jsx3(
349
+ Input,
350
+ {
351
+ id: `${uid}-name`,
352
+ autoComplete: "name",
353
+ placeholder: "Ada Lovelace",
354
+ value: values.name ?? "",
355
+ onChange: (e) => setValues((v) => ({ ...v, name: e.target.value })),
356
+ disabled: busy
357
+ }
358
+ )
359
+ ] }),
360
+ /* @__PURE__ */ jsxs3("div", { className: "ods-mkt-access__field", children: [
361
+ /* @__PURE__ */ jsx3("label", { className: "ods-mkt-access__label", htmlFor: `${uid}-email`, children: "Work email" }),
362
+ /* @__PURE__ */ jsx3(
363
+ Input,
364
+ {
365
+ id: `${uid}-email`,
366
+ type: "email",
367
+ autoComplete: "email",
368
+ placeholder: "ada@company.com",
369
+ value: values.email,
370
+ onChange: (e) => setValues((v) => ({ ...v, email: e.target.value })),
371
+ disabled: busy
372
+ }
373
+ )
374
+ ] }),
375
+ fields === "full" && /* @__PURE__ */ jsxs3("div", { className: "ods-mkt-access__field", children: [
376
+ /* @__PURE__ */ jsx3("label", { className: "ods-mkt-access__label", htmlFor: `${uid}-company`, children: "Company" }),
377
+ /* @__PURE__ */ jsx3(
378
+ Input,
379
+ {
380
+ id: `${uid}-company`,
381
+ autoComplete: "organization",
382
+ placeholder: "Acme Inc.",
383
+ value: values.company ?? "",
384
+ onChange: (e) => setValues((v) => ({ ...v, company: e.target.value })),
385
+ disabled: busy
386
+ }
387
+ )
388
+ ] }),
389
+ fields === "full" && teamSizes && teamSizes.length > 0 && /* @__PURE__ */ jsxs3("div", { className: "ods-mkt-access__field", children: [
390
+ /* @__PURE__ */ jsx3("span", { className: "ods-mkt-access__label", id: `${uid}-teamsize-label`, children: "Team size" }),
391
+ /* @__PURE__ */ jsx3(
392
+ Select,
393
+ {
394
+ "aria-labelledby": `${uid}-teamsize-label`,
395
+ placeholder: "Select team size\u2026",
396
+ options: teamSizes.map((size) => ({ value: size, label: size })),
397
+ value: values.teamSize ?? "",
398
+ onChange: (teamSize) => setValues((v) => ({ ...v, teamSize })),
399
+ disabled: busy
400
+ }
401
+ )
402
+ ] }),
403
+ fields === "full" && plans && plans.length > 0 && /* @__PURE__ */ jsxs3("div", { className: "ods-mkt-access__field", children: [
404
+ /* @__PURE__ */ jsx3("span", { className: "ods-mkt-access__label", id: `${uid}-plan-label`, children: "Plan (optional)" }),
405
+ /* @__PURE__ */ jsx3(
406
+ Select,
407
+ {
408
+ "aria-labelledby": `${uid}-plan-label`,
409
+ placeholder: "Not sure yet",
410
+ options: plans.map((plan) => ({ value: plan, label: plan })),
411
+ value: values.plan ?? "",
412
+ onChange: (plan) => setValues((v) => ({ ...v, plan })),
413
+ disabled: busy
414
+ }
415
+ )
416
+ ] }),
417
+ /* @__PURE__ */ jsx3(
418
+ Button,
419
+ {
420
+ type: "submit",
421
+ variant: "primary",
422
+ loading: phase === "submitting",
423
+ disabled,
424
+ children: submitLabel
425
+ }
426
+ )
427
+ ]
428
+ }
429
+ ),
430
+ error && /* @__PURE__ */ jsx3("p", { className: "ods-mkt-access__error", role: "alert", children: error }),
431
+ footnote && /* @__PURE__ */ jsx3("p", { className: "ods-mkt-access__footnote", children: footnote })
432
+ ]
433
+ }
434
+ );
435
+ }
436
+
437
+ // src/marketing/components/BlogGrid/BlogGrid.tsx
438
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
439
+ function BlogGrid({
440
+ posts,
441
+ columns = 3,
442
+ viewAllHref,
443
+ viewAllLabel = "View all posts \u2192",
444
+ className,
445
+ ...rest
446
+ }) {
447
+ return /* @__PURE__ */ jsxs4("div", { ...rest, className: cn("ods-mkt-blog", className), children: [
448
+ /* @__PURE__ */ jsx4("div", { className: cn("ods-mkt-blog__grid", `ods-mkt-blog__grid--${columns}`), children: posts.map((post) => /* @__PURE__ */ jsx4(
449
+ BlogCard,
450
+ {
451
+ title: post.title,
452
+ description: post.excerpt,
453
+ href: post.href,
454
+ meta: post.date,
455
+ readingTime: post.readTime,
456
+ tags: post.tags,
457
+ cover: post.cover,
458
+ author: post.author
459
+ },
460
+ post.id
461
+ )) }),
462
+ viewAllHref && /* @__PURE__ */ jsx4("div", { className: "ods-mkt-blog__more", children: /* @__PURE__ */ jsx4("a", { className: "ods-mkt-blog__more-link", href: viewAllHref, children: viewAllLabel }) })
463
+ ] });
464
+ }
465
+
466
+ // src/marketing/components/ContactForm/ContactForm.tsx
467
+ import { useId as useId2, useState as useState2 } from "react";
468
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
469
+ function ContactForm({
470
+ title = "Talk to us",
471
+ subtitle = "SALES \xB7 PARTNERSHIPS \xB7 ANYTHING ELSE \u2014 WE READ EVERYTHING",
472
+ topics,
473
+ submitLabel = "Send message \u2192",
474
+ footnote = "WE USUALLY REPLY WITHIN ONE BUSINESS DAY",
475
+ onSubmit,
476
+ successTitle = "Message sent.",
477
+ successBody = "Thanks for reaching out \u2014 we'll get back to you by email.",
478
+ disabled = false,
479
+ className
480
+ }) {
481
+ const uid = useId2();
482
+ const [values, setValues] = useState2({
483
+ name: "",
484
+ email: "",
485
+ company: "",
486
+ topic: "",
487
+ message: ""
488
+ });
489
+ const selectedTopic = topics?.find((t) => t.value === values.topic);
490
+ const [phase, setPhase] = useState2("idle");
491
+ const [error, setError] = useState2(null);
492
+ const handleSubmit = async (event) => {
493
+ event.preventDefault();
494
+ if (phase === "submitting") return;
495
+ if (!values.name.trim()) {
496
+ setError("Please enter your name.");
497
+ return;
498
+ }
499
+ if (!isValidEmail(values.email)) {
500
+ setError("Please enter a valid work email.");
501
+ return;
502
+ }
503
+ if (topics?.length && !values.topic) {
504
+ setError("Please choose a topic.");
505
+ return;
506
+ }
507
+ if (!values.message.trim()) {
508
+ setError("Please write a short message.");
509
+ return;
510
+ }
511
+ setError(null);
512
+ setPhase("submitting");
513
+ try {
514
+ await onSubmit?.(values);
515
+ setPhase("success");
516
+ } catch {
517
+ setError("Something went wrong \u2014 please try again.");
518
+ setPhase("idle");
519
+ }
520
+ };
521
+ if (phase === "success") {
522
+ return /* @__PURE__ */ jsxs5("div", { className: cn("ods-mkt-contact", "ods-mkt-contact--success", className), role: "status", children: [
523
+ /* @__PURE__ */ jsxs5("p", { className: "ods-mkt-contact__success-mark", children: [
524
+ "\u2713 ",
525
+ successTitle
526
+ ] }),
527
+ /* @__PURE__ */ jsx5("p", { className: "ods-mkt-contact__success-body", children: successBody })
528
+ ] });
529
+ }
530
+ const busy = disabled || phase === "submitting";
531
+ return /* @__PURE__ */ jsxs5("form", { className: cn("ods-mkt-contact", className), onSubmit: handleSubmit, noValidate: true, children: [
532
+ /* @__PURE__ */ jsxs5("div", { className: "ods-mkt-contact__head", children: [
533
+ /* @__PURE__ */ jsx5("h3", { className: "ods-mkt-contact__title", children: title }),
534
+ subtitle && /* @__PURE__ */ jsx5("p", { className: "ods-mkt-contact__subtitle", children: subtitle })
535
+ ] }),
536
+ /* @__PURE__ */ jsxs5("div", { className: "ods-mkt-contact__grid", children: [
537
+ /* @__PURE__ */ jsxs5("div", { className: "ods-mkt-contact__field", children: [
538
+ /* @__PURE__ */ jsx5("label", { className: "ods-mkt-contact__label", htmlFor: `${uid}-name`, children: "Full name" }),
539
+ /* @__PURE__ */ jsx5(
540
+ Input,
541
+ {
542
+ id: `${uid}-name`,
543
+ autoComplete: "name",
544
+ placeholder: "Ada Lovelace",
545
+ value: values.name,
546
+ onChange: (e) => setValues((v) => ({ ...v, name: e.target.value })),
547
+ disabled: busy
548
+ }
549
+ )
550
+ ] }),
551
+ /* @__PURE__ */ jsxs5("div", { className: "ods-mkt-contact__field", children: [
552
+ /* @__PURE__ */ jsx5("label", { className: "ods-mkt-contact__label", htmlFor: `${uid}-email`, children: "Work email" }),
553
+ /* @__PURE__ */ jsx5(
554
+ Input,
555
+ {
556
+ id: `${uid}-email`,
557
+ type: "email",
558
+ autoComplete: "email",
559
+ placeholder: "ada@company.com",
560
+ value: values.email,
561
+ onChange: (e) => setValues((v) => ({ ...v, email: e.target.value })),
562
+ disabled: busy
563
+ }
564
+ )
565
+ ] }),
566
+ /* @__PURE__ */ jsxs5("div", { className: "ods-mkt-contact__field ods-mkt-contact__field--wide", children: [
567
+ /* @__PURE__ */ jsxs5("label", { className: "ods-mkt-contact__label", htmlFor: `${uid}-company`, children: [
568
+ "Company ",
569
+ /* @__PURE__ */ jsx5("span", { className: "ods-mkt-contact__optional", children: "(optional)" })
570
+ ] }),
571
+ /* @__PURE__ */ jsx5(
572
+ Input,
573
+ {
574
+ id: `${uid}-company`,
575
+ autoComplete: "organization",
576
+ placeholder: "Acme Inc.",
577
+ value: values.company ?? "",
578
+ onChange: (e) => setValues((v) => ({ ...v, company: e.target.value })),
579
+ disabled: busy
580
+ }
581
+ )
582
+ ] }),
583
+ topics && topics.length > 0 && /* @__PURE__ */ jsxs5("div", { className: "ods-mkt-contact__field ods-mkt-contact__field--wide", children: [
584
+ /* @__PURE__ */ jsx5("span", { className: "ods-mkt-contact__label", id: `${uid}-topic-label`, children: "Topic" }),
585
+ /* @__PURE__ */ jsx5(
586
+ Select,
587
+ {
588
+ "aria-labelledby": `${uid}-topic-label`,
589
+ placeholder: "Choose a topic\u2026",
590
+ options: topics.map((t) => ({ value: t.value, label: t.label })),
591
+ value: values.topic ?? "",
592
+ onChange: (topic) => setValues((v) => ({ ...v, topic })),
593
+ disabled: busy
594
+ }
595
+ ),
596
+ selectedTopic?.hint && /* @__PURE__ */ jsx5("p", { className: "ods-mkt-contact__topic-hint", children: selectedTopic.hint })
597
+ ] }),
598
+ /* @__PURE__ */ jsxs5("div", { className: "ods-mkt-contact__field ods-mkt-contact__field--wide", children: [
599
+ /* @__PURE__ */ jsx5(
600
+ "label",
601
+ {
602
+ className: "ods-mkt-contact__label",
603
+ id: `${uid}-message-label`,
604
+ htmlFor: `${uid}-message`,
605
+ children: "Message"
606
+ }
607
+ ),
608
+ /* @__PURE__ */ jsx5(
609
+ Textarea,
610
+ {
611
+ id: `${uid}-message`,
612
+ "aria-labelledby": `${uid}-message-label`,
613
+ placeholder: "What are you trying to build?",
614
+ rows: 4,
615
+ value: values.message,
616
+ onChange: (e) => setValues((v) => ({ ...v, message: e.target.value })),
617
+ disabled: busy
618
+ }
619
+ )
620
+ ] })
621
+ ] }),
622
+ error && /* @__PURE__ */ jsx5("p", { className: "ods-mkt-contact__error", role: "alert", children: error }),
623
+ /* @__PURE__ */ jsxs5("div", { className: "ods-mkt-contact__foot", children: [
624
+ footnote && /* @__PURE__ */ jsx5("p", { className: "ods-mkt-contact__footnote", children: footnote }),
625
+ /* @__PURE__ */ jsx5(
626
+ Button,
627
+ {
628
+ type: "submit",
629
+ variant: "primary",
630
+ loading: phase === "submitting",
631
+ disabled,
632
+ children: submitLabel
633
+ }
634
+ )
635
+ ] })
636
+ ] });
637
+ }
638
+
639
+ // src/marketing/components/CtaBanner/CtaBanner.tsx
640
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
641
+ function Action({
642
+ action,
643
+ variant
644
+ }) {
645
+ if (action.href) {
646
+ return /* @__PURE__ */ jsx6(
647
+ "a",
648
+ {
649
+ className: cn("ods-mkt-cta__link", `ods-mkt-cta__link--${variant}`),
650
+ href: action.href,
651
+ onClick: action.onClick,
652
+ children: action.label
653
+ }
654
+ );
655
+ }
656
+ return /* @__PURE__ */ jsx6(Button, { variant, onClick: action.onClick, children: action.label });
657
+ }
658
+ function CtaBanner({
659
+ title,
660
+ lede,
661
+ primary,
662
+ secondary,
663
+ footnote,
664
+ className,
665
+ ...rest
666
+ }) {
667
+ return /* @__PURE__ */ jsxs6("section", { ...rest, className: cn("ods-mkt-cta", className), children: [
668
+ /* @__PURE__ */ jsx6("h2", { className: "ods-mkt-cta__title", children: title }),
669
+ lede && /* @__PURE__ */ jsx6("p", { className: "ods-mkt-cta__lede", children: lede }),
670
+ /* @__PURE__ */ jsxs6("div", { className: "ods-mkt-cta__actions", children: [
671
+ /* @__PURE__ */ jsx6(Action, { action: primary, variant: "primary" }),
672
+ secondary && /* @__PURE__ */ jsx6(Action, { action: secondary, variant: "secondary" })
673
+ ] }),
674
+ footnote && /* @__PURE__ */ jsx6("p", { className: "ods-mkt-cta__footnote", children: footnote })
675
+ ] });
676
+ }
677
+
678
+ // src/marketing/components/FaqSection/FaqSection.tsx
679
+ import { jsx as jsx7 } from "react/jsx-runtime";
680
+ function FaqSection({
681
+ items,
682
+ columns = 1,
683
+ defaultOpenIds = [],
684
+ className,
685
+ ...rest
686
+ }) {
687
+ const half = Math.ceil(items.length / 2);
688
+ const columnItems = columns === 2 ? [items.slice(0, half), items.slice(half)] : [items];
689
+ return /* @__PURE__ */ jsx7("div", { ...rest, className: cn("ods-mkt-faq", columns === 2 && "ods-mkt-faq--2", className), children: columnItems.map((column, i) => /* @__PURE__ */ jsx7(
690
+ Accordion,
691
+ {
692
+ mode: "multiple",
693
+ defaultValue: defaultOpenIds,
694
+ items: column.map((item) => ({
695
+ id: item.id,
696
+ label: item.question,
697
+ content: /* @__PURE__ */ jsx7("div", { className: "ods-mkt-faq__answer", children: item.answer })
698
+ }))
699
+ },
700
+ i
701
+ )) });
702
+ }
703
+
704
+ // src/marketing/components/FeatureGrid/FeatureGrid.tsx
705
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
706
+ function FeatureGrid({
707
+ items,
708
+ columns = 3,
709
+ dense = false,
710
+ className,
711
+ ...rest
712
+ }) {
713
+ return /* @__PURE__ */ jsx8(
714
+ "div",
715
+ {
716
+ ...rest,
717
+ className: cn(
718
+ "ods-mkt-features",
719
+ `ods-mkt-features--${columns}`,
720
+ dense && "ods-mkt-features--dense",
721
+ className
722
+ ),
723
+ children: items.map((item) => /* @__PURE__ */ jsxs7("article", { className: "ods-mkt-features__cell", children: [
724
+ item.icon && /* @__PURE__ */ jsx8("span", { className: "ods-mkt-features__icon", "aria-hidden": "true", children: item.icon }),
725
+ /* @__PURE__ */ jsx8("h3", { className: "ods-mkt-features__title", children: item.title }),
726
+ /* @__PURE__ */ jsx8("p", { className: "ods-mkt-features__body", children: item.body })
727
+ ] }, item.id))
728
+ }
729
+ );
730
+ }
731
+
732
+ // src/marketing/components/IntegrationsFinder/IntegrationsFinder.tsx
733
+ import { CheckmarkIcon, SearchIcon } from "@octaviaflow/icons";
734
+ import { useMemo, useState as useState3 } from "react";
735
+ import { Fragment, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
736
+ function LetterTile({ name }) {
737
+ return /* @__PURE__ */ jsx9("span", { className: "ods-mkt-finder__letter", "aria-hidden": "true", children: name.trim().charAt(0).toUpperCase() });
738
+ }
739
+ function IntegrationsFinder({
740
+ items,
741
+ categories,
742
+ searchPlaceholder = "Find your connector \u2014 search by name or category\u2026",
743
+ universalBadgeLabel = "Open API",
744
+ onRequestConnector,
745
+ requestErrorHint = "Couldn't send right now \u2014 please try again in a moment.",
746
+ className
747
+ }) {
748
+ const [query, setQuery] = useState3("");
749
+ const [activeCategory, setActiveCategory] = useState3(null);
750
+ const [email, setEmail] = useState3("");
751
+ const [requestState, setRequestState] = useState3("idle");
752
+ const [emailError, setEmailError] = useState3(false);
753
+ const pillCategories = useMemo(() => {
754
+ if (categories?.length) return categories;
755
+ const seen = [];
756
+ for (const item of items) {
757
+ if (!seen.includes(item.category)) seen.push(item.category);
758
+ }
759
+ return seen;
760
+ }, [categories, items]);
761
+ const counts = useMemo(() => {
762
+ const map = /* @__PURE__ */ new Map();
763
+ for (const item of items) map.set(item.category, (map.get(item.category) ?? 0) + 1);
764
+ return map;
765
+ }, [items]);
766
+ const results = useMemo(() => {
767
+ const q = query.trim().toLowerCase();
768
+ let list = items;
769
+ if (activeCategory) list = list.filter((c) => c.category === activeCategory);
770
+ if (q) {
771
+ list = list.filter(
772
+ (c) => c.name.toLowerCase().includes(q) || c.category.toLowerCase().includes(q) || c.aliases?.some((a) => a.toLowerCase().includes(q))
773
+ );
774
+ }
775
+ return [...list].sort((a, b) => {
776
+ const aKind = a.kind ?? "native";
777
+ const bKind = b.kind ?? "native";
778
+ if (aKind !== bKind) return aKind === "native" ? -1 : 1;
779
+ return a.name.localeCompare(b.name);
780
+ });
781
+ }, [items, query, activeCategory]);
782
+ const handleRequest = async (event) => {
783
+ event.preventDefault();
784
+ if (!onRequestConnector || requestState === "sending") return;
785
+ if (!isValidEmail(email)) {
786
+ setEmailError(true);
787
+ return;
788
+ }
789
+ setEmailError(false);
790
+ setRequestState("sending");
791
+ try {
792
+ await onRequestConnector({ query: query.trim(), email });
793
+ setRequestState("sent");
794
+ } catch {
795
+ setRequestState("error");
796
+ }
797
+ };
798
+ return /* @__PURE__ */ jsxs8("div", { className: cn("ods-mkt-finder", className), children: [
799
+ /* @__PURE__ */ jsx9("div", { className: "ods-mkt-finder__search", children: /* @__PURE__ */ jsx9(
800
+ Input,
801
+ {
802
+ type: "search",
803
+ "aria-label": "Search connectors",
804
+ placeholder: searchPlaceholder,
805
+ leftIcon: /* @__PURE__ */ jsx9(SearchIcon, { size: "sm" }),
806
+ value: query,
807
+ onChange: (e) => {
808
+ setQuery(e.target.value);
809
+ setRequestState("idle");
810
+ }
811
+ }
812
+ ) }),
813
+ /* @__PURE__ */ jsxs8("fieldset", { className: "ods-mkt-finder__pills", "aria-label": "Connector categories", children: [
814
+ /* @__PURE__ */ jsxs8(
815
+ "button",
816
+ {
817
+ type: "button",
818
+ className: cn(
819
+ "ods-mkt-finder__pill",
820
+ activeCategory === null && "ods-mkt-finder__pill--active"
821
+ ),
822
+ onClick: () => setActiveCategory(null),
823
+ children: [
824
+ "All ",
825
+ /* @__PURE__ */ jsx9("span", { className: "ods-mkt-finder__count", children: items.length })
826
+ ]
827
+ }
828
+ ),
829
+ pillCategories.map((category) => /* @__PURE__ */ jsxs8(
830
+ "button",
831
+ {
832
+ type: "button",
833
+ className: cn(
834
+ "ods-mkt-finder__pill",
835
+ activeCategory === category && "ods-mkt-finder__pill--active"
836
+ ),
837
+ onClick: () => setActiveCategory(activeCategory === category ? null : category),
838
+ children: [
839
+ category,
840
+ " ",
841
+ /* @__PURE__ */ jsx9("span", { className: "ods-mkt-finder__count", children: counts.get(category) ?? 0 })
842
+ ]
843
+ },
844
+ category
845
+ ))
846
+ ] }),
847
+ results.length > 0 ? /* @__PURE__ */ jsx9("div", { className: "ods-mkt-finder__grid", children: results.map((item) => /* @__PURE__ */ jsxs8("div", { className: "ods-mkt-finder__card", children: [
848
+ /* @__PURE__ */ jsx9("span", { className: "ods-mkt-finder__card-icon", "aria-hidden": "true", children: item.icon ?? /* @__PURE__ */ jsx9(LetterTile, { name: item.name }) }),
849
+ /* @__PURE__ */ jsx9("span", { className: "ods-mkt-finder__card-name", children: item.name }),
850
+ (item.kind ?? "native") === "universal" && /* @__PURE__ */ jsx9("span", { className: "ods-mkt-finder__badge", children: universalBadgeLabel })
851
+ ] }, item.name)) }) : /* @__PURE__ */ jsx9("div", { className: "ods-mkt-finder__miss", children: requestState === "sent" ? /* @__PURE__ */ jsxs8("p", { className: "ods-mkt-finder__sent", role: "status", children: [
852
+ /* @__PURE__ */ jsx9(CheckmarkIcon, { size: "sm", "aria-hidden": "true" }),
853
+ " Got it \u2014 we'll let you know when a",
854
+ " ",
855
+ /* @__PURE__ */ jsx9("strong", { children: query.trim() }),
856
+ " connector is available."
857
+ ] }) : /* @__PURE__ */ jsxs8(Fragment, { children: [
858
+ /* @__PURE__ */ jsxs8("h3", { className: "ods-mkt-finder__miss-title", children: [
859
+ "No native ",
860
+ /* @__PURE__ */ jsx9("strong", { children: query.trim() }),
861
+ " connector yet"
862
+ ] }),
863
+ /* @__PURE__ */ jsxs8("p", { className: "ods-mkt-finder__miss-body", children: [
864
+ "Our universal open connectors likely cover it today \u2014 and we build native connectors on request. ",
865
+ onRequestConnector && "Leave your email and we'll notify you."
866
+ ] }),
867
+ onRequestConnector && /* @__PURE__ */ jsxs8("form", { className: "ods-mkt-finder__miss-form", onSubmit: handleRequest, noValidate: true, children: [
868
+ /* @__PURE__ */ jsx9(
869
+ Input,
870
+ {
871
+ type: "email",
872
+ "aria-label": "Work email for connector request",
873
+ placeholder: "you@company.com",
874
+ value: email,
875
+ error: emailError,
876
+ errorMessage: emailError ? "Please enter a valid work email." : void 0,
877
+ onChange: (e) => {
878
+ setEmail(e.target.value);
879
+ setEmailError(false);
880
+ }
881
+ }
882
+ ),
883
+ /* @__PURE__ */ jsx9(Button, { type: "submit", variant: "primary", loading: requestState === "sending", children: "Request connector" })
884
+ ] }),
885
+ requestState === "error" && /* @__PURE__ */ jsx9("p", { className: "ods-mkt-finder__miss-error", role: "alert", children: requestErrorHint })
886
+ ] }) })
887
+ ] });
888
+ }
889
+
890
+ // src/marketing/components/IntegrationsWall/IntegrationsWall.tsx
891
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
892
+ function IntegrationsWall({
893
+ categories,
894
+ footnote,
895
+ columns = 3,
896
+ className,
897
+ ...rest
898
+ }) {
899
+ return /* @__PURE__ */ jsxs9("div", { ...rest, className: cn("ods-mkt-wall", className), children: [
900
+ /* @__PURE__ */ jsx10("div", { className: cn("ods-mkt-wall__grid", `ods-mkt-wall__grid--${columns}`), children: categories.map((category) => /* @__PURE__ */ jsxs9("div", { className: "ods-mkt-wall__card", children: [
901
+ /* @__PURE__ */ jsxs9("div", { className: "ods-mkt-wall__card-head", children: [
902
+ category.icon && /* @__PURE__ */ jsx10("span", { className: "ods-mkt-wall__card-icon", "aria-hidden": "true", children: category.icon }),
903
+ /* @__PURE__ */ jsx10("h3", { className: "ods-mkt-wall__card-label", children: category.label })
904
+ ] }),
905
+ /* @__PURE__ */ jsx10("div", { className: "ods-mkt-wall__pills", children: category.items.map((item) => /* @__PURE__ */ jsxs9("span", { className: "ods-mkt-wall__pill", children: [
906
+ item.icon && /* @__PURE__ */ jsx10("span", { className: "ods-mkt-wall__pill-icon", "aria-hidden": "true", children: item.icon }),
907
+ item.name
908
+ ] }, item.name)) })
909
+ ] }, category.id)) }),
910
+ footnote && /* @__PURE__ */ jsx10("p", { className: "ods-mkt-wall__footnote", children: footnote })
911
+ ] });
912
+ }
913
+
914
+ // src/marketing/components/LiveConsole/LiveConsole.tsx
915
+ import { CheckmarkIcon as CheckmarkIcon2, CloseIcon } from "@octaviaflow/icons";
916
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
917
+ function PendingGlyph() {
918
+ return /* @__PURE__ */ jsx11(
919
+ "svg",
920
+ {
921
+ viewBox: "0 0 24 24",
922
+ width: "13",
923
+ height: "13",
924
+ fill: "none",
925
+ stroke: "currentColor",
926
+ strokeWidth: "2.4",
927
+ strokeLinecap: "round",
928
+ strokeDasharray: "3.5 3.5",
929
+ "aria-hidden": "true",
930
+ children: /* @__PURE__ */ jsx11("circle", { cx: "12", cy: "12", r: "9" })
931
+ }
932
+ );
933
+ }
934
+ function StateGlyph({ state }) {
935
+ switch (state) {
936
+ case "done":
937
+ return /* @__PURE__ */ jsx11(CheckmarkIcon2, { size: "sm", "aria-hidden": "true" });
938
+ case "running":
939
+ return /* @__PURE__ */ jsx11(Spinner, { size: "sm" });
940
+ case "error":
941
+ return /* @__PURE__ */ jsx11(CloseIcon, { size: "sm", "aria-hidden": "true" });
942
+ case "queued":
943
+ return /* @__PURE__ */ jsx11(PendingGlyph, {});
944
+ }
945
+ }
946
+ function LiveConsole({
947
+ title,
948
+ badge = "LIVE",
949
+ lines,
950
+ animated = true,
951
+ className,
952
+ ...rest
953
+ }) {
954
+ return /* @__PURE__ */ jsxs10("div", { ...rest, className: cn("ods-mkt-console", className), children: [
955
+ /* @__PURE__ */ jsxs10("div", { className: "ods-mkt-console__head", children: [
956
+ /* @__PURE__ */ jsx11("span", { className: "ods-mkt-console__title", children: title }),
957
+ badge != null && /* @__PURE__ */ jsxs10("span", { className: "ods-mkt-console__badge", children: [
958
+ /* @__PURE__ */ jsx11("span", { className: "ods-mkt-console__dot" }),
959
+ badge
960
+ ] })
961
+ ] }),
962
+ /* @__PURE__ */ jsx11("div", { className: "ods-mkt-console__body", children: lines.map((line, i) => {
963
+ const state = line.state ?? "done";
964
+ return /* @__PURE__ */ jsxs10(
965
+ "div",
966
+ {
967
+ className: cn("ods-mkt-console__line", animated && "ods-mkt-console__line--animated"),
968
+ style: animated ? { animationDelay: `${0.3 + i * 0.6}s` } : void 0,
969
+ children: [
970
+ /* @__PURE__ */ jsx11(
971
+ "span",
972
+ {
973
+ className: cn("ods-mkt-console__glyph", `ods-mkt-console__glyph--${state}`),
974
+ "aria-hidden": "true",
975
+ children: /* @__PURE__ */ jsx11(StateGlyph, { state })
976
+ }
977
+ ),
978
+ /* @__PURE__ */ jsxs10("span", { className: "ods-mkt-console__text", children: [
979
+ /* @__PURE__ */ jsx11("span", { className: "ods-mkt-console__label", children: line.label }),
980
+ line.detail && /* @__PURE__ */ jsxs10(
981
+ "span",
982
+ {
983
+ className: cn(
984
+ "ods-mkt-console__detail",
985
+ state === "running" && "ods-mkt-console__detail--running",
986
+ state === "error" && "ods-mkt-console__detail--error"
987
+ ),
988
+ children: [
989
+ " ",
990
+ line.detail
991
+ ]
992
+ }
993
+ )
994
+ ] })
995
+ ]
996
+ },
997
+ line.id
998
+ );
999
+ }) })
1000
+ ] });
1001
+ }
1002
+
1003
+ // src/marketing/components/LogoMarquee/LogoMarquee.tsx
1004
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1005
+ function Track({ items, hidden }) {
1006
+ return /* @__PURE__ */ jsx12("div", { className: "ods-mkt-marquee__track", "aria-hidden": hidden || void 0, children: items.map((item) => /* @__PURE__ */ jsx12("span", { className: "ods-mkt-marquee__logo", title: item.label, children: item.icon ?? /* @__PURE__ */ jsx12("span", { className: "ods-mkt-marquee__wordmark", children: item.label }) }, item.id)) });
1007
+ }
1008
+ function LogoMarquee({
1009
+ items,
1010
+ label,
1011
+ speed = 30,
1012
+ grayscale = true,
1013
+ className,
1014
+ ...rest
1015
+ }) {
1016
+ return /* @__PURE__ */ jsxs11(
1017
+ "div",
1018
+ {
1019
+ ...rest,
1020
+ className: cn("ods-mkt-marquee", grayscale && "ods-mkt-marquee--gray", className),
1021
+ children: [
1022
+ label && /* @__PURE__ */ jsx12("p", { className: "ods-mkt-marquee__label", children: label }),
1023
+ /* @__PURE__ */ jsx12("div", { className: "ods-mkt-marquee__viewport", children: /* @__PURE__ */ jsxs11("div", { className: "ods-mkt-marquee__rail", style: { animationDuration: `${speed}s` }, children: [
1024
+ /* @__PURE__ */ jsx12(Track, { items }),
1025
+ /* @__PURE__ */ jsx12(Track, { items, hidden: true })
1026
+ ] }) })
1027
+ ]
1028
+ }
1029
+ );
1030
+ }
1031
+
1032
+ // src/marketing/glyphs.tsx
1033
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1034
+ var base = {
1035
+ xmlns: "http://www.w3.org/2000/svg",
1036
+ viewBox: "0 0 24 24",
1037
+ fill: "none",
1038
+ stroke: "currentColor",
1039
+ strokeWidth: 2,
1040
+ strokeLinecap: "round",
1041
+ strokeLinejoin: "round"
1042
+ };
1043
+ function SourceGlyph({ size = 12 }) {
1044
+ return /* @__PURE__ */ jsxs12("svg", { ...base, width: size, height: size, "aria-hidden": "true", children: [
1045
+ /* @__PURE__ */ jsx13("ellipse", { cx: "12", cy: "5", rx: "9", ry: "3" }),
1046
+ /* @__PURE__ */ jsx13("path", { d: "M3 5v14a9 3 0 0 0 18 0V5" }),
1047
+ /* @__PURE__ */ jsx13("path", { d: "M3 12a9 3 0 0 0 18 0" })
1048
+ ] });
1049
+ }
1050
+ function DestinationGlyph({ size = 12 }) {
1051
+ return /* @__PURE__ */ jsxs12("svg", { ...base, width: size, height: size, "aria-hidden": "true", children: [
1052
+ /* @__PURE__ */ jsx13("rect", { x: "2", y: "3", width: "20", height: "5", rx: "1" }),
1053
+ /* @__PURE__ */ jsx13("path", { d: "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8" }),
1054
+ /* @__PURE__ */ jsx13("path", { d: "M10 12h4" })
1055
+ ] });
1056
+ }
1057
+ function ActionGlyph({ size = 12 }) {
1058
+ return /* @__PURE__ */ jsx13("svg", { ...base, width: size, height: size, "aria-hidden": "true", children: /* @__PURE__ */ jsx13("path", { d: "M13 2 3 14h9l-1 8 10-12h-9l1-8z" }) });
1059
+ }
1060
+ function NotifyGlyph({ size = 12 }) {
1061
+ return /* @__PURE__ */ jsx13("svg", { ...base, width: size, height: size, "aria-hidden": "true", children: /* @__PURE__ */ jsx13("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
1062
+ }
1063
+ function ConnectorGlyph({ size = 12 }) {
1064
+ return /* @__PURE__ */ jsxs12("svg", { ...base, width: size, height: size, "aria-hidden": "true", children: [
1065
+ /* @__PURE__ */ jsx13("path", { d: "M12 22v-5" }),
1066
+ /* @__PURE__ */ jsx13("path", { d: "M9 8V2M15 8V2" }),
1067
+ /* @__PURE__ */ jsx13("path", { d: "M18 8v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8h12z" })
1068
+ ] });
1069
+ }
1070
+ function BrandMark({ size = 18 }) {
1071
+ return /* @__PURE__ */ jsxs12("svg", { viewBox: "0 0 18 18", width: size, height: size, "aria-hidden": "true", children: [
1072
+ /* @__PURE__ */ jsx13("rect", { width: "18", height: "18", fill: "var(--ods-accent)" }),
1073
+ /* @__PURE__ */ jsx13("path", { d: "M4 9h8.5M9.5 5.5 13 9l-3.5 3.5", stroke: "#fff", strokeWidth: "1.6", fill: "none" })
1074
+ ] });
1075
+ }
1076
+ function roleGlyph(role, size = 12) {
1077
+ switch (role) {
1078
+ case "source":
1079
+ return /* @__PURE__ */ jsx13(SourceGlyph, { size });
1080
+ case "destination":
1081
+ return /* @__PURE__ */ jsx13(DestinationGlyph, { size });
1082
+ case "action":
1083
+ return /* @__PURE__ */ jsx13(ActionGlyph, { size });
1084
+ case "notify":
1085
+ return /* @__PURE__ */ jsx13(NotifyGlyph, { size });
1086
+ }
1087
+ }
1088
+
1089
+ // src/marketing/components/MarketingFooter/MarketingFooter.tsx
1090
+ import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1091
+ function MarketingFooter({
1092
+ brand,
1093
+ tagline,
1094
+ meta,
1095
+ columns = [],
1096
+ newsletter,
1097
+ legal,
1098
+ social,
1099
+ className,
1100
+ ...rest
1101
+ }) {
1102
+ return /* @__PURE__ */ jsxs13("footer", { ...rest, className: cn("ods-mkt-footer", className), children: [
1103
+ /* @__PURE__ */ jsxs13("div", { className: "ods-mkt-footer__grid", children: [
1104
+ /* @__PURE__ */ jsxs13("div", { className: "ods-mkt-footer__brand-col", children: [
1105
+ /* @__PURE__ */ jsx14("div", { className: "ods-mkt-footer__brand", children: brand ?? /* @__PURE__ */ jsxs13(Fragment2, { children: [
1106
+ /* @__PURE__ */ jsx14(BrandMark, { size: 16 }),
1107
+ /* @__PURE__ */ jsx14("span", { children: "OctaviaFlow" })
1108
+ ] }) }),
1109
+ tagline && /* @__PURE__ */ jsx14("p", { className: "ods-mkt-footer__tagline", children: tagline }),
1110
+ meta && /* @__PURE__ */ jsx14("div", { className: "ods-mkt-footer__meta", children: meta }),
1111
+ newsletter && /* @__PURE__ */ jsx14("div", { className: "ods-mkt-footer__newsletter", children: newsletter })
1112
+ ] }),
1113
+ columns.map((column) => /* @__PURE__ */ jsxs13("nav", { className: "ods-mkt-footer__col", "aria-label": String(column.id), children: [
1114
+ /* @__PURE__ */ jsx14("span", { className: "ods-mkt-footer__col-label", children: column.label }),
1115
+ column.links.map((link) => /* @__PURE__ */ jsx14("a", { className: "ods-mkt-footer__link", href: link.href, children: link.label }, link.href))
1116
+ ] }, column.id))
1117
+ ] }),
1118
+ (legal || social) && /* @__PURE__ */ jsxs13("div", { className: "ods-mkt-footer__bar", children: [
1119
+ /* @__PURE__ */ jsx14("span", { children: legal }),
1120
+ /* @__PURE__ */ jsx14("span", { children: social })
1121
+ ] })
1122
+ ] });
1123
+ }
1124
+
1125
+ // src/marketing/components/MarketingHero/MarketingHero.tsx
1126
+ import { motion, useReducedMotion } from "framer-motion";
1127
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
1128
+ function MarketingHero({
1129
+ kicker,
1130
+ title,
1131
+ lede,
1132
+ align = "center",
1133
+ className,
1134
+ children,
1135
+ ...rest
1136
+ }) {
1137
+ const reducedMotion = useReducedMotion();
1138
+ const words = title.split(/\s+/).filter(Boolean);
1139
+ return /* @__PURE__ */ jsxs14(
1140
+ "section",
1141
+ {
1142
+ ...rest,
1143
+ className: cn("ods-mkt-hero", align === "center" && "ods-mkt-hero--center", className),
1144
+ children: [
1145
+ kicker && /* @__PURE__ */ jsx15("p", { className: "ods-mkt-hero__kicker", children: kicker }),
1146
+ /* @__PURE__ */ jsx15("h1", { className: "ods-mkt-hero__title", children: words.map((word, i) => /* @__PURE__ */ jsxs14(
1147
+ "span",
1148
+ {
1149
+ className: "ods-mkt-hero__word-clip",
1150
+ children: [
1151
+ /* @__PURE__ */ jsx15(
1152
+ motion.span,
1153
+ {
1154
+ className: "ods-mkt-hero__word",
1155
+ initial: reducedMotion ? false : { opacity: 0, y: "100%" },
1156
+ animate: { opacity: 1, y: 0 },
1157
+ transition: {
1158
+ duration: 0.7,
1159
+ delay: 0.05 + i * 0.08,
1160
+ ease: [0.2, 0.7, 0.2, 1]
1161
+ },
1162
+ children: word
1163
+ }
1164
+ ),
1165
+ " "
1166
+ ]
1167
+ },
1168
+ i
1169
+ )) }),
1170
+ lede && /* @__PURE__ */ jsx15(
1171
+ motion.p,
1172
+ {
1173
+ className: "ods-mkt-hero__lede",
1174
+ initial: reducedMotion ? false : { opacity: 0, y: 12 },
1175
+ animate: { opacity: 1, y: 0 },
1176
+ transition: { duration: 0.8, delay: 0.6, ease: [0.2, 0.7, 0.2, 1] },
1177
+ children: lede
1178
+ }
1179
+ ),
1180
+ children && /* @__PURE__ */ jsx15(
1181
+ motion.div,
1182
+ {
1183
+ className: "ods-mkt-hero__body",
1184
+ initial: reducedMotion ? false : { opacity: 0, y: 12 },
1185
+ animate: { opacity: 1, y: 0 },
1186
+ transition: { duration: 0.8, delay: 0.75, ease: [0.2, 0.7, 0.2, 1] },
1187
+ children
1188
+ }
1189
+ )
1190
+ ]
1191
+ }
1192
+ );
1193
+ }
1194
+
1195
+ // src/marketing/components/MarketingNav/MarketingNav.tsx
1196
+ import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
1197
+ function MarketingNav({
1198
+ brand,
1199
+ brandHref = "/",
1200
+ links = [],
1201
+ actions,
1202
+ sticky = true,
1203
+ className,
1204
+ ...rest
1205
+ }) {
1206
+ return /* @__PURE__ */ jsxs15("header", { ...rest, className: cn("ods-mkt-nav", sticky && "ods-mkt-nav--sticky", className), children: [
1207
+ /* @__PURE__ */ jsx16("a", { className: "ods-mkt-nav__brand", href: brandHref, children: brand ?? /* @__PURE__ */ jsxs15(Fragment3, { children: [
1208
+ /* @__PURE__ */ jsx16(BrandMark, {}),
1209
+ /* @__PURE__ */ jsx16("span", { children: "OctaviaFlow" })
1210
+ ] }) }),
1211
+ links.length > 0 && /* @__PURE__ */ jsx16("nav", { className: "ods-mkt-nav__links", "aria-label": "Main", children: links.map((link) => /* @__PURE__ */ jsx16(
1212
+ "a",
1213
+ {
1214
+ href: link.href,
1215
+ className: cn("ods-mkt-nav__link", link.active && "ods-mkt-nav__link--active"),
1216
+ "aria-current": link.active ? "page" : void 0,
1217
+ children: link.label
1218
+ },
1219
+ link.href
1220
+ )) }),
1221
+ actions && /* @__PURE__ */ jsx16("div", { className: "ods-mkt-nav__actions", children: actions })
1222
+ ] });
1223
+ }
1224
+
1225
+ // src/marketing/components/MarketingSection/MarketingSection.tsx
1226
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
1227
+ function MarketingSection({
1228
+ kicker,
1229
+ title,
1230
+ lede,
1231
+ align = "start",
1232
+ tone = "default",
1233
+ flushTop = false,
1234
+ className,
1235
+ children,
1236
+ ...rest
1237
+ }) {
1238
+ return /* @__PURE__ */ jsxs16(
1239
+ "section",
1240
+ {
1241
+ ...rest,
1242
+ className: cn(
1243
+ "ods-mkt-section",
1244
+ align === "center" && "ods-mkt-section--center",
1245
+ tone === "subtle" && "ods-mkt-section--subtle",
1246
+ flushTop && "ods-mkt-section--flush",
1247
+ className
1248
+ ),
1249
+ children: [
1250
+ (kicker || title || lede) && /* @__PURE__ */ jsxs16("header", { className: "ods-mkt-section__head", children: [
1251
+ kicker && /* @__PURE__ */ jsx17("p", { className: "ods-mkt-section__kicker", children: kicker }),
1252
+ title && /* @__PURE__ */ jsx17("h2", { className: "ods-mkt-section__title", children: title }),
1253
+ lede && /* @__PURE__ */ jsx17("p", { className: "ods-mkt-section__lede", children: lede })
1254
+ ] }),
1255
+ children
1256
+ ]
1257
+ }
1258
+ );
1259
+ }
1260
+
1261
+ // src/marketing/components/PageHero/PageHero.tsx
1262
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
1263
+ function PageHero({
1264
+ kicker,
1265
+ title,
1266
+ subtitle,
1267
+ actions,
1268
+ align = "center",
1269
+ className,
1270
+ ...rest
1271
+ }) {
1272
+ return /* @__PURE__ */ jsxs17(
1273
+ "header",
1274
+ {
1275
+ ...rest,
1276
+ className: cn("ods-mkt-pagehero", align === "start" && "ods-mkt-pagehero--start", className),
1277
+ children: [
1278
+ kicker && /* @__PURE__ */ jsx18("span", { className: "ods-mkt-pagehero__kicker", children: kicker }),
1279
+ /* @__PURE__ */ jsx18("h1", { className: "ods-mkt-pagehero__title", children: title }),
1280
+ subtitle && /* @__PURE__ */ jsx18("p", { className: "ods-mkt-pagehero__subtitle", children: subtitle }),
1281
+ actions && /* @__PURE__ */ jsx18("div", { className: "ods-mkt-pagehero__actions", children: actions })
1282
+ ]
1283
+ }
1284
+ );
1285
+ }
1286
+
1287
+ // src/marketing/components/PricingTiers/PricingTiers.tsx
1288
+ import { CheckmarkIcon as CheckmarkIcon3 } from "@octaviaflow/icons";
1289
+ import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
1290
+ function TierCta({ cta, featured }) {
1291
+ if (cta.href) {
1292
+ return /* @__PURE__ */ jsx19(
1293
+ "a",
1294
+ {
1295
+ className: cn(
1296
+ "ods-mkt-pricing__cta",
1297
+ featured ? "ods-mkt-pricing__cta--primary" : "ods-mkt-pricing__cta--secondary"
1298
+ ),
1299
+ href: cta.href,
1300
+ onClick: cta.onClick,
1301
+ children: cta.label
1302
+ }
1303
+ );
1304
+ }
1305
+ return /* @__PURE__ */ jsx19(Button, { variant: featured ? "primary" : "secondary", fullWidth: true, onClick: cta.onClick, children: cta.label });
1306
+ }
1307
+ function PricingTiers({ tiers, note, className, ...rest }) {
1308
+ return /* @__PURE__ */ jsxs18("div", { ...rest, className: cn("ods-mkt-pricing", className), children: [
1309
+ /* @__PURE__ */ jsx19("div", { className: "ods-mkt-pricing__grid", children: tiers.map((tier) => /* @__PURE__ */ jsxs18(
1310
+ "article",
1311
+ {
1312
+ className: cn(
1313
+ "ods-mkt-pricing__card",
1314
+ tier.featured && "ods-mkt-pricing__card--featured"
1315
+ ),
1316
+ children: [
1317
+ tier.featured && /* @__PURE__ */ jsx19("span", { className: "ods-mkt-pricing__badge", children: tier.badge ?? "Recommended" }),
1318
+ /* @__PURE__ */ jsx19("h3", { className: "ods-mkt-pricing__name", children: tier.name }),
1319
+ /* @__PURE__ */ jsxs18("div", { className: "ods-mkt-pricing__price-row", children: [
1320
+ /* @__PURE__ */ jsx19("span", { className: "ods-mkt-pricing__price", children: tier.price }),
1321
+ tier.period && /* @__PURE__ */ jsx19("span", { className: "ods-mkt-pricing__period", children: tier.period })
1322
+ ] }),
1323
+ tier.annualNote && /* @__PURE__ */ jsx19("span", { className: "ods-mkt-pricing__annual", children: tier.annualNote }),
1324
+ tier.description && /* @__PURE__ */ jsx19("p", { className: "ods-mkt-pricing__desc", children: tier.description }),
1325
+ /* @__PURE__ */ jsx19("ul", { className: "ods-mkt-pricing__features", children: tier.features.map((feature, i) => (
1326
+ // biome-ignore lint/suspicious/noArrayIndexKey: features are positional copy
1327
+ /* @__PURE__ */ jsxs18("li", { className: "ods-mkt-pricing__feature", children: [
1328
+ /* @__PURE__ */ jsx19(CheckmarkIcon3, { size: "sm", "aria-hidden": "true" }),
1329
+ /* @__PURE__ */ jsx19("span", { children: feature })
1330
+ ] }, i)
1331
+ )) }),
1332
+ /* @__PURE__ */ jsx19(TierCta, { cta: tier.cta, featured: Boolean(tier.featured) })
1333
+ ]
1334
+ },
1335
+ tier.id
1336
+ )) }),
1337
+ note && /* @__PURE__ */ jsx19("p", { className: "ods-mkt-pricing__note", children: note })
1338
+ ] });
1339
+ }
1340
+
1341
+ // src/marketing/components/StatBand/StatBand.tsx
1342
+ import { useReducedMotion as useReducedMotion2 } from "framer-motion";
1343
+ import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
1344
+ function StatBand({ items, orientation = "column", className, ...rest }) {
1345
+ const reducedMotion = useReducedMotion2();
1346
+ return /* @__PURE__ */ jsx20(
1347
+ "div",
1348
+ {
1349
+ ...rest,
1350
+ className: cn("ods-mkt-statband", `ods-mkt-statband--${orientation}`, className),
1351
+ children: items.map((item) => /* @__PURE__ */ jsxs19("div", { className: "ods-mkt-statband__item", children: [
1352
+ /* @__PURE__ */ jsx20("div", { className: "ods-mkt-statband__value", children: typeof item.value === "number" ? /* @__PURE__ */ jsx20(
1353
+ CountUp,
1354
+ {
1355
+ value: item.value,
1356
+ duration: 900,
1357
+ disableAnimation: Boolean(reducedMotion),
1358
+ prefix: item.prefix,
1359
+ suffix: item.suffix,
1360
+ formatValue: (v) => Math.round(v).toLocaleString("en-US")
1361
+ }
1362
+ ) : /* @__PURE__ */ jsxs19(Fragment4, { children: [
1363
+ item.prefix,
1364
+ item.value,
1365
+ item.suffix
1366
+ ] }) }),
1367
+ /* @__PURE__ */ jsx20("div", { className: "ods-mkt-statband__label", children: item.label })
1368
+ ] }, item.id))
1369
+ }
1370
+ );
1371
+ }
1372
+
1373
+ // src/marketing/components/TestimonialStrip/TestimonialStrip.tsx
1374
+ import { jsx as jsx21 } from "react/jsx-runtime";
1375
+ function TestimonialStrip({
1376
+ items,
1377
+ columns = 3,
1378
+ className,
1379
+ ...rest
1380
+ }) {
1381
+ return /* @__PURE__ */ jsx21(
1382
+ "div",
1383
+ {
1384
+ ...rest,
1385
+ className: cn("ods-mkt-testimonials", `ods-mkt-testimonials--${columns}`, className),
1386
+ children: items.map((item) => /* @__PURE__ */ jsx21(
1387
+ TestimonialCard,
1388
+ {
1389
+ quote: item.quote,
1390
+ author: item.author,
1391
+ rating: item.rating,
1392
+ logo: item.logo
1393
+ },
1394
+ item.id
1395
+ ))
1396
+ }
1397
+ );
1398
+ }
1399
+
1400
+ // src/marketing/components/WorkflowShowcase/WorkflowShowcase.tsx
1401
+ import { AnimatePresence as AnimatePresence2, motion as motion3, useReducedMotion as useReducedMotion4 } from "framer-motion";
1402
+ import {
1403
+ useCallback,
1404
+ useEffect as useEffect2,
1405
+ useMemo as useMemo2,
1406
+ useRef as useRef2,
1407
+ useState as useState6
1408
+ } from "react";
1409
+
1410
+ // src/marketing/components/WorkflowShowcase/ShowcaseScene.tsx
1411
+ import { useEffect, useRef, useState as useState4 } from "react";
1412
+ import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
1413
+ function slots(n) {
1414
+ return Array.from({ length: n }, (_, i) => 208 + (i - (n - 1) / 2) * 80);
1415
+ }
1416
+ var LANES = [228, 190, 266, 152, 304];
1417
+ var laneFor = (index) => LANES[index % LANES.length];
1418
+ var leftGuide = (cy, lane) => `M74 ${cy} H150 V${lane} H193`;
1419
+ var rightGuide = (cy, lane) => `M263 ${lane} H340 V${cy} H388`;
1420
+ function particlesFor(side, index, path, active, fast) {
1421
+ const base2 = index * 0.4 + (side === "r" ? 0.5 : 0);
1422
+ const duration = fast ? active ? "1.1s" : "2.6s" : active ? "2.2s" : "4.8s";
1423
+ const size = active ? 8 : 6;
1424
+ const out = [
1425
+ { key: `${side}${index}-a`, path, size, duration, delay: `${base2}s`, variant: "lead" },
1426
+ {
1427
+ key: `${side}${index}-b`,
1428
+ path,
1429
+ size,
1430
+ duration,
1431
+ delay: `${base2 + (active ? 1.1 : 2.4)}s`,
1432
+ variant: "echo"
1433
+ }
1434
+ ];
1435
+ if (active) {
1436
+ out.push({
1437
+ key: `${side}${index}-c`,
1438
+ path,
1439
+ size: 6,
1440
+ duration,
1441
+ delay: `${base2 + 0.55}s`,
1442
+ variant: "spark"
1443
+ });
1444
+ }
1445
+ return out;
1446
+ }
1447
+ function DefaultCoreGlyph() {
1448
+ return /* @__PURE__ */ jsxs20("svg", { viewBox: "0 0 24 24", width: "30", height: "30", fill: "none", "aria-hidden": "true", children: [
1449
+ /* @__PURE__ */ jsx22("rect", { x: "3", y: "3", width: "18", height: "18", rx: "1", stroke: "currentColor", strokeWidth: "1.6" }),
1450
+ /* @__PURE__ */ jsx22(
1451
+ "path",
1452
+ {
1453
+ d: "M7 12h7M11.5 8.5 15 12l-3.5 3.5",
1454
+ stroke: "currentColor",
1455
+ strokeWidth: "1.6",
1456
+ strokeLinecap: "round",
1457
+ strokeLinejoin: "round"
1458
+ }
1459
+ )
1460
+ ] });
1461
+ }
1462
+ function CubeFace({ connector }) {
1463
+ return /* @__PURE__ */ jsx22(
1464
+ "span",
1465
+ {
1466
+ className: cn(
1467
+ "ods-showcase__apptile",
1468
+ "ods-showcase__apptile--lg",
1469
+ `ods-showcase__apptile--${connector.role}`
1470
+ ),
1471
+ children: connector.icon ?? roleGlyph(connector.role, 18)
1472
+ }
1473
+ );
1474
+ }
1475
+ function ShowcaseScene({
1476
+ left,
1477
+ right,
1478
+ engaged,
1479
+ tiles,
1480
+ coreIcon,
1481
+ caption,
1482
+ onCoreClick
1483
+ }) {
1484
+ const [pulse, setPulse] = useState4(false);
1485
+ const pulseTimer = useRef(null);
1486
+ useEffect(
1487
+ () => () => {
1488
+ if (pulseTimer.current) clearTimeout(pulseTimer.current);
1489
+ },
1490
+ []
1491
+ );
1492
+ const firePulse = () => {
1493
+ if (pulse) return;
1494
+ setPulse(true);
1495
+ pulseTimer.current = setTimeout(() => setPulse(false), 1500);
1496
+ };
1497
+ const leftYs = slots(left.length);
1498
+ const rightYs = slots(right.length);
1499
+ const guides = [];
1500
+ const particles = [];
1501
+ const bypassFor = (index) => index % 2 === 0 ? 188 : 268;
1502
+ left.forEach((node, i) => {
1503
+ const on = engaged && node.active;
1504
+ const laneIn = laneFor(i);
1505
+ const bypass = bypassFor(i);
1506
+ let d;
1507
+ if (right.length) {
1508
+ const pairIdx = i % right.length;
1509
+ const laneOut = laneFor(i + 1);
1510
+ d = `M74 ${leftYs[i]} H150 V${laneIn} H186 V${bypass} H270 V${laneOut} H340 V${rightYs[pairIdx]} H388`;
1511
+ } else {
1512
+ d = `M74 ${leftYs[i]} H150 V${laneIn} H186 V${bypass} H${210 + i % 3 * 40} V372`;
1513
+ }
1514
+ guides.push({ d, on, delay: `${i * 0.2}s` });
1515
+ particles.push(...particlesFor("l", i, d, on, pulse));
1516
+ });
1517
+ right.forEach((node, j) => {
1518
+ if (left.length > 0 && j < left.length) return;
1519
+ const d = rightGuide(rightYs[j], laneFor(j + 1));
1520
+ const on = engaged && node.active;
1521
+ guides.push({ d, on, delay: `${j * 0.2 + 0.3}s` });
1522
+ particles.push(...particlesFor("r", j, d, on, pulse));
1523
+ });
1524
+ if (!left.length) guides.push({ d: leftGuide(208, 228), on: false, delay: "0s" });
1525
+ if (!right.length) guides.push({ d: rightGuide(208, 228), on: false, delay: "0s" });
1526
+ const pins = [];
1527
+ const pads = [];
1528
+ for (let x = 118; x <= 338; x += 20) {
1529
+ const south = x / 20 % 4 === 0;
1530
+ const north = x / 20 % 4 === 2;
1531
+ pins.push({ d: `M${x} 346 L${x} 366`, accent: south });
1532
+ pads.push({ x, y: 369, accent: south });
1533
+ pins.push({ d: `M${x} 110 L${x} 90`, accent: north });
1534
+ pads.push({ x, y: 87, accent: north });
1535
+ }
1536
+ for (let y = 118; y <= 338; y += 20) {
1537
+ const east = y / 20 % 4 === 1;
1538
+ const west = y / 20 % 4 === 3;
1539
+ pins.push({ d: `M346 ${y} L366 ${y}`, accent: east });
1540
+ pads.push({ x: 369, y, accent: east });
1541
+ pins.push({ d: `M110 ${y} L90 ${y}`, accent: west });
1542
+ pads.push({ x: 87, y, accent: west });
1543
+ }
1544
+ const tilePositions = [
1545
+ { left: 8, top: 8 },
1546
+ { left: 83, top: 8 },
1547
+ { left: 158, top: 8 },
1548
+ { left: 8, top: 83 },
1549
+ { left: 158, top: 83 },
1550
+ { left: 8, top: 158 },
1551
+ { left: 83, top: 158 },
1552
+ { left: 158, top: 158 }
1553
+ ];
1554
+ return /* @__PURE__ */ jsxs20("div", { className: "ods-showcase__scene", "aria-hidden": "true", children: [
1555
+ /* @__PURE__ */ jsxs20("div", { className: "ods-showcase__scene-stage", children: [
1556
+ /* @__PURE__ */ jsxs20("svg", { className: "ods-showcase__wires", width: "460", height: "460", "aria-hidden": "true", children: [
1557
+ pins.map((pin) => /* @__PURE__ */ jsx22(
1558
+ "path",
1559
+ {
1560
+ d: pin.d,
1561
+ className: cn("ods-showcase__pin", pin.accent && "ods-showcase__pin--accent")
1562
+ },
1563
+ pin.d
1564
+ )),
1565
+ pads.map((pad) => /* @__PURE__ */ jsx22(
1566
+ "rect",
1567
+ {
1568
+ x: pad.x - 2,
1569
+ y: pad.y - 2,
1570
+ width: 4,
1571
+ height: 4,
1572
+ className: cn("ods-showcase__pin-pad", pad.accent && "ods-showcase__pin-pad--accent")
1573
+ },
1574
+ `${pad.x}-${pad.y}`
1575
+ )),
1576
+ guides.map((guide) => /* @__PURE__ */ jsxs20("g", { children: [
1577
+ /* @__PURE__ */ jsx22("path", { d: guide.d, className: "ods-showcase__guide" }),
1578
+ /* @__PURE__ */ jsx22(
1579
+ "path",
1580
+ {
1581
+ d: guide.d,
1582
+ className: cn(
1583
+ "ods-showcase__guide-trace",
1584
+ guide.on && "ods-showcase__guide-trace--on"
1585
+ ),
1586
+ style: { animationDelay: guide.delay }
1587
+ }
1588
+ )
1589
+ ] }, guide.d))
1590
+ ] }),
1591
+ particles.map((p) => /* @__PURE__ */ jsx22(
1592
+ "span",
1593
+ {
1594
+ className: cn("ods-showcase__particle", `ods-showcase__particle--${p.variant}`),
1595
+ style: {
1596
+ width: p.size,
1597
+ height: p.size,
1598
+ offsetPath: `path('${p.path}')`,
1599
+ animationDuration: p.duration,
1600
+ animationDelay: p.delay
1601
+ }
1602
+ },
1603
+ p.key
1604
+ )),
1605
+ /* @__PURE__ */ jsxs20("div", { className: "ods-showcase__platform", children: [
1606
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__platform-south" }),
1607
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__platform-east" }),
1608
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__platform-top" }),
1609
+ tiles.slice(0, 8).map((label, i) => /* @__PURE__ */ jsxs20(
1610
+ "span",
1611
+ {
1612
+ className: "ods-showcase__tile",
1613
+ style: { left: tilePositions[i].left, top: tilePositions[i].top },
1614
+ children: [
1615
+ /* @__PURE__ */ jsxs20("span", { className: "ods-showcase__tile-flip", children: [
1616
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__tile-wall ods-showcase__tile-wall--south" }),
1617
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__tile-wall ods-showcase__tile-wall--east" })
1618
+ ] }),
1619
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__tile-wall ods-showcase__tile-wall--south" }),
1620
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__tile-wall ods-showcase__tile-wall--east" }),
1621
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__tile-face", children: label })
1622
+ ]
1623
+ },
1624
+ label
1625
+ )),
1626
+ pulse && /* @__PURE__ */ jsx22("span", { className: "ods-showcase__core-ring" }),
1627
+ /* @__PURE__ */ jsxs20(
1628
+ "button",
1629
+ {
1630
+ type: "button",
1631
+ tabIndex: -1,
1632
+ className: "ods-showcase__core",
1633
+ onClick: () => {
1634
+ firePulse();
1635
+ onCoreClick?.();
1636
+ },
1637
+ children: [
1638
+ /* @__PURE__ */ jsxs20("span", { className: "ods-showcase__core-flip", children: [
1639
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__core-wall ods-showcase__core-wall--south ods-showcase__core-wall--back" }),
1640
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__core-wall ods-showcase__core-wall--east ods-showcase__core-wall--back" })
1641
+ ] }),
1642
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__core-wall ods-showcase__core-wall--south" }),
1643
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__core-wall ods-showcase__core-wall--east" }),
1644
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__core-top", children: coreIcon ?? /* @__PURE__ */ jsx22(DefaultCoreGlyph, {}) })
1645
+ ]
1646
+ }
1647
+ )
1648
+ ] }),
1649
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__floater ods-showcase__floater--a" }),
1650
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__floater ods-showcase__floater--b" }),
1651
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__floater ods-showcase__floater--c" }),
1652
+ !left.length && /* @__PURE__ */ jsx22("span", { className: "ods-showcase__ghost", style: { left: 8, top: 178 }, children: "+" }),
1653
+ !right.length && /* @__PURE__ */ jsx22("span", { className: "ods-showcase__ghost", style: { left: 392, top: 178 }, children: "+" }),
1654
+ left.map((node, i) => /* @__PURE__ */ jsx22(
1655
+ "span",
1656
+ {
1657
+ className: "ods-showcase__cube-slot",
1658
+ style: { left: 8, top: leftYs[i] - 30 },
1659
+ children: /* @__PURE__ */ jsxs20(
1660
+ "span",
1661
+ {
1662
+ className: cn(
1663
+ "ods-showcase__cube",
1664
+ node.active && "ods-showcase__cube--active",
1665
+ i % 2 ? "ods-showcase__cube--float-b" : "ods-showcase__cube--float-a"
1666
+ ),
1667
+ style: { animationDelay: `${i * 0.15}s` },
1668
+ children: [
1669
+ /* @__PURE__ */ jsxs20("span", { className: "ods-showcase__cube-flip", children: [
1670
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__cube-south ods-showcase__cube-wall--back" }),
1671
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__cube-east ods-showcase__cube-wall--back" })
1672
+ ] }),
1673
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__cube-south" }),
1674
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__cube-east" }),
1675
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__cube-top", children: /* @__PURE__ */ jsx22(CubeFace, { connector: node.connector }) })
1676
+ ]
1677
+ }
1678
+ )
1679
+ },
1680
+ node.connector.name
1681
+ )),
1682
+ right.map((node, j) => /* @__PURE__ */ jsx22(
1683
+ "span",
1684
+ {
1685
+ className: "ods-showcase__cube-slot",
1686
+ style: { left: 392, top: rightYs[j] - 30 },
1687
+ children: /* @__PURE__ */ jsxs20(
1688
+ "span",
1689
+ {
1690
+ className: cn(
1691
+ "ods-showcase__cube",
1692
+ node.active && "ods-showcase__cube--active",
1693
+ j % 2 ? "ods-showcase__cube--float-a" : "ods-showcase__cube--float-b"
1694
+ ),
1695
+ style: { animationDelay: `${j * 0.15}s` },
1696
+ children: [
1697
+ /* @__PURE__ */ jsxs20("span", { className: "ods-showcase__cube-flip", children: [
1698
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__cube-south ods-showcase__cube-wall--back" }),
1699
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__cube-east ods-showcase__cube-wall--back" })
1700
+ ] }),
1701
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__cube-south" }),
1702
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__cube-east" }),
1703
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__cube-top", children: /* @__PURE__ */ jsx22(CubeFace, { connector: node.connector }) })
1704
+ ]
1705
+ }
1706
+ )
1707
+ },
1708
+ node.connector.name
1709
+ ))
1710
+ ] }),
1711
+ /* @__PURE__ */ jsx22("span", { className: "ods-showcase__scene-caption", children: caption })
1712
+ ] });
1713
+ }
1714
+
1715
+ // src/marketing/components/WorkflowShowcase/ShowcaseSignup.tsx
1716
+ import { AnimatePresence, motion as motion2, useReducedMotion as useReducedMotion3 } from "framer-motion";
1717
+ import { useId as useId3, useState as useState5 } from "react";
1718
+ import { FocusScope } from "react-aria";
1719
+ import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
1720
+ var OVERLAY_MOTION = {
1721
+ initial: { opacity: 0 },
1722
+ animate: { opacity: 1 },
1723
+ exit: { opacity: 0 }
1724
+ };
1725
+ function ShowcaseSignup({
1726
+ phase,
1727
+ stepCount,
1728
+ workspaceDomain,
1729
+ teamSizes,
1730
+ error,
1731
+ onSubmit,
1732
+ onBack,
1733
+ dashboardHref = "#",
1734
+ onboardingHref = "#"
1735
+ }) {
1736
+ const reducedMotion = useReducedMotion3();
1737
+ const titleId = useId3();
1738
+ const subtitleId = useId3();
1739
+ const [values, setValues] = useState5({
1740
+ name: "",
1741
+ email: "",
1742
+ company: "",
1743
+ teamSize: teamSizes[0] ?? "1\u201310"
1744
+ });
1745
+ const open = phase === "signup" || phase === "creating" || phase === "welcome";
1746
+ const cardMotion = reducedMotion ? OVERLAY_MOTION : {
1747
+ initial: { opacity: 0, y: 14, scale: 0.985 },
1748
+ animate: { opacity: 1, y: 0, scale: 1 },
1749
+ exit: { opacity: 0, y: 8, scale: 0.99 }
1750
+ };
1751
+ const handleSubmit = (event) => {
1752
+ event.preventDefault();
1753
+ onSubmit(values);
1754
+ };
1755
+ const firstName = values.name.trim().split(/\s+/)[0] || "";
1756
+ const emailShown = values.email.trim() || "your inbox";
1757
+ const slug = `${slugify(values.company)}.${workspaceDomain}`;
1758
+ return /* @__PURE__ */ jsx23(AnimatePresence, { children: open && /* @__PURE__ */ jsx23(
1759
+ motion2.div,
1760
+ {
1761
+ className: "ods-showcase__veil",
1762
+ ...OVERLAY_MOTION,
1763
+ transition: { duration: reducedMotion ? 0 : 0.22 },
1764
+ children: /* @__PURE__ */ jsxs21(FocusScope, { contain: true, restoreFocus: true, autoFocus: true, children: [
1765
+ phase === "signup" && /* @__PURE__ */ jsxs21(
1766
+ motion2.form,
1767
+ {
1768
+ className: "ods-showcase__glass-card",
1769
+ role: "dialog",
1770
+ "aria-modal": "true",
1771
+ "aria-labelledby": titleId,
1772
+ "aria-describedby": subtitleId,
1773
+ onSubmit: handleSubmit,
1774
+ onKeyDown: (e) => {
1775
+ if (e.key === "Escape") onBack();
1776
+ },
1777
+ ...cardMotion,
1778
+ transition: { duration: reducedMotion ? 0 : 0.3, ease: [0.2, 0.7, 0.2, 1] },
1779
+ children: [
1780
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__glass-head", children: [
1781
+ /* @__PURE__ */ jsx23("h3", { id: titleId, className: "ods-showcase__glass-title", children: "Create your workspace" }),
1782
+ /* @__PURE__ */ jsxs21("p", { id: subtitleId, className: "ods-showcase__microcopy", children: [
1783
+ "FREE IN PRIVATE BETA \xB7 YOUR ",
1784
+ stepCount,
1785
+ "-STEP WORKFLOW COMES WITH YOU"
1786
+ ] })
1787
+ ] }),
1788
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__form-grid", children: [
1789
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__field", children: [
1790
+ /* @__PURE__ */ jsx23("span", { className: "ods-showcase__field-label", children: "FULL NAME" }),
1791
+ /* @__PURE__ */ jsx23(
1792
+ Input,
1793
+ {
1794
+ "aria-label": "Full name",
1795
+ autoComplete: "name",
1796
+ placeholder: "Ada Lovelace",
1797
+ value: values.name,
1798
+ onChange: (e) => setValues((v) => ({ ...v, name: e.target.value }))
1799
+ }
1800
+ )
1801
+ ] }),
1802
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__field", children: [
1803
+ /* @__PURE__ */ jsx23("span", { className: "ods-showcase__field-label", children: "WORK EMAIL" }),
1804
+ /* @__PURE__ */ jsx23(
1805
+ Input,
1806
+ {
1807
+ "aria-label": "Work email",
1808
+ type: "email",
1809
+ autoComplete: "email",
1810
+ placeholder: "ada@company.com",
1811
+ value: values.email,
1812
+ onChange: (e) => setValues((v) => ({ ...v, email: e.target.value }))
1813
+ }
1814
+ )
1815
+ ] }),
1816
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__field", children: [
1817
+ /* @__PURE__ */ jsx23("span", { className: "ods-showcase__field-label", children: "COMPANY" }),
1818
+ /* @__PURE__ */ jsx23(
1819
+ Input,
1820
+ {
1821
+ "aria-label": "Company",
1822
+ autoComplete: "organization",
1823
+ placeholder: "Acme Inc.",
1824
+ value: values.company,
1825
+ onChange: (e) => setValues((v) => ({ ...v, company: e.target.value }))
1826
+ }
1827
+ )
1828
+ ] }),
1829
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__field", children: [
1830
+ /* @__PURE__ */ jsx23("span", { className: "ods-showcase__field-label", children: "TEAM SIZE" }),
1831
+ /* @__PURE__ */ jsx23(
1832
+ Select,
1833
+ {
1834
+ "aria-label": "Team size",
1835
+ options: teamSizes.map((size) => ({ value: size, label: size })),
1836
+ value: values.teamSize,
1837
+ onChange: (teamSize) => setValues((v) => ({ ...v, teamSize }))
1838
+ }
1839
+ )
1840
+ ] })
1841
+ ] }),
1842
+ error && /* @__PURE__ */ jsx23("p", { className: "ods-showcase__form-error", role: "alert", children: error }),
1843
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__glass-foot", children: [
1844
+ /* @__PURE__ */ jsx23("span", { className: "ods-showcase__microcopy", children: "NO CREDIT CARD \xB7 SSO & SELF-HOSTING LATER" }),
1845
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__glass-actions", children: [
1846
+ /* @__PURE__ */ jsx23(Button, { type: "button", variant: "secondary", onClick: onBack, children: "Back" }),
1847
+ /* @__PURE__ */ jsx23(Button, { type: "submit", variant: "primary", children: "Create account & deploy \u2192" })
1848
+ ] })
1849
+ ] })
1850
+ ]
1851
+ },
1852
+ "signup"
1853
+ ),
1854
+ phase === "creating" && /* @__PURE__ */ jsxs21(
1855
+ motion2.div,
1856
+ {
1857
+ className: "ods-showcase__glass-card ods-showcase__glass-card--slim",
1858
+ role: "status",
1859
+ ...cardMotion,
1860
+ transition: { duration: reducedMotion ? 0 : 0.25 },
1861
+ children: [
1862
+ /* @__PURE__ */ jsx23("span", { className: "ods-showcase__spin", "aria-hidden": "true", children: "\u27F3" }),
1863
+ /* @__PURE__ */ jsxs21("span", { className: "ods-showcase__creating-line", children: [
1864
+ "provisioning workspace \xB7 saving draft \xB7 inviting ",
1865
+ emailShown
1866
+ ] })
1867
+ ]
1868
+ },
1869
+ "creating"
1870
+ ),
1871
+ phase === "welcome" && /* @__PURE__ */ jsxs21(
1872
+ motion2.div,
1873
+ {
1874
+ className: "ods-showcase__glass-card ods-showcase__glass-card--welcome",
1875
+ role: "dialog",
1876
+ "aria-modal": "true",
1877
+ "aria-labelledby": titleId,
1878
+ ...cardMotion,
1879
+ transition: { duration: reducedMotion ? 0 : 0.3, ease: [0.2, 0.7, 0.2, 1] },
1880
+ children: [
1881
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__glass-head", children: [
1882
+ /* @__PURE__ */ jsx23("p", { className: "ods-showcase__microcopy ods-showcase__microcopy--success", children: "\u2713 WORKSPACE READY" }),
1883
+ /* @__PURE__ */ jsxs21("h3", { id: titleId, className: "ods-showcase__glass-title", children: [
1884
+ "Welcome to OctaviaFlow",
1885
+ firstName ? `, ${firstName}` : "",
1886
+ "."
1887
+ ] }),
1888
+ /* @__PURE__ */ jsxs21("p", { className: "ods-showcase__welcome-body", children: [
1889
+ "We emailed a sign-in link to ",
1890
+ /* @__PURE__ */ jsx23("strong", { children: emailShown }),
1891
+ ". Your ",
1892
+ stepCount,
1893
+ "-step workflow is saved as a draft in",
1894
+ " ",
1895
+ /* @__PURE__ */ jsx23("code", { className: "ods-showcase__slug", children: slug }),
1896
+ " \u2014 deploy it from the dashboard whenever you're ready."
1897
+ ] })
1898
+ ] }),
1899
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__glass-foot", children: [
1900
+ /* @__PURE__ */ jsxs21("div", { className: "ods-showcase__glass-actions", children: [
1901
+ /* @__PURE__ */ jsx23("a", { className: "ods-showcase__solid-link", href: dashboardHref, children: "Open dashboard \u2192" }),
1902
+ /* @__PURE__ */ jsx23("a", { className: "ods-showcase__text-link", href: onboardingHref, children: "Book onboarding \u2192" })
1903
+ ] }),
1904
+ /* @__PURE__ */ jsxs21("span", { className: "ods-showcase__microcopy ods-showcase__microcopy--right", children: [
1905
+ "PRIVATE BETA",
1906
+ /* @__PURE__ */ jsx23("br", {}),
1907
+ "ONBOARDING INCLUDED"
1908
+ ] })
1909
+ ] })
1910
+ ]
1911
+ },
1912
+ "welcome"
1913
+ )
1914
+ ] })
1915
+ }
1916
+ ) });
1917
+ }
1918
+
1919
+ // src/marketing/components/WorkflowShowcase/WorkflowShowcase.tsx
1920
+ import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
1921
+ var EMPTY_PLAN = { left: [], right: [], all: [], totalSteps: 1 };
1922
+ function ConnectorTile({ connector }) {
1923
+ return /* @__PURE__ */ jsx24(
1924
+ "span",
1925
+ {
1926
+ "aria-hidden": "true",
1927
+ className: cn("ods-showcase__apptile", `ods-showcase__apptile--${connector.role}`),
1928
+ children: connector.icon ?? roleGlyph(connector.role)
1929
+ }
1930
+ );
1931
+ }
1932
+ function WorkflowShowcase({
1933
+ connectors = WORKFLOW_SHOWCASE_DEFAULT_CONNECTORS,
1934
+ examples = WORKFLOW_SHOWCASE_DEFAULT_EXAMPLES,
1935
+ metrics = WORKFLOW_SHOWCASE_DEFAULT_METRICS,
1936
+ defaultPrompt = "",
1937
+ rotatePrompts = true,
1938
+ modelLabel = "octavia-core-1",
1939
+ canvasLabel = "workflow_canvas",
1940
+ railLabel = "OCTAVIA IS DOING",
1941
+ platformTiles = WORKFLOW_SHOWCASE_DEFAULT_TILES,
1942
+ coreIcon,
1943
+ catalogNote = "600+",
1944
+ teamSizes = ["1\u201310", "11\u201350", "51\u2013200", "200+"],
1945
+ workspaceDomain = "octaviaflow.com",
1946
+ dashboardHref,
1947
+ onboardingHref = "#",
1948
+ promptAriaLabel = "Describe your pipeline",
1949
+ onBuild,
1950
+ onPhaseChange,
1951
+ onSignup,
1952
+ className,
1953
+ ...rest
1954
+ }) {
1955
+ const reducedMotion = useReducedMotion4();
1956
+ const rotationActive = rotatePrompts && !defaultPrompt && examples.length > 0;
1957
+ const [prompt, setPrompt] = useState6(
1958
+ defaultPrompt || (rotationActive ? examples[0]?.prompt ?? "" : "")
1959
+ );
1960
+ const [engagedWithPrompt, setEngagedWithPrompt] = useState6(false);
1961
+ const [promptHovered, setPromptHovered] = useState6(false);
1962
+ const [promptFocused, setPromptFocused] = useState6(false);
1963
+ const rotateIdx = useRef2(0);
1964
+ const [selected, setSelected] = useState6([]);
1965
+ const [phase, setPhase] = useState6("idle");
1966
+ const [shown, setShown] = useState6(0);
1967
+ const [status, setStatus] = useState6("");
1968
+ const [pickerOpen, setPickerOpen] = useState6(false);
1969
+ const [schedIdx, setSchedIdx] = useState6(0);
1970
+ const [swap, setSwap] = useState6(null);
1971
+ const [signupError, setSignupError] = useState6(null);
1972
+ const signupReturnPhase = useRef2("done");
1973
+ const cardRef = useRef2(null);
1974
+ const timers = useRef2([]);
1975
+ const clearTimers = useCallback(() => {
1976
+ for (const t of timers.current) clearTimeout(t);
1977
+ timers.current = [];
1978
+ }, []);
1979
+ useEffect2(() => clearTimers, [clearTimers]);
1980
+ const tempo = reducedMotion ? 0.35 : 1;
1981
+ const at = useCallback(
1982
+ (ms, fn) => {
1983
+ timers.current.push(setTimeout(fn, ms * tempo));
1984
+ },
1985
+ [tempo]
1986
+ );
1987
+ const firstPhase = useRef2(true);
1988
+ useEffect2(() => {
1989
+ if (firstPhase.current) {
1990
+ firstPhase.current = false;
1991
+ return;
1992
+ }
1993
+ onPhaseChange?.(phase);
1994
+ }, [phase, onPhaseChange]);
1995
+ const phaseRef = useRef2(phase);
1996
+ phaseRef.current = phase;
1997
+ const byName = useMemo2(() => new Map(connectors.map((c) => [c.name, c])), [connectors]);
1998
+ const detected = useMemo2(() => detectConnectors(prompt, connectors), [prompt, connectors]);
1999
+ const union = useMemo2(() => [.../* @__PURE__ */ new Set([...selected, ...detected])], [selected, detected]);
2000
+ const settled = SETTLED_PHASES.includes(phase);
2001
+ const engaged = phase !== "idle";
2002
+ const buildingNow = phase === "analyzing" || phase === "building";
2003
+ const plan = useMemo2(() => {
2004
+ if (!selected.length) return EMPTY_PLAN;
2005
+ return resolvePlan(selected, [], connectors);
2006
+ }, [selected, connectors]);
2007
+ const schedules = WORKFLOW_SHOWCASE_SCHEDULES;
2008
+ const inferredSchedule = scheduleFromPrompt(prompt);
2009
+ const manualSchedule = schedules[schedIdx];
2010
+ const scheduleShown = inferredSchedule ?? (manualSchedule === "AUTO" ? "HOURLY" : manualSchedule);
2011
+ const triggers = WORKFLOW_SHOWCASE_TRIGGERS;
2012
+ const [triggerIdx, setTriggerIdx] = useState6(0);
2013
+ const manualTrigger = triggers[triggerIdx];
2014
+ const cadenceShown = manualTrigger === "SCHEDULE" ? scheduleShown : manualTrigger;
2015
+ useEffect2(() => {
2016
+ if (!rotationActive || engagedWithPrompt || promptHovered || promptFocused || phase !== "idle") {
2017
+ return;
2018
+ }
2019
+ const timer = setInterval(() => {
2020
+ rotateIdx.current = (rotateIdx.current + 1) % examples.length;
2021
+ setPrompt(examples[rotateIdx.current].prompt);
2022
+ }, 4200);
2023
+ return () => clearInterval(timer);
2024
+ }, [rotationActive, engagedWithPrompt, promptHovered, promptFocused, phase, examples]);
2025
+ const startBuild = useCallback(
2026
+ (text, baseSelected) => {
2027
+ if (phaseRef.current === "analyzing" || phaseRef.current === "building") return;
2028
+ phaseRef.current = "analyzing";
2029
+ clearTimers();
2030
+ const resolved = resolvePlan(baseSelected, detectConnectors(text, connectors), connectors);
2031
+ const target = resolved.all.map((c) => c.name);
2032
+ const additions = target.filter((n) => !baseSelected.includes(n));
2033
+ setPrompt(text);
2034
+ setSelected(baseSelected);
2035
+ setPhase("analyzing");
2036
+ setShown(0);
2037
+ setStatus("analyzing request \xB7 matching connectors");
2038
+ setPickerOpen(false);
2039
+ setSwap(null);
2040
+ onBuild?.({
2041
+ prompt: text,
2042
+ connectors: target,
2043
+ schedule: scheduleShown,
2044
+ trigger: manualTrigger
2045
+ });
2046
+ additions.forEach((name, i) => {
2047
+ at(250 + i * 200, () => setSelected((s) => s.includes(name) ? s : [...s, name]));
2048
+ });
2049
+ const t0 = 250 + additions.length * 200;
2050
+ at(t0 + 750, () => setStatus("wiring transforms \xB7 adding error handling"));
2051
+ at(t0 + 1500, () => {
2052
+ setPhase("building");
2053
+ setStatus("assembling workflow \xB7 optimizing plan");
2054
+ });
2055
+ for (let i = 0; i < resolved.totalSteps; i++) {
2056
+ at(t0 + 1600 + i * 380, () => setShown(i + 1));
2057
+ }
2058
+ at(t0 + 1600 + resolved.totalSteps * 380 + 350, () => setPhase("done"));
2059
+ },
2060
+ [clearTimers, connectors, onBuild, scheduleShown, manualTrigger, at]
2061
+ );
2062
+ const resetToIdle = useCallback(() => {
2063
+ clearTimers();
2064
+ phaseRef.current = "idle";
2065
+ setPhase("idle");
2066
+ setShown(0);
2067
+ setStatus("");
2068
+ setSwap(null);
2069
+ }, [clearTimers]);
2070
+ const toggleConnector = (name) => {
2071
+ resetToIdle();
2072
+ setSelected((s) => s.includes(name) ? s.filter((n) => n !== name) : [...s, name]);
2073
+ };
2074
+ const runExample = (example) => {
2075
+ resetToIdle();
2076
+ startBuild(example.prompt, []);
2077
+ };
2078
+ const openSwap = (name, text, anchor) => {
2079
+ const card = cardRef.current;
2080
+ if (!card) return;
2081
+ const r = anchor.getBoundingClientRect();
2082
+ const cr = card.getBoundingClientRect();
2083
+ const x = Math.max(8, Math.min(r.left - cr.left, cr.width - 264));
2084
+ setSwap({ name, text, x, y: r.bottom - cr.top + 6 });
2085
+ };
2086
+ const doSwap = (current, next) => {
2087
+ resetToIdle();
2088
+ const re = new RegExp(current.text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "i");
2089
+ setPrompt((p) => p.replace(re, next));
2090
+ setSelected((s) => s.map((n) => n === current.name ? next : n));
2091
+ };
2092
+ const swapRole = swap ? byName.get(swap.name)?.role : void 0;
2093
+ const swapItems = swapRole ? connectors.filter((c) => c.role === swapRole) : [];
2094
+ const roles = union.map((n) => byName.get(n)?.role);
2095
+ const hasSource = roles.includes("source");
2096
+ const hasSink = roles.some((r) => r && r !== "source");
2097
+ const hasNotify = roles.includes("notify");
2098
+ let coachLine;
2099
+ let coachAdds = [];
2100
+ const notIn = (c) => !union.includes(c.name);
2101
+ if (!union.length) {
2102
+ coachLine = prompt ? "LISTENING\u2026 CONNECTOR NAMES LIGHT UP AS OCTAVIA RECOGNIZES THEM" : `OCTAVIA MATCHES CONNECTORS LIVE AS YOU TYPE \u2014 OR PICK FROM ${catalogNote}`;
2103
+ } else if (union.length >= connectors.length) {
2104
+ coachLine = "FULL STACK \u2014 OCTAVIA SPLITS THIS INTO PARALLEL INGEST \u2192 AI TRANSFORM \u2192 SEQUENCED ACTIONS";
2105
+ } else if (union.length >= 6) {
2106
+ coachLine = `BIG STACK \u2014 ${union.length} CONNECTORS FAN OUT ACROSS PARALLEL BRANCHES \xB7 COST OPTIMIZER ON`;
2107
+ } else if (hasSource && !hasSink) {
2108
+ coachLine = "SOURCES WIRED \u2014 WHERE SHOULD THE DATA LAND?";
2109
+ coachAdds = connectors.filter((c) => c.role === "destination" && notIn(c)).slice(0, 2);
2110
+ } else if (!hasSource && hasSink) {
2111
+ coachLine = "DESTINATION SET \u2014 WHAT SHOULD OCTAVIA PULL FROM?";
2112
+ coachAdds = connectors.filter((c) => c.role === "source" && notIn(c)).slice(0, 2);
2113
+ } else if (!hasNotify) {
2114
+ coachLine = `\u2713 ${union.length} CONNECTORS \xB7 ${cadenceShown} \xB7 TIP: ALERT YOUR TEAM WHEN RUNS FINISH`;
2115
+ coachAdds = connectors.filter((c) => c.role === "notify" && notIn(c)).slice(0, 1);
2116
+ } else {
2117
+ coachLine = `\u2713 ${union.length} CONNECTORS \xB7 ${cadenceShown} \xB7 CLICK A HIGHLIGHTED NAME TO SWAP IT`;
2118
+ }
2119
+ const coachTone = union.length ? hasSource && hasSink ? "success" : "accent" : "muted";
2120
+ const badge = settled ? { label: "LIVE", tone: "success", pulse: true } : buildingNow ? {
2121
+ label: phase === "analyzing" ? "ANALYZING" : "BUILDING",
2122
+ tone: "accent",
2123
+ pulse: true
2124
+ } : { label: "IDLE", tone: "muted", pulse: false };
2125
+ const canvasSub = settled ? "production" : buildingNow ? "generating" : "draft";
2126
+ const sceneCaption = settled ? "PIPELINE LIVE \xB7 SQUARES = ROWS IN FLIGHT" : phase === "building" ? "ASSEMBLING WORKFLOW\u2026" : phase === "analyzing" ? "ANALYZING REQUEST\u2026" : "CLICK THE CORE \xB7 CONNECTORS LAND AS CUBES";
2127
+ const activity = buildActivity({ phase, shown, plan, selected, status });
2128
+ const costMetric = metrics.find((m) => m.tone === "success");
2129
+ const costLabel = costMetric ? `${costMetric.prefix ?? ""}${costMetric.value}${costMetric.suffix ?? ""}` : "";
2130
+ const railFoot = phase === "idle" ? `${catalogNote} CONNECTORS \xB7 FREE IN PRIVATE BETA` : settled ? `COST PLAN SELECTED \xB7 ${costLabel} SAVED` : "COST OPTIMIZER RUNNING\u2026";
2131
+ const nLeft = plan.left.length;
2132
+ const sceneLeft = plan.left.map((c, i) => ({
2133
+ connector: c,
2134
+ active: engaged && (settled || shown > i)
2135
+ }));
2136
+ const sceneRight = plan.right.map((c, j) => ({
2137
+ connector: c,
2138
+ active: engaged && (settled || shown > nLeft + 1 + j)
2139
+ }));
2140
+ const stepCount = (selected.length || 3) + 1;
2141
+ const doneNote = costMetric ? `${stepCount}-step workflow generated \xB7 cost optimizer: ${costMetric.value}% below baseline` : `${stepCount}-step workflow generated`;
2142
+ const submitSignup = (values) => {
2143
+ if (!values.name.trim() || !isValidEmail(values.email)) {
2144
+ setSignupError("Please enter your name and a valid work email.");
2145
+ return;
2146
+ }
2147
+ setSignupError(null);
2148
+ setPhase("creating");
2149
+ const finish = () => setPhase("welcome");
2150
+ const fail = () => {
2151
+ setSignupError("Something went wrong \u2014 please try again.");
2152
+ setPhase("signup");
2153
+ };
2154
+ if (!onSignup) {
2155
+ at(1600, finish);
2156
+ return;
2157
+ }
2158
+ try {
2159
+ const result = onSignup(values);
2160
+ if (result && typeof result.then === "function") {
2161
+ result.then(finish, fail);
2162
+ } else {
2163
+ finish();
2164
+ }
2165
+ } catch {
2166
+ fail();
2167
+ }
2168
+ };
2169
+ const segments = segmentPrompt(prompt, connectors);
2170
+ const onPromptKeyDown = (e) => {
2171
+ if (e.key === "Enter" && !e.shiftKey) {
2172
+ e.preventDefault();
2173
+ startBuild(prompt, selected);
2174
+ }
2175
+ };
2176
+ const rise = (delay = 0) => reducedMotion ? {} : {
2177
+ initial: { opacity: 0, y: 10 },
2178
+ animate: { opacity: 1, y: 0 },
2179
+ transition: { duration: 0.4, delay, ease: [0.2, 0.7, 0.2, 1] }
2180
+ };
2181
+ return /* @__PURE__ */ jsxs22("section", { ...rest, className: cn("ods-showcase", className), children: [
2182
+ /* @__PURE__ */ jsxs22(
2183
+ "div",
2184
+ {
2185
+ ref: cardRef,
2186
+ className: "ods-showcase__card",
2187
+ onMouseEnter: () => setPromptHovered(true),
2188
+ onMouseLeave: () => setPromptHovered(false),
2189
+ children: [
2190
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__prompt", children: [
2191
+ /* @__PURE__ */ jsx24(
2192
+ "textarea",
2193
+ {
2194
+ className: "ods-showcase__prompt-input",
2195
+ value: prompt,
2196
+ onChange: (e) => {
2197
+ setEngagedWithPrompt(true);
2198
+ setPrompt(e.target.value);
2199
+ },
2200
+ onKeyDown: onPromptKeyDown,
2201
+ onFocus: () => setPromptFocused(true),
2202
+ onBlur: () => setPromptFocused(false),
2203
+ "aria-label": promptAriaLabel,
2204
+ spellCheck: false,
2205
+ rows: 2
2206
+ }
2207
+ ),
2208
+ /* @__PURE__ */ jsx24("div", { className: "ods-showcase__prompt-render", "aria-hidden": "true", children: prompt ? segments.map(
2209
+ (seg, i) => seg.connector ? /* @__PURE__ */ jsxs22(
2210
+ "button",
2211
+ {
2212
+ type: "button",
2213
+ tabIndex: -1,
2214
+ className: cn(
2215
+ "ods-showcase__token",
2216
+ `ods-showcase__token--${seg.connector.role}`
2217
+ ),
2218
+ onClick: (e) => {
2219
+ const name = seg.connector?.name;
2220
+ if (name) openSwap(name, seg.text, e.currentTarget);
2221
+ },
2222
+ children: [
2223
+ !promptFocused && /* @__PURE__ */ jsx24(ConnectorTile, { connector: seg.connector }),
2224
+ seg.text
2225
+ ]
2226
+ },
2227
+ i
2228
+ ) : (
2229
+ // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional by nature
2230
+ /* @__PURE__ */ jsx24("span", { children: seg.text }, i)
2231
+ )
2232
+ ) : /* @__PURE__ */ jsxs22(Fragment5, { children: [
2233
+ /* @__PURE__ */ jsx24("span", { className: "ods-showcase__placeholder", children: "Describe your pipeline \u2014 e.g. " }),
2234
+ /* @__PURE__ */ jsx24("span", { className: "ods-showcase__placeholder ods-showcase__placeholder--faint", children: '"Sync Storefront orders to Warehouse hourly, alert sales in Team Chat"' })
2235
+ ] }) })
2236
+ ] }),
2237
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__coach", children: [
2238
+ /* @__PURE__ */ jsx24(
2239
+ "span",
2240
+ {
2241
+ className: cn("ods-showcase__coach-line", `ods-showcase__coach-line--${coachTone}`),
2242
+ children: coachLine
2243
+ }
2244
+ ),
2245
+ coachAdds.map((c) => /* @__PURE__ */ jsxs22(
2246
+ "button",
2247
+ {
2248
+ type: "button",
2249
+ className: "ods-showcase__coach-add",
2250
+ onClick: () => toggleConnector(c.name),
2251
+ children: [
2252
+ /* @__PURE__ */ jsx24(ConnectorTile, { connector: c }),
2253
+ "+ ",
2254
+ c.name
2255
+ ]
2256
+ },
2257
+ c.name
2258
+ ))
2259
+ ] }),
2260
+ /* @__PURE__ */ jsx24(AnimatePresence2, { initial: false, children: pickerOpen && /* @__PURE__ */ jsx24(
2261
+ motion3.div,
2262
+ {
2263
+ className: "ods-showcase__picker",
2264
+ initial: reducedMotion ? false : { opacity: 0, height: 0 },
2265
+ animate: { opacity: 1, height: "auto" },
2266
+ exit: reducedMotion ? { opacity: 0 } : { opacity: 0, height: 0 },
2267
+ transition: { duration: 0.22, ease: [0.2, 0.7, 0.2, 1] },
2268
+ children: /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__picker-row", children: [
2269
+ /* @__PURE__ */ jsx24("span", { className: "ods-showcase__microcopy", children: "CONNECTORS" }),
2270
+ connectors.map((c) => /* @__PURE__ */ jsxs22(
2271
+ "button",
2272
+ {
2273
+ type: "button",
2274
+ className: cn(
2275
+ "ods-showcase__pick",
2276
+ selected.includes(c.name) && "ods-showcase__pick--on"
2277
+ ),
2278
+ "aria-pressed": selected.includes(c.name),
2279
+ onClick: () => toggleConnector(c.name),
2280
+ children: [
2281
+ /* @__PURE__ */ jsx24(ConnectorTile, { connector: c }),
2282
+ c.name
2283
+ ]
2284
+ },
2285
+ c.name
2286
+ )),
2287
+ /* @__PURE__ */ jsxs22("span", { className: "ods-showcase__microcopy ods-showcase__microcopy--faint", children: [
2288
+ "+ ",
2289
+ catalogNote,
2290
+ " IN THE APP"
2291
+ ] })
2292
+ ] })
2293
+ }
2294
+ ) }),
2295
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__toolbar", children: [
2296
+ /* @__PURE__ */ jsxs22(
2297
+ "button",
2298
+ {
2299
+ type: "button",
2300
+ className: cn(
2301
+ "ods-showcase__tool",
2302
+ (pickerOpen || selected.length > 0) && "ods-showcase__tool--on"
2303
+ ),
2304
+ "aria-expanded": pickerOpen,
2305
+ onClick: () => setPickerOpen((o) => !o),
2306
+ children: [
2307
+ "\uFF0B Connectors",
2308
+ selected.length ? ` \xB7 ${selected.length}` : ""
2309
+ ]
2310
+ }
2311
+ ),
2312
+ /* @__PURE__ */ jsxs22(
2313
+ "button",
2314
+ {
2315
+ type: "button",
2316
+ className: cn(
2317
+ "ods-showcase__tool",
2318
+ manualTrigger !== "SCHEDULE" && "ods-showcase__tool--on"
2319
+ ),
2320
+ onClick: () => setTriggerIdx((i) => (i + 1) % triggers.length),
2321
+ children: [
2322
+ "\u2691 ",
2323
+ manualTrigger
2324
+ ]
2325
+ }
2326
+ ),
2327
+ manualTrigger === "SCHEDULE" && /* @__PURE__ */ jsxs22(
2328
+ "button",
2329
+ {
2330
+ type: "button",
2331
+ className: "ods-showcase__tool",
2332
+ onClick: () => setSchedIdx((i) => (i + 1) % schedules.length),
2333
+ children: [
2334
+ "\u25F7 ",
2335
+ manualSchedule
2336
+ ]
2337
+ }
2338
+ ),
2339
+ /* @__PURE__ */ jsx24("span", { className: "ods-showcase__model", children: modelLabel }),
2340
+ /* @__PURE__ */ jsx24(
2341
+ Button,
2342
+ {
2343
+ variant: "primary",
2344
+ onClick: () => startBuild(prompt, selected),
2345
+ disabled: buildingNow,
2346
+ children: buildingNow ? "Building\u2026" : "Build workflow \u2192"
2347
+ }
2348
+ )
2349
+ ] }),
2350
+ swap && swapRole && /* @__PURE__ */ jsxs22(Fragment5, { children: [
2351
+ /* @__PURE__ */ jsx24(
2352
+ "button",
2353
+ {
2354
+ type: "button",
2355
+ className: "ods-showcase__swap-backdrop",
2356
+ "aria-label": "Close swap menu",
2357
+ onClick: () => setSwap(null)
2358
+ }
2359
+ ),
2360
+ /* @__PURE__ */ jsxs22(
2361
+ "div",
2362
+ {
2363
+ className: "ods-showcase__swap",
2364
+ role: "menu",
2365
+ style: { left: swap.x, top: swap.y },
2366
+ onKeyDown: (e) => {
2367
+ if (e.key === "Escape") setSwap(null);
2368
+ },
2369
+ children: [
2370
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__swap-head", children: [
2371
+ "SWAP ",
2372
+ swapRole.toUpperCase(),
2373
+ " \u2014 ",
2374
+ swap.name.toUpperCase()
2375
+ ] }),
2376
+ swapItems.map((c) => /* @__PURE__ */ jsxs22(
2377
+ "button",
2378
+ {
2379
+ type: "button",
2380
+ role: "menuitem",
2381
+ className: "ods-showcase__swap-item",
2382
+ onClick: () => doSwap(swap, c.name),
2383
+ children: [
2384
+ /* @__PURE__ */ jsx24(ConnectorTile, { connector: c }),
2385
+ /* @__PURE__ */ jsx24("span", { className: "ods-showcase__swap-name", children: c.name }),
2386
+ c.name === swap.name && /* @__PURE__ */ jsx24("span", { className: "ods-showcase__swap-mark", children: "\u25CF CURRENT" })
2387
+ ]
2388
+ },
2389
+ c.name
2390
+ )),
2391
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__swap-foot", children: [
2392
+ catalogNote,
2393
+ " CONNECTORS IN THE APP"
2394
+ ] })
2395
+ ]
2396
+ }
2397
+ )
2398
+ ] })
2399
+ ]
2400
+ }
2401
+ ),
2402
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__examples", children: [
2403
+ /* @__PURE__ */ jsx24("span", { className: "ods-showcase__microcopy", children: "TRY:" }),
2404
+ examples.map((ex) => /* @__PURE__ */ jsx24(
2405
+ "button",
2406
+ {
2407
+ type: "button",
2408
+ className: "ods-showcase__try",
2409
+ onClick: () => runExample(ex),
2410
+ children: ex.label
2411
+ },
2412
+ ex.id
2413
+ ))
2414
+ ] }),
2415
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__canvas", children: [
2416
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__canvas-head", children: [
2417
+ /* @__PURE__ */ jsxs22("span", { className: "ods-showcase__microcopy", children: [
2418
+ canvasLabel,
2419
+ " \xB7 ",
2420
+ canvasSub
2421
+ ] }),
2422
+ /* @__PURE__ */ jsxs22("span", { className: cn("ods-showcase__badge", `ods-showcase__badge--${badge.tone}`), children: [
2423
+ /* @__PURE__ */ jsx24("span", { className: cn("ods-showcase__dot", badge.pulse && "ods-showcase__dot--pulse") }),
2424
+ badge.label
2425
+ ] })
2426
+ ] }),
2427
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__stage", children: [
2428
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__rail", children: [
2429
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__rail-head", children: [
2430
+ /* @__PURE__ */ jsx24("span", { className: "ods-showcase__microcopy", children: railLabel }),
2431
+ /* @__PURE__ */ jsx24(
2432
+ "span",
2433
+ {
2434
+ className: cn("ods-showcase__dot", badge.pulse && "ods-showcase__dot--pulse")
2435
+ }
2436
+ )
2437
+ ] }),
2438
+ /* @__PURE__ */ jsx24("div", { className: "ods-showcase__rail-body", children: /* @__PURE__ */ jsx24(AnimatePresence2, { initial: false, children: activity.map((line) => /* @__PURE__ */ jsx24(
2439
+ motion3.div,
2440
+ {
2441
+ className: cn("ods-showcase__act", `ods-showcase__act--${line.tone}`),
2442
+ initial: reducedMotion ? false : { opacity: 0, y: 6 },
2443
+ animate: { opacity: 1, y: 0 },
2444
+ exit: { opacity: 0 },
2445
+ transition: { duration: 0.25 },
2446
+ children: line.text
2447
+ },
2448
+ line.id
2449
+ )) }) }),
2450
+ /* @__PURE__ */ jsx24(
2451
+ "div",
2452
+ {
2453
+ className: cn(
2454
+ "ods-showcase__rail-foot",
2455
+ settled && "ods-showcase__rail-foot--done",
2456
+ buildingNow && "ods-showcase__rail-foot--active"
2457
+ ),
2458
+ children: railFoot
2459
+ }
2460
+ )
2461
+ ] }),
2462
+ /* @__PURE__ */ jsx24(
2463
+ ShowcaseScene,
2464
+ {
2465
+ left: sceneLeft,
2466
+ right: sceneRight,
2467
+ engaged,
2468
+ tiles: platformTiles,
2469
+ coreIcon,
2470
+ caption: sceneCaption,
2471
+ onCoreClick: () => {
2472
+ if (buildingNow || phase === "signup" || phase === "creating" || phase === "welcome") {
2473
+ return;
2474
+ }
2475
+ signupReturnPhase.current = phase;
2476
+ setSignupError(null);
2477
+ setPhase("signup");
2478
+ }
2479
+ }
2480
+ ),
2481
+ /* @__PURE__ */ jsx24("div", { className: "ods-showcase__metrics", children: metrics.map((m, idx) => {
2482
+ const revealed = settled || phase === "building" && shown > idx;
2483
+ const interim = m.buildingValue != null && !settled && revealed;
2484
+ return /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__metric", children: [
2485
+ /* @__PURE__ */ jsxs22(
2486
+ "div",
2487
+ {
2488
+ className: cn(
2489
+ "ods-showcase__metric-value",
2490
+ !revealed && "ods-showcase__metric-value--empty",
2491
+ m.tone === "success" && settled && "ods-showcase__metric-value--success"
2492
+ ),
2493
+ children: [
2494
+ settled ? /* @__PURE__ */ jsx24(
2495
+ CountUp,
2496
+ {
2497
+ value: m.value,
2498
+ from: m.buildingValue ?? 0,
2499
+ decimals: m.decimals ?? 0,
2500
+ duration: reducedMotion ? 0 : 900,
2501
+ disableAnimation: Boolean(reducedMotion),
2502
+ prefix: m.prefix,
2503
+ formatValue: m.decimals ? void 0 : (v) => Math.round(v).toLocaleString("en-US")
2504
+ }
2505
+ ) : interim ? `${m.prefix ?? ""}${m.buildingValue}` : "\u2014",
2506
+ revealed && m.suffix ? m.suffix : null,
2507
+ revealed && m.unit ? /* @__PURE__ */ jsxs22("span", { className: "ods-showcase__metric-unit", children: [
2508
+ " ",
2509
+ m.unit
2510
+ ] }) : null
2511
+ ]
2512
+ }
2513
+ ),
2514
+ /* @__PURE__ */ jsx24("div", { className: "ods-showcase__microcopy", children: m.label })
2515
+ ] }, m.id);
2516
+ }) }),
2517
+ /* @__PURE__ */ jsx24(
2518
+ ShowcaseSignup,
2519
+ {
2520
+ phase,
2521
+ stepCount,
2522
+ workspaceDomain,
2523
+ teamSizes,
2524
+ error: signupError,
2525
+ onSubmit: submitSignup,
2526
+ onBack: () => {
2527
+ setSignupError(null);
2528
+ setPhase(signupReturnPhase.current);
2529
+ },
2530
+ dashboardHref,
2531
+ onboardingHref
2532
+ }
2533
+ )
2534
+ ] })
2535
+ ] }),
2536
+ /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__outro", "aria-live": "polite", children: [
2537
+ buildingNow && /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__building", children: [
2538
+ /* @__PURE__ */ jsx24("span", { className: "ods-showcase__spin", "aria-hidden": "true", children: "\u27F3" }),
2539
+ " ",
2540
+ status
2541
+ ] }),
2542
+ phase === "done" && /* @__PURE__ */ jsxs22("div", { className: "ods-showcase__done", children: [
2543
+ /* @__PURE__ */ jsxs22(motion3.div, { className: "ods-showcase__done-note", ...rise(0), children: [
2544
+ "\u2713 ",
2545
+ doneNote
2546
+ ] }),
2547
+ /* @__PURE__ */ jsxs22(motion3.div, { className: "ods-showcase__cta", ...rise(0.2), children: [
2548
+ /* @__PURE__ */ jsx24("span", { className: "ods-showcase__cta-copy", children: "Deploy it on your own data \u2014 takes 2 minutes." }),
2549
+ /* @__PURE__ */ jsx24(
2550
+ Button,
2551
+ {
2552
+ variant: "primary",
2553
+ onClick: () => {
2554
+ signupReturnPhase.current = "done";
2555
+ setSignupError(null);
2556
+ setPhase("signup");
2557
+ },
2558
+ children: "Create free account \u2192"
2559
+ }
2560
+ ),
2561
+ /* @__PURE__ */ jsx24("a", { className: "ods-showcase__text-link", href: onboardingHref, children: "Book onboarding \u2192" })
2562
+ ] })
2563
+ ] })
2564
+ ] })
2565
+ ] });
2566
+ }
2567
+ export {
2568
+ ActionGlyph,
2569
+ AssistantTranscript,
2570
+ BackedBy,
2571
+ BetaAccessForm,
2572
+ BlogGrid,
2573
+ BrandMark,
2574
+ ConnectorGlyph,
2575
+ ContactForm,
2576
+ CtaBanner,
2577
+ DestinationGlyph,
2578
+ FaqSection,
2579
+ FeatureGrid,
2580
+ IntegrationsFinder,
2581
+ IntegrationsWall,
2582
+ LiveConsole,
2583
+ LogoMarquee,
2584
+ MarketingFooter,
2585
+ MarketingHero,
2586
+ MarketingNav,
2587
+ MarketingSection,
2588
+ NotifyGlyph,
2589
+ PageHero,
2590
+ PricingTiers,
2591
+ SourceGlyph,
2592
+ StatBand,
2593
+ TestimonialStrip,
2594
+ WORKFLOW_SHOWCASE_DEFAULT_CONNECTORS,
2595
+ WORKFLOW_SHOWCASE_DEFAULT_EXAMPLES,
2596
+ WORKFLOW_SHOWCASE_DEFAULT_METRICS,
2597
+ WORKFLOW_SHOWCASE_DEFAULT_TILES,
2598
+ WORKFLOW_SHOWCASE_SCHEDULES,
2599
+ WorkflowShowcase,
2600
+ roleGlyph
2601
+ };
2602
+ //# sourceMappingURL=marketing.js.map