@spectare-personalisation/react 0.1.4 → 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 CHANGED
@@ -5,99 +5,125 @@ var marked = require('marked');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
 
7
7
  // src/PersonalisedSection.tsx
8
+
9
+ // src/types.ts
10
+ var COMPONENT_ZONES = {
11
+ HeroStatement: "hero",
12
+ ImageCtaHero: "hero",
13
+ AtomCard: "body",
14
+ StatGrid: "body",
15
+ CodeBlock: "body",
16
+ ComparisonTable: "body",
17
+ FeatureList: "body",
18
+ TestimonialCard: "proof",
19
+ CtaStrip: "cta"
20
+ };
21
+ function filterAssemblyByZone(assembly, zone) {
22
+ return assembly.filter((item) => {
23
+ var _a;
24
+ const effectiveZone = (_a = item.zone) != null ? _a : COMPONENT_ZONES[item.component];
25
+ return effectiveZone === zone;
26
+ });
27
+ }
8
28
  function renderMarkdown(content) {
9
29
  return marked.marked.parse(content, { async: false });
10
30
  }
11
31
  var HALF_COMPONENTS = /* @__PURE__ */ new Set(["TestimonialCard"]);
12
32
  function HeroStatement({ headline, subheading }) {
13
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { paddingTop: "1.5rem", paddingBottom: "1.5rem" }, children: [
14
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: { fontSize: "2rem", fontWeight: 700, letterSpacing: "-0.025em", lineHeight: 1.2, color: "var(--sp-text)", margin: "0 0 0.75rem" }, children: headline }),
15
- subheading && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "1.125rem", color: "var(--sp-text-sub)", lineHeight: 1.6, maxWidth: "42rem", margin: 0 }, children: subheading })
33
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { paddingTop: "24px", paddingBottom: "24px" }, children: [
34
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: { fontSize: "32px", fontWeight: 700, letterSpacing: "-0.025em", lineHeight: 1.2, color: "var(--sp-text)", margin: "0 0 12px" }, children: headline }),
35
+ subheading && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "18px", color: "var(--sp-text-sub)", lineHeight: 1.6, maxWidth: "672px", margin: 0 }, children: subheading })
16
36
  ] });
17
37
  }
18
38
  function AtomCard({ title, content }) {
19
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: "0.75rem", padding: "1.5rem", height: "100%" }, children: [
20
- title && /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { fontSize: "1rem", fontWeight: 600, color: "var(--sp-text)", margin: "0 0 0.75rem" }, children: title }),
39
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: "12px", padding: "24px", height: "100%" }, children: [
40
+ title && /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { fontSize: "16px", fontWeight: 600, color: "var(--sp-text)", margin: "0 0 12px" }, children: title }),
21
41
  content && /* @__PURE__ */ jsxRuntime.jsx(
22
42
  "div",
23
43
  {
24
44
  className: "sp-prose",
25
- style: { fontSize: "0.875rem", color: "var(--sp-text-sub)", lineHeight: 1.6 },
45
+ style: { fontSize: "15px", color: "var(--sp-text-sub)", lineHeight: 1.6 },
26
46
  dangerouslySetInnerHTML: { __html: renderMarkdown(content) }
27
47
  }
28
48
  )
29
49
  ] });
30
50
  }
31
- function StatGrid({ stats, caption }) {
51
+ function StatGrid({ stats = [], caption }) {
32
52
  const cols = stats.length === 2 ? 2 : stats.length === 3 ? 3 : 4;
33
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: "0.75rem", padding: "1.5rem" }, children: [
34
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "grid", gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: "1.5rem" }, children: stats.map(({ value, label }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center" }, children: [
35
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "1.875rem", fontWeight: 700, color: "var(--sp-text)", fontVariantNumeric: "tabular-nums", margin: 0 }, children: value }),
36
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.75rem", color: "var(--sp-text-muted)", marginTop: "0.375rem", textTransform: "uppercase", letterSpacing: "0.05em" }, children: label })
53
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
54
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "grid", gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: "12px" }, children: stats.map(({ value, label }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: "10px", padding: "16px 20px", display: "flex", flexDirection: "column", justifyContent: "space-between", minHeight: "88px" }, children: [
55
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "11px", color: "var(--sp-text-muted)", textTransform: "uppercase", letterSpacing: "0.06em", margin: "0 0 12px", lineHeight: 1.3 }, children: label }),
56
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "20px", fontWeight: 500, color: "var(--sp-text)", fontVariantNumeric: "tabular-nums", lineHeight: 1, margin: 0 }, children: value })
37
57
  ] }, label)) }),
