@3plate/graph-core 0.1.10 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2790,8 +2790,10 @@ var EditEdgeModal = class _EditEdgeModal extends Modal {
2790
2790
  }
2791
2791
  };
2792
2792
 
2793
+ // src/canvas/styles.css
2794
+ var styles_default = "/* ==================== Theme Variables ==================== */\n\n/* Light theme (default) */\n:root {\n --g3p-bg: #fafafa;\n --g3p-bg-node: #ffffff;\n --g3p-bg-secondary: #f8fafc;\n --g3p-border: #e2e8f0;\n --g3p-border-hover: #cbd5e1;\n --g3p-border-selected: #3b82f6;\n --g3p-text: #1e293b;\n --g3p-text-muted: #475569;\n --g3p-text-subtle: #64748b;\n --g3p-edge-color: #64748b;\n --g3p-port-bg: #e2e8f0;\n --g3p-port-bg-hover: #cbd5e1;\n --g3p-shadow: rgba(0, 0, 0, 0.15);\n}\n\n/* Dark theme (auto via prefers-color-scheme) */\n@media (prefers-color-scheme: dark) {\n :root {\n --g3p-bg: #1a1a1a;\n --g3p-bg-node: #333333;\n --g3p-bg-secondary: #2a2a2a;\n --g3p-border: #4a4a4a;\n --g3p-border-hover: #5a5a5a;\n --g3p-border-selected: #60a5fa;\n --g3p-text: #f0f0f0;\n --g3p-text-muted: #c0c0c0;\n --g3p-text-subtle: #909090;\n --g3p-edge-color: #b0b0b0;\n --g3p-port-bg: #444444;\n --g3p-port-bg-hover: #555555;\n --g3p-shadow: rgba(0, 0, 0, 0.5);\n }\n}\n\n/* Explicit light mode override */\n.g3p-light {\n --g3p-bg: #fafafa;\n --g3p-bg-node: #ffffff;\n --g3p-bg-secondary: #f8fafc;\n --g3p-border: #e2e8f0;\n --g3p-border-hover: #cbd5e1;\n --g3p-border-selected: #3b82f6;\n --g3p-text: #1e293b;\n --g3p-text-muted: #475569;\n --g3p-text-subtle: #64748b;\n --g3p-edge-color: #64748b;\n --g3p-port-bg: #e2e8f0;\n --g3p-port-bg-hover: #cbd5e1;\n --g3p-shadow: rgba(0, 0, 0, 0.15);\n}\n\n/* Explicit dark mode override */\n.g3p-dark {\n --g3p-bg: #1a1a1a;\n --g3p-bg-node: #333333;\n --g3p-bg-secondary: #2a2a2a;\n --g3p-border: #4a4a4a;\n --g3p-border-hover: #5a5a5a;\n --g3p-border-selected: #60a5fa;\n --g3p-text: #f0f0f0;\n --g3p-text-muted: #c0c0c0;\n --g3p-text-subtle: #909090;\n --g3p-edge-color: #b0b0b0;\n --g3p-port-bg: #444444;\n --g3p-port-bg-hover: #555555;\n --g3p-shadow: rgba(0, 0, 0, 0.5);\n}\n\n/* ==================== Canvas ==================== */\n\n.g3p-canvas-container {\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.g3p-canvas-root {\n display: block;\n width: 100%;\n height: 100%;\n user-select: none;\n background: var(--g3p-bg);\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n/* ==================== Zoom Controls ==================== */\n\n.g3p-zoom-controls {\n position: absolute;\n bottom: 1rem;\n right: 1rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n background: var(--g3p-bg-node);\n border-radius: 8px;\n padding: 0.5rem;\n box-shadow: 0 2px 8px var(--g3p-shadow);\n z-index: 10;\n}\n\n.g3p-zoom-btn {\n width: 36px;\n height: 36px;\n border: 1px solid var(--g3p-border);\n background: var(--g3p-bg-node);\n border-radius: 6px;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--g3p-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n}\n\n.g3p-zoom-btn:hover {\n background: var(--g3p-bg-secondary);\n border-color: var(--g3p-border-hover);\n color: var(--g3p-text);\n}\n\n.g3p-zoom-btn:active {\n transform: scale(0.95);\n}\n\n.g3p-zoom-reset {\n font-size: 1.1rem;\n}\n\n.g3p-zoom-level {\n text-align: center;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--g3p-text-subtle);\n padding: 0.25rem 0;\n}\n\n/* ==================== Nodes ==================== */\n\n/* Default node content styles */\n.g3p-node-default {\n padding: 8px 12px;\n font: 14px/1.4 system-ui, sans-serif;\n color: var(--g3p-text);\n}\n\n.g3p-node-title {\n font-weight: 500;\n}\n\n.g3p-node-detail {\n font-size: 12px;\n color: var(--g3p-text-muted);\n margin-top: 2px;\n}\n\n.g3p-node-container {\n transition: opacity 0.2s ease;\n}\n\n.g3p-node-border {\n background: var(--g3p-bg-node);\n border: 1px solid var(--g3p-border);\n border-radius: 8px;\n overflow: hidden;\n transition: all 0.15s ease;\n}\n\n.g3p-node-border:hover {\n border-color: var(--g3p-border-hover);\n}\n\n.g3p-node-border.selected {\n outline: 2px solid var(--g3p-border-selected);\n}\n\n.g3p-node-content-wrapper {\n pointer-events: none;\n}\n\n.g3p-node-content {\n pointer-events: auto;\n box-sizing: border-box;\n}\n\n.g3p-node-content>div {\n width: 100%;\n height: 100%;\n}\n\n/* Dummy node styles - these remain SVG since dummies are ellipses */\n.g3p-node-dummy .g3p-node-background {\n fill: var(--g3p-bg-secondary);\n opacity: 0.8;\n}\n\n.g3p-node-dummy {\n stroke: var(--g3p-border-hover);\n stroke-dasharray: 3, 3;\n cursor: default;\n}\n\n/* Port container styles */\n.g3p-node-ports {\n display: flex;\n gap: 4px;\n}\n\n.g3p-node-ports-row {\n flex-direction: row;\n justify-content: center;\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.g3p-node-ports-col {\n flex-direction: column;\n justify-content: center;\n padding-top: 8px;\n padding-bottom: 8px;\n}\n\n/* Port styles */\n.g3p-node-port {\n background: var(--g3p-port-bg);\n border: 1px solid var(--g3p-border-hover);\n padding: 2px 6px;\n font-size: 0.5em;\n color: var(--g3p-text-muted);\n white-space: nowrap;\n transition: all 0.15s ease;\n}\n\n.g3p-node-port:hover {\n background: var(--g3p-port-bg-hover);\n border-color: var(--g3p-text-subtle);\n}\n\n.g3p-node-port-rotated-left {\n writing-mode: vertical-lr;\n}\n\n.g3p-node-port-rotated-right {\n writing-mode: vertical-rl;\n}\n\n/* Outside ports: rounded corners away from the node rectangle, no border on touching side */\n.g3p-node-port-out-top {\n border-radius: 4px 4px 0 0;\n border-bottom: none;\n}\n\n.g3p-node-port-out-bottom {\n border-radius: 0 0 4px 4px;\n border-top: none;\n}\n\n.g3p-node-port-out-left {\n border-radius: 4px 0 0 4px;\n border-right: none;\n}\n\n.g3p-node-port-out-right {\n border-radius: 0 4px 4px 0;\n border-left: none;\n}\n\n/* Inside ports: rounded corners toward the content, no border on outer edge */\n.g3p-node-port-in-top {\n border-radius: 0 0 4px 4px;\n border-top: none;\n}\n\n.g3p-node-port-in-bottom {\n border-radius: 4px 4px 0 0;\n border-bottom: none;\n}\n\n.g3p-node-port-in-left {\n border-radius: 0 4px 4px 0;\n border-left: none;\n}\n\n.g3p-node-port-in-right {\n border-radius: 4px 0 0 4px;\n border-right: none;\n}\n\n/* Port wrapper */\n.g3p-node-with-ports {\n display: flex;\n}\n\n.g3p-node-with-ports-v {\n flex-direction: column;\n}\n\n.g3p-node-with-ports-h {\n flex-direction: row;\n}\n\n/* ==================== Edges (Segments) ==================== */\n\n.g3p-seg-container {\n transition: opacity 0.2s ease;\n}\n\n.g3p-seg-line {\n stroke: var(--g3p-edge-color);\n stroke-width: 1;\n transition: stroke 0.2s ease, stroke-width 0.2s ease;\n}\n\n.g3p-seg-marker {\n fill: var(--g3p-edge-color);\n}\n\n.g3p-seg-line.hovered {\n stroke-width: 2;\n opacity: 1;\n}\n\n.g3p-seg-line.selected {\n stroke: var(--g3p-border-selected);\n stroke-width: 2;\n}\n\n.g3p-seg-hitbox {\n cursor: pointer;\n}\n\n/* ==================== Markers ==================== */\n\n.g3p-marker {\n fill: context-stroke;\n stroke: none;\n}\n\n.g3p-marker-bar {\n fill: none;\n stroke: context-stroke;\n stroke-width: 2;\n}\n\n.g3p-marker.hovered {\n fill: var(--g3p-text-muted);\n}\n\n.g3p-marker.selected {\n fill: var(--g3p-border-selected);\n}\n\n.g3p-marker-bar.hovered {\n stroke: var(--g3p-text-muted);\n}\n\n.g3p-marker-bar.selected {\n stroke: var(--g3p-border-selected);\n}\n\n/* ==================== New Edge (Edit Mode) ==================== */\n\n.g3p-new-edge-container {\n pointer-events: none;\n}\n\n.g3p-new-edge-origin {\n fill: var(--g3p-edge-color, #64748b);\n stroke: none;\n}\n\n.g3p-new-edge-line {\n stroke: var(--g3p-edge-color, #64748b);\n stroke-width: 2;\n stroke-dasharray: 6 4;\n stroke-linecap: round;\n fill: none;\n animation: g3p-dash-animation 0.5s linear infinite;\n}\n\n.g3p-new-edge-end {\n fill: var(--g3p-edge-color, #64748b);\n stroke: white;\n stroke-width: 1.5;\n}\n\n@keyframes g3p-dash-animation {\n to {\n stroke-dashoffset: -10;\n }\n}\n\n/* ==================== Edit Mode Hover States ==================== */\n\n.g3p-node-container.g3p-drop-target .g3p-node-border {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n.g3p-node-port.g3p-drop-target {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n/* ==================== Modals ==================== */\n\n.g3p-modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.g3p-modal-dialog {\n background: var(--g3p-bg-node);\n border: 1px solid var(--g3p-border);\n border-radius: 8px;\n box-shadow: 0 4px 20px var(--g3p-shadow);\n min-width: 280px;\n max-width: 400px;\n}\n\n.g3p-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--g3p-border);\n}\n\n.g3p-modal-title {\n font-weight: 600;\n font-size: 14px;\n color: var(--g3p-text);\n}\n\n.g3p-modal-close {\n background: none;\n border: none;\n font-size: 20px;\n color: var(--g3p-text-muted);\n cursor: pointer;\n padding: 0;\n line-height: 1;\n}\n\n.g3p-modal-close:hover {\n color: var(--g3p-text);\n}\n\n.g3p-modal-body {\n padding: 16px;\n}\n\n.g3p-modal-field {\n margin-bottom: 12px;\n}\n\n.g3p-modal-field:last-child {\n margin-bottom: 0;\n}\n\n.g3p-modal-label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: var(--g3p-text-muted);\n margin-bottom: 4px;\n}\n\n.g3p-modal-input,\n.g3p-modal-select {\n width: 100%;\n padding: 8px 10px;\n font-size: 13px;\n border: 1px solid var(--g3p-border);\n border-radius: 4px;\n background: var(--g3p-bg);\n color: var(--g3p-text);\n box-sizing: border-box;\n}\n\n.g3p-modal-input:focus,\n.g3p-modal-select:focus {\n outline: none;\n border-color: var(--g3p-border-selected);\n}\n\n.g3p-modal-footer {\n padding: 12px 16px;\n border-top: 1px solid var(--g3p-border);\n}\n\n.g3p-modal-buttons {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.g3p-modal-spacer {\n flex: 1;\n}\n\n.g3p-modal-btn {\n padding: 6px 12px;\n font-size: 13px;\n font-weight: 500;\n border-radius: 4px;\n cursor: pointer;\n border: 1px solid transparent;\n transition: all 0.15s ease;\n}\n\n.g3p-modal-btn-primary {\n background: var(--g3p-border-selected);\n color: white;\n}\n\n.g3p-modal-btn-primary:hover {\n filter: brightness(1.1);\n}\n\n.g3p-modal-btn-secondary {\n background: var(--g3p-bg);\n border-color: var(--g3p-border);\n color: var(--g3p-text);\n}\n\n.g3p-modal-btn-secondary:hover {\n background: var(--g3p-bg-secondary);\n}\n\n.g3p-modal-btn-danger {\n background: #ef4444;\n color: white;\n}\n\n.g3p-modal-btn-danger:hover {\n background: #dc2626;\n}";
2795
+
2793
2796
  // src/canvas/canvas.tsx
