@joycostudio/studio 0.1.3 → 0.1.5

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/react.js CHANGED
@@ -11,10 +11,10 @@ import {
11
11
  PlugZap,
12
12
  Unplug
13
13
  } from "lucide-react";
14
- import { useEffect as useEffect5, useRef as useRef3, useState as useState8 } from "react";
14
+ import { useEffect as useEffect5, useRef as useRef3, useState as useState9 } from "react";
15
15
 
16
16
  // package.json
17
- var version = "0.1.3";
17
+ var version = "0.1.5";
18
18
 
19
19
  // src/client/studio.ts
20
20
  import {
@@ -43,6 +43,13 @@ function resetSlidersOnDoubleClick(handle) {
43
43
  return () => folder.element.removeEventListener("dblclick", onDoubleClick);
44
44
  };
45
45
  }
46
+ function everyFrame(refresh) {
47
+ let frame = requestAnimationFrame(function tick() {
48
+ refresh();
49
+ frame = requestAnimationFrame(tick);
50
+ });
51
+ return () => cancelAnimationFrame(frame);
52
+ }
46
53
  var instances = globalThis.__joycoStudio ??= /* @__PURE__ */ new Map();
47
54
 
48
55
  // src/react/hooks.ts
@@ -67,7 +74,7 @@ function useToolConfig(handle) {
67
74
  // src/react/inspector.tsx
68
75
  import { bindDebugSchema } from "@joycostudio/xyz/debug";
69
76
  import { SquareSplitHorizontal } from "lucide-react";
70
- import { useEffect, useRef, useState } from "react";
77
+ import { useEffect, useRef, useState as useState2 } from "react";
71
78
 
72
79
  // src/react/theme.ts
73
80
  var tweakpaneTheme = {
@@ -218,48 +225,126 @@ function KbdGroup({ className, ...props }) {
218
225
  }
219
226
 
220
227
  // src/react/ui/tooltip.tsx
221
- import { Tooltip as TooltipPrimitive } from "radix-ui";
222
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
223
- function TooltipProvider({ delayDuration = 0, ...props }) {
224
- return /* @__PURE__ */ jsx4(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props });
228
+ import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
229
+
230
+ // src/react/shadow-root.tsx
231
+ import { createContext, useCallback, useContext, useState } from "react";
232
+ import { createPortal } from "react-dom";
233
+
234
+ // src/react/generated/studio.css
235
+ var studio_default = `/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
236
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--color-sky-400:oklch(74.6% .16 232.661);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--radius-xs:.125rem;--radius-lg:calc(var(--radius) + 2px);--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--studio-font);--default-mono-font-family:var(--studio-font);--color-border:var(--border);--color-sidebar:var(--sidebar)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}body{background-color:var(--background);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--foreground)}}@layer components{.studio-surface{border-radius:calc(var(--radius) - 2px);background:var(--card);padding:6px}.studio-toolbar{pointer-events:auto;flex-wrap:wrap;align-items:center;gap:4px;display:flex}.studio-toolbar>button:not([data-slot=select-trigger]),.studio-toolbar [data-slot=toolbar-action]{border-radius:calc(var(--radius) - 2px);min-height:28px;color:var(--muted-foreground);font:inherit;white-space:nowrap;cursor:pointer;background:0 0;border:1px solid #0000;align-items:center;gap:6px;padding:4px 8px;font-size:11px;display:inline-flex}:is(.studio-toolbar>button:not([data-slot=select-trigger]),.studio-toolbar [data-slot=toolbar-action]):hover{color:var(--foreground);background:var(--field-hover)}:is(.studio-toolbar>button:not([data-slot=select-trigger]),.studio-toolbar [data-slot=toolbar-action]):is(:active,[aria-pressed=true]){color:var(--foreground);background:var(--field-active)}:is(.studio-toolbar>button:not([data-slot=select-trigger]),.studio-toolbar [data-slot=toolbar-action]):focus-visible{outline:2px solid var(--ring);outline-offset:2px}.studio-canvas-toolbar{z-index:20;min-width:0;color:var(--muted-foreground);pointer-events:none;flex-shrink:0;position:relative}.studio-canvas-actions{opacity:1;transition:opacity .2s ease-out,translate .2s ease-out;translate:0}.studio-canvas-toolbar[data-ghost]{position:absolute;inset:4px 4px auto}.studio-canvas-toolbar[data-ghost]:before{content:"";pointer-events:auto;height:24px;position:absolute;inset:-4px 0 auto}.studio-canvas-toolbar[data-ghost] .studio-canvas-actions{-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);opacity:0;transition-delay:3s;translate:0 calc(-100% - 8px)}.studio-canvas-toolbar[data-ghost]:is(:hover,:has(:focus-visible,[aria-expanded=true],[data-state=open])) .studio-canvas-actions{opacity:1;transition-delay:0s;translate:0}@media (hover:none){.studio-canvas-toolbar[data-ghost] .studio-canvas-actions{opacity:1;translate:0}}.studio-canvas-toolbar[data-expanded]{height:80px;position:absolute;inset:0 0 auto}.studio-canvas-toolbar[data-expanded] .studio-canvas-actions{pointer-events:none;background:0 0;height:100%;padding:0}.studio-canvas-toolbar[data-expanded] .studio-canvas-actions>:not(.studio-canvas-toggle){display:none}.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle{width:min(280px,100%);height:100%;padding-top:max(12px, env(safe-area-inset-top));pointer-events:auto;justify-content:center;align-items:flex-start;margin-inline:auto;display:flex}.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button{border-color:var(--sidebar-border);border-radius:var(--radius);min-height:30px;color:var(--foreground);background:var(--sidebar)}@supports (color:color-mix(in lab, red, red)){.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button{background:color-mix(in srgb, var(--sidebar) 85%, transparent)}}.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button{-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);font-size:inherit;opacity:0;transition:opacity .2s ease-out 3s,translate .2s ease-out 3s;translate:0 -8px;box-shadow:0 4px 12px #0006}.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button:hover{background:var(--field-hover)}.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle:hover>button,.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button:focus-visible{opacity:1;transition-delay:0s;translate:0}@media (hover:none){.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button{opacity:1;translate:0}}@media (prefers-reduced-motion:reduce){.studio-canvas-actions,.studio-canvas-toolbar[data-expanded] .studio-canvas-toggle>button{transition-duration:0s}}.studio-preview-canvas{border:1px solid var(--sidebar-border);border-radius:calc(var(--radius) + 2px);background:var(--sidebar);flex-direction:column;gap:4px;min-width:0;min-height:0;padding:4px;display:flex;position:relative;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.studio-preview-canvas{background:color-mix(in srgb, var(--sidebar) 85%, transparent)}}.studio-preview-canvas{font:12px/1.5 var(--studio-font);box-shadow:0 12px 24px #0006}.studio-preview-source{align-items:center;min-width:0;margin-right:auto;display:flex}.studio-preview-title{padding-inline:8px}.studio-preview-canvas>iframe{border-radius:calc(var(--radius) - 2px);background:var(--background);border:0;flex:1;width:100%;min-height:0}.studio-preview-canvas[data-expanded]{z-index:30;background:var(--background);border:0;border-radius:0;padding:0;position:fixed;inset:0}.studio-preview-canvas[data-expanded]>iframe{border-radius:0}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{inset-inline:0}.inset-y-0{inset-block:0}.inset-y-2{inset-block:calc(var(--spacing) * 2)}.-top-0\\.5{top:calc(var(--spacing) * -.5)}.top-0{top:0}.top-1\\/2{top:50%}.top-4{top:calc(var(--spacing) * 4)}.-right-0\\.5{right:calc(var(--spacing) * -.5)}.right-0{right:0}.right-1{right:var(--spacing)}.right-2{right:calc(var(--spacing) * 2)}.right-4{right:calc(var(--spacing) * 4)}.bottom-0{bottom:0}.left-0{left:0}.left-1{left:var(--spacing)}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mt-1{margin-top:var(--spacing)}.mt-auto{margin-top:auto}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.aspect-square{aspect-ratio:1}.size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2\\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3\\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.h-3\\.5{height:calc(var(--spacing) * 3.5)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-16{height:calc(var(--spacing) * 16)}.h-auto{height:auto}.h-full{height:100%}.h-svh{height:100svh}.max-h-\\(--available-height\\){max-height:var(--available-height)}.max-h-\\[300px\\]{max-height:300px}.min-h-0{min-height:0}.min-h-7{min-height:calc(var(--spacing) * 7)}.min-h-svh{min-height:100svh}.w-\\(--sidebar-width\\){width:var(--sidebar-width)}.w-\\(--studio-inspector-width\\){width:var(--studio-inspector-width)}.w-3\\/4{width:75%}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.max-w-full{max-width:100%}.min-w-\\(--anchor-width\\){min-width:var(--anchor-width)}.min-w-0{min-width:0}.min-w-5{min-width:calc(var(--spacing) * 5)}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.origin-\\(--transform-origin\\){transform-origin:var(--transform-origin)}.-translate-x-\\[calc\\(100\\%\\+0\\.25rem\\)\\]{--tw-translate-x:calc(calc(100% + .25rem) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-\\[calc\\(100\\%\\+1rem\\)\\]{--tw-translate-x:calc(calc(100% + 1rem) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-\\[calc\\(100\\%\\+0\\.25rem\\)\\]{--tw-translate-x:calc(100% + .25rem);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-\\[calc\\(100\\%\\+1rem\\)\\]{--tw-translate-x:calc(100% + 1rem);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\\[calc\\(-50\\%-2px\\)\\]{--tw-translate-y:calc(-50% - 2px);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-45{rotate:45deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.scroll-py-1{scroll-padding-block:var(--spacing)}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.place-items-center{place-items:center}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded-\\[2px\\]{border-radius:2px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:calc(var(--radius) + 2px)}.rounded-md{border-radius:var(--radius)}.rounded-sm{border-radius:calc(var(--radius) - 2px)}.rounded-xs{border-radius:var(--radius-xs)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-border{border-color:var(--border)}.border-input{border-color:var(--input)}.border-sidebar-border{border-color:var(--sidebar-border)}.bg-\\(--field\\){background-color:var(--field)}.bg-background{background-color:var(--background)}.bg-black\\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-current{background-color:currentColor}.bg-destructive{background-color:var(--destructive)}.bg-foreground{background-color:var(--foreground)}.bg-muted{background-color:var(--muted)}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-secondary{background-color:var(--secondary)}.bg-sidebar,.bg-sidebar\\/85{background-color:var(--sidebar)}@supports (color:color-mix(in lab, red, red)){.bg-sidebar\\/85{background-color:color-mix(in oklab, var(--sidebar) 85%, transparent)}}.bg-transparent{background-color:#0000}.bg-warning{background-color:var(--warning)}.fill-foreground{fill:var(--foreground)}.p-0{padding:0}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.px-0{padding-inline:0}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0{padding-block:0}.py-1{padding-block:var(--spacing)}.py-1\\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.ps-3{padding-inline-start:calc(var(--spacing) * 3)}.pe-3{padding-inline-end:calc(var(--spacing) * 3)}.pt-2\\.5{padding-top:calc(var(--spacing) * 2.5)}.pr-0{padding-right:0}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-5\\.5{padding-left:calc(var(--spacing) * 5.5)}.text-center{text-align:center}.text-left{text-align:left}.font-\\(family-name\\:--studio-font\\),.font-mono{font-family:var(--studio-font)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[10px\\]{font-size:10px}.text-\\[11px\\]{font-size:11px}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\\[0\\.08em\\]{--tw-tracking:.08em;letter-spacing:.08em}.text-balance{text-wrap:balance}.text-clip\\!{text-overflow:clip!important}.whitespace-nowrap{white-space:nowrap}.text-background{color:var(--background)}.text-destructive{color:var(--destructive)}.text-faint{color:var(--faint)}.text-foreground{color:var(--foreground)}.text-muted-foreground{color:var(--muted-foreground)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-sidebar-foreground{color:var(--sidebar-foreground)}.text-sidebar-primary{color:var(--sidebar-primary)}.text-sky-400{color:var(--color-sky-400)}.text-success{color:var(--success)}.text-warning{color:var(--warning)}.text-white{color:var(--color-white)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\\[0_0_0_1px_var\\(--sidebar-border\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--sidebar-border));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-black\\/40{--tw-shadow-color:#0006}@supports (color:color-mix(in lab, red, red)){.shadow-black\\/40{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 40%, transparent) var(--tw-shadow-alpha), transparent)}}.ring-sidebar-ring{--tw-ring-color:var(--sidebar-ring)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[color\\,box-shadow\\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[left\\,right\\,width\\,translate\\]{transition-property:left,right,width,translate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[left\\,right\\,width\\]{transition-property:left,right,width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[padding\\]{transition-property:padding;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[translate\\,opacity\\]{transition-property:translate,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[width\\,height\\,padding\\]{transition-property:width,height,padding;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[width\\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-linear{--tw-ease:linear;transition-timing-function:linear}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.paused{animation-play-state:paused}.running{animation-play-state:running}.group-focus-within\\/menu-item\\:opacity-100:is(:where(.group\\/menu-item):focus-within *){opacity:1}@media (hover:hover){.group-hover\\/edge\\:translate-x-0:is(:where(.group\\/edge):hover *){--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.group-hover\\/edge\\:opacity-100:is(:where(.group\\/edge):hover *),.group-hover\\/menu-item\\:opacity-100:is(:where(.group\\/menu-item):hover *){opacity:1}}.group-has-data-\\[sidebar\\=menu-action\\]\\/menu-item\\:pr-8:is(:where(.group\\/menu-item):has([data-sidebar=menu-action]) *){padding-right:calc(var(--spacing) * 8)}.group-data-\\[collapsible\\=icon\\]\\:hidden:is(:where(.group)[data-collapsible=icon] *){display:none}.group-data-\\[collapsible\\=icon\\]\\:size-8\\!:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--spacing) * 8)!important;height:calc(var(--spacing) * 8)!important}.group-data-\\[collapsible\\=icon\\]\\:w-\\(--sidebar-width-icon\\):is(:where(.group)[data-collapsible=icon] *){width:var(--sidebar-width-icon)}.group-data-\\[collapsible\\=icon\\]\\:w-\\[calc\\(var\\(--sidebar-width-icon\\)\\+\\(--spacing\\(4\\)\\)\\)\\]:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)))}.group-data-\\[collapsible\\=icon\\]\\:w-\\[calc\\(var\\(--sidebar-width-icon\\)\\+\\(--spacing\\(4\\)\\)\\+2px\\)\\]:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)) + 2px)}.group-data-\\[collapsible\\=icon\\]\\:overflow-hidden:is(:where(.group)[data-collapsible=icon] *){overflow:hidden}.group-data-\\[collapsible\\=icon\\]\\:p-0\\!:is(:where(.group)[data-collapsible=icon] *){padding:0!important}.group-data-\\[collapsible\\=icon\\]\\:p-2\\!:is(:where(.group)[data-collapsible=icon] *){padding:calc(var(--spacing) * 2)!important}.group-data-\\[collapsible\\=icon\\]\\:pl-\\[calc\\(1\\.5rem-0\\.875rem\\*352\\/144\\/2\\)\\]:is(:where(.group)[data-collapsible=icon] *){padding-left:.430556rem}.group-data-\\[collapsible\\=offcanvas\\]\\:right-\\[calc\\(var\\(--sidebar-width\\)\\*-1\\)\\]:is(:where(.group)[data-collapsible=offcanvas] *){right:calc(var(--sidebar-width) * -1)}.group-data-\\[collapsible\\=offcanvas\\]\\:left-\\[calc\\(var\\(--sidebar-width\\)\\*-1\\)\\]:is(:where(.group)[data-collapsible=offcanvas] *){left:calc(var(--sidebar-width) * -1)}.group-data-\\[collapsible\\=offcanvas\\]\\:w-0:is(:where(.group)[data-collapsible=offcanvas] *){width:0}.group-data-\\[side\\=left\\]\\:border-r:is(:where(.group)[data-side=left] *){border-right-style:var(--tw-border-style);border-right-width:1px}.group-data-\\[side\\=right\\]\\:rotate-180:is(:where(.group)[data-side=right] *){rotate:180deg}.group-data-\\[side\\=right\\]\\:border-l:is(:where(.group)[data-side=right] *){border-left-style:var(--tw-border-style);border-left-width:1px}@media (hover:hover){.peer-hover\\/menu-button\\:text-sidebar-accent-foreground:is(:where(.peer\\/menu-button):hover~*){color:var(--sidebar-accent-foreground)}}.peer-data-\\[active\\=true\\]\\/menu-button\\:text-sidebar-accent-foreground:is(:where(.peer\\/menu-button)[data-active=true]~*){color:var(--sidebar-accent-foreground)}.placeholder\\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.after\\:absolute:after{content:var(--tw-content);position:absolute}.after\\:-inset-2:after{content:var(--tw-content);inset:calc(var(--spacing) * -2)}@media (hover:hover){.hover\\:bg-\\(--field-hover\\):hover{background-color:var(--field-hover)}.hover\\:bg-accent:hover{background-color:var(--accent)}.hover\\:bg-destructive\\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-destructive\\/90:hover{background-color:color-mix(in oklab, var(--destructive) 90%, transparent)}}.hover\\:bg-primary\\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-primary\\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.hover\\:bg-secondary\\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-secondary\\/80:hover{background-color:color-mix(in oklab, var(--secondary) 80%, transparent)}}.hover\\:bg-sidebar-accent:hover{background-color:var(--sidebar-accent)}.hover\\:bg-sidebar\\/95:hover{background-color:var(--sidebar)}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-sidebar\\/95:hover{background-color:color-mix(in oklab, var(--sidebar) 95%, transparent)}}.hover\\:bg-transparent:hover{background-color:#0000}.hover\\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\\:text-foreground:hover{color:var(--foreground)}.hover\\:text-sidebar-accent-foreground:hover{color:var(--sidebar-accent-foreground)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:opacity-100:hover{opacity:1}.hover\\:shadow-\\[0_0_0_1px_var\\(--sidebar-accent\\)\\]:hover{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--sidebar-accent));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\\:translate-x-0:focus{--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.focus\\:opacity-100:focus{opacity:1}.focus\\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.focus-visible\\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\\:ring-\\[3px\\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\\:ring-destructive\\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\:ring-destructive\\/20:focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.focus-visible\\:ring-ring\\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\\:ring-ring\\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.active\\:bg-sidebar-accent:active{background-color:var(--sidebar-accent)}.active\\:bg-transparent:active{background-color:#0000}.active\\:text-sidebar-accent-foreground:active{color:var(--sidebar-accent-foreground)}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.has-data-\\[variant\\=inset\\]\\:bg-sidebar:has([data-variant=inset]){background-color:var(--sidebar)}.has-\\[\\>svg\\]\\:px-1\\.5:has(>svg){padding-inline:calc(var(--spacing) * 1.5)}.has-\\[\\>svg\\]\\:px-2\\.5:has(>svg){padding-inline:calc(var(--spacing) * 2.5)}.has-\\[\\>svg\\]\\:px-3:has(>svg){padding-inline:calc(var(--spacing) * 3)}.has-\\[\\>svg\\]\\:px-4:has(>svg){padding-inline:calc(var(--spacing) * 4)}.aria-disabled\\:pointer-events-none[aria-disabled=true]{pointer-events:none}.aria-disabled\\:opacity-50[aria-disabled=true]{opacity:.5}.aria-invalid\\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\\:ring-destructive\\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.aria-invalid\\:ring-destructive\\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.aria-pressed\\:bg-primary[aria-pressed=true]{background-color:var(--primary)}.aria-pressed\\:text-primary-foreground[aria-pressed=true]{color:var(--primary-foreground)}.data-closed\\:animate-out[data-closed]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-closed\\:duration-300[data-closed]{--tw-duration:.3s;transition-duration:.3s}.data-closed\\:fade-out-0[data-closed]{--tw-exit-opacity:0}.data-closed\\:zoom-out-95[data-closed]{--tw-exit-scale:.95}.data-closed\\:slide-out-to-bottom[data-closed]{--tw-exit-translate-y:100%}.data-closed\\:slide-out-to-left[data-closed]{--tw-exit-translate-x:-100%}.data-closed\\:slide-out-to-right[data-closed]{--tw-exit-translate-x:100%}.data-closed\\:slide-out-to-top[data-closed]{--tw-exit-translate-y:-100%}.data-open\\:animate-in[data-open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-open\\:duration-500[data-open]{--tw-duration:.5s;transition-duration:.5s}.data-open\\:fade-in-0[data-open]{--tw-enter-opacity:0}.data-open\\:zoom-in-95[data-open]{--tw-enter-scale:.95}.data-open\\:slide-in-from-bottom[data-open]{--tw-enter-translate-y:100%}.data-open\\:slide-in-from-left[data-open]{--tw-enter-translate-x:-100%}.data-open\\:slide-in-from-right[data-open]{--tw-enter-translate-x:100%}.data-open\\:slide-in-from-top[data-open]{--tw-enter-translate-y:-100%}.data-\\[active\\=true\\]\\:bg-sidebar-accent[data-active=true]{background-color:var(--sidebar-accent)}.data-\\[active\\=true\\]\\:font-medium[data-active=true]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.data-\\[active\\=true\\]\\:text-sidebar-accent-foreground[data-active=true]{color:var(--sidebar-accent-foreground)}.data-\\[disabled\\]\\:pointer-events-none[data-disabled]{pointer-events:none}.data-\\[disabled\\]\\:opacity-50[data-disabled]{opacity:.5}.data-\\[disabled\\=true\\]\\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\\[disabled\\=true\\]\\:opacity-50[data-disabled=true]{opacity:.5}.data-\\[highlighted\\]\\:bg-\\(--field-hover\\)[data-highlighted]{background-color:var(--field-hover)}.data-\\[highlighted\\]\\:text-accent-foreground[data-highlighted]{color:var(--accent-foreground)}.data-\\[instant\\]\\:animate-none[data-instant]{animation:none}.data-\\[selected\\=true\\]\\:bg-accent[data-selected=true]{background-color:var(--accent)}.data-\\[selected\\=true\\]\\:text-accent-foreground[data-selected=true]{color:var(--accent-foreground)}.data-\\[side\\=bottom\\]\\:top-1[data-side=bottom]{top:var(--spacing)}.data-\\[side\\=bottom\\]\\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:calc(2*var(--spacing)*-1)}.data-\\[side\\=left\\]\\:top-1\\/2\\![data-side=left]{top:50%!important}.data-\\[side\\=left\\]\\:-right-1[data-side=left]{right:calc(var(--spacing) * -1)}.data-\\[side\\=left\\]\\:-translate-y-1\\/2[data-side=left]{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=left\\]\\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:calc(2*var(--spacing))}.data-\\[side\\=right\\]\\:top-1\\/2\\![data-side=right]{top:50%!important}.data-\\[side\\=right\\]\\:-left-1[data-side=right]{left:calc(var(--spacing) * -1)}.data-\\[side\\=right\\]\\:-translate-y-1\\/2[data-side=right]{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\\[side\\=right\\]\\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:calc(2*var(--spacing)*-1)}.data-\\[side\\=top\\]\\:-bottom-2\\.5[data-side=top]{bottom:calc(var(--spacing) * -2.5)}.data-\\[side\\=top\\]\\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:calc(2*var(--spacing))}.data-\\[state\\=open\\]\\:opacity-100[data-state=open]{opacity:1}@media (hover:hover){.data-\\[state\\=open\\]\\:hover\\:bg-sidebar-accent[data-state=open]:hover{background-color:var(--sidebar-accent)}.data-\\[state\\=open\\]\\:hover\\:text-sidebar-accent-foreground[data-state=open]:hover{color:var(--sidebar-accent-foreground)}}@media (prefers-reduced-motion:reduce){.motion-reduce\\:transition-none{transition-property:none}}@media (min-width:40rem){.sm\\:max-w-sm{max-width:var(--container-sm)}}@media (min-width:48rem){.md\\:block{display:block}.md\\:flex{display:flex}.md\\:opacity-0{opacity:0}.md\\:after\\:hidden:after{content:var(--tw-content);display:none}}@media (prefers-color-scheme:dark){.dark\\:border-input{border-color:var(--input)}.dark\\:bg-destructive\\/60{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:bg-destructive\\/60{background-color:color-mix(in oklab, var(--destructive) 60%, transparent)}}.dark\\:bg-input\\/30{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\\:bg-input\\/30{background-color:color-mix(in oklab, var(--input) 30%, transparent)}}@media (hover:hover){.dark\\:hover\\:bg-accent\\/50:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.dark\\:hover\\:bg-accent\\/50:hover{background-color:color-mix(in oklab, var(--accent) 50%, transparent)}}.dark\\:hover\\:bg-input\\/50:hover{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\\:hover\\:bg-input\\/50:hover{background-color:color-mix(in oklab, var(--input) 50%, transparent)}}}.dark\\:focus-visible\\:ring-destructive\\/40:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:focus-visible\\:ring-destructive\\/40:focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\\:aria-invalid\\:ring-destructive\\/40[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\\:aria-invalid\\:ring-destructive\\/40[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}}.\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.\\[\\&_svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-3 svg:not([class*=size-]){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\\[\\&_svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\\[\\&_svg\\:not\\(\\[class\\*\\=\\'text-\\'\\]\\)\\]\\:text-muted-foreground svg:not([class*=text-]){color:var(--muted-foreground)}.\\[\\&\\>button\\]\\:hidden>button{display:none}.\\[\\&\\>span\\:first-child\\]\\:truncate>span:first-child,.\\[\\&\\>span\\:last-child\\]\\:truncate>span:last-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\\[\\&\\>svg\\]\\:size-3>svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\\[\\&\\>svg\\]\\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\\[\\&\\>svg\\]\\:shrink-0>svg{flex-shrink:0}@media (hover:none){.\\[\\@media\\(hover\\:none\\)\\]\\:translate-x-0{--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.\\[\\@media\\(hover\\:none\\)\\]\\:opacity-100{opacity:1}}[data-slot=tooltip-content] .\\[\\[data-slot\\=tooltip-content\\]_\\&\\]\\:bg-background\\/20{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){[data-slot=tooltip-content] .\\[\\[data-slot\\=tooltip-content\\]_\\&\\]\\:bg-background\\/20{background-color:color-mix(in oklab, var(--background) 20%, transparent)}}[data-slot=tooltip-content] .\\[\\[data-slot\\=tooltip-content\\]_\\&\\]\\:text-background{color:var(--background)}@media (prefers-color-scheme:dark){[data-slot=tooltip-content] .dark\\:\\[\\[data-slot\\=tooltip-content\\]_\\&\\]\\:bg-background\\/10{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){[data-slot=tooltip-content] .dark\\:\\[\\[data-slot\\=tooltip-content\\]_\\&\\]\\:bg-background\\/10{background-color:color-mix(in oklab, var(--background) 10%, transparent)}}}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}.studio-workspace{color:var(--foreground);background:var(--background);font:12px/1.5 var(--studio-font);cursor:default}.studio-workspace [data-slot=studio-config-file][href]{cursor:pointer;text-underline-offset:3px;text-decoration:none}.studio-workspace [data-slot=studio-config-file][href]:is(:hover,:focus-visible){text-decoration-line:underline}.studio-workspace [data-slot=studio-config-file][href]:focus-visible{outline:2px solid var(--ring);outline-offset:2px}.studio-workspace :is([data-slot=sidebar-header],[data-slot=sidebar-footer]){isolation:isolate;flex-shrink:0;position:relative}.studio-workspace :is([data-slot=sidebar-header],[data-slot=sidebar-footer]):before{content:"";z-index:-1;border-radius:calc(var(--radius-lg) - .25rem);background:var(--card);pointer-events:none;position:absolute;inset:4px}.studio-workspace [data-slot=sidebar-content] [data-slot=sidebar-menu-button]{min-height:36px;color:var(--muted-foreground);gap:10px;font-size:13px;line-height:20px}.studio-workspace [data-slot=sidebar-content] [data-slot=sidebar-menu-button]>span:first-child{flex-shrink:0;display:flex}.studio-workspace [data-slot=sidebar-content] [data-slot=sidebar-menu-button]:is(:hover,:focus-visible,[data-active=true]){color:var(--sidebar-accent-foreground)}.studio-workspace{--studio-inspector-width:20rem;--preview-left:8px;--preview-right:8px;--preview-bottom:8px;position:relative}@media (min-width:768px){.studio-workspace[data-sidebar-panel=shown]{--preview-left:var(--sidebar-width)}.studio-workspace[data-sidebar-panel=shown]:has([data-slot=sidebar][data-state=collapsed]){--preview-left:calc(var(--sidebar-width-icon) + 1rem + 2px)}}@media (min-width:1024px){.studio-workspace:has([data-slot=studio-inspector][aria-hidden=false]){--preview-right:calc(var(--studio-inspector-width) + 1rem)}}@media (max-width:1023px){.studio-workspace:is(:has(>[data-slot=preview-canvas]:not([data-expanded])),[data-preview-layout=custom]):has([data-slot=studio-inspector][aria-hidden=false]){--preview-bottom:40%}.studio-workspace:is(:has(>[data-slot=preview-canvas]:not([data-expanded])),[data-preview-layout=custom]) [data-slot=studio-inspector]{inset:calc(60% + 8px) 8px 8px var(--preview-left);width:auto}}.studio-workspace>[data-slot=preview-canvas]{z-index:0}.studio-workspace>[data-slot=preview-canvas]:not([data-expanded]){inset:8px var(--preview-right) var(--preview-bottom) var(--preview-left);position:absolute}.studio-workspace>iframe[data-slot=studio-preview]{background:var(--background);border:0;width:100%;height:100%;position:absolute;inset:0}.studio-workspace[data-preview-layout=custom]>iframe[data-slot=studio-preview]{inset:0 calc(var(--preview-right) - 8px) calc(var(--preview-bottom) - 8px) calc(var(--preview-left) - 8px);width:calc(100% - var(--preview-left) - var(--preview-right) + 16px);height:calc(100% - var(--preview-bottom) + 8px)}:root{--background:#000;--foreground:#d6d7dc;--card:#ffffff0a;--card-foreground:#d6d7dc;--popover:#18191c;--popover-foreground:#d6d7dc;--primary:#e6e7ea;--primary-foreground:#000;--secondary:#ffffff14;--secondary-foreground:#d6d7dc;--muted:#18191c;--muted-foreground:#8b8c94;--faint:#5d5e66;--accent:#18191c;--accent-foreground:#d6d7dc;--destructive:#f87171;--success:#4ade80;--warning:#facc15;--border:#26272b;--input:#26272b;--ring:#5d5e66;--radius:.5rem;--field:#ffffff0f;--field-hover:#ffffff17;--field-active:#ffffff1f;--knob:#4a4b52;--knob-hover:#5a5b63;--sidebar:#000;--sidebar-foreground:#8b8c94;--sidebar-primary:#e6e7ea;--sidebar-primary-foreground:#000;--sidebar-accent:#ffffff14;--sidebar-accent-foreground:#d6d7dc;--sidebar-border:#26272b;--sidebar-ring:#5d5e66;--studio-font:ui-monospace, SFMono-Regular, Menlo, monospace;color-scheme:dark}[data-slot=studio-controls] :is(.tp-lblv_l,.tp-fldv_t):first-letter{text-transform:uppercase}[data-slot=studio-command-overlay]{z-index:1000;background:#0000004d;position:fixed;inset:0}[data-slot=studio-command-menu]{z-index:1001;border:1px solid var(--sidebar-border);border-radius:calc(var(--radius) + 2px);background:var(--sidebar);width:min(480px,100vw - 32px);max-height:calc(100dvh - min(20vh,160px) - 16px);position:fixed;top:min(20vh,160px);left:50%;overflow:auto;transform:translate(-50%)}@supports (color:color-mix(in lab, red, red)){[data-slot=studio-command-menu]{background:color-mix(in srgb, var(--sidebar) 85%, transparent)}}[data-slot=studio-command-menu]{color:var(--foreground);color-scheme:dark;font:12px/1.5 var(--studio-font);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);box-shadow:0 20px 25px -5px #0006,0 8px 10px -6px #0006}[data-slot=studio-command-menu],[data-slot=studio-command-menu] *{box-sizing:border-box}[data-slot=studio-command-menu] svg{width:16px;height:16px;color:inherit;flex-shrink:0}[data-slot=studio-command-menu] [data-slot=kbd]{pointer-events:none;border:1px solid var(--border);border-radius:calc(var(--radius) - 2px);background:var(--muted);width:fit-content;min-width:20px;height:20px;font:inherit;color:var(--muted-foreground);-webkit-user-select:none;user-select:none;border-bottom-width:2px;justify-content:center;align-items:center;gap:4px;padding:0 4px;font-size:12px;font-weight:400;display:inline-flex}[data-slot=studio-command-menu] [data-slot=kbd-group]{align-items:center;gap:4px;display:inline-flex}[data-slot=studio-command-menu] button{font:inherit;color:inherit;cursor:pointer;background:0 0;border:0;border-radius:4px}[data-slot=studio-command-menu] button:focus-visible{outline:2px solid var(--sidebar-ring);outline-offset:2px}[data-slot=studio-command-menu] [data-slot=studio-command-heading]{align-items:center;gap:8px;height:40px;padding:0 12px 0 16px;display:flex}[data-slot=studio-command-menu] [data-slot=studio-command-heading] h2{font:inherit;flex:1;align-items:center;gap:10px;margin:0;display:flex}[data-slot=studio-command-menu] [data-slot=studio-command-heading] svg{width:auto;height:14px}[data-slot=studio-command-menu] [data-slot=studio-command-heading] strong{letter-spacing:.08em;white-space:nowrap;font-weight:700}[data-slot=studio-command-menu] [data-slot=studio-command-heading] button{padding:0}[data-slot=studio-command-menu] [data-slot=studio-command-heading] button:hover{background:var(--sidebar-accent)}[data-slot=studio-command-menu] [data-slot=studio-command-description]{display:none}[data-slot=studio-command-menu] [data-slot=command]{height:auto;color:inherit;background:0 0;flex-direction:column;display:flex;overflow:hidden}[data-slot=studio-command-menu] [data-slot=command-input-wrapper]{border-radius:var(--radius);background:var(--field);height:36px;color:var(--muted-foreground);border:1px solid #0000;align-items:center;gap:8px;margin:8px;padding:0 8px;display:flex}[data-slot=studio-command-menu] [data-slot=command-input-wrapper]:focus-within{border-color:var(--sidebar-ring)}[data-slot=studio-command-menu] [data-slot=command-input-wrapper] svg{opacity:1}[data-slot=studio-command-menu] [data-slot=command-input]{width:100%;min-width:0;height:100%;color:var(--sidebar-primary);font:inherit;background:0 0;border:0;outline:none;padding:0}[data-slot=studio-command-menu] [data-slot=command-input]::placeholder{color:var(--muted-foreground)}[data-slot=studio-command-menu] [data-slot=command-list]{overscroll-behavior:contain;max-height:300px;padding:0 8px 8px;scroll-padding:4px;overflow-y:auto}[data-slot=studio-command-menu] [data-slot=command-item]{border-radius:calc(var(--radius) - 2px);min-height:36px;font:inherit;color:var(--sidebar-foreground);cursor:pointer;align-items:center;gap:8px;padding:8px;display:flex}[data-slot=studio-command-menu] [data-slot=command-item][data-selected=true]{background:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}[data-slot=studio-command-menu] [data-slot=studio-command-label]{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}[data-slot=studio-command-menu] [data-slot=command-empty]{text-align:center;font:inherit;color:var(--muted-foreground);padding:24px 8px}[data-slot=studio-command-menu] [data-slot=studio-command-footer]{border-top:1px solid var(--sidebar-border);color:var(--muted-foreground);align-items:center;gap:16px;padding:8px 12px;font-size:10px;display:flex}[data-slot=studio-command-menu] [data-slot=studio-command-footer]>span{align-items:center;gap:6px;display:inline-flex}[data-studio-root]{all:initial;color:var(--foreground);font:12px/1.5 var(--studio-font);color-scheme:dark;display:contents}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}`;
237
+
238
+ // src/react/shadow-css.ts
239
+ var ROOT_FONT_SIZE = 16;
240
+ function toShadowCss(css) {
241
+ const defaults = [...css.matchAll(/@property\s*(--[\w-]+)\s*\{([^}]*)\}/g)].flatMap(([, name, body]) => {
242
+ const value = /initial-value:\s*([^;}]+)/.exec(body)?.[1]?.trim();
243
+ return value ? [`${name}:${value}`] : [];
244
+ });
245
+ const scoped = css.replace(/(^|[{};])\s*:root(?:\s*,\s*:host)?\s*\{/g, "$1[data-studio-root]{");
246
+ const pinned = scoped.replace(
247
+ /[^{};]+(?=[;}])/g,
248
+ (declaration) => declaration.replace(/(?<![\w.\\])(-?\d*\.?\d+)rem\b/g, (_, value) => `${+value * ROOT_FONT_SIZE}px`)
249
+ );
250
+ if (!defaults.length) return pinned;
251
+ return `${pinned}
252
+ @layer properties{*,::before,::after,::backdrop{${defaults.join(";")}}}`;
253
+ }
254
+
255
+ // src/react/shadow-root.tsx
256
+ import { jsx as jsx4 } from "react/jsx-runtime";
257
+ var sheet;
258
+ function studioStyleSheet() {
259
+ if (!sheet) {
260
+ sheet = new CSSStyleSheet();
261
+ sheet.replaceSync(toShadowCss(studio_default));
262
+ }
263
+ return sheet;
264
+ }
265
+ var PortalContainer = createContext(null);
266
+ var usePortalContainer = () => useContext(PortalContainer) ?? void 0;
267
+ function StudioShadowRoot({ children }) {
268
+ const [root, setRoot] = useState(null);
269
+ const attach = useCallback((host) => {
270
+ if (!host) return;
271
+ let shadow = host.shadowRoot;
272
+ if (!shadow) {
273
+ shadow = host.attachShadow({ mode: "open" });
274
+ shadow.adoptedStyleSheets = [studioStyleSheet()];
275
+ const container = document.createElement("div");
276
+ container.setAttribute("data-studio-root", "");
277
+ shadow.append(container);
278
+ }
279
+ setRoot(shadow.querySelector("[data-studio-root]"));
280
+ }, []);
281
+ return (
282
+ // `display: contents` keeps the host out of layout; inline so host stylesheets can't override it.
283
+ /* @__PURE__ */ jsx4("div", { ref: attach, "data-studio-host": "", style: { display: "contents" }, children: root && createPortal(/* @__PURE__ */ jsx4(PortalContainer.Provider, { value: root, children }), root) })
284
+ );
285
+ }
286
+ function activeElement() {
287
+ let element = document.activeElement;
288
+ while (element?.shadowRoot?.activeElement) element = element.shadowRoot.activeElement;
289
+ return element;
290
+ }
291
+ var eventTarget = (event) => event.composedPath()[0] ?? event.target;
292
+
293
+ // src/react/ui/tooltip.tsx
294
+ import { jsx as jsx5, jsxs } from "react/jsx-runtime";
295
+ function TooltipProvider({ delay = 0, ...props }) {
296
+ return /* @__PURE__ */ jsx5(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delay, ...props });
225
297
  }