38
- caption && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.75rem", color: "var(--sp-text-muted)", textAlign: "center", marginTop: "1.25rem", borderTop: "1px solid var(--sp-border)", paddingTop: "1rem" }, children: caption })
58
+ caption && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "13px", color: "var(--sp-text-muted)", margin: "12px 0 0" }, children: caption })
39
59
  ] });
40
60
  }
41
61
  function CodeBlock({ code, lang = "typescript", caption }) {
42
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { borderRadius: "0.75rem", overflow: "hidden", border: "1px solid var(--sp-border)" }, children: [
43
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { background: "var(--sp-bg)", padding: "0.625rem 1rem", display: "flex", alignItems: "center", justifyContent: "space-between", borderBottom: "1px solid var(--sp-border)" }, children: [
44
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.75rem", color: "var(--sp-text-muted)", fontFamily: "monospace" }, children: lang }),
45
- caption && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.75rem", color: "var(--sp-text-muted)" }, children: caption })
62
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { borderRadius: "12px", overflow: "hidden", border: "1px solid var(--sp-border)" }, children: [
63
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { background: "var(--sp-bg)", padding: "10px 16px", display: "flex", alignItems: "center", justifyContent: "space-between", borderBottom: "1px solid var(--sp-border)" }, children: [
64
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12px", color: "var(--sp-text-muted)", fontFamily: "monospace" }, children: lang }),
65
+ caption && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12px", color: "var(--sp-text-muted)" }, children: caption })
46
66
  ] }),
47
- /* @__PURE__ */ jsxRuntime.jsx("pre", { style: { background: "var(--sp-surface)", padding: "1.25rem", fontSize: "0.75rem", color: "var(--sp-text-sub)", overflowX: "auto", lineHeight: 1.6, fontFamily: "monospace", whiteSpace: "pre", margin: 0 }, children: code })
67
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { style: { background: "var(--sp-surface)", padding: "20px", fontSize: "13px", color: "var(--sp-text-sub)", overflowX: "auto", lineHeight: 1.6, fontFamily: "monospace", whiteSpace: "pre", margin: 0 }, children: code })
48
68
  ] });
49
69
  }
50
- function ComparisonTable({ brand = "Us", competitor, rows }) {
51
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { border: "1px solid var(--sp-border)", borderRadius: "0.75rem", overflow: "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsxs("table", { style: { width: "100%", fontSize: "0.875rem", borderCollapse: "collapse" }, children: [
70
+ function ComparisonTable({ brand = "Us", competitor, rows = [] }) {
71
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { border: "1px solid var(--sp-border)", borderRadius: "12px", overflow: "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsxs("table", { style: { width: "100%", fontSize: "14px", borderCollapse: "collapse" }, children: [
52
72
  /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { style: { borderBottom: "1px solid var(--sp-border)", background: "var(--sp-bg)" }, children: [
53
- /* @__PURE__ */ jsxRuntime.jsx("th", { style: { textAlign: "left", padding: "0.75rem 1rem", color: "var(--sp-text-muted)", fontWeight: 500, fontSize: "0.75rem", width: "33%" } }),
54
- /* @__PURE__ */ jsxRuntime.jsx("th", { style: { textAlign: "left", padding: "0.75rem 1rem", fontWeight: 600, color: "var(--sp-accent)", fontSize: "0.75rem" }, children: brand }),
55
- /* @__PURE__ */ jsxRuntime.jsx("th", { style: { textAlign: "left", padding: "0.75rem 1rem", color: "var(--sp-text-muted)", fontWeight: 500, fontSize: "0.75rem" }, children: competitor })
73
+ /* @__PURE__ */ jsxRuntime.jsx("th", { style: { textAlign: "left", padding: "12px 16px", color: "var(--sp-text-muted)", fontWeight: 500, fontSize: "12px", width: "33%" } }),
74
+ /* @__PURE__ */ jsxRuntime.jsx("th", { style: { textAlign: "left", padding: "12px 16px", fontWeight: 600, color: "var(--sp-accent)", fontSize: "12px" }, children: brand }),
75
+ /* @__PURE__ */ jsxRuntime.jsx("th", { style: { textAlign: "left", padding: "12px 16px", color: "var(--sp-text-muted)", fontWeight: 500, fontSize: "12px" }, children: competitor })
56
76
  ] }) }),
57
77
  /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map(({ label, spectare, them }) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { style: { borderBottom: "1px solid var(--sp-border)" }, children: [
58
- /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "0.75rem 1rem", fontSize: "0.75rem", color: "var(--sp-text-muted)", fontWeight: 500 }, children: label }),
59
- /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "0.75rem 1rem", fontSize: "0.75rem", color: "var(--sp-positive)", fontWeight: 500 }, children: spectare }),
60
- /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "0.75rem 1rem", fontSize: "0.75rem", color: "var(--sp-text-muted)" }, children: them })
78
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "12px 16px", fontSize: "13px", color: "var(--sp-text-muted)", fontWeight: 500 }, children: label }),
79
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "12px 16px", fontSize: "13px", color: "var(--sp-positive)", fontWeight: 500 }, children: spectare }),
80
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "12px 16px", fontSize: "13px", color: "var(--sp-text-muted)" }, children: them })
61
81
  ] }, label)) })
