@portel/photon 1.20.1 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +5 -5
  2. package/dist/ag-ui/adapter.d.ts.map +1 -1
  3. package/dist/ag-ui/adapter.js +25 -0
  4. package/dist/ag-ui/adapter.js.map +1 -1
  5. package/dist/auto-ui/beam/routes/api-browse.d.ts.map +1 -1
  6. package/dist/auto-ui/beam/routes/api-browse.js +8 -49
  7. package/dist/auto-ui/beam/routes/api-browse.js.map +1 -1
  8. package/dist/auto-ui/beam.d.ts.map +1 -1
  9. package/dist/auto-ui/beam.js +23 -31
  10. package/dist/auto-ui/beam.js.map +1 -1
  11. package/dist/auto-ui/bridge/index.d.ts.map +1 -1
  12. package/dist/auto-ui/bridge/index.js +107 -11
  13. package/dist/auto-ui/bridge/index.js.map +1 -1
  14. package/dist/auto-ui/bridge/renderers.d.ts +14 -0
  15. package/dist/auto-ui/bridge/renderers.d.ts.map +1 -1
  16. package/dist/auto-ui/bridge/renderers.js +680 -57
  17. package/dist/auto-ui/bridge/renderers.js.map +1 -1
  18. package/dist/auto-ui/frontend/index.html +3 -3
  19. package/dist/auto-ui/frontend/pure-view.html +19 -19
  20. package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
  21. package/dist/auto-ui/streamable-http-transport.js +29 -0
  22. package/dist/auto-ui/streamable-http-transport.js.map +1 -1
  23. package/dist/auto-ui/ui-resolver.d.ts +25 -0
  24. package/dist/auto-ui/ui-resolver.d.ts.map +1 -0
  25. package/dist/auto-ui/ui-resolver.js +95 -0
  26. package/dist/auto-ui/ui-resolver.js.map +1 -0
  27. package/dist/beam-form.bundle.js +7 -7
  28. package/dist/beam-form.bundle.js.map +1 -1
  29. package/dist/beam.bundle.js +905 -185
  30. package/dist/beam.bundle.js.map +4 -4
  31. package/dist/cli/commands/build.d.ts.map +1 -1
  32. package/dist/cli/commands/build.js +9 -5
  33. package/dist/cli/commands/build.js.map +1 -1
  34. package/dist/cli/commands/init.d.ts.map +1 -1
  35. package/dist/cli/commands/init.js +90 -50
  36. package/dist/cli/commands/init.js.map +1 -1
  37. package/dist/cli/commands/publish.d.ts +14 -0
  38. package/dist/cli/commands/publish.d.ts.map +1 -0
  39. package/dist/cli/commands/publish.js +126 -0
  40. package/dist/cli/commands/publish.js.map +1 -0
  41. package/dist/cli/commands/run.d.ts.map +1 -1
  42. package/dist/cli/commands/run.js +2 -0
  43. package/dist/cli/commands/run.js.map +1 -1
  44. package/dist/cli/index.d.ts.map +1 -1
  45. package/dist/cli/index.js +3 -0
  46. package/dist/cli/index.js.map +1 -1
  47. package/dist/context.d.ts +6 -0
  48. package/dist/context.d.ts.map +1 -1
  49. package/dist/context.js +17 -5
  50. package/dist/context.js.map +1 -1
  51. package/dist/daemon/client.d.ts +9 -1
  52. package/dist/daemon/client.d.ts.map +1 -1
  53. package/dist/daemon/client.js +54 -1
  54. package/dist/daemon/client.js.map +1 -1
  55. package/dist/daemon/manager.d.ts +3 -0
  56. package/dist/daemon/manager.d.ts.map +1 -1
  57. package/dist/daemon/manager.js +88 -38
  58. package/dist/daemon/manager.js.map +1 -1
  59. package/dist/daemon/ownership.d.ts +12 -0
  60. package/dist/daemon/ownership.d.ts.map +1 -0
  61. package/dist/daemon/ownership.js +55 -0
  62. package/dist/daemon/ownership.js.map +1 -0
  63. package/dist/daemon/protocol.d.ts +3 -1
  64. package/dist/daemon/protocol.d.ts.map +1 -1
  65. package/dist/daemon/protocol.js +14 -2
  66. package/dist/daemon/protocol.js.map +1 -1
  67. package/dist/daemon/server.js +549 -83
  68. package/dist/daemon/server.js.map +1 -1
  69. package/dist/daemon/session-manager.d.ts +9 -1
  70. package/dist/daemon/session-manager.d.ts.map +1 -1
  71. package/dist/daemon/session-manager.js +54 -1
  72. package/dist/daemon/session-manager.js.map +1 -1
  73. package/dist/daemon/worker-manager.d.ts +12 -0
  74. package/dist/daemon/worker-manager.d.ts.map +1 -1
  75. package/dist/daemon/worker-manager.js +89 -6
  76. package/dist/daemon/worker-manager.js.map +1 -1
  77. package/dist/loader.d.ts +3 -9
  78. package/dist/loader.d.ts.map +1 -1
  79. package/dist/loader.js +168 -113
  80. package/dist/loader.js.map +1 -1
  81. package/dist/photon-cli-runner.d.ts.map +1 -1
  82. package/dist/photon-cli-runner.js +26 -2
  83. package/dist/photon-cli-runner.js.map +1 -1
  84. package/dist/photons/canvas/ui/canvas.photon.html +1493 -0
  85. package/dist/photons/canvas.photon.d.ts +400 -0
  86. package/dist/photons/canvas.photon.d.ts.map +1 -0
  87. package/dist/photons/canvas.photon.js +662 -0
  88. package/dist/photons/canvas.photon.js.map +1 -0
  89. package/dist/photons/canvas.photon.ts +814 -0
  90. package/dist/photons/publish.photon.d.ts +97 -0
  91. package/dist/photons/publish.photon.d.ts.map +1 -0
  92. package/dist/photons/publish.photon.js +569 -0
  93. package/dist/photons/publish.photon.js.map +1 -0
  94. package/dist/photons/publish.photon.ts +683 -0
  95. package/dist/photons/ui/canvas.photon.html +624 -0
  96. package/dist/resource-server.d.ts.map +1 -1
  97. package/dist/resource-server.js +7 -1
  98. package/dist/resource-server.js.map +1 -1
  99. package/dist/shared-utils.d.ts.map +1 -1
  100. package/dist/shared-utils.js +2 -2
  101. package/dist/shared-utils.js.map +1 -1
  102. package/dist/tsx-compiler.d.ts +23 -0
  103. package/dist/tsx-compiler.d.ts.map +1 -0
  104. package/dist/tsx-compiler.js +221 -0
  105. package/dist/tsx-compiler.js.map +1 -0
  106. package/package.json +7 -7
@@ -18105,9 +18105,9 @@ var theme = i`
18105
18105
  --radius-full: 9999px;
18106
18106
 
18107
18107
  /* Typography - same for all themes */
18108
- --font-display: 'Space Grotesk', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
18109
- --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
18110
- --font-mono: 'JetBrains Mono', monospace;
18108
+ --font-display: 'Sora', 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
18109
+ --font-sans: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
18110
+ --font-mono: 'Berkeley Mono', 'JetBrains Mono', 'Fira Code', monospace;
18111
18111
 
18112
18112
  /* Type scale */
18113
18113
  --text-3xl: 2rem;
@@ -18134,17 +18134,17 @@ var theme = i`
18134
18134
  /* Shared Utility Classes */
18135
18135
  .glass {
18136
18136
  background: var(--bg-glass);
18137
- backdrop-filter: blur(16px);
18138
- -webkit-backdrop-filter: blur(16px);
18139
18137
  border: 1px solid var(--border-glass);
18138
+ border-top-color: color-mix(in srgb, var(--border-glass) 100%, white 8%);
18139
+ border-left-color: color-mix(in srgb, var(--border-glass) 100%, white 5%);
18140
18140
  box-shadow: var(--shadow-md);
18141
18141
  }
18142
18142
 
