@hai3/studio 0.4.0-alpha.0 → 0.4.0-alpha.1

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/README.md CHANGED
@@ -125,8 +125,6 @@ Apache-2.0
125
125
  ## Related Packages
126
126
 
127
127
  - [`@hai3/uicore`](../uicore) - Core layout and state management
128
- - [`@hai3/uikit`](../uikit) - UI component library
129
- - [`@hai3/uikit-contracts`](../uikit-contracts) - Type definitions
130
128
 
131
129
  ## Contributing
132
130
 
package/dist/index.cjs CHANGED
@@ -3,12 +3,37 @@
3
3
  var React2 = require('react');
4
4
  var react = require('@hai3/react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
- var uikit = require('@hai3/uikit');
6
+ var clsx = require('clsx');
7
+ var tailwindMerge = require('tailwind-merge');
8
+ var reactSlot = require('@radix-ui/react-slot');
9
+ var classVarianceAuthority = require('class-variance-authority');
7
10
  var lodash = require('lodash');
11
+ var DropdownMenuPrimitive = require('@radix-ui/react-dropdown-menu');
12
+ var SwitchPrimitives = require('@radix-ui/react-switch');
8
13
 
9
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
15
 
16
+ function _interopNamespace(e) {
17
+ if (e && e.__esModule) return e;
18
+ var n = Object.create(null);
19
+ if (e) {
20
+ Object.keys(e).forEach(function (k) {
21
+ if (k !== 'default') {
22
+ var d = Object.getOwnPropertyDescriptor(e, k);
23
+ Object.defineProperty(n, k, d.get ? d : {
24
+ enumerable: true,
25
+ get: function () { return e[k]; }
26
+ });
27
+ }
28
+ });
29
+ }
30
+ n.default = e;
31
+ return Object.freeze(n);
32
+ }
33
+
11
34
  var React2__default = /*#__PURE__*/_interopDefault(React2);
35
+ var DropdownMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(DropdownMenuPrimitive);
36
+ var SwitchPrimitives__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitives);
12
37
 
13
38
  var __create = Object.create;
14
39
  var __defProp = Object.defineProperty;
@@ -1061,6 +1086,69 @@ var StudioProvider = ({ children }) => {
1061
1086
  );
1062
1087
  };
1063
1088
  StudioProvider.displayName = "StudioProvider";