62
82
  ] }) }) });
63
83
  }
64
- function FeatureList({ items }) {
65
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: "0.75rem", padding: "1.5rem" }, children: /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: "1rem" }, children: items.map(({ text, sub }) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: { display: "flex", gap: "0.75rem" }, children: [
66
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--sp-accent)", flexShrink: 0, fontSize: "0.875rem", marginTop: "0.125rem" }, children: "\u2713" }),
84
+ function FeatureList({ items = [] }) {
85
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: "12px", padding: "24px" }, children: /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: "16px" }, children: items.map(({ text, sub }) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: { display: "flex", gap: "12px" }, children: [
86
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--sp-accent)", flexShrink: 0, fontSize: "15px", marginTop: "2px" }, children: "\u2713" }),
67
87
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
68
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", fontWeight: 500, color: "var(--sp-text)", lineHeight: 1.4, margin: 0 }, children: text }),
69
- sub && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.75rem", color: "var(--sp-text-muted)", marginTop: "0.25rem", lineHeight: 1.5, margin: "0.25rem 0 0" }, children: sub })
88
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "15px", fontWeight: 500, color: "var(--sp-text)", lineHeight: 1.4, margin: 0 }, children: text }),
89
+ sub && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "13px", color: "var(--sp-text-muted)", lineHeight: 1.5, margin: "4px 0 0" }, children: sub })
70
90
  ] })
71
91
  ] }, text)) }) });
72
92
  }
73
93
  function TestimonialCard({ quote, name, role, company }) {
74
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: "0.75rem", padding: "1.5rem", display: "flex", flexDirection: "column", gap: "1.25rem", height: "100%" }, children: [
75
- /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "0.875rem", color: "var(--sp-text-sub)", lineHeight: 1.6, flex: 1, margin: 0 }, children: [
76
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--sp-text-dim)", fontSize: "1.125rem", lineHeight: 1, marginRight: "0.25rem" }, children: '"' }),
94
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: "12px", padding: "24px", display: "flex", flexDirection: "column", gap: "20px", height: "100%" }, children: [
95
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "15px", color: "var(--sp-text-sub)", lineHeight: 1.6, flex: 1, margin: 0 }, children: [
96
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--sp-text-dim)", fontSize: "18px", lineHeight: 1, marginRight: "4px" }, children: '"' }),
77
97
  quote,
78
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--sp-text-dim)", fontSize: "1.125rem", lineHeight: 1, marginLeft: "0.25rem" }, children: '"' })
98
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--sp-text-dim)", fontSize: "18px", lineHeight: 1, marginLeft: "4px" }, children: '"' })
79
99
  ] }),
80
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { borderTop: "1px solid var(--sp-border)", paddingTop: "1rem" }, children: [
81
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", fontWeight: 600, color: "var(--sp-text)", margin: 0 }, children: name }),
82
- /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "0.75rem", color: "var(--sp-text-muted)", marginTop: "0.125rem", margin: "0.125rem 0 0" }, children: [
100
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { borderTop: "1px solid var(--sp-border)", paddingTop: "16px" }, children: [
101
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "14px", fontWeight: 600, color: "var(--sp-text)", margin: 0 }, children: name }),
102
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "13px", color: "var(--sp-text-muted)", margin: "2px 0 0" }, children: [
83
103
  role,
84
104
  company ? `, ${company}` : ""
85
105
  ] })
