@joycostudio/studio 0.1.2 → 0.1.4

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 useEffect4, useRef as useRef3, useState as useState7 } 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.2";
17
+ var version = "0.1.4";
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,11 +398,11 @@ 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" };
@@ -327,6 +412,13 @@ function describe(studio, handle) {
327
412
  if (state.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,7 +428,7 @@ function Inspector({
336
428
  useStudio(studio);
337
429
  const container = useRef(null);
338
430
  const pane = useRef(null);
339
- const [failure, setFailure] = useState(null);
431
+ const [failure, setFailure] = useState2(null);
340
432
  const run = (action) => void action.then((result) => setFailure(result.ok ? null : result.message ?? result.error));
341
433
  const save = (force = false) => run(handle.save({ force }));
342
434
  useEffect(() => {
@@ -351,6 +443,7 @@ function Inspector({
351
443
  schema: () => handle.controls(),
352
444
  extend: resetSlidersOnDoubleClick(handle)
353
445
  });
446
+ adoptTweakpaneStyles(container.current);
354
447
  const unsubscribe = handle.subscribe(() => bound.refresh());
355
448
  teardown = () => {
356
449
  unsubscribe();
@@ -386,11 +479,11 @@ function Inspector({
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,12 +538,12 @@ 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",
@@ -461,11 +554,11 @@ function Inspector({
461
554
  children: "Discard"
462
555
  }
463
556
  ),
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: [
557
+ 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: !editable2, onClick: () => save(), children: [
465
558
  "Save",
466
559
  /* @__PURE__ */ jsxs2(KbdGroup, { children: [
467
- /* @__PURE__ */ jsx7(Kbd, { children: "\u2318" }),
468
- /* @__PURE__ */ jsx7(Kbd, { children: "S" })
560
+ /* @__PURE__ */ jsx8(Kbd, { children: "\u2318" }),
561
+ /* @__PURE__ */ jsx8(Kbd, { children: "S" })
469
562
  ] })
470
563
  ] })
471
564
  ] })
@@ -474,13 +567,13 @@ function Inspector({
474
567
  }
475
568
 
476
569
  // src/react/logo.tsx
477
- import { jsx as jsx8 } from "react/jsx-runtime";
570
+ import { jsx as jsx9 } from "react/jsx-runtime";
478
571
  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" }) });
572
+ 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
573
  }
481
574
 
482
575
  // src/react/pinned-tools.ts
483
- import { useEffect as useEffect2, useState as useState2 } from "react";
576
+ import { useEffect as useEffect2, useState as useState3 } from "react";
484
577
  var STORAGE_KEY = "joyco-studio:pinned-tools";
485
578
  var CHANGE_EVENT = "joyco-studio:pins-changed";
486
579
  function readPins() {
@@ -492,7 +585,7 @@ function readPins() {
492
585
  }
493
586
  }
494
587
  function usePinnedTools(studio) {
495
- const [pins, setPins] = useState2([]);
588
+ const [pins, setPins] = useState3([]);
496
589
  useEffect2(() => {
497
590
  setPins(readPins());
498
591
  const onChange = (event) => setPins(event.detail);
@@ -507,9 +600,7 @@ function usePinnedTools(studio) {
507
600
  };
508
601
  }, []);
509
602
  const pinned = new Set(pins);
510
- const tools = [...studio.tools].sort(
511
- (a, b) => Number(pinned.has(b.definition.id)) - Number(pinned.has(a.definition.id))
512
- );
603
+ const tools = [...studio.definitions].sort((a, b) => Number(pinned.has(b.id)) - Number(pinned.has(a.id)));
513
604
  const togglePin = (id) => {
514
605
  const next = pinned.has(id) ? pins.filter((pin) => pin !== id) : [...pins, id];
515
606
  try {
@@ -523,17 +614,17 @@ function usePinnedTools(studio) {
523
614
 
524
615
  // src/react/preview-canvas.tsx
525
616
  import { RotateCw } from "lucide-react";
526
- import { forwardRef as forwardRef3, useImperativeHandle, useRef as useRef2, useState as useState4 } from "react";
617
+ import { forwardRef as forwardRef3, useImperativeHandle, useRef as useRef2, useState as useState5 } from "react";
527
618
 
528
619
  // src/react/canvas-toolbar.tsx
529
620
  import { Maximize, Minimize, Pin, PinOff } from "lucide-react";
530
- import { useState as useState3 } from "react";
531
- import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
621
+ import { useState as useState4 } from "react";
622
+ import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
532
623
  function CanvasToolbar({ label, expanded = false, onToggle, children }) {
533
- const [ghost, setGhost] = useState3(false);
624
+ const [ghost, setGhost] = useState4(false);
534
625
  const ExpandIcon = expanded ? Minimize : Maximize;
535
626
  const PinIcon = ghost ? PinOff : Pin;
536
- return /* @__PURE__ */ jsx9(
627
+ return /* @__PURE__ */ jsx10(
537
628
  "div",
538
629
  {
539
630
  className: "studio-canvas-toolbar",
@@ -544,11 +635,11 @@ function CanvasToolbar({ label, expanded = false, onToggle, children }) {
544
635
  "aria-label": label,
545
636
  children: /* @__PURE__ */ jsxs3(StudioToolbar, { className: "studio-canvas-actions", children: [
546
637
  children,
547
- onToggle && /* @__PURE__ */ jsx9("div", { className: "studio-canvas-toggle", children: /* @__PURE__ */ jsxs3("button", { "data-slot": "toolbar-action", type: "button", "aria-pressed": expanded, onClick: onToggle, children: [
548
- /* @__PURE__ */ jsx9(ExpandIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true }),
638
+ onToggle && /* @__PURE__ */ jsx10("div", { className: "studio-canvas-toggle", children: /* @__PURE__ */ jsxs3("button", { "data-slot": "toolbar-action", type: "button", "aria-pressed": expanded, onClick: onToggle, children: [
639
+ /* @__PURE__ */ jsx10(ExpandIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true }),
549
640
  expanded ? "Contain canvas" : "Expand"
550
641
  ] }) }),
551
- !expanded && /* @__PURE__ */ jsx9(
642
+ !expanded && /* @__PURE__ */ jsx10(
552
643
  "button",
553
644
  {
554
645
  type: "button",
@@ -556,7 +647,7 @@ function CanvasToolbar({ label, expanded = false, onToggle, children }) {
556
647
  "aria-pressed": ghost,
557
648
  title: ghost ? "Pin header" : "Auto-hide header",
558
649
  onClick: () => setGhost(!ghost),
559
- children: /* @__PURE__ */ jsx9(PinIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
650
+ children: /* @__PURE__ */ jsx10(PinIcon, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
560
651
  }
561
652
  )
562
653
  ] })
@@ -565,9 +656,9 @@ function CanvasToolbar({ label, expanded = false, onToggle, children }) {
565
656
  }
566
657
 
567
658
  // src/react/preview-canvas.tsx
568
- import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
659
+ import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
569
660
  var PreviewCanvas = forwardRef3(function PreviewCanvas2({ title = "Preview", expanded: controlled, onExpandedChange, onReload, toolbar, ...props }, ref) {
570
- const [localExpanded, setExpanded] = useState4(false);
661
+ const [localExpanded, setExpanded] = useState5(false);
571
662
  const expanded = controlled ?? localExpanded;
572
663
  const frame = useRef2(null);
573
664
  useImperativeHandle(ref, () => frame.current, []);
@@ -589,7 +680,7 @@ var PreviewCanvas = forwardRef3(function PreviewCanvas2({ title = "Preview", exp
589
680
  onExpandedChange?.(!expanded);
590
681
  },
591
682
  children: [
592
- /* @__PURE__ */ jsx10(
683
+ /* @__PURE__ */ jsx11(
593
684
  "button",
594
685
  {
595
686
  type: "button",
@@ -599,19 +690,38 @@ var PreviewCanvas = forwardRef3(function PreviewCanvas2({ title = "Preview", exp
599
690
  onReload?.();
600
691
  if (frame.current) frame.current.src = frame.current.src;
601
692
  },
602
- children: /* @__PURE__ */ jsx10(RotateCw, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
693
+ children: /* @__PURE__ */ jsx11(RotateCw, { size: 14, strokeWidth: 1.5, "aria-hidden": true })
603
694
  }
604
695
  ),
605
- /* @__PURE__ */ jsx10("div", { className: "studio-preview-source", children: toolbar ?? /* @__PURE__ */ jsx10("span", { className: "studio-preview-title", children: title }) })
696
+ /* @__PURE__ */ jsx11("div", { className: "studio-preview-source", children: toolbar ?? /* @__PURE__ */ jsx11("span", { className: "studio-preview-title", children: title }) })
606
697
  ]
607
698
  }
608
699
  ),
609
- /* @__PURE__ */ jsx10("iframe", { ...props, ref: frame, title })
700
+ /* @__PURE__ */ jsx11("iframe", { ...props, ref: frame, title })
610
701
  ]
611
702
  }
612
703
  );
613
704
  });
614
705
 
706
+ // src/react/session-flag.ts
707
+ import { useEffect as useEffect3, useState as useState6 } from "react";
708
+ function useSessionFlag(key) {
709
+ const [value, setValue] = useState6(() => {
710
+ try {
711
+ return sessionStorage.getItem(key) === "true";
712
+ } catch {
713
+ return false;
714
+ }
715
+ });
716
+ useEffect3(() => {
717
+ try {
718
+ sessionStorage.setItem(key, String(value));
719
+ } catch {
720
+ }
721
+ }, [key, value]);
722
+ return [value, setValue];
723
+ }
724
+
615
725
  // src/react/ui/sidebar.tsx
616
726
  import * as React2 from "react";
617
727
  import { cva as cva2 } from "class-variance-authority";
@@ -636,21 +746,21 @@ function useIsMobile() {
636
746
 
637
747
  // src/react/ui/sheet.tsx
638
748
  import { XIcon } from "lucide-react";
639
- import { Dialog as SheetPrimitive } from "radix-ui";
640
- import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
749
+ import { Dialog as SheetPrimitive } from "@base-ui/react/dialog";
750
+ import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
641
751
  function Sheet({ ...props }) {
642
- return /* @__PURE__ */ jsx11(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
752
+ return /* @__PURE__ */ jsx12(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
643
753
  }
644
754
  function SheetPortal({ ...props }) {
645
- return /* @__PURE__ */ jsx11(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
755
+ return /* @__PURE__ */ jsx12(SheetPrimitive.Portal, { "data-slot": "sheet-portal", container: usePortalContainer(), ...props });
646
756
  }
647
757
  function SheetOverlay({ className, ...props }) {
648
- return /* @__PURE__ */ jsx11(
649
- SheetPrimitive.Overlay,
758
+ return /* @__PURE__ */ jsx12(
759
+ SheetPrimitive.Backdrop,
650
760
  {
651
761
  "data-slot": "sheet-overlay",
652
762
  className: cn(
653
- "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",
763
+ "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",
654
764
  className
655
765
  ),
656
766
  ...props
@@ -665,25 +775,25 @@ function SheetContent({
665
775
  ...props
666
776
  }) {
667
777
  return /* @__PURE__ */ jsxs5(SheetPortal, { children: [
668
- /* @__PURE__ */ jsx11(SheetOverlay, {}),
778
+ /* @__PURE__ */ jsx12(SheetOverlay, {}),
669
779
  /* @__PURE__ */ jsxs5(
670
- SheetPrimitive.Content,
780
+ SheetPrimitive.Popup,
671
781
  {
672
782
  "data-slot": "sheet-content",
673
783
  className: cn(
674
- "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",
675
- 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",
676
- 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",
677
- 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",
678
- 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",
784
+ "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",
785
+ 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",
786
+ 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",
787
+ side === "top" && "inset-x-0 top-0 h-auto border-b data-closed:slide-out-to-top data-open:slide-in-from-top",
788
+ side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-closed:slide-out-to-bottom data-open:slide-in-from-bottom",
679
789
  className
680
790
  ),
681
791
  ...props,
682
792
  children: [
683
793
  children,
684
- 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: [
685
- /* @__PURE__ */ jsx11(XIcon, { className: "size-4" }),
686
- /* @__PURE__ */ jsx11("span", { className: "sr-only", children: "Close" })
794
+ 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: [
795
+ /* @__PURE__ */ jsx12(XIcon, { className: "size-4" }),
796
+ /* @__PURE__ */ jsx12("span", { className: "sr-only", children: "Close" })
687
797
  ] })
688
798
  ]
689
799
  }
@@ -691,10 +801,10 @@ function SheetContent({
691
801
  ] });
692
802
  }
693
803
  function SheetHeader({ className, ...props }) {
694
- return /* @__PURE__ */ jsx11("div", { "data-slot": "sheet-header", className: cn("flex flex-col gap-1.5 p-4", className), ...props });
804
+ return /* @__PURE__ */ jsx12("div", { "data-slot": "sheet-header", className: cn("flex flex-col gap-1.5 p-4", className), ...props });
695
805
  }
696
806
  function SheetTitle({ className, ...props }) {
697
- return /* @__PURE__ */ jsx11(
807
+ return /* @__PURE__ */ jsx12(
698
808
  SheetPrimitive.Title,
699
809
  {
700
810
  "data-slot": "sheet-title",
@@ -704,7 +814,7 @@ function SheetTitle({ className, ...props }) {
704
814
  );
705
815
  }
706
816
  function SheetDescription({ className, ...props }) {
707
- return /* @__PURE__ */ jsx11(
817
+ return /* @__PURE__ */ jsx12(
708
818
  SheetPrimitive.Description,
709
819
  {
710
820
  "data-slot": "sheet-description",
@@ -715,12 +825,12 @@ function SheetDescription({ className, ...props }) {
715
825
  }
716
826
 
717
827
  // src/react/ui/sidebar.tsx
718
- import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
828
+ import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
719
829
  var SIDEBAR_COOKIE_NAME = "sidebar_state";
720
830
  var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
721
- var SIDEBAR_WIDTH = "16rem";
722
- var SIDEBAR_WIDTH_MOBILE = "18rem";
723
- var SIDEBAR_WIDTH_ICON = "3rem";
831
+ var SIDEBAR_WIDTH = "256px";
832
+ var SIDEBAR_WIDTH_MOBILE = "288px";
833
+ var SIDEBAR_WIDTH_ICON = "48px";
724
834
  var SidebarContext = React2.createContext(null);
725
835
  function useSidebar() {
726
836
  const context = React2.useContext(SidebarContext);
@@ -770,7 +880,7 @@ function SidebarProvider({
770
880
  }),
771
881
  [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
772
882
  );
773
- return /* @__PURE__ */ jsx12(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx12(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx12(
883
+ return /* @__PURE__ */ jsx13(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx13(TooltipProvider, { delay: 0, children: /* @__PURE__ */ jsx13(
774
884
  "div",
775
885
  {
776
886
  "data-slot": "sidebar-wrapper",
@@ -796,7 +906,7 @@ function Sidebar({
796
906
  const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
797
907
  const Surface = variant === "floating" ? Panel : "div";
798
908
  if (collapsible === "none") {
799
- return /* @__PURE__ */ jsx12(
909
+ return /* @__PURE__ */ jsx13(
800
910
  "div",
801
911
  {
802
912
  "data-slot": "sidebar",
@@ -807,7 +917,7 @@ function Sidebar({
807
917
  );
808
918
  }
809
919
  if (isMobile) {
810
- return /* @__PURE__ */ jsx12(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs6(
920
+ return /* @__PURE__ */ jsx13(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs6(
811
921
  SheetContent,
812
922
  {
813
923
  "data-sidebar": "sidebar",
@@ -820,10 +930,10 @@ function Sidebar({
820
930
  side,
821
931
  children: [
822
932
  /* @__PURE__ */ jsxs6(SheetHeader, { className: "sr-only", children: [
823
- /* @__PURE__ */ jsx12(SheetTitle, { children: "Sidebar" }),
824
- /* @__PURE__ */ jsx12(SheetDescription, { children: "Displays the mobile sidebar." })
933
+ /* @__PURE__ */ jsx13(SheetTitle, { children: "Sidebar" }),
934
+ /* @__PURE__ */ jsx13(SheetDescription, { children: "Displays the mobile sidebar." })
825
935
  ] }),
826
- /* @__PURE__ */ jsx12("div", { className: "flex h-full w-full flex-col", children })
936
+ /* @__PURE__ */ jsx13("div", { className: "flex h-full w-full flex-col", children })
827
937
  ]
828
938
  }
829
939
  ) });
@@ -838,7 +948,7 @@ function Sidebar({
838
948
  "data-side": side,
839
949
  "data-slot": "sidebar",
840
950
  children: [
841
- /* @__PURE__ */ jsx12(
951
+ /* @__PURE__ */ jsx13(
842
952
  "div",
843
953
  {
844
954
  "data-slot": "sidebar-gap",
@@ -850,7 +960,7 @@ function Sidebar({
850
960
  )
851
961
  }
852
962
  ),
853
- /* @__PURE__ */ jsx12(
963
+ /* @__PURE__ */ jsx13(
854
964
  "div",
855
965
  {
856
966
  "data-slot": "sidebar-container",
@@ -862,7 +972,7 @@ function Sidebar({
862
972
  className
863
973
  ),
864
974
  ...props,
865
- children: /* @__PURE__ */ jsx12(
975
+ children: /* @__PURE__ */ jsx13(
866
976
  Surface,
867
977
  {
868
978
  "data-sidebar": "sidebar",
@@ -878,7 +988,7 @@ function Sidebar({
878
988
  );
879
989
  }
880
990
  function SidebarHeader({ className, ...props }) {
881
- return /* @__PURE__ */ jsx12(
991
+ return /* @__PURE__ */ jsx13(
882
992
  "div",
883
993
  {
884
994
  "data-slot": "sidebar-header",
@@ -889,7 +999,7 @@ function SidebarHeader({ className, ...props }) {
889
999
  );
890
1000
  }
891
1001
  function SidebarFooter({ className, ...props }) {
892
- return /* @__PURE__ */ jsx12(
1002
+ return /* @__PURE__ */ jsx13(
893
1003
  "div",
894
1004
  {
895
1005
  "data-slot": "sidebar-footer",
@@ -900,7 +1010,7 @@ function SidebarFooter({ className, ...props }) {
900
1010
  );
901
1011
  }
902
1012
  function SidebarContent({ className, ...props }) {
903
- return /* @__PURE__ */ jsx12(
1013
+ return /* @__PURE__ */ jsx13(
904
1014
  "div",
905
1015
  {
906
1016
  "data-slot": "sidebar-content",
@@ -914,7 +1024,7 @@ function SidebarContent({ className, ...props }) {
914
1024
  );
915
1025
  }
916
1026
  function SidebarGroup({ className, ...props }) {
917
- return /* @__PURE__ */ jsx12(
1027
+ return /* @__PURE__ */ jsx13(
918
1028
  "div",
919
1029
  {
920
1030
  "data-slot": "sidebar-group",
@@ -925,7 +1035,7 @@ function SidebarGroup({ className, ...props }) {
925
1035
  );
926
1036
  }
927
1037
  function SidebarMenu({ className, ...props }) {
928
- return /* @__PURE__ */ jsx12(
1038
+ return /* @__PURE__ */ jsx13(
929
1039
  "ul",
930
1040
  {
931
1041
  "data-slot": "sidebar-menu",
@@ -936,7 +1046,7 @@ function SidebarMenu({ className, ...props }) {
936
1046
  );
937
1047
  }
938
1048
  function SidebarMenuItem({ className, ...props }) {
939
- return /* @__PURE__ */ jsx12(
1049
+ return /* @__PURE__ */ jsx13(
940
1050
  "li",
941
1051
  {
942
1052
  "data-slot": "sidebar-menu-item",
@@ -977,7 +1087,7 @@ function SidebarMenuButton({
977
1087
  }) {
978
1088
  const Comp = asChild ? Slot4.Root : "button";
979
1089
  const { isMobile, state } = useSidebar();
980
- const button2 = /* @__PURE__ */ jsx12(
1090
+ const button2 = /* @__PURE__ */ jsx13(
981
1091
  Comp,
982
1092
  {
983
1093
  "data-slot": "sidebar-menu-button",
@@ -990,7 +1100,7 @@ function SidebarMenuButton({
990
1100
  );
991
1101
  if (!tooltip) return button2;
992
1102
  const { children, ...hint } = typeof tooltip === "string" ? { children: tooltip } : tooltip;
993
- return /* @__PURE__ */ jsx12(Hint, { side: "right", align: "center", hidden: state !== "collapsed" || isMobile, ...hint, content: children, children: button2 });
1103
+ return /* @__PURE__ */ jsx13(Hint, { side: "right", align: "center", disabled: state !== "collapsed" || isMobile, ...hint, content: children, children: button2 });
994
1104
  }
995
1105
  function SidebarMenuAction({
996
1106
  className,
@@ -999,7 +1109,7 @@ function SidebarMenuAction({
999
1109
  ...props
1000
1110
  }) {
1001
1111
  const Comp = asChild ? Slot4.Root : "button";
1002
- return /* @__PURE__ */ jsx12(
1112
+ return /* @__PURE__ */ jsx13(
1003
1113
  Comp,
1004
1114
  {
1005
1115
  "data-slot": "sidebar-menu-action",
@@ -1018,7 +1128,7 @@ function SidebarMenuAction({
1018
1128
  }
1019
1129
 
1020
1130
  // src/react/studio.tsx
1021
- import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
1131
+ import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
1022
1132
  var CONNECTION = {
1023
1133
  connected: { icon: PlugZap, tone: "text-success", label: "Runtime connected" },
1024
1134
  connecting: { icon: LoaderCircle, tone: "text-warning animate-spin", label: "Connecting to runtime" },
@@ -1029,20 +1139,20 @@ function StudioFooter({ connection }) {
1029
1139
  const { state, toggleSidebar } = useSidebar();
1030
1140
  const { icon: Status, tone, label } = CONNECTION[connection.phase];
1031
1141
  const Toggle = state === "expanded" ? PanelLeftClose : PanelLeftOpen;
1032
- return /* @__PURE__ */ jsx13(SidebarFooter, { children: /* @__PURE__ */ jsxs7(SidebarMenu, { children: [
1033
- /* @__PURE__ */ jsx13(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(SidebarMenuButton, { tooltip: label, className: "cursor-default hover:bg-transparent active:bg-transparent", children: [
1034
- /* @__PURE__ */ jsx13(Status, { className: tone }),
1035
- /* @__PURE__ */ jsx13("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: label })
1142
+ return /* @__PURE__ */ jsx14(SidebarFooter, { children: /* @__PURE__ */ jsxs7(SidebarMenu, { children: [
1143
+ /* @__PURE__ */ jsx14(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(SidebarMenuButton, { tooltip: label, className: "cursor-default hover:bg-transparent active:bg-transparent", children: [
1144
+ /* @__PURE__ */ jsx14(Status, { className: tone }),
1145
+ /* @__PURE__ */ jsx14("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: label })
1036
1146
  ] }) }),
1037
- /* @__PURE__ */ jsx13(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(
1147
+ /* @__PURE__ */ jsx14(SidebarMenuItem, { children: /* @__PURE__ */ jsxs7(
1038
1148
  SidebarMenuButton,
1039
1149
  {
1040
1150
  "aria-label": `${state === "expanded" ? "Collapse" : "Expand"} sidebar`,
1041
1151
  tooltip: `${state === "expanded" ? "Collapse" : "Expand"} sidebar`,
1042
1152
  onClick: toggleSidebar,
1043
1153
  children: [
1044
- /* @__PURE__ */ jsx13(Toggle, {}),
1045
- /* @__PURE__ */ jsx13("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: "Collapse" })
1154
+ /* @__PURE__ */ jsx14(Toggle, {}),
1155
+ /* @__PURE__ */ jsx14("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: "Collapse" })
1046
1156
  ]
1047
1157
  }
1048
1158
  ) })
@@ -1050,13 +1160,13 @@ function StudioFooter({ connection }) {
1050
1160
  }
1051
1161
  var SHORTCUTS = /* @__PURE__ */ new Set(["b", "s", "k"]);
1052
1162
  var COMPARE_KEY = "\\";
1053
- var editable = (target) => !!target?.matches?.("input, textarea, select, [contenteditable]");
1163
+ var editable = (event) => !!eventTarget(event)?.matches?.("input, textarea, select, [contenteditable]");
1054
1164
  var historyAction = (event) => {
1055
- if (!(event.metaKey || event.ctrlKey) || event.altKey || editable(event.target)) return null;
1165
+ if (!(event.metaKey || event.ctrlKey) || event.altKey || editable(event)) return null;
1056
1166
  const key = event.key.toLowerCase();
1057
1167
  return key === "z" ? event.shiftKey ? "redo" : "undo" : key === "y" ? "redo" : null;
1058
1168
  };
1059
- var isShortcut = (event) => (event.metaKey || event.ctrlKey) && SHORTCUTS.has(event.key.toLowerCase()) || event.key === COMPARE_KEY && !editable(event.target) || !!historyAction(event);
1169
+ var isShortcut = (event) => (event.metaKey || event.ctrlKey) && SHORTCUTS.has(event.key.toLowerCase()) || event.key === COMPARE_KEY && !editable(event) || !!historyAction(event);
1060
1170
  function forwardShortcuts(frame) {
1061
1171
  const forward = (event) => {
1062
1172
  if (event.defaultPrevented || !isShortcut(event)) return;
@@ -1072,24 +1182,33 @@ function forwardShortcuts(frame) {
1072
1182
  function Studio({ studio, previewComponent, getConfigFileHref }) {
1073
1183
  useStudio(studio);
1074
1184
  const { tools, pinned, togglePin } = usePinnedTools(studio);
1075
- const [mounted, setMounted] = useState7(false);
1076
- const [panelsHidden, setPanelsHidden] = useState7(false);
1077
- const [selected, setSelected] = useState7(studio.tools[0]?.definition.id);
1185
+ const [mounted, setMounted] = useState9(false);
1186
+ const [sidebarHidden, setSidebarHidden] = useSessionFlag("joyco-studio:sidebar-hidden");
1187
+ const [inspectorHidden, setInspectorHidden] = useSessionFlag("joyco-studio:inspector-hidden");
1188
+ const [canvasExpanded, setCanvasExpanded] = useSessionFlag("joyco-studio:canvas-expanded");
1189
+ const [selected, setSelected] = useState9(studio.definitions[0]?.id);
1078
1190
  const preview = useRef3(null);
1191
+ const definition = studio.definitions.find((tool) => tool.id === selected);
1079
1192
  const handle = studio.tools.find((tool) => tool.definition.id === selected);
1080
- const Preview = previewComponent ?? (handle?.definition.previewLayout === "custom" ? "iframe" : PreviewCanvas);
1081
- useEffect4(() => {
1193
+ const Preview = previewComponent ?? (definition?.previewLayout === "custom" ? "iframe" : PreviewCanvas);
1194
+ const hidden = { left: sidebarHidden, right: inspectorHidden || !handle };
1195
+ const show = { left: () => setSidebarHidden(false), right: () => setInspectorHidden(false) };
1196
+ const layout = useRef3(hidden);
1197
+ layout.current = hidden;
1198
+ useEffect5(() => {
1082
1199
  const onKey = (event) => {
1083
1200
  if (event.defaultPrevented || event.isComposing || event.altKey || !(event.metaKey || event.ctrlKey)) return;
1084
1201
  if (event.key.toLowerCase() !== "b") return;
1085
1202
  event.preventDefault();
1086
1203
  if (event.repeat) return;
1087
- const active = document.activeElement;
1204
+ const active = activeElement();
1088
1205
  if (active instanceof HTMLElement && active.closest('[data-slot="sidebar-container"], [data-slot="studio-inspector"]')) {
1089
1206
  active.blur();
1090
1207
  preview.current?.focus();
1091
1208
  }
1092
- setPanelsHidden((hidden) => !hidden);
1209
+ const hide = !layout.current.left || !layout.current.right;
1210
+ setSidebarHidden(hide);
1211
+ setInspectorHidden(hide);
1093
1212
  };
1094
1213
  window.addEventListener("keydown", onKey);
1095
1214
  return () => window.removeEventListener("keydown", onKey);
@@ -1099,12 +1218,12 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1099
1218
  handle.compare(showSaved);
1100
1219
  postCompare(preview.current?.contentWindow, handle.definition.id, showSaved);
1101
1220
  };
1102
- useEffect4(() => () => handle?.compare(false), [handle]);
1221
+ useEffect5(() => () => handle?.compare(false), [handle]);
1103
1222
  const current = useRef3({ handle, compare });
1104
1223
  current.current = { handle, compare };
1105
- useEffect4(() => {
1224
+ useEffect5(() => {
1106
1225
  const onKey = (event) => {
1107
- if (event.key !== COMPARE_KEY || editable(event.target) || event.repeat) return;
1226
+ if (event.key !== COMPARE_KEY || editable(event) || event.repeat) return;
1108
1227
  event.preventDefault();
1109
1228
  const { handle: handle2, compare: compare2 } = current.current;
1110
1229
  compare2(event.type === "keydown" && !!handle2?.dirty);
@@ -1120,7 +1239,7 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1120
1239
  removeEventListener("blur", release);
1121
1240
  };
1122
1241
  }, []);
1123
- useEffect4(() => {
1242
+ useEffect5(() => {
1124
1243
  const onKey = (event) => {
1125
1244
  const action = event.defaultPrevented ? null : historyAction(event);
1126
1245
  if (!action) return;
@@ -1130,10 +1249,10 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1130
1249
  addEventListener("keydown", onKey);
1131
1250
  return () => removeEventListener("keydown", onKey);
1132
1251
  }, []);
1133
- useEffect4(() => {
1252
+ useEffect5(() => {
1134
1253
  const fromHash = () => {
1135
1254
  const id = decodeURIComponent(location.hash.slice(1));
1136
- if (studio.tools.some((handle2) => handle2.definition.id === id)) setSelected(id);
1255
+ if (studio.definitions.some((tool) => tool.id === id)) setSelected(id);
1137
1256
  };
1138
1257
  setMounted(true);
1139
1258
  fromHash();
@@ -1142,59 +1261,63 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1142
1261
  }, [studio]);
1143
1262
  if (!mounted) return null;
1144
1263
  const sidebarOpen = !document.cookie.split("; ").includes("sidebar_state=false");
1145
- return /* @__PURE__ */ jsxs7(
1264
+ return /* @__PURE__ */ jsx14(StudioShadowRoot, { children: /* @__PURE__ */ jsxs7(
1146
1265
  SidebarProvider,
1147
1266
  {
1148
1267
  defaultOpen: sidebarOpen,
1149
- "data-preview-layout": previewComponent ? "canvas" : handle?.definition.previewLayout ?? "canvas",
1268
+ "data-preview-layout": previewComponent ? "canvas" : definition?.previewLayout ?? "canvas",
1269
+ "data-sidebar-panel": hidden.left ? "hidden" : "shown",
1150
1270
  className: "studio-workspace relative h-svh min-h-0 overflow-hidden text-xs",
1151
1271
  children: [
1152
- handle?.definition.preview ? /* @__PURE__ */ jsx13(
1272
+ definition?.preview ? /* @__PURE__ */ jsx14(
1153
1273
  Preview,
1154
1274
  {
1155
1275
  "data-slot": "studio-preview",
1156
1276
  ref: preview,
1157
- src: handle.definition.preview,
1158
- title: handle.definition.title ?? handle.definition.id,
1159
- onLoad: (event) => forwardShortcuts(event.currentTarget)
1277
+ src: definition.preview,
1278
+ title: definition.title ?? definition.id,
1279
+ onLoad: (event) => forwardShortcuts(event.currentTarget),
1280
+ ...Preview === PreviewCanvas && { expanded: canvasExpanded, onExpandedChange: setCanvasExpanded }
1160
1281
  },
1161
- handle.definition.id
1162
- ) : /* @__PURE__ */ jsx13("div", { className: "absolute inset-0 grid place-items-center text-faint", children: handle ? "This tool has no preview" : "No tools registered" }),
1163
- panelsHidden && ["left", "right"].map((side) => {
1282
+ definition.id
1283
+ ) : /* @__PURE__ */ jsx14("div", { className: "absolute inset-0 grid place-items-center text-faint", children: definition ? "This tool has no preview" : "No tools registered" }),
1284
+ ["left", "right"].filter((side) => hidden[side] && (side === "left" || handle)).map((side) => {
1164
1285
  const Chevron = side === "left" ? ChevronRight : ChevronLeft;
1165
- return /* @__PURE__ */ jsx13(
1286
+ const label = side === "left" ? "Show tools" : "Show inspector";
1287
+ return /* @__PURE__ */ jsx14(
1166
1288
  "div",
1167
1289
  {
1168
1290
  "data-slot": "studio-panel-edge",
1169
1291
  "data-side": side,
1170
1292
  className: cn("group/edge absolute inset-y-0 z-20 w-8", side === "left" ? "left-0" : "right-0"),
1171
- children: /* @__PURE__ */ jsx13(
1293
+ children: /* @__PURE__ */ jsx14(
1172
1294
  Hint,
1173
1295
  {
1174
1296
  side: side === "left" ? "right" : "left",
1175
1297
  sideOffset: 8,
1176
1298
  className: "flex items-center gap-2",
1177
1299
  content: /* @__PURE__ */ jsxs7(Fragment2, { children: [
1178
- "Show Studio panels",
1300
+ label,
1179
1301
  " ",
1302
+ /* @__PURE__ */ jsx14("span", { className: "text-faint", children: "\xB7 both" }),
1180
1303
  /* @__PURE__ */ jsxs7(KbdGroup, { children: [
1181
- /* @__PURE__ */ jsx13(Kbd, { children: "\u2318/Ctrl" }),
1182
- /* @__PURE__ */ jsx13(Kbd, { children: "B" })
1304
+ /* @__PURE__ */ jsx14(Kbd, { children: "\u2318/Ctrl" }),
1305
+ /* @__PURE__ */ jsx14(Kbd, { children: "B" })
1183
1306
  ] })
1184
1307
  ] }),
1185
- children: /* @__PURE__ */ jsx13(Panel, { asChild: true, children: /* @__PURE__ */ jsx13(
1308
+ children: /* @__PURE__ */ jsx14(Panel, { asChild: true, children: /* @__PURE__ */ jsx14(
1186
1309
  Button,
1187
1310
  {
1188
1311
  "data-slot": "studio-panel-reveal",
1189
1312
  variant: "ghost",
1190
1313
  size: "icon",
1191
- "aria-label": "Show Studio panels",
1192
- onClick: () => setPanelsHidden(false),
1314
+ "aria-label": label,
1315
+ onClick: show[side],
1193
1316
  className: cn(
1194
1317
  "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",
1195
1318
  side === "left" ? "left-1 -translate-x-[calc(100%+0.25rem)]" : "right-1 translate-x-[calc(100%+0.25rem)]"
1196
1319
  ),
1197
- children: /* @__PURE__ */ jsx13(Chevron, { "aria-hidden": true })
1320
+ children: /* @__PURE__ */ jsx14(Chevron, { "aria-hidden": true })
1198
1321
  }
1199
1322
  ) })
1200
1323
  }
@@ -1208,36 +1331,37 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1208
1331
  {
1209
1332
  collapsible: "icon",
1210
1333
  variant: "floating",
1211
- inert: panelsHidden,
1212
- "aria-hidden": panelsHidden,
1334
+ inert: hidden.left,
1335
+ "aria-hidden": hidden.left,
1213
1336
  className: cn(
1214
1337
  "transition-[left,right,width,translate] duration-200 ease-out motion-reduce:transition-none",
1215
- panelsHidden && "-translate-x-[calc(100%+1rem)]"
1338
+ hidden.left && "-translate-x-[calc(100%+1rem)]"
1216
1339
  ),
1217
1340
  children: [
1218
- /* @__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: [
1219
- /* @__PURE__ */ jsx13(Logo, { className: "h-3.5 w-auto shrink-0" }),
1220
- /* @__PURE__ */ jsx13("strong", { className: "tracking-[0.08em] whitespace-nowrap", children: "STUDIO" }),
1341
+ /* @__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: [
1342
+ /* @__PURE__ */ jsx14(Logo, { className: "h-3.5 w-auto shrink-0" }),
1343
+ /* @__PURE__ */ jsx14("strong", { className: "tracking-[0.08em] whitespace-nowrap", children: "STUDIO" }),
1221
1344
  /* @__PURE__ */ jsxs7("span", { "data-slot": "studio-version", className: "text-[10px] text-faint group-data-[collapsible=icon]:hidden", children: [
1222
1345
  "v",
1223
1346
  version
1224
1347
  ] })
1225
1348
  ] }) }),
1226
- /* @__PURE__ */ jsx13(SidebarContent, { children: /* @__PURE__ */ jsx13(SidebarGroup, { children: /* @__PURE__ */ jsx13(SidebarMenu, { children: tools.map(({ definition, state, dirty }) => {
1227
- const title = definition.title ?? definition.id;
1228
- const isPinned = pinned.has(definition.id);
1349
+ /* @__PURE__ */ jsx14(SidebarContent, { children: /* @__PURE__ */ jsx14(SidebarGroup, { children: /* @__PURE__ */ jsx14(SidebarMenu, { children: tools.map((tool) => {
1350
+ const title = tool.title ?? tool.id;
1351
+ const isPinned = pinned.has(tool.id);
1352
+ const { state, dirty } = studio.tools.find((handle2) => handle2.definition.id === tool.id) ?? {};
1229
1353
  const pinLabel = `${isPinned ? "Unpin" : "Pin"} ${title}`;
1230
1354
  return /* @__PURE__ */ jsxs7(SidebarMenuItem, { children: [
1231
1355
  /* @__PURE__ */ jsxs7(
1232
1356
  SidebarMenuButton,
1233
1357
  {
1234
- isActive: definition.id === selected,
1358
+ isActive: tool.id === selected,
1235
1359
  tooltip: title,
1236
- onClick: () => location.hash = definition.id,
1360
+ onClick: () => location.hash = tool.id,
1237
1361
  children: [
1238
1362
  /* @__PURE__ */ jsxs7("span", { className: "relative", children: [
1239
- /* @__PURE__ */ jsx13(ToolIcon, { icon: definition.icon, className: "size-4" }),
1240
- dirty && /* @__PURE__ */ jsx13(
1363
+ /* @__PURE__ */ jsx14(ToolIcon, { icon: tool.icon, className: "size-4" }),
1364
+ dirty && /* @__PURE__ */ jsx14(
1241
1365
  "span",
1242
1366
  {
1243
1367
  "aria-label": state?.conflict ? "Changed on disk" : "Unsaved",
@@ -1248,42 +1372,42 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1248
1372
  }
1249
1373
  )
1250
1374
  ] }),
1251
- /* @__PURE__ */ jsx13("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: title })
1375
+ /* @__PURE__ */ jsx14("span", { className: "text-clip! group-data-[collapsible=icon]:hidden", children: title })
1252
1376
  ]
1253
1377
  }
1254
1378
  ),
1255
- /* @__PURE__ */ jsx13(Hint, { content: pinLabel, side: "right", children: /* @__PURE__ */ jsx13(
1379
+ /* @__PURE__ */ jsx14(Hint, { content: pinLabel, side: "right", children: /* @__PURE__ */ jsx14(
1256
1380
  SidebarMenuAction,
1257
1381
  {
1258
1382
  type: "button",
1259
1383
  "aria-label": pinLabel,
1260
1384
  "aria-pressed": isPinned,
1261
1385
  showOnHover: !isPinned,
1262
- onClick: () => togglePin(definition.id),
1386
+ onClick: () => togglePin(tool.id),
1263
1387
  className: cn(
1264
1388
  "cursor-pointer [&>svg]:size-3 [@media(hover:none)]:opacity-100",
1265
1389
  isPinned && "text-sidebar-primary"
1266
1390
  ),
1267
- children: /* @__PURE__ */ jsx13(Pin2, { "aria-hidden": true, fill: isPinned ? "currentColor" : "none" })
1391
+ children: /* @__PURE__ */ jsx14(Pin2, { "aria-hidden": true, fill: isPinned ? "currentColor" : "none" })
1268
1392
  }
1269
1393
  ) })
1270
- ] }, definition.id);
1394
+ ] }, tool.id);
1271
1395
  }) }) }) }),
1272
- /* @__PURE__ */ jsx13(StudioFooter, { connection: studio.connection })
1396
+ /* @__PURE__ */ jsx14(StudioFooter, { connection: studio.connection })
1273
1397
  ]
1274
1398
  }
1275
1399
  ),
1276
- handle && /* @__PURE__ */ jsx13(Panel, { asChild: true, children: /* @__PURE__ */ jsx13(
1400
+ handle && /* @__PURE__ */ jsx14(Panel, { asChild: true, children: /* @__PURE__ */ jsx14(
1277
1401
  "aside",
1278
1402
  {
1279
1403
  "data-slot": "studio-inspector",
1280
- inert: panelsHidden,
1281
- "aria-hidden": panelsHidden,
1404
+ inert: hidden.right,
1405
+ "aria-hidden": hidden.right,
1282
1406
  className: cn(
1283
1407
  "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",
1284
- panelsHidden && "translate-x-[calc(100%+1rem)]"
1408
+ hidden.right && "translate-x-[calc(100%+1rem)]"
1285
1409
  ),
1286
- children: /* @__PURE__ */ jsx13(
1410
+ children: /* @__PURE__ */ jsx14(
1287
1411
  Inspector,
1288
1412
  {
1289
1413
  studio,
@@ -1297,21 +1421,36 @@ function Studio({ studio, previewComponent, getConfigFileHref }) {
1297
1421
  ) })
1298
1422
  ]
1299
1423
  }
1300
- );
1424
+ ) });
1425
+ }
1426
+
1427
+ // src/react/debug.tsx
1428
+ import { DebugManager } from "@joycostudio/xyz/debug";
1429
+ import { useEffect as useEffect6 } from "react";
1430
+ function StudioDebug({ studio }) {
1431
+ useEffect6(() => {
1432
+ const debug = new DebugManager({
1433
+ createPane: async () => new (await import("tweakpane")).Pane({ title: "debug" }),
1434
+ binding: { registerFrame: everyFrame }
1435
+ });
1436
+ for (const tool of studio.tools) debug.register(tool);
1437
+ return () => debug.dispose();
1438
+ }, [studio]);
1439
+ return null;
1301
1440
  }
1302
1441
 
1303
1442
  // src/react/command-menu.tsx
1443
+ import { Dialog } from "@base-ui/react/dialog";
1304
1444
  import { Pin as Pin3 } from "lucide-react";
1305
- import { Dialog } from "radix-ui";
1306
- import { useEffect as useEffect5, useRef as useRef4, useState as useState8 } from "react";
1445
+ import { useEffect as useEffect7, useRef as useRef4, useState as useState10 } from "react";
1307
1446
 
1308
1447
  // src/react/ui/command.tsx
1309
1448
  import * as React3 from "react";
1310
1449
  import { Command as CommandPrimitive } from "cmdk";
1311
1450
  import { SearchIcon } from "lucide-react";
1312
- import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
1451
+ import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
1313
1452
  function Command({ className, ...props }) {
1314
- return /* @__PURE__ */ jsx14(
1453
+ return /* @__PURE__ */ jsx15(
1315
1454
  CommandPrimitive,
1316
1455
  {
1317
1456
  "data-slot": "command",
@@ -1325,8 +1464,8 @@ function Command({ className, ...props }) {
1325
1464
  }
1326
1465
  var CommandInput = React3.forwardRef(function CommandInput2({ className, ...props }, ref) {
1327
1466
  return /* @__PURE__ */ jsxs8("div", { "data-slot": "command-input-wrapper", className: "flex h-9 items-center gap-2 border-b px-3", children: [
1328
- /* @__PURE__ */ jsx14(SearchIcon, { "aria-hidden": true, className: "size-4 shrink-0 opacity-50" }),
1329
- /* @__PURE__ */ jsx14(
1467
+ /* @__PURE__ */ jsx15(SearchIcon, { "aria-hidden": true, className: "size-4 shrink-0 opacity-50" }),
1468
+ /* @__PURE__ */ jsx15(
1330
1469
  CommandPrimitive.Input,
1331
1470
  {
1332
1471
  ref,
@@ -1341,7 +1480,7 @@ var CommandInput = React3.forwardRef(function CommandInput2({ className, ...prop
1341
1480
  ] });
1342
1481
  });
1343
1482
  function CommandList({ className, ...props }) {
1344
- return /* @__PURE__ */ jsx14(
1483
+ return /* @__PURE__ */ jsx15(
1345
1484
  CommandPrimitive.List,
1346
1485
  {
1347
1486
  "data-slot": "command-list",
@@ -1351,10 +1490,10 @@ function CommandList({ className, ...props }) {
1351
1490
  );
1352
1491
  }
1353
1492
  function CommandEmpty({ ...props }) {
1354
- return /* @__PURE__ */ jsx14(CommandPrimitive.Empty, { "data-slot": "command-empty", className: "py-6 text-center text-sm", ...props });
1493
+ return /* @__PURE__ */ jsx15(CommandPrimitive.Empty, { "data-slot": "command-empty", className: "py-6 text-center text-sm", ...props });
1355
1494
  }
1356
1495
  function CommandItem({ className, ...props }) {
1357
- return /* @__PURE__ */ jsx14(
1496
+ return /* @__PURE__ */ jsx15(
1358
1497
  CommandPrimitive.Item,
1359
1498
  {
1360
1499
  "data-slot": "command-item",
@@ -1368,26 +1507,35 @@ function CommandItem({ className, ...props }) {
1368
1507
  }
1369
1508
 
1370
1509
  // src/react/command-menu.tsx
1371
- import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
1372
- function StudioCommandMenu({ studio, studioPath = "/studio", navigate }) {
1510
+ import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
1511
+ function StudioCommandMenu(props) {
1512
+ return /* @__PURE__ */ jsx16(StudioShadowRoot, { children: /* @__PURE__ */ jsx16(CommandMenu, { ...props }) });
1513
+ }
1514
+ function CommandMenu({ studio, studioPath = "/studio", navigate }) {
1373
1515
  const { tools, pinned } = usePinnedTools(studio);
1374
- const [open, setOpen] = useState8(false);
1375
- const opener = useRef4(null);
1516
+ const [open, setOpen] = useState10(false);
1517
+ const [session, setSession] = useState10(0);
1518
+ const isOpen = useRef4(open);
1519
+ isOpen.current = open;
1520
+ const show = (next) => {
1521
+ if (next && !isOpen.current) setSession((count) => count + 1);
1522
+ setOpen(next);
1523
+ };
1376
1524
  const input = useRef4(null);
1377
- useEffect5(() => {
1525
+ useEffect7(() => {
1378
1526
  if (window.frameElement?.getAttribute("data-slot") === "studio-preview") return;
1379
1527
  const onKey = (event) => {
1380
1528
  if (event.defaultPrevented || event.isComposing || event.altKey || !(event.metaKey || event.ctrlKey)) return;
1381
1529
  if (event.key.toLowerCase() !== "k") return;
1382
1530
  event.preventDefault();
1383
1531
  if (event.repeat) return;
1384
- setOpen((current) => !current);
1532
+ show(!isOpen.current);
1385
1533
  };
1386
1534
  window.addEventListener("keydown", onKey);
1387
1535
  return () => window.removeEventListener("keydown", onKey);
1388
1536
  }, []);
1389
1537
  const select = (id) => {
1390
- setOpen(false);
1538
+ show(false);
1391
1539
  const target = new URL(studioPath, window.location.href);
1392
1540
  target.hash = id;
1393
1541
  if (target.pathname === window.location.pathname) {
@@ -1398,75 +1546,73 @@ function StudioCommandMenu({ studio, studioPath = "/studio", navigate }) {
1398
1546
  window.location.assign(target.href);
1399
1547
  }
1400
1548
  };
1401
- return /* @__PURE__ */ jsx15(Dialog.Root, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs9(Dialog.Portal, { children: [
1402
- /* @__PURE__ */ jsx15(Dialog.Overlay, { "data-slot": "studio-command-overlay" }),
1403
- /* @__PURE__ */ jsxs9(
1404
- Dialog.Content,
1405
- {
1406
- "data-slot": "studio-command-menu",
1407
- onOpenAutoFocus: (event) => {
1408
- event.preventDefault();
1409
- opener.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
1410
- input.current?.focus();
1411
- },
1412
- onCloseAutoFocus: (event) => {
1413
- event.preventDefault();
1414
- opener.current?.focus();
1415
- },
1416
- children: [
1417
- /* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-heading", children: [
1418
- /* @__PURE__ */ jsxs9(Dialog.Title, { "aria-label": "Studio tools", children: [
1419
- /* @__PURE__ */ jsx15(Logo, { "aria-hidden": true }),
1420
- /* @__PURE__ */ jsx15("strong", { children: "STUDIO" })
1421
- ] }),
1422
- /* @__PURE__ */ jsx15(Dialog.Close, { "aria-label": "Close tool menu", children: /* @__PURE__ */ jsx15(Kbd, { children: "esc" }) })
1423
- ] }),
1424
- /* @__PURE__ */ jsx15(Dialog.Description, { "data-slot": "studio-command-description", children: "Open a tool in Studio." }),
1425
- /* @__PURE__ */ jsxs9(Command, { label: "Studio tools", loop: true, vimBindings: false, children: [
1426
- /* @__PURE__ */ jsx15(CommandInput, { ref: input, placeholder: "Search tools\u2026" }),
1427
- /* @__PURE__ */ jsxs9(CommandList, { children: [
1428
- /* @__PURE__ */ jsx15(CommandEmpty, { children: studio.tools.length ? "No tools found." : "No tools registered yet." }),
1429
- tools.map(({ definition: tool }) => /* @__PURE__ */ jsxs9(
1430
- CommandItem,
1431
- {
1432
- value: tool.id,
1433
- keywords: [tool.title ?? tool.id],
1434
- onSelect: () => select(tool.id),
1435
- children: [
1436
- /* @__PURE__ */ jsx15(ToolIcon, { icon: tool.icon }),
1437
- /* @__PURE__ */ jsx15("span", { "data-slot": "studio-command-label", children: tool.title ?? tool.id }),
1438
- pinned.has(tool.id) && /* @__PURE__ */ jsx15(Pin3, { "aria-hidden": true })
1439
- ]
1440
- },
1441
- tool.id
1442
- ))
1443
- ] })
1549
+ return /* @__PURE__ */ jsx16(Dialog.Root, { open, onOpenChange: show, children: /* @__PURE__ */ jsxs9(Dialog.Portal, { container: usePortalContainer(), children: [
1550
+ /* @__PURE__ */ jsx16(Dialog.Backdrop, { "data-slot": "studio-command-overlay" }),
1551
+ /* @__PURE__ */ jsxs9(Dialog.Popup, { "data-slot": "studio-command-menu", initialFocus: input, children: [
1552
+ /* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-heading", children: [
1553
+ /* @__PURE__ */ jsxs9(Dialog.Title, { "aria-label": "Studio tools", children: [
1554
+ /* @__PURE__ */ jsx16(Logo, { "aria-hidden": true }),
1555
+ /* @__PURE__ */ jsx16("strong", { children: "STUDIO" })
1556
+ ] }),
1557
+ /* @__PURE__ */ jsx16(Dialog.Close, { "aria-label": "Close tool menu", children: /* @__PURE__ */ jsx16(Kbd, { children: "esc" }) })
1558
+ ] }),
1559
+ /* @__PURE__ */ jsx16(Dialog.Description, { "data-slot": "studio-command-description", children: "Open a tool in Studio." }),
1560
+ /* @__PURE__ */ jsxs9(Command, { label: "Studio tools", loop: true, vimBindings: false, children: [
1561
+ /* @__PURE__ */ jsx16(CommandInput, { ref: input, placeholder: "Search tools\u2026" }),
1562
+ /* @__PURE__ */ jsxs9(CommandList, { children: [
1563
+ /* @__PURE__ */ jsx16(CommandEmpty, { children: studio.definitions.length ? "No tools found." : "No tools registered yet." }),
1564
+ tools.map((tool) => /* @__PURE__ */ jsxs9(
1565
+ CommandItem,
1566
+ {
1567
+ value: tool.id,
1568
+ keywords: [tool.title ?? tool.id],
1569
+ onSelect: () => select(tool.id),
1570
+ children: [
1571
+ /* @__PURE__ */ jsx16(ToolIcon, { icon: tool.icon }),
1572
+ /* @__PURE__ */ jsx16("span", { "data-slot": "studio-command-label", children: tool.title ?? tool.id }),
1573
+ pinned.has(tool.id) && /* @__PURE__ */ jsx16(Pin3, { "aria-hidden": true })
1574
+ ]
1575
+ },
1576
+ tool.id
1577
+ ))
1578
+ ] })
1579
+ ] }, session),
1580
+ /* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-footer", "aria-hidden": true, children: [
1581
+ /* @__PURE__ */ jsxs9("span", { children: [
1582
+ /* @__PURE__ */ jsxs9(KbdGroup, { children: [
1583
+ /* @__PURE__ */ jsx16(Kbd, { children: "\u2191" }),
1584
+ /* @__PURE__ */ jsx16(Kbd, { children: "\u2193" })
1444
1585
  ] }),
1445
- /* @__PURE__ */ jsxs9("div", { "data-slot": "studio-command-footer", "aria-hidden": true, children: [
1446
- /* @__PURE__ */ jsxs9("span", { children: [
1447
- /* @__PURE__ */ jsxs9(KbdGroup, { children: [
1448
- /* @__PURE__ */ jsx15(Kbd, { children: "\u2191" }),
1449
- /* @__PURE__ */ jsx15(Kbd, { children: "\u2193" })
1450
- ] }),
1451
- "navigate"
1452
- ] }),
1453
- /* @__PURE__ */ jsxs9("span", { children: [
1454
- /* @__PURE__ */ jsx15(Kbd, { children: "\u21B5" }),
1455
- " open tool"
1456
- ] })
1457
- ] })
1458
- ]
1459
- }
1460
- )
1586
+ "navigate"
1587
+ ] }),
1588
+ /* @__PURE__ */ jsxs9("span", { children: [
1589
+ /* @__PURE__ */ jsx16(Kbd, { children: "\u21B5" }),
1590
+ " open tool"
1591
+ ] })
1592
+ ] })
1593
+ ] })
1461
1594
  ] }) });
1462
1595
  }
1463
1596
 
1464
1597
  // src/react/select.tsx
1598
+ import { Select } from "@base-ui/react/select";
1465
1599
  import { Check, ChevronDown, ChevronUp } from "lucide-react";
1466
- import { Select } from "radix-ui";
1467
- import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
1600
+
1601
+ // src/react/select-labels.ts
1602
+ import { Children, isValidElement } from "react";
1603
+ function itemLabels(children, labels = {}) {
1604
+ Children.forEach(children, (child) => {
1605
+ if (!isValidElement(child)) return;
1606
+ if (typeof child.props.value === "string") labels[child.props.value] = child.props.children;
1607
+ else itemLabels(child.props.children, labels);
1608
+ });
1609
+ return labels;
1610
+ }
1611
+
1612
+ // src/react/select.tsx
1613
+ import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
1468
1614
  function StudioSelect({ label, title, className, children, ...props }) {
1469
- return /* @__PURE__ */ jsxs10(Select.Root, { ...props, children: [
1615
+ return /* @__PURE__ */ jsxs10(Select.Root, { items: itemLabels(children), ...props, children: [
1470
1616
  /* @__PURE__ */ jsxs10(
1471
1617
  Select.Trigger,
1472
1618
  {
@@ -1478,26 +1624,23 @@ function StudioSelect({ label, title, className, children, ...props }) {
1478
1624
  className
1479
1625
  ),
1480
1626
  children: [
1481
- /* @__PURE__ */ jsx16(Select.Value, {}),
1482
- /* @__PURE__ */ jsx16(Select.Icon, { children: /* @__PURE__ */ jsx16(ChevronDown, { className: "shrink-0 text-muted-foreground", size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
1627
+ /* @__PURE__ */ jsx17(Select.Value, {}),
1628
+ /* @__PURE__ */ jsx17(Select.Icon, { children: /* @__PURE__ */ jsx17(ChevronDown, { className: "shrink-0 text-muted-foreground", size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
1483
1629
  ]
1484
1630
  }
1485
1631
  ),
1486
- /* @__PURE__ */ jsx16(Select.Portal, { children: /* @__PURE__ */ jsxs10(
1487
- Select.Content,
1632
+ /* @__PURE__ */ jsx17(Select.Portal, { container: usePortalContainer(), children: /* @__PURE__ */ jsx17(Select.Positioner, { align: "end", sideOffset: 6, alignItemWithTrigger: false, className: "isolate z-50", children: /* @__PURE__ */ jsxs10(
1633
+ Select.Popup,
1488
1634
  {
1489
- 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",
1635
+ 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",
1490
1636
  "data-slot": "select-content",
1491
- position: "popper",
1492
- align: "end",
1493
- sideOffset: 6,
1494
1637
  children: [
1495
- /* @__PURE__ */ jsx16(Select.ScrollUpButton, { className: "flex justify-center py-1", children: /* @__PURE__ */ jsx16(ChevronUp, { size: 14, "aria-hidden": true }) }),
1496
- /* @__PURE__ */ jsx16(Select.Viewport, { className: "p-1", children }),
1497
- /* @__PURE__ */ jsx16(Select.ScrollDownButton, { className: "flex justify-center py-1", children: /* @__PURE__ */ jsx16(ChevronDown, { size: 14, "aria-hidden": true }) })
1638
+ /* @__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 }) }),
1639
+ /* @__PURE__ */ jsx17(Select.List, { children }),
1640
+ /* @__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 }) })
1498
1641
  ]
1499
1642
  }
1500
- ) })
1643
+ ) }) })
1501
1644
  ] });
1502
1645
  }
1503
1646
  function StudioSelectItem({ className, children, ...props }) {
@@ -1511,8 +1654,8 @@ function StudioSelectItem({ className, children, ...props }) {
1511
1654
  ),
1512
1655
  ...props,
1513
1656
  children: [
1514
- /* @__PURE__ */ jsx16(Select.ItemText, { children }),
1515
- /* @__PURE__ */ jsx16(Select.ItemIndicator, { className: "absolute right-2", children: /* @__PURE__ */ jsx16(Check, { size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
1657
+ /* @__PURE__ */ jsx17(Select.ItemText, { children }),
1658
+ /* @__PURE__ */ jsx17(Select.ItemIndicator, { className: "absolute right-2", children: /* @__PURE__ */ jsx17(Check, { size: 14, strokeWidth: 1.5, "aria-hidden": true }) })
1516
1659
  ]
1517
1660
  }
1518
1661
  );
@@ -1520,9 +1663,9 @@ function StudioSelectItem({ className, children, ...props }) {
1520
1663
 
1521
1664
  // src/react/ui/input.tsx
1522
1665
  import { forwardRef as forwardRef5 } from "react";
1523
- import { jsx as jsx17 } from "react/jsx-runtime";
1666
+ import { jsx as jsx18 } from "react/jsx-runtime";
1524
1667
  var Input = forwardRef5(function Input2({ className, ...props }, ref) {
1525
- return /* @__PURE__ */ jsx17(
1668
+ return /* @__PURE__ */ jsx18(
1526
1669
  "input",
1527
1670
  {
1528
1671
  ref,
@@ -1540,6 +1683,7 @@ export {
1540
1683
  PreviewCanvas,
1541
1684
  Studio,
1542
1685
  StudioCommandMenu,
1686
+ StudioDebug,
1543
1687
  Input as StudioInput,
1544
1688
  Panel as StudioPanel,
1545
1689
  PanelContent as StudioPanelContent,