@syntrologie/runtime-sdk 2.4.0-canary.22 → 2.4.0-canary.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/actions/schema.d.ts +3603 -36279
  2. package/dist/actions/schema.js +3 -3
  3. package/dist/{chunk-P5G4KT2U.js → chunk-BU4Z6PD7.js} +9 -4
  4. package/dist/chunk-BU4Z6PD7.js.map +7 -0
  5. package/dist/{chunk-WCQCVPJ7.js → chunk-LD22WJ44.js} +440 -132
  6. package/dist/chunk-LD22WJ44.js.map +7 -0
  7. package/dist/{chunk-HF3D7YFQ.js → chunk-NM5Y27GX.js} +24 -26
  8. package/dist/chunk-NM5Y27GX.js.map +7 -0
  9. package/dist/{chunk-2UYZ5DWI.js → chunk-WILWIL6L.js} +43 -5
  10. package/dist/chunk-WILWIL6L.js.map +7 -0
  11. package/dist/components/ShadowCanvasOverlay.d.ts +2 -1
  12. package/dist/components/TileIcon.d.ts +14 -0
  13. package/dist/config/schema.d.ts +914 -3656
  14. package/dist/config/schema.js +4 -2
  15. package/dist/decisions/schema.d.ts +19 -1467
  16. package/dist/decisions/schema.js +3 -1
  17. package/dist/decisions/types.d.ts +2 -2
  18. package/dist/index.js +87 -94
  19. package/dist/index.js.map +2 -2
  20. package/dist/react.js +4 -4
  21. package/dist/smart-canvas.esm.js +105 -62
  22. package/dist/smart-canvas.esm.js.map +4 -4
  23. package/dist/smart-canvas.js +849 -295
  24. package/dist/smart-canvas.js.map +4 -4
  25. package/dist/smart-canvas.min.js +105 -62
  26. package/dist/smart-canvas.min.js.map +4 -4
  27. package/dist/theme/types.d.ts +2 -1
  28. package/dist/version.d.ts +1 -1
  29. package/dist/widgets/WidgetRegistry.d.ts +1 -0
  30. package/package.json +9 -8
  31. package/schema/canvas-config.schema.json +1346 -372
  32. package/dist/chunk-2UYZ5DWI.js.map +0 -7
  33. package/dist/chunk-HF3D7YFQ.js.map +0 -7
  34. package/dist/chunk-P5G4KT2U.js.map +0 -7
  35. package/dist/chunk-WCQCVPJ7.js.map +0 -7