86
106
  ] })
87
107
  ] });
88
108
  }
89
- function ImageHero({ src, alt = "", ratio = "16:9" }) {
109
+ function ImageCtaHero({ src, alt = "", headline, subheading, ctaLabel, ctaHref }) {
90
110
  if (!src) return null;
91
- const [w, h] = ratio.split(":").map(Number);
92
- const paddingBottom = w && h ? `${h / w * 100}%` : "56.25%";
93
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { borderRadius: "0.75rem", overflow: "hidden", position: "relative", width: "100%", paddingBottom }, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt, style: { position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" } }) });
111
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { borderRadius: "12px", overflow: "hidden", position: "relative", width: "100%", paddingBottom: "56.25%" }, children: [
112
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt, style: { position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" } }),
113
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", inset: 0, background: "linear-gradient(to top, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.3) 55%, transparent 100%)" } }),
114
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "absolute", bottom: 0, left: 0, right: 0, padding: "28px" }, children: [
115
+ headline && /* @__PURE__ */ jsxRuntime.jsx("h2", { style: { fontSize: "24px", fontWeight: 700, color: "#fff", lineHeight: 1.2, margin: "0 0 8px", letterSpacing: "-0.02em" }, children: headline }),
116
+ subheading && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "15px", color: "rgba(255,255,255,0.75)", lineHeight: 1.5, margin: "0 0 20px" }, children: subheading }),
117
+ ctaHref && ctaLabel && /* @__PURE__ */ jsxRuntime.jsx("a", { href: ctaHref, style: { display: "inline-block", background: "#fff", color: "#09090b", padding: "8px 20px", borderRadius: "8px", fontWeight: 600, fontSize: "14px", textDecoration: "none" }, children: ctaLabel })
118
+ ] })
119
+ ] });
94
120
  }
95
121
  function CtaStrip({ headline, primary, secondary }) {
96
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { border: "1px solid var(--sp-border)", borderRadius: "0.75rem", padding: "2rem", textAlign: "center", background: "var(--sp-bg)" }, children: [
97
- /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { fontSize: "1.5rem", fontWeight: 700, color: "var(--sp-text)", margin: "0 0 1.5rem" }, children: headline }),
98
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "1rem", flexWrap: "wrap" }, children: [
99
- /* @__PURE__ */ jsxRuntime.jsx("a", { href: primary.href, style: { background: "#fff", color: "#09090b", padding: "0.625rem 1.5rem", borderRadius: "0.75rem", fontWeight: 600, fontSize: "0.875rem", textDecoration: "none" }, children: primary.label }),
100
- secondary && /* @__PURE__ */ jsxRuntime.jsxs("a", { href: secondary.href, style: { fontSize: "0.875rem", color: "var(--sp-text-sub)", textDecoration: "none" }, children: [
122
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { border: "1px solid var(--sp-border)", borderRadius: "12px", padding: "32px", textAlign: "center", background: "var(--sp-bg)" }, children: [
123
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { fontSize: "24px", fontWeight: 700, color: "var(--sp-text)", margin: "0 0 24px" }, children: headline }),
124
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "16px", flexWrap: "wrap" }, children: [
125
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: primary.href, style: { background: "#fff", color: "#09090b", padding: "10px 24px", borderRadius: "12px", fontWeight: 600, fontSize: "15px", textDecoration: "none" }, children: primary.label }),
126
+ secondary && /* @__PURE__ */ jsxRuntime.jsxs("a", { href: secondary.href, style: { fontSize: "15px", color: "var(--sp-text-sub)", textDecoration: "none" }, children: [
101
127
  secondary.label,
102
128
  " \u2192"
103
129
  ] })
@@ -122,8 +148,8 @@ function renderSingle(item, brand) {
122
148
  return /* @__PURE__ */ jsxRuntime.jsx(FeatureList, { items: s.items });
123
149
  case "TestimonialCard":
124
150
  return /* @__PURE__ */ jsxRuntime.jsx(TestimonialCard, { quote: s.quote, name: s.name, role: s.role, company: s.company });
125
- case "ImageHero":
126
- return /* @__PURE__ */ jsxRuntime.jsx(ImageHero, { src: s.src, alt: s.alt, ratio: s.ratio });
151
+ case "ImageCtaHero":
152
+ return /* @__PURE__ */ jsxRuntime.jsx(ImageCtaHero, { src: s.src, alt: s.alt, headline: s.headline, subheading: s.subheading, ctaLabel: s.ctaLabel, ctaHref: s.ctaHref });
127
153
  case "CtaStrip":
128
154
  return /* @__PURE__ */ jsxRuntime.jsx(CtaStrip, { headline: s.headline, primary: s.primary, secondary: s.secondary });
129
155
  default:
@@ -154,48 +180,44 @@ function buildLayout(assembly) {
154
180
  return groups;
155
181
  }
156
182
  function XrayBadge({ name, size }) {
157
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "absolute", top: "0.5rem", left: "0.5rem", zIndex: 10, display: "flex", alignItems: "center", gap: "0.375rem", pointerEvents: "none", userSelect: "none" }, children: [
158
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.625rem", fontFamily: "monospace", background: "rgba(59,130,246,0.9)", color: "#fff", padding: "0.125rem 0.375rem", borderRadius: "0.25rem", lineHeight: 1 }, children: name }),
159
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.625rem", fontFamily: "monospace", color: "#71717a", lineHeight: 1 }, children: size })
183
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "absolute", top: "8px", left: "8px", zIndex: 10, display: "flex", alignItems: "center", gap: "6px", pointerEvents: "none", userSelect: "none" }, children: [
184
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "10px", fontFamily: "monospace", background: "rgba(59,130,246,0.9)", color: "#fff", padding: "2px 6px", borderRadius: "4px", lineHeight: 1 }, children: name }),
185
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "10px", fontFamily: "monospace", color: "#71717a", lineHeight: 1 }, children: size })
160
186
  ] });