1089
+ function cn(...inputs) {
1090
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
1091
+ }
1092
+ var Card = ({
1093
+ ref,
1094
+ className,
1095
+ ...props
1096
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
1097
+ "div",
1098
+ {
1099
+ ref,
1100
+ className: cn(
1101
+ "rounded-xl border bg-card text-card-foreground shadow",
1102
+ className
1103
+ ),
1104
+ ...props
1105
+ }
1106
+ );
1107
+ Card.displayName = "Card";
1108
+ var buttonVariants = classVarianceAuthority.cva(
1109
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
1110
+ {
1111
+ variants: {
1112
+ variant: {
1113
+ ["default" /* Default */]: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
1114
+ ["destructive" /* Destructive */]: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
1115
+ ["outline" /* Outline */]: "border border-input bg-background text-foreground shadow-sm hover:bg-accent data-[state=open]:bg-accent",
1116
+ ["secondary" /* Secondary */]: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
1117
+ ["ghost" /* Ghost */]: "hover:bg-accent data-[state=open]:bg-accent",
1118
+ ["link" /* Link */]: "text-primary underline-offset-4 hover:underline"
1119
+ },
1120
+ size: {
1121
+ ["default" /* Default */]: "h-9 px-4 py-2",
1122
+ ["sm" /* Sm */]: "h-8 rounded-md px-3 text-xs",
1123
+ ["lg" /* Lg */]: "h-10 rounded-md px-8",
1124
+ ["icon" /* Icon */]: "h-9 w-9"
1125
+ }
1126
+ },
1127
+ defaultVariants: {
1128
+ variant: "default" /* Default */,
1129
+ size: "default" /* Default */
1130
+ }
1131
+ }
1132
+ );
1133
+ var Button = ({
1134
+ ref,
1135
+ className,
1136
+ variant,
1137
+ size,
1138
+ asChild = false,
1139
+ ...props
1140
+ }) => {
1141
+ const Comp = asChild ? reactSlot.Slot : "button";
1142
+ return /* @__PURE__ */ jsxRuntime.jsx(
1143
+ Comp,
1144
+ {
1145
+ className: cn(buttonVariants({ variant, size, className })),
1146
+ ref,
1147
+ ...props
1148
+ }
1149
+ );
1150
+ };
1151
+ Button.displayName = "Button";
1064
1152
  var VIEWPORT_MARGIN = 20;
1065
1153
  function clampToViewport(pos, size) {
1066
1154
  const maxX = Math.max(VIEWPORT_MARGIN, window.innerWidth - size.width - VIEWPORT_MARGIN);
@@ -1190,6 +1278,90 @@ var useResizable = () => {
1190
1278
  handleMouseDown
1191
1279
  };
1192
1280
  };
1281
+ var DropdownMenu = ({
1282
+ dir,
1283
+ ...props
1284
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
1285
+ DropdownMenuPrimitive__namespace.Root,
1286
+ {
1287
+ ...props,
1288
+ dir
1289
+ }
1290
+ );
1291
+ DropdownMenu.displayName = "DropdownMenu";
1292
+ var DropdownMenuTrigger = DropdownMenuPrimitive__namespace.Trigger;
1293
+ var DropdownMenuContent = ({
1294
+ ref,
1295
+ className,
1296
+ sideOffset = 4,
1297
+ container,
1298
+ ...props
1299
+ }) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
1300
+ DropdownMenuPrimitive__namespace.Content,
1301
+ {
1302
+ ref,
1303
+ sideOffset,
1304
+ style: { backgroundColor: "hsl(var(--background, 0 0% 100%))" },
1305
+ className: cn(
1306
+ "z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
1307
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]: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 origin-[--radix-dropdown-menu-content-transform-origin]",
1308
+ className
1309
+ ),
1310
+ ...props
1311
+ }
1312
+ ) });
1313
+ DropdownMenuContent.displayName = DropdownMenuPrimitive__namespace.Content.displayName;
1314
+ var DropdownMenuItem = ({
1315
+ ref,
1316
+ className,
1317
+ inset,
1318
+ ...props
1319
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
1320
+ DropdownMenuPrimitive__namespace.Item,
1321
+ {
1322
+ ref,
1323
+ className: cn(
1324
+ "relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
1325
+ inset && "pl-8",
1326
+ className
1327
+ ),
1328
+ ...props
1329
+ }
1330
+ );
1331
+ DropdownMenuItem.displayName = DropdownMenuPrimitive__namespace.Item.displayName;
1332
+ var ChevronDownIcon = ({ className = "" }) => /* @__PURE__ */ jsxRuntime.jsx(
1333
+ "svg",
1334
+ {
1335
+ className,
1336
+ fill: "none",
1337
+ stroke: "currentColor",
1338
+ strokeWidth: 2,
1339
+ viewBox: "0 0 24 24",
1340
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
1341
+ }
1342
+ );
1343
+ var DropdownButton = ({
1344
+ ref,
1345
+ children,
1346
+ variant = "outline" /* Outline */,
1347
+ className,
1348
+ ...props
1349
+ }) => {
1350
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1351
+ Button,
1352
+ {
1353
+ ref,
1354
+ variant,
1355
+ className: cn("min-w-40 justify-between rtl:flex-row-reverse", className),
1356
+ ...props,
1357
+ children: [
1358
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children }),
1359
+ /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { className: "h-4 w-4" })
1360
+ ]
1361
+ }
1362
+ );
1363
+ };
1364
+ DropdownButton.displayName = "DropdownButton";
1193
1365
  function isScreenExtension2(ext) {
1194
1366
  return "presentation" in ext && typeof ext.presentation === "object";
1195
1367
  }