18143
18143
  .glass-panel {
18144
18144
  background: var(--bg-glass-strong);
18145
- backdrop-filter: blur(24px);
18146
- -webkit-backdrop-filter: blur(24px);
18147
18145
  border: 1px solid var(--border-glass);
18146
+ border-top-color: color-mix(in srgb, var(--border-glass) 100%, white 8%);
18147
+ border-left-color: color-mix(in srgb, var(--border-glass) 100%, white 5%);
18148
18148
  border-radius: var(--radius-md);
18149
18149
  box-shadow: var(--shadow-sm);
18150
18150
  color: inherit;
@@ -19528,10 +19528,10 @@ function oklchToRgba(L3, C3, H3, alpha2) {
19528
19528
  return `rgba(${Math.round(clamp01(r7) * 255)}, ${Math.round(clamp01(g3) * 255)}, ${Math.round(clamp01(b3) * 255)}, ${alpha2})`;
19529
19529
  }
19530
19530
  var themePresets = [
19531
- { name: "Default Violet", config: { hue: 260, chroma: 0.15, lightness: 0.65 } },
19531
+ { name: "Amber", config: { hue: 75, chroma: 0.14, lightness: 0.7 } },
19532
19532
  { name: "Ocean Blue", config: { hue: 220, chroma: 0.12, lightness: 0.6 } },
19533
19533
  { name: "Emerald", config: { hue: 155, chroma: 0.14, lightness: 0.6 } },
19534
- { name: "Amber", config: { hue: 75, chroma: 0.14, lightness: 0.7 } },
19534
+ { name: "Violet", config: { hue: 260, chroma: 0.15, lightness: 0.65 } },
19535
19535
  { name: "Rose", config: { hue: 350, chroma: 0.14, lightness: 0.62 } },
19536
19536
  { name: "Monochrome", config: { hue: 0, chroma: 0, lightness: 0.65 } }
19537
19537
  ];
@@ -19744,20 +19744,20 @@ var colorPalette = {
19744
19744
  95: "#f2f2f2",
19745
19745
  100: "#ffffff"
19746
19746
  },
19747
- // Light-theme neutrals (warm cream/beige undertone)
19747
+ // Light-theme neutrals (cool mineral paper)
19748
19748
  neutralLight: {
19749
- 85: "#C8C0B8",
19749
+ 85: "#B0BCCC",
19750
19750
  // heavy borders / dividers
19751
- 88: "#D0C9C1",
19751
+ 88: "#D8E0EA",
19752
19752
  // surface-container-highest
19753
- 91: "#DDD7CF",
19753
+ 91: "#E4EAF1",
19754
19754
  // surface-container-high
19755
- 94: "#EAE4DD",
19756
- // bg-app — warm cream structure
19757
- 96: "#F0EBE5",
19755
+ 94: "#EEF1F5",
19756
+ // bg-app — mineral paper
19757
+ 96: "#F5F7FA",
19758
19758
  // surface-container
19759
- 98: "#F8F5F1"
19760
- // surface — warm off-white panels
19759
+ 98: "#FFFFFF"
19760
+ // surface — white panels
19761
19761
  },
19762
19762
  // Primary (blue - trust, action)
19763
19763
  primary: {
@@ -19850,24 +19850,24 @@ var colorsDark = {
19850
19850
  scrim: "rgba(0, 0, 0, 0.5)"
19851
19851
  };
19852
19852
  var colorsLight = {
19853
- // Surfaces (cool blue-gray, higher contrast between levels)
19853
+ // Surfaces (cool mineral paper)
19854
19854
  surface: colorPalette.neutralLight[98],
19855
- // #F6F7F9 — panels
19855
+ // #FFFFFF — panels
19856
19856
  surfaceContainer: colorPalette.neutralLight[96],
19857
- // #EBEEF2 — containers
19857
+ // #F5F7FA — containers
19858
19858
  surfaceContainerHigh: colorPalette.neutralLight[91],
19859
- // #D5DBE1
19859
+ // #E4EAF1
19860
19860
  surfaceContainerHighest: colorPalette.neutralLight[88],
19861
- // #C4CDD5
19861
+ // #D8E0EA
19862
19862
  surfaceBright: colorPalette.neutral[100],
19863
19863
  // #FFFFFF — overlays/modals
19864
- // Text on surfaces (warm charcoal, high contrast)
19865
- onSurface: "#2C2420",
19866
- // warm brown-charcoal — WCAG AAA
19867
- onSurfaceVariant: "#4A3F38",
19868
- // warm dark brown for readability
19869
- onSurfaceMuted: "#6B5E54",
19870
- // warm muted brown — WCAG AA
19864
+ // Text on surfaces (cool ink, high contrast)
19865
+ onSurface: "#0D1420",
19866
+ // dark ink — WCAG AAA
19867
+ onSurfaceVariant: "#3A4A5C",
19868
+ // cool dark for readability
19869
+ onSurfaceMuted: "#5F6B7A",
19870
+ // steel muted — WCAG AA
19871
19871
  // Primary (darker for light theme)
19872
19872
  primary: colorPalette.primary[40],
19873
19873
  primaryContainer: colorPalette.primary[90],
@@ -19892,11 +19892,11 @@ var colorsLight = {
19892
19892
  onError: colorPalette.neutral[100],
19893
19893
  // white text
19894
19894
  onErrorContainer: colorPalette.error[10],
19895
- // Outline (warm, visible but not harsh)
19896
- outline: "#9B9088",
19897
- // warm gray-brown for visibility
19898
- outlineVariant: "#D5CFC8",
19899
- // warm border, not washed out
19895
+ // Outline (cool, visible but not harsh)
19896
+ outline: "#8893A0",
19897
+ // cool steel for visibility
19898
+ outlineVariant: "#C8D2DE",
19899
+ // cool border, not washed out
19900
19900
  // Scrim (overlay — lighter than dark theme's 0.5)
19901
19901
  scrim: "rgba(0, 0, 0, 0.2)"
19902
19902
  };
@@ -20143,10 +20143,10 @@ var ThemeSettings = class extends i4 {
20143
20143
  constructor() {
20144
20144
  super(...arguments);
20145
20145
  this.currentTheme = "dark";
20146
- this._hue = 260;
20147
- this._chroma = 0.15;
20148
- this._lightness = 0.65;
20149
- this._presetName = "Default Violet";
20146
+ this._hue = 75;
20147
+ this._chroma = 0.14;
20148
+ this._lightness = 0.7;
20149
+ this._presetName = "Amber";
20150
20150
  this._previousConfig = null;
20151
20151
  }
20152
20152
  connectedCallback() {
@@ -20233,10 +20233,10 @@ var ThemeSettings = class extends i4 {
20233
20233
  }
20234
20234
  _reset() {
20235
20235
  localStorage.removeItem(THEME_CONFIG_KEY);
20236
- this._hue = 260;
20237
- this._chroma = 0.15;
20238
- this._lightness = 0.65;
20239
- this._presetName = "Default Violet";
20236
+ this._hue = 75;
20237
+ this._chroma = 0.14;
20238
+ this._lightness = 0.7;
20239
+ this._presetName = "Amber";
20240
20240
  this.dispatchEvent(new CustomEvent("oklch-theme-reset", { bubbles: true, composed: true }));
20241
20241
  }
20242
20242
  _revert() {
@@ -20561,16 +20561,16 @@ ThemeSettings.styles = [
20561
20561
  .chroma-slider {
20562
20562
  background: linear-gradient(
20563
20563
  to right,
20564
- oklch(0.65 0 var(--hue-val, 260)),
20565
- oklch(0.65 0.3 var(--hue-val, 260))
20564
+ oklch(0.65 0 var(--hue-val, 75)),
20565
+ oklch(0.65 0.3 var(--hue-val, 75))
20566
20566
  );
20567
20567
  }
20568
20568
 
20569
20569
  .lightness-slider {
20570
20570
  background: linear-gradient(
20571
20571
  to right,
20572
- oklch(0.2 0.1 var(--hue-val, 260)),
20573
- oklch(0.9 0.1 var(--hue-val, 260))
20572
+ oklch(0.2 0.1 var(--hue-val, 75)),
20573
+ oklch(0.9 0.1 var(--hue-val, 75))
20574
20574
  );
20575
20575
  }
20576
20576
 
@@ -22089,6 +22089,9 @@ var MCPClientService = class {
22089
22089
  case "beam/render":
22090
22090
  this.emit("render", notification.params);
22091
22091
  break;
22092
+ case "beam/canvas":
22093
+ this.emit("canvas", notification.params);
22094
+ break;
22092
22095
  case "photon/board-update":
22093
22096
  this.emit("board-update", notification.params);
22094
22097
  break;
@@ -22658,6 +22661,7 @@ var BeamApp = class extends i4 {
22658
22661
  this._runningTests = false;
22659
22662
  this._selectedMethod = null;
22660
22663
  this._lastResult = null;
22664
+ this._canvasActive = false;
22661
22665
  this._customUiRevision = 0;
22662
22666
  this._customFormatUri = null;
22663
22667
  this._lastFormParams = {};
@@ -23534,6 +23538,11 @@ var BeamApp = class extends i4 {
23534
23538
  }
23535
23539
  }
23536
23540
  }
23541
+ if (msg.type === "photon:toast") {
23542
+ const validTypes = ["success", "error", "info", "warning"];
23543
+ const toastType = validTypes.includes(msg.toastType) ? msg.toastType : "info";
23544
+ showToast(msg.message || "Notification", toastType, msg.duration || 3e3);
23545
+ }
23537
23546
  if (msg.type === "photon:viewing") {
23538
23547
  const photonId = this._selectedPhoton?.id;
23539
23548
  const itemId = msg.itemId || msg.board;
@@ -23626,9 +23635,9 @@ var BeamApp = class extends i4 {
23626
23635
  this.style.removeProperty(prop);
23627
23636
  }
23628
23637
  const theme3 = this._theme || "dark";
23629
- const defaultViolet = { hue: 260, chroma: 0.15, lightness: 0.65, theme: theme3 };
23638
+ const defaultAmber = { hue: 75, chroma: 0.14, lightness: 0.7, theme: theme3 };
23630
23639
  this._oklchEnabled = true;
23631
- this._applyOklchTheme(defaultViolet);
23640
+ this._applyOklchTheme(defaultAmber);
23632
23641
  this._broadcastThemeToIframes();
23633
23642
  showToast("Theme reset to default", "info");
23634
23643
  };
@@ -24680,6 +24689,25 @@ var BeamApp = class extends i4 {
24680
24689
  this.requestUpdate();
24681
24690
  }
24682
24691
  });
24692
+ mcpClient.on("canvas", (data) => {
24693
+ if (!data?.photon || !data?.method) return;
24694
+ const currentPhoton = this._selectedPhoton?.name;
24695
+ const currentMethod = this._selectedMethod?.name;
24696
+ if (data.photon !== currentPhoton || data.method !== currentMethod) return;
24697
+ if (!this._canvasActive) {
24698
+ this._canvasActive = true;
24699
+ this.requestUpdate();
24700
+ }
24701
+ void this.updateComplete.then(() => {
24702
+ const canvas = this.shadowRoot?.querySelector("canvas-renderer");
24703
+ if (!canvas) return;
24704
+ if (data.type === "ui") {
24705
+ canvas.pushUI(data.html);
24706
+ } else if (data.type === "data") {
24707
+ canvas.pushData(data.slot, data.data);
24708
+ }
24709
+ });
24710
+ });
24683
24711
  mcpClient.on("photons", (data) => {
24684
24712
  if (data?.photons) {
24685
24713
  const prevNames = new Set(this._photons.filter((p5) => !p5.internal).map((p5) => p5.name));
@@ -25282,8 +25310,6 @@ var BeamApp = class extends i4 {
25282
25310
  </div>
25283
25311
  ` : ""}
25284
25312
 
25285
- <div class="background-glow" aria-hidden="true"></div>
25286
-
25287
25313
  <!-- Mobile Menu Button: shows back arrow when in method detail, hamburger otherwise -->
25288
25314
  <button
25289
25315
  class="mobile-menu-btn ${this._sidebarVisible ? "open" : ""}"
@@ -26713,6 +26739,7 @@ ${photon.errorMessage || "Unknown error"}</pre
26713
26739
  }
26714
26740
  _handleMethodSelect(e8) {
26715
26741
  this._teardownActiveCustomUI();
26742
+ this._canvasActive = false;
26716
26743
  this._lastFormParams = {};
26717
26744
  if (this._viewMode === "full") {
26718
26745
  this._sharedFormParams = null;
@@ -27063,7 +27090,7 @@ ${photon.errorMessage || "Unknown error"}</pre
27063
27090
  </div>
27064
27091
  </div>
27065
27092
  ` : ""}
27066
- ${opts.result !== null ? this._customFormatUri ? b2`
27093
+ ${opts.result !== null || this._canvasActive ? this._customFormatUri ? b2`
27067
27094
  <custom-ui-renderer
27068
27095
  .photon=${opts.photon?.name || ""}
27069
27096
  .method=${opts.method?.name || ""}
@@ -27095,17 +27122,21 @@ ${photon.errorMessage || "Unknown error"}</pre
27095
27122
  <button @click=${() => this._handleShareResult()}>Share</button>
27096
27123
  </div>
27097
27124
  </div>` : ""}
27098
- <result-viewer
27099
- .result=${opts.result}
27100
- .outputFormat=${opts.method?.outputFormat}
27101
- .layoutHints=${opts.method?.layoutHints}
27102
- .photonName=${opts.photon?.name}
27103
- .theme=${this._theme}
27104
- .live=${this._currentCollectionName !== null}
27105
- .resultKey=${opts.photon && opts.method ? `${opts.photon.name}/${opts.method.name}` : void 0}
27106
- @share=${() => this._handleShareResult()}
27107
- @checklist-action=${(e8) => this._handleChecklistAction(e8)}
27108
- ></result-viewer>
27125
+ ${this._canvasActive ? b2`<canvas-renderer
27126
+ .photon=${opts.photon?.name || ""}
27127
+ .method=${opts.method?.name || ""}
27128
+ .theme=${this._theme}
27129
+ ></canvas-renderer>` : b2`<result-viewer
27130
+ .result=${opts.result}
27131
+ .outputFormat=${opts.method?.outputFormat}
27132
+ .layoutHints=${opts.method?.layoutHints}
27133
+ .photonName=${opts.photon?.name}
27134
+ .theme=${this._theme}
27135
+ .live=${this._currentCollectionName !== null}
27136
+ .resultKey=${opts.photon && opts.method ? `${opts.photon.name}/${opts.method.name}` : void 0}
27137
+ @share=${() => this._handleShareResult()}
27138
+ @checklist-action=${(e8) => this._handleChecklistAction(e8)}
27139
+ ></result-viewer>`}
27109
27140
  ` : b2`
27110
27141
  <div class="empty-state-inline result-empty">
27111
27142
  <span class="empty-state-icon">${play}</span>
@@ -27828,7 +27859,7 @@ ${photon.errorMessage || "Unknown error"}</pre
27828
27859
  */
27829
27860
  _forwardToIframes(message) {
27830
27861
  const iframes = [];
27831
- this.shadowRoot?.querySelectorAll("custom-ui-renderer").forEach((renderer) => {
27862
+ this.shadowRoot?.querySelectorAll("custom-ui-renderer, canvas-renderer").forEach((renderer) => {
27832
27863
  const iframe = renderer.shadowRoot?.querySelector("iframe");
27833
27864
  if (iframe) iframes.push(iframe);
27834
27865
  });
@@ -29198,47 +29229,47 @@ BeamApp.styles = [
29198
29229
  theme,
29199
29230
  i`
29200
29231
  :host {
29201
- /* ===== Dark Theme (Default) ===== */
29202
- --bg-app: hsl(220, 15%, 10%);
29203
- --bg-glass: hsla(220, 15%, 14%, 0.6);
29204
- --bg-glass-strong: hsla(220, 15%, 14%, 0.85);
29205
- --bg-panel: hsl(220, 15%, 12%);
29206
- --t-primary: hsl(220, 10%, 95%);
29207
- --t-muted: hsl(220, 10%, 65%);
29208
- --border-glass: hsla(220, 10%, 80%, 0.1);
29209
- --accent-primary: hsl(260, 100%, 65%);
29210
- --accent-secondary: hsl(190, 100%, 50%);
29211
- --glow-primary: hsla(260, 100%, 65%, 0.3);
29232
+ /* ===== Dark Theme (Default) — Precision Optics ===== */
29233
+ --bg-app: #0b1018;
29234
+ --bg-glass: hsla(215, 25%, 12%, 0.6);
29235
+ --bg-glass-strong: hsla(215, 25%, 12%, 0.85);
29236
+ --bg-panel: #131b28;
29237
+ --t-primary: #f0ede6;
29238
+ --t-muted: #6b8a8a;
29239
+ --border-glass: hsla(210, 20%, 50%, 0.12);
29240
+ --accent-primary: #ffb000;
29241
+ --accent-secondary: #78e6ff;
29242
+ --glow-primary: rgba(255, 176, 0, 0.3);
29212
29243
 
29213
29244
  /* Semantic status colors */
29214
- --color-error: #ff4444;
29215
- --color-error-glow: rgba(255, 68, 68, 0.6);
29216
- --color-error-bg: rgba(255, 68, 68, 0.1);
29217
- --color-success: #00e676;
29218
- --color-success-glow: rgba(0, 230, 118, 0.6);
29219
- --color-success-bg: rgba(0, 230, 118, 0.15);
29220
- --color-warning: #ffab00;
29221
- --color-warning-bg: rgba(255, 171, 0, 0.15);
29222
- --color-warning-glow: rgba(255, 171, 0, 0.6);
29245
+ --color-error: #ff6b6b;
29246
+ --color-error-glow: rgba(255, 107, 107, 0.6);
29247
+ --color-error-bg: rgba(255, 107, 107, 0.1);
29248
+ --color-success: #58d68d;
29249
+ --color-success-glow: rgba(88, 214, 141, 0.6);
29250
+ --color-success-bg: rgba(88, 214, 141, 0.15);
29251
+ --color-warning: #ffb347;
29252
+ --color-warning-bg: rgba(255, 179, 71, 0.15);
29253
+ --color-warning-glow: rgba(255, 179, 71, 0.6);
29223
29254
  --color-info: var(--accent-secondary);
29224
29255
 
29225
29256
  /* CLI preview */
29226
- --cli-bg: hsl(220, 15%, 6%);
29227
- --cli-border: hsl(220, 10%, 20%);
29228
- --cli-text: hsl(142, 76%, 57%);
29229
- --cli-muted: hsl(220, 10%, 40%);
29230
- --cli-hover-bg: hsl(220, 15%, 10%);
29257
+ --cli-bg: #080c12;
29258
+ --cli-border: #1e2d3d;
29259
+ --cli-text: #58d68d;
29260
+ --cli-muted: #4a6565;
29261
+ --cli-hover-bg: #0b1018;
29231
29262
 
29232
29263
  /* Initials icon (marketplace cards) */
29233
- --initials-bg-sat: 35%;
29234
- --initials-bg-lum: 22%;
29235
- --initials-fg-sat: 60%;
29236
- --initials-fg-lum: 75%;
29264
+ --initials-bg-sat: 25%;
29265
+ --initials-bg-lum: 18%;
29266
+ --initials-fg-sat: 50%;
29267
+ --initials-fg-lum: 70%;
29237
29268
 
29238
29269
  /* Shadow tokens (dark defaults) */
29239
- --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
29240
- --shadow-md: 0 4px 24px -1px rgba(0, 0, 0, 0.2);
29241
- --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.3);
29270
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
29271
+ --shadow-md: 0 4px 24px -1px rgba(0, 0, 0, 0.3);
29272
+ --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.35);
29242
29273
 
29243
29274
  display: flex;
29244
29275
  height: 100vh;
@@ -29249,52 +29280,52 @@ BeamApp.styles = [
29249
29280
  overflow: visible; /* Allow focus rings and shadows to display */
29250
29281
  }
29251
29282
 
29252
- /* ===== Light Theme - "Warm, Soft, Professional" ===== */
29283
+ /* ===== Light Theme Mineral Paper ===== */
29253
29284
  :host([data-theme='light']) {
29254
- --bg-app: #eae4dd;
29255
- --bg-glass: rgba(255, 253, 250, 0.75);
29256
- --bg-glass-strong: rgba(255, 253, 250, 0.9);
29257
- --bg-panel: #f8f5f1;
29258
- --t-primary: #2c2420;
29259
- --t-muted: #6b5e54;
29260
- --border-glass: rgba(120, 90, 60, 0.2);
29261
- --accent-primary: hsl(215, 55%, 45%);
29262
- --accent-secondary: hsl(165, 45%, 35%);
29263
- --glow-primary: hsla(215, 55%, 45%, 0.15);
29264
-
29265
- /* Semantic status colors — light theme (same vivid LED colors) */
29266
- --color-error: #e53935;
29267
- --color-error-glow: rgba(229, 57, 53, 0.5);
29268
- --color-error-bg: rgba(229, 57, 53, 0.08);
29269
- --color-success: #00c853;
29270
- --color-success-glow: rgba(0, 200, 83, 0.55);
29271
- --color-success-bg: rgba(0, 200, 83, 0.1);
29272
- --color-warning: #ff8f00;
29273
- --color-warning-bg: rgba(255, 143, 0, 0.1);
29274
- --color-warning-glow: rgba(255, 143, 0, 0.5);
29285
+ --bg-app: #eef1f5;
29286
+ --bg-glass: rgba(255, 255, 255, 0.75);
29287
+ --bg-glass-strong: rgba(255, 255, 255, 0.9);
29288
+ --bg-panel: #ffffff;
29289
+ --t-primary: #0d1420;
29290
+ --t-muted: #5f6b7a;
29291
+ --border-glass: rgba(100, 120, 150, 0.15);
29292
+ --accent-primary: #d98a00;
29293
+ --accent-secondary: #0ea5c6;
29294
+ --glow-primary: rgba(217, 138, 0, 0.15);
29295
+
29296
+ /* Semantic status colors — light theme */
29297
+ --color-error: #d64545;
29298
+ --color-error-glow: rgba(214, 69, 69, 0.5);
29299
+ --color-error-bg: rgba(214, 69, 69, 0.08);
29300
+ --color-success: #1f9d68;
29301
+ --color-success-glow: rgba(31, 157, 104, 0.55);
29302
+ --color-success-bg: rgba(31, 157, 104, 0.1);
29303
+ --color-warning: #d98a00;
29304
+ --color-warning-bg: rgba(217, 138, 0, 0.1);
29305
+ --color-warning-glow: rgba(217, 138, 0, 0.5);
29275
29306
  --color-info: var(--accent-secondary);
29276
29307
 
29277
29308
  /* CLI preview — light theme */
29278
- --cli-bg: hsl(30, 15%, 95%);
29309
+ --cli-bg: #f5f7fa;
29279
29310
  --cli-border: var(--border-glass);
29280
- --cli-text: hsl(142, 45%, 32%);
29311
+ --cli-text: #1f9d68;
29281
29312
  --cli-muted: var(--t-muted);
29282
- --cli-hover-bg: hsl(30, 15%, 91%);
29313
+ --cli-hover-bg: #e8ecf2;
29283
29314
 
29284
- /* Light-mode shadows — warm, visible but not harsh */
29285
- --shadow-sm: 0px 1px 3px rgba(80, 60, 40, 0.1), 0px 1px 2px rgba(80, 60, 40, 0.08);
29286
- --shadow-md: 0px 2px 6px rgba(80, 60, 40, 0.1), 0px 4px 8px rgba(80, 60, 40, 0.06);
29287
- --shadow-lg: 0px 4px 8px rgba(80, 60, 40, 0.1), 0px 10px 20px rgba(80, 60, 40, 0.06);
29315
+ /* Light-mode shadows — cool, clean */
29316
+ --shadow-sm: 0px 1px 3px rgba(0, 20, 50, 0.06), 0px 1px 2px rgba(0, 20, 50, 0.04);
29317
+ --shadow-md: 0px 2px 6px rgba(0, 20, 50, 0.06), 0px 4px 8px rgba(0, 20, 50, 0.04);
29318
+ --shadow-lg: 0px 4px 8px rgba(0, 20, 50, 0.06), 0px 10px 20px rgba(0, 20, 50, 0.04);
29288
29319
 
29289
29320
  /* Initials icon (marketplace cards) */
29290
- --initials-bg-sat: 30%;
29291
- --initials-bg-lum: 90%;
29292
- --initials-fg-sat: 50%;
29321
+ --initials-bg-sat: 20%;
29322
+ --initials-bg-lum: 92%;
29323
+ --initials-fg-sat: 40%;
29293
29324
  --initials-fg-lum: 35%;
29294
29325
 
29295
- /* Parameter tags — warm chip style for light backgrounds */
29296
- --param-tag-bg: hsla(25, 20%, 55%, 0.12);
29297
- --param-tag-color: hsl(20, 15%, 40%);
29326
+ /* Parameter tags — cool chip style for light backgrounds */
29327
+ --param-tag-bg: rgba(100, 120, 150, 0.1);
29328
+ --param-tag-color: #3a4a5c;
29298
29329
  }
29299
29330
 
29300
29331
  /* Skip to main content link — WCAG 2.4.1 */
@@ -29391,12 +29422,12 @@ BeamApp.styles = [
29391
29422
  :host(.view-result) .result-empty,
29392
29423
  :host(.view-form) result-viewer,
29393
29424
  :host(.view-form) custom-ui-renderer,
29425
+ :host(.view-form) canvas-renderer,
29394
29426
  :host(.view-form) .result-empty {
29395
29427
  display: none !important;
29396
29428
  }
29397
29429
 
29398
29430
  :host(.view-result) .mobile-menu-btn,
29399
- :host(.view-result) .background-glow,
29400
29431
  :host(.view-result) .focus-toolbar,
29401
29432
  :host(.view-result) .main-toolbar,
29402
29433
  :host(.view-result) .method-toolbar,
@@ -29407,7 +29438,6 @@ BeamApp.styles = [
29407
29438
  :host(.view-result) app-layout,
29408
29439
  :host(.view-result) .result-chrome,
29409
29440
  :host(.view-form) .mobile-menu-btn,
29410
- :host(.view-form) .background-glow,
29411
29441
  :host(.view-form) .focus-toolbar,
29412
29442
  :host(.view-form) .main-toolbar,
29413
29443
  :host(.view-form) .method-toolbar,
@@ -29851,9 +29881,9 @@ BeamApp.styles = [
29851
29881
  }
29852
29882
 
29853
29883
  .photon-badge.app {
29854
- background: hsla(260, 100%, 65%, 0.15);
29855
- border-color: hsla(260, 100%, 65%, 0.3);
29856
- color: hsl(260, 100%, 75%);
29884
+ background: rgba(255, 176, 0, 0.15);
29885
+ border-color: rgba(255, 176, 0, 0.3);
29886
+ color: #ffca4d;
29857
29887
  }
29858
29888
 
29859
29889
  .photon-badge.update {
@@ -30194,17 +30224,6 @@ BeamApp.styles = [
30194
30224
  font-weight: 500;
30195
30225
  }
30196
30226
 
30197
- .background-glow {
30198
- position: absolute;
30199
- top: -20%;
30200
- left: -10%;
30201
- width: 50%;
30202
- height: 50%;
30203
- background: radial-gradient(circle, var(--glow-primary) 0%, transparent 70%);
30204
- pointer-events: none;
30205
- z-index: 0;
30206
- }
30207
-
30208
30227
  .connection-banner {
30209
30228
  position: fixed;
30210
30229
  top: 0;
@@ -31255,6 +31274,9 @@ __decorateClass([
31255
31274
  __decorateClass([
31256
31275
  r5()
31257
31276
  ], BeamApp.prototype, "_lastResult", 2);
31277
+ __decorateClass([
31278
+ r5()
31279
+ ], BeamApp.prototype, "_canvasActive", 2);
31258
31280
  __decorateClass([
31259
31281
  r5()
31260
31282
  ], BeamApp.prototype, "_customUiRevision", 2);
@@ -36588,6 +36610,9 @@ var ResultViewer = class extends i4 {
36588
36610
  this._expandedAuditTrails = /* @__PURE__ */ new Set();
36589
36611
  // The detected ID field for the current result (shared across diff, animation, warmth)
36590
36612
  this._activeIdField = "id";
36613
+ // Column format pipe cache (invalidated when layoutHints changes)
36614
+ this._columnPipes = null;
36615
+ this._expandedRows = /* @__PURE__ */ new Set();
36591
36616
  // Chart.js instance for reactive updates
36592
36617
  this._chartInstance = null;
36593
36618
  this._chartInstances = /* @__PURE__ */ new Map();
@@ -36757,6 +36782,15 @@ var ResultViewer = class extends i4 {
36757
36782
  }
36758
36783
  this._chartInstances.forEach((chart) => chart.destroy());
36759
36784
  this._chartInstances.clear();
36785
+ for (const timer of this._slidesRefreshTimers) clearInterval(timer);
36786
+ this._slidesRefreshTimers = [];
36787
+ this._slidesBoundElements.forEach((el2) => {
36788
+ const cleanup = el2._renderCleanup;
36789
+ if (typeof cleanup === "function") cleanup();
36790
+ });
36791
+ this._slidesBoundElements.clear();
36792
+ this._slidesResizeObserver?.disconnect();
36793
+ this._slidesResizeObserver = null;
36760
36794
  }
36761
36795
  _closeFullscreen() {
36762
36796
  this._fullscreenImage = null;
@@ -37657,6 +37691,8 @@ var ResultViewer = class extends i4 {
37657
37691
  case "metric":
37658
37692
  case "gauge":
37659
37693
  return typeof data === "object" && !Array.isArray(data) && (data.value !== void 0 || data.count !== void 0 || data.total !== void 0 || data.current !== void 0);
37694
+ case "ring":
37695
+ return typeof data === "number" || typeof data === "object" && !Array.isArray(data) && (data.value !== void 0 || data.progress !== void 0);
37660
37696
  case "chart":
37661
37697
  return typeof data !== "string";
37662
37698
  case "mermaid":
@@ -37715,6 +37751,8 @@ var ResultViewer = class extends i4 {
37715
37751
  return this._renderMetric(filteredData);
37716
37752
  case "gauge":
37717
37753
  return this._renderGauge(filteredData);
37754
+ case "ring":
37755
+ return this._renderRing(filteredData);
37718
37756
  case "timeline":
37719
37757
  return this._renderTimeline(filteredData);
37720
37758
  case "dashboard":
@@ -37796,10 +37834,12 @@ var ResultViewer = class extends i4 {
37796
37834
  const startIndex = this._currentPage * this._pageSize;
37797
37835
  const endIndex = Math.min(startIndex + this._pageSize, totalItems);
37798
37836
  const pageData = sortedData.slice(startIndex, endIndex);
37837
+ const idField = this._detectIdField(originalData);
37799
37838
  return b2`
37800
37839
  <table class="smart-table">
37801
37840
  <thead>
37802
37841
  <tr>
37842
+ <th class="row-expand-th"></th>
37803
37843
  ${columns.map(
37804
37844
  (col) => b2`<th
37805
37845
  class="sortable ${this._sortColumn === col ? "sorted" : ""}"
@@ -37813,15 +37853,42 @@ var ResultViewer = class extends i4 {
37813
37853
  </tr>
37814
37854
  </thead>
37815
37855
  <tbody class="motion-stagger">
37816
- ${pageData.map(
37817
- (row) => b2`
37818
- <tr class="${this._getItemAnimationClass(row)} ${this._getItemWarmthClass(row)}">
37856
+ ${pageData.map((row, idx) => {
37857
+ const rowId = String(row[idField] ?? `__idx_${startIndex + idx}`);
37858
+ const isExpanded = this._expandedRows.has(rowId);
37859
+ return b2`
37860
+ <tr
37861
+ class="${this._getItemAnimationClass(row)} ${this._getItemWarmthClass(
37862
+ row
37863
+ )} ${isExpanded ? "row-expanded" : ""}"
37864
+ @click=${() => this._toggleRowExpansion(rowId)}
37865
+ style="cursor: pointer;"
37866
+ >
37867
+ <td class="row-expand-td">
37868
+ <span class="row-expand-chevron ${isExpanded ? "open" : ""}">▶</span>
37869
+ </td>
37819
37870
  ${columns.map(
37820
37871
  (col) => b2`<td>${this._formatCellValue(row[col], col, true)}</td>`
37821
37872
  )}
37822
37873
  </tr>
37823
- `
37824
- )}
37874
+ ${isExpanded ? b2`<tr class="detail-row">
37875
+ <td colspan="${columns.length + 1}">
37876
+ <div class="detail-panel">
37877
+ ${Object.entries(row).filter(([k3]) => k3 !== "__meta").map(
37878
+ ([k3, v2]) => b2`
37879
+ <div class="detail-field">
37880
+ <span class="detail-key">${this._formatColumnName(k3)}</span>
37881
+ <span class="detail-value"
37882
+ >${this._formatCellValue(v2, k3, true)}</span
37883
+ >
37884
+ </div>
37885
+ `
37886
+ )}
37887
+ </div>
37888
+ </td>
37889
+ </tr>` : ""}
37890
+ `;
37891
+ })}
37825
37892
  </tbody>
37826
37893
  </table>
37827
37894
  ${totalItems > this._pageSize ? this._renderPagination(totalItems, totalPages) : ""}
@@ -37836,6 +37903,15 @@ var ResultViewer = class extends i4 {
37836
37903
  }
37837
37904
  this._currentPage = 0;
37838
37905
  }
37906
+ _toggleRowExpansion(rowId) {
37907
+ const next = new Set(this._expandedRows);
37908
+ if (next.has(rowId)) {
37909
+ next.delete(rowId);
37910
+ } else {
37911
+ next.add(rowId);
37912
+ }
37913
+ this._expandedRows = next;
37914
+ }
37839
37915
  _renderPagination(totalItems, totalPages) {
37840
37916
  const startItem = this._currentPage * this._pageSize + 1;
37841
37917
  const endItem = Math.min((this._currentPage + 1) * this._pageSize, totalItems);
@@ -38380,6 +38456,9 @@ ${rows}`);
38380
38456
  }
38381
38457
  updated(changedProperties) {
38382
38458
  super.updated(changedProperties);
38459
+ if (changedProperties.has("layoutHints")) {
38460
+ this._columnPipes = null;
38461
+ }
38383
38462
  if (changedProperties.has("result") && this.result && typeof this.result === "object" && !Array.isArray(this.result) && typeof this.result._photonType === "string") {
38384
38463
  const data = this.result;
38385
38464
  const photonType = data._photonType;
@@ -41684,9 +41763,70 @@ ${footerText || pageNum ? `<div class="slide-footer"><span>${footerText || ""}</
41684
41763
  _formatColumnName(name2) {
41685
41764
  return formatLabel(name2);
41686
41765
  }
41766
+ _getColumnPipes() {
41767
+ if (this._columnPipes) return this._columnPipes;
41768
+ this._columnPipes = /* @__PURE__ */ new Map();
41769
+ const raw = this.layoutHints?.columnFormats;
41770
+ if (!raw) return this._columnPipes;
41771
+ for (const part of raw.split(",")) {
41772
+ const trimmed = part.trim();
41773
+ const colonIdx = trimmed.indexOf(":");
41774
+ if (colonIdx <= 0) continue;
41775
+ const col = trimmed.slice(0, colonIdx).trim();
41776
+ const pipeSpec = trimmed.slice(colonIdx + 1).trim();
41777
+ const pipeMatch = pipeSpec.match(/^(\w+)(?:\((\d+)\))?$/);
41778
+ if (col && pipeMatch) {
41779
+ this._columnPipes.set(col, { pipe: pipeMatch[1], arg: pipeMatch[2] });
41780
+ }
41781
+ }
41782
+ return this._columnPipes;
41783
+ }
41784
+ _applyPipe(value, pipe2, arg) {
41785
+ if (value === null || value === void 0) return "\u2014";
41786
+ switch (pipe2) {
41787
+ case "currency":
41788
+ return typeof value === "number" ? value.toLocaleString(void 0, { style: "currency", currency: arg || "USD" }) : String(value);
41789
+ case "percent": {
41790
+ if (typeof value === "number") {
41791
+ const pct = Math.abs(value) <= 1 ? value * 100 : value;
41792
+ const digits = arg ? parseInt(arg, 10) : 1;
41793
+ return `${pct.toFixed(digits)}%`;
41794
+ }
41795
+ return String(value);
41796
+ }
41797
+ case "date": {
41798
+ const d5 = new Date(value);
41799
+ return isNaN(d5.getTime()) ? String(value) : d5.toLocaleDateString();
41800
+ }
41801
+ case "truncate": {
41802
+ const max = parseInt(arg || "30", 10);
41803
+ const str = String(value);
41804
+ return str.length > max ? str.slice(0, max) + "\u2026" : str;
41805
+ }
41806
+ case "number":
41807
+ return typeof value === "number" ? value.toLocaleString() : String(value);
41808
+ case "compact": {
41809
+ if (typeof value !== "number") return String(value);
41810
+ if (Math.abs(value) >= 1e9) return (value / 1e9).toFixed(1) + "B";
41811
+ if (Math.abs(value) >= 1e6) return (value / 1e6).toFixed(1) + "M";
41812
+ if (Math.abs(value) >= 1e3) return (value / 1e3).toFixed(1) + "K";
41813
+ return value.toLocaleString();
41814
+ }
41815
+ default:
41816
+ return String(value);
41817
+ }
41818
+ }
41687
41819
  _formatCellValue(value, key, highlight = false) {
41688
41820
  if (value === null || value === void 0) return "\u2014";
41689
41821
  if (typeof value === "boolean") return value ? "\u2713" : "\u2717";
41822
+ const pipes = this._getColumnPipes();
41823
+ if (pipes.size > 0) {
41824
+ const pipe2 = pipes.get(key);
41825
+ if (pipe2) {
41826
+ const formatted = this._applyPipe(value, pipe2.pipe, pipe2.arg);
41827
+ return highlight ? this._highlightText(formatted) : formatted;
41828
+ }
41829
+ }
41690
41830
  if (this._isImageUrl(value)) {
41691
41831
  return b2`
41692
41832
  <div>
@@ -42112,9 +42252,157 @@ ${str}</pre
42112
42252
  const dateKeys = keys2.filter(
42113
42253
  (k3) => /^(date|time|createdAt|updatedAt|created|updated|timestamp|.*At|.*Date|.*Time)$/i.test(k3) || typeof sample2[k3] === "string" && /^\d{4}-\d{2}-\d{2}/.test(sample2[k3])
42114
42254
  );
42255
+ if (chartType === "histogram") {
42256
+ const field = this.layoutHints?.x || numericKeys[0];
42257
+ if (!field) return null;
42258
+ const values = items.map((i7) => i7[field]).filter((v2) => typeof v2 === "number");
42259
+ if (values.length === 0) return null;
42260
+ const binCount = Math.min(20, Math.max(5, Math.ceil(Math.sqrt(values.length))));
42261
+ const minVal = Math.min(...values);
42262
+ const maxVal = Math.max(...values);
42263
+ const binWidth = (maxVal - minVal) / binCount || 1;
42264
+ const bins = Array(binCount).fill(0);
42265
+ for (const v2 of values) {
42266
+ const idx = Math.min(binCount - 1, Math.floor((v2 - minVal) / binWidth));
42267
+ bins[idx]++;
42268
+ }
42269
+ const labels2 = bins.map((_3, i7) => `${(minVal + i7 * binWidth).toFixed(1)}`);
42270
+ return {
42271
+ type: "bar",
42272
+ data: {
42273
+ labels: labels2,
42274
+ datasets: [
42275
+ {
42276
+ label: this._formatColumnName(field),
42277
+ data: bins,
42278
+ backgroundColor: this._hexToRgba(palette2[0], 0.7),
42279
+ borderColor: palette2[0],
42280
+ borderWidth: 1
42281
+ }
42282
+ ]
42283
+ },
42284
+ options: {
42285
+ responsive: true,
42286
+ maintainAspectRatio: true,
42287
+ animation: { duration: 600, easing: "easeOutQuart" },
42288
+ plugins: {
42289
+ legend: { display: false },
42290
+ tooltip: {
42291
+ backgroundColor: "rgba(15, 23, 42, 0.9)",
42292
+ titleColor: "#e2e8f0",
42293
+ bodyColor: "#e2e8f0",
42294
+ borderColor: "rgba(99, 102, 241, 0.3)",
42295
+ borderWidth: 1,
42296
+ cornerRadius: 8,
42297
+ padding: 10
42298
+ }
42299
+ },
42300
+ scales: {
42301
+ x: { grid: { color: gridColor }, ticks: { color: textColor, maxRotation: 45 } },
42302
+ y: { grid: { color: gridColor }, ticks: { color: textColor }, beginAtZero: true }
42303
+ }
42304
+ }
42305
+ };
42306
+ }
42307
+ if (chartType === "scatter") {
42308
+ const xField = this.layoutHints?.x || numericKeys[0];
42309
+ const yField = this.layoutHints?.y || numericKeys[1];
42310
+ if (!xField || !yField) return null;
42311
+ return {
42312
+ type: "scatter",
42313
+ data: {
42314
+ datasets: [
42315
+ {
42316
+ label: `${this._formatColumnName(xField)} vs ${this._formatColumnName(yField)}`,
42317
+ data: items.map((item) => ({ x: item[xField], y: item[yField] })),
42318
+ backgroundColor: this._hexToRgba(palette2[0], 0.7),
42319
+ borderColor: palette2[0],
42320
+ pointRadius: 5,
42321
+ pointHoverRadius: 8
42322
+ }
42323
+ ]
42324
+ },
42325
+ options: {
42326
+ responsive: true,
42327
+ maintainAspectRatio: true,
42328
+ animation: { duration: 600, easing: "easeOutQuart" },
42329
+ plugins: {
42330
+ legend: { display: false },
42331
+ tooltip: {
42332
+ backgroundColor: "rgba(15, 23, 42, 0.9)",
42333
+ titleColor: "#e2e8f0",
42334
+ bodyColor: "#e2e8f0",
42335
+ borderColor: "rgba(99, 102, 241, 0.3)",
42336
+ borderWidth: 1,
42337
+ cornerRadius: 8,
42338
+ padding: 10
42339
+ }
42340
+ },
42341
+ scales: {
42342
+ x: {
42343
+ type: "linear",
42344
+ title: { display: true, text: this._formatColumnName(xField), color: textColor },
42345
+ grid: { color: gridColor },
42346
+ ticks: { color: textColor }
42347
+ },
42348
+ y: {
42349
+ type: "linear",
42350
+ title: { display: true, text: this._formatColumnName(yField), color: textColor },
42351
+ grid: { color: gridColor },
42352
+ ticks: { color: textColor }
42353
+ }
42354
+ }
42355
+ }
42356
+ };
42357
+ }
42115
42358
  const labelField = this.layoutHints?.label || this.layoutHints?.x || dateKeys[0] || stringKeys[0];
42116
42359
  const valueFields = this.layoutHints?.y ? [this.layoutHints.y] : this.layoutHints?.value ? [this.layoutHints.value] : numericKeys;
42117
42360
  if (!labelField || valueFields.length === 0) return null;
42361
+ if (chartType === "radar" && items.length === 1) {
42362
+ const labels2 = valueFields.map((f5) => this._formatColumnName(f5));
42363
+ return {
42364
+ type: "radar",
42365
+ data: {
42366
+ labels: labels2,
42367
+ datasets: [
42368
+ {
42369
+ label: items[0][stringKeys[0]] || "Values",
42370
+ data: valueFields.map((f5) => items[0][f5] ?? 0),
42371
+ backgroundColor: this._hexToRgba(palette2[0], 0.2),
42372
+ borderColor: palette2[0],
42373
+ borderWidth: 2,
42374
+ pointRadius: 4,
42375
+ pointHoverRadius: 6,
42376
+ fill: true
42377
+ }
42378
+ ]
42379
+ },
42380
+ options: {
42381
+ responsive: true,
42382
+ maintainAspectRatio: true,
42383
+ animation: { duration: 600, easing: "easeOutQuart" },
42384
+ plugins: {
42385
+ legend: { display: false },
42386
+ tooltip: {
42387
+ backgroundColor: "rgba(15, 23, 42, 0.9)",
42388
+ titleColor: "#e2e8f0",
42389
+ bodyColor: "#e2e8f0",
42390
+ borderColor: "rgba(99, 102, 241, 0.3)",
42391
+ borderWidth: 1,
42392
+ cornerRadius: 8,
42393
+ padding: 10
42394
+ }
42395
+ },
42396
+ scales: {
42397
+ r: {
42398
+ grid: { color: gridColor },
42399
+ pointLabels: { color: textColor },
42400
+ ticks: { color: textColor, backdropColor: "transparent" }
42401
+ }
42402
+ }
42403
+ }
42404
+ };
42405
+ }
42118
42406
  const labels = items.map((item) => {
42119
42407
  const val = item[labelField];
42120
42408
  if (dateKeys.includes(labelField) && typeof val === "string") {
@@ -42136,9 +42424,10 @@ ${str}</pre
42136
42424
  borderColor: palette2[i7 % palette2.length],
42137
42425
  borderWidth: chartType === "pie" || chartType === "doughnut" ? 0 : 2,
42138
42426
  tension: 0.3,
42139
- fill: chartType === "line" && valueFields.length === 1 ? "origin" : false,
42140
- pointRadius: chartType === "scatter" ? 5 : 3,
42141
- pointHoverRadius: chartType === "scatter" ? 8 : 5
42427
+ fill: chartType === "radar" ? true : chartType === "line" && valueFields.length === 1 ? "origin" : false,
42428
+ pointRadius: 3,
42429
+ pointHoverRadius: 5,
42430
+ ...chartType === "radar" ? { backgroundColor: this._hexToRgba(palette2[i7 % palette2.length], 0.2) } : {}
42142
42431
  }));
42143
42432
  const isPolar = chartType === "pie" || chartType === "doughnut" || chartType === "radar";
42144
42433
  return {
@@ -42170,7 +42459,13 @@ ${str}</pre
42170
42459
  padding: 10
42171
42460
  }
42172
42461
  },
42173
- scales: isPolar ? {} : {
42462
+ scales: chartType === "radar" ? {
42463
+ r: {
42464
+ grid: { color: gridColor },
42465
+ pointLabels: { color: textColor },
42466
+ ticks: { color: textColor, backdropColor: "transparent" }
42467
+ }
42468
+ } : isPolar ? {} : {
42174
42469
  x: {
42175
42470
  grid: { color: gridColor },
42176
42471
  ticks: { color: textColor, maxRotation: 45 }
@@ -42204,8 +42499,12 @@ ${str}</pre
42204
42499
  const keys2 = Object.keys(sample2);
42205
42500
  const numericKeys = keys2.filter((k3) => typeof sample2[k3] === "number");
42206
42501
  const hasDate = this._hasDateLikeFields(sample2);
42502
+ const stringKeys = keys2.filter((k3) => typeof sample2[k3] === "string");
42207
42503
  if (hasDate && numericKeys.length >= 1) return "line";
42504
+ if (numericKeys.length >= 2 && stringKeys.length === 0 && items.length > 1) return "scatter";
42208
42505
  if (keys2.length === 2 && numericKeys.length === 1 && items.length <= 8) return "pie";
42506
+ if (items.length === 1 && numericKeys.length >= 5) return "radar";
42507
+ if (items.length <= 5 && numericKeys.length >= 4 && stringKeys.length === 1) return "radar";
42209
42508
  return "bar";
42210
42509
  }
42211
42510
  _hexToRgba(hex4, alpha2) {
@@ -42349,6 +42648,74 @@ ${str}</pre
42349
42648
  }
42350
42649
  }
42351
42650
  // ═══════════════════════════════════════════════════════════════════════════
42651
+ // Ring (Circular Progress) Rendering
42652
+ // ═══════════════════════════════════════════════════════════════════════════
42653
+ _renderRing(data) {
42654
+ let value;
42655
+ let max = 100;
42656
+ let label;
42657
+ if (typeof data === "number") {
42658
+ value = data;
42659
+ } else if (data && typeof data === "object") {
42660
+ if ("progress" in data && typeof data.progress === "number") {
42661
+ value = data.progress * 100;
42662
+ } else {
42663
+ value = data.value ?? 0;
42664
+ }
42665
+ max = parseFloat(this.layoutHints?.max ?? String(data.max ?? 100));
42666
+ label = data.label || this.layoutHints?.title;
42667
+ } else {
42668
+ return b2`<div class="empty-state">No ring data</div>`;
42669
+ }
42670
+ const normalized = Math.max(0, Math.min(1, value / max));
42671
+ const cx = 60;
42672
+ const cy = 60;
42673
+ const r7 = 50;
42674
+ const circumference = 2 * Math.PI * r7;
42675
+ const dashOffset = circumference * (1 - normalized);
42676
+ const color2 = this._getGaugeColor(normalized);
42677
+ const displayValue = data?.progress !== void 0 ? `${Math.round(value)}%` : String(Math.round(value));
42678
+ return b2`
42679
+ <div class="ring-container ${this._objectJustChanged ? "value-flash" : ""}">
42680
+ <svg viewBox="0 0 120 120" width="120" height="120">
42681
+ <circle
42682
+ cx="${cx}"
42683
+ cy="${cy}"
42684
+ r="${r7}"
42685
+ fill="none"
42686
+ stroke="${this.theme === "light" ? "#e2e8f0" : "#334155"}"
42687
+ stroke-width="8"
42688
+ />
42689
+ <circle
42690
+ cx="${cx}"
42691
+ cy="${cy}"
42692
+ r="${r7}"
42693
+ fill="none"
42694
+ stroke="${color2}"
42695
+ stroke-width="8"
42696
+ stroke-dasharray="${circumference}"
42697
+ stroke-dashoffset="${dashOffset}"
42698
+ stroke-linecap="round"
42699
+ transform="rotate(-90 ${cx} ${cy})"
42700
+ />
42701
+ <text
42702
+ x="${cx}"
42703
+ y="${cy}"
42704
+ text-anchor="middle"
42705
+ dominant-baseline="central"
42706
+ font-size="20"
42707
+ font-weight="700"
42708
+ font-variant-numeric="tabular-nums"
42709
+ fill="${this.theme === "light" ? "#1e293b" : "#e2e8f0"}"
42710
+ >
42711
+ ${displayValue}
42712
+ </text>
42713
+ </svg>
42714
+ ${label ? b2`<div class="ring-label">${label}</div>` : ""}
42715
+ </div>
42716
+ `;
42717
+ }
42718
+ // ═══════════════════════════════════════════════════════════════════════════
42352
42719
  // Timeline Rendering
42353
42720
  // ═══════════════════════════════════════════════════════════════════════════
42354
42721
  _renderTimeline(data) {
@@ -43077,6 +43444,67 @@ ResultViewer.styles = [
43077
43444
  background: var(--bg-glass);
43078
43445
  }
43079
43446
 
43447
+ /* Row expansion */
43448
+ .row-expand-th {
43449
+ width: 32px;
43450
+ padding: 0 !important;
43451
+ }
43452
+ .row-expand-td {
43453
+ width: 32px;
43454
+ padding: 4px 6px !important;
43455
+ text-align: center;
43456
+ }
43457
+ .row-expand-chevron {
43458
+ display: inline-block;
43459
+ font-size: 0.6em;
43460
+ color: var(--t-muted);
43461
+ transition: transform 0.2s ease;
43462
+ }
43463
+ .row-expand-chevron.open {
43464
+ transform: rotate(90deg);
43465
+ }
43466
+ .row-expanded td {
43467
+ border-bottom: none;
43468
+ }
43469
+ .detail-row td {
43470
+ padding: 0 !important;
43471
+ border-bottom: 1px solid var(--border-glass);
43472
+ }
43473
+ .detail-panel {
43474
+ display: grid;
43475
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
43476
+ gap: var(--space-xs) var(--space-md);
43477
+ padding: var(--space-sm) var(--space-md) var(--space-sm) 40px;
43478
+ background: var(--bg-glass);
43479
+ animation: detail-slide-down 0.2s ease-out;
43480
+ }
43481
+ .detail-field {
43482
+ display: flex;
43483
+ flex-direction: column;
43484
+ gap: 2px;
43485
+ }
43486
+ .detail-key {
43487
+ font-size: var(--text-xs);
43488
+ font-weight: 600;
43489
+ color: var(--t-muted);
43490
+ text-transform: uppercase;
43491
+ letter-spacing: 0.05em;
43492
+ }
43493
+ .detail-value {
43494
+ font-size: var(--text-md);
43495
+ color: var(--t-primary);
43496
+ }
43497
+ @keyframes detail-slide-down {
43498
+ from {
43499
+ opacity: 0;
43500
+ transform: translateY(-4px);
43501
+ }
43502
+ to {
43503
+ opacity: 1;
43504
+ transform: translateY(0);
43505
+ }
43506
+ }
43507
+
43080
43508
  /* Key-Value Table (single object) */
43081
43509
  .kv-table {
43082
43510
  max-width: 600px;
@@ -44868,6 +45296,28 @@ ResultViewer.styles = [
44868
45296
  stroke 0.3s ease-out;
44869
45297
  }
44870
45298
 
45299
+ /* ═══════════════════════════════════════════════════════════════
45300
+ Ring (Circular Progress)
45301
+ ═══════════════════════════════════════════════════════════════ */
45302
+ .ring-container {
45303
+ display: flex;
45304
+ flex-direction: column;
45305
+ align-items: center;
45306
+ padding: 12px;
45307
+ }
45308
+ .ring-container svg circle {
45309
+ transition:
45310
+ stroke-dashoffset 0.6s ease-out,
45311
+ stroke 0.3s ease-out;
45312
+ }
45313
+ .ring-label {
45314
+ font-size: var(--text-md);
45315
+ color: var(--t-muted);
45316
+ margin-top: var(--space-xs);
45317
+ text-transform: uppercase;
45318
+ letter-spacing: 0.06em;
45319
+ }
45320
+
44871
45321
  /* ═══════════════════════════════════════════════════════════════
44872
45322
  Timeline Component
44873
45323
  ═══════════════════════════════════════════════════════════════ */
@@ -45496,6 +45946,9 @@ __decorateClass([
45496
45946
  __decorateClass([
45497
45947
  r5()
45498
45948
  ], ResultViewer.prototype, "_checklistToggledDone", 2);
45949
+ __decorateClass([
45950
+ r5()
45951
+ ], ResultViewer.prototype, "_expandedRows", 2);
45499
45952
  __decorateClass([
45500
45953
  n4({ type: String })
45501
45954
  ], ResultViewer.prototype, "collectionProperty", 2);
@@ -47953,7 +48406,7 @@ MarketplaceView = __decorateClass([
47953
48406
 
47954
48407
  // src/auto-ui/frontend/styles/beam-tokens.ts
47955
48408
  var beamTypographyTokens = {
47956
- "--font-display": "'Space Grotesk', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif",
48409
+ "--font-display": "'Sora', 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif",
47957
48410
  "--text-3xl": "2rem",
47958
48411
  "--text-2xl": "1.5rem",
47959
48412
  "--text-xl": "1.25rem",
@@ -47968,17 +48421,17 @@ var beamTypographyTokens = {
47968
48421
  function getBeamThemeTokens(themeMode) {
47969
48422
  const tokens = getThemeTokens(themeMode);
47970
48423
  if (themeMode === "dark") {
47971
- tokens["--color-surface"] = "hsl(220, 15%, 10%)";
47972
- tokens["--color-surface-container"] = "hsl(220, 15%, 12%)";
47973
- tokens["--color-surface-container-high"] = "hsl(220, 15%, 14%)";
47974
- tokens["--color-surface-container-highest"] = "hsl(220, 15%, 16%)";
47975
- tokens["--bg"] = "hsl(220, 15%, 10%)";
48424
+ tokens["--color-surface"] = "#0B1018";
48425
+ tokens["--color-surface-container"] = "#131B28";
48426
+ tokens["--color-surface-container-high"] = "#1A2433";
48427
+ tokens["--color-surface-container-highest"] = "#212D3E";
48428
+ tokens["--bg"] = "#0B1018";
47976
48429
  } else {
47977
- tokens["--color-surface"] = "#eae4dd";
47978
- tokens["--color-surface-container"] = "#f8f5f1";
47979
- tokens["--color-surface-container-high"] = "#f0ebe5";
47980
- tokens["--color-surface-container-highest"] = "#e8e2db";
47981
- tokens["--bg"] = "#eae4dd";
48430
+ tokens["--color-surface"] = "#EEF1F5";
48431
+ tokens["--color-surface-container"] = "#FFFFFF";
48432
+ tokens["--color-surface-container-high"] = "#E4EAF1";
48433
+ tokens["--color-surface-container-highest"] = "#D8E0EA";
48434
+ tokens["--bg"] = "#EEF1F5";
47982
48435
  }
47983
48436
  return tokens;
47984
48437
  }
@@ -48558,6 +49011,273 @@ CustomUiRenderer = __decorateClass([
48558
49011
  t4("custom-ui-renderer")
48559
49012
  ], CustomUiRenderer);
48560
49013
 
49014
+ // src/auto-ui/frontend/components/canvas-renderer.ts
49015
+ function getBeamThemeTokens2(themeMode) {
49016
+ const tokens = getThemeTokens(themeMode);
49017
+ if (themeMode === "dark") {
49018
+ tokens["--color-surface"] = "#0B1018";
49019
+ tokens["--color-surface-container"] = "#131B28";
49020
+ tokens["--color-surface-container-high"] = "#1A2433";
49021
+ tokens["--color-surface-container-highest"] = "#212D3E";
49022
+ tokens["--bg"] = "#0B1018";
49023
+ } else {
49024
+ tokens["--color-surface"] = "#EEF1F5";
49025
+ tokens["--color-surface-container"] = "#FFFFFF";
49026
+ tokens["--color-surface-container-high"] = "#E4EAF1";
49027
+ tokens["--color-surface-container-highest"] = "#D8E0EA";
49028
+ tokens["--bg"] = "#EEF1F5";
49029
+ }
49030
+ return tokens;
49031
+ }
49032
+ var CanvasRenderer = class extends i4 {
49033
+ constructor() {
49034
+ super(...arguments);
49035
+ this.photon = "";
49036
+ this.method = "";
49037
+ this.theme = "dark";
49038
+ this._loading = true;
49039
+ this._iframeRef = null;
49040
+ this._blobUrl = null;
49041
+ this._iframeReady = false;
49042
+ this._messageBuffer = [];
49043
+ this._resizeObserver = null;
49044
+ }
49045
+ connectedCallback() {
49046
+ super.connectedCallback();
49047
+ void this._buildAndMount();
49048
+ }
49049
+ disconnectedCallback() {
49050
+ super.disconnectedCallback();
49051
+ if (this._blobUrl) {
49052
+ URL.revokeObjectURL(this._blobUrl);
49053
+ this._blobUrl = null;
49054
+ }
49055
+ }
49056
+ /**
49057
+ * Push a canvas/ui message to the iframe (HTML layout with data-slot placeholders)
49058
+ */
49059
+ pushUI(htmlContent) {
49060
+ this._postOrBuffer({
49061
+ jsonrpc: "2.0",
49062
+ method: "canvas/ui",
49063
+ params: { html: htmlContent }
49064
+ });
49065
+ }
49066
+ /**
49067
+ * Push a canvas/data message to the iframe (JSON data targeting a named slot)
49068
+ */
49069
+ pushData(slot, data) {
49070
+ this._postOrBuffer({
49071
+ jsonrpc: "2.0",
49072
+ method: "canvas/data",
49073
+ params: { slot, data }
49074
+ });
49075
+ }
49076
+ _postOrBuffer(message) {
49077
+ if (this._iframeReady && this._iframeRef?.contentWindow) {
49078
+ this._iframeRef.contentWindow.postMessage(message, "*");
49079
+ } else {
49080
+ this._messageBuffer.push(message);
49081
+ }
49082
+ }
49083
+ _flushBuffer() {
49084
+ if (!this._iframeRef?.contentWindow) return;
49085
+ for (const msg of this._messageBuffer) {
49086
+ this._iframeRef.contentWindow.postMessage(msg, "*");
49087
+ }
49088
+ this._messageBuffer = [];
49089
+ }
49090
+ async _buildAndMount() {
49091
+ this._loading = true;
49092
+ try {
49093
+ const bridgeRes = await fetch(
49094
+ `/api/platform-bridge?photon=${encodeURIComponent(this.photon)}&method=${encodeURIComponent(this.method)}&theme=${encodeURIComponent(this.theme)}`,
49095
+ { signal: AbortSignal.timeout(1e4) }
49096
+ );
49097
+ if (!bridgeRes.ok) throw new Error("Failed to load platform bridge");
49098
+ const bridgeScript = await bridgeRes.text();
49099
+ const baseCSS = `<style>
49100
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
49101
+ body {
49102
+ font-family: var(--font-family-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
49103
+ background: var(--color-surface);
49104
+ color: var(--color-on-surface);
49105
+ font-size: var(--font-size-sm, 14px);
49106
+ line-height: 1.5;
49107
+ padding: var(--space-4, 16px);
49108
+ }
49109
+ a { color: var(--color-primary); }
49110
+ [data-slot] {
49111
+ min-height: 40px;
49112
+ transition: opacity 0.2s ease;
49113
+ }
49114
+ [data-slot].photon-loading {
49115
+ opacity: 0.4;
49116
+ }
49117
+ [data-slot][data-rendered] {
49118
+ opacity: 1;
49119
+ }
49120
+ </style>`;
49121
+ const renderersScript = `<script src="/api/photon-renderers.js"><\/script>`;
49122
+ const shellHtml = `<html>
49123
+ <head>
49124
+ <meta name="photon-canvas" content="true">
49125
+ ${bridgeScript}
49126
+ ${baseCSS}
49127
+ ${renderersScript}
49128
+ </head>
49129
+ <body></body>
49130
+ </html>`;
49131
+ const blob = new Blob([shellHtml], { type: "text/html" });
49132
+ this._blobUrl = URL.createObjectURL(blob);
49133
+ await this.updateComplete;
49134
+ const container = this.shadowRoot?.querySelector(".iframe-host");
49135
+ if (!container) return;
49136
+ const old = container.querySelector("iframe");
49137
+ if (old) old.remove();
49138
+ const iframe = document.createElement("iframe");
49139
+ iframe.setAttribute(
49140
+ "sandbox",
49141
+ "allow-scripts allow-forms allow-same-origin allow-popups allow-modals"
49142
+ );
49143
+ iframe.setAttribute("allowtransparency", "true");
49144
+ iframe.addEventListener("load", () => this._handleIframeLoad(iframe));
49145
+ iframe.src = this._blobUrl;
49146
+ container.appendChild(iframe);
49147
+ } catch (e8) {
49148
+ console.error("[canvas-renderer] Failed to build:", e8);
49149
+ this._loading = false;
49150
+ }
49151
+ }
49152
+ _handleIframeLoad(iframe) {
49153
+ this._iframeRef = iframe;
49154
+ this._loading = false;
49155
+ const themeTokens = getBeamThemeTokens2(this.theme);
49156
+ iframe.contentWindow?.postMessage(
49157
+ {
49158
+ jsonrpc: "2.0",
49159
+ method: "ui/notifications/host-context-changed",
49160
+ params: {
49161
+ theme: this.theme,
49162
+ styles: { variables: themeTokens }
49163
+ }
49164
+ },
49165
+ "*"
49166
+ );
49167
+ iframe.contentWindow?.postMessage(
49168
+ {
49169
+ type: "photon:theme-change",
49170
+ theme: this.theme,
49171
+ themeTokens: { ...themeTokens, ...beamTypographyTokens }
49172
+ },
49173
+ "*"
49174
+ );
49175
+ this._iframeReady = true;
49176
+ this._flushBuffer();
49177
+ this._startAutoResize(iframe);
49178
+ }
49179
+ _startAutoResize(iframe) {
49180
+ const resize = () => {
49181
+ try {
49182
+ const height = iframe.contentDocument?.body?.scrollHeight;
49183
+ if (height && height > 0) {
49184
+ iframe.style.height = `${height + 16}px`;
49185
+ this.style.minHeight = `${height + 16}px`;
49186
+ }
49187
+ } catch (_3) {
49188
+ }
49189
+ };
49190
+ try {
49191
+ const body = iframe.contentDocument?.body;
49192
+ if (body) {
49193
+ this._resizeObserver = new MutationObserver(resize);
49194
+ this._resizeObserver.observe(body, { childList: true, subtree: true, attributes: true });
49195
+ }
49196
+ } catch (_3) {
49197
+ }
49198
+ const interval = setInterval(resize, 500);
49199
+ setTimeout(() => clearInterval(interval), 1e4);
49200
+ }
49201
+ updated(changedProperties) {
49202
+ if (changedProperties.has("theme") && this._iframeRef?.contentWindow) {
49203
+ const themeTokens = getBeamThemeTokens2(this.theme);
49204
+ this._iframeRef.contentWindow.postMessage(
49205
+ {
49206
+ jsonrpc: "2.0",
49207
+ method: "ui/notifications/host-context-changed",
49208
+ params: {
49209
+ theme: this.theme,
49210
+ styles: { variables: themeTokens }
49211
+ }
49212
+ },
49213
+ "*"
49214
+ );
49215
+ }
49216
+ }
49217
+ render() {
49218
+ return b2`
49219
+ <div class="iframe-host"></div>
49220
+ ${this._loading ? b2`<div class="loading"><span>Preparing canvas…</span></div>` : ""}
49221
+ `;
49222
+ }
49223
+ };
49224
+ CanvasRenderer.styles = [
49225
+ theme,
49226
+ i`
49227
+ :host {
49228
+ display: block;
49229
+ position: relative;
49230
+ width: 100%;
49231
+ height: 100%;
49232
+ min-height: 400px;
49233
+ background: transparent;
49234
+ border-radius: var(--radius-md);
49235
+ overflow: visible;
49236
+ }
49237
+
49238
+ .iframe-host {
49239
+ width: 100%;
49240
+ height: 100%;
49241
+ }
49242
+
49243
+ iframe {
49244
+ width: 100%;
49245
+ height: 100%;
49246
+ border: none;
49247
+ display: block;
49248
+ will-change: transform;
49249
+ }
49250
+
49251
+ .loading {
49252
+ position: absolute;
49253
+ inset: 0;
49254
+ z-index: 1;
49255
+ display: flex;
49256
+ flex-direction: column;
49257
+ align-items: center;
49258
+ justify-content: center;
49259
+ gap: 12px;
49260
+ color: var(--t-muted);
49261
+ font-size: 13px;
49262
+ }
49263
+ `
49264
+ ];
49265
+ __decorateClass([
49266
+ n4({ type: String })
49267
+ ], CanvasRenderer.prototype, "photon", 2);
49268
+ __decorateClass([
49269
+ n4({ type: String })
49270
+ ], CanvasRenderer.prototype, "method", 2);
49271
+ __decorateClass([
49272
+ n4({ type: String })
49273
+ ], CanvasRenderer.prototype, "theme", 2);
49274
+ __decorateClass([
49275
+ r5()
49276
+ ], CanvasRenderer.prototype, "_loading", 2);
49277
+ CanvasRenderer = __decorateClass([
49278
+ t4("canvas-renderer")
49279
+ ], CanvasRenderer);
49280
+
48561
49281
  // node_modules/zod/v4/core/core.js
48562
49282
  var NEVER = Object.freeze({
48563
49283
  status: "aborted"
@@ -68366,20 +69086,20 @@ function X_(r7, i7) {
68366
69086
  }
68367
69087
 
68368
69088
  // src/auto-ui/frontend/components/mcp-app-renderer.ts
68369
- function getBeamThemeTokens2(themeMode) {
69089
+ function getBeamThemeTokens3(themeMode) {
68370
69090
  const tokens = getThemeTokens(themeMode);
68371
69091
  if (themeMode === "dark") {
68372
- tokens["--color-surface"] = "hsl(220, 15%, 10%)";
68373
- tokens["--color-surface-container"] = "hsl(220, 15%, 12%)";
68374
- tokens["--color-surface-container-high"] = "hsl(220, 15%, 14%)";
68375
- tokens["--color-surface-container-highest"] = "hsl(220, 15%, 16%)";
68376
- tokens["--bg"] = "hsl(220, 15%, 10%)";
69092
+ tokens["--color-surface"] = "#0B1018";
69093
+ tokens["--color-surface-container"] = "#131B28";
69094
+ tokens["--color-surface-container-high"] = "#1A2433";
69095
+ tokens["--color-surface-container-highest"] = "#212D3E";
69096
+ tokens["--bg"] = "#0B1018";
68377
69097
  } else {
68378
- tokens["--color-surface"] = "#eae4dd";
68379
- tokens["--color-surface-container"] = "#f8f5f1";
68380
- tokens["--color-surface-container-high"] = "#f0ebe5";
68381
- tokens["--color-surface-container-highest"] = "#e8e2db";
68382
- tokens["--bg"] = "#eae4dd";
69098
+ tokens["--color-surface"] = "#EEF1F5";
69099
+ tokens["--color-surface-container"] = "#FFFFFF";
69100
+ tokens["--color-surface-container-high"] = "#E4EAF1";
69101
+ tokens["--color-surface-container-highest"] = "#D8E0EA";
69102
+ tokens["--bg"] = "#EEF1F5";
68383
69103
  }
68384
69104
  return tokens;
68385
69105
  }
@@ -68511,14 +69231,14 @@ var McpAppRenderer = class extends i4 {
68511
69231
  willUpdate(changedProperties) {
68512
69232
  if (changedProperties.has("theme")) {
68513
69233
  if (this._bridge) {
68514
- const specTokens = filterSpecVariables(getBeamThemeTokens2(this.theme));
69234
+ const specTokens = filterSpecVariables(getBeamThemeTokens3(this.theme));
68515
69235
  this._bridge.setHostContext({
68516
69236
  theme: this.theme,
68517
69237
  styles: { variables: specTokens }
68518
69238
  });
68519
69239
  }
68520
69240
  if (this._iframeRef?.contentWindow) {
68521
- const themeTokens = getBeamThemeTokens2(this.theme);
69241
+ const themeTokens = getBeamThemeTokens3(this.theme);
68522
69242
  this._iframeRef.contentWindow.postMessage(
68523
69243
  {
68524
69244
  jsonrpc: "2.0",
@@ -68632,7 +69352,7 @@ var McpAppRenderer = class extends i4 {
68632
69352
  const iframe = e8.target;
68633
69353
  this._iframeRef = iframe;
68634
69354
  if (!iframe.contentWindow) return;
68635
- const themeTokens = getBeamThemeTokens2(this.theme);
69355
+ const themeTokens = getBeamThemeTokens3(this.theme);
68636
69356
  iframe.contentWindow.postMessage(
68637
69357
  {
68638
69358
  jsonrpc: "2.0",
@@ -68676,7 +69396,7 @@ var McpAppRenderer = class extends i4 {
68676
69396
  const msg = event.data;
68677
69397
  if (!msg || typeof msg !== "object") return;
68678
69398
  if (msg.jsonrpc === "2.0" && msg.method === "ui/initialize" && msg.id != null) {
68679
- const themeTokens2 = getBeamThemeTokens2(this.theme);
69399
+ const themeTokens2 = getBeamThemeTokens3(this.theme);
68680
69400
  iframe.contentWindow?.postMessage(
68681
69401
  {
68682
69402
  jsonrpc: "2.0",
@@ -68745,7 +69465,7 @@ var McpAppRenderer = class extends i4 {
68745
69465
  void asyncMessageHandler(event);
68746
69466
  };
68747
69467
  window.addEventListener("message", this._messageHandler);
68748
- const specTokens = filterSpecVariables(getBeamThemeTokens2(this.theme));
69468
+ const specTokens = filterSpecVariables(getBeamThemeTokens3(this.theme));
68749
69469
  this._bridge = new W_(
68750
69470
  null,
68751
69471
  { name: "Photon Beam", version: "1.0.0" },
@@ -99300,7 +100020,7 @@ var OverflowMenu = class extends i4 {
99300
100020
  border: 1px solid ${borderGlass};
99301
100021
  border-radius: ${radiusMd};
99302
100022
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
99303
- font-family: 'Inter', sans-serif;
100023
+ font-family: 'DM Sans', sans-serif;
99304
100024
  padding: 4px 0;
99305
100025
  `;
99306
100026
  this.items.forEach((item) => {
@@ -99618,7 +100338,7 @@ var InstancePanel = class extends i4 {
99618
100338
  border: 1px solid ${borderGlass};
99619
100339
  border-radius: ${radiusMd};
99620
100340
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
99621
- font-family: 'Inter', sans-serif;
100341
+ font-family: 'DM Sans', sans-serif;
99622
100342
  padding: 8px;
99623
100343
  `;
99624
100344
  const addFocusGlow = (el2) => {