161
187
  }
162
- function ComponentRenderer({ assembly, brand, xray = false }) {
163
- const layout = buildLayout(assembly);
164
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "1.25rem" }, children: layout.map((group, i) => {
165
- if (group.type === "full") {
188
+ var PAIR_STYLE = ".sp-pair{display:grid;grid-template-columns:1fr 1fr;gap:20px}@media(max-width:640px){.sp-pair{grid-template-columns:1fr}}";
189
+ function ComponentRenderer({ assembly, brand, xray = false, zone }) {
190
+ const filtered = zone ? filterAssemblyByZone(assembly, zone) : assembly;
191
+ const layout = buildLayout(filtered);
192
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "20px", fontSize: "16px" }, children: [
193
+ /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: PAIR_STYLE } }),
194
+ layout.map((group, i) => {
195
+ if (group.type === "full") {
196
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
197
+ xray && /* @__PURE__ */ jsxRuntime.jsx(XrayBadge, { name: group.item.component, size: "full" }),
198
+ renderSingle(group.item, brand)
199
+ ] }, i);
200
+ }
201
+ if (group.type === "pair") {
202
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sp-pair", children: [
203
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
204
+ xray && /* @__PURE__ */ jsxRuntime.jsx(XrayBadge, { name: group.items[0].component, size: "half" }),
205
+ renderSingle(group.items[0], brand)
206
+ ] }),
207
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
208
+ xray && /* @__PURE__ */ jsxRuntime.jsx(XrayBadge, { name: group.items[1].component, size: "half" }),
209
+ renderSingle(group.items[1], brand)
210
+ ] })
211
+ ] }, i);
212
+ }
166
213
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
167
214
  xray && /* @__PURE__ */ jsxRuntime.jsx(XrayBadge, { name: group.item.component, size: "full" }),
168
215
  renderSingle(group.item, brand)
169
216
  ] }, i);
170
- }
171
- if (group.type === "pair") {
172
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "1.25rem" }, children: [
173
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
174
- xray && /* @__PURE__ */ jsxRuntime.jsx(XrayBadge, { name: group.items[0].component, size: "half" }),
175
- renderSingle(group.items[0], brand)
176
- ] }),
177
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
178
- xray && /* @__PURE__ */ jsxRuntime.jsx(XrayBadge, { name: group.items[1].component, size: "half" }),
179
- renderSingle(group.items[1], brand)
180
- ] })
181
- ] }, i);
182
- }
183
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: xray ? { position: "relative" } : void 0, children: [
184
- xray && /* @__PURE__ */ jsxRuntime.jsx(XrayBadge, { name: group.item.component, size: "full" }),
185
- renderSingle(group.item, brand)
186
- ] }, i);
187
- }) });
217
+ })
218
+ ] });
188
219
  }
