@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
@@ -3,7 +3,7 @@ import {
3
3
  __privateGet,
4
4
  __privateSet,
5
5
  __publicField
6
- } from "./chunk-P5G4KT2U.js";
6
+ } from "./chunk-BU4Z6PD7.js";
7
7
 
8
8
  // ../adaptives/adaptive-content/dist/reconciliation-guard.js
9
9
  function guardAgainstReconciliation(container, anchor, reinsertFn, opts) {
@@ -784,7 +784,7 @@ var CelebrationEngine = class {
784
784
  };
785
785
 
786
786
  // ../adaptives/adaptive-overlays/dist/celebrations/index.js
787
- var DEFAULT_COLORS2 = [
787
+ var FALLBACK_COLORS = [
788
788
  "#ff0000",
789
789
  "#00ff00",
790
790
  "#0000ff",
@@ -794,6 +794,22 @@ var DEFAULT_COLORS2 = [
794
794
  "#ff8800",
795
795
  "#8800ff"
796
796
  ];
797
+ function buildThemePalette(primary, hover) {
798
+ return [primary, hover, `${primary}cc`, `${hover}cc`, "#ffffff", `${primary}80`];
799
+ }
800
+ function readThemeColors(overlayRoot) {
801
+ var _a2, _b;
802
+ try {
803
+ const styles = getComputedStyle(overlayRoot);
804
+ const primary = (_a2 = styles.getPropertyValue("--sc-color-primary")) == null ? void 0 : _a2.trim();
805
+ const hover = (_b = styles.getPropertyValue("--sc-color-primary-hover")) == null ? void 0 : _b.trim();
806
+ if ((primary == null ? void 0 : primary.startsWith("#")) && primary.length >= 7) {
807
+ return buildThemePalette(primary, hover || primary);
808
+ }
809
+ } catch {
810
+ }
811
+ return null;
812
+ }
797
813
  var effectRegistry = /* @__PURE__ */ new Map([
798
814
  ["confetti", confettiEffect],
799
815
  ["fireworks", fireworksEffect],
@@ -801,17 +817,18 @@ var effectRegistry = /* @__PURE__ */ new Map([
801
817
  ["emoji-rain", emojiRainEffect]
802
818
  ]);
803
819
  var executeCelebrate = async (action, context) => {
804
- var _a2, _b, _c;
820
+ var _a2, _b, _c, _d;
805
821
  const effect = effectRegistry.get(action.effect);
806
822
  if (!effect) {
807
823
  console.warn(`[adaptive-overlays] Unknown celebration effect: "${action.effect}". Available: ${[...effectRegistry.keys()].join(", ")}`);
808
824
  return { cleanup: () => {
809
825
  } };
810
826
  }
827
+ const colors = (_b = (_a2 = action.colors) != null ? _a2 : readThemeColors(context.overlayRoot)) != null ? _b : FALLBACK_COLORS;
811
828
  const config = {
812
- duration: (_a2 = action.duration) != null ? _a2 : 3e3,
813
- intensity: (_b = action.intensity) != null ? _b : "medium",
814
- colors: (_c = action.colors) != null ? _c : DEFAULT_COLORS2,
829
+ duration: (_c = action.duration) != null ? _c : 3e3,
830
+ intensity: (_d = action.intensity) != null ? _d : "medium",
831
+ colors,
815
832
  props: action.props
816
833
  };
817
834
  const engine = new CelebrationEngine();
@@ -1684,6 +1701,13 @@ function sanitizeHtml2(html) {
1684
1701
  }
1685
1702
 
1686
1703
  // ../adaptives/adaptive-overlays/dist/modal.js
1704
+ var V = {
1705
+ bg: "var(--sc-overlay-background, #ffffff)",
1706
+ title: "var(--sc-overlay-title-color, var(--sc-overlay-text-color, #111827))",
1707
+ text: "var(--sc-overlay-text-color, #4b5563)",
1708
+ accent: "var(--sc-color-primary, #4f46e5)",
1709
+ radius: "var(--sc-border-radius, 12px)"
1710
+ };
1687
1711
  var executeModal = async (action, context) => {
1688
1712
  var _a2, _b;
1689
1713
  const { content, size = "md", blocking = false, scrim, dismiss, ctaButtons } = action;
@@ -1710,8 +1734,8 @@ var executeModal = async (action, context) => {
1710
1734
  transform: translate(-50%, -50%) scale(0.95);
1711
1735
  max-width: ${sizeMap[size]};
1712
1736
  width: 90%;
1713
- background: ${base.white};
1714
- border-radius: 12px;
1737
+ background: ${V.bg};
1738
+ border-radius: ${V.radius};
1715
1739
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
1716
1740
  z-index: 2147483646;
1717
1741
  opacity: 0;
@@ -1720,9 +1744,9 @@ var executeModal = async (action, context) => {
1720
1744
  `;
1721
1745
  let html = "";
1722
1746
  if (content.title) {
1723
- html += `<h2 class="syntro-modal-title" style="margin: 0 0 12px 0; font-size: 18px; font-weight: 600; color: #111827;">${sanitizeHtml2(content.title)}</h2>`;
1747
+ html += `<h2 class="syntro-modal-title" style="margin: 0 0 12px 0; font-size: 18px; font-weight: 600; color: ${V.title};">${sanitizeHtml2(content.title)}</h2>`;
1724
1748
  }
1725
- html += `<div class="syntro-modal-body" style="color: #4b5563; line-height: 1.5;">${sanitizeHtml2(content.body)}</div>`;
1749
+ html += `<div class="syntro-modal-body" style="color: ${V.text}; line-height: 1.5;">${sanitizeHtml2(content.body)}</div>`;
1726
1750
  if ((dismiss == null ? void 0 : dismiss.closeButton) !== false) {
1727
1751
  html += `
1728
1752
  <button class="syntro-modal-close" data-syntro-action="dismiss" style="
@@ -1733,7 +1757,8 @@ var executeModal = async (action, context) => {
1733
1757
  border: none;
1734
1758
  cursor: pointer;
1735
1759
  padding: 4px;
1736
- color: #6b7280;
1760
+ color: ${V.text};
1761
+ opacity: 0.6;
1737
1762
  " aria-label="Close">
1738
1763
  <svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor">
1739
1764
  <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"/>
@@ -1756,7 +1781,7 @@ var executeModal = async (action, context) => {
1756
1781
  font-weight: 500;
1757
1782
  cursor: pointer;
1758
1783
  transition: background 150ms ease;
1759
- ${isPrimary ? "background: #4f46e5; color: white; border: none;" : "background: white; color: #374151; border: 1px solid #d1d5db;"}
1784
+ ${isPrimary ? `background: ${V.accent}; color: white; border: none;` : `background: transparent; color: ${V.accent}; border: 1px solid currentColor; opacity: 0.7;`}
1760
1785
  "
1761
1786
  >
1762
1787
  ${sanitizeHtml2(btn.label)}
@@ -2413,7 +2438,7 @@ var executeHighlight = async (action, context) => {
2413
2438
  };
2414
2439
  };
2415
2440
  var executePulse = async (action, context) => {
2416
- var _a2;
2441
+ var _a2, _b, _c;
2417
2442
  let anchorEl = context.resolveAnchor(action.anchorId);
2418
2443
  if (!anchorEl && context.waitForAnchor) {
2419
2444
  anchorEl = await context.waitForAnchor(action.anchorId, 3e3);
@@ -2423,24 +2448,67 @@ var executePulse = async (action, context) => {
2423
2448
  return { cleanup: () => {
2424
2449
  } };
2425
2450
  }
2426
- const duration = (_a2 = action.duration) != null ? _a2 : 2e3;
2427
- if (!document.querySelector("[data-syntro-pulse-styles]")) {
2428
- const style = document.createElement("style");
2429
- style.setAttribute("data-syntro-pulse-styles", "");
2451
+ const duration = (_a2 = action.duration) != null ? _a2 : 4e3;
2452
+ await new Promise((resolve) => requestAnimationFrame(resolve));
2453
+ const parseHex = (hex) => ({
2454
+ r: parseInt(hex.slice(1, 3), 16),
2455
+ g: parseInt(hex.slice(3, 5), 16),
2456
+ b: parseInt(hex.slice(5, 7), 16)
2457
+ });
2458
+ const fallback = { r: 79, g: 70, b: 229 };
2459
+ let primary = fallback;
2460
+ let secondary = null;
2461
+ try {
2462
+ const styles = getComputedStyle(context.overlayRoot);
2463
+ const pHex = (_b = styles.getPropertyValue("--sc-color-primary")) == null ? void 0 : _b.trim();
2464
+ const sHex = (_c = styles.getPropertyValue("--sc-color-primary-hover")) == null ? void 0 : _c.trim();
2465
+ if ((pHex == null ? void 0 : pHex.startsWith("#")) && pHex.length >= 7) {
2466
+ primary = parseHex(pHex);
2467
+ }
2468
+ if ((sHex == null ? void 0 : sHex.startsWith("#")) && sHex.length >= 7) {
2469
+ secondary = parseHex(sHex);
2470
+ }
2471
+ } catch {
2472
+ }
2473
+ const existing = document.querySelector("[data-syntro-pulse-styles]");
2474
+ if (existing)
2475
+ existing.remove();
2476
+ const style = document.createElement("style");
2477
+ style.setAttribute("data-syntro-pulse-styles", "");
2478
+ const { r: pr, g: pg, b: pb } = primary;
2479
+ if (secondary) {
2480
+ const { r: sr, g: sg, b: sb } = secondary;
2481
+ style.textContent = `
2482
+ @keyframes syntro-pulse-anim {
2483
+ 0%, 100% {
2484
+ box-shadow: 0 0 0 0 rgba(${pr}, ${pg}, ${pb}, 0.35);
2485
+ }
2486
+ 25% {
2487
+ box-shadow: 0 0 0 12px rgba(${pr}, ${pg}, ${pb}, 0);
2488
+ }
2489
+ 50% {
2490
+ box-shadow: 0 0 0 0 rgba(${sr}, ${sg}, ${sb}, 0.35);
2491
+ }
2492
+ 75% {
2493
+ box-shadow: 0 0 0 12px rgba(${sr}, ${sg}, ${sb}, 0);
2494
+ }
2495
+ }
2496
+ `;
2497
+ } else {
2430
2498
  style.textContent = `
2431
2499
  @keyframes syntro-pulse-anim {
2432
2500
  0%, 100% {
2433
- box-shadow: 0 0 0 0 rgba(79, 70, 229, 0.4);
2501
+ box-shadow: 0 0 0 0 rgba(${pr}, ${pg}, ${pb}, 0.35);
2434
2502
  }
2435
2503
  50% {
2436
- box-shadow: 0 0 0 8px rgba(79, 70, 229, 0);
2504
+ box-shadow: 0 0 0 12px rgba(${pr}, ${pg}, ${pb}, 0);
2437
2505
  }
2438
2506
  }
2439
2507
  `;
2440
- document.head.appendChild(style);
2441
2508
  }
2509
+ document.head.appendChild(style);
2442
2510
  const originalAnimation = anchorEl.style.animation;
2443
- anchorEl.style.animation = "syntro-pulse-anim 1s cubic-bezier(0.4, 0, 0.6, 1) infinite";
2511
+ anchorEl.style.animation = "syntro-pulse-anim 2.5s cubic-bezier(0.4, 0, 0.6, 1) infinite";
2444
2512
  anchorEl.setAttribute("data-syntro-pulse", "true");
2445
2513
  const timeoutId = setTimeout(() => {
2446
2514
  anchorEl.style.animation = originalAnimation;
@@ -2461,7 +2529,7 @@ var executePulse = async (action, context) => {
2461
2529
  };
2462
2530
  };
2463
2531
  var executeBadge = async (action, context) => {
2464
- var _a2;
2532
+ var _a2, _b;
2465
2533
  let anchorEl = context.resolveAnchor(action.anchorId);
2466
2534
  if (!anchorEl && context.waitForAnchor) {
2467
2535
  anchorEl = await context.waitForAnchor(action.anchorId, 3e3);
@@ -2471,6 +2539,14 @@ var executeBadge = async (action, context) => {
2471
2539
  return { cleanup: () => {
2472
2540
  } };
2473
2541
  }
2542
+ let badgeColor = "#4f46e5";
2543
+ try {
2544
+ const primary = (_a2 = getComputedStyle(context.overlayRoot).getPropertyValue("--sc-color-primary")) == null ? void 0 : _a2.trim();
2545
+ if ((primary == null ? void 0 : primary.startsWith("#")) && primary.length >= 7) {
2546
+ badgeColor = primary;
2547
+ }
2548
+ } catch {
2549
+ }
2474
2550
  const badge2 = document.createElement("div");
2475
2551
  badge2.textContent = action.content;
2476
2552
  badge2.setAttribute("data-syntro-badge", action.anchorId.selector);
@@ -2481,13 +2557,13 @@ var executeBadge = async (action, context) => {
2481
2557
  fontWeight: "600",
2482
2558
  lineHeight: "1",
2483
2559
  color: "white",
2484
- background: "var(--syntro-accent, #4f46e5)",
2560
+ background: badgeColor,
2485
2561
  borderRadius: "9999px",
2486
2562
  pointerEvents: "none",
2487
2563
  zIndex: "2147483646",
2488
2564
  whiteSpace: "nowrap"
2489
2565
  });
2490
- const position = (_a2 = action.position) != null ? _a2 : "top-right";
2566
+ const position = (_b = action.position) != null ? _b : "top-right";
2491
2567
  const originalPosition = anchorEl.style.position;
2492
2568
  if (getComputedStyle(anchorEl).position === "static") {
2493
2569
  anchorEl.style.position = "relative";
@@ -2622,7 +2698,7 @@ var runtime2 = {
2622
2698
  executors: executors2,
2623
2699
  widgets: [
2624
2700
  {
2625
- id: "workflow:tracker",
2701
+ id: "adaptive-overlays:workflow-tracker",
2626
2702
  component: WorkflowMountableWidget,
2627
2703
  metadata: {
2628
2704
  name: "Workflow Tracker",
@@ -3240,7 +3316,7 @@ function getAntiFlickerSnippet(config = {}) {
3240
3316
  }
3241
3317
 
3242
3318
  // src/version.ts
3243
- var SDK_VERSION = "2.4.0-canary.22";
3319
+ var SDK_VERSION = "2.4.0-canary.24";
3244
3320
 
3245
3321
  // src/types.ts
3246
3322
  var SDK_SCHEMA_VERSION = "2.0";
@@ -3899,7 +3975,7 @@ function NotificationToastStack({
3899
3975
  ]
3900
3976
  }
3901
3977
  ),
3902
- /* @__PURE__ */ jsx2("div", { style: { height: "2px", background: "rgba(255, 255, 255, 0.06)" }, children: /* @__PURE__ */ jsx2(
3978
+ /* @__PURE__ */ jsx2("div", { style: { height: "2px", background: "rgba(0, 0, 0, 0.08)" }, children: /* @__PURE__ */ jsx2(
3903
3979
  "div",
3904
3980
  {
3905
3981
  className: "syntro-toast-progress",
@@ -4195,8 +4271,51 @@ function useDecision(strategy, defaultValue) {
4195
4271
  }
4196
4272
 
4197
4273
  // src/components/TileCard.tsx
4198
- import { useCallback as useCallback3, useEffect as useEffect5, useReducer, useRef as useRef4, useState as useState4 } from "react";
4199
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
4274
+ import {
4275
+ useCallback as useCallback3,
4276
+ useEffect as useEffect5,
4277
+ useMemo as useMemo3,
4278
+ useReducer,
4279
+ useRef as useRef4,
4280
+ useState as useState4
4281
+ } from "react";
4282
+
4283
+ // src/components/TileIcon.tsx
4284
+ import {
4285
+ Compass,
4286
+ FileText,
4287
+ Gamepad2,
4288
+ HelpCircle,
4289
+ Layers,
4290
+ MessageCircle,
4291
+ Sparkles,
4292
+ Trophy
4293
+ } from "lucide-react";
4294
+ import { jsx as jsx4 } from "react/jsx-runtime";
4295
+ var ICON_MAP = {
4296
+ "\u2753": HelpCircle,
4297
+ "\u{1F9ED}": Compass,
4298
+ "\u{1F4DD}": FileText,
4299
+ "\u{1F3AF}": Layers,
4300
+ "\u{1F3C6}": Trophy,
4301
+ "\u2728": Sparkles,
4302
+ "\u{1F4AC}": MessageCircle,
4303
+ "\u{1F3AE}": Gamepad2
4304
+ };
4305
+ function TileIcon({
4306
+ emoji,
4307
+ size = 18,
4308
+ color = "currentColor"
4309
+ }) {
4310
+ const Icon = ICON_MAP[emoji];
4311
+ if (!Icon) {
4312
+ return /* @__PURE__ */ jsx4("span", { children: emoji });
4313
+ }
4314
+ return /* @__PURE__ */ jsx4(Icon, { size, color });
4315
+ }
4316
+
4317
+ // src/components/TileCard.tsx
4318
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
4200
4319
  function WidgetMount({ widgetId, props }) {
4201
4320
  var _a2;
4202
4321
  const runtime3 = useRuntime();
@@ -4239,7 +4358,7 @@ function WidgetMount({ widgetId, props }) {
4239
4358
  }
4240
4359
  );
4241
4360
  }
4242
- return /* @__PURE__ */ jsx4("div", { ref: containerRef, style: { width: "100%", minHeight: "40px" } });
4361
+ return /* @__PURE__ */ jsx5("div", { ref: containerRef, style: { width: "100%", minHeight: "40px" } });
4243
4362
  }
4244
4363
  function TileCard({
4245
4364
  config,
@@ -4247,12 +4366,29 @@ function TileCard({
4247
4366
  telemetry: _telemetry,
4248
4367
  style
4249
4368
  }) {
4250
- const { title, widget, props } = config;
4369
+ const { title, subtitle, widget, props, icon } = config;
4251
4370
  const [, setTick] = useState4(0);
4252
4371
  const runtime3 = useRuntime();
4253
4372
  useEffect5(() => {
4254
4373
  if (runtime3) setTick((t) => t + 1);
4255
4374
  }, [runtime3]);
4375
+ const registration = useMemo3(
4376
+ () => {
4377
+ var _a2, _b;
4378
+ return (_b = (_a2 = runtime3 == null ? void 0 : runtime3.widgets) == null ? void 0 : _a2.getRegistration) == null ? void 0 : _b.call(_a2, widget);
4379
+ },
4380
+ [runtime3 == null ? void 0 : runtime3.widgets, widget]
4381
+ );
4382
+ const resolvedIcon = useMemo3(() => {
4383
+ var _a2, _b;
4384
+ if (icon) return icon;
4385
+ return (_b = (_a2 = registration == null ? void 0 : registration.metadata) == null ? void 0 : _a2.icon) != null ? _b : "+";
4386
+ }, [icon, registration]);
4387
+ const resolvedSubtitle = useMemo3(() => {
4388
+ var _a2;
4389
+ if (subtitle) return subtitle;
4390
+ return (_a2 = registration == null ? void 0 : registration.metadata) == null ? void 0 : _a2.subtitle;
4391
+ }, [subtitle, registration]);
4256
4392
  const [hovered, setHovered] = useState4(false);
4257
4393
  const onMouseEnter = useCallback3(() => setHovered(true), []);
4258
4394
  const onMouseLeave = useCallback3(() => setHovered(false), []);
@@ -4276,21 +4412,15 @@ function TileCard({
4276
4412
  const headerStyle = {
4277
4413
  display: "flex",
4278
4414
  alignItems: "center",
4279
- gap: "0.75rem",
4280
- padding: "0.875rem 1rem",
4281
- minHeight: "72px"
4415
+ gap: "var(--sc-tile-gap, 0.25rem)",
4416
+ padding: "var(--sc-tile-header-padding, 0.375rem 0.75rem)",
4417
+ minHeight: "44px"
4282
4418
  };
4283
4419
  const iconStyle = {
4284
- width: "40px",
4285
- height: "40px",
4286
- borderRadius: "10px",
4287
- background: "var(--sc-tile-icon-background)",
4288
4420
  display: "flex",
4289
4421
  alignItems: "center",
4290
4422
  justifyContent: "center",
4291
- fontSize: "1.25rem",
4292
- flexShrink: 0,
4293
- boxShadow: "var(--sc-tile-icon-shadow)"
4423
+ flexShrink: 0
4294
4424
  };
4295
4425
  return /* @__PURE__ */ jsxs2(
4296
4426
  "article",
@@ -4301,31 +4431,48 @@ function TileCard({
4301
4431
  onMouseLeave,
4302
4432
  children: [
4303
4433
  /* @__PURE__ */ jsxs2("div", { style: headerStyle, children: [
4304
- /* @__PURE__ */ jsx4("div", { style: iconStyle, children: "+" }),
4305
- /* @__PURE__ */ jsx4("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx4(
4306
- "h3",
4307
- {
4308
- style: {
4309
- fontSize: "0.95rem",
4310
- fontWeight: 600,
4311
- color: "var(--sc-tile-title-color)",
4312
- margin: "0.125rem 0 0",
4313
- whiteSpace: "nowrap",
4314
- overflow: "hidden",
4315
- textOverflow: "ellipsis"
4316
- },
4317
- children: title != null ? title : widget
4318
- }
4319
- ) })
4434
+ /* @__PURE__ */ jsx5("div", { style: iconStyle, children: /* @__PURE__ */ jsx5(TileIcon, { emoji: resolvedIcon, size: resolvedSubtitle ? 36 : 24 }) }),
4435
+ /* @__PURE__ */ jsxs2("div", { style: { flex: 1, minWidth: 0 }, children: [
4436
+ /* @__PURE__ */ jsx5(
4437
+ "h3",
4438
+ {
4439
+ style: {
4440
+ fontSize: "1.14rem",
4441
+ fontWeight: 600,
4442
+ color: "var(--sc-tile-title-color)",
4443
+ margin: "0.125rem 0 0",
4444
+ whiteSpace: "nowrap",
4445
+ overflow: "hidden",
4446
+ textOverflow: "ellipsis"
4447
+ },
4448
+ children: title != null ? title : widget
4449
+ }
4450
+ ),
4451
+ resolvedSubtitle && /* @__PURE__ */ jsx5(
4452
+ "p",
4453
+ {
4454
+ style: {
4455
+ fontSize: "0.8rem",
4456
+ fontWeight: 400,
4457
+ color: "var(--sc-tile-text-color)",
4458
+ margin: "0.125rem 0 0",
4459
+ whiteSpace: "nowrap",
4460
+ overflow: "hidden",
4461
+ textOverflow: "ellipsis"
4462
+ },
4463
+ children: resolvedSubtitle
4464
+ }
4465
+ )
4466
+ ] })
4320
4467
  ] }),
4321
- /* @__PURE__ */ jsx4(
4468
+ /* @__PURE__ */ jsx5(
4322
4469
  "div",
4323
4470
  {
4324
4471
  style: {
4325
- padding: "0 1rem 1rem",
4472
+ padding: "var(--sc-tile-body-padding, 0 0.75rem 0.5rem)",
4326
4473
  borderTop: "1px solid rgba(255, 255, 255, 0.06)"
4327
4474
  },
4328
- children: /* @__PURE__ */ jsx4("div", { style: { paddingTop: "0.875rem" }, children: /* @__PURE__ */ jsx4(WidgetMount, { widgetId: widget, props: { ...props, instanceId: config.id } }) })
4475
+ children: /* @__PURE__ */ jsx5("div", { style: { paddingTop: "var(--sc-tile-gap, 0.25rem)" }, children: /* @__PURE__ */ jsx5(WidgetMount, { widgetId: widget, props: { ...props, instanceId: config.id } }) })
4329
4476
  }
4330
4477
  )
4331
4478
  ]
@@ -4334,7 +4481,7 @@ function TileCard({
4334
4481
  }
4335
4482
 
4336
4483
  // src/components/ShadowCanvasOverlay.tsx
4337
- import { useCallback as useCallback4, useEffect as useEffect7, useMemo as useMemo4, useRef as useRef5, useState as useState5 } from "react";
4484
+ import { useCallback as useCallback4, useEffect as useEffect7, useMemo as useMemo5, useRef as useRef5, useState as useState5 } from "react";
4338
4485
  import { createPortal } from "react-dom";
4339
4486
 
4340
4487
  // src/theme/defaultTheme.ts
@@ -4508,17 +4655,19 @@ var darkDefaults = {
4508
4655
  borderRadius: "12px",
4509
4656
  canvas: {
4510
4657
  position: "right",
4658
+ layout: "overlay",
4511
4659
  background: withAlpha(slateGrey[1], 0.6),
4512
4660
  blur: "blur(24px)",
4513
4661
  border: "none",
4514
- width: "clamp(320px, 16.666vw, 420px)"
4662
+ width: "clamp(380px, 25vw, 520px)"
4515
4663
  },
4516
4664
  launcher: {
4517
4665
  background: button.primary.backgroundDefault,
4518
4666
  backgroundHover: button.primary.backgroundHover,
4519
4667
  color: button.primary.icon,
4520
4668
  size: "56px",
4521
- shadow: `0 8px 32px ${withAlpha(slateGrey[0], 0.6)}`
4669
+ shadow: `0 8px 32px ${withAlpha(slateGrey[0], 0.6)}`,
4670
+ borderRadius: "9999px"
4522
4671
  },
4523
4672
  tile: {
4524
4673
  background: withAlpha(slateGrey[1], 0.6),
@@ -4529,11 +4678,17 @@ var darkDefaults = {
4529
4678
  titleColor: text.primary,
4530
4679
  textColor: text.secondary,
4531
4680
  iconBackground: `linear-gradient(135deg, ${brand[3]} 0%, ${brand[3]}cc 100%)`,
4532
- iconShadow: `0 2px 8px ${brand[3]}40`
4681
+ iconShadow: `0 2px 8px ${brand[3]}40`,
4682
+ headerPadding: "0.375rem 0.75rem",
4683
+ bodyPadding: "0 0.75rem 0.5rem",
4684
+ gap: "0.25rem"
4533
4685
  },
4534
4686
  overlay: {
4535
4687
  background: withAlpha(slateGrey[1], 0.6),
4536
4688
  textColor: text.primary,
4689
+ titleColor: text.primary,
4690
+ arrowColor: withAlpha(slateGrey[1], 0.6),
4691
+ arrowSize: "8px",
4537
4692
  border: "none",
4538
4693
  borderRadius: "0",
4539
4694
  scrimOpacity: "0",
@@ -4550,6 +4705,26 @@ var darkDefaults = {
4550
4705
  errorColor: red[4],
4551
4706
  iconBackground: withAlpha(brand[3], 0.15),
4552
4707
  progressGradient: `linear-gradient(90deg, ${brand[3]}, ${brand[4]})`
4708
+ },
4709
+ content: {
4710
+ background: withAlpha(slateGrey[3], 0.8),
4711
+ backgroundHover: withAlpha(slateGrey[5], 0.6),
4712
+ border: `1px solid ${withAlpha(slateGrey[5], 0.5)}`,
4713
+ borderRadius: "8px",
4714
+ textColor: text.primary,
4715
+ textSecondaryColor: text.secondary,
4716
+ itemDivider: "none",
4717
+ itemGap: "6px",
4718
+ itemPadding: "12px 16px",
4719
+ itemFontSize: "15px",
4720
+ bodyPadding: "0 16px 12px 16px",
4721
+ bodyFontSize: "14px",
4722
+ categoryPadding: "8px 4px 4px 4px",
4723
+ categoryGap: "4px",
4724
+ categoryFontSize: "12px",
4725
+ searchBackground: withAlpha(slateGrey[3], 0.8),
4726
+ searchColor: text.primary,
4727
+ chevronColor: "currentColor"
4553
4728
  }
4554
4729
  };
4555
4730
  var lightDefaults = {
@@ -4560,17 +4735,19 @@ var lightDefaults = {
4560
4735
  borderRadius: "12px",
4561
4736
  canvas: {
4562
4737
  position: "right",
4738
+ layout: "overlay",
4563
4739
  background: withAlpha(slateGrey[12], 0.7),
4564
4740
  blur: "blur(24px)",
4565
4741
  border: "none",
4566
- width: "clamp(320px, 16.666vw, 420px)"
4742
+ width: "clamp(380px, 25vw, 520px)"
4567
4743
  },
4568
4744
  launcher: {
4569
4745
  background: brand[3],
4570
4746
  backgroundHover: brand[2],
4571
4747
  color: "#ffffff",
4572
4748
  size: "56px",
4573
- shadow: "0 8px 32px rgba(0, 0, 0, 0.15)"
4749
+ shadow: "0 8px 32px rgba(0, 0, 0, 0.15)",
4750
+ borderRadius: "9999px"
4574
4751
  },
4575
4752
  tile: {
4576
4753
  background: withAlpha(slateGrey[12], 0.7),
@@ -4581,11 +4758,17 @@ var lightDefaults = {
4581
4758
  titleColor: slateGrey[1],
4582
4759
  textColor: slateGrey[6],
4583
4760
  iconBackground: `linear-gradient(135deg, ${brand[3]} 0%, ${brand[3]}cc 100%)`,
4584
- iconShadow: `0 2px 8px ${brand[3]}40`
4761
+ iconShadow: `0 2px 8px ${brand[3]}40`,
4762
+ headerPadding: "0.375rem 0.75rem",
4763
+ bodyPadding: "0 0.75rem 0.5rem",
4764
+ gap: "0.25rem"
4585
4765
  },
4586
4766
  overlay: {
4587
4767
  background: withAlpha(slateGrey[12], 0.7),
4588
4768
  textColor: slateGrey[1],
4769
+ titleColor: slateGrey[1],
4770
+ arrowColor: withAlpha(slateGrey[12], 0.7),
4771
+ arrowSize: "8px",
4589
4772
  border: "none",
4590
4773
  borderRadius: "0",
4591
4774
  scrimOpacity: "0",
@@ -4602,6 +4785,26 @@ var lightDefaults = {
4602
4785
  errorColor: red[4],
4603
4786
  iconBackground: withAlpha(brand[3], 0.1),
4604
4787
  progressGradient: `linear-gradient(90deg, ${brand[3]}, ${brand[2]})`
4788
+ },
4789
+ content: {
4790
+ background: withAlpha(slateGrey[12], 0.8),
4791
+ backgroundHover: withAlpha(slateGrey[11], 0.6),
4792
+ border: `1px solid ${slateGrey[11]}`,
4793
+ borderRadius: "8px",
4794
+ textColor: slateGrey[1],
4795
+ textSecondaryColor: slateGrey[6],
4796
+ itemDivider: "none",
4797
+ itemGap: "6px",
4798
+ itemPadding: "12px 16px",
4799
+ itemFontSize: "15px",
4800
+ bodyPadding: "0 16px 12px 16px",
4801
+ bodyFontSize: "14px",
4802
+ categoryPadding: "8px 4px 4px 4px",
4803
+ categoryGap: "4px",
4804
+ categoryFontSize: "12px",
4805
+ searchBackground: slateGrey[12],
4806
+ searchColor: slateGrey[1],
4807
+ chevronColor: "currentColor"
4605
4808
  }
4606
4809
  };
4607
4810
  function mergeThemeConfig(customer) {
@@ -4617,7 +4820,8 @@ function mergeThemeConfig(customer) {
4617
4820
  launcher: { ...base2.launcher, ...customer.launcher },
4618
4821
  tile: { ...base2.tile, ...customer.tile },
4619
4822
  overlay: { ...base2.overlay, ...customer.overlay },
4620
- notification: { ...base2.notification, ...customer.notification }
4823
+ notification: { ...base2.notification, ...customer.notification },
4824
+ content: { ...base2.content, ...customer.content }
4621
4825
  };
4622
4826
  }
4623
4827
  function mergeThemeWithWorkspace(workspaceTheme, configTheme) {
@@ -4638,10 +4842,18 @@ function mergeThemeWithWorkspace(workspaceTheme, configTheme) {
4638
4842
  ...base2.notification,
4639
4843
  ...workspaceTheme.notification,
4640
4844
  ...configTheme.notification
4641
- }
4845
+ },
4846
+ content: { ...base2.content, ...workspaceTheme.content, ...configTheme.content }
4642
4847
  };
4643
4848
  }
4644
- var ELEMENT_SECTIONS = ["canvas", "launcher", "tile", "overlay", "notification"];
4849
+ var ELEMENT_SECTIONS = [
4850
+ "canvas",
4851
+ "launcher",
4852
+ "tile",
4853
+ "overlay",
4854
+ "notification",
4855
+ "content"
4856
+ ];
4645
4857
  function flattenThemeConfig(config) {
4646
4858
  const vars = {};
4647
4859
  if (config.fontFamily) vars["--sc-font-family"] = config.fontFamily;
@@ -4661,8 +4873,8 @@ function flattenThemeConfig(config) {
4661
4873
  }
4662
4874
 
4663
4875
  // src/theme/ThemeProvider.tsx
4664
- import { createContext as createContext3, useContext as useContext3, useEffect as useEffect6, useMemo as useMemo3 } from "react";
4665
- import { jsx as jsx5 } from "react/jsx-runtime";
4876
+ import { createContext as createContext3, useContext as useContext3, useEffect as useEffect6, useMemo as useMemo4 } from "react";
4877
+ import { jsx as jsx6 } from "react/jsx-runtime";
4666
4878
  var ThemeContext = createContext3(null);
4667
4879
  function ThemeProvider({
4668
4880
  children,
@@ -4670,11 +4882,11 @@ function ThemeProvider({
4670
4882
  workspaceTheme,
4671
4883
  shadowRoot
4672
4884
  }) {
4673
- const merged = useMemo3(
4885
+ const merged = useMemo4(
4674
4886
  () => workspaceTheme ? mergeThemeWithWorkspace(workspaceTheme, themeConfig != null ? themeConfig : {}) : mergeThemeConfig(themeConfig != null ? themeConfig : {}),
4675
4887
  [themeConfig, workspaceTheme]
4676
4888
  );
4677
- const cssVariables = useMemo3(() => flattenThemeConfig(merged), [merged]);
4889
+ const cssVariables = useMemo4(() => flattenThemeConfig(merged), [merged]);
4678
4890
  useEffect6(() => {
4679
4891
  if (!shadowRoot) return;
4680
4892
  let styleEl = shadowRoot.querySelector("#sc-theme-vars");
@@ -4693,7 +4905,7 @@ ${cssRules}
4693
4905
  mode: merged.mode,
4694
4906
  cssVariables
4695
4907
  };
4696
- return /* @__PURE__ */ jsx5(ThemeContext.Provider, { value, children });
4908
+ return /* @__PURE__ */ jsx6(ThemeContext.Provider, { value, children });
4697
4909
  }
4698
4910
  function useTheme() {
4699
4911
  const context = useContext3(ThemeContext);
@@ -4704,7 +4916,7 @@ function useTheme() {
4704
4916
  }
4705
4917
 
4706
4918
  // src/components/ShadowCanvasOverlay.tsx
4707
- import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
4919
+ import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
4708
4920
  var LAUNCHER_STYLES_ID = "syntro-launcher-styles";
4709
4921
  function ensureLauncherStyles(target, css) {
4710
4922
  if (target.querySelector(`#${LAUNCHER_STYLES_ID}`)) return;
@@ -4718,6 +4930,7 @@ function ShadowCanvasOverlay({
4718
4930
  onToggle,
4719
4931
  telemetry,
4720
4932
  launcherLabel: _launcherLabel = "Adaptives",
4933
+ launcherIcon,
4721
4934
  launcherAnimate = false,
4722
4935
  launcherAnimationStyle: _launcherAnimationStyle = "pulse",
4723
4936
  notificationCount: _notificationCount,
@@ -4762,7 +4975,7 @@ function ShadowCanvasOverlay({
4762
4975
  },
4763
4976
  [runtime3, isOpen, onToggle, dismissNotification]
4764
4977
  );
4765
- const launcherCss = useMemo4(
4978
+ const launcherCss = useMemo5(
4766
4979
  () => `
4767
4980
  @keyframes syntro-launcher-pulse {
4768
4981
  0%, 100% {
@@ -4861,7 +5074,38 @@ function ShadowCanvasOverlay({
4861
5074
  );
4862
5075
  const isFocused = displayMode === "focused";
4863
5076
  const isRight = config.canvas.position === "right";
5077
+ const isPush = config.canvas.layout === "push";
5078
+ const containerRef = useRef5(null);
4864
5079
  const zIndex = 2147483600;
5080
+ useEffect7(() => {
5081
+ var _a3, _b2;
5082
+ if (!isPush) return;
5083
+ const root = document.documentElement;
5084
+ const prop = isRight ? "marginRight" : "marginLeft";
5085
+ const prevTransition = root.style.transition;
5086
+ root.style.transition = `${prop} 340ms cubic-bezier(0.16, 1, 0.3, 1)`;
5087
+ if (isOpen) {
5088
+ const width = (_b2 = (_a3 = containerRef.current) == null ? void 0 : _a3.offsetWidth) != null ? _b2 : 380;
5089
+ root.style[prop] = `${width}px`;
5090
+ } else {
5091
+ root.style[prop] = "0px";
5092
+ }
5093
+ return () => {
5094
+ root.style[prop] = "";
5095
+ root.style.transition = prevTransition;
5096
+ };
5097
+ }, [isPush, isOpen, isRight]);
5098
+ useEffect7(() => {
5099
+ if (!isPush || !isOpen) return;
5100
+ const container = containerRef.current;
5101
+ if (!container) return;
5102
+ const prop = isRight ? "marginRight" : "marginLeft";
5103
+ const observer = new ResizeObserver(([entry]) => {
5104
+ document.documentElement.style[prop] = `${entry.contentRect.width}px`;
5105
+ });
5106
+ observer.observe(container);
5107
+ return () => observer.disconnect();
5108
+ }, [isPush, isOpen, isRight]);
4865
5109
  const containerStyle = {
4866
5110
  display: "flex",
4867
5111
  flexDirection: "column",
@@ -4898,7 +5142,7 @@ function ShadowCanvasOverlay({
4898
5142
  pointerEvents: "none",
4899
5143
  padding: "0"
4900
5144
  };
4901
- const content = /* @__PURE__ */ jsx6(
5145
+ const content = /* @__PURE__ */ jsx7(
4902
5146
  "div",
4903
5147
  {
4904
5148
  "data-shadow-canvas-id": "overlay-root",
@@ -4909,8 +5153,8 @@ function ShadowCanvasOverlay({
4909
5153
  zIndex
4910
5154
  },
4911
5155
  children: /* @__PURE__ */ jsxs3("div", { style: wrapperStyle, children: [
4912
- /* @__PURE__ */ jsxs3("div", { "data-shadow-canvas-id": "overlay-container", style: containerStyle, children: [
4913
- isFocused && canvasTitle && /* @__PURE__ */ jsx6("header", { style: { color: "white", padding: "1.5rem 1.5rem 0" }, children: /* @__PURE__ */ jsx6(
5156
+ /* @__PURE__ */ jsxs3("div", { ref: containerRef, "data-shadow-canvas-id": "overlay-container", style: containerStyle, children: [
5157
+ isFocused && canvasTitle && /* @__PURE__ */ jsx7("header", { style: { color: "white", padding: "1.5rem 1.5rem 0" }, children: /* @__PURE__ */ jsx7(
4914
5158
  "p",
4915
5159
  {
4916
5160
  style: {
@@ -4923,7 +5167,7 @@ function ShadowCanvasOverlay({
4923
5167
  children: canvasTitle
4924
5168
  }
4925
5169
  ) }),
4926
- /* @__PURE__ */ jsx6("div", { style: { flex: 1, overflowY: "auto", padding: isFocused ? "0" : "1rem" }, children: isLoading ? /* @__PURE__ */ jsx6(
5170
+ /* @__PURE__ */ jsx7("div", { style: { flex: 1, overflowY: "auto", padding: isFocused ? "0" : "1rem" }, children: isLoading ? /* @__PURE__ */ jsx7(
4927
5171
  "div",
4928
5172
  {
4929
5173
  style: { color: "var(--sc-overlay-text-color)", padding: isFocused ? "1rem" : "0" },
@@ -4943,7 +5187,7 @@ function ShadowCanvasOverlay({
4943
5187
  }
4944
5188
  ) : isFocused ? (
4945
5189
  /* Focused Mode: Render first tile full size */
4946
- tiles.length > 0 ? /* @__PURE__ */ jsx6(
5190
+ tiles.length > 0 ? /* @__PURE__ */ jsx7(
4947
5191
  TileCard,
4948
5192
  {
4949
5193
  config: tiles[0],
@@ -4954,7 +5198,7 @@ function ShadowCanvasOverlay({
4954
5198
  ) : null
4955
5199
  ) : (
4956
5200
  /* Standard Mode: Stacked cards — widgets always visible */
4957
- /* @__PURE__ */ jsx6(
5201
+ /* @__PURE__ */ jsx7(
4958
5202
  "div",
4959
5203
  {
4960
5204
  style: {
@@ -4963,7 +5207,7 @@ function ShadowCanvasOverlay({
4963
5207
  gap: "0.75rem",
4964
5208
  width: "100%"
4965
5209
  },
4966
- children: tiles.map((tile) => /* @__PURE__ */ jsx6(
5210
+ children: tiles.map((tile) => /* @__PURE__ */ jsx7(
4967
5211
  TileCard,
4968
5212
  {
4969
5213
  config: tile,
@@ -4978,7 +5222,7 @@ function ShadowCanvasOverlay({
4978
5222
  ) }),
4979
5223
  footerSlot
4980
5224
  ] }),
4981
- /* @__PURE__ */ jsx6(
5225
+ /* @__PURE__ */ jsx7(
4982
5226
  "div",
4983
5227
  {
4984
5228
  onClick: toggle2,
@@ -5006,7 +5250,7 @@ function ShadowCanvasOverlay({
5006
5250
  zIndex: zIndex + 47
5007
5251
  },
5008
5252
  children: [
5009
- /* @__PURE__ */ jsx6(
5253
+ /* @__PURE__ */ jsx7(
5010
5254
  NotificationToastStack,
5011
5255
  {
5012
5256
  notifications,
@@ -5034,7 +5278,7 @@ function ShadowCanvasOverlay({
5034
5278
  justifyContent: "center",
5035
5279
  width: "var(--sc-launcher-size, 56px)",
5036
5280
  height: "var(--sc-launcher-size, 56px)",
5037
- borderRadius: "9999px",
5281
+ borderRadius: "var(--sc-launcher-border-radius, 9999px)",
5038
5282
  color: "var(--sc-launcher-color)",
5039
5283
  boxShadow: "var(--sc-launcher-shadow)",
5040
5284
  transition: dragRef.current ? "none" : "transform 0.2s ease, opacity 0.3s ease, background-color 0.2s ease",
@@ -5061,7 +5305,39 @@ function ShadowCanvasOverlay({
5061
5305
  }
5062
5306
  },
5063
5307
  children: [
5064
- /* @__PURE__ */ jsx6(
5308
+ isOpen ? /* @__PURE__ */ jsxs3(
5309
+ "svg",
5310
+ {
5311
+ width: "24",
5312
+ height: "24",
5313
+ viewBox: "0 0 24 24",
5314
+ fill: "none",
5315
+ stroke: "currentColor",
5316
+ strokeWidth: "2",
5317
+ strokeLinecap: "round",
5318
+ strokeLinejoin: "round",
5319
+ "aria-hidden": "true",
5320
+ focusable: "false",
5321
+ style: { transition: "transform 200ms ease" },
5322
+ children: [
5323
+ /* @__PURE__ */ jsx7("path", { d: "M18 6L6 18" }),
5324
+ /* @__PURE__ */ jsx7("path", { d: "M6 6l12 12" })
5325
+ ]
5326
+ }
5327
+ ) : launcherIcon ? /* @__PURE__ */ jsx7(
5328
+ "img",
5329
+ {
5330
+ src: launcherIcon,
5331
+ alt: "",
5332
+ "aria-hidden": "true",
5333
+ style: {
5334
+ width: "60%",
5335
+ height: "60%",
5336
+ objectFit: "contain",
5337
+ pointerEvents: "none"
5338
+ }
5339
+ }
5340
+ ) : /* @__PURE__ */ jsxs3(
5065
5341
  "svg",
5066
5342
  {
5067
5343
  width: "24",
@@ -5075,20 +5351,17 @@ function ShadowCanvasOverlay({
5075
5351
  "aria-hidden": "true",
5076
5352
  focusable: "false",
5077
5353
  style: { transition: "transform 200ms ease" },
5078
- children: isOpen ? /* @__PURE__ */ jsxs3(Fragment, { children: [
5079
- /* @__PURE__ */ jsx6("path", { d: "M18 6L6 18" }),
5080
- /* @__PURE__ */ jsx6("path", { d: "M6 6l12 12" })
5081
- ] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
5082
- /* @__PURE__ */ jsx6("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" }),
5083
- /* @__PURE__ */ jsx6("path", { d: "M5 3v4" }),
5084
- /* @__PURE__ */ jsx6("path", { d: "M3 5h4" }),
5085
- /* @__PURE__ */ jsx6("path", { d: "M19 17v4" }),
5086
- /* @__PURE__ */ jsx6("path", { d: "M17 19h4" })
5087
- ] })
5354
+ children: [
5355
+ /* @__PURE__ */ jsx7("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" }),
5356
+ /* @__PURE__ */ jsx7("path", { d: "M5 3v4" }),
5357
+ /* @__PURE__ */ jsx7("path", { d: "M3 5h4" }),
5358
+ /* @__PURE__ */ jsx7("path", { d: "M19 17v4" }),
5359
+ /* @__PURE__ */ jsx7("path", { d: "M17 19h4" })
5360
+ ]
5088
5361
  }
5089
5362
  ),
5090
5363
  !isOpen && notifications.length > 0 && /* @__PURE__ */ jsxs3("div", { style: { position: "absolute", top: -2, right: -2, pointerEvents: "none" }, children: [
5091
- /* @__PURE__ */ jsx6(
5364
+ /* @__PURE__ */ jsx7(
5092
5365
  "span",
5093
5366
  {
5094
5367
  className: "syntro-badge-ping",
@@ -5100,7 +5373,7 @@ function ShadowCanvasOverlay({
5100
5373
  }
5101
5374
  }
5102
5375
  ),
5103
- /* @__PURE__ */ jsx6(
5376
+ /* @__PURE__ */ jsx7(
5104
5377
  "span",
5105
5378
  {
5106
5379
  className: "syntro-badge-glow",
@@ -5111,7 +5384,7 @@ function ShadowCanvasOverlay({
5111
5384
  }
5112
5385
  }
5113
5386
  ),
5114
- /* @__PURE__ */ jsx6(
5387
+ /* @__PURE__ */ jsx7(
5115
5388
  "span",
5116
5389
  {
5117
5390
  className: "syntro-badge-bounce",
@@ -5145,7 +5418,7 @@ function ShadowCanvasOverlay({
5145
5418
  }
5146
5419
 
5147
5420
  // src/hooks/useShadowCanvasConfig.ts
5148
- import { useCallback as useCallback5, useEffect as useEffect8, useMemo as useMemo5, useRef as useRef6, useState as useState6 } from "react";
5421
+ import { useCallback as useCallback5, useEffect as useEffect8, useMemo as useMemo6, useRef as useRef6, useState as useState6 } from "react";
5149
5422
  var sortTiles = (tiles) => [...tiles].sort((a, b) => {
5150
5423
  var _a2, _b;
5151
5424
  return ((_a2 = b.priority) != null ? _a2 : 0) - ((_b = a.priority) != null ? _b : 0);
@@ -5163,11 +5436,23 @@ function useShadowCanvasConfig({
5163
5436
  isLoading: true
5164
5437
  });
5165
5438
  const prevActionsJsonRef = useRef6("[]");
5439
+ const rawConfigRef = useRef6(null);
5440
+ const refilter = useCallback5(async () => {
5441
+ const raw = rawConfigRef.current;
5442
+ if (!raw || !runtime3) return;
5443
+ let tiles = raw.tiles || [];
5444
+ tiles = await runtime3.filterTiles(tiles);
5445
+ if (experiments) {
5446
+ tiles = tiles.filter((tile) => experiments.shouldRenderRectangle(tile));
5447
+ }
5448
+ setState((prev) => ({ ...prev, tiles: sortTiles(tiles) }));
5449
+ }, [runtime3, experiments]);
5166
5450
  const load = useCallback5(async () => {
5167
5451
  try {
5168
5452
  setState((prev) => ({ ...prev, isLoading: true, error: void 0 }));
5169
5453
  const response = await fetcher();
5170
5454
  debug("SmartCanvas Config", "Raw config response", response);
5455
+ rawConfigRef.current = response;
5171
5456
  let tiles = response.tiles || [];
5172
5457
  if (runtime3) {
5173
5458
  tiles = await runtime3.filterTiles(tiles);
@@ -5210,6 +5495,18 @@ function useShadowCanvasConfig({
5210
5495
  return experiments.onFeaturesChanged(() => load());
5211
5496
  }
5212
5497
  }, [load, experiments, pageUrl]);
5498
+ useEffect8(() => {
5499
+ if (!(runtime3 == null ? void 0 : runtime3.accumulator)) return;
5500
+ return runtime3.accumulator.subscribe(() => {
5501
+ refilter();
5502
+ });
5503
+ }, [runtime3, refilter]);
5504
+ useEffect8(() => {
5505
+ if (!(runtime3 == null ? void 0 : runtime3.context)) return;
5506
+ return runtime3.context.subscribe(() => {
5507
+ refilter();
5508
+ });
5509
+ }, [runtime3, refilter]);
5213
5510
  useEffect8(() => {
5214
5511
  if (!pollIntervalMs) return;
5215
5512
  const id = setInterval(() => {
@@ -5217,12 +5514,12 @@ function useShadowCanvasConfig({
5217
5514
  }, pollIntervalMs);
5218
5515
  return () => clearInterval(id);
5219
5516
  }, [load, pollIntervalMs]);
5220
- return useMemo5(() => state, [state]);
5517
+ return useMemo6(() => state, [state]);
5221
5518
  }
5222
5519
 
5223
5520
  // src/SmartCanvasApp.tsx
5224
- import { useEffect as useEffect9, useMemo as useMemo6, useRef as useRef7, useState as useState7 } from "react";
5225
- import { jsx as jsx7 } from "react/jsx-runtime";
5521
+ import { useEffect as useEffect9, useMemo as useMemo7, useRef as useRef7, useState as useState7 } from "react";
5522
+ import { jsx as jsx8 } from "react/jsx-runtime";
5226
5523
  function SmartCanvasApp({
5227
5524
  controller,
5228
5525
  fetcher,
@@ -5245,7 +5542,7 @@ function SmartCanvasApp({
5245
5542
  workspaceTheme
5246
5543
  }) {
5247
5544
  if (runtime3) {
5248
- return /* @__PURE__ */ jsx7(RuntimeProvider, { runtime: runtime3, children: /* @__PURE__ */ jsx7(
5545
+ return /* @__PURE__ */ jsx8(RuntimeProvider, { runtime: runtime3, children: /* @__PURE__ */ jsx8(
5249
5546
  SmartCanvasAppInner,
5250
5547
  {
5251
5548
  controller,
@@ -5270,7 +5567,7 @@ function SmartCanvasApp({
5270
5567
  }
5271
5568
  ) });
5272
5569
  }
5273
- return /* @__PURE__ */ jsx7(
5570
+ return /* @__PURE__ */ jsx8(
5274
5571
  SmartCanvasAppInner,
5275
5572
  {
5276
5573
  controller,
@@ -5315,7 +5612,7 @@ function SmartCanvasAppInner({
5315
5612
  initialBatchHandle,
5316
5613
  workspaceTheme
5317
5614
  }) {
5318
- var _a2, _b, _c, _d, _e, _f;
5615
+ var _a2, _b, _c, _d, _e, _f, _g;
5319
5616
  const [open, setOpen] = useState7(controller.getState().open);
5320
5617
  const pageContext = usePageContext();
5321
5618
  const [localUrl, setLocalUrl] = useState7(
@@ -5345,7 +5642,7 @@ function SmartCanvasAppInner({
5345
5642
  history.replaceState = originalReplaceState;
5346
5643
  };
5347
5644
  }, [runtime3]);
5348
- const derivedFetcher = useMemo6(() => {
5645
+ const derivedFetcher = useMemo7(() => {
5349
5646
  if (fetcher) return fetcher;
5350
5647
  return createCanvasConfigFetcher({
5351
5648
  configUri,
@@ -5427,13 +5724,13 @@ function SmartCanvasAppInner({
5427
5724
  if (!configState.isLoading && !hasContent) {
5428
5725
  return null;
5429
5726
  }
5430
- return /* @__PURE__ */ jsx7(
5727
+ return /* @__PURE__ */ jsx8(
5431
5728
  ThemeProvider,
5432
5729
  {
5433
5730
  themeConfig,
5434
5731
  workspaceTheme,
5435
5732
  shadowRoot,
5436
- children: /* @__PURE__ */ jsx7(
5733
+ children: /* @__PURE__ */ jsx8(
5437
5734
  ShadowCanvasOverlay,
5438
5735
  {
5439
5736
  tiles: configState.tiles,
@@ -5442,9 +5739,10 @@ function SmartCanvasAppInner({
5442
5739
  canvasTitle: configState.canvasTitle,
5443
5740
  telemetry,
5444
5741
  launcherLabel: launcherLabel != null ? launcherLabel : (_b = configState.launcher) == null ? void 0 : _b.label,
5445
- launcherAnimate: (_c = configState.launcher) == null ? void 0 : _c.animate,
5446
- launcherAnimationStyle: (_d = configState.launcher) == null ? void 0 : _d.animationStyle,
5447
- notificationCount: (_f = (_e = configState.launcher) == null ? void 0 : _e.notificationCount) != null ? _f : configState.tiles.length,
5742
+ launcherIcon: (_c = configState.launcher) == null ? void 0 : _c.icon,
5743
+ launcherAnimate: (_d = configState.launcher) == null ? void 0 : _d.animate,
5744
+ launcherAnimationStyle: (_e = configState.launcher) == null ? void 0 : _e.animationStyle,
5745
+ notificationCount: (_g = (_f = configState.launcher) == null ? void 0 : _f.notificationCount) != null ? _g : configState.tiles.length,
5448
5746
  footerSlot,
5449
5747
  isOpen: open,
5450
5748
  onToggle: () => controller.toggle(),
@@ -5457,7 +5755,7 @@ function SmartCanvasAppInner({
5457
5755
 
5458
5756
  // src/SmartCanvasElement.tsx
5459
5757
  import { createRoot as createRoot2 } from "react-dom/client";
5460
- import { jsx as jsx8 } from "react/jsx-runtime";
5758
+ import { jsx as jsx9 } from "react/jsx-runtime";
5461
5759
  var TAG_NAME = "smart-canvas";
5462
5760
  var BASE_CSS = `
5463
5761
  :host {
@@ -5558,13 +5856,13 @@ var SmartCanvasElement = class extends HTMLElement {
5558
5856
  __privateSet(this, _root, createRoot2(__privateGet(this, _mount)));
5559
5857
  }
5560
5858
  __privateGet(this, _root).render(
5561
- /* @__PURE__ */ jsx8(
5859
+ /* @__PURE__ */ jsx9(
5562
5860
  ShadowRootProvider,
5563
5861
  {
5564
5862
  shadowRoot: __privateGet(this, _shadow),
5565
5863
  portalRoot: __privateGet(this, _portalRoot),
5566
5864
  overlayContainer: __privateGet(this, _overlayContainer),
5567
- children: /* @__PURE__ */ jsx8(SmartCanvasApp, { ...__privateGet(this, _lastAppProps), controller: __privateGet(this, _controller), canvasHost: this })
5865
+ children: /* @__PURE__ */ jsx9(SmartCanvasApp, { ...__privateGet(this, _lastAppProps), controller: __privateGet(this, _controller), canvasHost: this })
5568
5866
  }
5569
5867
  )
5570
5868
  );
@@ -5830,6 +6128,9 @@ function injectBaseStyles(target) {
5830
6128
  --syntro-border: var(--sc-overlay-border, #2b333f);
5831
6129
  --syntro-tooltip-bg: var(--syntro-surface);
5832
6130
  --syntro-tooltip-fg: var(--syntro-fg);
6131
+ --syntro-tooltip-title-color: var(--sc-overlay-title-color, var(--syntro-fg));
6132
+ --syntro-tooltip-arrow-bg: var(--sc-overlay-arrow-color, var(--syntro-tooltip-bg));
6133
+ --syntro-tooltip-arrow-size: var(--sc-overlay-arrow-size, 8px);
5833
6134
  --syntro-tooltip-radius: var(--syntro-radius);
5834
6135
  --syntro-tooltip-padding: 12px 16px;
5835
6136
  --syntro-tooltip-shadow: var(--syntro-shadow);
@@ -5856,14 +6157,13 @@ function injectBaseStyles(target) {
5856
6157
  transform 200ms cubic-bezier(0.16, 1, 0.3, 1);
5857
6158
  }
5858
6159
 
5859
- /* Tooltip arrow */
6160
+ /* Tooltip arrow \u2014 triangle via clip-path (square box so rotation is symmetric) */
5860
6161
  .syntro-tooltip-arrow {
5861
6162
  position: absolute;
5862
- width: 8px;
5863
- height: 8px;
5864
- background: inherit;
5865
- transform: rotate(45deg);
5866
- z-index: -1;
6163
+ width: var(--syntro-tooltip-arrow-size);
6164
+ height: var(--syntro-tooltip-arrow-size);
6165
+ background: var(--syntro-tooltip-arrow-bg);
6166
+ clip-path: polygon(0 0, 100% 0, 50% 100%);
5867
6167
  }
5868
6168
 
5869
6169
  /* Tooltip content */
@@ -5871,6 +6171,7 @@ function injectBaseStyles(target) {
5871
6171
  font-weight: 600;
5872
6172
  font-size: 15px;
5873
6173
  margin-bottom: 6px;
6174
+ color: var(--syntro-tooltip-title-color);
5874
6175
  }
5875
6176
 
5876
6177
  .syntro-tt-body {
@@ -8382,7 +8683,7 @@ function evaluateCondition(condition, evalContext) {
8382
8683
  case "page_url": {
8383
8684
  const { url } = condition;
8384
8685
  const currentUrl = context.page.url;
8385
- const pattern = url.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*");
8686
+ const pattern = url.replace(/\*\*/g, "\0GLOBSTAR\0").replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\0GLOBSTAR\0/g, ".*");
8386
8687
  const regex = new RegExp(`^${pattern}$`);
8387
8688
  return regex.test(currentUrl);
8388
8689
  }
@@ -10150,6 +10451,7 @@ function createSmartCanvasRuntime(options = {}) {
10150
10451
  return decisionEngine.evaluateSync(strategy, context.get());
10151
10452
  },
10152
10453
  async filterTiles(tiles) {
10454
+ var _a3, _b2;
10153
10455
  const currentUrl = context.get().page.url;
10154
10456
  const results = [];
10155
10457
  for (const tile of tiles) {
@@ -10161,14 +10463,20 @@ function createSmartCanvasRuntime(options = {}) {
10161
10463
  if (!matchesRouteFilter(currentUrl, activation.routes)) {
10162
10464
  continue;
10163
10465
  }
10164
- if (!activation.strategy) {
10165
- results.push(tile);
10166
- continue;
10167
- }
10168
- const result = await this.evaluate(activation.strategy);
10169
- if (result.value) {
10170
- results.push(tile);
10466
+ if (activation.onlyIfPopulated) {
10467
+ const actions2 = (_b2 = (_a3 = tile.props) == null ? void 0 : _a3.actions) != null ? _b2 : [];
10468
+ if (actions2.length > 0) {
10469
+ const hasVisible = actions2.some((a) => {
10470
+ if (!a.triggerWhen) return true;
10471
+ return decisionEngine.evaluateSync(
10472
+ a.triggerWhen,
10473
+ context.get()
10474
+ ).value;
10475
+ });
10476
+ if (!hasVisible) continue;
10477
+ }
10171
10478
  }
10479
+ results.push(tile);
10172
10480
  }
10173
10481
  return results;
10174
10482
  },
@@ -10941,4 +11249,4 @@ export {
10941
11249
  encodeToken,
10942
11250
  Syntro
10943
11251
  };
10944
- //# sourceMappingURL=chunk-WCQCVPJ7.js.map
11252
+ //# sourceMappingURL=chunk-LD22WJ44.js.map