@spectare-personalisation/react 0.5.0 → 0.6.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.d.cts CHANGED
@@ -44,11 +44,57 @@ interface PersonalisedSectionProps {
44
44
  align?: 'left' | 'center' | 'right';
45
45
  /**
46
46
  * Brand accent. Passed through to ComponentRenderer, which emits it into the scoped
47
- * token set. Defaults to #60a5fa.
47
+ * token set. Defaults to #60a5fa (dark) or #2563eb (light).
48
48
  */
49
49
  accent?: string;
50
+ /** dark (default) or light, matching your page's ground. See ComponentRenderer. */
51
+ theme?: 'dark' | 'light';
50
52
  }
51
- declare function PersonalisedSection({ orgSlug, baseUrl, brand, pageHint, className, style, initialAssembly, initialIntent, initialVariantId, directSummary, zone, align, accent, }: PersonalisedSectionProps): react_jsx_runtime.JSX.Element | null;
53
+ declare function PersonalisedSection({ orgSlug, baseUrl, brand, pageHint, className, style, initialAssembly, initialIntent, initialVariantId, directSummary, zone, align, accent, theme, }: PersonalisedSectionProps): react_jsx_runtime.JSX.Element | null;
54
+
55
+ /**
56
+ * The one place this package's design tokens are defined.
57
+ *
58
+ * Two things that are easy to get wrong here:
59
+ *
60
+ * 1. Tokens are declared on `.sp-root`, not `:root`. Declaring them at `:root` writes into
61
+ * the host's document, allows only one theme per page, and means a customer overriding
62
+ * `--sp-accent` competes with us at equal specificity so tag order decides the winner.
63
+ * Scoping also lets two differently themed sections sit on one page.
64
+ *
65
+ * 2. `tokens.css` must stay byte-identical to `buildTokenCss({ scope: STYLESHEET_SCOPE })`,
66
+ * which differs from the injected CSS in its selector and in nothing else.
67
+ * tests/unit/react-tokens.test.ts enforces both halves, because a customer who imports the
68
+ * stylesheet and a customer who renders the component must get the same page.
69
+ *
70
+ * components/ServerAssemblyRenderer.tsx in the Spectare app is a deliberate mirror of the
71
+ * values below. It is not the same file: that renderer uses rem, this one uses px.
72
+ */
73
+ /** The package default. `spectare.js` and the WordPress plugin default to #2563eb, which is
74
+ * a live inconsistency and a brand decision rather than a technical one, so it is left alone
75
+ * here. Pass `accent` to override on either path. */
76
+ declare const DEFAULT_ACCENT = "#60a5fa";
77
+ type SpTheme = 'dark' | 'light';
78
+ /** Class the tokens are scoped to. Applied by ComponentRenderer to its own wrapper. */
79
+ declare const SP_ROOT = "sp-root";
80
+ /**
81
+ * Returns the stylesheet a renderer injects.
82
+ *
83
+ * @param accent brand colour. Accepts anything CSS does; `--sp-accent-bg` and
84
+ * `--sp-accent-border` are derived from it so a customer sets one value
85
+ * rather than three. Defaults to DEFAULT_ACCENT.
86
+ * @param unit length unit for layout rules. 'px' for this package, 'rem' for the app's
87
+ * server renderer, which sizes in rem throughout.
88
+ * @param scope selector the custom properties are declared on. Defaults to `.sp-root`, which is
89
+ * what a renderer injecting this at runtime wants. `tokens.css` is generated with
90
+ * STYLESHEET_SCOPE instead, so importing it works without a wrapper.
91
+ */
92
+ declare function buildTokenCss({ accent, unit, scope, theme }?: {
93
+ accent?: string;
94
+ unit?: 'px' | 'rem';
95
+ scope?: string;
96
+ theme?: SpTheme;
97
+ }): string;
52
98
 
53
99
  type Unit = 'px' | 'rem';
54
100
  type Align = 'left' | 'center' | 'right';
@@ -75,9 +121,10 @@ declare function HeroStatement({ headline, subheading, align, unit }: {
75
121
  align?: Align;
76
122
  unit?: Unit;
77
123
  }): react_jsx_runtime.JSX.Element;