189
220
  var CSS_TOKENS = `:root{--sp-accent:#60a5fa;--sp-accent-bg:rgba(96,165,250,0.1);--sp-accent-border:rgba(96,165,250,0.2);--sp-bg:#18181b;--sp-surface:#09090b;--sp-border:#27272a;--sp-text:#f4f4f5;--sp-text-sub:#d4d4d8;--sp-text-strong:#e4e4e7;--sp-text-muted:#71717a;--sp-text-dim:#52525b;--sp-text-body:#a1a1aa;--sp-positive:#6ee7b7;--sp-divider:rgba(255,255,255,0.06);--sp-code-bg:rgba(255,255,255,0.07);--sp-code-border:rgba(255,255,255,0.08);--sp-pre-bg:rgba(0,0,0,0.4)}.sp-prose p{margin-bottom:.625rem}.sp-prose p:last-child{margin-bottom:0}.sp-prose ul{list-style:disc;padding-left:1.25rem;margin-bottom:.625rem}.sp-prose ol{list-style:decimal;padding-left:1.25rem;margin-bottom:.625rem}.sp-prose li{margin-bottom:.25rem}.sp-prose strong{color:var(--sp-text-strong);font-weight:600}.sp-prose h2,.sp-prose h3{color:var(--sp-text);font-weight:600;margin:.875rem 0 .375rem;font-size:1rem}.sp-prose code{background:var(--sp-code-bg);border:1px solid var(--sp-code-border);padding:.1rem .35rem;border-radius:.25rem;font-size:.82em;color:var(--sp-text)}.sp-prose blockquote{border-left:3px solid var(--sp-border);padding-left:1rem;color:var(--sp-text-muted);margin:.75rem 0}`;
190
- function extractAtomIds(assembly) {
191
- var _a;
192
- const ids = [];
193
- for (const item of assembly) {
194
- const id = (_a = item.slots) == null ? void 0 : _a.atomId;
195
- if (typeof id === "number") ids.push(id);
196
- }
197
- return ids;
198
- }
199
221
  function buildSummary(pageHint, orgSlug) {
200
222
  const parts = [pageHint];
201
223
  const referrer = document.referrer;
@@ -217,11 +239,11 @@ function buildSummary(pageHint, orgSlug) {
217
239
  return parts.filter(Boolean).join(". ");
218
240
  }
219
241
  function Shimmer() {
220
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
221
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "1.25rem", background: "rgba(39,39,42,0.6)", borderRadius: "0.5rem", width: "75%", animation: "sp-pulse 1.5s ease-in-out infinite" } }),
222
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "0.875rem", background: "rgba(39,39,42,0.4)", borderRadius: "0.5rem", width: "100%", animation: "sp-pulse 1.5s ease-in-out infinite" } }),
223
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "0.875rem", background: "rgba(39,39,42,0.4)", borderRadius: "0.5rem", width: "83%", animation: "sp-pulse 1.5s ease-in-out infinite" } }),
224
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "0.875rem", background: "rgba(39,39,42,0.4)", borderRadius: "0.5rem", width: "67%", animation: "sp-pulse 1.5s ease-in-out infinite" } })
242
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
243
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "20px", background: "rgba(39,39,42,0.6)", borderRadius: "8px", width: "75%", animation: "sp-pulse 1.5s ease-in-out infinite" } }),
244
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "14px", background: "rgba(39,39,42,0.4)", borderRadius: "8px", width: "100%", animation: "sp-pulse 1.5s ease-in-out infinite" } }),
245
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "14px", background: "rgba(39,39,42,0.4)", borderRadius: "8px", width: "83%", animation: "sp-pulse 1.5s ease-in-out infinite" } }),
246
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "14px", background: "rgba(39,39,42,0.4)", borderRadius: "8px", width: "67%", animation: "sp-pulse 1.5s ease-in-out infinite" } })
225
247
  ] });
226
248
  }