2794
- import styles from "./styles.css?raw";
2795
2797
  import { jsx as jsx6, jsxs as jsxs5 } from "jsx-dom/jsx-runtime";
2796
2798
  var log10 = logger("canvas");
2797
2799
  var Canvas = class {
@@ -3036,7 +3038,7 @@ var Canvas = class {
3036
3038
  if (!document.getElementById("g3p-styles")) {
3037
3039
  const baseStyleEl = document.createElement("style");
3038
3040
  baseStyleEl.id = "g3p-styles";
3039
- baseStyleEl.textContent = styles;
3041
+ baseStyleEl.textContent = styles_default;
3040
3042
  document.head.appendChild(baseStyleEl);
3041
3043
  }
3042
3044
  const dynamicStyles = this.generateDynamicStyles();
@@ -3503,7 +3505,6 @@ function renderNode(node, props) {
3503
3505
  if (typeof node == "string") node = { id: node };
3504
3506
  const title = node?.title ?? props?.title ?? node?.label ?? node?.name ?? node?.text ?? props?.text ?? node?.id ?? "?";
3505
3507
  const detail = node?.detail ?? node?.description ?? node?.subtitle;
3506
- console.log(`renderNode: ${node.id} ${title} ${detail}`);
3507
3508
  return /* @__PURE__ */ jsxs6("div", { className: "g3p-node-default", children: [
3508
3509
  /* @__PURE__ */ jsx7("div", { className: "g3p-node-title", children: title }),
3509
3510
  detail && /* @__PURE__ */ jsx7("div", { className: "g3p-node-detail", children: detail })
@@ -3635,7 +3636,7 @@ var Ingest = class {
3635
3636
  * Apply an incoming ingest message to the API.
3636
3637
  * - snapshot: rebuild state from nodes/edges (clears prior history)
3637
3638
  * - update: apply incremental update
3638
- * - history: initialize from a set of frames (clears prior history)
3639
+ * - history: initialize from a set of updates (clears prior history)
3639
3640
  */
3640
3641
  async apply(msg) {
3641
3642
  switch (msg.type) {
@@ -3656,7 +3657,7 @@ var Ingest = class {
3656
3657
  break;
3657
3658
  }
3658
3659
  case "history": {
3659
- await this.api.replaceHistory(msg.frames);
3660
+ await this.api.replaceHistory(msg.history);
3660
3661
  break;
3661
3662
  }
3662
3663
  }
@@ -4030,9 +4031,9 @@ var API = class {
4030
4031
  this.canvas.editMode.editable = editable;
4031
4032
  }
4032
4033
  /** Replace entire history (clears prior) */
4033
- async replaceHistory(frames) {
4034
+ async replaceHistory(history) {
4034
4035
  this.reset();
4035
- this.history = frames;
4036
+ this.history = history;
4036
4037
  await this.applyHistory();
4037
4038
  }
4038
4039
  /** Rebuild from snapshot (nodes/edges) */
@@ -4499,8 +4500,8 @@ var API = class {
4499
4500
  }
4500
4501
  } else if (prev.history && isHistoryPrefix(prev.history, props.history)) {
4501
4502
  const prevLength = prev.history.length;
4502
- const newFrames = props.history.slice(prevLength);
4503
- for (const frame of newFrames) {
4503
+ const newUpdates = props.history.slice(prevLength);
4504
+ for (const frame of newUpdates) {
4504
4505
  this.update((u) => {
4505
4506
  if (frame.addNodes) u.addNodes(...frame.addNodes);
4506
4507
  if (frame.removeNodes) u.deleteNodes(...frame.removeNodes);
@@ -4587,8 +4588,411 @@ function shallowEqualUpdate(a, b) {
4587
4588
  return true;
4588
4589
  }
4589
4590
 
4591
+ // src/playground/styles.css
4592
+ var styles_default2 = `.playground {
4593
+ display: flex;
4594
+ height: calc(100vh - 60px);
4595
+ }
4596
+
4597
+ .sidebar {
4598
+ width: 280px;
4599
+ background: var(--color-bg);
4600
+ border-right: 1px solid var(--color-border);
4601
+ padding: 1.5rem;
4602
+ overflow-y: auto;
4603
+ }
4604
+
4605
+ .sidebar h2 {
4606
+ font-size: 0.875rem;
4607
+ text-transform: uppercase;
4608
+ letter-spacing: 0.05em;
4609
+ color: var(--color-text-muted);
4610
+ margin-bottom: 0.75rem;
4611
+ margin-top: 1.5rem;
4612
+ }
4613
+
4614
+ .sidebar h2:first-child {
4615
+ margin-top: 0;
4616
+ }
4617
+
4618
+ .example-list {
4619
+ display: flex;
4620
+ flex-direction: column;
4621
+ gap: 0.5rem;
4622
+ }
4623
+
4624
+ .example-btn {
4625
+ padding: 0.75rem 1rem;
4626
+ background: var(--color-bg-secondary);
4627
+ border: 1px solid var(--color-border);
4628
+ border-radius: 0.5rem;
4629
+ text-align: left;
4630
+ cursor: pointer;
4631
+ font-size: 0.875rem;
4632
+ color: var(--color-text);
4633
+ transition: all 0.15s;
4634
+ }
4635
+
4636
+ .example-btn:hover {
4637
+ background: var(--color-border);
4638
+ }
4639
+
4640
+ .example-btn.active {
4641
+ background: var(--color-primary);
4642
+ color: white;
4643
+ border-color: var(--color-primary);
4644
+ }
4645
+
4646
+ .options {
4647
+ display: flex;
4648
+ flex-direction: column;
4649
+ gap: 1rem;
4650
+ }
4651
+
4652
+ .option-group {
4653
+ display: flex;
4654
+ flex-direction: column;
4655
+ gap: 0.25rem;
4656
+ }
4657
+
4658
+ .option-group label {
4659
+ font-size: 0.875rem;
4660
+ color: var(--color-text-muted);
4661
+ }
4662
+
4663
+ .option-group select {
4664
+ padding: 0.5rem;
4665
+ border: 1px solid var(--color-border);
4666
+ border-radius: 0.25rem;
4667
+ font-size: 0.875rem;
4668
+ }
4669
+
4670
+ .option-group input[type="checkbox"] {
4671
+ margin-right: 0.5rem;
4672
+ }
4673
+
4674
+ .graph-area {
4675
+ flex: 1;
4676
+ padding: 1.5rem;
4677
+ overflow: hidden;
4678
+ display: flex;
4679
+ flex-direction: column;
4680
+ gap: 0.75rem;
4681
+ }
4682
+
4683
+ .graph-toolbar {
4684
+ display: flex;
4685
+ align-items: center;
4686
+ gap: 1rem;
4687
+ }
4688
+
4689
+ .nav-controls {
4690
+ display: flex;
4691
+ align-items: center;
4692
+ gap: 0.25rem;
4693
+ }
4694
+
4695
+ .nav-btn {
4696
+ padding: 0.5rem 0.75rem;
4697
+ background: var(--color-bg-secondary);
4698
+ border: 1px solid var(--color-border);
4699
+ border-radius: 0.25rem;
4700
+ cursor: pointer;
4701
+ font-size: 0.875rem;
4702
+ color: var(--color-text);
4703
+ transition: all 0.15s;
4704
+ height: 2.25rem;
4705
+ display: inline-flex;
4706
+ align-items: center;
4707
+ justify-content: center;
4708
+ box-sizing: border-box;
4709
+ }
4710
+
4711
+ .nav-btn:hover:not(:disabled) {
4712
+ background: var(--color-border);
4713
+ }
4714
+
4715
+ .nav-btn:disabled {
4716
+ opacity: 0.4;
4717
+ cursor: not-allowed;
4718
+ }
4719
+
4720
+ /* Prominent edit toggle */
4721
+ #edit-toggle {
4722
+ background: var(--color-primary);
4723
+ border-color: var(--color-primary);
4724
+ color: #fff;
4725
+ font-weight: 600;
4726
+ }
4727
+
4728
+ /* Source Icon Button */
4729
+ .source-icon-btn {
4730
+ font-size: 1.1rem;
4731
+ padding: 0.5rem;
4732
+ min-width: 2.5rem;
4733
+ position: relative;
4734
+ height: 2.25rem;
4735
+ }
4736
+
4737
+ .source-icon-btn::after {
4738
+ content: '';
4739
+ position: absolute;
4740
+ bottom: 2px;
4741
+ right: 2px;
4742
+ width: 8px;
4743
+ height: 8px;
4744
+ border-radius: 50%;
4745
+ background: var(--color-border);
4746
+ border: 1px solid var(--color-bg);
4747
+ }
4748
+
4749
+ .source-icon-btn.active::after {
4750
+ background: rgb(34, 197, 94);
4751
+ box-shadow: 0 0 4px rgba(34, 197, 94, 0.5);
4752
+ }
4753
+
4754
+ .source-icon-btn.connecting::after {
4755
+ background: rgb(251, 191, 36);
4756
+ box-shadow: 0 0 4px rgba(251, 191, 36, 0.5);
4757
+ animation: pulse-dot 1.5s ease-in-out infinite;
4758
+ }
4759
+
4760
+ .source-icon-btn.error::after {
4761
+ background: rgb(239, 68, 68);
4762
+ box-shadow: 0 0 4px rgba(239, 68, 68, 0.5);
4763
+ }
4764
+
4765
+ .source-icon-btn.active {
4766
+ background: var(--color-primary);
4767
+ border-color: var(--color-primary);
4768
+ color: #fff;
4769
+ }
4770
+
4771
+ .source-icon-btn.connecting {
4772
+ background: var(--color-primary);
4773
+ border-color: var(--color-primary);
4774
+ color: #fff;
4775
+ opacity: 0.7;
4776
+ animation: pulse 1.5s ease-in-out infinite;
4777
+ }
4778
+
4779
+ .source-icon-btn.error {
4780
+ border-color: rgb(239, 68, 68);
4781
+ }
4782
+
4783
+ @keyframes pulse-dot {
4784
+ 0%, 100% { opacity: 1; transform: scale(1); }
4785
+ 50% { opacity: 0.5; transform: scale(0.8); }
4786
+ }
4787
+
4788
+ @keyframes pulse {
4789
+ 0%, 100% { opacity: 0.7; }
4790
+ 50% { opacity: 1; }
4791
+ }
4792
+
4793
+ .graph-container {
4794
+ flex: 1;
4795
+ background: var(--color-bg);
4796
+ border-radius: 0.75rem;
4797
+ box-shadow: var(--shadow-md);
4798
+ overflow: hidden;
4799
+ }
4800
+
4801
+ /* Modal styles (global) */
4802
+ .modal-overlay {
4803
+ position: fixed;
4804
+ inset: 0;
4805
+ background: rgba(0, 0, 0, 0.35);
4806
+ display: none;
4807
+ align-items: center;
4808
+ justify-content: center;
4809
+ z-index: 1000;
4810
+ }
4811
+
4812
+ .modal {
4813
+ width: min(680px, calc(100vw - 2rem));
4814
+ background: var(--color-bg);
4815
+ color: var(--color-text);
4816
+ border: 1px solid var(--color-border);
4817
+ border-radius: 0.75rem;
4818
+ box-shadow: var(--shadow-lg);
4819
+ overflow: hidden;
4820
+ }
4821
+
4822
+ .modal-header {
4823
+ display: flex;
4824
+ align-items: center;
4825
+ justify-content: space-between;
4826
+ padding: 0.75rem 1rem;
4827
+ border-bottom: 1px solid var(--color-border);
4828
+ background: var(--color-bg-secondary);
4829
+ }
4830
+
4831
+ .modal-header h3 {
4832
+ font-size: 1rem;
4833
+ font-weight: 600;
4834
+ }
4835
+
4836
+ .modal-close {
4837
+ background: transparent;
4838
+ border: none;
4839
+ color: var(--color-text);
4840
+ font-size: 1.25rem;
4841
+ cursor: pointer;
4842
+ }
4843
+
4844
+ .modal-body {
4845
+ padding: 1rem;
4846
+ line-height: 1.6;
4847
+ }
4848
+
4849
+ .modal-body ul {
4850
+ margin: 0.5rem 0 0 1.25rem;
4851
+ }
4852
+
4853
+ .modal-body .form-group {
4854
+ margin-bottom: 1rem;
4855
+ }
4856
+
4857
+ .modal-body label {
4858
+ display: block;
4859
+ font-size: 0.875rem;
4860
+ color: var(--color-text-muted);
4861
+ margin-bottom: 0.5rem;
4862
+ }
4863
+
4864
+ .modal-body input[type="text"] {
4865
+ width: 100%;
4866
+ padding: 0.5rem;
4867
+ border: 1px solid var(--color-border);
4868
+ border-radius: 0.25rem;
4869
+ font-size: 0.875rem;
4870
+ background: var(--color-bg);
4871
+ color: var(--color-text);
4872
+ }
4873
+
4874
+ .modal-body .button-group {
4875
+ display: flex;
4876
+ gap: 0.5rem;
4877
+ margin-top: 1rem;
4878
+ }
4879
+
4880
+ .modal-body .button-group button {
4881
+ flex: 1;
4882
+ padding: 0.5rem 1rem;
4883
+ border: 1px solid var(--color-border);
4884
+ border-radius: 0.25rem;
4885
+ background: var(--color-bg-secondary);
4886
+ color: var(--color-text);
4887
+ cursor: pointer;
4888
+ font-size: 0.875rem;
4889
+ transition: all 0.15s;
4890
+ }
4891
+
4892
+ .modal-body .button-group button:hover:not(:disabled) {
4893
+ background: var(--color-border);
4894
+ }
4895
+
4896
+ .modal-body .button-group button:disabled {
4897
+ opacity: 0.5;
4898
+ cursor: not-allowed;
4899
+ }
4900
+
4901
+ .modal-body .button-group button.primary {
4902
+ background: var(--color-primary);
4903
+ border-color: var(--color-primary);
4904
+ color: #fff;
4905
+ }
4906
+
4907
+ .modal-body .button-group button.primary:hover:not(:disabled) {
4908
+ background: var(--color-primary);
4909
+ opacity: 0.9;
4910
+ }
4911
+
4912
+ .modal-body .status-message {
4913
+ margin-top: 1rem;
4914
+ padding: 0.75rem;
4915
+ border-radius: 0.25rem;
4916
+ font-size: 0.875rem;
4917
+ }
4918
+
4919
+ .modal-body .status-message.info {
4920
+ background: rgba(59, 130, 246, 0.1);
4921
+ color: rgb(59, 130, 246);
4922
+ border: 1px solid rgba(59, 130, 246, 0.2);
4923
+ }
4924
+
4925
+ .modal-body .status-message.error {
4926
+ background: rgba(239, 68, 68, 0.1);
4927
+ color: rgb(239, 68, 68);
4928
+ border: 1px solid rgba(239, 68, 68, 0.2);
4929
+ }
4930
+
4931
+ .modal-body .status-message.success {
4932
+ background: rgba(34, 197, 94, 0.1);
4933
+ color: rgb(34, 197, 94);
4934
+ border: 1px solid rgba(34, 197, 94, 0.2);
4935
+ }
4936
+
4937
+ .modal-body .loading-spinner {
4938
+ display: inline-block;
4939
+ width: 1rem;
4940
+ height: 1rem;
4941
+ border: 2px solid var(--color-border);
4942
+ border-top-color: var(--color-primary);
4943
+ border-radius: 50%;
4944
+ animation: spin 0.6s linear infinite;
4945
+ margin-right: 0.5rem;
4946
+ vertical-align: middle;
4947
+ }
4948
+
4949
+ @keyframes spin {
4950
+ to { transform: rotate(360deg); }
4951
+ }
4952
+
4953
+ .modal-body .source-type-selector {
4954
+ display: flex;
4955
+ gap: 0.5rem;
4956
+ margin-bottom: 1rem;
4957
+ padding: 0.5rem;
4958
+ background: var(--color-bg-secondary);
4959
+ border-radius: 0.25rem;
4960
+ }
4961
+
4962
+ .modal-body .source-type-option {
4963
+ flex: 1;
4964
+ padding: 0.5rem;
4965
+ border: 1px solid var(--color-border);
4966
+ border-radius: 0.25rem;
4967
+ background: var(--color-bg);
4968
+ color: var(--color-text);
4969
+ cursor: pointer;
4970
+ text-align: center;
4971
+ font-size: 0.875rem;
4972
+ transition: all 0.15s;
4973
+ }
4974
+
4975
+ .modal-body .source-type-option:hover {
4976
+ background: var(--color-border);
4977
+ }
4978
+
4979
+ .modal-body .source-type-option.active {
4980
+ background: var(--color-primary);
4981
+ border-color: var(--color-primary);
4982
+ color: #fff;
4983
+ }
4984
+
4985
+ .modal-body .source-controls {
4986
+ display: none;
4987
+ }
4988
+
4989
+ .modal-body .source-controls.active {
4990
+ display: block;
4991
+ }
4992
+
4993
+ `;
4994
+
4590
4995
  // src/playground/playground.ts
4591
- import styles2 from "./styles.css?raw";
4592
4996
  var Playground = class {
4593
4997
  options;
4594
4998
  rootElement;
@@ -4637,7 +5041,7 @@ var Playground = class {
4637
5041
  if (!document.getElementById("g3p-playground-styles")) {
4638
5042
  const styleEl = document.createElement("style");
4639
5043
  styleEl.id = "g3p-playground-styles";
4640
- styleEl.textContent = styles2;
5044
+ styleEl.textContent = styles_default2;
4641
5045
  document.head.appendChild(styleEl);
4642
5046
  }
4643
5047
  }
@@ -5385,3 +5789,4 @@ export {
5385
5789
  index_default as default,
5386
5790
  graph
5387
5791
  };
5792
+ //# sourceMappingURL=index.js.map