78
- declare function AtomCard({ title, content, layout, stats, ctaText, ctaUrl, full, unit }: {
124
+ declare function AtomCard({ title, content, summary, layout, stats, ctaText, ctaUrl, full, variant, unit }: {
79
125
  title?: string;
80
126
  content?: string;
127
+ summary?: string;
81
128
  layout?: string[];
82
129
  stats?: {
83
130
  value: string;
@@ -86,6 +133,7 @@ declare function AtomCard({ title, content, layout, stats, ctaText, ctaUrl, full
86
133
  ctaText?: string;
87
134
  ctaUrl?: string;
88
135
  full?: boolean;
136
+ variant?: string;
89
137
  unit?: Unit;
90
138
  }): react_jsx_runtime.JSX.Element;
91
139
  declare function StatGrid({ stats, caption, unit }: {
@@ -169,6 +217,13 @@ interface ComponentRendererProps {
169
217
  * from it, so one value covers all three. Defaults to #60a5fa.
170
218
  */
171
219
  accent?: string;
220
+ /**
221
+ * dark (default) is the package's original near-black card set. light renders white cards
222
+ * with a dark text ramp for light host pages; without it the components paint near-white
223
+ * text and near-black slabs onto a light ground. Both palettes hold the same contrast
224
+ * floors (see tests/unit/token-contrast.test.ts).
225
+ */
226
+ theme?: SpTheme;
172
227
  /**
173
228
  * px (default) sizes components absolutely, predictable inside arbitrary host pages.
174
229
  * rem tracks the reader's font-size preference; the root then also inherits the host's
@@ -189,48 +244,6 @@ interface ComponentRendererProps {
189
244
  /** Extra attributes for the root element (e.g. a data marker a host overlay targets). */
190
245
  rootProps?: Record<string, unknown>;
191
246
  }
192
- declare function ComponentRenderer({ assembly, brand, xray, zone, align, accent, unit, renderOverride, renderItem, rootProps }: ComponentRendererProps): react_jsx_runtime.JSX.Element;
193
-
194
- /**
195
- * The one place this package's design tokens are defined.
196
- *
197
- * Two things that are easy to get wrong here:
198
- *
199
- * 1. Tokens are declared on `.sp-root`, not `:root`. Declaring them at `:root` writes into
200
- * the host's document, allows only one theme per page, and means a customer overriding
201
- * `--sp-accent` competes with us at equal specificity so tag order decides the winner.
202
- * Scoping also lets two differently themed sections sit on one page.
203
- *
204
- * 2. `tokens.css` must stay byte-identical to `buildTokenCss({ scope: STYLESHEET_SCOPE })`,
205
- * which differs from the injected CSS in its selector and in nothing else.
206
- * tests/unit/react-tokens.test.ts enforces both halves, because a customer who imports the
207
- * stylesheet and a customer who renders the component must get the same page.
208
- *
209
- * components/ServerAssemblyRenderer.tsx in the Spectare app is a deliberate mirror of the
210
- * values below. It is not the same file: that renderer uses rem, this one uses px.
211
- */
212
- /** The package default. `spectare.js` and the WordPress plugin default to #2563eb, which is
213
- * a live inconsistency and a brand decision rather than a technical one, so it is left alone
214
- * here. Pass `accent` to override on either path. */
215
- declare const DEFAULT_ACCENT = "#60a5fa";
216
- /** Class the tokens are scoped to. Applied by ComponentRenderer to its own wrapper. */
217
- declare const SP_ROOT = "sp-root";
218
- /**
219
- * Returns the stylesheet a renderer injects.
220
- *
221
- * @param accent brand colour. Accepts anything CSS does; `--sp-accent-bg` and
222
- * `--sp-accent-border` are derived from it so a customer sets one value
223
- * rather than three. Defaults to DEFAULT_ACCENT.
224
- * @param unit length unit for layout rules. 'px' for this package, 'rem' for the app's
225
- * server renderer, which sizes in rem throughout.
226
- * @param scope selector the custom properties are declared on. Defaults to `.sp-root`, which is
227
- * what a renderer injecting this at runtime wants. `tokens.css` is generated with
228
- * STYLESHEET_SCOPE instead, so importing it works without a wrapper.
229
- */
230
- declare function buildTokenCss({ accent, unit, scope }?: {
231
- accent?: string;
232
- unit?: 'px' | 'rem';
233
- scope?: string;
234
- }): string;
247
+ declare function ComponentRenderer({ assembly, brand, xray, zone, align, accent, theme, unit, renderOverride, renderItem, rootProps }: ComponentRendererProps): react_jsx_runtime.JSX.Element;
235
248
 
236
249
  export { AnnouncementBar, type AssemblyZone, AtomCard, CodeBlock, ComparisonTable, type ComponentAssembly, type ComponentName, ComponentRenderer, type ComponentRendererProps, CtaStrip, DEFAULT_ACCENT, FeatureList, HeroStatement, ImageCtaHero, PersonalisedSection, type PersonalisedSectionProps, SP_ROOT, StatGrid, TestimonialCard, buildTokenCss, filterAssemblyByZone };
package/dist/index.d.ts CHANGED
@@ -44,11 +44,57 @@ interface PersonalisedSectionProps {
44
44
  align?: 'left' | 'center' | 'right';
45
45
  /**
46
46
  * Brand accent. Passed through to ComponentRenderer, which emits it into the scoped
47
- * token set. Defaults to #60a5fa.
47
+ * token set. Defaults to #60a5fa (dark) or #2563eb (light).
48
48
  */
49
49
  accent?: string;
50
+ /** dark (default) or light, matching your page's ground. See ComponentRenderer. */
51
+ theme?: 'dark' | 'light';
50
52
  }
51
- declare function PersonalisedSection({ orgSlug, baseUrl, brand, pageHint, className, style, initialAssembly, initialIntent, initialVariantId, directSummary, zone, align, accent, }: PersonalisedSectionProps): react_jsx_runtime.JSX.Element | null;
53
+ declare function PersonalisedSection({ orgSlug, baseUrl, brand, pageHint, className, style, initialAssembly, initialIntent, initialVariantId, directSummary, zone, align, accent, theme, }: PersonalisedSectionProps): react_jsx_runtime.JSX.Element | null;
54
+
55
+ /**
56
+ * The one place this package's design tokens are defined.
57
+ *
58
+ * Two things that are easy to get wrong here:
59
+ *
60
+ * 1. Tokens are declared on `.sp-root`, not `:root`. Declaring them at `:root` writes into
61
+ * the host's document, allows only one theme per page, and means a customer overriding
62
+ * `--sp-accent` competes with us at equal specificity so tag order decides the winner.
63
+ * Scoping also lets two differently themed sections sit on one page.
64
+ *
65
+ * 2. `tokens.css` must stay byte-identical to `buildTokenCss({ scope: STYLESHEET_SCOPE })`,
66
+ * which differs from the injected CSS in its selector and in nothing else.
67
+ * tests/unit/react-tokens.test.ts enforces both halves, because a customer who imports the
68
+ * stylesheet and a customer who renders the component must get the same page.
69
+ *
70
+ * components/ServerAssemblyRenderer.tsx in the Spectare app is a deliberate mirror of the
71
+ * values below. It is not the same file: that renderer uses rem, this one uses px.
72
+ */
73
+ /** The package default. `spectare.js` and the WordPress plugin default to #2563eb, which is
74
+ * a live inconsistency and a brand decision rather than a technical one, so it is left alone
75
+ * here. Pass `accent` to override on either path. */
76
+ declare const DEFAULT_ACCENT = "#60a5fa";
77
+ type SpTheme = 'dark' | 'light';
78
+ /** Class the tokens are scoped to. Applied by ComponentRenderer to its own wrapper. */
79
+ declare const SP_ROOT = "sp-root";
80
+ /**
81
+ * Returns the stylesheet a renderer injects.
82
+ *
83
+ * @param accent brand colour. Accepts anything CSS does; `--sp-accent-bg` and
84
+ * `--sp-accent-border` are derived from it so a customer sets one value
85
+ * rather than three. Defaults to DEFAULT_ACCENT.
86
+ * @param unit length unit for layout rules. 'px' for this package, 'rem' for the app's
87
+ * server renderer, which sizes in rem throughout.
88
+ * @param scope selector the custom properties are declared on. Defaults to `.sp-root`, which is
89
+ * what a renderer injecting this at runtime wants. `tokens.css` is generated with
90
+ * STYLESHEET_SCOPE instead, so importing it works without a wrapper.
91
+ */
92
+ declare function buildTokenCss({ accent, unit, scope, theme }?: {
93
+ accent?: string;
94
+ unit?: 'px' | 'rem';
95
+ scope?: string;
96
+ theme?: SpTheme;
97
+ }): string;
52
98
 
53
99
  type Unit = 'px' | 'rem';
54
100
  type Align = 'left' | 'center' | 'right';
@@ -75,9 +121,10 @@ declare function HeroStatement({ headline, subheading, align, unit }: {
75
121
  align?: Align;
76
122
  unit?: Unit;
77
123
  }): react_jsx_runtime.JSX.Element;
78
- declare function AtomCard({ title, content, layout, stats, ctaText, ctaUrl, full, unit }: {
124
+ declare function AtomCard({ title, content, summary, layout, stats, ctaText, ctaUrl, full, variant, unit }: {
79
125
  title?: string;
80
126
  content?: string;
127
+ summary?: string;
81
128
  layout?: string[];
82
129
  stats?: {
83
130
  value: string;
@@ -86,6 +133,7 @@ declare function AtomCard({ title, content, layout, stats, ctaText, ctaUrl, full
86
133
  ctaText?: string;
87
134
  ctaUrl?: string;
88
135
  full?: boolean;
136
+ variant?: string;
89
137
  unit?: Unit;
90
138
  }): react_jsx_runtime.JSX.Element;
91
139
  declare function StatGrid({ stats, caption, unit }: {
@@ -169,6 +217,13 @@ interface ComponentRendererProps {
169
217
  * from it, so one value covers all three. Defaults to #60a5fa.
170
218
  */
171
219
  accent?: string;
220
+ /**
221
+ * dark (default) is the package's original near-black card set. light renders white cards
222
+ * with a dark text ramp for light host pages; without it the components paint near-white
223
+ * text and near-black slabs onto a light ground. Both palettes hold the same contrast
224
+ * floors (see tests/unit/token-contrast.test.ts).
225
+ */
226
+ theme?: SpTheme;
172
227
  /**
173
228
  * px (default) sizes components absolutely, predictable inside arbitrary host pages.
174
229
  * rem tracks the reader's font-size preference; the root then also inherits the host's
@@ -189,48 +244,6 @@ interface ComponentRendererProps {
189
244
  /** Extra attributes for the root element (e.g. a data marker a host overlay targets). */
190
245
  rootProps?: Record<string, unknown>;
191
246
  }
192
- declare function ComponentRenderer({ assembly, brand, xray, zone, align, accent, unit, renderOverride, renderItem, rootProps }: ComponentRendererProps): react_jsx_runtime.JSX.Element;
193
-
194
- /**
195
- * The one place this package's design tokens are defined.
196
- *
197
- * Two things that are easy to get wrong here:
198
- *
199
- * 1. Tokens are declared on `.sp-root`, not `:root`. Declaring them at `:root` writes into
200
- * the host's document, allows only one theme per page, and means a customer overriding
201
- * `--sp-accent` competes with us at equal specificity so tag order decides the winner.
202
- * Scoping also lets two differently themed sections sit on one page.
203
- *
204
- * 2. `tokens.css` must stay byte-identical to `buildTokenCss({ scope: STYLESHEET_SCOPE })`,
205
- * which differs from the injected CSS in its selector and in nothing else.
206
- * tests/unit/react-tokens.test.ts enforces both halves, because a customer who imports the
207
- * stylesheet and a customer who renders the component must get the same page.
208
- *
209
- * components/ServerAssemblyRenderer.tsx in the Spectare app is a deliberate mirror of the
210
- * values below. It is not the same file: that renderer uses rem, this one uses px.
211
- */
212
- /** The package default. `spectare.js` and the WordPress plugin default to #2563eb, which is
213
- * a live inconsistency and a brand decision rather than a technical one, so it is left alone
214
- * here. Pass `accent` to override on either path. */
215
- declare const DEFAULT_ACCENT = "#60a5fa";
216
- /** Class the tokens are scoped to. Applied by ComponentRenderer to its own wrapper. */
217
- declare const SP_ROOT = "sp-root";
218
- /**
219
- * Returns the stylesheet a renderer injects.
220
- *
221
- * @param accent brand colour. Accepts anything CSS does; `--sp-accent-bg` and
222
- * `--sp-accent-border` are derived from it so a customer sets one value
223
- * rather than three. Defaults to DEFAULT_ACCENT.
224
- * @param unit length unit for layout rules. 'px' for this package, 'rem' for the app's
225
- * server renderer, which sizes in rem throughout.
226
- * @param scope selector the custom properties are declared on. Defaults to `.sp-root`, which is
227
- * what a renderer injecting this at runtime wants. `tokens.css` is generated with
228
- * STYLESHEET_SCOPE instead, so importing it works without a wrapper.
229
- */
230
- declare function buildTokenCss({ accent, unit, scope }?: {
231
- accent?: string;
232
- unit?: 'px' | 'rem';
233
- scope?: string;
234
- }): string;
247
+ declare function ComponentRenderer({ assembly, brand, xray, zone, align, accent, theme, unit, renderOverride, renderItem, rootProps }: ComponentRendererProps): react_jsx_runtime.JSX.Element;
235
248
 
236
249
  export { AnnouncementBar, type AssemblyZone, AtomCard, CodeBlock, ComparisonTable, type ComponentAssembly, type ComponentName, ComponentRenderer, type ComponentRendererProps, CtaStrip, DEFAULT_ACCENT, FeatureList, HeroStatement, ImageCtaHero, PersonalisedSection, type PersonalisedSectionProps, SP_ROOT, StatGrid, TestimonialCard, buildTokenCss, filterAssemblyByZone };
package/dist/index.js CHANGED
@@ -42,13 +42,38 @@ var COMPONENT_CATEGORIES = {
42
42
 
43
43
  // src/tokens.ts
44
44
  var DEFAULT_ACCENT = "#60a5fa";
45
+ var DEFAULT_ACCENT_LIGHT = "#2563eb";
45
46
  var SP_ROOT = "sp-root";
46
47
  var STYLESHEET_SCOPE = `:where(:root),.${SP_ROOT}`;
47
- function palette(accent) {
48
- return {
48
+ function palette(accent, theme) {
49
+ const shared = {
49
50
  "--sp-accent": accent,
50
51
  "--sp-accent-bg": `color-mix(in srgb,${accent} 10%,transparent)`,
51
- "--sp-accent-border": `color-mix(in srgb,${accent} 20%,transparent)`,
52
+ "--sp-accent-border": `color-mix(in srgb,${accent} 20%,transparent)`
53
+ };
54
+ if (theme === "light") {
55
+ return {
56
+ ...shared,
57
+ "--sp-bg": "#ffffff",
58
+ "--sp-surface": "#f4f4f5",
59
+ "--sp-border": "#e4e4e7",
60
+ "--sp-text": "#18181b",
61
+ "--sp-text-sub": "#3f3f46",
62
+ "--sp-text-strong": "#27272a",
63
+ "--sp-text-muted": "#6b6b74",
64
+ "--sp-text-dim": "#82828b",
65
+ "--sp-text-body": "#52525b",
66
+ "--sp-positive": "#047857",
67
+ "--sp-cta-bg": "#18181b",
68
+ "--sp-cta-text": "#ffffff",
69
+ "--sp-divider": "rgba(0,0,0,0.06)",
70
+ "--sp-code-bg": "rgba(0,0,0,0.05)",
71
+ "--sp-code-border": "rgba(0,0,0,0.08)",
72
+ "--sp-pre-bg": "rgba(0,0,0,0.04)"
73
+ };
74
+ }
75
+ return {
76
+ ...shared,
52
77
  "--sp-bg": "#18181b",
53
78
  "--sp-surface": "#09090b",
54
79
  "--sp-border": "#27272a",
@@ -83,8 +108,9 @@ function rules(unit) {
83
108
  "@media(max-width:640px){.sp-root .sp-pair{grid-template-columns:1fr}}"
84
109
  ].join("");
85
110
  }
86
- function buildTokenCss({ accent = DEFAULT_ACCENT, unit = "px", scope = `.${SP_ROOT}` } = {}) {
87
- const decls = Object.entries(palette(accent)).map(([k, v]) => `${k}:${v}`).join(";");
111
+ function buildTokenCss({ accent, unit = "px", scope = `.${SP_ROOT}`, theme = "dark" } = {}) {
112
+ const resolved = accent != null ? accent : theme === "light" ? DEFAULT_ACCENT_LIGHT : DEFAULT_ACCENT;
113
+ const decls = Object.entries(palette(resolved, theme)).map(([k, v]) => `${k}:${v}`).join(";");
88
114
  return `${scope}{${decls}}${rules(unit)}`;
89
115
  }
90
116
 
@@ -138,8 +164,23 @@ var clampStyle = {
138
164
  WebkitBoxOrient: "vertical",
139
165
  overflow: "hidden"
140
166
  };
141
- function AtomCard({ title, content, layout, stats = [], ctaText, ctaUrl, full, unit = "px" }) {
167
+ function AtomCard({ title, content, summary, layout, stats = [], ctaText, ctaUrl, full, variant, unit = "px" }) {
142
168
  const u = scaler(unit);
169
+ if (variant === "card") {
170
+ const face = (summary == null ? void 0 : summary.trim()) || (content ? `${content.replace(/\s+/g, " ").split(/(?<=[.!?])\s/)[0]}` : "");
171
+ return /* @__PURE__ */ jsxs("div", { style: { background: "var(--sp-bg)", border: "1px solid var(--sp-border)", borderRadius: u(12), padding: u(20) }, children: [
172
+ title && /* @__PURE__ */ jsx("h3", { style: { fontSize: u(16), fontWeight: 600, color: "var(--sp-text)", margin: 0, lineHeight: 1.35 }, children: title }),
173
+ face && /* @__PURE__ */ jsx("p", { style: { fontSize: u(15), color: "var(--sp-text-sub)", lineHeight: 1.6, margin: `${u(8)} 0 0` }, children: face }),
174
+ content && /* @__PURE__ */ jsxs("details", { style: { marginTop: u(10) }, children: [
175
+ /* @__PURE__ */ jsx("summary", { style: { cursor: "pointer", fontSize: u(13), fontWeight: 600, color: "var(--sp-accent)", listStyle: "none" }, children: "Read more" }),
176
+ /* @__PURE__ */ jsx("div", { className: "sp-prose", style: { fontSize: u(15), color: "var(--sp-text-sub)", lineHeight: 1.6, marginTop: u(10) }, dangerouslySetInnerHTML: { __html: renderMarkdown(content) } })
177
+ ] }),
178
+ ctaText && ctaUrl && /* @__PURE__ */ jsxs("a", { href: ctaUrl, style: { display: "inline-flex", alignItems: "center", gap: u(4), marginTop: u(10), fontSize: u(13), fontWeight: 600, color: "var(--sp-accent)", textDecoration: "none" }, children: [
179
+ ctaText,
180
+ " \u2192"
181
+ ] })
182
+ ] });
183
+ }
143
184
  const order = layout && layout.length ? layout : ATOM_LAYOUT_DEFAULT;
144
185
  const element = (name) => {
145
186
  if (name === "title") return title ? /* @__PURE__ */ jsx("h3", { style: { fontSize: u(16), fontWeight: 600, color: "var(--sp-text)", margin: `0 0 ${u(12)}` }, children: title }, "title") : null;
@@ -257,7 +298,7 @@ function renderSingle(item, brand, align, unit = "px") {
257
298
  return /* @__PURE__ */ jsx(HeroStatement, { headline: s.headline, subheading: s.subheading, align, unit });
258
299
  // A full-width card has nothing beside it, so there is nothing for a clamp to protect.
259
300
  case "AtomCard":
260
- return /* @__PURE__ */ jsx(AtomCard, { title: s.title, content: s.content, layout: s.layout, stats: s.stats, ctaText: s.ctaText, ctaUrl: s.ctaUrl, full: s.full || resolvedSize(item) === "full", unit });
301
+ return /* @__PURE__ */ jsx(AtomCard, { title: s.title, content: s.content, summary: s.summary, layout: s.layout, stats: s.stats, ctaText: s.ctaText, ctaUrl: s.ctaUrl, full: s.full || resolvedSize(item) === "full", variant: s.variant, unit });
261
302
  case "StatGrid":
262
303
  return /* @__PURE__ */ jsx(StatGrid, { stats: s.stats, caption: s.caption, unit });
263
304
  case "CodeBlock":
@@ -323,7 +364,7 @@ function XrayBadge({ name, size }) {
323
364
  /* @__PURE__ */ jsx("span", { style: { fontSize: PX(10), fontFamily: "monospace", color: "#71717a", lineHeight: 1 }, children: size })
324
365
  ] });
325
366
  }
326
- function ComponentRenderer({ assembly, brand, xray = false, zone, align, accent, unit = "px", renderOverride, renderItem, rootProps }) {
367
+ function ComponentRenderer({ assembly, brand, xray = false, zone, align, accent, theme, unit = "px", renderOverride, renderItem, rootProps }) {
327
368
  const u = scaler(unit);
328
369
  const filtered = zone ? filterAssemblyByZone(assembly, zone) : assembly;
329
370
  const layout = buildLayout(filtered);
@@ -334,7 +375,7 @@ function ComponentRenderer({ assembly, brand, xray = false, zone, align, accent,
334
375
  return renderItem ? renderItem(item, node) : node;
335
376
  };
336
377
  return /* @__PURE__ */ jsxs("div", { className: extraClass ? `${SP_ROOT} ${extraClass}` : SP_ROOT, ...restRoot, style: { ...extraStyle, display: "flex", flexDirection: "column", gap: u(20), ...unit === "px" ? { fontSize: "16px" } : {} }, children: [
337
- /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: buildTokenCss({ accent, unit }) } }),
378
+ /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: buildTokenCss({ accent, unit, theme }) } }),
338
379
  layout.map((group, i) => {
339
380
  if (group.type === "pair") {
340
381
  return /* @__PURE__ */ jsxs("div", { className: "sp-pair", children: [
@@ -427,7 +468,8 @@ function PersonalisedSection({
427
468
  directSummary,
428
469
  zone,
429
470
  align,
430
- accent
471
+ accent,
472
+ theme
431
473
  }) {
432
474
  const [assembly, setAssembly] = useState(initialAssembly != null ? initialAssembly : []);
433
475
  const [loading, setLoading] = useState(!initialAssembly);
@@ -678,7 +720,7 @@ function PersonalisedSection({
678
720
  debugIntent.stage
679
721
  ] })
680
722
  ] }),
681
- loading && assembly.length === 0 ? /* @__PURE__ */ jsx2(Shimmer, {}) : /* @__PURE__ */ jsx2(ComponentRenderer, { assembly: zone ? filterAssemblyByZone(assembly, zone) : assembly, brand: brand != null ? brand : orgName, align, accent })
723
+ loading && assembly.length === 0 ? /* @__PURE__ */ jsx2(Shimmer, {}) : /* @__PURE__ */ jsx2(ComponentRenderer, { assembly: zone ? filterAssemblyByZone(assembly, zone) : assembly, brand: brand != null ? brand : orgName, align, accent, theme })
682
724
  ] })
683
725
  ] });
684
726
  }