226
298
  function Tooltip({ ...props }) {
227
- return /* @__PURE__ */ jsx4(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
299
+ return /* @__PURE__ */ jsx5(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
228
300
  }
229
301
  function TooltipTrigger({ ...props }) {
230
- return /* @__PURE__ */ jsx4(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
302
+ return /* @__PURE__ */ jsx5(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
231
303
  }
232
304
  function TooltipContent({
233
305
  className,
306
+ side = "top",
234
307
  sideOffset = 0,
308
+ align = "center",
309
+ alignOffset = 0,
235
310
  children,
236
311
  ...props
237
312
  }) {
238
- return /* @__PURE__ */ jsx4(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
239
- TooltipPrimitive.Content,
313
+ return /* @__PURE__ */ jsx5(TooltipPrimitive.Portal, { container: usePortalContainer(), children: /* @__PURE__ */ jsx5(
314
+ TooltipPrimitive.Positioner,
240
315
  {
241
- "data-slot": "tooltip-content",
316
+ align,
317
+ alignOffset,
318
+ side,
242
319
  sideOffset,
243
- className: cn(
244
- "z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
245
- className
246
- ),
247
- ...props,
248
- children: [
249
- children,
250
- /* @__PURE__ */ jsx4(TooltipPrimitive.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" })
251
- ]
320
+ className: "isolate z-50",
321
+ children: /* @__PURE__ */ jsxs(
322
+ TooltipPrimitive.Popup,
323
+ {
324
+ "data-slot": "tooltip-content",
325
+ className: cn(
326
+ "z-50 w-fit origin-(--transform-origin) rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[instant]:animate-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
327
+ className
328
+ ),
329
+ ...props,
330
+ children: [
331
+ children,
332
+ /* @__PURE__ */ jsx5(TooltipPrimitive.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" })
333
+ ]
334
+ }
335
+ )
252
336
  }
253
337
  ) });
254
338
  }
255
339
  function Hint({
256
340
  children,
257
341
  content,
342
+ disabled,
258
343
  ...props
259
344
  }) {
260
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
261
- /* @__PURE__ */ jsx4(TooltipTrigger, { asChild: true, children }),
262
- /* @__PURE__ */ jsx4(TooltipContent, { ...props, children: content })
345
+ return /* @__PURE__ */ jsxs(Tooltip, { disabled, children: [
346
+ /* @__PURE__ */ jsx5(TooltipTrigger, { render: children }),
347
+ /* @__PURE__ */ jsx5(TooltipContent, { ...props, children: content })
263
348
  ] });
264
349
  }
265
350
 
@@ -270,22 +355,22 @@ import { forwardRef as forwardRef2 } from "react";
270
355
  // src/react/surface.tsx
271
356
  import { Slot as Slot2 } from "radix-ui";
272
357
  import { forwardRef } from "react";
273
- import { jsx as jsx5 } from "react/jsx-runtime";
358
+ import { jsx as jsx6 } from "react/jsx-runtime";
274
359
  var StudioSurface = forwardRef(
275
360
  function StudioSurface2({ asChild = false, className, ...props }, ref) {
276
361
  const Comp = asChild ? Slot2.Root : "div";
277
- return /* @__PURE__ */ jsx5(Comp, { ref, "data-slot": "studio-surface", className: cn("studio-surface", className), ...props });
362
+ return /* @__PURE__ */ jsx6(Comp, { ref, "data-slot": "studio-surface", className: cn("studio-surface", className), ...props });
278
363
  }
279
364
  );
280
365
  var StudioToolbar = forwardRef(function StudioToolbar2({ className, ...props }, ref) {
281
- return /* @__PURE__ */ jsx5(StudioSurface, { ref, role: "group", className: cn("studio-toolbar", className), ...props });
366
+ return /* @__PURE__ */ jsx6(StudioSurface, { ref, role: "group", className: cn("studio-toolbar", className), ...props });
282
367
  });
283
368
 
284
369
  // src/react/ui/panel.tsx
285
- import { jsx as jsx6 } from "react/jsx-runtime";
370
+ import { jsx as jsx7 } from "react/jsx-runtime";
286
371
  var Panel = forwardRef2(function Panel2({ className, asChild = false, ...props }, ref) {
287
372
  const Comp = asChild ? Slot3.Root : "div";
288
- return /* @__PURE__ */ jsx6(
373
+ return /* @__PURE__ */ jsx7(
289
374
  Comp,
290
375
  {
291
376
  ref,
@@ -299,10 +384,10 @@ var Panel = forwardRef2(function Panel2({ className, asChild = false, ...props }
299
384
  );
300
385
  });
301
386
  function PanelHeader({ className, ...props }) {
302
- return /* @__PURE__ */ jsx6(StudioSurface, { asChild: true, className: cn("px-3 pt-2.5 pb-2", className), children: /* @__PURE__ */ jsx6("header", { "data-slot": "panel-header", ...props }) });
387
+ return /* @__PURE__ */ jsx7(StudioSurface, { asChild: true, className: cn("px-3 pt-2.5 pb-2", className), children: /* @__PURE__ */ jsx7("header", { "data-slot": "panel-header", ...props }) });
303
388
  }
304
389
  var PanelContent = forwardRef2(function PanelContent2({ className, ...props }, ref) {
305
- return /* @__PURE__ */ jsx6(
390
+ return /* @__PURE__ */ jsx7(
306
391
  "div",
307
392
  {
308
393
  ref,
@@ -313,20 +398,27 @@ var PanelContent = forwardRef2(function PanelContent2({ className, ...props }, r
313
398
  );
314
399
  });
315
400
  function PanelFooter({ className, ...props }) {
316
- return /* @__PURE__ */ jsx6(StudioSurface, { asChild: true, className: cn("grid gap-2 p-2", className), children: /* @__PURE__ */ jsx6("footer", { "data-slot": "panel-footer", ...props }) });
401
+ return /* @__PURE__ */ jsx7(StudioSurface, { asChild: true, className: cn("grid gap-2 p-2", className), children: /* @__PURE__ */ jsx7("footer", { "data-slot": "panel-footer", ...props }) });
317
402
  }
318
403
 
319
404
  // src/react/inspector.tsx
320
- import { Fragment, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
405
+ import { Fragment, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
321
406
  function describe(studio, handle) {
322
407
  const { state } = handle;
323
408
  if (handle.comparing) return { tone: "text-sky-400", text: "Showing saved" };
324
409
  if (studio.connection.phase !== "connected") return { tone: "text-faint", text: "Not persisting" };
325
410
  if (!state) return { tone: "text-destructive", text: "Restart studio dev" };
326
411
  if (state.conflict) return { tone: "text-destructive", text: "Changed on disk" };
327
- if (state.dirty) return { tone: "text-warning", text: "Unsaved" };
412
+ if (handle.dirty) return { tone: "text-warning", text: "Unsaved" };
328
413
  return { tone: "text-success", text: state.saved.hash ? "Saved" : "Not on disk yet" };
329
414
  }
415
+ function adoptTweakpaneStyles(container) {
416
+ const root = container.getRootNode();
417
+ if (!(root instanceof ShadowRoot)) return;
418
+ for (const style of document.head.querySelectorAll("style[data-tp-style]")) {
419
+ if (!root.querySelector(`style[data-tp-style="${style.dataset.tpStyle}"]`)) root.append(style.cloneNode(true));
420
+ }
421
+ }
330
422
  function Inspector({
331
423
  studio,
332
424
  handle,
@@ -336,9 +428,11 @@ function Inspector({
336
428
  useStudio(studio);
337
429
  const container = useRef(null);
338
430
  const pane = useRef(null);
339
- const [failure, setFailure] = useState(null);
340
- const run = (action) => void action.then((result) => setFailure(result.ok ? null : result.message ?? result.error));
341
- const save = (force = false) => run(handle.save({ force }));
431
+ const [failure, setFailure] = useState2(null);
432
+ const { definition, state } = handle;
433
+ const canDiscard = handle.dirty && !handle.comparing;
434
+ const canSave = canDiscard && !!state;
435
+ const save = (force = false) => void handle.save({ force }).then((result) => setFailure(result.ok ? null : result.message ?? result.error));
342
436
  useEffect(() => {
343
437
  let disposed = false;
344
438
  let teardown = () => {
@@ -351,6 +445,7 @@ function Inspector({
351
445
  schema: () => handle.controls(),
352
446
  extend: resetSlidersOnDoubleClick(handle)
353
447
  });
448
+ adoptTweakpaneStyles(container.current);
354
449
  const unsubscribe = handle.subscribe(() => bound.refresh());
355
450
  teardown = () => {
356
451
  unsubscribe();
@@ -368,7 +463,7 @@ function Inspector({
368
463
  const onKeyDown = (event) => {
369
464
  if (event.key !== "s" || !(event.metaKey || event.ctrlKey)) return;
370
465
  event.preventDefault();
371
- if (handle.state?.dirty) save();
466
+ if (canSave) save();
372
467
  };
373
468
  addEventListener("keydown", onKeyDown);
374
469
  return () => removeEventListener("keydown", onKeyDown);
@@ -376,21 +471,19 @@ function Inspector({
376
471
  useEffect(() => {
377
472
  if (pane.current) pane.current.disabled = handle.comparing;
378
473
  });
379
- const { definition, state } = handle;
380
474
  const ConfigFile = fileHref ? "a" : "span";
381
475
  const status = describe(studio, handle);
382
- const editable2 = studio.connection.phase === "connected" && !!state?.dirty && !handle.comparing;
383
476
  const changes = handle.changes.map(
384
477
  (path) => path.split(".").map((key) => key.charAt(0).toUpperCase() + key.slice(1)).join(" \u203A ")
385
478
  );
386
479
  return /* @__PURE__ */ jsxs2(Fragment, { children: [
387
480
  /* @__PURE__ */ jsxs2(PanelHeader, { children: [
388
481
  /* @__PURE__ */ jsxs2("strong", { className: "flex min-w-0 items-center gap-2 text-foreground", children: [
389
- /* @__PURE__ */ jsx7(ToolIcon, { icon: definition.icon, className: "size-3.5 shrink-0" }),
390
- /* @__PURE__ */ jsx7("span", { className: "truncate", title: definition.title ?? definition.id, children: definition.title ?? definition.id })
482
+ /* @__PURE__ */ jsx8(ToolIcon, { icon: definition.icon, className: "size-3.5 shrink-0" }),
483
+ /* @__PURE__ */ jsx8("span", { className: "truncate", title: definition.title ?? definition.id, children: definition.title ?? definition.id })
391
484
  ] }),
392
485
  /* @__PURE__ */ jsxs2("div", { className: "mt-1 flex items-center gap-3 pl-5.5 text-[11px]", children: [
393
- /* @__PURE__ */ jsx7(
486
+ /* @__PURE__ */ jsx8(
394
487
  ConfigFile,
395
488
  {
396
489
  "data-slot": "studio-config-file",
@@ -406,31 +499,31 @@ function Inspector({
406
499
  className: `flex shrink-0 items-center gap-1.5 ${status.tone}`,
407
500
  title: state ? `Draft revision ${state.draft.revision}` : void 0,
408
501
  children: [
409
- /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", className: "size-1.5 rounded-full bg-current" }),
502
+ /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "size-1.5 rounded-full bg-current" }),
410
503
  status.text
411
504
  ]
412
505
  }
413
506
  )
414
507
  ] })
415
508
  ] }),
416
- /* @__PURE__ */ jsx7(PanelContent, { ref: container, "data-slot": "studio-controls", style: tweakpaneTheme }),
509
+ /* @__PURE__ */ jsx8(PanelContent, { ref: container, "data-slot": "studio-controls", style: tweakpaneTheme }),
417
510
  /* @__PURE__ */ jsxs2(PanelFooter, { children: [
418
- failure && /* @__PURE__ */ jsx7("div", { className: "text-destructive", children: failure }),
511
+ failure && /* @__PURE__ */ jsx8("div", { className: "text-destructive", children: failure }),
419
512
  changes.length > 0 && /* @__PURE__ */ jsxs2("div", { className: "truncate text-muted-foreground", title: changes.join(", "), children: [
420
513
  changes.length,
421
514
  " changed: ",
422
- /* @__PURE__ */ jsx7("span", { className: "text-foreground", children: changes.join(", ") })
515
+ /* @__PURE__ */ jsx8("span", { className: "text-foreground", children: changes.join(", ") })
423
516
  ] }),
424
517
  /* @__PURE__ */ jsxs2("div", { className: "flex gap-2", children: [
425
- /* @__PURE__ */ jsx7(
518
+ /* @__PURE__ */ jsx8(
426
519
  Hint,
427
520
  {
428
521
  className: "flex items-center gap-2",
429
522
  content: /* @__PURE__ */ jsxs2(Fragment, { children: [
430
523
  "Hold to compare with saved ",
431
- /* @__PURE__ */ jsx7(Kbd, { children: "\\" })
524
+ /* @__PURE__ */ jsx8(Kbd, { children: "\\" })
432
525
  ] }),
433
- children: /* @__PURE__ */ jsx7(
526
+ children: /* @__PURE__ */ jsx8(
434
527
  Button,
435
528
  {
436
529
  variant: "secondary",
@@ -445,27 +538,30 @@ function Inspector({
445
538
  },
446
539
  onPointerUp: () => onCompare(false),
447
540
  onPointerCancel: () => onCompare(false),
448
- children: /* @__PURE__ */ jsx7(SquareSplitHorizontal, {})
541
+ children: /* @__PURE__ */ jsx8(SquareSplitHorizontal, {})
449
542
  }
450
543
  )
451
544
  }
452
545
  ),
453
- /* @__PURE__ */ jsx7(
546
+ /* @__PURE__ */ jsx8(
454
547
  Button,
455
548
  {
456
549
  variant: "secondary",
457
550
  size: "sm",
458
551
  className: "flex-1",
459
- disabled: !editable2,
460
- onClick: () => run(handle.discard()),
552
+ disabled: !canDiscard,
553
+ onClick: () => {
554
+ setFailure(null);
555
+ handle.discard();
556
+ },
461
557
  children: "Discard"
462
558
  }
463
559
  ),
464
- state?.conflict ? /* @__PURE__ */ jsx7(Button, { variant: "destructive", size: "sm", className: "flex-1", onClick: () => save(true), children: "Overwrite file" }) : /* @__PURE__ */ jsxs2(Button, { size: "sm", className: "flex-1", disabled: !editable2, onClick: () => save(), children: [
560
+ state?.conflict ? /* @__PURE__ */ jsx8(Button, { variant: "destructive", size: "sm", className: "flex-1", onClick: () => save(true), children: "Overwrite file" }) : /* @__PURE__ */ jsxs2(Button, { size: "sm", className: "flex-1", disabled: !canSave, onClick: () => save(), children: [
465
561
  "Save",
466
562
  /* @__PURE__ */ jsxs2(KbdGroup, { children: [
467
- /* @__PURE__ */ jsx7(Kbd, { children: "\u2318" }),
468
- /* @__PURE__ */ jsx7(Kbd, { children: "S" })
563
+ /* @__PURE__ */ jsx8(Kbd, { children: "\u2318" }),
564
+ /* @__PURE__ */ jsx8(Kbd, { children: "S" })
469
565
  ] })
470
566
  ] })
471
567
  ] })
@@ -474,13 +570,13 @@ function Inspector({
474
570
  }
475
571
 
476
572
  // src/react/logo.tsx
477
- import { jsx as jsx8 } from "react/jsx-runtime";
573
+ import { jsx as jsx9 } from "react/jsx-runtime";
478
574
  function Logo(props) {
479
- return /* @__PURE__ */ jsx8("svg", { viewBox: "0 0 352 144", fill: "currentColor", "aria-label": "JOYCO", role: "img", ...props, children: /* @__PURE__ */ jsx8("path", { d: "M328 96L280 144H0V40H176V112H192V24H0V0H352V24H328V96Z" }) });
575
+ return /* @__PURE__ */ jsx9("svg", { viewBox: "0 0 352 144", fill: "currentColor", "aria-label": "JOYCO", role: "img", ...props, children: /* @__PURE__ */ jsx9("path", { d: "M328 96L280 144H0V40H176V112H192V24H0V0H352V24H328V96Z" }) });
480
576
  }
481
577
 
482
578
  // src/react/pinned-tools.ts
483
- import { useEffect as useEffect2, useState as useState2 } from "react";
579
+ import { useEffect as useEffect2, useState as useState3 } from "react";
484
580
  var STORAGE_KEY = "joyco-studio:pinned-tools";
485
581
  var CHANGE_EVENT = "joyco-studio:pins-changed";
486
582
  function readPins() {
@@ -492,7 +588,7 @@ function readPins() {
492
588
  }
493
589
  }
494
590
  function usePinnedTools(studio) {
495
- const [pins, setPins] = useState2([]);
591
+ const [pins, setPins] = useState3([]);
496
592
  useEffect2(() => {
497
593
  setPins(readPins());
498
594
  const onChange = (event) => setPins(event.detail);
@@ -521,17 +617,17 @@ function usePinnedTools(studio) {
521
617
 
522
618
  // src/react/preview-canvas.tsx
523
619
  import { RotateCw } from "lucide-react";
524
- import { forwardRef as forwardRef3, useImperativeHandle, useRef as useRef2, useState as useState4 } from "react";
620
+ import { forwardRef as forwardRef3, useImperativeHandle, useRef as useRef2, useState as useState5 } from "react";
525
621
 
526
622
  // src/react/canvas-toolbar.tsx
527
623
  import { Maximize, Minimize, Pin, PinOff } from "lucide-react";
528
- import { useState as useState3 } from "react";
529
- import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
624
+ import { useState as useState4 } from "react";
625
+ import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
530
626
  function CanvasToolbar({ label, expanded = false, onToggle, children }) {
531
- const [ghost, setGhost] = useState3(false);
627
+ const [ghost, setGhost] = useState4(false);
532
628
  const ExpandIcon = expanded ? Minimize : Maximize;
533
629
  const PinIcon = ghost ? PinOff : Pin;
534
- return /* @__PURE__ */ jsx9(
630
+ return /* @__PURE__ */ jsx10(
535
631
  "div",
536
632
  {
537
633
  className: "studio-canvas-toolbar",
@@ -542,11 +638,11 @@ function CanvasToolbar({ label, expanded = false, onToggle, children }) {
542
638
  "aria-label": label,
543
639
  children: /* @__PURE__ */ jsxs3(StudioToolbar, { className: "studio-canvas-actions", children: [
544
640
  children,
545
- onToggle && /* @__PURE__ */ jsx9("div", { className: "studio-canvas-toggle", children: /* @__PURE__ */ jsxs3("button", { "data-slot": "toolbar-action", type: "button", "aria-pressed": expanded, onClick: onToggle, children: [
546
- /* @__PURE__ */ jsx9(ExpandIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true }),
641
+ onToggle && /* @__PURE__ */ jsx10("div", { className: "studio-canvas-toggle", children: /* @__PURE__ */ jsxs3("button", { "data-slot": "toolbar-action", type: "button", "aria-pressed": expanded, onClick: onToggle, children: [
642
+ /* @__PURE__ */ jsx10(ExpandIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true }),
547
643
  expanded ? "Contain canvas" : "Expand"
548
644
  ] }) }),
549
- !expanded && /* @__PURE__ */ jsx9(
645
+ !expanded && /* @__PURE__ */ jsx10(
550
646
  "button",
551
647
  {
552
648
  type: "button",
@@ -554,7 +650,7 @@ function CanvasToolbar({ label, expanded = false, onToggle, children }) {
554
650
  "aria-pressed": ghost,
555
651
  title: ghost ? "Pin header" : "Auto-hide header",
556
652
  onClick: () => setGhost(!ghost),
557
- children: /* @__PURE__ */ jsx9(PinIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
653
+ children: /* @__PURE__ */ jsx10(PinIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
558
654
  }
559
655
  )
560
656
  ] })
@@ -563,9 +659,9 @@ function CanvasToolbar({ label, expanded = false, onToggle, children }) {
563
659
  }
564
660
 
565
661
  // src/react/preview-canvas.tsx
566
- import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
662
+ import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
567
663
  var PreviewCanvas = forwardRef3(function PreviewCanvas2({ title = "Preview", expanded: controlled, onExpandedChange, onReload, toolbar, ...props }, ref) {
568
- const [localExpanded, setExpanded] = useState4(false);
664
+ const [localExpanded, setExpanded] = useState5(false);
569
665
  const expanded = controlled ?? localExpanded;
570
666
  const frame = useRef2(null);
571
667
  useImperativeHandle(ref, () => frame.current, []);
@@ -587,7 +683,7 @@ var PreviewCanvas = forwardRef3(function PreviewCanvas2({ title = "Preview", exp
587
683
  onExpandedChange?.(!expanded);
588
684
  },
589
685
  children: [
590
- /* @__PURE__ */ jsx10(
686
+ /* @__PURE__ */ jsx11(
591
687
  "button",
592
688
  {
593
689
  type: "button",
@@ -597,23 +693,23 @@ var PreviewCanvas = forwardRef3(function PreviewCanvas2({ title = "Preview", exp
597
693
  onReload?.();
598
694
  if (frame.current) frame.current.src = frame.current.src;
599
695
  },
600
- children: /* @__PURE__ */ jsx10(RotateCw, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
696
+ children: /* @__PURE__ */ jsx11(RotateCw, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
601
697
  }
602
698
  ),
603
- /* @__PURE__ */ jsx10("div", { className: "studio-preview-source", children: toolbar ?? /* @__PURE__ */ jsx10("span", { className: "studio-preview-title", children: title }) })
699
+ /* @__PURE__ */ jsx11("div", { className: "studio-preview-source", children: toolbar ?? /* @__PURE__ */ jsx11("span", { className: "studio-preview-title", children: title }) })
604
700
  ]
605
701
  }
606
702
  ),
607
- /* @__PURE__ */ jsx10("iframe", { ...props, ref: frame, title })
703
+ /* @__PURE__ */ jsx11("iframe", { ...props, ref: frame, title })
608
704
  ]
609
705
  }
610
706
  );
611
707
  });
612
708
 
613
709
  // src/react/session-flag.ts
614
- import { useEffect as useEffect3, useState as useState5 } from "react";
710
+ import { useEffect as useEffect3, useState as useState6 } from "react";
615
711
  function useSessionFlag(key) {
616
- const [value, setValue] = useState5(() => {
712
+ const [value, setValue] = useState6(() => {
617
713
  try {
618
714
  return sessionStorage.getItem(key) === "true";
619
715
  } catch {
@@ -653,21 +749,21 @@ function useIsMobile() {
653
749
 
654
750
  // src/react/ui/sheet.tsx
655
751
  import { XIcon } from "lucide-react";
656
- import { Dialog as SheetPrimitive } from "radix-ui";
657
- import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
752
+ import { Dialog as SheetPrimitive } from "@base-ui/react/dialog";
753
+ import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
658
754
  function Sheet({ ...props }) {
659
- return /* @__PURE__ */ jsx11(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
755
+ return /* @__PURE__ */ jsx12(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
660
756
  }
661
757
  function SheetPortal({ ...props }) {
662
- return /* @__PURE__ */ jsx11(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
758
+ return /* @__PURE__ */ jsx12(SheetPrimitive.Portal, { "data-slot": "sheet-portal", container: usePortalContainer(), ...props });
663
759
  }
664
760
  function SheetOverlay({ className, ...props }) {
665
- return /* @__PURE__ */ jsx11(
666
- SheetPrimitive.Overlay,
761
+ return /* @__PURE__ */ jsx12(
762
+ SheetPrimitive.Backdrop,
667
763
  {
668
764
  "data-slot": "sheet-overlay",
669
765
  className: cn(
670
- "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
766
+ "fixed inset-0 z-50 bg-black/50 data-closed:animate-out data-closed:fade-out-0 data-open:animate-in data-open:fade-in-0",
671
767
  className
672
768
  ),
673
769
  ...props
@@ -682,25 +778,25 @@ function SheetContent({
682
778
  ...props
683
779
  }) {
684
780
  return /* @__PURE__ */ jsxs5(SheetPortal, { children: [
685
- /* @__PURE__ */ jsx11(SheetOverlay, {}),
781
+ /* @__PURE__ */ jsx12(SheetOverlay, {}),
686
782
  /* @__PURE__ */ jsxs5(
687
- SheetPrimitive.Content,
783
+ SheetPrimitive.Popup,
688
784
  {
689
785
  "data-slot": "sheet-content",
690
786
  className: cn(
691
- "fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500",
692
- side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
693
- side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
694
- side === "top" && "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
695
- side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
787
+ "fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-closed:animate-out data-closed:duration-300 data-open:animate-in data-open:duration-500",
788
+ side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-closed:slide-out-to-right data-open:slide-in-from-right sm:max-w-sm",
789
+ side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-closed:slide-out-to-left data-open:slide-in-from-left sm:max-w-sm",
790
+ side === "top" && "inset-x-0 top-0 h-auto border-b data-closed:slide-out-to-top data-open:slide-in-from-top",
791
+ side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-closed:slide-out-to-bottom data-open:slide-in-from-bottom",
696
792
  className
697
793
  ),
698
794
  ...props,
699
795
  children: [
700
796
  children,
701
- showCloseButton && /* @__PURE__ */ jsxs5(SheetPrimitive.Close, { className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
702
- /* @__PURE__ */ jsx11(XIcon, { className: "size-4" }),
703
- /* @__PURE__ */ jsx11("span", { className: "sr-only", children: "Close" })
797
+ showCloseButton && /* @__PURE__ */ jsxs5(SheetPrimitive.Close, { className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none", children: [
798
+ /* @__PURE__ */ jsx12(XIcon, { className: "size-4" }),
799
+ /* @__PURE__ */ jsx12("span", { className: "sr-only", children: "Close" })
704
800
  ] })
705
801
  ]
706
802
  }
@@ -708,10 +804,10 @@ function SheetContent({
708
804
  ] });
709
805
  }
710
806
  function SheetHeader({ className, ...props }) {
711
- return /* @__PURE__ */ jsx11("div", { "data-slot": "sheet-header", className: cn("flex flex-col gap-1.5 p-4", className), ...props });
807
+ return /* @__PURE__ */ jsx12("div", { "data-slot": "sheet-header", className: cn("flex flex-col gap-1.5 p-4", className), ...props });
712
808
  }
713
809
  function SheetTitle({ className, ...props }) {
714
- return /* @__PURE__ */ jsx11(
810
+ return /* @__PURE__ */ jsx12(
715
811
  SheetPrimitive.Title,
716
812
  {
717
813
  "data-slot": "sheet-title",
@@ -721,7 +817,7 @@ function SheetTitle({ className, ...props }) {
721
817
  );
722
818
  }
723
819
  function SheetDescription({ className, ...props }) {
724
- return /* @__PURE__ */ jsx11(
820
+ return /* @__PURE__ */ jsx12(
725
821
  SheetPrimitive.Description,
726
822
  {
727
823
  "data-slot": "sheet-description",
@@ -732,12 +828,12 @@ function SheetDescription({ className, ...props }) {
732
828
  }
733
829
 
734
830
  // src/react/ui/sidebar.tsx
735
- import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
831
+ import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
736
832
  var SIDEBAR_COOKIE_NAME = "sidebar_state";
737
833
  var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
738
- var SIDEBAR_WIDTH = "16rem";
739
- var SIDEBAR_WIDTH_MOBILE = "18rem";
740
- var SIDEBAR_WIDTH_ICON = "3rem";
834
+ var SIDEBAR_WIDTH = "256px";
835
+ var SIDEBAR_WIDTH_MOBILE = "288px";
836
+ var SIDEBAR_WIDTH_ICON = "48px";
741
837
  var SidebarContext = React2.createContext(null);
742
838
  function useSidebar() {
743
839
  const context = React2.useContext(SidebarContext);
@@ -787,7 +883,7 @@ function SidebarProvider({
787
883
  }),
788
884
  [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
789
885
  );
790
- return /* @__PURE__ */ jsx12(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx12(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx12(
886
+ return /* @__PURE__ */ jsx13(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx13(TooltipProvider, { delay: 0, children: /* @__PURE__ */ jsx13(
791
887
  "div",
792
888
  {
793
889
  "data-slot": "sidebar-wrapper",
@@ -813,7 +909,7 @@ function Sidebar({
813
909
  const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
814
910
  const Surface = variant === "floating" ? Panel : "div";
815
911
  if (collapsible === "none") {
816
- return /* @__PURE__ */ jsx12(
912
+ return /* @__PURE__ */ jsx13(
817
913
  "div",
818
914
  {
819
915
  "data-slot": "sidebar",
@@ -824,7 +920,7 @@ function Sidebar({
824
920
  );
825
921
  }
826
922
  if (isMobile) {
827
- return /* @__PURE__ */ jsx12(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs6(
923
+ return /* @__PURE__ */ jsx13(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs6(
828
924
  SheetContent,
829
925
  {
830
926
  "data-sidebar": "sidebar",
@@ -837,10 +933,10 @@ function Sidebar({
837
933
  side,
838
934
  children: [
839
935
  /* @__PURE__ */ jsxs6(SheetHeader, { className: "sr-only", children: [
840
- /* @__PURE__ */ jsx12(SheetTitle, { children: "Sidebar" }),
841
- /* @__PURE__ */ jsx12(SheetDescription, { children: "Displays the mobile sidebar." })
936
+ /* @__PURE__ */ jsx13(SheetTitle, { children: "Sidebar" }),
937
+ /* @__PURE__ */ jsx13(SheetDescription, { children: "Displays the mobile sidebar." })
842
938
  ] }),
843
- /* @__PURE__ */ jsx12("div", { className: "flex h-full w-full flex-col", children })
939
+ /* @__PURE__ */ jsx13("div", { className: "flex h-full w-full flex-col", children })
844
940
  ]
845
941
  }
846
942
  ) });
@@ -855,7 +951,7 @@ function Sidebar({
855
951
  "data-side": side,
856
952
  "data-slot": "sidebar",
857
953
  children: [
858
- /* @__PURE__ */ jsx12(
954
+ /* @__PURE__ */ jsx13(
859
955
  "div",
860
956
  {
861
957
  "data-slot": "sidebar-gap",
@@ -867,7 +963,7 @@ function Sidebar({
867
963
  )
868
964
  }
869
965
  ),
870
- /* @__PURE__ */ jsx12(
966
+ /* @__PURE__ */ jsx13(
871
967
  "div",
872
968
  {
873
969
  "data-slot": "sidebar-container",
@@ -879,7 +975,7 @@ function Sidebar({
879
975
  className
880
976
  ),
881
977
  ...props,
882
- children: /* @__PURE__ */ jsx12(
978
+ children: /* @__PURE__ */ jsx13(
883
979
  Surface,
884
980
  {
885
981
  "data-sidebar": "sidebar",
@@ -895,7 +991,7 @@ function Sidebar({
895
991
  );
896
992
  }
897
993
  function SidebarHeader({ className, ...props }) {
898
- return /* @__PURE__ */ jsx12(
994
+ return /* @__PURE__ */ jsx13(
899
995
  "div",
900
996
  {
901
997
  "data-slot": "sidebar-header",
@@ -906,7 +1002,7 @@ function SidebarHeader({ className, ...props }) {
906
1002
  );
907
1003
  }
908
1004
  function SidebarFooter({ className, ...props }) {
909
- return /* @__PURE__ */ jsx12(
1005
+ return /* @__PURE__ */ jsx13(
910
1006
  "div",
911
1007
  {
912
1008
  "data-slot": "sidebar-footer",
@@ -917,7 +1013,7 @@ function SidebarFooter({ className, ...props }) {
917
1013
  );
918
1014
  }
919
1015
  function SidebarContent({ className, ...props }) {
920
- return /* @__PURE__ */ jsx12(
1016
+ return /* @__PURE__ */ jsx13(
921
1017
  "div",
922
1018
  {
923
1019
  "data-slot": "sidebar-content",
@@ -931,7 +1027,7 @@ function SidebarContent({ className, ...props }) {
931
1027
  );
932
1028
  }
933
1029
  function SidebarGroup({ className, ...props }) {
934
- return /* @__PURE__ */ jsx12(
1030
+ return /* @__PURE__ */ jsx13(
935
1031
  "div",
936
1032
  {
937
1033
  "data-slot": "sidebar-group",
@@ -942,7 +1038,7 @@ function SidebarGroup({ className, ...props }) {
942
1038
  );
943
1039
  }
944
1040
  function SidebarMenu({ className, ...props }) {
945
- return /* @__PURE__ */ jsx12(
1041
+ return /* @__PURE__ */ jsx13(
946
1042
  "ul",
947
1043
  {
948
1044
  "data-slot": "sidebar-menu",
@@ -953,7 +1049,7 @@ function SidebarMenu({ className, ...props }) {
953
1049
  );
954
1050
  }
955
1051
  function SidebarMenuItem({ className, ...props }) {
956
- return /* @__PURE__ */ jsx12(
1052
+ return /* @__PURE__ */ jsx13(
957
1053
  "li",
958
1054
  {
959
1055
  "data-slot": "sidebar-menu-item",
@@ -994,7 +1090,7 @@ function SidebarMenuButton({
994
1090
  }) {
995
1091
  const Comp = asChild ? Slot4.Root : "button";
996
1092
  const { isMobile, state } = useSidebar();
997
- const button2 = /* @__PURE__ */ jsx12(
1093
+ const button2 = /* @__PURE__ */ jsx13(
998
1094
  Comp,
999
1095
  {
1000
1096
  "data-slot": "sidebar-menu-button",
@@ -1007,7 +1103,7 @@ function SidebarMenuButton({
1007
1103
  );
1008
1104
  if (!tooltip) return button2;
1009
1105
  const { children, ...hint } = typeof tooltip === "string" ? { children: tooltip } : tooltip;
1010
- return /* @__PURE__ */ jsx12(Hint, { side: "right", align: "center", hidden: state !== "collapsed" || isMobile, ...hint, content: children, children: button2 });
1106
+ return /* @__PURE__ */ jsx13(Hint, { side: "right", align: "center", disabled: state !== "collapsed" || isMobile, ...hint, content: children, children: button2 });
1011
1107
  }
1012
1108
  function SidebarMenuAction({
1013
1109
  className,
@@ -1016,7 +1112,7 @@ function SidebarMenuAction({
1016
1112
  ...props
1017
1113
  }) {
1018
1114
  const Comp = asChild ? Slot4.Root : "button";
1019
- return /* @__PURE__ */ jsx12(
1115
+ return /* @__PURE__ */ jsx13(
1020
1116
  Comp,
1021
1117
  {
1022
1118
  "data-slot": "sidebar-menu-action",
@@ -1035,7 +1131,7 @@ function SidebarMenuAction({
1035
1131
  }
1036
1132
 
1037
1133
  // src/react/studio.tsx
1038
- import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
1134
+ import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
1039
1135
  var CONNECTION = {
1040
1136
  connected: { icon: PlugZap, tone: "text-success", label: "Runtime connected" },
1041
1137
  connecting: { icon: LoaderCircle, tone: "text-warning animate-spin", label: "Connecting to runtime" },
@@ -1046,20 +1142,20 @@ function StudioFooter({ connection }) {
1046
1142
  const { state, toggleSidebar } = useSidebar();
1047
1143
  const { icon: Status, tone, label } = CONNECTION[connection.phase];
1048
1144
  const Toggle = state === "expanded" ? PanelLeftClose : PanelLeftOpen;
1049
- return /* @__PURE__ */ jsx13(SidebarFooter, { children: /* @__PURE__ */ jsxs7(SidebarMenu, { children: [
1050
- /* @__PURE__ */ jsx13(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(SidebarMenuButton, { tooltip: label, className: "cursor-default hover:bg-transparent active:bg-transparent", children: [
1051
- /* @__PURE__ */ jsx13(Status, { className: tone }),
1052
- /* @__PURE__ */ jsx13("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: label })
1145
+ return /* @__PURE__ */ jsx14(SidebarFooter, { children: /* @__PURE__ */ jsxs7(SidebarMenu, { children: [
1146
+ /* @__PURE__ */ jsx14(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(SidebarMenuButton, { tooltip: label, className: "cursor-default hover:bg-transparent active:bg-transparent", children: [
1147
+ /* @__PURE__ */ jsx14(Status, { className: tone }),
1148
+ /* @__PURE__ */ jsx14("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: label })
1053
1149
  ] }) }),
1054
- /* @__PURE__ */ jsx13(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(
1150
+ /* @__PURE__ */ jsx14(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(
1055
1151
  SidebarMenuButton,
1056
1152
  {
1057
1153
  "aria-label": `${state === "expanded" ? "Collapse" : "Expand"} sidebar`,
1058
1154
  tooltip: `${state === "expanded" ? "Collapse" : "Expand"} sidebar`,
1059
1155
  onClick: toggleSidebar,
1060
1156
  children: [
1061
- /* @__PURE__ */ jsx13(Toggle, {}),
1062
- /* @__PURE__ */ jsx13("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: "Collapse" })
1157
+ /* @__PURE__ */ jsx14(Toggle, {}),
1158
+ /* @__PURE__ */ jsx14("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: "Collapse" })
1063
1159
  ]
1064
1160
  }
1065
1161
  ) })
@@ -1067,13 +1163,13 @@ function StudioFooter({ connection }) {
1067
1163
  }
1068
1164
  var SHORTCUTS = /* @__PURE__ */ new Set(["b", "s", "k"]);
1069
1165
  var COMPARE_KEY = "\\";
1070
- var editable = (target) => !!target?.matches?.("input, textarea, select, [contenteditable]");
1166
+ var editable = (event) => !!eventTarget(event)?.matches?.("input, textarea, select, [contenteditable]");
1071
1167
  var historyAction = (event) => {
1072
- if (!(event.metaKey || event.ctrlKey) || event.altKey || editable(event.target)) return null;
1168
+ if (!(event.metaKey || event.ctrlKey) || event.altKey || editable(event)) return null;
1073
1169
  const key = event.key.toLowerCase();
1074
1170
  return key === "z" ? event.shiftKey ? "redo" : "undo" : key === "y" ? "redo" : null;
1075
1171
  };
1076
- var isShortcut = (event) => (event.metaKey || event.ctrlKey) && SHORTCUTS.has(event.key.toLowerCase()) || event.key === COMPARE_KEY && !editable(event.target) || !!historyAction(event);
1172
+ var isShortcut = (event) => (event.metaKey || event.ctrlKey) && SHORTCUTS.has(event.key.toLowerCase()) || event.key === COMPARE_KEY && !editable(event) || !!historyAction(event);
1077
1173
  function forwardShortcuts(frame) {
1078
1174
  const forward = (event) => {
1079
1175
  if (event.defaultPrevented || !isShortcut(event)) return;
@@ -1089,11 +1185,11 @@ function forwardShortcuts(frame) {
1089
1185
  function Studio({ studio, previewComponent, getConfigFileHref }) {
1090
1186
  useStudio(studio);
1091
1187
  const { tools, pinned, togglePin } = usePinnedTools(studio);
1092
- const [mounted, setMounted] = useState8(false);
1188
+ const [mounted, setMounted] = useState9(false);
1093
1189
  const [sidebarHidden, setSidebarHidden] = useSessionFlag("joyco-studio:sidebar-hidden");
1094
1190
  const [inspectorHidden, setInspectorHidden] = useSessionFlag("joyco-studio:inspector-hidden");
1095
1191
  const [canvasExpanded, setCanvasExpanded] = useSessionFlag("joyco-studio:canvas-expanded");
1096
- const [selected, setSelected] = useState8(studio.definitions[0]?.id);
1192
+ const [selected, setSelected] = useState9(studio.definitions[0]?.id);
1097
1193
  const preview = useRef3(null);
1098
1194
  const definition = studio.definitions.find((tool) => tool.id === selected);
1099
1195
  const handle = studio.tools.find((tool) => tool.definition.id === selected);
@@ -1108,7 +1204,7 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1108
1204
  if (event.key.toLowerCase() !== "b") return;
1109
1205
  event.preventDefault();
1110
1206
  if (event.repeat) return;
1111
- const active = document.activeElement;
1207
+ const active = activeElement();
1112
1208
  if (active instanceof HTMLElement && active.closest('[data-slot="sidebar-container"], [data-slot="studio-inspector"]')) {
1113
1209
  active.blur();
1114
1210
  preview.current?.focus();
@@ -1130,7 +1226,7 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1130
1226
  current.current = { handle, compare };
1131
1227
  useEffect5(() => {
1132
1228
  const onKey = (event) => {
1133
- if (event.key !== COMPARE_KEY || editable(event.target) || event.repeat) return;
1229
+ if (event.key !== COMPARE_KEY || editable(event) || event.repeat) return;
1134
1230
  event.preventDefault();
1135
1231
  const { handle: handle2, compare: compare2 } = current.current;
1136
1232
  compare2(event.type === "keydown" && !!handle2?.dirty);
@@ -1168,7 +1264,7 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1168
1264
  }, [studio]);
1169
1265
  if (!mounted) return null;
1170
1266
  const sidebarOpen = !document.cookie.split("; ").includes("sidebar_state=false");
1171
- return /* @__PURE__ */ jsxs7(
1267
+ return /* @__PURE__ */ jsx14(StudioShadowRoot, { children: /* @__PURE__ */ jsxs7(
1172
1268
  SidebarProvider,
1173
1269
  {
1174
1270
  defaultOpen: sidebarOpen,
@@ -1176,7 +1272,7 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1176
1272
  "data-sidebar-panel": hidden.left ? "hidden" : "shown",
1177
1273
  className: "studio-workspace relative h-svh min-h-0 overflow-hidden text-xs",
1178
1274
  children: [
1179
- definition?.preview ? /* @__PURE__ */ jsx13(
1275
+ definition?.preview ? /* @__PURE__ */ jsx14(
1180
1276
  Preview,
1181
1277
  {
1182
1278
  "data-slot": "studio-preview",
@@ -1187,17 +1283,17 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1187
1283
  ...Preview === PreviewCanvas && { expanded: canvasExpanded, onExpandedChange: setCanvasExpanded }
1188
1284
  },
1189
1285
  definition.id
1190
- ) : /* @__PURE__ */ jsx13("div", { className: "absolute inset-0 grid place-items-center text-faint", children: definition ? "This tool has no preview" : "No tools registered" }),
1286
+ ) : /* @__PURE__ */ jsx14("div", { className: "absolute inset-0 grid place-items-center text-faint", children: definition ? "This tool has no preview" : "No tools registered" }),
1191
1287
  ["left", "right"].filter((side) => hidden[side] && (side === "left" || handle)).map((side) => {
1192
1288
  const Chevron = side === "left" ? ChevronRight : ChevronLeft;
1193
1289
  const label = side === "left" ? "Show tools" : "Show inspector";
1194
- return /* @__PURE__ */ jsx13(
1290
+ return /* @__PURE__ */ jsx14(
1195
1291
  "div",
1196
1292
  {
1197
1293
  "data-slot": "studio-panel-edge",
1198
1294
  "data-side": side,
1199
1295
  className: cn("group/edge absolute inset-y-0 z-20 w-8", side === "left" ? "left-0" : "right-0"),
1200
- children: /* @__PURE__ */ jsx13(
1296
+ children: /* @__PURE__ */ jsx14(
1201
1297
  Hint,
1202
1298
  {
1203
1299
  side: side === "left" ? "right" : "left",
@@ -1206,13 +1302,13 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1206
1302
  content: /* @__PURE__ */ jsxs7(Fragment2, { children: [
1207
1303
  label,
1208
1304
  " ",
1209
- /* @__PURE__ */ jsx13("span", { className: "text-faint", children: "\xB7 both" }),
1305
+ /* @__PURE__ */ jsx14("span", { className: "text-faint", children: "\xB7 both" }),
1210
1306
  /* @__PURE__ */ jsxs7(KbdGroup, { children: [
1211
- /* @__PURE__ */ jsx13(Kbd, { children: "\u2318/Ctrl" }),
1212
- /* @__PURE__ */ jsx13(Kbd, { children: "B" })
1307
+ /* @__PURE__ */ jsx14(Kbd, { children: "\u2318/Ctrl" }),
1308
+ /* @__PURE__ */ jsx14(Kbd, { children: "B" })
1213
1309
  ] })
1214
1310
  ] }),
1215
- children: /* @__PURE__ */ jsx13(Panel, { asChild: true, children: /* @__PURE__ */ jsx13(
1311
+ children: /* @__PURE__ */ jsx14(Panel, { asChild: true, children: /* @__PURE__ */ jsx14(
1216
1312
  Button,
1217
1313
  {
1218
1314
  "data-slot": "studio-panel-reveal",
@@ -1224,7 +1320,7 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1224
1320
  "absolute top-1/2 h-16 w-6 -translate-y-1/2 cursor-pointer px-0 text-sidebar-foreground opacity-0 transition-[translate,opacity] duration-200 ease-out hover:bg-sidebar/95 hover:text-foreground focus:translate-x-0 focus:opacity-100 group-hover/edge:translate-x-0 group-hover/edge:opacity-100 motion-reduce:transition-none [@media(hover:none)]:translate-x-0 [@media(hover:none)]:opacity-100",
1225
1321
  side === "left" ? "left-1 -translate-x-[calc(100%+0.25rem)]" : "right-1 translate-x-[calc(100%+0.25rem)]"
1226
1322
  ),
1227
- children: /* @__PURE__ */ jsx13(Chevron, { "aria-hidden": true })
1323
+ children: /* @__PURE__ */ jsx14(Chevron, { "aria-hidden": true })
1228
1324
  }
1229
1325
  ) })
1230
1326
  }
@@ -1245,15 +1341,15 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1245
1341
  hidden.left && "-translate-x-[calc(100%+1rem)]"
1246
1342
  ),
1247
1343
  children: [
1248
- /* @__PURE__ */ jsx13(SidebarHeader, { className: "h-10 flex-row items-center overflow-hidden py-0 pr-0 pl-4 transition-[padding] duration-200 ease-out group-data-[collapsible=icon]:pl-[calc(1.5rem-0.875rem*352/144/2)] motion-reduce:transition-none", children: /* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-2.5 text-foreground", children: [
1249
- /* @__PURE__ */ jsx13(Logo, { className: "h-3.5 w-auto shrink-0" }),
1250
- /* @__PURE__ */ jsx13("strong", { className: "tracking-[0.08em] whitespace-nowrap", children: "STUDIO" }),
1344
+ /* @__PURE__ */ jsx14(SidebarHeader, { className: "h-10 flex-row items-center overflow-hidden py-0 pr-0 pl-4 transition-[padding] duration-200 ease-out group-data-[collapsible=icon]:pl-[calc(1.5rem-0.875rem*352/144/2)] motion-reduce:transition-none", children: /* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-2.5 text-foreground", children: [
1345
+ /* @__PURE__ */ jsx14(Logo, { className: "h-3.5 w-auto shrink-0" }),
1346
+ /* @__PURE__ */ jsx14("strong", { className: "tracking-[0.08em] whitespace-nowrap", children: "STUDIO" }),
1251
1347
  /* @__PURE__ */ jsxs7("span", { "data-slot": "studio-version", className: "text-[10px] text-faint group-data-[collapsible=icon]:hidden", children: [
1252
1348
  "v",
1253
1349
  version
1254
1350
  ] })
1255
1351
  ] }) }),
1256
- /* @__PURE__ */ jsx13(SidebarContent, { children: /* @__PURE__ */ jsx13(SidebarGroup, { children: /* @__PURE__ */ jsx13(SidebarMenu, { children: tools.map((tool) => {
1352
+ /* @__PURE__ */ jsx14(SidebarContent, { children: /* @__PURE__ */ jsx14(SidebarGroup, { children: /* @__PURE__ */ jsx14(SidebarMenu, { children: tools.map((tool) => {
1257
1353
  const title = tool.title ?? tool.id;
1258
1354
  const isPinned = pinned.has(tool.id);
1259
1355
  const { state, dirty } = studio.tools.find((handle2) => handle2.definition.id === tool.id) ?? {};
@@ -1267,8 +1363,8 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1267
1363
  onClick: () => location.hash = tool.id,
1268
1364
  children: [
1269
1365
  /* @__PURE__ */ jsxs7("span", { className: "relative", children: [
1270
- /* @__PURE__ */ jsx13(ToolIcon, { icon: tool.icon, className: "size-4" }),
1271
- dirty && /* @__PURE__ */ jsx13(
1366
+ /* @__PURE__ */ jsx14(ToolIcon, { icon: tool.icon, className: "size-4" }),
1367
+ dirty && /* @__PURE__ */ jsx14(
1272
1368
  "span",
1273
1369
  {
1274
1370
  "aria-label": state?.conflict ? "Changed on disk" : "Unsaved",
@@ -1279,11 +1375,11 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1279
1375
  }
1280
1376
  )
1281
1377
  ] }),
1282
- /* @__PURE__ */ jsx13("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: title })
1378
+ /* @__PURE__ */ jsx14("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: title })
1283
1379
  ]
1284
1380
  }
1285
1381
  ),
1286
- /* @__PURE__ */ jsx13(Hint, { content: pinLabel, side: "right", children: /* @__PURE__ */ jsx13(
1382
+ /* @__PURE__ */ jsx14(Hint, { content: pinLabel, side: "right", children: /* @__PURE__ */ jsx14(
1287
1383
  SidebarMenuAction,
1288
1384
  {
1289
1385
  type: "button",
@@ -1295,16 +1391,16 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1295
1391
  "cursor-pointer [&>svg]:size-3 [@media(hover:none)]:opacity-100",
1296
1392
  isPinned && "text-sidebar-primary"
1297
1393
  ),
1298
- children: /* @__PURE__ */ jsx13(Pin2, { "aria-hidden": true, fill: isPinned ? "currentColor" : "none" })
1394
+ children: /* @__PURE__ */ jsx14(Pin2, { "aria-hidden": true, fill: isPinned ? "currentColor" : "none" })
1299
1395
  }
1300
1396
  ) })
1301
1397
  ] }, tool.id);
1302
1398
  }) }) }) }),
1303
- /* @__PURE__ */ jsx13(StudioFooter, { connection: studio.connection })
1399
+ /* @__PURE__ */ jsx14(StudioFooter, { connection: studio.connection })
1304
1400
  ]
1305
1401
  }
1306
1402
  ),
1307
- handle && /* @__PURE__ */ jsx13(Panel, { asChild: true, children: /* @__PURE__ */ jsx13(
1403
+ handle && /* @__PURE__ */ jsx14(Panel, { asChild: true, children: /* @__PURE__ */ jsx14(
1308
1404
  "aside",
1309
1405
  {
1310
1406
  "data-slot": "studio-inspector",
@@ -1314,7 +1410,7 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1314
1410
  "absolute inset-y-2 right-2 z-10 flex w-(--studio-inspector-width) flex-col gap-1 p-1 transition-transform duration-200 ease-out motion-reduce:transition-none",
1315
1411
  hidden.right && "translate-x-[calc(100%+1rem)]"
1316
1412
  ),
1317
- children: /* @__PURE__ */ jsx13(
1413
+ children: /* @__PURE__ */ jsx14(
1318
1414
  Inspector,
1319
1415
  {
1320
1416
  studio,
@@ -1328,21 +1424,36 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1328
1424
  ) })
1329
1425
  ]
1330
1426
  }
1331
- );
1427
+ ) });
1428
+ }
1429
+
1430
+ // src/react/debug.tsx
1431
+ import { DebugManager } from "@joycostudio/xyz/debug";
1432
+ import { useEffect as useEffect6 } from "react";
1433
+ function StudioDebug({ studio }) {
1434
+ useEffect6(() => {
1435
+ const debug = new DebugManager({
1436
+ createPane: async () => new (await import("tweakpane")).Pane({ title: "debug" }),
1437
+ binding: { registerFrame: everyFrame }
1438
+ });
1439
+ for (const tool of studio.tools) debug.register(tool);
1440
+ return () => debug.dispose();
1441
+ }, [studio]);
1442
+ return null;
1332
1443
  }
1333
1444
 
1334
1445
  // src/react/command-menu.tsx
1446
+ import { Dialog } from "@base-ui/react/dialog";
1335
1447
  import { Pin as Pin3 } from "lucide-react";
1336
- import { Dialog } from "radix-ui";
1337
- import { useEffect as useEffect6, useRef as useRef4, useState as useState9 } from "react";
1448
+ import { useEffect as useEffect7, useRef as useRef4, useState as useState10 } from "react";
1338
1449
 
1339
1450
  // src/react/ui/command.tsx
1340
1451
  import * as React3 from "react";
1341
1452
  import { Command as CommandPrimitive } from "cmdk";
1342
1453
  import { SearchIcon } from "lucide-react";
1343
- import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
1454
+ import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
1344
1455
  function Command({ className, ...props }) {
1345
- return /* @__PURE__ */ jsx14(
1456
+ return /* @__PURE__ */ jsx15(
1346
1457
  CommandPrimitive,
1347
1458
  {
1348
1459
  "data-slot": "command",
@@ -1356,8 +1467,8 @@ function Command({ className, ...props }) {
1356
1467
  }
1357
1468
  var CommandInput = React3.forwardRef(function CommandInput2({ className, ...props }, ref) {
1358
1469
  return /* @__PURE__ */ jsxs8("div", { "data-slot": "command-input-wrapper", className: "flex h-9 items-center gap-2 border-b px-3", children: [
1359
- /* @__PURE__ */ jsx14(SearchIcon, { "aria-hidden": true, className: "size-4 shrink-0 opacity-50" }),
1360
- /* @__PURE__ */ jsx14(
1470
+ /* @__PURE__ */ jsx15(SearchIcon, { "aria-hidden": true, className: "size-4 shrink-0 opacity-50" }),
1471
+ /* @__PURE__ */ jsx15(
1361
1472
  CommandPrimitive.Input,
1362
1473
  {
1363
1474
  ref,
@@ -1372,7 +1483,7 @@ var CommandInput = React3.forwardRef(function CommandInput2({ className, ...prop
1372
1483
  ] });
1373
1484
  });
1374
1485
  function CommandList({ className, ...props }) {
1375
- return /* @__PURE__ */ jsx14(
1486
+ return /* @__PURE__ */ jsx15(
1376
1487
  CommandPrimitive.List,
1377
1488
  {
1378
1489
  "data-slot": "command-list",
@@ -1382,10 +1493,10 @@ function CommandList({ className, ...props }) {
1382
1493
  );
1383
1494
  }
1384
1495
  function CommandEmpty({ ...props }) {
1385
- return /* @__PURE__ */ jsx14(CommandPrimitive.Empty, { "data-slot": "command-empty", className: "py-6 text-center text-sm", ...props });
1496
+ return /* @__PURE__ */ jsx15(CommandPrimitive.Empty, { "data-slot": "command-empty", className: "py-6 text-center text-sm", ...props });
1386
1497
  }
1387
1498
  function CommandItem({ className, ...props }) {
1388
- return /* @__PURE__ */ jsx14(
1499
+ return /* @__PURE__ */ jsx15(
1389
1500
  CommandPrimitive.Item,
1390
1501
  {
1391
1502
  "data-slot": "command-item",
@@ -1399,26 +1510,35 @@ function CommandItem({ className, ...props }) {
1399
1510
  }
1400
1511
 
1401
1512
  // src/react/command-menu.tsx
1402
- import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
1403
- function StudioCommandMenu({ studio, studioPath = "/studio", navigate }) {
1513
+ import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
1514
+ function StudioCommandMenu(props) {
1515
+ return /* @__PURE__ */ jsx16(StudioShadowRoot, { children: /* @__PURE__ */ jsx16(CommandMenu, { ...props }) });
1516
+ }
1517
+ function CommandMenu({ studio, studioPath = "/studio", navigate }) {
1404
1518
  const { tools, pinned } = usePinnedTools(studio);
1405
- const [open, setOpen] = useState9(false);
1406
- const opener = useRef4(null);
1519
+ const [open, setOpen] = useState10(false);
1520
+ const [session, setSession] = useState10(0);
1521
+ const isOpen = useRef4(open);
1522
+ isOpen.current = open;
1523
+ const show = (next) => {
1524
+ if (next && !isOpen.current) setSession((count) => count + 1);
1525
+ setOpen(next);
1526
+ };
1407
1527
  const input = useRef4(null);
1408
- useEffect6(() => {
1528
+ useEffect7(() => {
1409
1529
  if (window.frameElement?.getAttribute("data-slot") === "studio-preview") return;
1410
1530
  const onKey = (event) => {
1411
1531
  if (event.defaultPrevented || event.isComposing || event.altKey || !(event.metaKey || event.ctrlKey)) return;
1412
1532
  if (event.key.toLowerCase() !== "k") return;
1413
1533
  event.preventDefault();
1414
1534
  if (event.repeat) return;
1415
- setOpen((current) => !current);
1535
+ show(!isOpen.current);
1416
1536
  };
1417
1537
  window.addEventListener("keydown", onKey);
1418
1538
  return () => window.removeEventListener("keydown", onKey);
1419
1539
  }, []);
1420
1540
  const select = (id) => {
1421
- setOpen(false);
1541
+ show(false);
1422
1542
  const target = new URL(studioPath, window.location.href);
1423
1543
  target.hash = id;
1424
1544
  if (target.pathname === window.location.pathname) {
@@ -1429,75 +1549,73 @@ function StudioCommandMenu({ studio, studioPath = "/studio", navigate }) {
1429
1549
  window.location.assign(target.href);
1430
1550
  }
1431
1551
  };
1432
- return /* @__PURE__ */ jsx15(Dialog.Root, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs9(Dialog.Portal, { children: [
1433
- /* @__PURE__ */ jsx15(Dialog.Overlay, { "data-slot": "studio-command-overlay" }),
1434
- /* @__PURE__ */ jsxs9(
1435
- Dialog.Content,
1436
- {
1437
- "data-slot": "studio-command-menu",
1438
- onOpenAutoFocus: (event) => {
1439
- event.preventDefault();
1440
- opener.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
1441
- input.current?.focus();
1442
- },
1443
- onCloseAutoFocus: (event) => {
1444
- event.preventDefault();
1445
- opener.current?.focus();
1446
- },
1447
- children: [
1448
- /* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-heading", children: [
1449
- /* @__PURE__ */ jsxs9(Dialog.Title, { "aria-label": "Studio tools", children: [
1450
- /* @__PURE__ */ jsx15(Logo, { "aria-hidden": true }),
1451
- /* @__PURE__ */ jsx15("strong", { children: "STUDIO" })
1452
- ] }),
1453
- /* @__PURE__ */ jsx15(Dialog.Close, { "aria-label": "Close tool menu", children: /* @__PURE__ */ jsx15(Kbd, { children: "esc" }) })
1454
- ] }),
1455
- /* @__PURE__ */ jsx15(Dialog.Description, { "data-slot": "studio-command-description", children: "Open a tool in Studio." }),
1456
- /* @__PURE__ */ jsxs9(Command, { label: "Studio tools", loop: true, vimBindings: false, children: [
1457
- /* @__PURE__ */ jsx15(CommandInput, { ref: input, placeholder: "Search tools\u2026" }),
1458
- /* @__PURE__ */ jsxs9(CommandList, { children: [
1459
- /* @__PURE__ */ jsx15(CommandEmpty, { children: studio.definitions.length ? "No tools found." : "No tools registered yet." }),
1460
- tools.map((tool) => /* @__PURE__ */ jsxs9(
1461
- CommandItem,
1462
- {
1463
- value: tool.id,
1464
- keywords: [tool.title ?? tool.id],
1465
- onSelect: () => select(tool.id),
1466
- children: [
1467
- /* @__PURE__ */ jsx15(ToolIcon, { icon: tool.icon }),
1468
- /* @__PURE__ */ jsx15("span", { "data-slot": "studio-command-label", children: tool.title ?? tool.id }),
1469
- pinned.has(tool.id) && /* @__PURE__ */ jsx15(Pin3, { "aria-hidden": true })
1470
- ]
1471
- },
1472
- tool.id
1473
- ))
1474
- ] })
1552
+ return /* @__PURE__ */ jsx16(Dialog.Root, { open, onOpenChange: show, children: /* @__PURE__ */ jsxs9(Dialog.Portal, { container: usePortalContainer(), children: [
1553
+ /* @__PURE__ */ jsx16(Dialog.Backdrop, { "data-slot": "studio-command-overlay" }),
1554
+ /* @__PURE__ */ jsxs9(Dialog.Popup, { "data-slot": "studio-command-menu", initialFocus: input, children: [
1555
+ /* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-heading", children: [
1556
+ /* @__PURE__ */ jsxs9(Dialog.Title, { "aria-label": "Studio tools", children: [
1557
+ /* @__PURE__ */ jsx16(Logo, { "aria-hidden": true }),
1558
+ /* @__PURE__ */ jsx16("strong", { children: "STUDIO" })
1559
+ ] }),
1560
+ /* @__PURE__ */ jsx16(Dialog.Close, { "aria-label": "Close tool menu", children: /* @__PURE__ */ jsx16(Kbd, { children: "esc" }) })
1561
+ ] }),
1562
+ /* @__PURE__ */ jsx16(Dialog.Description, { "data-slot": "studio-command-description", children: "Open a tool in Studio." }),
1563
+ /* @__PURE__ */ jsxs9(Command, { label: "Studio tools", loop: true, vimBindings: false, children: [
1564
+ /* @__PURE__ */ jsx16(CommandInput, { ref: input, placeholder: "Search tools\u2026" }),
1565
+ /* @__PURE__ */ jsxs9(CommandList, { children: [
1566
+ /* @__PURE__ */ jsx16(CommandEmpty, { children: studio.definitions.length ? "No tools found." : "No tools registered yet." }),
1567
+ tools.map((tool) => /* @__PURE__ */ jsxs9(
1568
+ CommandItem,
1569
+ {
1570
+ value: tool.id,
1571
+ keywords: [tool.title ?? tool.id],
1572
+ onSelect: () => select(tool.id),
1573
+ children: [
1574
+ /* @__PURE__ */ jsx16(ToolIcon, { icon: tool.icon }),
1575
+ /* @__PURE__ */ jsx16("span", { "data-slot": "studio-command-label", children: tool.title ?? tool.id }),
1576
+ pinned.has(tool.id) && /* @__PURE__ */ jsx16(Pin3, { "aria-hidden": true })
1577
+ ]
1578
+ },
1579
+ tool.id
1580
+ ))
1581
+ ] })
1582
+ ] }, session),
1583
+ /* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-footer", "aria-hidden": true, children: [
1584
+ /* @__PURE__ */ jsxs9("span", { children: [
1585
+ /* @__PURE__ */ jsxs9(KbdGroup, { children: [
1586
+ /* @__PURE__ */ jsx16(Kbd, { children: "\u2191" }),
1587
+ /* @__PURE__ */ jsx16(Kbd, { children: "\u2193" })
1475
1588
  ] }),
1476
- /* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-footer", "aria-hidden": true, children: [
1477
- /* @__PURE__ */ jsxs9("span", { children: [
1478
- /* @__PURE__ */ jsxs9(KbdGroup, { children: [
1479
- /* @__PURE__ */ jsx15(Kbd, { children: "\u2191" }),
1480
- /* @__PURE__ */ jsx15(Kbd, { children: "\u2193" })
1481
- ] }),
1482
- "navigate"
1483
- ] }),
1484
- /* @__PURE__ */ jsxs9("span", { children: [
1485
- /* @__PURE__ */ jsx15(Kbd, { children: "\u21B5" }),
1486
- " open tool"
1487
- ] })
1488
- ] })
1489
- ]
1490
- }
1491
- )
1589
+ "navigate"
1590
+ ] }),
1591
+ /* @__PURE__ */ jsxs9("span", { children: [
1592
+ /* @__PURE__ */ jsx16(Kbd, { children: "\u21B5" }),
1593
+ " open tool"
1594
+ ] })
1595
+ ] })
1596
+ ] })
1492
1597
  ] }) });
1493
1598
  }
1494
1599
 
1495
1600
  // src/react/select.tsx
1601
+ import { Select } from "@base-ui/react/select";
1496
1602
  import { Check, ChevronDown, ChevronUp } from "lucide-react";
1497
- import { Select } from "radix-ui";
1498
- import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
1603
+
1604
+ // src/react/select-labels.ts
1605
+ import { Children, isValidElement } from "react";
1606
+ function itemLabels(children, labels = {}) {
1607
+ Children.forEach(children, (child) => {
1608
+ if (!isValidElement(child)) return;
1609
+ if (typeof child.props.value === "string") labels[child.props.value] = child.props.children;
1610
+ else itemLabels(child.props.children, labels);
1611
+ });
1612
+ return labels;
1613
+ }
1614
+
1615
+ // src/react/select.tsx
1616
+ import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
1499
1617
  function StudioSelect({ label, title, className, children, ...props }) {
1500
- return /* @__PURE__ */ jsxs10(Select.Root, { ...props, children: [
1618
+ return /* @__PURE__ */ jsxs10(Select.Root, { items: itemLabels(children), ...props, children: [
1501
1619
  /* @__PURE__ */ jsxs10(
1502
1620
  Select.Trigger,
1503
1621
  {
@@ -1509,26 +1627,23 @@ function StudioSelect({ label, title, className, children, ...props }) {
1509
1627
  className
1510
1628
  ),
1511
1629
  children: [
1512
- /* @__PURE__ */ jsx16(Select.Value, {}),
1513
- /* @__PURE__ */ jsx16(Select.Icon, { children: /* @__PURE__ */ jsx16(ChevronDown, { className: "shrink-0 text-muted-foreground", size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
1630
+ /* @__PURE__ */ jsx17(Select.Value, {}),
1631
+ /* @__PURE__ */ jsx17(Select.Icon, { children: /* @__PURE__ */ jsx17(ChevronDown, { className: "shrink-0 text-muted-foreground", size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
1514
1632
  ]
1515
1633
  }
1516
1634
  ),
1517
- /* @__PURE__ */ jsx16(Select.Portal, { children: /* @__PURE__ */ jsxs10(
1518
- Select.Content,
1635
+ /* @__PURE__ */ jsx17(Select.Portal, { container: usePortalContainer(), children: /* @__PURE__ */ jsx17(Select.Positioner, { align: "end", sideOffset: 6, alignItemWithTrigger: false, className: "isolate z-50", children: /* @__PURE__ */ jsxs10(
1636
+ Select.Popup,
1519
1637
  {
1520
- className: "relative z-50 max-h-(--radix-select-content-available-height) min-w-(--radix-select-trigger-width) overflow-hidden rounded-md border border-border bg-popover font-(family-name:--studio-font) text-xs font-normal text-popover-foreground shadow-md",
1638
+ className: "relative max-h-(--available-height) min-w-(--anchor-width) overflow-y-auto rounded-md border border-border bg-popover p-1 font-(family-name:--studio-font) text-xs font-normal text-popover-foreground shadow-md outline-none",
1521
1639
  "data-slot": "select-content",
1522
- position: "popper",
1523
- align: "end",
1524
- sideOffset: 6,
1525
1640
  children: [
1526
- /* @__PURE__ */ jsx16(Select.ScrollUpButton, { className: "flex justify-center py-1", children: /* @__PURE__ */ jsx16(ChevronUp, { size: 14, "aria-hidden": true }) }),
1527
- /* @__PURE__ */ jsx16(Select.Viewport, { className: "p-1", children }),
1528
- /* @__PURE__ */ jsx16(Select.ScrollDownButton, { className: "flex justify-center py-1", children: /* @__PURE__ */ jsx16(ChevronDown, { size: 14, "aria-hidden": true }) })
1641
+ /* @__PURE__ */ jsx17(Select.ScrollUpArrow, { className: "sticky top-0 z-10 flex w-full justify-center bg-popover py-1", children: /* @__PURE__ */ jsx17(ChevronUp, { size: 14, "aria-hidden": true }) }),
1642
+ /* @__PURE__ */ jsx17(Select.List, { children }),
1643
+ /* @__PURE__ */ jsx17(Select.ScrollDownArrow, { className: "sticky bottom-0 z-10 flex w-full justify-center bg-popover py-1", children: /* @__PURE__ */ jsx17(ChevronDown, { size: 14, "aria-hidden": true }) })
1529
1644
  ]
1530
1645
  }
1531
- ) })
1646
+ ) }) })
1532
1647
  ] });
1533
1648
  }
1534
1649
  function StudioSelectItem({ className, children, ...props }) {
@@ -1542,8 +1657,8 @@ function StudioSelectItem({ className, children, ...props }) {
1542
1657
  ),
1543
1658
  ...props,
1544
1659
  children: [
1545
- /* @__PURE__ */ jsx16(Select.ItemText, { children }),
1546
- /* @__PURE__ */ jsx16(Select.ItemIndicator, { className: "absolute right-2", children: /* @__PURE__ */ jsx16(Check, { size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
1660
+ /* @__PURE__ */ jsx17(Select.ItemText, { children }),
1661
+ /* @__PURE__ */ jsx17(Select.ItemIndicator, { className: "absolute right-2", children: /* @__PURE__ */ jsx17(Check, { size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
1547
1662
  ]
1548
1663
  }
1549
1664
  );
@@ -1551,9 +1666,9 @@ function StudioSelectItem({ className, children, ...props }) {
1551
1666
 
1552
1667
  // src/react/ui/input.tsx
1553
1668
  import { forwardRef as forwardRef5 } from "react";
1554
- import { jsx as jsx17 } from "react/jsx-runtime";
1669
+ import { jsx as jsx18 } from "react/jsx-runtime";
1555
1670
  var Input = forwardRef5(function Input2({ className, ...props }, ref) {
1556
- return /* @__PURE__ */ jsx17(
1671
+ return /* @__PURE__ */ jsx18(
1557
1672
  "input",
1558
1673
  {
1559
1674
  ref,
@@ -1571,6 +1686,7 @@ export {
1571
1686
  PreviewCanvas,
1572
1687
  Studio,
1573
1688
  StudioCommandMenu,
1689
+ StudioDebug,
1574
1690
  Input as StudioInput,
1575
1691
  Panel as StudioPanel,
1576
1692
  PanelContent as StudioPanelContent,