@dreamtree-org/landing-kit 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,1138 @@
1
+ 'use client';
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.js
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Audiences: () => Audiences,
24
+ AuthShell: () => AuthShell,
25
+ BookDemoButton: () => BookDemoButton,
26
+ BrandLockup: () => BrandLockup,
27
+ BrandMark: () => BrandMark2,
28
+ Breadcrumbs: () => Breadcrumbs,
29
+ Cta: () => Cta,
30
+ DEFAULT_DEMO_FIELDS: () => DEFAULT_DEMO_FIELDS,
31
+ DemoCta: () => DemoCta,
32
+ DemoDialog: () => DemoDialog,
33
+ DreamtreeFooter: () => DreamtreeFooter,
34
+ DreamtreeMark: () => DreamtreeMark,
35
+ Eyebrow: () => Eyebrow,
36
+ Faq: () => Faq,
37
+ FeatureSection: () => FeatureSection,
38
+ Header: () => Header,
39
+ Hero: () => Hero,
40
+ HowItWorks: () => HowItWorks,
41
+ LandingPage: () => LandingPage,
42
+ LandingProvider: () => LandingProvider,
43
+ MarketingLayout: () => MarketingLayout,
44
+ PageHero: () => PageHero,
45
+ PreviewFrame: () => PreviewFrame,
46
+ Section: () => Section,
47
+ SectionIntro: () => SectionIntro,
48
+ SmartLink: () => SmartLink,
49
+ TextLink: () => TextLink,
50
+ Wordmark: () => Wordmark,
51
+ Wrap: () => Wrap,
52
+ brandStyle: () => brandStyle,
53
+ brands: () => brands,
54
+ createDemoIsland: () => createDemoIsland,
55
+ getBrand: () => getBrand,
56
+ resolveHref: () => resolveHref,
57
+ useLanding: () => useLanding
58
+ });
59
+ module.exports = __toCommonJS(index_exports);
60
+
61
+ // src/LandingPage.jsx
62
+ var import_react5 = require("react");
63
+
64
+ // src/AuthShell.jsx
65
+ var import_react = require("react");
66
+ var import_jsx_runtime = require("react/jsx-runtime");
67
+ var DEFAULT_LEGAL = [
68
+ { label: "Privacy Policy", href: "/privacy" },
69
+ { label: "Terms", href: "/terms" },
70
+ { label: "Data Policy", href: "/data-policy" }
71
+ ];
72
+ function BrandMark({ brand, size }) {
73
+ if (brand.logoSrc) {
74
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { className: "dt-auth-mark-img", src: brand.logoSrc, alt: "", width: size, height: size });
75
+ }
76
+ if (brand.mark) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dt-auth-mark-node", children: brand.mark });
77
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dt-auth-monogram", style: { width: size, height: size }, "aria-hidden": "true", children: brand.name.charAt(0) });
78
+ }
79
+ function brandStyle(brand) {
80
+ return {
81
+ "--dt-brand": brand.primary,
82
+ "--dt-brand-accent": brand.accent || brand.primary,
83
+ ...brand.panel ? { "--dt-brand-panel": brand.panel } : {}
84
+ };
85
+ }
86
+ function AuthShell({
87
+ brand,
88
+ title,
89
+ subtitle,
90
+ children,
91
+ footer,
92
+ variant = "tenant",
93
+ legalLinks = DEFAULT_LEGAL,
94
+ linkComponent: LinkComponent,
95
+ className = ""
96
+ }) {
97
+ var _a;
98
+ const headingId = (0, import_react.useId)();
99
+ const isPlatform = variant === "platform";
100
+ const headline = isPlatform ? brand.platformHeadline || "Platform administration" : brand.headline;
101
+ const pitch = isPlatform ? brand.platformPitch || `Super administrator console for ${brand.name}. Every action here is audited.` : brand.pitch;
102
+ const renderLink = (l) => LinkComponent ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LinkComponent, { to: l.href, href: l.href, className: "dt-auth-legal-link", children: l.label }, l.href) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: l.href, className: "dt-auth-legal-link", children: l.label }, l.href);
103
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
104
+ "div",
105
+ {
106
+ className: `dt-auth ${isPlatform ? "dt-auth--platform" : ""} ${className}`,
107
+ style: brandStyle(brand),
108
+ "data-product": brand.id,
109
+ children: [
110
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", { className: "dt-auth-panel", children: [
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", { href: "/", className: "dt-auth-brand", children: [
112
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BrandMark, { brand, size: 28 }),
113
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dt-auth-brand-name", children: brand.name }),
114
+ isPlatform ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dt-auth-badge", children: "Platform" }) : null
115
+ ] }),
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dt-auth-pitch", children: [
117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: headline }),
118
+ pitch ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: pitch }) : null,
119
+ !isPlatform && ((_a = brand.points) == null ? void 0 : _a.length) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { children: brand.points.map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: p }, p)) }) : null
120
+ ] }),
121
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dt-auth-panel-foot", children: brand.category || "by Dreamtree-Org" })
122
+ ] }),
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("main", { className: "dt-auth-main", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dt-auth-column", children: [
124
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", { href: "/", className: "dt-auth-brand dt-auth-brand--mobile", children: [
125
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BrandMark, { brand, size: 24 }),
126
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dt-auth-brand-name", children: brand.name }),
127
+ isPlatform ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dt-auth-badge", children: "Platform" }) : null
128
+ ] }),
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "dt-auth-card", "aria-labelledby": headingId, children: [
130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", { className: "dt-auth-head", children: [
131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { id: headingId, children: title }),
132
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: subtitle }) : null
133
+ ] }),
134
+ children
135
+ ] }),
136
+ footer ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dt-auth-footer", children: footer }) : null,
137
+ (legalLinks == null ? void 0 : legalLinks.length) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", { className: "dt-auth-legal", "aria-label": "Legal", children: legalLinks.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dt-auth-legal-item", children: [
138
+ i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", children: "\xB7" }) : null,
139
+ renderLink(l)
140
+ ] }, l.href)) }) : null
141
+ ] }) })
142
+ ]
143
+ }
144
+ );
145
+ }
146
+
147
+ // src/context.jsx
148
+ var import_react2 = require("react");
149
+ var import_jsx_runtime2 = require("react/jsx-runtime");
150
+ var LandingContext = (0, import_react2.createContext)({ brand: null, linkComponent: null, onBookDemo: null, home: true });
151
+ var LandingProvider = LandingContext.Provider;
152
+ var useLanding = () => (0, import_react2.useContext)(LandingContext);
153
+ function resolveHref(href, home) {
154
+ if (!href) return href;
155
+ return !home && href.startsWith("#") ? `/${href}` : href;
156
+ }
157
+ function SmartLink({ href, children, className, reload, ...rest }) {
158
+ const { linkComponent: Link, home } = useLanding();
159
+ const to = resolveHref(href, home);
160
+ const internal = to && to.startsWith("/") && !to.startsWith("//") && !to.includes("#");
161
+ if (Link && internal && !reload) {
162
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Link, { to, href: to, className, ...rest, children });
163
+ }
164
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: to, className, ...rest, children });
165
+ }
166
+
167
+ // src/Header.jsx
168
+ var import_react4 = require("react");
169
+
170
+ // src/icons.jsx
171
+ var import_react3 = require("react");
172
+ var import_jsx_runtime3 = require("react/jsx-runtime");
173
+ var base = {
174
+ viewBox: "0 0 24 24",
175
+ fill: "none",
176
+ stroke: "currentColor",
177
+ strokeWidth: 2,
178
+ strokeLinecap: "round",
179
+ strokeLinejoin: "round",
180
+ "aria-hidden": "true",
181
+ focusable: "false"
182
+ };
183
+ var make = (paths) => function Icon({ size = 16, className = "dt-lp-icon" }) {
184
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...base, width: size, height: size, className, children: paths });
185
+ };
186
+ var ArrowRight = make(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M5 12h14M13 6l6 6-6 6" }));
187
+ var ChevronRight = make(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m9 6 6 6-6 6" }));
188
+ var Check = make(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M20 6 9 17l-5-5" }));
189
+ var Help = make(
190
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
191
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
192
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3M12 17h.01" })
193
+ ] })
194
+ );
195
+ var Alert = make(
196
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
197
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z" }),
198
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 9v4M12 17h.01" })
199
+ ] })
200
+ );
201
+ var MenuIcon = make(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M4 6h16M4 12h16M4 18h16" }));
202
+ var Close = make(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }));
203
+ var Calendar = make(
204
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
205
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
206
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M16 2v4M8 2v4M3 10h18m-12 6 2 2 4-4" })
207
+ ] })
208
+ );
209
+ function renderIcon(icon, size = 20, className = "dt-lp-icon") {
210
+ if (!icon) return null;
211
+ if ((0, import_react3.isValidElement)(icon)) return icon;
212
+ return (0, import_react3.createElement)(icon, { size, "aria-hidden": true, className, strokeWidth: 1.8 });
213
+ }
214
+
215
+ // src/Brand.jsx
216
+ var import_jsx_runtime4 = require("react/jsx-runtime");
217
+ function BrandMark2({ brand, size = 36 }) {
218
+ if (brand.logoSrc) {
219
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("img", { className: "dt-lp-mark-img", src: brand.logoSrc, alt: "", width: size, height: size });
220
+ }
221
+ if (brand.mark) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dt-lp-mark-node", "aria-hidden": "true", children: brand.mark });
222
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dt-lp-monogram", style: { width: size, height: size }, "aria-hidden": "true", children: brand.name.charAt(0) });
223
+ }
224
+ function Wordmark({ name }) {
225
+ const m = /^(.+?)(Pro)$/.exec(name);
226
+ if (!m) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dt-lp-wordmark", children: name });
227
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "dt-lp-wordmark", children: [
228
+ m[1],
229
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dt-lp-wordmark-hi", children: m[2] })
230
+ ] });
231
+ }
232
+ function BrandLockup({ brand: own, byline = "by Dreamtree-Org", href = "/" }) {
233
+ const ctx = useLanding();
234
+ const brand = own || ctx.brand;
235
+ if (!brand) return null;
236
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("a", { href, className: "dt-lp-brand", "aria-label": `${brand.name}${byline ? ` ${byline}` : ""}, home`, children: [
237
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BrandMark2, { brand }),
238
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "dt-lp-brand-text", "aria-hidden": "true", children: [
239
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Wordmark, { name: brand.name }),
240
+ byline ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dt-lp-byline", children: byline }) : null
241
+ ] })
242
+ ] });
243
+ }
244
+
245
+ // src/BookDemoButton.jsx
246
+ var import_jsx_runtime5 = require("react/jsx-runtime");
247
+ function BookDemoButton({ size = "md", variant = "primary", className = "", children = "Book a demo", onClick }) {
248
+ const { onBookDemo } = useLanding();
249
+ const handler = onClick || (onBookDemo ? (e) => onBookDemo(e.currentTarget) : void 0);
250
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
251
+ "button",
252
+ {
253
+ type: "button",
254
+ className: `dt-lp-btn dt-lp-btn--${variant} dt-lp-btn--${size} ${className}`.trim(),
255
+ "data-book-demo": "",
256
+ "aria-haspopup": "dialog",
257
+ onClick: handler,
258
+ children
259
+ }
260
+ );
261
+ }
262
+
263
+ // src/Section.jsx
264
+ var import_jsx_runtime6 = require("react/jsx-runtime");
265
+ function Wrap({ className = "", narrow, children }) {
266
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `dt-lp-wrap${narrow ? " dt-lp-wrap--narrow" : ""} ${className}`.trim(), children });
267
+ }
268
+ function Eyebrow({ children, className = "" }) {
269
+ if (!children) return null;
270
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: `dt-lp-eyebrow ${className}`.trim(), children });
271
+ }
272
+ function SectionIntro({ id, eyebrow, title, body, align = "start", children }) {
273
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `dt-lp-intro dt-lp-intro--${align}`, children: [
274
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Eyebrow, { children: eyebrow }),
275
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { id, className: "dt-lp-h2", children: title }),
276
+ body ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "dt-lp-lead", children: body }) : null,
277
+ children
278
+ ] });
279
+ }
280
+ function Section({ id, labelledBy, tone = "plain", className = "", children, narrow }) {
281
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("section", { id, "aria-labelledby": labelledBy, className: `dt-lp-section dt-lp-tone--${tone} ${className}`.trim(), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Wrap, { narrow, children }) });
282
+ }
283
+ function TextLink({ href, children, className = "", ...rest }) {
284
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(SmartLink, { href, className: `dt-lp-textlink ${className}`.trim(), ...rest, children: [
285
+ children,
286
+ " ",
287
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArrowRight, {})
288
+ ] });
289
+ }
290
+ function Cta({ cta, className = "" }) {
291
+ if (!cta) return null;
292
+ if (Array.isArray(cta)) {
293
+ if (!cta.length) return null;
294
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `dt-lp-ctas ${className}`.trim(), children: cta.map((c2, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Cta, { cta: c2 }, i)) });
295
+ }
296
+ const c = typeof cta === "string" ? { label: cta, demo: true } : cta;
297
+ if (c.href && !c.demo) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TextLink, { href: c.href, className, children: c.label });
298
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(BookDemoButton, { size: "lg", className, children: [
299
+ c.label,
300
+ " ",
301
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArrowRight, {})
302
+ ] });
303
+ }
304
+
305
+ // src/Header.jsx
306
+ var import_jsx_runtime7 = require("react/jsx-runtime");
307
+ function Header({ nav = [], login = { label: "Log in", href: "/login" }, cta = "Book a demo", brand }) {
308
+ const { home } = useLanding();
309
+ const [open, setOpen] = (0, import_react4.useState)(false);
310
+ const items = login ? [...nav, login] : nav;
311
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("header", { className: "dt-lp-header", children: [
312
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Wrap, { className: "dt-lp-header-bar", children: [
313
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BrandLockup, { brand }),
314
+ nav.length ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("nav", { "aria-label": "Primary", className: "dt-lp-nav", children: nav.map((n) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SmartLink, { href: n.href, className: "dt-lp-nav-link", children: n.label }, n.href)) }) : null,
315
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dt-lp-header-actions", children: [
316
+ login ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SmartLink, { href: login.href, className: "dt-lp-nav-link dt-lp-login", reload: true, children: login.label }) : null,
317
+ cta ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(BookDemoButton, { size: "sm", children: cta }) : null,
318
+ items.length ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
319
+ "button",
320
+ {
321
+ type: "button",
322
+ className: "dt-lp-menu-btn",
323
+ "aria-label": open ? "Close menu" : "Open menu",
324
+ "aria-expanded": open ? "true" : "false",
325
+ "aria-controls": "mobile-nav",
326
+ "data-menu-toggle": "",
327
+ onClick: () => setOpen((o) => !o),
328
+ children: [
329
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dt-lp-menu-open", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MenuIcon, { size: 20 }) }),
330
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dt-lp-menu-close", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Close, { size: 20 }) })
331
+ ]
332
+ }
333
+ ) : null
334
+ ] })
335
+ ] }),
336
+ items.length ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("nav", { id: "mobile-nav", "aria-label": "Mobile", className: "dt-lp-mobile-nav", hidden: !open, onClick: (e) => {
337
+ var _a, _b;
338
+ return ((_b = (_a = e.target).closest) == null ? void 0 : _b.call(_a, "a")) && setOpen(false);
339
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Wrap, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { children: items.map((n) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SmartLink, { href: n.href, reload: n === login, children: n.label }) }, n.href)) }) }) }) : null
340
+ ] });
341
+ }
342
+
343
+ // src/DreamtreeFooter.jsx
344
+ var import_jsx_runtime8 = require("react/jsx-runtime");
345
+ function DreamtreeMark({ size = 28 }) {
346
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "dt-lp-org", role: "img", "aria-label": "Dreamtree-Org", children: [
347
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { viewBox: "0 0 48.35 48.35", width: size, height: size, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("g", { fill: "none", strokeWidth: "4", strokeLinecap: "round", strokeLinejoin: "round", stroke: "#0f766e", children: [
348
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M23.01,44.02c-9.02.03-16.36-7.27-16.39-16.29-.02-7.98,5.72-14.81,13.59-16.16,13.31-2.57,16.81-3.78,21.48-9.57,2.33,4.67,4.67,9.76,4.67,18.67,0,12.84-11.16,23.34-23.34,23.34Z" }),
349
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M2,46.35c0-7,4.32-12.51,11.86-14.01,5.65-1.12,11.49-4.67,13.82-7" })
350
+ ] }) }),
351
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-hidden": "true", className: "dt-lp-org-name", children: "Dreamtree-Org" })
352
+ ] });
353
+ }
354
+ function DreamtreeFooter({
355
+ blurb,
356
+ columns = [],
357
+ org = "Dreamtree-Org",
358
+ tagline,
359
+ legal = [],
360
+ year = (/* @__PURE__ */ new Date()).getFullYear(),
361
+ brand: own
362
+ }) {
363
+ const ctx = useLanding();
364
+ const brand = own || ctx.brand;
365
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("footer", { className: "dt-lp-footer", children: [
366
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Wrap, { className: `dt-lp-footer-grid dt-lp-footer-grid--${Math.min(columns.length, 3)}`, children: [
367
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dt-lp-footer-about", children: [
368
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DreamtreeMark, {}),
369
+ blurb ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: blurb }) : null
370
+ ] }),
371
+ columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("nav", { "aria-label": col.label || col.title, className: "dt-lp-footer-col", children: [
372
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "dt-lp-footer-title", children: col.title }),
373
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { className: col.links.length > 5 && col.compact !== false ? "dt-lp-footer-links" : "dt-lp-footer-links dt-lp-footer-links--one", children: col.links.map((l) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SmartLink, { href: l.href, reload: l.reload, children: l.label }) }, l.href)) })
374
+ ] }, col.title))
375
+ ] }),
376
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dt-lp-footer-bar", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Wrap, { className: "dt-lp-footer-bar-inner", children: [
377
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { children: [
378
+ "\xA9 ",
379
+ year,
380
+ " ",
381
+ org,
382
+ ". All rights reserved."
383
+ ] }),
384
+ legal.length ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("nav", { "aria-label": "Legal", className: "dt-lp-footer-legal", children: legal.map((l) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SmartLink, { href: l.href, children: l.label }, l.href)) }) : null,
385
+ brand && tagline ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { children: [
386
+ brand.name,
387
+ ": ",
388
+ tagline
389
+ ] }) : null
390
+ ] }) })
391
+ ] });
392
+ }
393
+
394
+ // src/MarketingLayout.jsx
395
+ var import_jsx_runtime9 = require("react/jsx-runtime");
396
+ function MarketingLayout({
397
+ brand,
398
+ nav = [],
399
+ login,
400
+ cta,
401
+ footer,
402
+ home = true,
403
+ linkComponent = null,
404
+ onBookDemo = null,
405
+ className = "",
406
+ children
407
+ }) {
408
+ if (!brand || !brand.name) {
409
+ throw new Error(`landing-kit: "brand" is missing. Pass getBrand('<product>') from @dreamtree-org/auth-kit, or your own { id, name, primary }.`);
410
+ }
411
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LandingProvider, { value: { brand, linkComponent, onBookDemo, home }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: `dt-landing ${className}`.trim(), style: brandStyle(brand), "data-product": brand.id, children: [
412
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("a", { href: "#main", className: "dt-lp-skip", children: "Skip to content" }),
413
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Header, { nav, ...login !== void 0 ? { login } : {}, ...cta !== void 0 ? { cta } : {} }),
414
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("main", { id: "main", children }),
415
+ footer === false ? null : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DreamtreeFooter, { ...footer || {} })
416
+ ] }) });
417
+ }
418
+
419
+ // src/Hero.jsx
420
+ var import_jsx_runtime10 = require("react/jsx-runtime");
421
+ function Hero({
422
+ eyebrow,
423
+ title,
424
+ subtitle,
425
+ lead,
426
+ chips,
427
+ chipsLabel = "Who it is for",
428
+ cta = "Book a demo",
429
+ secondary,
430
+ overlap = false,
431
+ id = "hero",
432
+ backdrop
433
+ }) {
434
+ const [first, hi] = Array.isArray(title) ? title : [title, null];
435
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { id, "aria-labelledby": "hero-title", className: `dt-lp-hero${overlap ? " dt-lp-hero--overlap" : ""}`, children: [
436
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dt-lp-hero-glow", "aria-hidden": "true" }),
437
+ backdrop ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dt-lp-hero-backdrop", "aria-hidden": "true", children: backdrop }) : null,
438
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Wrap, { className: "dt-lp-hero-inner", children: [
439
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Eyebrow, { children: eyebrow }),
440
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("h1", { id: "hero-title", className: "dt-lp-h1", children: [
441
+ first,
442
+ hi ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
443
+ " ",
444
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "dt-lp-h1-hi", children: hi })
445
+ ] }) : null
446
+ ] }),
447
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "dt-lp-hero-subtitle", children: subtitle }) : null,
448
+ lead ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "dt-lp-hero-lead", children: lead }) : null,
449
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dt-lp-actions", children: [
450
+ cta ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BookDemoButton, { size: "lg", children: cta }) : null,
451
+ secondary ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TextLink, { href: secondary.href, children: secondary.label }) : null
452
+ ] }),
453
+ (chips == null ? void 0 : chips.length) ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { className: "dt-lp-chips", "aria-label": chipsLabel, children: chips.map((c) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("li", { children: c }, c)) }) : null
454
+ ] })
455
+ ] });
456
+ }
457
+
458
+ // src/FeatureSection.jsx
459
+ var import_jsx_runtime11 = require("react/jsx-runtime");
460
+ var asItem = (x) => typeof x === "string" ? { title: x } : x;
461
+ function Items({ items, kind }) {
462
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: `dt-lp-grid dt-lp-grid--${kind}`, children: items.map(asItem).map((f) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { className: `dt-lp-card dt-lp-card--${kind}`, children: [
463
+ f.icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dt-lp-icon-tile", children: renderIcon(f.icon, 20) }) : null,
464
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dt-lp-card-text", children: [
465
+ f.label ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "dt-lp-kicker", children: f.label }) : null,
466
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "dt-lp-h3", children: f.href ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SmartLink, { href: f.href, children: f.title }) : f.title }),
467
+ f.body ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: f.body }) : null
468
+ ] })
469
+ ] }, f.title)) });
470
+ }
471
+ function Checklist({ items, icon: Icon = Check, tone = "good", labelledBy }) {
472
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: `dt-lp-checklist dt-lp-checklist--${tone}`, "aria-labelledby": labelledBy, children: items.map((x) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { children: [
473
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { size: 18 }),
474
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: x })
475
+ ] }, x)) });
476
+ }
477
+ function InlineItems({ items }) {
478
+ if (!(items == null ? void 0 : items.length)) return null;
479
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "dt-lp-inline-items", children: items.map(asItem).map((f) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { children: [
480
+ f.icon ? renderIcon(f.icon, 22) : null,
481
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
482
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dt-lp-inline-title", children: f.title }),
483
+ f.body ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dt-lp-inline-body", children: f.body }) : null
484
+ ] })
485
+ ] }, f.title)) });
486
+ }
487
+ function Media({ children }) {
488
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dt-lp-media", children });
489
+ }
490
+ function Pair({ className, reverse, text, side }) {
491
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `${className}${reverse ? " dt-lp-pair--reverse" : ""}`, children: [
492
+ reverse ? side : text,
493
+ reverse ? text : side
494
+ ] });
495
+ }
496
+ function Chips({ items, label, className = "" }) {
497
+ if (!(items == null ? void 0 : items.length)) return null;
498
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: `dt-lp-chips dt-lp-chips--start ${className}`.trim(), "aria-label": label, children: items.map((c) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("li", { children: c }, c)) });
499
+ }
500
+ function FeatureSection(props) {
501
+ const { id, variant = "cards", tone, eyebrow, title, body, items = [], cta, footnote, media, reverse, bullets } = props;
502
+ const hid = `${id || variant}-title`;
503
+ const defaultTone = { highlight: "dark", split: "tinted", compare: "muted" }[variant] || "plain";
504
+ const shell = (children, extra = {}) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Section, { id, labelledBy: hid, tone: tone || defaultTone, className: `dt-lp-feature dt-lp-feature--${variant}`, ...extra, children });
505
+ switch (variant) {
506
+ case "split":
507
+ return shell(
508
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
509
+ Pair,
510
+ {
511
+ className: "dt-lp-split",
512
+ reverse,
513
+ text: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(SectionIntro, { id: hid, eyebrow, title, body, children: [
514
+ media ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(InlineItems, { items }) : null,
515
+ (bullets == null ? void 0 : bullets.length) ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Checklist, { items: bullets }) : null,
516
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Cta, { cta, className: "dt-lp-mt" })
517
+ ] }, "text"),
518
+ side: media ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Media, { children: media }, "side") : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Items, { items, kind: "split" }, "side")
519
+ }
520
+ )
521
+ );
522
+ case "list":
523
+ return shell(
524
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
525
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionIntro, { id: hid, eyebrow, title, body, align: "center" }),
526
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Items, { items, kind: "list" }),
527
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Cta, { cta, className: "dt-lp-mt" })
528
+ ] })
529
+ );
530
+ case "intro": {
531
+ const { subtitle, detail, note, glance = [], glanceTitle = "At a glance", link } = props;
532
+ return shell(
533
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dt-lp-intro-grid", children: [
534
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
535
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionIntro, { id: hid, eyebrow, title, body }),
536
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "dt-lp-h3 dt-lp-h3--lg", children: subtitle }) : null,
537
+ detail ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "dt-lp-body", children: detail }) : null,
538
+ note ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "dt-lp-note", children: note }) : null,
539
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Cta, { cta, className: "dt-lp-mt" })
540
+ ] }),
541
+ glance.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("aside", { className: "dt-lp-glance", "aria-labelledby": `${hid}-glance`, children: [
542
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { id: `${hid}-glance`, className: "dt-lp-eyebrow", children: glanceTitle }),
543
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Checklist, { items: glance }),
544
+ props.glanceNote ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "dt-lp-note", children: props.glanceNote }) : null,
545
+ link ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TextLink, { href: link.href, className: "dt-lp-mt", children: link.label }) : null
546
+ ] }) : null
547
+ ] })
548
+ );
549
+ }
550
+ case "highlight": {
551
+ const { note, noteLabel = "Important:" } = props;
552
+ const text = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dt-lp-intro", children: [
553
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Eyebrow, { children: eyebrow }),
554
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { id: hid, className: "dt-lp-h2", children: title }),
555
+ body ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "dt-lp-lead", children: body }) : null,
556
+ note ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "dt-lp-callout", children: [
557
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Alert, { size: 20 }),
558
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
559
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: noteLabel }),
560
+ " ",
561
+ note
562
+ ] })
563
+ ] }) : null,
564
+ media ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(InlineItems, { items }) : null,
565
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Cta, { cta, className: "dt-lp-mt" })
566
+ ] }, "text");
567
+ const side = media ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Media, { children: media }, "side") : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "dt-lp-grid dt-lp-grid--chips", children: items.map(asItem).map((f) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { className: "dt-lp-chip-card", children: [
568
+ renderIcon(f.icon, 22),
569
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: f.title })
570
+ ] }, f.title)) }, "side");
571
+ return shell(/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Pair, { className: "dt-lp-split dt-lp-split--wide", reverse, text, side }));
572
+ }
573
+ case "band": {
574
+ const { examples, examplesLabel = "Examples" } = props;
575
+ const text = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
576
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionIntro, { id: hid, eyebrow, title, body }),
577
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Chips, { items: examples, label: examplesLabel, className: "dt-lp-mt" }),
578
+ media ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(InlineItems, { items }) : null,
579
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Cta, { cta, className: "dt-lp-mt" })
580
+ ] }, "text");
581
+ const side = media ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Media, { children: media }, "side") : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "dt-lp-band-list", children: items.map(asItem).map((f) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { children: [
582
+ renderIcon(f.icon, 22),
583
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: f.title })
584
+ ] }, f.title)) }, "side");
585
+ return shell(/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Pair, { className: "dt-lp-band", reverse, text, side }));
586
+ }
587
+ case "compare": {
588
+ const { columns = [] } = props;
589
+ return shell(
590
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
591
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionIntro, { id: hid, eyebrow, title, body }),
592
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "dt-lp-compare", children: columns.map((col, i) => {
593
+ const cid = `${id || "compare"}-${i + 1}`;
594
+ const tone2 = col.tone || (i === 0 ? "good" : "check");
595
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dt-lp-card dt-lp-card--compare", children: [
596
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { id: cid, className: "dt-lp-h3 dt-lp-h3--lg", children: col.title }),
597
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Checklist, { items: col.items, tone: tone2, icon: tone2 === "good" ? Check : Help, labelledBy: cid })
598
+ ] }, cid);
599
+ }) })
600
+ ] })
601
+ );
602
+ }
603
+ case "links":
604
+ return shell(
605
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
606
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionIntro, { id: hid, eyebrow, title, body }),
607
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "dt-lp-grid dt-lp-grid--links", children: items.map((s) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(SmartLink, { href: s.href, className: "dt-lp-linkcard", children: [
608
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "dt-lp-linkcard-title", children: [
609
+ s.title,
610
+ " ",
611
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ArrowRight, {})
612
+ ] }),
613
+ s.body ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dt-lp-linkcard-body", children: s.body }) : null
614
+ ] }) }, s.href)) })
615
+ ] })
616
+ );
617
+ case "detail": {
618
+ return shell(
619
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dt-lp-detail", children: [
620
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { id: hid, className: "dt-lp-h2", children: title }),
621
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
622
+ body ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "dt-lp-body", children: body }) : null,
623
+ (bullets == null ? void 0 : bullets.length) ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Checklist, { items: bullets }) : null
624
+ ] })
625
+ ] })
626
+ );
627
+ }
628
+ default:
629
+ return shell(
630
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
631
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionIntro, { id: hid, eyebrow, title, body }),
632
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Items, { items, kind: "cards" }),
633
+ footnote ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "dt-lp-footnote", children: footnote }) : null,
634
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Cta, { cta, className: "dt-lp-mt" })
635
+ ] })
636
+ );
637
+ }
638
+ }
639
+
640
+ // src/Audiences.jsx
641
+ var import_jsx_runtime12 = require("react/jsx-runtime");
642
+ function Audiences({ id = "audiences", eyebrow, title, body, items = [], linkLabel = "See how it works", tone = "muted" }) {
643
+ const hid = `${id}-title`;
644
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Section, { id, labelledBy: hid, tone, className: "dt-lp-audiences", children: [
645
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SectionIntro, { id: hid, eyebrow, title, body, align: "center" }),
646
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: `dt-lp-grid dt-lp-grid--audiences dt-lp-grid--n${Math.min(items.length, 4)}`, children: items.map((a, i) => {
647
+ var _a;
648
+ const aid = a.id || `${id}-${i + 1}`;
649
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("article", { id: aid, "aria-labelledby": `${aid}-title`, className: "dt-lp-card dt-lp-card--audience", children: [
650
+ a.icon ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "dt-lp-audience-icon", children: renderIcon(a.icon, 30) }) : null,
651
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: a.media ? "dt-lp-audience-head" : void 0, children: [
652
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
653
+ a.keyword ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "dt-lp-kicker", children: a.keyword }) : null,
654
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { id: `${aid}-title`, className: "dt-lp-h3 dt-lp-h3--lg", children: a.title }),
655
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: a.media || a.features ? void 0 : "dt-lp-grow", children: a.body })
656
+ ] }),
657
+ a.media ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "dt-lp-audience-media", "aria-hidden": "true", children: a.media }) : null
658
+ ] }),
659
+ ((_a = a.features) == null ? void 0 : _a.length) ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { className: "dt-lp-audience-features dt-lp-grow", children: a.features.map((f) => {
660
+ const it = typeof f === "string" ? { title: f } : f;
661
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("li", { children: [
662
+ it.icon ? renderIcon(it.icon, 22) : null,
663
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: it.title })
664
+ ] }, it.title);
665
+ }) }) : null,
666
+ a.href ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TextLink, { href: a.href, "aria-label": `${a.keyword || a.title}: ${(a.linkLabel || linkLabel).toLowerCase()}`, children: a.linkLabel || linkLabel }) : null
667
+ ] }, aid);
668
+ }) })
669
+ ] });
670
+ }
671
+
672
+ // src/HowItWorks.jsx
673
+ var import_jsx_runtime13 = require("react/jsx-runtime");
674
+ function HowItWorks({ id = "how-it-works", eyebrow, title, body, steps, items, tone = "plain", cta }) {
675
+ const list = steps || items || [];
676
+ const hid = `${id}-title`;
677
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Section, { id, labelledBy: hid, tone, className: "dt-lp-steps", children: [
678
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SectionIntro, { id: hid, eyebrow, title, body }),
679
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("ol", { className: "dt-lp-grid dt-lp-grid--steps", children: list.map((st, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("li", { className: "dt-lp-card", children: [
680
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dt-lp-step-num", "aria-hidden": "true", children: i + 1 }),
681
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { className: "dt-lp-h3", children: st.name || st.title }),
682
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: st.text || st.body })
683
+ ] }, st.name || st.title)) }),
684
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Cta, { cta, className: "dt-lp-mt" })
685
+ ] });
686
+ }
687
+
688
+ // src/Faq.jsx
689
+ var import_jsx_runtime14 = require("react/jsx-runtime");
690
+ function Faq({ id = "faq", eyebrow, title = "Frequently asked questions", intro, items = [], openFirst = true, tone = "muted" }) {
691
+ const hid = `${id}-title`;
692
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Section, { id, labelledBy: hid, tone, narrow: true, className: "dt-lp-faq", children: [
693
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SectionIntro, { id: hid, eyebrow, title, body: intro, align: "center" }),
694
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "dt-lp-faq-list", children: items.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("details", { className: "dt-lp-faq-item", open: openFirst && i === 0, children: [
695
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("summary", { children: [
696
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "dt-lp-h3", children: f.q }),
697
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChevronRight, { size: 18, className: "dt-lp-icon dt-lp-faq-chevron" })
698
+ ] }),
699
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: f.a })
700
+ ] }, f.q)) })
701
+ ] });
702
+ }
703
+
704
+ // src/DemoCta.jsx
705
+ var import_jsx_runtime15 = require("react/jsx-runtime");
706
+ function DemoCta({ id = "demo", eyebrow, title, body, label = "Book a demo", chips, chipsLabel = "Business types", note, link }) {
707
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("section", { id, "aria-labelledby": `${id}-title`, className: "dt-lp-section dt-lp-cta", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Wrap, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "dt-lp-cta-panel", children: [
708
+ eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "dt-lp-eyebrow dt-lp-eyebrow--inverse", children: eyebrow }) : null,
709
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h2", { id: `${id}-title`, className: "dt-lp-h2 dt-lp-h2--cta", children: title }),
710
+ body ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "dt-lp-cta-body", children: body }) : null,
711
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(BookDemoButton, { size: "lg", variant: "inverse", children: label }),
712
+ (chips == null ? void 0 : chips.length) ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ul", { className: "dt-lp-chips dt-lp-chips--inverse", "aria-label": chipsLabel, children: chips.map((k) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("li", { children: k }, k)) }) : null,
713
+ note ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "dt-lp-cta-note", children: [
714
+ note.title ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { className: "dt-lp-h3", children: note.title }) : null,
715
+ note.body ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: note.body }) : null
716
+ ] }) : null,
717
+ link ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "dt-lp-cta-link", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SmartLink, { href: link.href, reload: link.reload, children: link.label }) }) : null
718
+ ] }) }) });
719
+ }
720
+
721
+ // src/LandingPage.jsx
722
+ var import_jsx_runtime16 = require("react/jsx-runtime");
723
+ var BLOCKS = { audiences: Audiences, steps: HowItWorks, faq: Faq, cta: DemoCta };
724
+ var TAIL = ["audiences", "steps", "faq", "cta"];
725
+ function LandingPage({ brand, content, preview = null, slots = {}, linkComponent, onBookDemo, home = true, className }) {
726
+ if (!content || !content.hero) {
727
+ throw new Error('landing-kit: "content.hero" is missing. LandingPage needs at least { hero: { title } }; see README "Content".');
728
+ }
729
+ const { nav = [], login, hero, sections = [], footer, header = {} } = content;
730
+ const used = new Set(sections.filter((s) => s && s.use).map((s) => s.use));
731
+ const previewInline = used.has("preview");
732
+ const render = (s, i) => {
733
+ var _a;
734
+ if (!s) return null;
735
+ if ((0, import_react5.isValidElement)(s)) return (0, import_react5.cloneElement)(s, { key: (_a = s.key) != null ? _a : `el-${i}` });
736
+ if (s.use === "preview") return preview ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { children: preview }, "preview") : null;
737
+ if (s.use) {
738
+ if (slots && Object.prototype.hasOwnProperty.call(slots, s.use)) {
739
+ const node = slots[s.use];
740
+ return node ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react5.Fragment, { children: node }, `slot-${s.use}`) : null;
741
+ }
742
+ const Block = BLOCKS[s.use];
743
+ if (!Block) {
744
+ const known = ["preview", ...TAIL, ...Object.keys(slots || {})].join(", ");
745
+ throw new Error(`landing-kit: unknown section use "${s.use}" (known: ${known}). Pass custom sections as <LandingPage slots={{ ${s.use}: <YourSection /> }} />.`);
746
+ }
747
+ return content[s.use] ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Block, { ...content[s.use] }, s.use) : null;
748
+ }
749
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(FeatureSection, { ...s }, s.id || `section-${i}`);
750
+ };
751
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
752
+ MarketingLayout,
753
+ {
754
+ brand,
755
+ nav,
756
+ login,
757
+ cta: header.cta,
758
+ footer,
759
+ home,
760
+ linkComponent,
761
+ onBookDemo,
762
+ className,
763
+ children: [
764
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Hero, { ...hero, overlap: !!preview && !previewInline }),
765
+ preview && !previewInline ? preview : null,
766
+ sections.map(render),
767
+ TAIL.filter((k) => !used.has(k) && content[k]).map((k) => {
768
+ const Block = BLOCKS[k];
769
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Block, { ...content[k] }, k);
770
+ })
771
+ ]
772
+ }
773
+ );
774
+ }
775
+
776
+ // src/PreviewFrame.jsx
777
+ var import_jsx_runtime17 = require("react/jsx-runtime");
778
+ function PreviewFrame({
779
+ id = "product",
780
+ heading,
781
+ caption,
782
+ meta,
783
+ badge = "Demo data",
784
+ brand: own,
785
+ children
786
+ }) {
787
+ const ctx = useLanding();
788
+ const brand = own || ctx.brand;
789
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("section", { id, "aria-labelledby": `${id}-title`, className: "dt-lp-preview", children: [
790
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { id: `${id}-title`, className: "dt-lp-sr-only", children: heading || `${brand ? brand.name : "Product"} overview` }),
791
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Wrap, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("figure", { className: "dt-lp-preview-frame", children: [
792
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "dt-lp-preview-bar", children: [
793
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "dt-lp-preview-title", children: [
794
+ brand ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Wordmark, { name: brand.name }) : null,
795
+ meta ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "dt-lp-preview-meta", children: meta }) : null
796
+ ] }),
797
+ badge ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "dt-lp-preview-badge", children: badge }) : null
798
+ ] }),
799
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "dt-lp-preview-body", children }),
800
+ caption ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("figcaption", { className: "dt-lp-sr-only", children: caption }) : null
801
+ ] }) })
802
+ ] });
803
+ }
804
+
805
+ // src/DemoDialog.jsx
806
+ var import_react6 = require("react");
807
+ var import_jsx_runtime18 = require("react/jsx-runtime");
808
+ var DEFAULT_DEMO_FIELDS = [
809
+ { name: "name", label: "Your name", required: true, maxLength: 120, autoComplete: "name" },
810
+ { name: "phone", label: "Mobile", type: "tel", required: true, maxLength: 20, autoComplete: "tel", inputMode: "tel" },
811
+ { name: "email", label: "Email", type: "email", maxLength: 190, autoComplete: "email" },
812
+ { name: "company", label: "Business name", maxLength: 160, autoComplete: "organization" }
813
+ ];
814
+ var initial = (fields) => Object.fromEntries(fields.map((f) => [f.name, ""]));
815
+ function Field({ f, value, onChange, error }) {
816
+ const id = `dt-demo-${f.name}`;
817
+ const errId = `${id}-error`;
818
+ const common = {
819
+ id,
820
+ name: f.name,
821
+ value,
822
+ onChange,
823
+ required: !!f.required,
824
+ className: "dt-lp-input",
825
+ ...error ? { "aria-invalid": "true", "aria-describedby": errId } : {}
826
+ };
827
+ let control;
828
+ if (f.type === "select") {
829
+ control = /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("select", { ...common, children: [
830
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "", children: f.placeholder || "Choose one" }),
831
+ (f.options || []).map((o) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: o.value, children: o.label }, o.value))
832
+ ] });
833
+ } else if (f.type === "textarea") {
834
+ control = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("textarea", { ...common, rows: f.rows || 3, maxLength: f.maxLength });
835
+ } else {
836
+ control = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
837
+ "input",
838
+ {
839
+ ...common,
840
+ type: f.type || "text",
841
+ maxLength: f.maxLength,
842
+ min: f.min,
843
+ inputMode: f.inputMode,
844
+ autoComplete: f.autoComplete,
845
+ placeholder: f.placeholder
846
+ }
847
+ );
848
+ }
849
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("label", { htmlFor: id, className: `dt-lp-field${f.wide || f.type === "textarea" ? " dt-lp-field--wide" : ""}`, children: [
850
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { children: [
851
+ f.label,
852
+ f.required ? " *" : ""
853
+ ] }),
854
+ control,
855
+ error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { id: errId, className: "dt-lp-field-error", children: error }) : null
856
+ ] });
857
+ }
858
+ function DemoDialog({
859
+ brand,
860
+ open = true,
861
+ onClose = () => {
862
+ },
863
+ onSubmit,
864
+ fields = DEFAULT_DEMO_FIELDS,
865
+ title,
866
+ intro = "Tell us a little about your business and we will walk you through the workflows that matter to your team.",
867
+ fiduciary = "Dreamtree-Org",
868
+ consentText,
869
+ privacyHref = "/privacy",
870
+ policyVersion,
871
+ submitLabel = "Request my demo",
872
+ successMessage,
873
+ validate
874
+ }) {
875
+ const ref = (0, import_react6.useRef)(null);
876
+ const [form, setForm] = (0, import_react6.useState)(() => initial(fields));
877
+ const [website, setWebsite] = (0, import_react6.useState)("");
878
+ const [consent, setConsent] = (0, import_react6.useState)(false);
879
+ const [busy, setBusy] = (0, import_react6.useState)(false);
880
+ const [err, setErr] = (0, import_react6.useState)("");
881
+ const [fieldErrors, setFieldErrors] = (0, import_react6.useState)({});
882
+ const [sent, setSent] = (0, import_react6.useState)(false);
883
+ const name = brand ? brand.name : "a";
884
+ (0, import_react6.useEffect)(() => {
885
+ const dlg = ref.current;
886
+ if (open && dlg && !dlg.open && typeof dlg.showModal === "function") dlg.showModal();
887
+ }, [open]);
888
+ if (!open) return null;
889
+ if (typeof onSubmit !== "function") {
890
+ throw new Error('landing-kit DemoDialog: "onSubmit" is missing. Pass async (data) => { /* POST the demo request */ }.');
891
+ }
892
+ const set = (k) => (e) => {
893
+ setForm((f) => ({ ...f, [k]: e.target.value }));
894
+ if (fieldErrors[k]) setFieldErrors(({ [k]: _gone, ...rest }) => rest);
895
+ };
896
+ const ready = consent && (typeof validate === "function" || fields.every((f) => !f.required || String(form[f.name] || "").trim()));
897
+ const submit = async (e) => {
898
+ e.preventDefault();
899
+ if (!ready || busy) return;
900
+ setErr("");
901
+ if (typeof validate === "function") {
902
+ const found = validate(form) || {};
903
+ setFieldErrors(found);
904
+ if (Object.keys(found).length) return;
905
+ }
906
+ setBusy(true);
907
+ try {
908
+ await onSubmit({ ...form, website, consent: true, source_path: typeof window === "undefined" ? "/" : window.location.pathname });
909
+ setSent(true);
910
+ } catch (ex) {
911
+ if (ex && ex.fields && typeof ex.fields === "object") setFieldErrors(ex.fields);
912
+ setErr(ex && ex.message || "Could not send your request. Please try again.");
913
+ } finally {
914
+ setBusy(false);
915
+ }
916
+ };
917
+ const first = String(form.name || "").trim().split(/\s+/)[0] || "there";
918
+ const thanks = typeof successMessage === "function" ? successMessage(form) : successMessage || `Thanks, ${first}. We have your request. Someone from the ${name} team will call you within one working day to fix a time.`;
919
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
920
+ "dialog",
921
+ {
922
+ ref,
923
+ className: "dt-lp-dialog",
924
+ style: brand ? brandStyle(brand) : void 0,
925
+ "aria-labelledby": "dt-demo-title",
926
+ onClose,
927
+ onCancel: (e) => {
928
+ e.preventDefault();
929
+ onClose();
930
+ },
931
+ children: [
932
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "dt-lp-dialog-head", children: [
933
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h2", { id: "dt-demo-title", children: sent ? "Thank you" : title || `Book a ${name} demo` }),
934
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "button", className: "dt-lp-dialog-x", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Close, { size: 18 }) })
935
+ ] }),
936
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "dt-lp-dialog-body", children: sent ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "dt-lp-stack", children: [
937
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { role: "status", children: thanks }),
938
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "button", className: "dt-lp-btn dt-lp-btn--outline dt-lp-btn--md", onClick: onClose, children: "Close" })
939
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("form", { className: "dt-lp-stack", onSubmit: submit, noValidate: true, children: [
940
+ intro ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "dt-lp-muted", children: intro }) : null,
941
+ err ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { role: "alert", className: "dt-lp-error", children: err }) : null,
942
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "dt-lp-fields", children: fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Field, { f, value: form[f.name], onChange: set(f.name), error: fieldErrors[f.name] }, f.name)) }),
943
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { "aria-hidden": "true", className: "dt-lp-honeypot", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("label", { children: [
944
+ "Website",
945
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("input", { type: "text", name: "website", tabIndex: -1, autoComplete: "off", value: website, onChange: (e) => setWebsite(e.target.value) })
946
+ ] }) }),
947
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("label", { className: "dt-lp-consent", children: [
948
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("input", { type: "checkbox", checked: consent, onChange: (e) => setConsent(e.target.checked) }),
949
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: consentText || `I agree that ${fiduciary} may call, message or email me about this demo.` })
950
+ ] }),
951
+ privacyHref ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("p", { className: "dt-lp-fineprint", children: [
952
+ "Used only to arrange your demo. See the ",
953
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { href: privacyHref, children: "privacy policy" }),
954
+ policyVersion ? ` (v${policyVersion})` : "",
955
+ "."
956
+ ] }) : null,
957
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("button", { type: "submit", className: "dt-lp-btn dt-lp-btn--primary dt-lp-btn--md", disabled: !ready || busy, "aria-busy": busy ? "true" : void 0, children: [
958
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Calendar, { size: 16 }),
959
+ busy ? "Sending\u2026" : submitLabel
960
+ ] })
961
+ ] }) })
962
+ ]
963
+ }
964
+ );
965
+ }
966
+
967
+ // src/PageHero.jsx
968
+ var import_jsx_runtime19 = require("react/jsx-runtime");
969
+ function Breadcrumbs({ items = [] }) {
970
+ if (!items.length) return null;
971
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("nav", { "aria-label": "Breadcrumb", className: "dt-lp-crumbs", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("ol", { children: items.map((c, i) => {
972
+ const last = i === items.length - 1;
973
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("li", { children: [
974
+ i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChevronRight, { size: 14 }) : null,
975
+ last || !c.href ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "aria-current": last ? "page" : void 0, children: c.label }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SmartLink, { href: c.href, children: c.label })
976
+ ] }, `${c.label}-${i}`);
977
+ }) }) });
978
+ }
979
+ function PageHero({ breadcrumbs, eyebrow, title, lead, cta = "Book a demo", secondary }) {
980
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("section", { "aria-labelledby": "hero-title", className: "dt-lp-hero dt-lp-hero--page", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Wrap, { className: "dt-lp-hero-inner dt-lp-hero-inner--start", children: [
981
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Breadcrumbs, { items: breadcrumbs }),
982
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Eyebrow, { className: "dt-lp-mt-lg", children: eyebrow }),
983
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h1", { id: "hero-title", className: "dt-lp-h1 dt-lp-h1--page", children: title }),
984
+ lead ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { id: "answer", className: "dt-lp-hero-lead", children: lead }) : null,
985
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "dt-lp-actions dt-lp-actions--start", children: [
986
+ cta ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(BookDemoButton, { size: "lg", children: cta }) : null,
987
+ secondary ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TextLink, { href: secondary.href, children: secondary.label }) : null
988
+ ] })
989
+ ] }) });
990
+ }
991
+
992
+ // src/island.jsx
993
+ var import_client = require("react-dom/client");
994
+ var import_jsx_runtime20 = require("react/jsx-runtime");
995
+ function createDemoIsland(props) {
996
+ let root;
997
+ let returnTo = null;
998
+ const close = () => {
999
+ root.render(null);
1000
+ const target = returnTo;
1001
+ if (target) setTimeout(() => target.focus(), 0);
1002
+ };
1003
+ return {
1004
+ openDemo(trigger) {
1005
+ returnTo = trigger || null;
1006
+ if (!root) {
1007
+ const host = document.createElement("div");
1008
+ host.id = "demo-dialog-root";
1009
+ document.body.appendChild(host);
1010
+ root = (0, import_client.createRoot)(host);
1011
+ }
1012
+ const p = typeof props === "function" ? props() : props;
1013
+ root.render(/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DemoDialog, { ...p, onClose: close }, Date.now()));
1014
+ },
1015
+ close
1016
+ };
1017
+ }
1018
+
1019
+ // src/brands.js
1020
+ var brands = {
1021
+ billpro: {
1022
+ id: "billpro",
1023
+ name: "BillPro",
1024
+ primary: "#15803d",
1025
+ // current #19a249, darkened one step for AA contrast on white
1026
+ accent: "#4ade80",
1027
+ logoSrc: "/brand/billpro-mark.svg",
1028
+ headline: "Billing, inventory and GST \u2014 done right, every day.",
1029
+ pitch: "GST invoices, stock, purchases and accounts for growing Indian businesses.",
1030
+ points: ["GST-ready invoices and returns", "Live inventory across branches", "Payments, ledgers and reports"],
1031
+ category: "Billing & Inventory \xB7 by Dreamtree-Org"
1032
+ },
1033
+ taskpro: {
1034
+ id: "taskpro",
1035
+ name: "TaskPro",
1036
+ primary: "#065f46",
1037
+ accent: "#34d399",
1038
+ logoSrc: "/taskpro-mark-48.webp",
1039
+ headline: "Projects and workflows, shaped the way your team works.",
1040
+ pitch: "Configurable project types, statuses and automations \u2014 one place for every task.",
1041
+ points: ["Your own workflows and statuses", "Boards, timelines and my-work", "Automations and audit trail"],
1042
+ category: "Project & Workflow Management \xB7 by Dreamtree-Org"
1043
+ },
1044
+ venturepro: {
1045
+ id: "venturepro",
1046
+ name: "VenturePro",
1047
+ primary: "#1e3a6e",
1048
+ accent: "#e5ad42",
1049
+ // accent-400, as shipped
1050
+ panel: "#182e57",
1051
+ // primary-700, as shipped
1052
+ logoSrc: "/brand/venturepro-mark.svg",
1053
+ headline: "Every venture, block and flat \u2014 in one place.",
1054
+ pitch: "Create ventures, lay out blocks and units, track sales, rentals and collections across your whole portfolio.",
1055
+ points: [],
1056
+ category: "Builder Property & Apartment Management System"
1057
+ },
1058
+ campaignpro: {
1059
+ id: "campaignpro",
1060
+ name: "CampaignPro",
1061
+ primary: "#6d28d9",
1062
+ // PROPOSED — was the same red as firepro
1063
+ accent: "#a78bfa",
1064
+ headline: "Run every campaign from one pipeline.",
1065
+ pitch: "Plan, send and track campaigns across channels with your whole team.",
1066
+ points: ["Multi-channel campaigns", "Pipeline and follow-ups", "Team roles and approvals"],
1067
+ category: "Campaign Management \xB7 by Dreamtree-Org"
1068
+ },
1069
+ firepro: {
1070
+ id: "firepro",
1071
+ name: "FirePro",
1072
+ primary: "#b42318",
1073
+ // keeps the red — it is the fire-safety product
1074
+ accent: "#fb923c",
1075
+ headline: "Fire safety compliance, inspections and service \u2014 on schedule.",
1076
+ pitch: "Assets, inspections, service jobs and certificates for fire-safety teams.",
1077
+ points: ["Scheduled inspections", "Asset and site registers", "Certificates and reports"],
1078
+ category: "Fire Safety Operations \xB7 by Dreamtree-Org"
1079
+ },
1080
+ procurementpro: {
1081
+ id: "procurementpro",
1082
+ name: "ProcurementPro",
1083
+ primary: "#1d4ed8",
1084
+ // current #2563eb, one step darker for panel contrast
1085
+ accent: "#60a5fa",
1086
+ headline: "From request to purchase order, without the chase.",
1087
+ pitch: "RFQs, quotations, approvals and purchase orders in one audited flow.",
1088
+ points: ["RFQs and quotation comparison", "Approval workflows", "Purchase orders and vendors"],
1089
+ category: "Procurement \xB7 by Dreamtree-Org"
1090
+ },
1091
+ fitweavepro: {
1092
+ id: "fitweavepro",
1093
+ name: "FitWeavePro",
1094
+ primary: "#be185d",
1095
+ // PROPOSED — was Tailwind blue
1096
+ accent: "#f9a8d4",
1097
+ headline: "Made-to-measure, made simple.",
1098
+ pitch: "Measurements, patterns and orders for tailoring shops.",
1099
+ points: ["Customer measurements", "Pattern and cutting plans", "Orders and deliveries"],
1100
+ category: "Tailoring Shop Management \xB7 by Dreamtree-Org"
1101
+ },
1102
+ aiagentbuilder: {
1103
+ id: "aiagentbuilder",
1104
+ name: "AI Agent Builder",
1105
+ primary: "#0f766e",
1106
+ // PROPOSED — was blue, same as procurementpro
1107
+ accent: "#5eead4",
1108
+ headline: "Build, approve and ship AI agents your team can trust.",
1109
+ pitch: "Multi-provider agents with approvals, knowledge bases, voice and an MCP server.",
1110
+ points: ["Human-in-the-loop approvals", "Knowledge bases (RAG)", "Voice calls and campaigns"],
1111
+ category: "AI Agent Platform \xB7 by Dreamtree-Org"
1112
+ },
1113
+ runloompro: {
1114
+ id: "runloompro",
1115
+ name: "RunLoom",
1116
+ primary: "#4f46e5",
1117
+ accent: "#a5b4fc",
1118
+ headline: "Missions, run reliably.",
1119
+ pitch: "Orchestrate long-running work across workers with full telemetry.",
1120
+ points: ["Durable missions", "Node and Python workers", "Telemetry built in"],
1121
+ category: "by Dreamtree-Org"
1122
+ },
1123
+ appforge: {
1124
+ id: "appforge",
1125
+ name: "AppForge",
1126
+ primary: "#1f3864",
1127
+ accent: "#2563eb",
1128
+ headline: "Design, build and publish business apps.",
1129
+ pitch: "Schema-driven apps with policy, review and one-click release.",
1130
+ points: ["Visual builder", "Policies and RBAC", "Review and publish"],
1131
+ category: "by Dreamtree-Org"
1132
+ }
1133
+ };
1134
+ function getBrand(id) {
1135
+ const b = brands[id];
1136
+ if (!b) throw new Error(`landing-kit: unknown brand "${id}" (known: ${Object.keys(brands).join(", ")})`);
1137
+ return b;
1138
+ }