@@ -1227,17 +1399,17 @@ var MfePackageSelector = ({
1227
1399
  };
1228
1400
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
1229
1401
  /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.gts_package") }),
1230
- /* @__PURE__ */ jsxRuntime.jsxs(uikit.DropdownMenu, { children: [
1231
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1232
- uikit.DropdownButton,
1402
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
1403
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1404
+ DropdownButton,
1233
1405
  {
1234
- variant: uikit.ButtonVariant.Outline,
1406
+ variant: "outline" /* Outline */,
1235
1407
  disabled: packages.length <= 1,
1236
1408
  children: activePackage || "No package"
1237
1409
  }
1238
1410
  ) }),
1239
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: packages.map((pkg) => /* @__PURE__ */ jsxRuntime.jsx(
1240
- uikit.DropdownMenuItem,
1411
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: packages.map((pkg) => /* @__PURE__ */ jsxRuntime.jsx(
1412
+ DropdownMenuItem,
1241
1413
  {
1242
1414
  onClick: () => handlePackageChange(pkg),
1243
1415
  children: pkg
@@ -1259,10 +1431,10 @@ var ThemeSelector = ({
1259
1431
  };
1260
1432
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
1261
1433
  /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.theme") }),
1262
- /* @__PURE__ */ jsxRuntime.jsxs(uikit.DropdownMenu, { children: [
1263
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownButton, { variant: uikit.ButtonVariant.Outline, children: formatThemeName(currentTheme || "") }) }),
1264
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: themes.map((theme) => /* @__PURE__ */ jsxRuntime.jsx(
1265
- uikit.DropdownMenuItem,
1434
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
1435
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownButton, { variant: "outline" /* Outline */, children: formatThemeName(currentTheme || "") }) }),
1436
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: themes.map((theme) => /* @__PURE__ */ jsxRuntime.jsx(
1437
+ DropdownMenuItem,
1266
1438
  {
1267
1439
  onClick: () => setTheme(theme.id),
1268
1440
  children: formatThemeName(theme.name || theme.id)
@@ -1283,10 +1455,10 @@ function LanguageSelector({
1283
1455
  const currentLanguage = language ? react.getLanguageMetadata(language) : null;
1284
1456
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
1285
1457
  /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.language") }),
1286
- /* @__PURE__ */ jsxRuntime.jsxs(uikit.DropdownMenu, { children: [
1287
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(uikit.Button, { variant: uikit.ButtonVariant.Outline, children: currentLanguage ? displayMode === react.LanguageDisplayMode.Native ? currentLanguage.name : currentLanguage.englishName : FALLBACK_SELECT_LANGUAGE_TEXT }) }),
1288
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: react.SUPPORTED_LANGUAGES.map((lang) => /* @__PURE__ */ jsxRuntime.jsxs(
1289
- uikit.DropdownMenuItem,
1458
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
1459
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline" /* Outline */, children: currentLanguage ? displayMode === react.LanguageDisplayMode.Native ? currentLanguage.name : currentLanguage.englishName : FALLBACK_SELECT_LANGUAGE_TEXT }) }),
1460
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: react.SUPPORTED_LANGUAGES.map((lang) => /* @__PURE__ */ jsxRuntime.jsxs(
1461
+ DropdownMenuItem,
1290
1462
  {
1291
1463
  onClick: () => setLanguage(lang.code),
1292
1464
  children: [
@@ -1299,6 +1471,32 @@ function LanguageSelector({
1299
1471
  ] })
1300
1472
  ] });
1301
1473
  }
1474
+ var Switch = ({
1475
+ ref,
1476
+ className,
1477
+ ...props
1478
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
1479
+ SwitchPrimitives__namespace.Root,
1480
+ {
1481
+ className: cn(
1482
+ "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
1483
+ className
1484
+ ),
1485
+ ...props,
1486
+ ref,
1487
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1488
+ SwitchPrimitives__namespace.Thumb,
1489
+ {
1490
+ className: cn(
1491
+ "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform",
1492
+ "data-[state=checked]:ltr:translate-x-4 data-[state=checked]:rtl:-translate-x-4",
1493
+ "data-[state=unchecked]:translate-x-0"
1494
+ )
1495
+ }
1496
+ )
1497
+ }
1498
+ );
1499
+ Switch.displayName = SwitchPrimitives__namespace.Root.displayName;
1302
1500
  var ApiModeToggle = ({
1303
1501
  className
1304
1502
  }) => {
@@ -1320,7 +1518,7 @@ var ApiModeToggle = ({
1320
1518
  }
1321
1519
  ),
1322
1520
  /* @__PURE__ */ jsxRuntime.jsx(
1323
- uikit.Switch,
1521
+ Switch,
1324
1522
  {
1325
1523
  id: "api-mode-toggle",
1326
1524
  checked: enabled,
@@ -1374,7 +1572,7 @@ var StudioPanel = () => {
1374
1572
  width: `${size.width}px`,
1375
1573
  height: `${size.height}px`
1376
1574
  },
1377
- children: /* @__PURE__ */ jsxRuntime.jsxs(uikit.Card, { className: "h-full w-full flex flex-col overflow-hidden bg-white/20 dark:bg-black/50 backdrop-blur-md backdrop-saturate-[180%] border border-white/30 dark:border-white/20 shadow-[0_8px_32px_rgba(0,0,0,0.2)]", children: [
1575
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "h-full w-full flex flex-col overflow-hidden bg-white/20 dark:bg-black/50 backdrop-blur-md backdrop-saturate-[180%] border border-white/30 dark:border-white/20 shadow-[0_8px_32px_rgba(0,0,0,0.2)]", children: [
1378
1576
  /* @__PURE__ */ jsxRuntime.jsxs(
1379
1577
  "div",
1380
1578
  {
@@ -1384,10 +1582,10 @@ var StudioPanel = () => {
1384
1582
  children: [
1385
1583
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold text-foreground", children: t("studio:title") }),
1386
1584
  /* @__PURE__ */ jsxRuntime.jsx(
1387
- uikit.Button,
1585
+ Button,
1388
1586
  {
1389
- variant: uikit.ButtonVariant.Ghost,
1390
- size: uikit.ButtonSize.Sm,
1587
+ variant: "ghost" /* Ghost */,
1588
+ size: "sm" /* Sm */,
1391
1589
  onClick: toggleCollapsed,
1392
1590
  className: "h-7 w-7 p-0",
1393
1591
  "aria-label": t("studio:aria.collapseButton"),
@@ -1464,9 +1662,9 @@ var GlassmorphicButton = ({
1464
1662
  isDragging = false
1465
1663
  }) => {
1466
1664
  return /* @__PURE__ */ jsxRuntime.jsx(
1467
- uikit.Button,
1665
+ Button,
1468
1666
  {
1469
- variant: uikit.ButtonVariant.Ghost,
1667
+ variant: "ghost" /* Ghost */,
1470
1668
  onMouseDown,
1471
1669
  onClick,
1472
1670
  title,
@@ -1539,6 +1737,278 @@ var CollapsedButton = ({ toggleCollapsed }) => {
1539
1737
  );
1540
1738
  };
1541
1739
  CollapsedButton.displayName = "CollapsedButton";
1740
+
1741
+ // src/styles/studioStyles.ts
1742
+ var STUDIO_STYLE_ID = "hai3-studio-styles";
1743
+ var STUDIO_CSS = (
1744
+ /* css */
1745
+ `
1746
+ /* ============================================================
1747
+ HAI3 Studio \u2014 Self-contained utility styles
1748
+ ============================================================ */
1749
+
1750
+ /* --- Base normalization (Preflight may be absent in no-uikit hosts) ---
1751
+ :where() keeps specificity at 0-0-0 so utility classes always win. */
1752
+ .studio-panel,
1753
+ .studio-portal-container {
1754
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1755
+ line-height: 1.5;
1756
+ }
1757
+ :where(.studio-panel *, .studio-portal-container *) { box-sizing: border-box; }
1758
+ :where(.studio-panel button, .studio-portal-container button) {
1759
+ font-family: inherit;
1760
+ font-size: inherit;
1761
+ line-height: inherit;
1762
+ color: inherit;
1763
+ border: 0 solid transparent;
1764
+ background: transparent;
1765
+ padding: 0;
1766
+ margin: 0;
1767
+ cursor: pointer;
1768
+ }
1769
+ :where(.studio-panel h2, .studio-panel h3, .studio-portal-container h2, .studio-portal-container h3) {
1770
+ font-size: inherit;
1771
+ font-weight: inherit;
1772
+ margin: 0;
1773
+ }
1774
+
1775
+ /* --- Layout --- */
1776
+ .fixed { position: fixed; }
1777
+ .absolute { position: absolute; }
1778
+ .relative { position: relative; }
1779
+ .flex { display: flex; }
1780
+ .inline-flex { display: inline-flex; }
1781
+ .block { display: block; }
1782
+ .peer { /* Radix peer marker \u2014 no CSS needed */ }
1783
+ .flex-col { flex-direction: column; }
1784
+ .flex-1 { flex: 1 1 0%; }
1785
+ .shrink-0 { flex-shrink: 0; }
1786
+ .items-center { align-items: center; }
1787
+ .justify-between { justify-content: space-between; }
1788
+ .justify-center { justify-content: center; }
1789
+ .gap-2 { gap: 0.5rem; }
1790
+ .overflow-hidden { overflow: hidden; }
1791
+ .overflow-y-auto { overflow-y: auto; }
1792
+ .overflow-x-hidden { overflow-x: hidden; }
1793
+
1794
+ /* --- Sizing --- */
1795
+ .h-full { height: 100%; }
1796
+ .w-full { width: 100%; }
1797
+ .h-4 { height: 1rem; }
1798
+ .w-4 { width: 1rem; }
1799
+ .h-5 { height: 1.25rem; }
1800
+ .w-5 { width: 1.25rem; }
1801
+ .w-9 { width: 2.25rem; }
1802
+ .h-6 { height: 1.5rem; }
1803
+ .w-6 { width: 1.5rem; }
1804
+ .h-7 { height: 1.75rem; }
1805
+ .w-7 { width: 1.75rem; }
1806
+ .h-8 { height: 2rem; }
1807
+ .h-9 { height: 2.25rem; }
1808
+ .h-10 { height: 2.5rem; }
1809
+ .h-12 { height: 3rem; }
1810
+ .w-12 { width: 3rem; }
1811
+ .min-w-\\[8rem\\] { min-width: 8rem; }
1812
+ .min-w-40 { min-width: 10rem; }
1813
+
1814
+ /* --- Spacing --- */
1815
+ .p-0 { padding: 0; }
1816
+ .p-1 { padding: 0.25rem; }
1817
+ .p-4 { padding: 1rem; }
1818
+ .px-2 { padding-left: 0.5rem; padding-right: 0.5rem; }
1819
+ .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
1820
+ .px-4 { padding-left: 1rem; padding-right: 1rem; }
1821
+ .px-8 { padding-left: 2rem; padding-right: 2rem; }
1822
+ .py-1\\.5 { padding-top: 0.375rem; padding-bottom: 0.375rem; }
1823
+ .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
1824
+ .py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; }
1825
+ .pl-8 { padding-left: 2rem; }
1826
+ .bottom-1 { bottom: 0.25rem; }
1827
+ .right-1 { right: 0.25rem; }
1828
+ .space-y-3 > :not([hidden]) ~ :not([hidden]) { margin-top: 0.75rem; }
1829
+ .space-y-4 > :not([hidden]) ~ :not([hidden]) { margin-top: 1rem; }
1830
+
1831
+ /* --- Typography --- */
1832
+ .text-xs { font-size: 0.75rem; line-height: 1rem; }
1833
+ .text-sm { font-size: 0.875rem; line-height: 1.25rem; }
1834
+ .font-medium { font-weight: 500; }
1835
+ .font-semibold { font-weight: 600; }
1836
+ .uppercase { text-transform: uppercase; }
1837
+ .tracking-wider { letter-spacing: 0.05em; }
1838
+ .whitespace-nowrap { white-space: nowrap; }
1839
+
1840
+ /* --- Colors (theme-aware via CSS variables) ---
1841
+ Some theme variables (--popover-foreground, --card-foreground) may have
1842
+ incorrect values in third-party themes. The Studio maps all component
1843
+ colors to --foreground / --background which are always correct (body uses them).
1844
+ :where() ensures host-app Tailwind utilities take precedence when available. */
1845
+ .text-foreground { color: hsl(var(--foreground)); }
1846
+ .text-muted-foreground { color: hsl(var(--muted-foreground)); }
1847
+ .text-muted-foreground\\/70 { color: hsl(var(--muted-foreground) / 0.7); }
1848
+ :where(.bg-popover) { background-color: hsl(var(--background)); }
1849
+ :where(.text-popover-foreground) { color: hsl(var(--foreground)); }
1850
+ :where(.bg-accent) { background-color: hsl(var(--foreground) / 0.1); }
1851
+ :where(.text-accent-foreground) { color: hsl(var(--foreground)); }
1852
+ :where(.bg-background) { background-color: hsl(var(--background)); }
1853
+ :where(.bg-card) { background-color: hsl(var(--background)); }
1854
+ :where(.text-card-foreground) { color: hsl(var(--foreground)); }
1855
+ :where(.bg-primary) { background-color: hsl(var(--foreground)); }
1856
+ :where(.text-primary-foreground) { color: hsl(var(--background)); }
1857
+ :where(.bg-input) { background-color: hsl(var(--foreground) / 0.15); }
1858
+ :where(.border-input) { border-color: hsl(var(--foreground) / 0.2); }
1859
+ :where(.ring-ring) { --tw-ring-color: hsl(var(--foreground) / 0.5); }
1860
+ .border-transparent { border-color: transparent; }
1861
+
1862
+ /* --- Borders --- */
1863
+ .border { border-width: 1px; }
1864
+ .border-2 { border-width: 2px; }
1865
+ .border-b { border-bottom-width: 1px; }
1866
+ :where(.border-border\\/50) { border-color: hsl(var(--foreground) / 0.15); }
1867
+ .rounded-full { border-radius: 9999px; }
1868
+ .rounded-xl { border-radius: 0.75rem; }
1869
+ .rounded-md { border-radius: calc(var(--radius, 0.5rem) - 2px); }
1870
+ .rounded-sm { border-radius: calc(var(--radius, 0.5rem) - 4px); }
1871
+
1872
+ /* --- Interaction --- */
1873
+ .select-none { -webkit-user-select: none; user-select: none; }
1874
+ .cursor-pointer { cursor: pointer; }
1875
+ .cursor-default { cursor: default; }
1876
+ .cursor-nwse-resize { cursor: nwse-resize; }
1877
+ .pointer-events-none { pointer-events: none; }
1878
+ .pointer-events-auto { pointer-events: auto; }
1879
+ .outline-none { outline: 2px solid transparent; outline-offset: 2px; }
1880
+ .transition-colors {
1881
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
1882
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1883
+ transition-duration: 150ms;
1884
+ }
1885
+ .transition-transform {
1886
+ transition-property: transform;
1887
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1888
+ transition-duration: 150ms;
1889
+ }
1890
+
1891
+ /* --- Z-index (arbitrary values) --- */
1892
+ .z-\\[10000\\] { z-index: 10000; }
1893
+ .z-\\[99999\\] { z-index: 99999; }
1894
+
1895
+ /* --- Glassmorphic: background with opacity --- */
1896
+ .bg-white\\/20 { background-color: rgb(255 255 255 / 0.2); }
1897
+ .bg-white\\/30 { background-color: rgb(255 255 255 / 0.3); }
1898
+ .dark .dark\\:bg-black\\/50 { background-color: rgb(0 0 0 / 0.5); }
1899
+ .dark .dark\\:bg-black\\/60 { background-color: rgb(0 0 0 / 0.6); }
1900
+
1901
+ /* --- Glassmorphic: border with opacity --- */
1902
+ .border-white\\/30 { border-color: rgb(255 255 255 / 0.3); }
1903
+ .dark .dark\\:border-white\\/20 { border-color: rgb(255 255 255 / 0.2); }
1904
+
1905
+ /* --- Glassmorphic: backdrop filters --- */
1906
+ .backdrop-blur-md {
1907
+ --tw-backdrop-blur: blur(12px);
1908
+ -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, );
1909
+ 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, );
1910
+ }
1911
+ .backdrop-saturate-\\[180\\%\\] {
1912
+ --tw-backdrop-saturate: saturate(1.8);
1913
+ -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, );
1914
+ 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, );
1915
+ }
1916
+
1917
+ /* --- Glassmorphic: box shadow (arbitrary) --- */
1918
+ .shadow-\\[0_8px_32px_rgba\\(0\\,0\\,0\\,0\\.2\\)\\] {
1919
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
1920
+ }
1921
+
1922
+ /* --- Shadows --- */
1923
+ .shadow { box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); }
1924
+ .shadow-sm { box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); }
1925
+ .shadow-md { box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); }
1926
+ .shadow-lg { box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); }
1927
+ .ring-0 { box-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width, 0px)) var(--tw-ring-color, transparent); }
1928
+
1929
+ /* --- Hover states --- */
1930
+ .hover\\:bg-white\\/30:hover { background-color: rgb(255 255 255 / 0.3); }
1931
+ .dark .dark\\:hover\\:bg-black\\/60:hover { background-color: rgb(0 0 0 / 0.6); }
1932
+ .hover\\:text-muted-foreground:hover { color: hsl(var(--muted-foreground)); }
1933
+ :where(.hover\\:bg-accent:hover) { background-color: hsl(var(--foreground) / 0.1); }
1934
+ :where(.hover\\:bg-primary\\/90:hover) { background-color: hsl(var(--foreground) / 0.85); }
1935
+ :where(.hover\\:bg-secondary\\/80:hover) { background-color: hsl(var(--foreground) / 0.08); }
1936
+ :where(.hover\\:bg-destructive\\/90:hover) { background-color: hsl(0 60% 50% / 0.9); }
1937
+
1938
+ /* --- Focus states --- */
1939
+ :where(.focus\\:bg-accent:focus) { background-color: hsl(var(--foreground) / 0.1); }
1940
+ :where(.focus\\:text-foreground:focus) { color: hsl(var(--foreground)); }
1941
+ :where(.focus\\:text-accent-foreground:focus) { color: hsl(var(--foreground)); }
1942
+ .focus-visible\\:outline-none:focus-visible { outline: 2px solid transparent; outline-offset: 2px; }
1943
+ :where(.focus-visible\\:ring-1:focus-visible) {
1944
+ box-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width, 0px)) var(--tw-ring-color, hsl(var(--foreground) / 0.5));
1945
+ }
1946
+ :where(.focus-visible\\:ring-2:focus-visible) {
1947
+ box-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width, 0px)) var(--tw-ring-color, hsl(var(--foreground) / 0.5));
1948
+ }
1949
+ :where(.focus-visible\\:ring-ring:focus-visible) { --tw-ring-color: hsl(var(--foreground) / 0.5); }
1950
+ :where(.focus-visible\\:ring-offset-2:focus-visible) { --tw-ring-offset-width: 2px; }
1951
+ :where(.focus-visible\\:ring-offset-background:focus-visible) { --tw-ring-offset-color: hsl(var(--background)); }
1952
+
1953
+ /* --- Data-attribute & disabled states --- */
1954
+ :where(.data-\\[state\\=open\\]\\:bg-accent[data-state=open]) { background-color: hsl(var(--foreground) / 0.1); }
1955
+ :where(.data-\\[state\\=checked\\]\\:bg-primary[data-state=checked]) { background-color: hsl(var(--foreground)); }
1956
+ :where(.data-\\[state\\=unchecked\\]\\:bg-input[data-state=unchecked]) { background-color: hsl(var(--foreground) / 0.15); }
1957
+ .data-\\[disabled\\]\\:pointer-events-none[data-disabled] { pointer-events: none; }
1958
+ .data-\\[disabled\\]\\:opacity-50[data-disabled] { opacity: 0.5; }
1959
+ .disabled\\:pointer-events-none:disabled { pointer-events: none; }
1960
+ .disabled\\:opacity-50:disabled { opacity: 0.5; }
1961
+ .disabled\\:cursor-not-allowed:disabled { cursor: not-allowed; }
1962
+
1963
+ /* --- SVG child selectors --- */
1964
+ [class*="[&>svg]:size-4"] > svg,
1965
+ [class*="[&_svg]:size-4"] svg { width: 1rem; height: 1rem; }
1966
+ [class*="[&>svg]:shrink-0"] > svg,
1967
+ [class*="[&_svg]:shrink-0"] svg { flex-shrink: 0; }
1968
+ [class*="[&_svg]:pointer-events-none"] svg { pointer-events: none; }
1969
+
1970
+ /* --- RTL support --- */
1971
+ .rtl\\:flex-row-reverse:where([dir=rtl], [dir=rtl] *) { flex-direction: row-reverse; }
1972
+ .data-\\[state\\=checked\\]\\:ltr\\:translate-x-4[data-state=checked]:where([dir=ltr], [dir=ltr] *) { transform: translateX(1rem); }
1973
+ .data-\\[state\\=checked\\]\\:rtl\\:-translate-x-4[data-state=checked]:where([dir=rtl], [dir=rtl] *) { transform: translateX(-1rem); }
1974
+ .data-\\[state\\=unchecked\\]\\:translate-x-0[data-state=unchecked] { transform: translateX(0); }
1975
+
1976
+ /* --- Radix animation (minimal enter/exit for dropdown) --- */
1977
+ @keyframes hai3-fade-in { from { opacity: 0; } to { opacity: 1; } }
1978
+ @keyframes hai3-fade-out { from { opacity: 1; } to { opacity: 0; } }
1979
+ @keyframes hai3-zoom-in { from { transform: scale(0.95); } to { transform: scale(1); } }
1980
+ @keyframes hai3-zoom-out { from { transform: scale(1); } to { transform: scale(0.95); } }
1981
+ .data-\\[state\\=open\\]\\:animate-in[data-state=open] { animation: hai3-fade-in 150ms ease-out, hai3-zoom-in 150ms ease-out; }
1982
+ .data-\\[state\\=closed\\]\\:animate-out[data-state=closed] { animation: hai3-fade-out 100ms ease-in, hai3-zoom-out 100ms ease-in; animation-fill-mode: forwards; }
1983
+
1984
+ /* --- Studio portal: scoped dropdown color overrides ---
1985
+ Dropdown content portaled here inherits host-app Tailwind utilities that
1986
+ may reference broken theme variables (e.g. --popover-foreground identical
1987
+ to --popover in some third-party themes). Scoped rules (specificity 0-2-0)
1988
+ beat host-app Tailwind (0-1-0) and map everything to --foreground / --background. */
1989
+ .studio-portal-container .bg-popover { background-color: hsl(var(--background, 0 0% 100%)); }
1990
+ .studio-portal-container .text-popover-foreground { color: hsl(var(--foreground, 0 0% 0%)); }
1991
+ .studio-portal-container .focus\\:bg-accent:focus { background-color: hsl(var(--foreground) / 0.1); }
1992
+ .studio-portal-container .focus\\:text-foreground:focus { color: hsl(var(--foreground)); }
1993
+
1994
+ /* --- Z-index (dropdown content) --- */
1995
+ .z-50 { z-index: 50; }
1996
+ `
1997
+ );
1998
+ function injectStudioStyles() {
1999
+ if (typeof document === "undefined") return () => {
2000
+ };
2001
+ let styleEl = document.getElementById(STUDIO_STYLE_ID);
2002
+ if (styleEl) return () => {
2003
+ };
2004
+ styleEl = document.createElement("style");
2005
+ styleEl.id = STUDIO_STYLE_ID;
2006
+ styleEl.textContent = STUDIO_CSS;
2007
+ document.head.appendChild(styleEl);
2008
+ return () => {
2009
+ styleEl?.remove();
2010
+ };
2011
+ }
1542
2012
  var StudioContent = () => {
1543
2013
  const { collapsed, toggleCollapsed } = useStudioContext();
1544
2014
  useKeyboardShortcut(toggleCollapsed);
@@ -1548,6 +2018,9 @@ var StudioContent = () => {
1548
2018
  return /* @__PURE__ */ jsxRuntime.jsx(StudioPanel, {});
1549
2019
  };
1550
2020
  var StudioOverlay = () => {
2021
+ React2.useEffect(() => {
2022
+ return injectStudioStyles();
2023
+ }, []);
1551
2024
  return /* @__PURE__ */ jsxRuntime.jsx(StudioProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(StudioContent, {}) });
1552
2025
  };
1553
2026
  StudioOverlay.displayName = "StudioOverlay";