227
249
  function PersonalisedSection({
@@ -233,13 +255,13 @@ function PersonalisedSection({
233
255
  style,
234
256
  initialAssembly,
235
257
  initialIntent,
236
- conversionUrlPatterns
258
+ zone
237
259
  }) {
238
- const [assembly, setAssembly] = react.useState(initialAssembly != null ? initialAssembly : null);
260
+ const [assembly, setAssembly] = react.useState(initialAssembly != null ? initialAssembly : []);
239
261
  const [loading, setLoading] = react.useState(!initialAssembly);
262
+ const [orgName, setOrgName] = react.useState(void 0);
240
263
  const tokenRef = react.useRef(null);
241
264
  const conversionFiredRef = react.useRef(false);
242
- const conversionPatternsRef = react.useRef(conversionUrlPatterns != null ? conversionUrlPatterns : []);
243
265
  react.useEffect(() => {
244
266
  let cancelled = false;
245
267
  async function load() {
@@ -263,11 +285,10 @@ function PersonalisedSection({
263
285
  setLoading(false);
264
286
  return;
265
287
  }
266
- const data2 = await res2.json();
267
- token = (_a = data2.token) != null ? _a : null;
288
+ const data = await res2.json();
289
+ token = (_a = data.token) != null ? _a : null;
268
290
  if (token) sessionStorage.setItem(tokenKey, token);
269
- const orgPatterns = (_b = data2.conversionUrlPatterns) != null ? _b : [];
270
- conversionPatternsRef.current = [.../* @__PURE__ */ new Set([...conversionUrlPatterns != null ? conversionUrlPatterns : [], ...orgPatterns])];
291
+ if (data.orgName) setOrgName(data.orgName);
271
292
  }
272
293
  if (!token || cancelled) {
273
294
  setLoading(false);
@@ -292,12 +313,10 @@ function PersonalisedSection({
292
313
  return;
293
314
  }
294
315
  const qData = await qRes.json();
295
- token = (_c = qData.token) != null ? _c : null;
316
+ token = (_b = qData.token) != null ? _b : null;
296
317
  if (token) {
297
318
  sessionStorage.setItem(tokenKey, token);
298
319
  tokenRef.current = token;
299
- const orgPatterns = (_d = qData.conversionUrlPatterns) != null ? _d : [];
300
- conversionPatternsRef.current = [.../* @__PURE__ */ new Set([...conversionUrlPatterns != null ? conversionUrlPatterns : [], ...orgPatterns])];
301
320
  }
302
321
  if (!token || cancelled) {
303
322
  setLoading(false);
@@ -313,13 +332,47 @@ function PersonalisedSection({
313
332
  setLoading(false);
314
333
  return;
315
334
  }
316
- const data = await res.json();
317
- if (cancelled) return;
318
- const clientAudience = (_f = (_e = data.intent) == null ? void 0 : _e.userContext) == null ? void 0 : _f.audience;
319
- const clientStage = (_h = (_g = data.intent) == null ? void 0 : _g.userContext) == null ? void 0 : _h.stage;
320
- const ssrMatches = initialIntent && clientAudience === initialIntent.audience && clientStage === initialIntent.stage;
321
- if (!ssrMatches && Array.isArray(data.assembly) && data.assembly.length > 0) {
322
- setAssembly(data.assembly);
335
+ const contentType = (_c = res.headers.get("content-type")) != null ? _c : "";
336
+ if (contentType.includes("text/event-stream")) {
337
+ const reader = res.body.getReader();
338
+ const decoder = new TextDecoder();
339
+ let buf = "";
340
+ let loadingCleared = false;
341
+ try {
342
+ while (!cancelled) {
343
+ const { done, value } = await reader.read();
344
+ if (done || cancelled) break;
345
+ buf += decoder.decode(value, { stream: true });
346
+ const lines = buf.split("\n");
347
+ buf = (_d = lines.pop()) != null ? _d : "";
348
+ for (const line of lines) {
349
+ if (!line.startsWith("data: ")) continue;
350
+ const payload = line.slice(6).trim();
351
+ if (payload === "[DONE]") break;
352
+ try {
353
+ const comp = JSON.parse(payload);
354
+ if (!loadingCleared) {
355
+ setLoading(false);
356
+ loadingCleared = true;
357
+ }
358
+ setAssembly((prev) => [...prev, comp]);
359
+ } catch (e) {
360
+ }
361
+ }
362
+ }
363
+ } finally {
364
+ reader.cancel().catch(() => {
365
+ });
366
+ }
367
+ } else {
368
+ const data = await res.json();
369
+ if (cancelled) return;
370
+ const clientAudience = (_f = (_e = data.intent) == null ? void 0 : _e.userContext) == null ? void 0 : _f.audience;
371
+ const clientStage = (_h = (_g = data.intent) == null ? void 0 : _g.userContext) == null ? void 0 : _h.stage;
372
+ const ssrMatches = initialIntent && clientAudience === initialIntent.audience && clientStage === initialIntent.stage;
373
+ if (!ssrMatches && Array.isArray(data.assembly) && data.assembly.length > 0) {
374
+ setAssembly(data.assembly);
375
+ }
323
376
  }
324
377
  } catch (e) {
325
378
  } finally {
@@ -332,28 +385,62 @@ function PersonalisedSection({
332
385
  };
333
386
  }, [orgSlug, baseUrl, pageHint, initialAssembly, initialIntent]);
334
387
  react.useEffect(() => {
335
- if (!assembly || !conversionPatternsRef.current.length || conversionFiredRef.current) return;
336
- const url = window.location.href;
337
- if (!conversionPatternsRef.current.some((p) => url.includes(p))) return;
338
- conversionFiredRef.current = true;
388
+ if (!assembly.length || conversionFiredRef.current) return;
339
389
  const token = tokenRef.current;
340
390
  if (!token) return;
341
- fetch(`${baseUrl}/api/conversion`, {
391
+ const url = window.location.href;
392
+ fetch(`${baseUrl}/api/conversion-check`, {
342
393
  method: "POST",
343
394
  headers: { "Content-Type": "application/json" },
344
- body: JSON.stringify({ token, orgSlug, url, atomsShown: extractAtomIds(assembly) })
395
+ body: JSON.stringify({ orgSlug, url })
396
+ }).then((r) => r.json()).then((data) => {
397
+ var _a, _b;
398
+ if (!data.matched) return;
399
+ conversionFiredRef.current = true;
400
+ let goalValue = null;
401
+ let goalCurrency = data.defaultCurrency;
402
+ if (data.valueSelector) {
403
+ try {
404
+ const el = document.querySelector(data.valueSelector);
405
+ if (el) {
406
+ const num = parseFloat(((_a = el.textContent) != null ? _a : "").trim().replace(/[^0-9.]/g, ""));
407
+ if (!isNaN(num)) goalValue = num;
408
+ }
409
+ } catch (e) {
410
+ }
411
+ }
412
+ if (data.currencySelector) {
413
+ try {
414
+ const el = document.querySelector(data.currencySelector);
415
+ if (el) goalCurrency = ((_b = el.textContent) != null ? _b : "").trim() || goalCurrency;
416
+ } catch (e) {
417
+ }
418
+ }
419
+ fetch(`${baseUrl}/api/conversion`, {
420
+ method: "POST",
421
+ headers: { "Content-Type": "application/json" },
422
+ body: JSON.stringify({
423
+ token,
424
+ orgSlug,
425
+ url,
426
+ ...data.goalName ? { goalName: data.goalName } : {},
427
+ ...goalValue !== null ? { goalValue, goalCurrency } : {}
428
+ })
429
+ }).catch(() => {
430
+ });
345
431
  }).catch(() => {
346
432
  });
347
433
  }, [assembly, orgSlug, baseUrl]);
348
- if (!loading && !assembly) return null;
434
+ if (!loading && assembly.length === 0) return null;
349
435
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
350
436
  /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: CSS_TOKENS } }),
351
437
  /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: "@keyframes sp-pulse{0%,100%{opacity:1}50%{opacity:0.4}}" } }),
352
- /* @__PURE__ */ jsxRuntime.jsx("div", { className, style, children: loading ? /* @__PURE__ */ jsxRuntime.jsx(Shimmer, {}) : assembly && /* @__PURE__ */ jsxRuntime.jsx(ComponentRenderer, { assembly, brand }) })
438
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className, style, children: loading && assembly.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(Shimmer, {}) : /* @__PURE__ */ jsxRuntime.jsx(ComponentRenderer, { assembly: zone ? filterAssemblyByZone(assembly, zone) : assembly, brand: brand != null ? brand : orgName }) })
353
439
  ] });
354
440
  }
355
441
 
356
442
  exports.ComponentRenderer = ComponentRenderer;
357
443
  exports.PersonalisedSection = PersonalisedSection;
444
+ exports.filterAssemblyByZone = filterAssemblyByZone;
358
445
  //# sourceMappingURL=index.cjs.map
359
446
  //# sourceMappingURL=index.cjs.map