@@ -12860,6 +12860,7 @@ var SyntrologieSDK = (() => {
12860
12860
  TooltipZ: () => TooltipZ,
12861
12861
  TourStepForSchemaZ: () => TourStepForSchemaZ,
12862
12862
  TourZ: () => TourZ,
12863
+ TriggerWhenZ: () => TriggerWhenZ,
12863
12864
  ViewportConditionZ: () => ViewportConditionZ,
12864
12865
  ViewportContextZ: () => ViewportContextZ,
12865
12866
  WaitZ: () => WaitZ,
@@ -12950,7 +12951,7 @@ var SyntrologieSDK = (() => {
12950
12951
  validateStrategy: () => validateStrategy,
12951
12952
  widgetRegistry: () => widgetRegistry
12952
12953
  });
12953
- var import_react17 = __toESM(require_react(), 1);
12954
+ var import_react19 = __toESM(require_react(), 1);
12954
12955
  var import_react_dom3 = __toESM(require_react_dom(), 1);
12955
12956
  var ReactDOMClient = __toESM(require_client(), 1);
12956
12957
 
@@ -13726,7 +13727,7 @@ var SyntrologieSDK = (() => {
13726
13727
  };
13727
13728
 
13728
13729
  // ../adaptives/adaptive-overlays/dist/celebrations/index.js
13729
- var DEFAULT_COLORS2 = [
13730
+ var FALLBACK_COLORS = [
13730
13731
  "#ff0000",
13731
13732
  "#00ff00",
13732
13733
  "#0000ff",
@@ -13736,6 +13737,21 @@ var SyntrologieSDK = (() => {
13736
13737
  "#ff8800",
13737
13738
  "#8800ff"
13738
13739
  ];
13740
+ function buildThemePalette(primary, hover) {
13741
+ return [primary, hover, `${primary}cc`, `${hover}cc`, "#ffffff", `${primary}80`];
13742
+ }
13743
+ function readThemeColors(overlayRoot) {
13744
+ try {
13745
+ const styles2 = getComputedStyle(overlayRoot);
13746
+ const primary = styles2.getPropertyValue("--sc-color-primary")?.trim();
13747
+ const hover = styles2.getPropertyValue("--sc-color-primary-hover")?.trim();
13748
+ if (primary?.startsWith("#") && primary.length >= 7) {
13749
+ return buildThemePalette(primary, hover || primary);
13750
+ }
13751
+ } catch {
13752
+ }
13753
+ return null;
13754
+ }
13739
13755
  var effectRegistry = /* @__PURE__ */ new Map([
13740
13756
  ["confetti", confettiEffect],
13741
13757
  ["fireworks", fireworksEffect],
@@ -13749,10 +13765,11 @@ var SyntrologieSDK = (() => {
13749
13765
  return { cleanup: () => {
13750
13766
  } };
13751
13767
  }
13768
+ const colors = action.colors ?? readThemeColors(context.overlayRoot) ?? FALLBACK_COLORS;
13752
13769
  const config = {
13753
13770
  duration: action.duration ?? 3e3,
13754
13771
  intensity: action.intensity ?? "medium",
13755
- colors: action.colors ?? DEFAULT_COLORS2,
13772
+ colors,
13756
13773
  props: action.props
13757
13774
  };
13758
13775
  const engine = new CelebrationEngine();
@@ -14622,6 +14639,13 @@ var SyntrologieSDK = (() => {
14622
14639
  }
14623
14640
 
14624
14641
  // ../adaptives/adaptive-overlays/dist/modal.js
14642
+ var V = {
14643
+ bg: "var(--sc-overlay-background, #ffffff)",
14644
+ title: "var(--sc-overlay-title-color, var(--sc-overlay-text-color, #111827))",
14645
+ text: "var(--sc-overlay-text-color, #4b5563)",
14646
+ accent: "var(--sc-color-primary, #4f46e5)",
14647
+ radius: "var(--sc-border-radius, 12px)"
14648
+ };
14625
14649
  var executeModal = async (action, context) => {
14626
14650
  const { content, size: size2 = "md", blocking = false, scrim, dismiss, ctaButtons } = action;
14627
14651
  const scrimEl = document.createElement("div");
@@ -14647,8 +14671,8 @@ var SyntrologieSDK = (() => {
14647
14671
  transform: translate(-50%, -50%) scale(0.95);
14648
14672
  max-width: ${sizeMap[size2]};
14649
14673
  width: 90%;
14650
- background: ${base.white};
14651
- border-radius: 12px;
14674
+ background: ${V.bg};
14675
+ border-radius: ${V.radius};
14652
14676
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
14653
14677
  z-index: 2147483646;
14654
14678
  opacity: 0;
@@ -14657,9 +14681,9 @@ var SyntrologieSDK = (() => {
14657
14681
  `;
14658
14682
  let html2 = "";
14659
14683
  if (content.title) {
14660
- html2 += `<h2 class="syntro-modal-title" style="margin: 0 0 12px 0; font-size: 18px; font-weight: 600; color: #111827;">${sanitizeHtml2(content.title)}</h2>`;
14684
+ html2 += `<h2 class="syntro-modal-title" style="margin: 0 0 12px 0; font-size: 18px; font-weight: 600; color: ${V.title};">${sanitizeHtml2(content.title)}</h2>`;
14661
14685
  }
14662
- html2 += `<div class="syntro-modal-body" style="color: #4b5563; line-height: 1.5;">${sanitizeHtml2(content.body)}</div>`;
14686
+ html2 += `<div class="syntro-modal-body" style="color: ${V.text}; line-height: 1.5;">${sanitizeHtml2(content.body)}</div>`;
14663
14687
  if (dismiss?.closeButton !== false) {
14664
14688
  html2 += `
14665
14689
  <button class="syntro-modal-close" data-syntro-action="dismiss" style="
@@ -14670,7 +14694,8 @@ var SyntrologieSDK = (() => {
14670
14694
  border: none;
14671
14695
  cursor: pointer;
14672
14696
  padding: 4px;
14673
- color: #6b7280;
14697
+ color: ${V.text};
14698
+ opacity: 0.6;
14674
14699
  " aria-label="Close">
14675
14700
  <svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor">
14676
14701
  <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
@@ -14693,7 +14718,7 @@ var SyntrologieSDK = (() => {
14693
14718
  font-weight: 500;
14694
14719
  cursor: pointer;
14695
14720
  transition: background 150ms ease;
14696
- ${isPrimary ? "background: #4f46e5; color: white; border: none;" : "background: white; color: #374151; border: 1px solid #d1d5db;"}
14721
+ ${isPrimary ? `background: ${V.accent}; color: white; border: none;` : `background: transparent; color: ${V.accent}; border: 1px solid currentColor; opacity: 0.7;`}
14697
14722
  "
14698
14723
  >
14699
14724
  ${sanitizeHtml2(btn.label)}
@@ -16808,24 +16833,67 @@ var SyntrologieSDK = (() => {
16808
16833
  return { cleanup: () => {
16809
16834
  } };
16810
16835
  }
16811
- const duration = action.duration ?? 2e3;
16812
- if (!document.querySelector("[data-syntro-pulse-styles]")) {
16813
- const style = document.createElement("style");
16814
- style.setAttribute("data-syntro-pulse-styles", "");
16836
+ const duration = action.duration ?? 4e3;
16837
+ await new Promise((resolve) => requestAnimationFrame(resolve));
16838
+ const parseHex = (hex) => ({
16839
+ r: parseInt(hex.slice(1, 3), 16),
16840
+ g: parseInt(hex.slice(3, 5), 16),
16841
+ b: parseInt(hex.slice(5, 7), 16)
16842
+ });
16843
+ const fallback = { r: 79, g: 70, b: 229 };
16844
+ let primary = fallback;
16845
+ let secondary = null;
16846
+ try {
16847
+ const styles2 = getComputedStyle(context.overlayRoot);
16848
+ const pHex = styles2.getPropertyValue("--sc-color-primary")?.trim();
16849
+ const sHex = styles2.getPropertyValue("--sc-color-primary-hover")?.trim();
16850
+ if (pHex?.startsWith("#") && pHex.length >= 7) {
16851
+ primary = parseHex(pHex);
16852
+ }
16853
+ if (sHex?.startsWith("#") && sHex.length >= 7) {
16854
+ secondary = parseHex(sHex);
16855
+ }
16856
+ } catch {
16857
+ }
16858
+ const existing = document.querySelector("[data-syntro-pulse-styles]");
16859
+ if (existing)
16860
+ existing.remove();
16861
+ const style = document.createElement("style");
16862
+ style.setAttribute("data-syntro-pulse-styles", "");
16863
+ const { r: pr2, g: pg, b: pb } = primary;
16864
+ if (secondary) {
16865
+ const { r: sr2, g: sg, b: sb } = secondary;
16815
16866
  style.textContent = `
16816
16867
  @keyframes syntro-pulse-anim {
16817
16868
  0%, 100% {
16818
- box-shadow: 0 0 0 0 rgba(79, 70, 229, 0.4);
16869
+ box-shadow: 0 0 0 0 rgba(${pr2}, ${pg}, ${pb}, 0.35);
16870
+ }
16871
+ 25% {
16872
+ box-shadow: 0 0 0 12px rgba(${pr2}, ${pg}, ${pb}, 0);
16819
16873
  }
16820
16874
  50% {
16821
- box-shadow: 0 0 0 8px rgba(79, 70, 229, 0);
16875
+ box-shadow: 0 0 0 0 rgba(${sr2}, ${sg}, ${sb}, 0.35);
16876
+ }
16877
+ 75% {
16878
+ box-shadow: 0 0 0 12px rgba(${sr2}, ${sg}, ${sb}, 0);
16879
+ }
16880
+ }
16881
+ `;
16882
+ } else {
16883
+ style.textContent = `
16884
+ @keyframes syntro-pulse-anim {
16885
+ 0%, 100% {
16886
+ box-shadow: 0 0 0 0 rgba(${pr2}, ${pg}, ${pb}, 0.35);
16887
+ }
16888
+ 50% {
16889
+ box-shadow: 0 0 0 12px rgba(${pr2}, ${pg}, ${pb}, 0);
16822
16890
  }
16823
16891
  }
16824
16892
  `;
16825
- document.head.appendChild(style);
16826
16893
  }
16894
+ document.head.appendChild(style);
16827
16895
  const originalAnimation = anchorEl.style.animation;
16828
- anchorEl.style.animation = "syntro-pulse-anim 1s cubic-bezier(0.4, 0, 0.6, 1) infinite";
16896
+ anchorEl.style.animation = "syntro-pulse-anim 2.5s cubic-bezier(0.4, 0, 0.6, 1) infinite";
16829
16897
  anchorEl.setAttribute("data-syntro-pulse", "true");
16830
16898
  const timeoutId = setTimeout(() => {
16831
16899
  anchorEl.style.animation = originalAnimation;
@@ -16855,6 +16923,14 @@ var SyntrologieSDK = (() => {
16855
16923
  return { cleanup: () => {
16856
16924
  } };
16857
16925
  }
16926
+ let badgeColor = "#4f46e5";
16927
+ try {
16928
+ const primary = getComputedStyle(context.overlayRoot).getPropertyValue("--sc-color-primary")?.trim();
16929
+ if (primary?.startsWith("#") && primary.length >= 7) {
16930
+ badgeColor = primary;
16931
+ }
16932
+ } catch {
16933
+ }
16858
16934
  const badge2 = document.createElement("div");
16859
16935
  badge2.textContent = action.content;
16860
16936
  badge2.setAttribute("data-syntro-badge", action.anchorId.selector);
@@ -16865,7 +16941,7 @@ var SyntrologieSDK = (() => {
16865
16941
  fontWeight: "600",
16866
16942
  lineHeight: "1",
16867
16943
  color: "white",
16868
- background: "var(--syntro-accent, #4f46e5)",
16944
+ background: badgeColor,
16869
16945
  borderRadius: "9999px",
16870
16946
  pointerEvents: "none",
16871
16947
  zIndex: "2147483646",
@@ -17005,7 +17081,7 @@ var SyntrologieSDK = (() => {
17005
17081
  executors: executors2,
17006
17082
  widgets: [
17007
17083
  {
17008
- id: "workflow:tracker",
17084
+ id: "adaptive-overlays:workflow-tracker",
17009
17085
  component: WorkflowMountableWidget,
17010
17086
  metadata: {
17011
17087
  name: "Workflow Tracker",
@@ -18042,12 +18118,12 @@ var SyntrologieSDK = (() => {
18042
18118
  }
18043
18119
  var baseStyles = {
18044
18120
  container: {
18045
- fontFamily: "system-ui, -apple-system, sans-serif",
18121
+ fontFamily: "var(--sc-font-family, system-ui, -apple-system, sans-serif)",
18046
18122
  maxWidth: "800px",
18047
18123
  margin: "0 auto"
18048
18124
  },
18049
18125
  searchWrapper: {
18050
- marginBottom: "16px"
18126
+ marginBottom: "8px"
18051
18127
  },
18052
18128
  searchInput: {
18053
18129
  width: "100%",
@@ -18055,38 +18131,41 @@ var SyntrologieSDK = (() => {
18055
18131
  borderRadius: "8px",
18056
18132
  fontSize: "14px",
18057
18133
  outline: "none",
18058
- transition: "border-color 0.15s ease"
18134
+ transition: "border-color 0.15s ease",
18135
+ backgroundColor: "var(--sc-content-search-background)",
18136
+ color: "var(--sc-content-search-color)"
18059
18137
  },
18060
18138
  accordion: {
18061
18139
  display: "flex",
18062
18140
  flexDirection: "column",
18063
- gap: "8px"
18141
+ gap: "var(--sc-content-item-gap, 6px)"
18064
18142
  },
18065
18143
  item: {
18066
- borderRadius: "8px",
18144
+ borderRadius: "var(--sc-content-border-radius, 8px)",
18067
18145
  overflow: "hidden",
18068
18146
  transition: "box-shadow 0.15s ease"
18069
18147
  },
18070
18148
  question: {
18071
18149
  width: "100%",
18072
- padding: "16px 20px",
18150
+ padding: "var(--sc-content-item-padding, 12px 16px)",
18073
18151
  display: "flex",
18074
18152
  alignItems: "center",
18075
18153
  justifyContent: "space-between",
18076
18154
  border: "none",
18077
18155
  cursor: "pointer",
18078
- fontSize: "15px",
18156
+ fontSize: "var(--sc-content-item-font-size, 15px)",
18079
18157
  fontWeight: 500,
18080
18158
  textAlign: "left",
18081
18159
  transition: "background-color 0.15s ease"
18082
18160
  },
18083
18161
  chevron: {
18084
- fontSize: "18px",
18085
- transition: "transform 0.2s ease"
18162
+ fontSize: "20px",
18163
+ transition: "transform 0.2s ease",
18164
+ color: "var(--sc-content-chevron-color, currentColor)"
18086
18165
  },
18087
18166
  answer: {
18088
- padding: "0 20px 16px 20px",
18089
- fontSize: "14px",
18167
+ padding: "var(--sc-content-body-padding, 0 16px 12px 16px)",
18168
+ fontSize: "var(--sc-content-body-font-size, 14px)",
18090
18169
  lineHeight: 1.6,
18091
18170
  overflow: "hidden",
18092
18171
  transition: "max-height 0.2s ease, padding 0.2s ease"
@@ -18102,12 +18181,12 @@ var SyntrologieSDK = (() => {
18102
18181
  marginBottom: "8px"
18103
18182
  },
18104
18183
  categoryHeader: {
18105
- fontSize: "13px",
18184
+ fontSize: "var(--sc-content-category-font-size, 12px)",
18106
18185
  fontWeight: 700,
18107
18186
  textTransform: "uppercase",
18108
18187
  letterSpacing: "0.05em",
18109
- padding: "12px 4px 6px 4px",
18110
- marginTop: "8px"
18188
+ padding: "var(--sc-content-category-padding, 8px 4px 4px 4px)",
18189
+ marginTop: "var(--sc-content-category-gap, 4px)"
18111
18190
  },
18112
18191
  feedback: {
18113
18192
  display: "flex",
@@ -18145,30 +18224,28 @@ var SyntrologieSDK = (() => {
18145
18224
  var themeStyles = {
18146
18225
  light: {
18147
18226
  container: {
18148
- backgroundColor: base.white,
18149
- color: slateGrey[1]
18227
+ backgroundColor: "transparent",
18228
+ color: "inherit"
18150
18229
  },
18151
18230
  searchInput: {
18152
- backgroundColor: slateGrey[12],
18153
- border: `1px solid ${slateGrey[11]}`,
18154
- color: slateGrey[1]
18231
+ border: `1px solid ${slateGrey[11]}`
18155
18232
  },
18156
18233
  item: {
18157
- backgroundColor: slateGrey[12],
18158
- border: `1px solid ${slateGrey[11]}`
18234
+ backgroundColor: "var(--sc-content-background)",
18235
+ border: "var(--sc-content-border)"
18159
18236
  },
18160
18237
  itemExpanded: {
18161
18238
  boxShadow: "0 4px 12px rgba(0, 0, 0, 0.08)"
18162
18239
  },
18163
18240
  question: {
18164
18241
  backgroundColor: "transparent",
18165
- color: slateGrey[1]
18242
+ color: "var(--sc-content-text-color)"
18166
18243
  },
18167
18244
  questionHover: {
18168
- backgroundColor: slateGrey[12]
18245
+ backgroundColor: "var(--sc-content-background-hover)"
18169
18246
  },
18170
18247
  answer: {
18171
- color: slateGrey[6]
18248
+ color: "var(--sc-content-text-secondary-color)"
18172
18249
  },
18173
18250
  category: {
18174
18251
  backgroundColor: purple[8],
@@ -18186,30 +18263,28 @@ var SyntrologieSDK = (() => {
18186
18263
  },
18187
18264
  dark: {
18188
18265
  container: {
18189
- backgroundColor: slateGrey[1],
18190
- color: slateGrey[12]
18266
+ backgroundColor: "transparent",
18267
+ color: "inherit"
18191
18268
  },
18192
18269
  searchInput: {
18193
- backgroundColor: slateGrey[3],
18194
- border: `1px solid ${slateGrey[5]}`,
18195
- color: slateGrey[12]
18270
+ border: `1px solid ${slateGrey[5]}`
18196
18271
  },
18197
18272
  item: {
18198
- backgroundColor: slateGrey[3],
18199
- border: `1px solid ${slateGrey[5]}`
18273
+ backgroundColor: "var(--sc-content-background)",
18274
+ border: "var(--sc-content-border)"
18200
18275
  },
18201
18276
  itemExpanded: {
18202
- boxShadow: "0 4px 12px rgba(0, 0, 0, 0.3)"
18277
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)"
18203
18278
  },
18204
18279
  question: {
18205
18280
  backgroundColor: "transparent",
18206
- color: slateGrey[12]
18281
+ color: "var(--sc-content-text-color)"
18207
18282
  },
18208
18283
  questionHover: {
18209
- backgroundColor: slateGrey[5]
18284
+ backgroundColor: "var(--sc-content-background-hover)"
18210
18285
  },
18211
18286
  answer: {
18212
- color: slateGrey[8]
18287
+ color: "var(--sc-content-text-secondary-color)"
18213
18288
  },
18214
18289
  category: {
18215
18290
  backgroundColor: purple[0],
@@ -18226,7 +18301,7 @@ var SyntrologieSDK = (() => {
18226
18301
  }
18227
18302
  }
18228
18303
  };
18229
- function FAQItem({ item, isExpanded, isHighlighted, onToggle, theme, feedbackConfig, feedbackValue, onFeedback }) {
18304
+ function FAQItem({ item, isExpanded, isHighlighted, isLast, onToggle, theme, feedbackConfig, feedbackValue, onFeedback }) {
18230
18305
  const [isHovered, setIsHovered] = (0, import_react4.useState)(false);
18231
18306
  const colors = themeStyles[theme];
18232
18307
  const { question, answer } = item.config;
@@ -18237,7 +18312,8 @@ var SyntrologieSDK = (() => {
18237
18312
  ...isHighlighted ? {
18238
18313
  boxShadow: "0 0 0 2px #6366f1, 0 0 12px rgba(99, 102, 241, 0.4)",
18239
18314
  transition: "box-shadow 0.3s ease"
18240
- } : {}
18315
+ } : {},
18316
+ ...!isLast ? { borderBottom: "var(--sc-content-item-divider, none)" } : {}
18241
18317
  };
18242
18318
  const questionStyle = {
18243
18319
  ...baseStyles.question,
@@ -18246,7 +18322,7 @@ var SyntrologieSDK = (() => {
18246
18322
  };
18247
18323
  const chevronStyle = {
18248
18324
  ...baseStyles.chevron,
18249
- transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)"
18325
+ transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
18250
18326
  };
18251
18327
  const answerStyle = {
18252
18328
  ...baseStyles.answer,
@@ -18258,7 +18334,7 @@ var SyntrologieSDK = (() => {
18258
18334
  ...baseStyles.feedback,
18259
18335
  ...colors.feedbackPrompt
18260
18336
  };
18261
- return (0, import_jsx_runtime4.jsxs)("div", { style: itemStyle, "data-faq-item-id": item.config.id, children: [(0, import_jsx_runtime4.jsxs)("button", { type: "button", style: questionStyle, onClick: onToggle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), "aria-expanded": isExpanded, children: [(0, import_jsx_runtime4.jsx)("span", { children: question }), (0, import_jsx_runtime4.jsx)("span", { style: chevronStyle, children: "\u25BC" })] }), (0, import_jsx_runtime4.jsxs)("div", { style: answerStyle, "aria-hidden": !isExpanded, children: [renderAnswer(answer), isExpanded && feedbackConfig && (0, import_jsx_runtime4.jsxs)("div", { style: feedbackStyle, children: [(0, import_jsx_runtime4.jsx)("span", { children: getFeedbackPrompt(feedbackConfig) }), (0, import_jsx_runtime4.jsx)("button", { type: "button", style: {
18337
+ return (0, import_jsx_runtime4.jsxs)("div", { style: itemStyle, "data-faq-item-id": item.config.id, children: [(0, import_jsx_runtime4.jsxs)("button", { type: "button", style: questionStyle, onClick: onToggle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), "aria-expanded": isExpanded, children: [(0, import_jsx_runtime4.jsx)("span", { children: question }), (0, import_jsx_runtime4.jsx)("span", { style: chevronStyle, children: "\u203A" })] }), (0, import_jsx_runtime4.jsxs)("div", { style: answerStyle, "aria-hidden": !isExpanded, children: [renderAnswer(answer), isExpanded && feedbackConfig && (0, import_jsx_runtime4.jsxs)("div", { style: feedbackStyle, children: [(0, import_jsx_runtime4.jsx)("span", { children: getFeedbackPrompt(feedbackConfig) }), (0, import_jsx_runtime4.jsx)("button", { type: "button", style: {
18262
18338
  ...baseStyles.feedbackButton,
18263
18339
  ...feedbackValue === "up" ? baseStyles.feedbackButtonSelected : {}
18264
18340
  }, "aria-label": "Thumbs up", onClick: () => onFeedback(item.config.id, question, "up"), children: "\u{1F44D}" }), (0, import_jsx_runtime4.jsx)("button", { type: "button", style: {
@@ -18439,11 +18515,11 @@ var SyntrologieSDK = (() => {
18439
18515
  ...baseStyles.categoryHeader,
18440
18516
  ...themeStyles[resolvedTheme].categoryHeader
18441
18517
  };
18442
- const renderItems = (items) => items.map((q2) => (0, import_jsx_runtime4.jsx)(FAQItem, { item: q2, isExpanded: expandedIds.has(q2.config.id), isHighlighted: highlightId === q2.config.id, onToggle: () => handleToggle(q2.config.id), theme: resolvedTheme, feedbackConfig, feedbackValue: feedbackState.get(q2.config.id), onFeedback: handleFeedback }, q2.config.id));
18518
+ const renderItems = (items) => items.map((q2, index2) => (0, import_jsx_runtime4.jsx)(FAQItem, { item: q2, isExpanded: expandedIds.has(q2.config.id), isHighlighted: highlightId === q2.config.id, isLast: index2 === items.length - 1, onToggle: () => handleToggle(q2.config.id), theme: resolvedTheme, feedbackConfig, feedbackValue: feedbackState.get(q2.config.id), onFeedback: handleFeedback }, q2.config.id));
18443
18519
  if (visibleQuestions.length === 0) {
18444
18520
  return (0, import_jsx_runtime4.jsx)("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-faq", children: (0, import_jsx_runtime4.jsx)("div", { style: emptyStateStyle, children: "No FAQ questions available." }) });
18445
18521
  }
18446
- return (0, import_jsx_runtime4.jsxs)("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-faq", children: [config.searchable && (0, import_jsx_runtime4.jsx)("div", { style: baseStyles.searchWrapper, children: (0, import_jsx_runtime4.jsx)("input", { type: "text", placeholder: "Search questions...", value: searchQuery, onChange: (e2) => setSearchQuery(e2.target.value), style: searchInputStyle }) }), (0, import_jsx_runtime4.jsx)("div", { style: baseStyles.accordion, children: hasCategories ? Array.from(categoryGroups.entries()).map(([category, items]) => (0, import_jsx_runtime4.jsxs)(import_react4.default.Fragment, { children: [category && (0, import_jsx_runtime4.jsx)("div", { style: categoryHeaderStyle, "data-category-header": category, children: category }), renderItems(items)] }, category ?? "__ungrouped")) : renderItems(filteredQuestions) }), config.searchable && filteredQuestions.length === 0 && searchQuery && (0, import_jsx_runtime4.jsxs)("div", { style: { ...baseStyles.noResults, ...themeStyles[resolvedTheme].emptyState }, children: ['No questions found matching "', searchQuery, '"'] })] });
18522
+ return (0, import_jsx_runtime4.jsxs)("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-faq", children: [config.searchable && (0, import_jsx_runtime4.jsxs)("div", { style: baseStyles.searchWrapper, children: [(0, import_jsx_runtime4.jsx)("style", { children: `[data-adaptive-id="${instanceId}"] input::placeholder { color: var(--sc-content-search-color, inherit); opacity: 0.7; }` }), (0, import_jsx_runtime4.jsx)("input", { type: "text", placeholder: "Search questions...", value: searchQuery, onChange: (e2) => setSearchQuery(e2.target.value), style: searchInputStyle })] }), (0, import_jsx_runtime4.jsx)("div", { style: baseStyles.accordion, children: hasCategories ? Array.from(categoryGroups.entries()).map(([category, items]) => (0, import_jsx_runtime4.jsxs)(import_react4.default.Fragment, { children: [category && (0, import_jsx_runtime4.jsx)("div", { style: categoryHeaderStyle, "data-category-header": category, children: category }), renderItems(items)] }, category ?? "__ungrouped")) : renderItems(filteredQuestions) }), config.searchable && filteredQuestions.length === 0 && searchQuery && (0, import_jsx_runtime4.jsxs)("div", { style: { ...baseStyles.noResults, ...themeStyles[resolvedTheme].emptyState }, children: ['No questions found matching "', searchQuery, '"'] })] });
18447
18523
  }
18448
18524
  var FAQMountableWidget = {
18449
18525
  mount(container, config) {
@@ -18501,7 +18577,8 @@ var SyntrologieSDK = (() => {
18501
18577
  metadata: {
18502
18578
  name: "FAQ Accordion",
18503
18579
  description: "Collapsible Q&A accordion with search, categories, and feedback",
18504
- icon: "\u2753"
18580
+ icon: "\u2753",
18581
+ subtitle: "Curated just for you."
18505
18582
  }
18506
18583
  }
18507
18584
  ],
@@ -18580,18 +18657,17 @@ var SyntrologieSDK = (() => {
18580
18657
  }
18581
18658
  var baseStyles2 = {
18582
18659
  container: {
18583
- fontFamily: "system-ui, -apple-system, sans-serif",
18584
- padding: "8px",
18660
+ fontFamily: "var(--sc-font-family, system-ui, -apple-system, sans-serif)",
18585
18661
  maxWidth: "100%",
18586
18662
  overflow: "hidden"
18587
18663
  },
18588
18664
  accordion: {
18589
18665
  display: "flex",
18590
18666
  flexDirection: "column",
18591
- gap: "4px"
18667
+ gap: "var(--sc-content-item-gap, 6px)"
18592
18668
  },
18593
18669
  item: {
18594
- borderRadius: "8px",
18670
+ borderRadius: "var(--sc-content-border-radius, 8px)",
18595
18671
  overflow: "hidden",
18596
18672
  transition: "box-shadow 0.2s ease"
18597
18673
  },
@@ -18600,20 +18676,21 @@ var SyntrologieSDK = (() => {
18600
18676
  alignItems: "center",
18601
18677
  gap: "8px",
18602
18678
  width: "100%",
18603
- padding: "12px 16px",
18679
+ padding: "var(--sc-content-item-padding, 12px 16px)",
18604
18680
  border: "none",
18605
18681
  cursor: "pointer",
18606
- fontSize: "14px",
18682
+ fontSize: "var(--sc-content-item-font-size, 15px)",
18607
18683
  fontWeight: 500,
18608
18684
  fontFamily: "inherit",
18609
18685
  textAlign: "left",
18610
18686
  transition: "background-color 0.15s ease"
18611
18687
  },
18612
18688
  chevron: {
18613
- fontSize: "10px",
18689
+ fontSize: "20px",
18614
18690
  transition: "transform 0.2s ease",
18615
18691
  marginLeft: "auto",
18616
- flexShrink: 0
18692
+ flexShrink: 0,
18693
+ color: "var(--sc-content-chevron-color, currentColor)"
18617
18694
  },
18618
18695
  icon: {
18619
18696
  fontSize: "16px",
@@ -18622,10 +18699,10 @@ var SyntrologieSDK = (() => {
18622
18699
  body: {
18623
18700
  overflow: "hidden",
18624
18701
  transition: "max-height 0.25s ease, padding-bottom 0.25s ease",
18625
- padding: "0 16px"
18702
+ padding: "var(--sc-content-body-padding, 0 16px 12px 16px)"
18626
18703
  },
18627
18704
  description: {
18628
- fontSize: "13px",
18705
+ fontSize: "var(--sc-content-body-font-size, 14px)",
18629
18706
  lineHeight: "1.5",
18630
18707
  margin: 0
18631
18708
  },
@@ -18644,11 +18721,11 @@ var SyntrologieSDK = (() => {
18644
18721
  transition: "background-color 0.15s ease"
18645
18722
  },
18646
18723
  categoryHeader: {
18647
- fontSize: "11px",
18724
+ fontSize: "var(--sc-content-category-font-size, 12px)",
18648
18725
  fontWeight: 600,
18649
18726
  textTransform: "uppercase",
18650
18727
  letterSpacing: "0.05em",
18651
- padding: "12px 4px 4px"
18728
+ padding: "var(--sc-content-category-padding, 8px 4px 4px 4px)"
18652
18729
  },
18653
18730
  emptyState: {
18654
18731
  fontSize: "13px",
@@ -18659,29 +18736,29 @@ var SyntrologieSDK = (() => {
18659
18736
  var themeStyles2 = {
18660
18737
  light: {
18661
18738
  container: {
18662
- backgroundColor: base.white,
18663
- color: slateGrey[1]
18739
+ backgroundColor: "transparent",
18740
+ color: "inherit"
18664
18741
  },
18665
18742
  item: {
18666
- backgroundColor: slateGrey[12],
18667
- border: `1px solid ${slateGrey[11]}`
18743
+ backgroundColor: "var(--sc-content-background)",
18744
+ border: "var(--sc-content-border)"
18668
18745
  },
18669
18746
  itemExpanded: {
18670
18747
  boxShadow: "0 4px 12px rgba(0, 0, 0, 0.08)"
18671
18748
  },
18672
18749
  header: {
18673
18750
  backgroundColor: "transparent",
18674
- color: slateGrey[1]
18751
+ color: "var(--sc-content-text-color)"
18675
18752
  },
18676
18753
  headerHover: {
18677
- backgroundColor: slateGrey[12]
18754
+ backgroundColor: "var(--sc-content-background-hover)"
18678
18755
  },
18679
18756
  body: {
18680
- color: slateGrey[6]
18757
+ color: "var(--sc-content-text-secondary-color)"
18681
18758
  },
18682
18759
  linkButton: {
18683
- backgroundColor: purple[8],
18684
- color: purple[2]
18760
+ backgroundColor: "var(--sc-color-primary, #6366f1)",
18761
+ color: "#ffffff"
18685
18762
  },
18686
18763
  categoryHeader: {
18687
18764
  color: slateGrey[7]
@@ -18692,29 +18769,29 @@ var SyntrologieSDK = (() => {
18692
18769
  },
18693
18770
  dark: {
18694
18771
  container: {
18695
- backgroundColor: slateGrey[1],
18696
- color: slateGrey[12]
18772
+ backgroundColor: "transparent",
18773
+ color: "inherit"
18697
18774
  },
18698
18775
  item: {
18699
- backgroundColor: slateGrey[3],
18700
- border: `1px solid ${slateGrey[5]}`
18776
+ backgroundColor: "var(--sc-content-background)",
18777
+ border: "var(--sc-content-border)"
18701
18778
  },
18702
18779
  itemExpanded: {
18703
- boxShadow: "0 4px 12px rgba(0, 0, 0, 0.3)"
18780
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)"
18704
18781
  },
18705
18782
  header: {
18706
18783
  backgroundColor: "transparent",
18707
- color: slateGrey[12]
18784
+ color: "var(--sc-content-text-color)"
18708
18785
  },
18709
18786
  headerHover: {
18710
- backgroundColor: slateGrey[5]
18787
+ backgroundColor: "var(--sc-content-background-hover)"
18711
18788
  },
18712
18789
  body: {
18713
- color: slateGrey[8]
18790
+ color: "var(--sc-content-text-secondary-color)"
18714
18791
  },
18715
18792
  linkButton: {
18716
- backgroundColor: purple[0],
18717
- color: purple[6]
18793
+ backgroundColor: "var(--sc-color-primary, #6366f1)",
18794
+ color: "#ffffff"
18718
18795
  },
18719
18796
  categoryHeader: {
18720
18797
  color: slateGrey[8]
@@ -18724,14 +18801,15 @@ var SyntrologieSDK = (() => {
18724
18801
  }
18725
18802
  }
18726
18803
  };
18727
- function NavTipItem({ item, isExpanded, onToggle, onNavigate, theme }) {
18804
+ function NavTipItem({ item, isExpanded, isLast, onToggle, onNavigate, theme }) {
18728
18805
  const [isHovered, setIsHovered] = (0, import_react5.useState)(false);
18729
18806
  const colors = themeStyles2[theme];
18730
18807
  const { title, description, href, icon, external } = item.config;
18731
18808
  const itemStyle = {
18732
18809
  ...baseStyles2.item,
18733
18810
  ...colors.item,
18734
- ...isExpanded ? colors.itemExpanded : {}
18811
+ ...isExpanded ? colors.itemExpanded : {},
18812
+ ...!isLast ? { borderBottom: "var(--sc-content-item-divider, none)" } : {}
18735
18813
  };
18736
18814
  const headerStyle = {
18737
18815
  ...baseStyles2.header,
@@ -18740,7 +18818,7 @@ var SyntrologieSDK = (() => {
18740
18818
  };
18741
18819
  const chevronStyle = {
18742
18820
  ...baseStyles2.chevron,
18743
- transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)"
18821
+ transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
18744
18822
  };
18745
18823
  const bodyStyle = {
18746
18824
  ...baseStyles2.body,
@@ -18755,7 +18833,7 @@ var SyntrologieSDK = (() => {
18755
18833
  onNavigate(href, external ?? false);
18756
18834
  }
18757
18835
  };
18758
- return (0, import_jsx_runtime5.jsxs)("div", { style: itemStyle, "data-nav-tip-id": item.config.id, children: [(0, import_jsx_runtime5.jsxs)("button", { type: "button", style: headerStyle, onClick: onToggle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), "aria-expanded": isExpanded, children: [icon && (0, import_jsx_runtime5.jsx)("span", { style: baseStyles2.icon, children: icon }), (0, import_jsx_runtime5.jsx)("span", { children: title }), (0, import_jsx_runtime5.jsx)("span", { style: chevronStyle, children: "\u25BC" })] }), (0, import_jsx_runtime5.jsxs)("div", { style: bodyStyle, "aria-hidden": !isExpanded, children: [(0, import_jsx_runtime5.jsx)("p", { style: baseStyles2.description, children: description }), href && (0, import_jsx_runtime5.jsxs)("a", { href, onClick: handleLinkClick, style: { ...baseStyles2.linkButton, ...colors.linkButton }, target: external ? "_blank" : void 0, rel: external ? "noopener noreferrer" : void 0, children: ["Go ", external ? "\u2197" : "\u2192"] })] })] });
18836
+ return (0, import_jsx_runtime5.jsxs)("div", { style: itemStyle, "data-nav-tip-id": item.config.id, children: [(0, import_jsx_runtime5.jsxs)("button", { type: "button", style: headerStyle, onClick: onToggle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), "aria-expanded": isExpanded, children: [icon && (0, import_jsx_runtime5.jsx)("span", { style: baseStyles2.icon, children: icon }), (0, import_jsx_runtime5.jsx)("span", { children: title }), (0, import_jsx_runtime5.jsx)("span", { style: chevronStyle, children: "\u203A" })] }), (0, import_jsx_runtime5.jsxs)("div", { style: bodyStyle, "aria-hidden": !isExpanded, children: [(0, import_jsx_runtime5.jsx)("p", { style: baseStyles2.description, children: description }), href && (0, import_jsx_runtime5.jsxs)("a", { href, onClick: handleLinkClick, style: { ...baseStyles2.linkButton, ...colors.linkButton }, target: external ? "_blank" : void 0, rel: external ? "noopener noreferrer" : void 0, children: ["Go ", external ? "\u2197" : "\u2192"] })] })] });
18759
18837
  }
18760
18838
  function NavWidget({ config, runtime: runtime7, instanceId }) {
18761
18839
  const [renderTick, forceUpdate] = (0, import_react5.useReducer)((x2) => x2 + 1, 0);
@@ -18867,7 +18945,7 @@ var SyntrologieSDK = (() => {
18867
18945
  ...baseStyles2.emptyState,
18868
18946
  ...themeStyles2[resolvedTheme].emptyState
18869
18947
  };
18870
- const renderItems = (items) => items.map((tip) => (0, import_jsx_runtime5.jsx)(NavTipItem, { item: tip, isExpanded: expandedIds.has(tip.config.id), onToggle: () => handleToggle(tip.config.id), onNavigate: handleNavigate, theme: resolvedTheme }, tip.config.id));
18948
+ const renderItems = (items) => items.map((tip, index2) => (0, import_jsx_runtime5.jsx)(NavTipItem, { item: tip, isExpanded: expandedIds.has(tip.config.id), isLast: index2 === items.length - 1, onToggle: () => handleToggle(tip.config.id), onNavigate: handleNavigate, theme: resolvedTheme }, tip.config.id));
18871
18949
  if (visibleTips.length === 0) {
18872
18950
  return (0, import_jsx_runtime5.jsx)("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-nav", children: (0, import_jsx_runtime5.jsx)("div", { style: emptyStateStyle, children: "No navigation tips available." }) });
18873
18951
  }
@@ -19166,7 +19244,7 @@ var SyntrologieSDK = (() => {
19166
19244
  }
19167
19245
 
19168
19246
  // src/version.ts
19169
- var SDK_VERSION = "2.4.0-canary.22";
19247
+ var SDK_VERSION = "2.4.0-canary.24";
19170
19248
 
19171
19249
  // src/types.ts
19172
19250
  var SDK_SCHEMA_VERSION = "2.0";
@@ -19631,6 +19709,9 @@ var SyntrologieSDK = (() => {
19631
19709
  --syntro-border: var(--sc-overlay-border, #2b333f);
19632
19710
  --syntro-tooltip-bg: var(--syntro-surface);
19633
19711
  --syntro-tooltip-fg: var(--syntro-fg);
19712
+ --syntro-tooltip-title-color: var(--sc-overlay-title-color, var(--syntro-fg));
19713
+ --syntro-tooltip-arrow-bg: var(--sc-overlay-arrow-color, var(--syntro-tooltip-bg));
19714
+ --syntro-tooltip-arrow-size: var(--sc-overlay-arrow-size, 8px);
19634
19715
  --syntro-tooltip-radius: var(--syntro-radius);
19635
19716
  --syntro-tooltip-padding: 12px 16px;
19636
19717
  --syntro-tooltip-shadow: var(--syntro-shadow);
@@ -19657,14 +19738,13 @@ var SyntrologieSDK = (() => {
19657
19738
  transform 200ms cubic-bezier(0.16, 1, 0.3, 1);
19658
19739
  }
19659
19740
 
19660
- /* Tooltip arrow */
19741
+ /* Tooltip arrow \u2014 triangle via clip-path (square box so rotation is symmetric) */
19661
19742
  .syntro-tooltip-arrow {
19662
19743
  position: absolute;
19663
- width: 8px;
19664
- height: 8px;
19665
- background: inherit;
19666
- transform: rotate(45deg);
19667
- z-index: -1;
19744
+ width: var(--syntro-tooltip-arrow-size);
19745
+ height: var(--syntro-tooltip-arrow-size);
19746
+ background: var(--syntro-tooltip-arrow-bg);
19747
+ clip-path: polygon(0 0, 100% 0, 50% 100%);
19668
19748
  }
19669
19749
 
19670
19750
  /* Tooltip content */
@@ -19672,6 +19752,7 @@ var SyntrologieSDK = (() => {
19672
19752
  font-weight: 600;
19673
19753
  font-size: 15px;
19674
19754
  margin-bottom: 6px;
19755
+ color: var(--syntro-tooltip-title-color);
19675
19756
  }
19676
19757
 
19677
19758
  .syntro-tt-body {
@@ -19954,10 +20035,10 @@ var SyntrologieSDK = (() => {
19954
20035
  }
19955
20036
 
19956
20037
  // src/SmartCanvasApp.tsx
19957
- var import_react14 = __toESM(require_react(), 1);
20038
+ var import_react16 = __toESM(require_react(), 1);
19958
20039
 
19959
20040
  // src/components/ShadowCanvasOverlay.tsx
19960
- var import_react12 = __toESM(require_react(), 1);
20041
+ var import_react14 = __toESM(require_react(), 1);
19961
20042
  var import_react_dom = __toESM(require_react_dom(), 1);
19962
20043
 
19963
20044
  // src/events/types.ts
@@ -20244,7 +20325,7 @@ var SyntrologieSDK = (() => {
20244
20325
  ]
20245
20326
  }
20246
20327
  ),
20247
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { height: "2px", background: "rgba(255, 255, 255, 0.06)" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
20328
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { height: "2px", background: "rgba(0, 0, 0, 0.08)" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
20248
20329
  "div",
20249
20330
  {
20250
20331
  className: "syntro-toast-progress",
@@ -20703,17 +20784,19 @@ var SyntrologieSDK = (() => {
20703
20784
  borderRadius: "12px",
20704
20785
  canvas: {
20705
20786
  position: "right",
20787
+ layout: "overlay",
20706
20788
  background: withAlpha(slateGrey[1], 0.6),
20707
20789
  blur: "blur(24px)",
20708
20790
  border: "none",
20709
- width: "clamp(320px, 16.666vw, 420px)"
20791
+ width: "clamp(380px, 25vw, 520px)"
20710
20792
  },
20711
20793
  launcher: {
20712
20794
  background: button.primary.backgroundDefault,
20713
20795
  backgroundHover: button.primary.backgroundHover,
20714
20796
  color: button.primary.icon,
20715
20797
  size: "56px",
20716
- shadow: `0 8px 32px ${withAlpha(slateGrey[0], 0.6)}`
20798
+ shadow: `0 8px 32px ${withAlpha(slateGrey[0], 0.6)}`,
20799
+ borderRadius: "9999px"
20717
20800
  },
20718
20801
  tile: {
20719
20802
  background: withAlpha(slateGrey[1], 0.6),
@@ -20724,11 +20807,17 @@ var SyntrologieSDK = (() => {
20724
20807
  titleColor: text.primary,
20725
20808
  textColor: text.secondary,
20726
20809
  iconBackground: `linear-gradient(135deg, ${brand[3]} 0%, ${brand[3]}cc 100%)`,
20727
- iconShadow: `0 2px 8px ${brand[3]}40`
20810
+ iconShadow: `0 2px 8px ${brand[3]}40`,
20811
+ headerPadding: "0.375rem 0.75rem",
20812
+ bodyPadding: "0 0.75rem 0.5rem",
20813
+ gap: "0.25rem"
20728
20814
  },
20729
20815
  overlay: {
20730
20816
  background: withAlpha(slateGrey[1], 0.6),
20731
20817
  textColor: text.primary,
20818
+ titleColor: text.primary,
20819
+ arrowColor: withAlpha(slateGrey[1], 0.6),
20820
+ arrowSize: "8px",
20732
20821
  border: "none",
20733
20822
  borderRadius: "0",
20734
20823
  scrimOpacity: "0",
@@ -20745,6 +20834,26 @@ var SyntrologieSDK = (() => {
20745
20834
  errorColor: red[4],
20746
20835
  iconBackground: withAlpha(brand[3], 0.15),
20747
20836
  progressGradient: `linear-gradient(90deg, ${brand[3]}, ${brand[4]})`
20837
+ },
20838
+ content: {
20839
+ background: withAlpha(slateGrey[3], 0.8),
20840
+ backgroundHover: withAlpha(slateGrey[5], 0.6),
20841
+ border: `1px solid ${withAlpha(slateGrey[5], 0.5)}`,
20842
+ borderRadius: "8px",
20843
+ textColor: text.primary,
20844
+ textSecondaryColor: text.secondary,
20845
+ itemDivider: "none",
20846
+ itemGap: "6px",
20847
+ itemPadding: "12px 16px",
20848
+ itemFontSize: "15px",
20849
+ bodyPadding: "0 16px 12px 16px",
20850
+ bodyFontSize: "14px",
20851
+ categoryPadding: "8px 4px 4px 4px",
20852
+ categoryGap: "4px",
20853
+ categoryFontSize: "12px",
20854
+ searchBackground: withAlpha(slateGrey[3], 0.8),
20855
+ searchColor: text.primary,
20856
+ chevronColor: "currentColor"
20748
20857
  }
20749
20858
  };
20750
20859
  var lightDefaults = {
@@ -20755,17 +20864,19 @@ var SyntrologieSDK = (() => {
20755
20864
  borderRadius: "12px",
20756
20865
  canvas: {
20757
20866
  position: "right",
20867
+ layout: "overlay",
20758
20868
  background: withAlpha(slateGrey[12], 0.7),
20759
20869
  blur: "blur(24px)",
20760
20870
  border: "none",
20761
- width: "clamp(320px, 16.666vw, 420px)"
20871
+ width: "clamp(380px, 25vw, 520px)"
20762
20872
  },
20763
20873
  launcher: {
20764
20874
  background: brand[3],
20765
20875
  backgroundHover: brand[2],
20766
20876
  color: "#ffffff",
20767
20877
  size: "56px",
20768
- shadow: "0 8px 32px rgba(0, 0, 0, 0.15)"
20878
+ shadow: "0 8px 32px rgba(0, 0, 0, 0.15)",
20879
+ borderRadius: "9999px"
20769
20880
  },
20770
20881
  tile: {
20771
20882
  background: withAlpha(slateGrey[12], 0.7),
@@ -20776,11 +20887,17 @@ var SyntrologieSDK = (() => {
20776
20887
  titleColor: slateGrey[1],
20777
20888
  textColor: slateGrey[6],
20778
20889
  iconBackground: `linear-gradient(135deg, ${brand[3]} 0%, ${brand[3]}cc 100%)`,
20779
- iconShadow: `0 2px 8px ${brand[3]}40`
20890
+ iconShadow: `0 2px 8px ${brand[3]}40`,
20891
+ headerPadding: "0.375rem 0.75rem",
20892
+ bodyPadding: "0 0.75rem 0.5rem",
20893
+ gap: "0.25rem"
20780
20894
  },
20781
20895
  overlay: {
20782
20896
  background: withAlpha(slateGrey[12], 0.7),
20783
20897
  textColor: slateGrey[1],
20898
+ titleColor: slateGrey[1],
20899
+ arrowColor: withAlpha(slateGrey[12], 0.7),
20900
+ arrowSize: "8px",
20784
20901
  border: "none",
20785
20902
  borderRadius: "0",
20786
20903
  scrimOpacity: "0",
@@ -20797,6 +20914,26 @@ var SyntrologieSDK = (() => {
20797
20914
  errorColor: red[4],
20798
20915
  iconBackground: withAlpha(brand[3], 0.1),
20799
20916
  progressGradient: `linear-gradient(90deg, ${brand[3]}, ${brand[2]})`
20917
+ },
20918
+ content: {
20919
+ background: withAlpha(slateGrey[12], 0.8),
20920
+ backgroundHover: withAlpha(slateGrey[11], 0.6),
20921
+ border: `1px solid ${slateGrey[11]}`,
20922
+ borderRadius: "8px",
20923
+ textColor: slateGrey[1],
20924
+ textSecondaryColor: slateGrey[6],
20925
+ itemDivider: "none",
20926
+ itemGap: "6px",
20927
+ itemPadding: "12px 16px",
20928
+ itemFontSize: "15px",
20929
+ bodyPadding: "0 16px 12px 16px",
20930
+ bodyFontSize: "14px",
20931
+ categoryPadding: "8px 4px 4px 4px",
20932
+ categoryGap: "4px",
20933
+ categoryFontSize: "12px",
20934
+ searchBackground: slateGrey[12],
20935
+ searchColor: slateGrey[1],
20936
+ chevronColor: "currentColor"
20800
20937
  }
20801
20938
  };
20802
20939
  function mergeThemeConfig(customer) {
@@ -20811,7 +20948,8 @@ var SyntrologieSDK = (() => {
20811
20948
  launcher: { ...base2.launcher, ...customer.launcher },
20812
20949
  tile: { ...base2.tile, ...customer.tile },
20813
20950
  overlay: { ...base2.overlay, ...customer.overlay },
20814
- notification: { ...base2.notification, ...customer.notification }
20951
+ notification: { ...base2.notification, ...customer.notification },
20952
+ content: { ...base2.content, ...customer.content }
20815
20953
  };
20816
20954
  }
20817
20955
  function mergeThemeWithWorkspace(workspaceTheme, configTheme) {
@@ -20831,10 +20969,18 @@ var SyntrologieSDK = (() => {
20831
20969
  ...base2.notification,
20832
20970
  ...workspaceTheme.notification,
20833
20971
  ...configTheme.notification
20834
- }
20972
+ },
20973
+ content: { ...base2.content, ...workspaceTheme.content, ...configTheme.content }
20835
20974
  };
20836
20975
  }
20837
- var ELEMENT_SECTIONS = ["canvas", "launcher", "tile", "overlay", "notification"];
20976
+ var ELEMENT_SECTIONS = [
20977
+ "canvas",
20978
+ "launcher",
20979
+ "tile",
20980
+ "overlay",
20981
+ "notification",
20982
+ "content"
20983
+ ];
20838
20984
  function flattenThemeConfig(config) {
20839
20985
  const vars = {};
20840
20986
  if (config.fontFamily) vars["--sc-font-family"] = config.fontFamily;
@@ -20897,16 +21043,257 @@ ${cssRules}
20897
21043
  }
20898
21044
 
20899
21045
  // src/components/TileCard.tsx
20900
- var import_react11 = __toESM(require_react(), 1);
21046
+ var import_react13 = __toESM(require_react(), 1);
21047
+
21048
+ // ../../node_modules/lucide-react/dist/esm/createLucideIcon.js
21049
+ var import_react12 = __toESM(require_react());
21050
+
21051
+ // ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
21052
+ var mergeClasses = (...classes2) => classes2.filter((className, index2, array) => {
21053
+ return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index2;
21054
+ }).join(" ").trim();
21055
+
21056
+ // ../../node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.js
21057
+ var toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
21058
+
21059
+ // ../../node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.js
21060
+ var toCamelCase = (string) => string.replace(
21061
+ /^([A-Z])|[\s-_]+(\w)/g,
21062
+ (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
21063
+ );
21064
+
21065
+ // ../../node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.js
21066
+ var toPascalCase = (string) => {
21067
+ const camelCase = toCamelCase(string);
21068
+ return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
21069
+ };
21070
+
21071
+ // ../../node_modules/lucide-react/dist/esm/Icon.js
21072
+ var import_react11 = __toESM(require_react());
21073
+
21074
+ // ../../node_modules/lucide-react/dist/esm/defaultAttributes.js
21075
+ var defaultAttributes = {
21076
+ xmlns: "http://www.w3.org/2000/svg",
21077
+ width: 24,
21078
+ height: 24,
21079
+ viewBox: "0 0 24 24",
21080
+ fill: "none",
21081
+ stroke: "currentColor",
21082
+ strokeWidth: 2,
21083
+ strokeLinecap: "round",
21084
+ strokeLinejoin: "round"
21085
+ };
21086
+
21087
+ // ../../node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.js
21088
+ var hasA11yProp = (props) => {
21089
+ for (const prop in props) {
21090
+ if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
21091
+ return true;
21092
+ }
21093
+ }
21094
+ return false;
21095
+ };
21096
+
21097
+ // ../../node_modules/lucide-react/dist/esm/Icon.js
21098
+ var Icon = (0, import_react11.forwardRef)(
21099
+ ({
21100
+ color = "currentColor",
21101
+ size: size2 = 24,
21102
+ strokeWidth = 2,
21103
+ absoluteStrokeWidth,
21104
+ className = "",
21105
+ children,
21106
+ iconNode,
21107
+ ...rest
21108
+ }, ref) => (0, import_react11.createElement)(
21109
+ "svg",
21110
+ {
21111
+ ref,
21112
+ ...defaultAttributes,
21113
+ width: size2,
21114
+ height: size2,
21115
+ stroke: color,
21116
+ strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size2) : strokeWidth,
21117
+ className: mergeClasses("lucide", className),
21118
+ ...!children && !hasA11yProp(rest) && { "aria-hidden": "true" },
21119
+ ...rest
21120
+ },
21121
+ [
21122
+ ...iconNode.map(([tag2, attrs]) => (0, import_react11.createElement)(tag2, attrs)),
21123
+ ...Array.isArray(children) ? children : [children]
21124
+ ]
21125
+ )
21126
+ );
21127
+
21128
+ // ../../node_modules/lucide-react/dist/esm/createLucideIcon.js
21129
+ var createLucideIcon = (iconName, iconNode) => {
21130
+ const Component = (0, import_react12.forwardRef)(
21131
+ ({ className, ...props }, ref) => (0, import_react12.createElement)(Icon, {
21132
+ ref,
21133
+ iconNode,
21134
+ className: mergeClasses(
21135
+ `lucide-${toKebabCase(toPascalCase(iconName))}`,
21136
+ `lucide-${iconName}`,
21137
+ className
21138
+ ),
21139
+ ...props
21140
+ })
21141
+ );
21142
+ Component.displayName = toPascalCase(iconName);
21143
+ return Component;
21144
+ };
21145
+
21146
+ // ../../node_modules/lucide-react/dist/esm/icons/circle-question-mark.js
21147
+ var __iconNode = [
21148
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
21149
+ ["path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3", key: "1u773s" }],
21150
+ ["path", { d: "M12 17h.01", key: "p32p05" }]
21151
+ ];
21152
+ var CircleQuestionMark = createLucideIcon("circle-question-mark", __iconNode);
21153
+
21154
+ // ../../node_modules/lucide-react/dist/esm/icons/compass.js
21155
+ var __iconNode2 = [
21156
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
21157
+ [
21158
+ "path",
21159
+ {
21160
+ d: "m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z",
21161
+ key: "9ktpf1"
21162
+ }
21163
+ ]
21164
+ ];
21165
+ var Compass = createLucideIcon("compass", __iconNode2);
21166
+
21167
+ // ../../node_modules/lucide-react/dist/esm/icons/file-text.js
21168
+ var __iconNode3 = [
21169
+ [
21170
+ "path",
21171
+ {
21172
+ d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",
21173
+ key: "1oefj6"
21174
+ }
21175
+ ],
21176
+ ["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }],
21177
+ ["path", { d: "M10 9H8", key: "b1mrlr" }],
21178
+ ["path", { d: "M16 13H8", key: "t4e002" }],
21179
+ ["path", { d: "M16 17H8", key: "z1uh3a" }]
21180
+ ];
21181
+ var FileText = createLucideIcon("file-text", __iconNode3);
21182
+
21183
+ // ../../node_modules/lucide-react/dist/esm/icons/gamepad-2.js
21184
+ var __iconNode4 = [
21185
+ ["line", { x1: "6", x2: "10", y1: "11", y2: "11", key: "1gktln" }],
21186
+ ["line", { x1: "8", x2: "8", y1: "9", y2: "13", key: "qnk9ow" }],
21187
+ ["line", { x1: "15", x2: "15.01", y1: "12", y2: "12", key: "krot7o" }],
21188
+ ["line", { x1: "18", x2: "18.01", y1: "10", y2: "10", key: "1lcuu1" }],
21189
+ [
21190
+ "path",
21191
+ {
21192
+ d: "M17.32 5H6.68a4 4 0 0 0-3.978 3.59c-.006.052-.01.101-.017.152C2.604 9.416 2 14.456 2 16a3 3 0 0 0 3 3c1 0 1.5-.5 2-1l1.414-1.414A2 2 0 0 1 9.828 16h4.344a2 2 0 0 1 1.414.586L17 18c.5.5 1 1 2 1a3 3 0 0 0 3-3c0-1.545-.604-6.584-.685-7.258-.007-.05-.011-.1-.017-.151A4 4 0 0 0 17.32 5z",
21193
+ key: "mfqc10"
21194
+ }
21195
+ ]
21196
+ ];
21197
+ var Gamepad2 = createLucideIcon("gamepad-2", __iconNode4);
21198
+
21199
+ // ../../node_modules/lucide-react/dist/esm/icons/layers.js
21200
+ var __iconNode5 = [
21201
+ [
21202
+ "path",
21203
+ {
21204
+ d: "M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",
21205
+ key: "zw3jo"
21206
+ }
21207
+ ],
21208
+ [
21209
+ "path",
21210
+ {
21211
+ d: "M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",
21212
+ key: "1wduqc"
21213
+ }
21214
+ ],
21215
+ [
21216
+ "path",
21217
+ {
21218
+ d: "M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",
21219
+ key: "kqbvx6"
21220
+ }
21221
+ ]
21222
+ ];
21223
+ var Layers = createLucideIcon("layers", __iconNode5);
21224
+
21225
+ // ../../node_modules/lucide-react/dist/esm/icons/message-circle.js
21226
+ var __iconNode6 = [
21227
+ [
21228
+ "path",
21229
+ {
21230
+ d: "M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",
21231
+ key: "1sd12s"
21232
+ }
21233
+ ]
21234
+ ];
21235
+ var MessageCircle = createLucideIcon("message-circle", __iconNode6);
21236
+
21237
+ // ../../node_modules/lucide-react/dist/esm/icons/sparkles.js
21238
+ var __iconNode7 = [
21239
+ [
21240
+ "path",
21241
+ {
21242
+ d: "M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",
21243
+ key: "1s2grr"
21244
+ }
21245
+ ],
21246
+ ["path", { d: "M20 2v4", key: "1rf3ol" }],
21247
+ ["path", { d: "M22 4h-4", key: "gwowj6" }],
21248
+ ["circle", { cx: "4", cy: "20", r: "2", key: "6kqj1y" }]
21249
+ ];
21250
+ var Sparkles = createLucideIcon("sparkles", __iconNode7);
21251
+
21252
+ // ../../node_modules/lucide-react/dist/esm/icons/trophy.js
21253
+ var __iconNode8 = [
21254
+ ["path", { d: "M10 14.66v1.626a2 2 0 0 1-.976 1.696A5 5 0 0 0 7 21.978", key: "1n3hpd" }],
21255
+ ["path", { d: "M14 14.66v1.626a2 2 0 0 0 .976 1.696A5 5 0 0 1 17 21.978", key: "rfe1zi" }],
21256
+ ["path", { d: "M18 9h1.5a1 1 0 0 0 0-5H18", key: "7xy6bh" }],
21257
+ ["path", { d: "M4 22h16", key: "57wxv0" }],
21258
+ ["path", { d: "M6 9a6 6 0 0 0 12 0V3a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1z", key: "1mhfuq" }],
21259
+ ["path", { d: "M6 9H4.5a1 1 0 0 1 0-5H6", key: "tex48p" }]
21260
+ ];
21261
+ var Trophy = createLucideIcon("trophy", __iconNode8);
21262
+
21263
+ // src/components/TileIcon.tsx
20901
21264
  var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
21265
+ var ICON_MAP = {
21266
+ "\u2753": CircleQuestionMark,
21267
+ "\u{1F9ED}": Compass,
21268
+ "\u{1F4DD}": FileText,
21269
+ "\u{1F3AF}": Layers,
21270
+ "\u{1F3C6}": Trophy,
21271
+ "\u2728": Sparkles,
21272
+ "\u{1F4AC}": MessageCircle,
21273
+ "\u{1F3AE}": Gamepad2
21274
+ };
21275
+ function TileIcon({
21276
+ emoji,
21277
+ size: size2 = 18,
21278
+ color = "currentColor"
21279
+ }) {
21280
+ const Icon2 = ICON_MAP[emoji];
21281
+ if (!Icon2) {
21282
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: emoji });
21283
+ }
21284
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon2, { size: size2, color });
21285
+ }
21286
+
21287
+ // src/components/TileCard.tsx
21288
+ var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
20902
21289
  function WidgetMount({ widgetId, props }) {
20903
21290
  const runtime7 = useRuntime();
20904
- const containerRef = (0, import_react11.useRef)(null);
20905
- const handleRef = (0, import_react11.useRef)(null);
21291
+ const containerRef = (0, import_react13.useRef)(null);
21292
+ const handleRef = (0, import_react13.useRef)(null);
20906
21293
  const registry = runtime7?.widgets;
20907
21294
  const widgetAvailable = registry?.has(widgetId) ?? false;
20908
- const [, forceUpdate] = (0, import_react11.useReducer)((x2) => x2 + 1, 0);
20909
- (0, import_react11.useEffect)(() => {
21295
+ const [, forceUpdate] = (0, import_react13.useReducer)((x2) => x2 + 1, 0);
21296
+ (0, import_react13.useEffect)(() => {
20910
21297
  if (!registry || widgetAvailable) return;
20911
21298
  return registry.subscribe((event) => {
20912
21299
  if (event.type === "registered" && event.widgetId === widgetId) {
@@ -20914,7 +21301,7 @@ ${cssRules}
20914
21301
  }
20915
21302
  });
20916
21303
  }, [registry, widgetId, widgetAvailable]);
20917
- (0, import_react11.useEffect)(() => {
21304
+ (0, import_react13.useEffect)(() => {
20918
21305
  if (!containerRef.current || !registry || !widgetAvailable) return;
20919
21306
  const handle = registry.mount(widgetId, containerRef.current, props);
20920
21307
  handleRef.current = handle;
@@ -20924,7 +21311,7 @@ ${cssRules}
20924
21311
  };
20925
21312
  }, [registry, widgetId, props, widgetAvailable]);
20926
21313
  if (!registry || !registry.has(widgetId)) {
20927
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
21314
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
20928
21315
  "div",
20929
21316
  {
20930
21317
  style: {
@@ -20940,7 +21327,7 @@ ${cssRules}
20940
21327
  }
20941
21328
  );
20942
21329
  }
20943
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: containerRef, style: { width: "100%", minHeight: "40px" } });
21330
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: containerRef, style: { width: "100%", minHeight: "40px" } });
20944
21331
  }
20945
21332
  function TileCard({
20946
21333
  config,
@@ -20948,15 +21335,27 @@ ${cssRules}
20948
21335
  telemetry: _telemetry,
20949
21336
  style
20950
21337
  }) {
20951
- const { title, widget, props } = config;
20952
- const [, setTick] = (0, import_react11.useState)(0);
21338
+ const { title, subtitle, widget, props, icon } = config;
21339
+ const [, setTick] = (0, import_react13.useState)(0);
20953
21340
  const runtime7 = useRuntime();
20954
- (0, import_react11.useEffect)(() => {
21341
+ (0, import_react13.useEffect)(() => {
20955
21342
  if (runtime7) setTick((t2) => t2 + 1);
20956
21343
  }, [runtime7]);
20957
- const [hovered, setHovered] = (0, import_react11.useState)(false);
20958
- const onMouseEnter = (0, import_react11.useCallback)(() => setHovered(true), []);
20959
- const onMouseLeave = (0, import_react11.useCallback)(() => setHovered(false), []);
21344
+ const registration = (0, import_react13.useMemo)(
21345
+ () => runtime7?.widgets?.getRegistration?.(widget),
21346
+ [runtime7?.widgets, widget]
21347
+ );
21348
+ const resolvedIcon = (0, import_react13.useMemo)(() => {
21349
+ if (icon) return icon;
21350
+ return registration?.metadata?.icon ?? "+";
21351
+ }, [icon, registration]);
21352
+ const resolvedSubtitle = (0, import_react13.useMemo)(() => {
21353
+ if (subtitle) return subtitle;
21354
+ return registration?.metadata?.subtitle;
21355
+ }, [subtitle, registration]);
21356
+ const [hovered, setHovered] = (0, import_react13.useState)(false);
21357
+ const onMouseEnter = (0, import_react13.useCallback)(() => setHovered(true), []);
21358
+ const onMouseLeave = (0, import_react13.useCallback)(() => setHovered(false), []);
20960
21359
  const cardStyle = {
20961
21360
  display: "flex",
20962
21361
  flexDirection: "column",
@@ -20977,23 +21376,17 @@ ${cssRules}
20977
21376
  const headerStyle = {
20978
21377
  display: "flex",
20979
21378
  alignItems: "center",
20980
- gap: "0.75rem",
20981
- padding: "0.875rem 1rem",
20982
- minHeight: "72px"
21379
+ gap: "var(--sc-tile-gap, 0.25rem)",
21380
+ padding: "var(--sc-tile-header-padding, 0.375rem 0.75rem)",
21381
+ minHeight: "44px"
20983
21382
  };
20984
21383
  const iconStyle = {
20985
- width: "40px",
20986
- height: "40px",
20987
- borderRadius: "10px",
20988
- background: "var(--sc-tile-icon-background)",
20989
21384
  display: "flex",
20990
21385
  alignItems: "center",
20991
21386
  justifyContent: "center",
20992
- fontSize: "1.25rem",
20993
- flexShrink: 0,
20994
- boxShadow: "var(--sc-tile-icon-shadow)"
21387
+ flexShrink: 0
20995
21388
  };
20996
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
21389
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
20997
21390
  "article",
20998
21391
  {
20999
21392
  "data-shadow-canvas-id": `tile-${config.id}`,
@@ -21001,32 +21394,49 @@ ${cssRules}
21001
21394
  onMouseEnter,
21002
21395
  onMouseLeave,
21003
21396
  children: [
21004
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: headerStyle, children: [
21005
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: iconStyle, children: "+" }),
21006
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
21007
- "h3",
21008
- {
21009
- style: {
21010
- fontSize: "0.95rem",
21011
- fontWeight: 600,
21012
- color: "var(--sc-tile-title-color)",
21013
- margin: "0.125rem 0 0",
21014
- whiteSpace: "nowrap",
21015
- overflow: "hidden",
21016
- textOverflow: "ellipsis"
21017
- },
21018
- children: title ?? widget
21019
- }
21020
- ) })
21397
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: headerStyle, children: [
21398
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: iconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TileIcon, { emoji: resolvedIcon, size: resolvedSubtitle ? 36 : 24 }) }),
21399
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
21400
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21401
+ "h3",
21402
+ {
21403
+ style: {
21404
+ fontSize: "1.14rem",
21405
+ fontWeight: 600,
21406
+ color: "var(--sc-tile-title-color)",
21407
+ margin: "0.125rem 0 0",
21408
+ whiteSpace: "nowrap",
21409
+ overflow: "hidden",
21410
+ textOverflow: "ellipsis"
21411
+ },
21412
+ children: title ?? widget
21413
+ }
21414
+ ),
21415
+ resolvedSubtitle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21416
+ "p",
21417
+ {
21418
+ style: {
21419
+ fontSize: "0.8rem",
21420
+ fontWeight: 400,
21421
+ color: "var(--sc-tile-text-color)",
21422
+ margin: "0.125rem 0 0",
21423
+ whiteSpace: "nowrap",
21424
+ overflow: "hidden",
21425
+ textOverflow: "ellipsis"
21426
+ },
21427
+ children: resolvedSubtitle
21428
+ }
21429
+ )
21430
+ ] })
21021
21431
  ] }),
21022
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
21432
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21023
21433
  "div",
21024
21434
  {
21025
21435
  style: {
21026
- padding: "0 1rem 1rem",
21436
+ padding: "var(--sc-tile-body-padding, 0 0.75rem 0.5rem)",
21027
21437
  borderTop: "1px solid rgba(255, 255, 255, 0.06)"
21028
21438
  },
21029
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { paddingTop: "0.875rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(WidgetMount, { widgetId: widget, props: { ...props, instanceId: config.id } }) })
21439
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { paddingTop: "var(--sc-tile-gap, 0.25rem)" }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(WidgetMount, { widgetId: widget, props: { ...props, instanceId: config.id } }) })
21030
21440
  }
21031
21441
  )
21032
21442
  ]
@@ -21035,7 +21445,7 @@ ${cssRules}
21035
21445
  }
21036
21446
 
21037
21447
  // src/components/ShadowCanvasOverlay.tsx
21038
- var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
21448
+ var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
21039
21449
  var LAUNCHER_STYLES_ID = "syntro-launcher-styles";
21040
21450
  function ensureLauncherStyles(target, css) {
21041
21451
  if (target.querySelector(`#${LAUNCHER_STYLES_ID}`)) return;
@@ -21049,6 +21459,7 @@ ${cssRules}
21049
21459
  onToggle,
21050
21460
  telemetry,
21051
21461
  launcherLabel: _launcherLabel = "Adaptives",
21462
+ launcherIcon,
21052
21463
  launcherAnimate = false,
21053
21464
  launcherAnimationStyle: _launcherAnimationStyle = "pulse",
21054
21465
  notificationCount: _notificationCount,
@@ -21059,9 +21470,9 @@ ${cssRules}
21059
21470
  canvasTitle,
21060
21471
  displayMode = "standard"
21061
21472
  }) {
21062
- const [mounted, setMounted] = (0, import_react12.useState)(false);
21063
- const [launcherPos, setLauncherPos] = (0, import_react12.useState)(null);
21064
- const dragRef = (0, import_react12.useRef)(null);
21473
+ const [mounted, setMounted] = (0, import_react14.useState)(false);
21474
+ const [launcherPos, setLauncherPos] = (0, import_react14.useState)(null);
21475
+ const dragRef = (0, import_react14.useRef)(null);
21065
21476
  const runtime7 = useRuntime();
21066
21477
  const { shadowRoot, portalRoot } = useShadowRoot();
21067
21478
  const { config } = useTheme();
@@ -21070,7 +21481,7 @@ ${cssRules}
21070
21481
  tiles
21071
21482
  );
21072
21483
  useNotifyWatcher(runtime7, tiles, runtime7?.apps);
21073
- const handleNotificationClick = (0, import_react12.useCallback)(
21484
+ const handleNotificationClick = (0, import_react14.useCallback)(
21074
21485
  (notif) => {
21075
21486
  if (runtime7) {
21076
21487
  runtime7.events.publish(StandardEvents.NOTIFICATION_CLICKED, {
@@ -21092,7 +21503,7 @@ ${cssRules}
21092
21503
  },
21093
21504
  [runtime7, isOpen, onToggle, dismissNotification]
21094
21505
  );
21095
- const launcherCss = (0, import_react12.useMemo)(
21506
+ const launcherCss = (0, import_react14.useMemo)(
21096
21507
  () => `
21097
21508
  @keyframes syntro-launcher-pulse {
21098
21509
  0%, 100% {
@@ -21129,7 +21540,7 @@ ${cssRules}
21129
21540
  `,
21130
21541
  [config.colorPrimary, config.colorPrimaryHover]
21131
21542
  );
21132
- (0, import_react12.useEffect)(() => {
21543
+ (0, import_react14.useEffect)(() => {
21133
21544
  if (!isOpen) return;
21134
21545
  tiles.forEach((tile) => {
21135
21546
  telemetry?.trackRectangleViewed(tile.id, "overlay");
@@ -21139,11 +21550,11 @@ ${cssRules}
21139
21550
  }
21140
21551
  });
21141
21552
  }, [telemetry, runtime7, isOpen, tiles]);
21142
- (0, import_react12.useEffect)(() => {
21553
+ (0, import_react14.useEffect)(() => {
21143
21554
  setMounted(true);
21144
21555
  ensureLauncherStyles(shadowRoot, launcherCss);
21145
21556
  }, [shadowRoot, launcherCss]);
21146
- const toggle2 = (0, import_react12.useCallback)(() => {
21557
+ const toggle2 = (0, import_react14.useCallback)(() => {
21147
21558
  const next = !isOpen;
21148
21559
  if (next) {
21149
21560
  telemetry?.trackCanvasOpened("overlay");
@@ -21156,7 +21567,7 @@ ${cssRules}
21156
21567
  }
21157
21568
  onToggle();
21158
21569
  }, [isOpen, telemetry, runtime7, onToggle]);
21159
- const onLauncherPointerDown = (0, import_react12.useCallback)((e2) => {
21570
+ const onLauncherPointerDown = (0, import_react14.useCallback)((e2) => {
21160
21571
  const rect = e2.currentTarget.getBoundingClientRect();
21161
21572
  dragRef.current = {
21162
21573
  startX: e2.clientX,
@@ -21167,7 +21578,7 @@ ${cssRules}
21167
21578
  };
21168
21579
  e2.currentTarget.setPointerCapture(e2.pointerId);
21169
21580
  }, []);
21170
- const onLauncherPointerMove = (0, import_react12.useCallback)((e2) => {
21581
+ const onLauncherPointerMove = (0, import_react14.useCallback)((e2) => {
21171
21582
  const drag = dragRef.current;
21172
21583
  if (!drag) return;
21173
21584
  const dx = e2.clientX - drag.startX;
@@ -21179,7 +21590,7 @@ ${cssRules}
21179
21590
  setLauncherPos({ x: drag.startElX + dx, y: drag.startElY + dy });
21180
21591
  }
21181
21592
  }, []);
21182
- const onLauncherPointerUp = (0, import_react12.useCallback)(
21593
+ const onLauncherPointerUp = (0, import_react14.useCallback)(
21183
21594
  (_e2) => {
21184
21595
  const drag = dragRef.current;
21185
21596
  dragRef.current = null;
@@ -21191,7 +21602,37 @@ ${cssRules}
21191
21602
  );
21192
21603
  const isFocused = displayMode === "focused";
21193
21604
  const isRight = config.canvas.position === "right";
21605
+ const isPush = config.canvas.layout === "push";
21606
+ const containerRef = (0, import_react14.useRef)(null);
21194
21607
  const zIndex = 2147483600;
21608
+ (0, import_react14.useEffect)(() => {
21609
+ if (!isPush) return;
21610
+ const root = document.documentElement;
21611
+ const prop = isRight ? "marginRight" : "marginLeft";
21612
+ const prevTransition = root.style.transition;
21613
+ root.style.transition = `${prop} 340ms cubic-bezier(0.16, 1, 0.3, 1)`;
21614
+ if (isOpen) {
21615
+ const width = containerRef.current?.offsetWidth ?? 380;
21616
+ root.style[prop] = `${width}px`;
21617
+ } else {
21618
+ root.style[prop] = "0px";
21619
+ }
21620
+ return () => {
21621
+ root.style[prop] = "";
21622
+ root.style.transition = prevTransition;
21623
+ };
21624
+ }, [isPush, isOpen, isRight]);
21625
+ (0, import_react14.useEffect)(() => {
21626
+ if (!isPush || !isOpen) return;
21627
+ const container = containerRef.current;
21628
+ if (!container) return;
21629
+ const prop = isRight ? "marginRight" : "marginLeft";
21630
+ const observer2 = new ResizeObserver(([entry]) => {
21631
+ document.documentElement.style[prop] = `${entry.contentRect.width}px`;
21632
+ });
21633
+ observer2.observe(container);
21634
+ return () => observer2.disconnect();
21635
+ }, [isPush, isOpen, isRight]);
21195
21636
  const containerStyle = {
21196
21637
  display: "flex",
21197
21638
  flexDirection: "column",
@@ -21228,7 +21669,7 @@ ${cssRules}
21228
21669
  pointerEvents: "none",
21229
21670
  padding: "0"
21230
21671
  };
21231
- const content = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21672
+ const content = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21232
21673
  "div",
21233
21674
  {
21234
21675
  "data-shadow-canvas-id": "overlay-root",
@@ -21238,9 +21679,9 @@ ${cssRules}
21238
21679
  pointerEvents: isOpen ? "auto" : "none",
21239
21680
  zIndex
21240
21681
  },
21241
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: wrapperStyle, children: [
21242
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { "data-shadow-canvas-id": "overlay-container", style: containerStyle, children: [
21243
- isFocused && canvasTitle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("header", { style: { color: "white", padding: "1.5rem 1.5rem 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21682
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: wrapperStyle, children: [
21683
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { ref: containerRef, "data-shadow-canvas-id": "overlay-container", style: containerStyle, children: [
21684
+ isFocused && canvasTitle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("header", { style: { color: "white", padding: "1.5rem 1.5rem 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21244
21685
  "p",
21245
21686
  {
21246
21687
  style: {
@@ -21253,13 +21694,13 @@ ${cssRules}
21253
21694
  children: canvasTitle
21254
21695
  }
21255
21696
  ) }),
21256
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { flex: 1, overflowY: "auto", padding: isFocused ? "0" : "1rem" }, children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21697
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { flex: 1, overflowY: "auto", padding: isFocused ? "0" : "1rem" }, children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21257
21698
  "div",
21258
21699
  {
21259
21700
  style: { color: "var(--sc-overlay-text-color)", padding: isFocused ? "1rem" : "0" },
21260
21701
  children: "Loading..."
21261
21702
  }
21262
- ) : error2 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
21703
+ ) : error2 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
21263
21704
  "div",
21264
21705
  {
21265
21706
  style: {
@@ -21273,7 +21714,7 @@ ${cssRules}
21273
21714
  }
21274
21715
  ) : isFocused ? (
21275
21716
  /* Focused Mode: Render first tile full size */
21276
- tiles.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21717
+ tiles.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21277
21718
  TileCard,
21278
21719
  {
21279
21720
  config: tiles[0],
@@ -21284,7 +21725,7 @@ ${cssRules}
21284
21725
  ) : null
21285
21726
  ) : (
21286
21727
  /* Standard Mode: Stacked cards — widgets always visible */
21287
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21728
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21288
21729
  "div",
21289
21730
  {
21290
21731
  style: {
@@ -21293,7 +21734,7 @@ ${cssRules}
21293
21734
  gap: "0.75rem",
21294
21735
  width: "100%"
21295
21736
  },
21296
- children: tiles.map((tile) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21737
+ children: tiles.map((tile) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21297
21738
  TileCard,
21298
21739
  {
21299
21740
  config: tile,
@@ -21308,7 +21749,7 @@ ${cssRules}
21308
21749
  ) }),
21309
21750
  footerSlot
21310
21751
  ] }),
21311
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21752
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21312
21753
  "div",
21313
21754
  {
21314
21755
  onClick: toggle2,
@@ -21323,9 +21764,9 @@ ${cssRules}
21323
21764
  }
21324
21765
  );
21325
21766
  if (!mounted) return null;
21326
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
21767
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
21327
21768
  (0, import_react_dom.createPortal)(
21328
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
21769
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
21329
21770
  "div",
21330
21771
  {
21331
21772
  "data-shadow-canvas-id": "overlay-launcher",
@@ -21336,7 +21777,7 @@ ${cssRules}
21336
21777
  zIndex: zIndex + 47
21337
21778
  },
21338
21779
  children: [
21339
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21780
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21340
21781
  NotificationToastStack,
21341
21782
  {
21342
21783
  notifications,
@@ -21345,7 +21786,7 @@ ${cssRules}
21345
21786
  position: config.canvas.position ?? "right"
21346
21787
  }
21347
21788
  ),
21348
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
21789
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
21349
21790
  "button",
21350
21791
  {
21351
21792
  type: "button",
@@ -21364,7 +21805,7 @@ ${cssRules}
21364
21805
  justifyContent: "center",
21365
21806
  width: "var(--sc-launcher-size, 56px)",
21366
21807
  height: "var(--sc-launcher-size, 56px)",
21367
- borderRadius: "9999px",
21808
+ borderRadius: "var(--sc-launcher-border-radius, 9999px)",
21368
21809
  color: "var(--sc-launcher-color)",
21369
21810
  boxShadow: "var(--sc-launcher-shadow)",
21370
21811
  transition: dragRef.current ? "none" : "transform 0.2s ease, opacity 0.3s ease, background-color 0.2s ease",
@@ -21389,7 +21830,7 @@ ${cssRules}
21389
21830
  }
21390
21831
  },
21391
21832
  children: [
21392
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21833
+ isOpen ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
21393
21834
  "svg",
21394
21835
  {
21395
21836
  width: "24",
@@ -21403,20 +21844,49 @@ ${cssRules}
21403
21844
  "aria-hidden": "true",
21404
21845
  focusable: "false",
21405
21846
  style: { transition: "transform 200ms ease" },
21406
- children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
21407
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M18 6L6 18" }),
21408
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M6 6l12 12" })
21409
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
21410
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M12 3l1.912 5.813a2 2 0 0 0 1.275 1.275L21 12l-5.813 1.912a2 2 0 0 0-1.275 1.275L12 21l-1.912-5.813a2 2 0 0 0-1.275-1.275L3 12l5.813-1.912a2 2 0 0 0 1.275-1.275L12 3Z" }),
21411
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M5 3v4" }),
21412
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M3 5h4" }),
21413
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M19 17v4" }),
21414
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M17 19h4" })
21415
- ] })
21847
+ children: [
21848
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M18 6L6 18" }),
21849
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M6 6l12 12" })
21850
+ ]
21851
+ }
21852
+ ) : launcherIcon ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21853
+ "img",
21854
+ {
21855
+ src: launcherIcon,
21856
+ alt: "",
21857
+ "aria-hidden": "true",
21858
+ style: {
21859
+ width: "60%",
21860
+ height: "60%",
21861
+ objectFit: "contain",
21862
+ pointerEvents: "none"
21863
+ }
21864
+ }
21865
+ ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
21866
+ "svg",
21867
+ {
21868
+ width: "24",
21869
+ height: "24",
21870
+ viewBox: "0 0 24 24",
21871
+ fill: "none",
21872
+ stroke: "currentColor",
21873
+ strokeWidth: "2",
21874
+ strokeLinecap: "round",
21875
+ strokeLinejoin: "round",
21876
+ "aria-hidden": "true",
21877
+ focusable: "false",
21878
+ style: { transition: "transform 200ms ease" },
21879
+ children: [
21880
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M12 3l1.912 5.813a2 2 0 0 0 1.275 1.275L21 12l-5.813 1.912a2 2 0 0 0-1.275 1.275L12 21l-1.912-5.813a2 2 0 0 0-1.275-1.275L3 12l5.813-1.912a2 2 0 0 0 1.275-1.275L12 3Z" }),
21881
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M5 3v4" }),
21882
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M3 5h4" }),
21883
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M19 17v4" }),
21884
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M17 19h4" })
21885
+ ]
21416
21886
  }
21417
21887
  ),
21418
- !isOpen && notifications.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { position: "absolute", top: -2, right: -2, pointerEvents: "none" }, children: [
21419
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21888
+ !isOpen && notifications.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { position: "absolute", top: -2, right: -2, pointerEvents: "none" }, children: [
21889
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21420
21890
  "span",
21421
21891
  {
21422
21892
  className: "syntro-badge-ping",
@@ -21428,7 +21898,7 @@ ${cssRules}
21428
21898
  }
21429
21899
  }
21430
21900
  ),
21431
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21901
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21432
21902
  "span",
21433
21903
  {
21434
21904
  className: "syntro-badge-glow",
@@ -21439,7 +21909,7 @@ ${cssRules}
21439
21909
  }
21440
21910
  }
21441
21911
  ),
21442
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
21912
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
21443
21913
  "span",
21444
21914
  {
21445
21915
  className: "syntro-badge-bounce",
@@ -21473,7 +21943,7 @@ ${cssRules}
21473
21943
  }
21474
21944
 
21475
21945
  // src/hooks/useShadowCanvasConfig.ts
21476
- var import_react13 = __toESM(require_react(), 1);
21946
+ var import_react15 = __toESM(require_react(), 1);
21477
21947
  var sortTiles = (tiles) => [...tiles].sort((a2, b2) => (b2.priority ?? 0) - (a2.priority ?? 0));
21478
21948
  function useShadowCanvasConfig({
21479
21949
  fetcher,
@@ -21482,17 +21952,29 @@ ${cssRules}
21482
21952
  pageUrl,
21483
21953
  pollIntervalMs
21484
21954
  }) {
21485
- const [state, setState] = (0, import_react13.useState)({
21955
+ const [state, setState] = (0, import_react15.useState)({
21486
21956
  tiles: [],
21487
21957
  actions: [],
21488
21958
  isLoading: true
21489
21959
  });
21490
- const prevActionsJsonRef = (0, import_react13.useRef)("[]");
21491
- const load = (0, import_react13.useCallback)(async () => {
21960
+ const prevActionsJsonRef = (0, import_react15.useRef)("[]");
21961
+ const rawConfigRef = (0, import_react15.useRef)(null);
21962
+ const refilter = (0, import_react15.useCallback)(async () => {
21963
+ const raw = rawConfigRef.current;
21964
+ if (!raw || !runtime7) return;
21965
+ let tiles = raw.tiles || [];
21966
+ tiles = await runtime7.filterTiles(tiles);
21967
+ if (experiments) {
21968
+ tiles = tiles.filter((tile) => experiments.shouldRenderRectangle(tile));
21969
+ }
21970
+ setState((prev) => ({ ...prev, tiles: sortTiles(tiles) }));
21971
+ }, [runtime7, experiments]);
21972
+ const load = (0, import_react15.useCallback)(async () => {
21492
21973
  try {
21493
21974
  setState((prev) => ({ ...prev, isLoading: true, error: void 0 }));
21494
21975
  const response = await fetcher();
21495
21976
  debug("SmartCanvas Config", "Raw config response", response);
21977
+ rawConfigRef.current = response;
21496
21978
  let tiles = response.tiles || [];
21497
21979
  if (runtime7) {
21498
21980
  tiles = await runtime7.filterTiles(tiles);
@@ -21529,24 +22011,36 @@ ${cssRules}
21529
22011
  }));
21530
22012
  }
21531
22013
  }, [experiments, fetcher, runtime7]);
21532
- (0, import_react13.useEffect)(() => {
22014
+ (0, import_react15.useEffect)(() => {
21533
22015
  load();
21534
22016
  if (experiments?.onFeaturesChanged) {
21535
22017
  return experiments.onFeaturesChanged(() => load());
21536
22018
  }
21537
22019
  }, [load, experiments, pageUrl]);
21538
- (0, import_react13.useEffect)(() => {
22020
+ (0, import_react15.useEffect)(() => {
22021
+ if (!runtime7?.accumulator) return;
22022
+ return runtime7.accumulator.subscribe(() => {
22023
+ refilter();
22024
+ });
22025
+ }, [runtime7, refilter]);
22026
+ (0, import_react15.useEffect)(() => {
22027
+ if (!runtime7?.context) return;
22028
+ return runtime7.context.subscribe(() => {
22029
+ refilter();
22030
+ });
22031
+ }, [runtime7, refilter]);
22032
+ (0, import_react15.useEffect)(() => {
21539
22033
  if (!pollIntervalMs) return;
21540
22034
  const id = setInterval(() => {
21541
22035
  load();
21542
22036
  }, pollIntervalMs);
21543
22037
  return () => clearInterval(id);
21544
22038
  }, [load, pollIntervalMs]);
21545
- return (0, import_react13.useMemo)(() => state, [state]);
22039
+ return (0, import_react15.useMemo)(() => state, [state]);
21546
22040
  }
21547
22041
 
21548
22042
  // src/SmartCanvasApp.tsx
21549
- var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
22043
+ var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
21550
22044
  function SmartCanvasApp({
21551
22045
  controller,
21552
22046
  fetcher,
@@ -21569,7 +22063,7 @@ ${cssRules}
21569
22063
  workspaceTheme
21570
22064
  }) {
21571
22065
  if (runtime7) {
21572
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RuntimeProvider, { runtime: runtime7, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
22066
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RuntimeProvider, { runtime: runtime7, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
21573
22067
  SmartCanvasAppInner,
21574
22068
  {
21575
22069
  controller,
@@ -21594,7 +22088,7 @@ ${cssRules}
21594
22088
  }
21595
22089
  ) });
21596
22090
  }
21597
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
22091
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
21598
22092
  SmartCanvasAppInner,
21599
22093
  {
21600
22094
  controller,
@@ -21639,13 +22133,13 @@ ${cssRules}
21639
22133
  initialBatchHandle,
21640
22134
  workspaceTheme
21641
22135
  }) {
21642
- const [open, setOpen] = (0, import_react14.useState)(controller.getState().open);
22136
+ const [open, setOpen] = (0, import_react16.useState)(controller.getState().open);
21643
22137
  const pageContext = usePageContext();
21644
- const [localUrl, setLocalUrl] = (0, import_react14.useState)(
22138
+ const [localUrl, setLocalUrl] = (0, import_react16.useState)(
21645
22139
  () => typeof window !== "undefined" ? window.location.href : "/"
21646
22140
  );
21647
22141
  const pageUrl = pageContext?.url ?? localUrl;
21648
- (0, import_react14.useEffect)(() => {
22142
+ (0, import_react16.useEffect)(() => {
21649
22143
  if (runtime7) return;
21650
22144
  if (typeof window === "undefined") return;
21651
22145
  const updateUrl = () => setLocalUrl(window.location.href);
@@ -21668,7 +22162,7 @@ ${cssRules}
21668
22162
  history.replaceState = originalReplaceState;
21669
22163
  };
21670
22164
  }, [runtime7]);
21671
- const derivedFetcher = (0, import_react14.useMemo)(() => {
22165
+ const derivedFetcher = (0, import_react16.useMemo)(() => {
21672
22166
  if (fetcher) return fetcher;
21673
22167
  return createCanvasConfigFetcher({
21674
22168
  configUri,
@@ -21685,15 +22179,15 @@ ${cssRules}
21685
22179
  pageUrl
21686
22180
  });
21687
22181
  const hasContent = configState.tiles.length > 0 && !configState.error;
21688
- (0, import_react14.useEffect)(() => controller.subscribe((state) => setOpen(state.open)), [controller]);
21689
- (0, import_react14.useEffect)(() => {
22182
+ (0, import_react16.useEffect)(() => controller.subscribe((state) => setOpen(state.open)), [controller]);
22183
+ (0, import_react16.useEffect)(() => {
21690
22184
  if (!configState.isLoading && !hasContent && controller.getState().open) {
21691
22185
  controller.setOpen(false);
21692
22186
  }
21693
22187
  }, [controller, hasContent, configState.isLoading]);
21694
- const batchHandleRef = (0, import_react14.useRef)(initialBatchHandle ?? null);
21695
- const adoptedInitialRef = (0, import_react14.useRef)(!!initialBatchHandle);
21696
- (0, import_react14.useEffect)(() => {
22188
+ const batchHandleRef = (0, import_react16.useRef)(initialBatchHandle ?? null);
22189
+ const adoptedInitialRef = (0, import_react16.useRef)(!!initialBatchHandle);
22190
+ (0, import_react16.useEffect)(() => {
21697
22191
  if (!runtime7?.actions) return;
21698
22192
  if (adoptedInitialRef.current) {
21699
22193
  if (configState.actions.length > 0) {
@@ -21738,7 +22232,7 @@ ${cssRules}
21738
22232
  }
21739
22233
  };
21740
22234
  }, [runtime7, configState.actions, pageUrl]);
21741
- (0, import_react14.useEffect)(() => {
22235
+ (0, import_react16.useEffect)(() => {
21742
22236
  if (!runtime7) return;
21743
22237
  return runtime7.events.subscribe(
21744
22238
  { names: ["canvas.requestOpen"] },
@@ -21750,13 +22244,13 @@ ${cssRules}
21750
22244
  if (!configState.isLoading && !hasContent) {
21751
22245
  return null;
21752
22246
  }
21753
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
22247
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
21754
22248
  ThemeProvider,
21755
22249
  {
21756
22250
  themeConfig,
21757
22251
  workspaceTheme,
21758
22252
  shadowRoot,
21759
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
22253
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
21760
22254
  ShadowCanvasOverlay,
21761
22255
  {
21762
22256
  tiles: configState.tiles,
@@ -21765,6 +22259,7 @@ ${cssRules}
21765
22259
  canvasTitle: configState.canvasTitle,
21766
22260
  telemetry,
21767
22261
  launcherLabel: launcherLabel ?? configState.launcher?.label,
22262
+ launcherIcon: configState.launcher?.icon,
21768
22263
  launcherAnimate: configState.launcher?.animate,
21769
22264
  launcherAnimationStyle: configState.launcher?.animationStyle,
21770
22265
  notificationCount: configState.launcher?.notificationCount ?? configState.tiles.length,
@@ -21779,7 +22274,7 @@ ${cssRules}
21779
22274
  }
21780
22275
 
21781
22276
  // src/SmartCanvasElement.tsx
21782
- var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
22277
+ var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
21783
22278
  var TAG_NAME = "smart-canvas";
21784
22279
  var BASE_CSS = `
21785
22280
  :host {
@@ -21879,13 +22374,13 @@ ${cssRules}
21879
22374
  __privateSet(this, _root, (0, import_client5.createRoot)(__privateGet(this, _mount)));
21880
22375
  }
21881
22376
  __privateGet(this, _root).render(
21882
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
22377
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
21883
22378
  ShadowRootProvider,
21884
22379
  {
21885
22380
  shadowRoot: __privateGet(this, _shadow),
21886
22381
  portalRoot: __privateGet(this, _portalRoot),
21887
22382
  overlayContainer: __privateGet(this, _overlayContainer),
21888
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SmartCanvasApp, { ...__privateGet(this, _lastAppProps), controller: __privateGet(this, _controller), canvasHost: this })
22383
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SmartCanvasApp, { ...__privateGet(this, _lastAppProps), controller: __privateGet(this, _controller), canvasHost: this })
21889
22384
  }
21890
22385
  )
21891
22386
  );
@@ -22111,32 +22606,32 @@ ${cssRules}
22111
22606
  }
22112
22607
 
22113
22608
  // src/components/TileWheel.tsx
22114
- var import_react15 = __toESM(require_react(), 1);
22115
- var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
22609
+ var import_react17 = __toESM(require_react(), 1);
22610
+ var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
22116
22611
  function TileWheel({ tiles, intervalMs = 7e3, telemetry }) {
22117
- const [index2, setIndex] = (0, import_react15.useState)(0);
22118
- const ordered = (0, import_react15.useMemo)(
22612
+ const [index2, setIndex] = (0, import_react17.useState)(0);
22613
+ const ordered = (0, import_react17.useMemo)(
22119
22614
  () => [...tiles].sort((a2, b2) => (a2.priority ?? 0) - (b2.priority ?? 0)),
22120
22615
  [tiles]
22121
22616
  );
22122
- (0, import_react15.useEffect)(() => {
22617
+ (0, import_react17.useEffect)(() => {
22123
22618
  telemetry?.trackCanvasOpened("wheel");
22124
22619
  }, [telemetry]);
22125
- (0, import_react15.useEffect)(() => {
22620
+ (0, import_react17.useEffect)(() => {
22126
22621
  if (ordered.length <= 1) return;
22127
22622
  const id = setInterval(() => {
22128
22623
  setIndex((prev) => (prev + 1) % ordered.length);
22129
22624
  }, intervalMs);
22130
22625
  return () => clearInterval(id);
22131
22626
  }, [ordered, intervalMs]);
22132
- (0, import_react15.useEffect)(() => {
22627
+ (0, import_react17.useEffect)(() => {
22133
22628
  const current = ordered[index2];
22134
22629
  if (current) {
22135
22630
  telemetry?.trackRectangleViewed(current.id, "wheel");
22136
22631
  }
22137
22632
  }, [index2, ordered, telemetry]);
22138
22633
  if (!ordered.length) return null;
22139
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
22634
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
22140
22635
  "div",
22141
22636
  {
22142
22637
  style: {
@@ -22150,7 +22645,7 @@ ${cssRules}
22150
22645
  },
22151
22646
  "data-shadow-canvas-id": "wheel",
22152
22647
  children: [
22153
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
22648
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
22154
22649
  "div",
22155
22650
  {
22156
22651
  style: {
@@ -22159,10 +22654,10 @@ ${cssRules}
22159
22654
  transform: `translateX(-${index2 * 100}%)`,
22160
22655
  width: `${ordered.length * 100}%`
22161
22656
  },
22162
- children: ordered.map((tile) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { width: "100%", flexShrink: 0, padding: "0 1rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(TileCard, { config: tile, surface: "wheel", telemetry }) }, tile.id))
22657
+ children: ordered.map((tile) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { width: "100%", flexShrink: 0, padding: "0 1rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TileCard, { config: tile, surface: "wheel", telemetry }) }, tile.id))
22163
22658
  }
22164
22659
  ),
22165
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { marginTop: "1rem", display: "flex", justifyContent: "center", gap: "0.5rem" }, children: ordered.map((tile, idx) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
22660
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { marginTop: "1rem", display: "flex", justifyContent: "center", gap: "0.5rem" }, children: ordered.map((tile, idx) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
22166
22661
  "button",
22167
22662
  {
22168
22663
  type: "button",
@@ -22259,18 +22754,7 @@ ${cssRules}
22259
22754
  if (config.tiles && Array.isArray(config.tiles)) {
22260
22755
  migrated.tiles = config.tiles.map((tile) => {
22261
22756
  const migratedTile = { ...tile };
22262
- if (tile.experiment && !tile.activation) {
22263
- const exp = tile.experiment;
22264
- if (exp.featureKey) {
22265
- migratedTile.activation = {
22266
- strategy: {
22267
- type: "external",
22268
- provider: "growthbook",
22269
- featureKey: exp.featureKey,
22270
- fallback: false
22271
- }
22272
- };
22273
- }
22757
+ if (tile.experiment) {
22274
22758
  delete migratedTile.experiment;
22275
22759
  }
22276
22760
  return migratedTile;
@@ -29366,11 +29850,11 @@ ${cssRules}
29366
29850
  };
29367
29851
 
29368
29852
  // src/SmartCanvasPortal.tsx
29369
- var import_react16 = __toESM(require_react(), 1);
29853
+ var import_react18 = __toESM(require_react(), 1);
29370
29854
  var import_react_dom2 = __toESM(require_react_dom(), 1);
29371
29855
  function SmartCanvasPortal({ element, children }) {
29372
- const [mountNode, setMountNode] = (0, import_react16.useState)(null);
29373
- (0, import_react16.useLayoutEffect)(() => {
29856
+ const [mountNode, setMountNode] = (0, import_react18.useState)(null);
29857
+ (0, import_react18.useLayoutEffect)(() => {
29374
29858
  if (!element) {
29375
29859
  setMountNode(null);
29376
29860
  return;
@@ -29555,7 +30039,7 @@ ${cssRules}
29555
30039
  }
29556
30040
  var W = [true, "true", 1, "1", "yes"];
29557
30041
  var G = (t2) => w(W, t2);
29558
- var V = [false, "false", 0, "0", "no"];
30042
+ var V2 = [false, "false", 0, "0", "no"];
29559
30043
  function J(t2, i2, e2, r2, s2) {
29560
30044
  return i2 > e2 && (r2.warn("min cannot be greater than max."), i2 = e2), L(t2) ? t2 > e2 ? (r2.warn(" cannot be greater than max: " + e2 + ". Using max value instead."), e2) : t2 < i2 ? (r2.warn(" cannot be less than min: " + i2 + ". Using min value instead."), i2) : t2 : (r2.warn(" must be a number. using max or fallback. max: " + e2 + ", fallback: " + s2), J(s2 || e2, i2, e2, r2));
29561
30045
  }
@@ -30781,7 +31265,7 @@ ${cssRules}
30781
31265
  }
30782
31266
  get K() {
30783
31267
  var t2 = this.Y.q(this.X);
30784
- return G(t2) ? Ne.GRANTED : w(V, t2) ? Ne.DENIED : Ne.PENDING;
31268
+ return G(t2) ? Ne.GRANTED : w(V2, t2) ? Ne.DENIED : Ne.PENDING;
30785
31269
  }
30786
31270
  get Y() {
30787
31271
  if (!this.Z) {
@@ -31623,8 +32107,8 @@ ${cssRules}
31623
32107
  }
31624
32108
  if (D2) {
31625
32109
  w2[P2++] = 268435456 | Os[A2] << 18 | As[D2];
31626
- var V2 = 31 & Os[A2], J2 = 31 & As[D2];
31627
- k2 += Ts[V2] + Rs[J2], ++x2[257 + V2], ++S2[J2], T2 = h2 + A2, ++E2;
32110
+ var V3 = 31 & Os[A2], J2 = 31 & As[D2];
32111
+ k2 += Ts[V3] + Rs[J2], ++x2[257 + V3], ++S2[J2], T2 = h2 + A2, ++E2;
31628
32112
  } else w2[P2++] = t3[h2], ++x2[t3[h2]];
31629
32113
  }
31630
32114
  }
@@ -35501,12 +35985,16 @@ ${cssRules}
35501
35985
 
35502
35986
  // src/decisions/schema.ts
35503
35987
  var RouteFilterZ = external_exports.object({
35504
- include: external_exports.array(external_exports.string()).optional(),
35505
- exclude: external_exports.array(external_exports.string()).optional()
35988
+ include: external_exports.array(external_exports.string()).optional().describe(
35989
+ "URL patterns where this tile appears. Supports *, **, :param wildcards. Use sparingly \u2014 mostly to isolate to specific webapp functionality. Omit to appear on all routes."
35990
+ ),
35991
+ exclude: external_exports.array(external_exports.string()).optional().describe("URL patterns where this tile should NOT appear. Evaluated before include.")
35506
35992
  });
35507
35993
  var ActivationConfigZ = external_exports.object({
35508
35994
  routes: RouteFilterZ,
35509
- strategy: DecisionStrategyZ.optional()
35995
+ onlyIfPopulated: external_exports.boolean().optional().describe(
35996
+ "When true, tile is hidden if none of its props.actions[] have an active triggerWhen. Useful for tiles with all-deferred FAQ questions or nav tips. Default: false."
35997
+ )
35510
35998
  });
35511
35999
  function validateCondition(data) {
35512
36000
  return ConditionZ.safeParse(data);
@@ -35547,6 +36035,8 @@ ${cssRules}
35547
36035
  var TileZ = external_exports.object({
35548
36036
  id: external_exports.string(),
35549
36037
  title: external_exports.string().optional(),
36038
+ subtitle: external_exports.string().optional(),
36039
+ icon: external_exports.string().optional(),
35550
36040
  priority: external_exports.number().optional(),
35551
36041
  widget: external_exports.string(),
35552
36042
  props: external_exports.record(external_exports.unknown()).optional(),
@@ -35555,6 +36045,7 @@ ${cssRules}
35555
36045
  }).strict();
35556
36046
  var CanvasElementConfigZ = external_exports.object({
35557
36047
  position: external_exports.enum(["left", "right"]).optional(),
36048
+ layout: external_exports.enum(["overlay", "push"]).optional(),
35558
36049
  background: external_exports.string().optional(),
35559
36050
  blur: external_exports.string().optional(),
35560
36051
  border: external_exports.string().optional(),
@@ -35565,7 +36056,8 @@ ${cssRules}
35565
36056
  backgroundHover: external_exports.string().optional(),
35566
36057
  color: external_exports.string().optional(),
35567
36058
  size: external_exports.string().optional(),
35568
- shadow: external_exports.string().optional()
36059
+ shadow: external_exports.string().optional(),
36060
+ borderRadius: external_exports.string().optional()
35569
36061
  });
35570
36062
  var TileElementConfigZ = external_exports.object({
35571
36063
  background: external_exports.string().optional(),
@@ -35576,11 +36068,17 @@ ${cssRules}
35576
36068
  titleColor: external_exports.string().optional(),
35577
36069
  textColor: external_exports.string().optional(),
35578
36070
  iconBackground: external_exports.string().optional(),
35579
- iconShadow: external_exports.string().optional()
36071
+ iconShadow: external_exports.string().optional(),
36072
+ headerPadding: external_exports.string().optional(),
36073
+ bodyPadding: external_exports.string().optional(),
36074
+ gap: external_exports.string().optional()
35580
36075
  });
35581
36076
  var OverlayElementConfigZ = external_exports.object({
35582
36077
  background: external_exports.string().optional(),
35583
36078
  textColor: external_exports.string().optional(),
36079
+ titleColor: external_exports.string().optional(),
36080
+ arrowColor: external_exports.string().optional(),
36081
+ arrowSize: external_exports.string().optional(),
35584
36082
  border: external_exports.string().optional(),
35585
36083
  borderRadius: external_exports.string().optional(),
35586
36084
  scrimOpacity: external_exports.string().optional(),
@@ -35598,6 +36096,31 @@ ${cssRules}
35598
36096
  iconBackground: external_exports.string().optional(),
35599
36097
  progressGradient: external_exports.string().optional()
35600
36098
  });
36099
+ var ContentElementConfigZ = external_exports.object({
36100
+ background: external_exports.string().optional(),
36101
+ backgroundHover: external_exports.string().optional(),
36102
+ border: external_exports.string().optional(),
36103
+ borderRadius: external_exports.string().optional(),
36104
+ textColor: external_exports.string().optional(),
36105
+ textSecondaryColor: external_exports.string().optional(),
36106
+ // Accordion layout
36107
+ itemDivider: external_exports.string().optional(),
36108
+ itemGap: external_exports.string().optional(),
36109
+ itemPadding: external_exports.string().optional(),
36110
+ itemFontSize: external_exports.string().optional(),
36111
+ // Expanded content
36112
+ bodyPadding: external_exports.string().optional(),
36113
+ bodyFontSize: external_exports.string().optional(),
36114
+ // Category headers
36115
+ categoryPadding: external_exports.string().optional(),
36116
+ categoryGap: external_exports.string().optional(),
36117
+ categoryFontSize: external_exports.string().optional(),
36118
+ // Search
36119
+ searchBackground: external_exports.string().optional(),
36120
+ searchColor: external_exports.string().optional(),
36121
+ // Chevron
36122
+ chevronColor: external_exports.string().optional()
36123
+ });
35601
36124
  var CanvasThemeConfigZ = external_exports.object({
35602
36125
  mode: external_exports.enum(["dark", "light"]).optional(),
35603
36126
  fontFamily: external_exports.string().optional(),
@@ -35608,11 +36131,13 @@ ${cssRules}
35608
36131
  launcher: LauncherElementConfigZ.optional(),
35609
36132
  tile: TileElementConfigZ.optional(),
35610
36133
  overlay: OverlayElementConfigZ.optional(),
35611
- notification: NotificationElementConfigZ.optional()
36134
+ notification: NotificationElementConfigZ.optional(),
36135
+ content: ContentElementConfigZ.optional()
35612
36136
  }).strict();
35613
36137
  var LauncherConfigZ = external_exports.object({
35614
36138
  enabled: external_exports.boolean().optional(),
35615
36139
  label: external_exports.string().optional(),
36140
+ icon: external_exports.string().optional(),
35616
36141
  position: external_exports.string().optional(),
35617
36142
  animate: external_exports.boolean().optional(),
35618
36143
  animationStyle: external_exports.enum(["pulse", "bounce", "glow"]).optional(),
@@ -35631,9 +36156,8 @@ ${cssRules}
35631
36156
  }).strict();
35632
36157
 
35633
36158
  // src/actions/schema.ts
35634
- var ActionActivationZ = {
35635
- activation: ActivationConfigZ.optional(),
35636
- triggerWhen: DecisionStrategyZ.nullable().optional()
36159
+ var ActionTriggerZ = {
36160
+ triggerWhen: TriggerWhenZ
35637
36161
  };
35638
36162
  var AnchorIdZ2 = external_exports.object({
35639
36163
  selector: external_exports.string(),
@@ -35694,32 +36218,32 @@ ${cssRules}
35694
36218
  anchorId: AnchorIdZ2,
35695
36219
  text: external_exports.string(),
35696
36220
  label: external_exports.string().optional()
35697
- }).extend(ActionActivationZ).strict();
36221
+ }).extend(ActionTriggerZ).strict();
35698
36222
  var SetAttrZ = external_exports.object({
35699
36223
  kind: external_exports.literal("content:setAttr"),
35700
36224
  anchorId: AnchorIdZ2,
35701
36225
  attr: external_exports.string(),
35702
36226
  value: external_exports.string(),
35703
36227
  label: external_exports.string().optional()
35704
- }).extend(ActionActivationZ).strict();
36228
+ }).extend(ActionTriggerZ).strict();
35705
36229
  var AddClassZ = external_exports.object({
35706
36230
  kind: external_exports.literal("content:addClass"),
35707
36231
  anchorId: AnchorIdZ2,
35708
36232
  className: external_exports.string(),
35709
36233
  label: external_exports.string().optional()
35710
- }).extend(ActionActivationZ).strict();
36234
+ }).extend(ActionTriggerZ).strict();
35711
36235
  var RemoveClassZ = external_exports.object({
35712
36236
  kind: external_exports.literal("content:removeClass"),
35713
36237
  anchorId: AnchorIdZ2,
35714
36238
  className: external_exports.string(),
35715
36239
  label: external_exports.string().optional()
35716
- }).extend(ActionActivationZ).strict();
36240
+ }).extend(ActionTriggerZ).strict();
35717
36241
  var SetStyleZ = external_exports.object({
35718
36242
  kind: external_exports.literal("content:setStyle"),
35719
36243
  anchorId: AnchorIdZ2,
35720
36244
  styles: external_exports.record(external_exports.string()),
35721
36245
  label: external_exports.string().optional()
35722
- }).extend(ActionActivationZ).strict();
36246
+ }).extend(ActionTriggerZ).strict();
35723
36247
  var InsertHtmlZ = external_exports.object({
35724
36248
  kind: external_exports.literal("content:insertHtml"),
35725
36249
  anchorId: AnchorIdZ2,
@@ -35727,27 +36251,27 @@ ${cssRules}
35727
36251
  position: InsertPositionZ,
35728
36252
  deepLink: NotificationDeepLinkZ.optional(),
35729
36253
  label: external_exports.string().optional()
35730
- }).extend(ActionActivationZ).strict();
36254
+ }).extend(ActionTriggerZ).strict();
35731
36255
  var HighlightZ = external_exports.object({
35732
36256
  kind: external_exports.literal("overlays:highlight"),
35733
36257
  anchorId: AnchorIdZ2,
35734
36258
  style: HighlightStyleZ.optional(),
35735
36259
  duration: external_exports.number().optional(),
35736
36260
  label: external_exports.string().optional()
35737
- }).extend(ActionActivationZ).strict();
36261
+ }).extend(ActionTriggerZ).strict();
35738
36262
  var PulseZ = external_exports.object({
35739
36263
  kind: external_exports.literal("overlays:pulse"),
35740
36264
  anchorId: AnchorIdZ2,
35741
36265
  duration: external_exports.number().optional(),
35742
36266
  label: external_exports.string().optional()
35743
- }).extend(ActionActivationZ).strict();
36267
+ }).extend(ActionTriggerZ).strict();
35744
36268
  var BadgeZ = external_exports.object({
35745
36269
  kind: external_exports.literal("overlays:badge"),
35746
36270
  anchorId: AnchorIdZ2,
35747
36271
  content: external_exports.string(),
35748
36272
  position: BadgePositionZ.optional(),
35749
36273
  label: external_exports.string().optional()
35750
- }).extend(ActionActivationZ).strict();
36274
+ }).extend(ActionTriggerZ).strict();
35751
36275
  var TooltipZ = external_exports.object({
35752
36276
  kind: external_exports.literal("overlays:tooltip"),
35753
36277
  anchorId: AnchorIdZ2,
@@ -35756,7 +36280,7 @@ ${cssRules}
35756
36280
  placement: PlacementZ.optional(),
35757
36281
  waitFor: external_exports.string().optional(),
35758
36282
  label: external_exports.string().optional()
35759
- }).extend(ActionActivationZ).strict();
36283
+ }).extend(ActionTriggerZ).strict();
35760
36284
  var ModalZ = external_exports.object({
35761
36285
  kind: external_exports.literal("overlays:modal"),
35762
36286
  content: ModalContentZ,
@@ -35773,7 +36297,7 @@ ${cssRules}
35773
36297
  ctaButtons: external_exports.array(CtaButtonZ).optional(),
35774
36298
  waitFor: external_exports.string().optional(),
35775
36299
  label: external_exports.string().optional()
35776
- }).extend(ActionActivationZ).strict();
36300
+ }).extend(ActionTriggerZ).strict();
35777
36301
  var ScrollToZ = external_exports.object({
35778
36302
  kind: external_exports.literal("navigation:scrollTo"),
35779
36303
  anchorId: AnchorIdZ2,
@@ -35781,36 +36305,36 @@ ${cssRules}
35781
36305
  block: ScrollLogicalPositionZ.optional(),
35782
36306
  inline: ScrollLogicalPositionZ.optional(),
35783
36307
  label: external_exports.string().optional()
35784
- }).extend(ActionActivationZ).strict();
36308
+ }).extend(ActionTriggerZ).strict();
35785
36309
  var NavigateZ = external_exports.object({
35786
36310
  kind: external_exports.literal("navigation:navigate"),
35787
36311
  url: external_exports.string(),
35788
36312
  target: external_exports.enum(["_self", "_blank"]).optional(),
35789
36313
  label: external_exports.string().optional()
35790
- }).extend(ActionActivationZ).strict();
36314
+ }).extend(ActionTriggerZ).strict();
35791
36315
  var MountWidgetZ = external_exports.object({
35792
36316
  kind: external_exports.literal("core:mountWidget"),
35793
36317
  slot: external_exports.string(),
35794
36318
  widget: WidgetConfigZ,
35795
36319
  label: external_exports.string().optional()
35796
- }).extend(ActionActivationZ).strict();
36320
+ }).extend(ActionTriggerZ).strict();
35797
36321
  var WaitZ = external_exports.object({
35798
36322
  kind: external_exports.literal("core:wait"),
35799
36323
  durationMs: external_exports.number().min(0).optional(),
35800
36324
  event: external_exports.string().optional(),
35801
36325
  label: external_exports.string().optional()
35802
- }).extend(ActionActivationZ).strict();
36326
+ }).extend(ActionTriggerZ).strict();
35803
36327
  var SequenceZ = external_exports.object({
35804
36328
  kind: external_exports.literal("core:sequence"),
35805
36329
  actions: external_exports.array(external_exports.any()),
35806
36330
  label: external_exports.string().optional()
35807
- }).extend(ActionActivationZ).strict();
36331
+ }).extend(ActionTriggerZ).strict();
35808
36332
  var ParallelZ = external_exports.object({
35809
36333
  kind: external_exports.literal("core:parallel"),
35810
36334
  actions: external_exports.array(external_exports.any()),
35811
36335
  waitFor: external_exports.enum(["all", "any"]).optional(),
35812
36336
  label: external_exports.string().optional()
35813
- }).extend(ActionActivationZ).strict();
36337
+ }).extend(ActionTriggerZ).strict();
35814
36338
  var TourZ = external_exports.object({
35815
36339
  kind: external_exports.literal("core:tour"),
35816
36340
  tourId: external_exports.string(),
@@ -35818,7 +36342,7 @@ ${cssRules}
35818
36342
  startStep: external_exports.string().optional(),
35819
36343
  autoStart: external_exports.boolean().optional(),
35820
36344
  label: external_exports.string().optional()
35821
- }).extend(ActionActivationZ).passthrough();
36345
+ }).extend(ActionTriggerZ).passthrough();
35822
36346
  var coreActionStepSchemas = [
35823
36347
  { defName: "setText", schema: SetTextZ },
35824
36348
  { defName: "setAttr", schema: SetAttrZ },
@@ -36269,7 +36793,7 @@ ${cssRules}
36269
36793
  case "page_url": {
36270
36794
  const { url } = condition;
36271
36795
  const currentUrl = context.page.url;
36272
- const pattern = url.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*");
36796
+ const pattern = url.replace(/\*\*/g, "\0GLOBSTAR\0").replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\0GLOBSTAR\0/g, ".*");
36273
36797
  const regex = new RegExp(`^${pattern}$`);
36274
36798
  return regex.test(currentUrl);
36275
36799
  }
@@ -38048,14 +38572,20 @@ ${cssRules}
38048
38572
  if (!matchesRouteFilter(currentUrl, activation.routes)) {
38049
38573
  continue;
38050
38574
  }
38051
- if (!activation.strategy) {
38052
- results.push(tile);
38053
- continue;
38054
- }
38055
- const result = await this.evaluate(activation.strategy);
38056
- if (result.value) {
38057
- results.push(tile);
38575
+ if (activation.onlyIfPopulated) {
38576
+ const actions2 = tile.props?.actions ?? [];
38577
+ if (actions2.length > 0) {
38578
+ const hasVisible = actions2.some((a2) => {
38579
+ if (!a2.triggerWhen) return true;
38580
+ return decisionEngine.evaluateSync(
38581
+ a2.triggerWhen,
38582
+ context.get()
38583
+ ).value;
38584
+ });
38585
+ if (!hasVisible) continue;
38586
+ }
38058
38587
  }
38588
+ results.push(tile);
38059
38589
  }
38060
38590
  return results;
38061
38591
  },
@@ -38732,7 +39262,7 @@ ${cssRules}
38732
39262
  }
38733
39263
 
38734
39264
  // src/index.ts
38735
- var RUNTIME_SDK_BUILD = true ? `${"2026-03-03T18:45:20.063Z"} (${"2f42a46615"})` : "dev";
39265
+ var RUNTIME_SDK_BUILD = true ? `${"2026-03-04T00:05:33.583Z"} (${"00e3189890"})` : "dev";
38736
39266
  if (typeof window !== "undefined") {
38737
39267
  console.log(`[Syntro Runtime] Build: ${RUNTIME_SDK_BUILD}`);
38738
39268
  const existing = window.SynOS;
@@ -38741,7 +39271,7 @@ ${cssRules}
38741
39271
  ...existing,
38742
39272
  appRegistry: registry,
38743
39273
  _runtimeBuild: RUNTIME_SDK_BUILD,
38744
- React: import_react17.default,
39274
+ React: import_react19.default,
38745
39275
  ReactDOM: { ...ReactDOMClient, createPortal: import_react_dom3.createPortal, flushSync: import_react_dom3.flushSync }
38746
39276
  };
38747
39277
  registerBuiltinRuntimeModules(registry);
@@ -38804,6 +39334,30 @@ react/cjs/react-jsx-runtime.production.js:
38804
39334
  * This source code is licensed under the MIT license found in the
38805
39335
  * LICENSE file in the root directory of this source tree.
38806
39336
  *)
39337
+
39338
+ lucide-react/dist/esm/shared/src/utils/mergeClasses.js:
39339
+ lucide-react/dist/esm/shared/src/utils/toKebabCase.js:
39340
+ lucide-react/dist/esm/shared/src/utils/toCamelCase.js:
39341
+ lucide-react/dist/esm/shared/src/utils/toPascalCase.js:
39342
+ lucide-react/dist/esm/defaultAttributes.js:
39343
+ lucide-react/dist/esm/shared/src/utils/hasA11yProp.js:
39344
+ lucide-react/dist/esm/Icon.js:
39345
+ lucide-react/dist/esm/createLucideIcon.js:
39346
+ lucide-react/dist/esm/icons/circle-question-mark.js:
39347
+ lucide-react/dist/esm/icons/compass.js:
39348
+ lucide-react/dist/esm/icons/file-text.js:
39349
+ lucide-react/dist/esm/icons/gamepad-2.js:
39350
+ lucide-react/dist/esm/icons/layers.js:
39351
+ lucide-react/dist/esm/icons/message-circle.js:
39352
+ lucide-react/dist/esm/icons/sparkles.js:
39353
+ lucide-react/dist/esm/icons/trophy.js:
39354
+ lucide-react/dist/esm/lucide-react.js:
39355
+ (**
39356
+ * @license lucide-react v0.576.0 - ISC
39357
+ *
39358
+ * This source code is licensed under the ISC license.
39359
+ * See the LICENSE file in the root directory of this source tree.
39360
+ *)
38807
39361
  */
38808
39362
  window.Syntro=SyntrologieSDK.Syntro;
38809
39363
  //# sourceMappingURL=smart-canvas.js.map