@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/dist/index.js CHANGED
@@ -1,8 +1,13 @@
1
1
  import React2, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';
2
2
  import { I18nRegistry, Language, i18nRegistry, eventBus, useHAI3, useTranslation, HAI3_SCREEN_DOMAIN, HAI3_ACTION_MOUNT_EXT, useRegisteredPackages, useActivePackage, useAppSelector, useTheme, getLanguageMetadata, LanguageDisplayMode, SUPPORTED_LANGUAGES, TextDirection, toggleMockMode } from '@hai3/react';
3
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
- import { Card, Button, ButtonSize, ButtonVariant, DropdownMenu, DropdownMenuTrigger, DropdownButton, DropdownMenuContent, DropdownMenuItem, Switch } from '@hai3/uikit';
4
+ import { clsx } from 'clsx';
5
+ import { twMerge } from 'tailwind-merge';
6
+ import { Slot } from '@radix-ui/react-slot';
7
+ import { cva } from 'class-variance-authority';
5
8
  import { clamp, upperFirst } from 'lodash';
9
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
10
+ import * as SwitchPrimitives from '@radix-ui/react-switch';
6
11
 
7
12
  var __create = Object.create;
8
13
  var __defProp = Object.defineProperty;
@@ -1055,6 +1060,69 @@ var StudioProvider = ({ children }) => {
1055
1060
  );
1056
1061
  };
1057
1062
  StudioProvider.displayName = "StudioProvider";
1063
+ function cn(...inputs) {
1064
+ return twMerge(clsx(inputs));
1065
+ }
1066
+ var Card = ({
1067
+ ref,
1068
+ className,
1069
+ ...props
1070
+ }) => /* @__PURE__ */ jsx(
1071
+ "div",
1072
+ {
1073
+ ref,
1074
+ className: cn(
1075
+ "rounded-xl border bg-card text-card-foreground shadow",
1076
+ className
1077
+ ),
1078
+ ...props
1079
+ }
1080
+ );
1081
+ Card.displayName = "Card";
1082
+ var buttonVariants = cva(
1083
+ "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",
1084
+ {
1085
+ variants: {
1086
+ variant: {
1087
+ ["default" /* Default */]: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
1088
+ ["destructive" /* Destructive */]: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
1089
+ ["outline" /* Outline */]: "border border-input bg-background text-foreground shadow-sm hover:bg-accent data-[state=open]:bg-accent",
1090
+ ["secondary" /* Secondary */]: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
1091
+ ["ghost" /* Ghost */]: "hover:bg-accent data-[state=open]:bg-accent",
1092
+ ["link" /* Link */]: "text-primary underline-offset-4 hover:underline"
1093
+ },
1094
+ size: {
1095
+ ["default" /* Default */]: "h-9 px-4 py-2",
1096
+ ["sm" /* Sm */]: "h-8 rounded-md px-3 text-xs",
1097
+ ["lg" /* Lg */]: "h-10 rounded-md px-8",
1098
+ ["icon" /* Icon */]: "h-9 w-9"
1099
+ }
1100
+ },
1101
+ defaultVariants: {
1102
+ variant: "default" /* Default */,
1103
+ size: "default" /* Default */
1104
+ }
1105
+ }
1106
+ );
1107
+ var Button = ({
1108
+ ref,
1109
+ className,
1110
+ variant,
1111
+ size,
1112
+ asChild = false,
1113
+ ...props
1114
+ }) => {
1115
+ const Comp = asChild ? Slot : "button";
1116
+ return /* @__PURE__ */ jsx(
1117
+ Comp,
1118
+ {
1119
+ className: cn(buttonVariants({ variant, size, className })),
1120
+ ref,
1121
+ ...props
1122
+ }
1123
+ );
1124
+ };
1125
+ Button.displayName = "Button";
1058
1126
  var VIEWPORT_MARGIN = 20;
1059
1127
  function clampToViewport(pos, size) {
1060
1128
  const maxX = Math.max(VIEWPORT_MARGIN, window.innerWidth - size.width - VIEWPORT_MARGIN);
@@ -1184,6 +1252,90 @@ var useResizable = () => {
1184
1252
  handleMouseDown
1185
1253
  };
1186
1254
  };
1255
+ var DropdownMenu = ({
1256
+ dir,
1257
+ ...props
1258
+ }) => /* @__PURE__ */ jsx(
1259
+ DropdownMenuPrimitive.Root,
1260
+ {
1261
+ ...props,
1262
+ dir
1263
+ }
1264
+ );
1265
+ DropdownMenu.displayName = "DropdownMenu";
1266
+ var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
1267
+ var DropdownMenuContent = ({
1268
+ ref,
1269
+ className,
1270
+ sideOffset = 4,
1271
+ container,
1272
+ ...props
1273
+ }) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
1274
+ DropdownMenuPrimitive.Content,
1275
+ {
1276
+ ref,
1277
+ sideOffset,
1278
+ style: { backgroundColor: "hsl(var(--background, 0 0% 100%))" },
1279
+ className: cn(
1280
+ "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",
1281
+ "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]",
1282
+ className
1283
+ ),
1284
+ ...props
1285
+ }
1286
+ ) });
1287
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
1288
+ var DropdownMenuItem = ({
1289
+ ref,
1290
+ className,
1291
+ inset,
1292
+ ...props
1293
+ }) => /* @__PURE__ */ jsx(
1294
+ DropdownMenuPrimitive.Item,
1295
+ {
1296
+ ref,
1297
+ className: cn(
1298
+ "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",
1299
+ inset && "pl-8",
1300
+ className
1301
+ ),
1302
+ ...props
1303
+ }
1304
+ );
1305
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
1306
+ var ChevronDownIcon = ({ className = "" }) => /* @__PURE__ */ jsx(
1307
+ "svg",
1308
+ {
1309
+ className,
1310
+ fill: "none",
1311
+ stroke: "currentColor",
1312
+ strokeWidth: 2,
1313
+ viewBox: "0 0 24 24",
1314
+ children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" })
1315
+ }
1316
+ );
1317
+ var DropdownButton = ({
1318
+ ref,
1319
+ children,
1320
+ variant = "outline" /* Outline */,
1321
+ className,
1322
+ ...props
1323
+ }) => {
1324
+ return /* @__PURE__ */ jsxs(
1325
+ Button,
1326
+ {
1327
+ ref,
1328
+ variant,
1329
+ className: cn("min-w-40 justify-between rtl:flex-row-reverse", className),
1330
+ ...props,
1331
+ children: [
1332
+ /* @__PURE__ */ jsx("span", { children }),
1333
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4" })
1334
+ ]
1335
+ }
1336
+ );
1337
+ };
1338
+ DropdownButton.displayName = "DropdownButton";
1187
1339
  function isScreenExtension2(ext) {
1188
1340
  return "presentation" in ext && typeof ext.presentation === "object";
1189
1341
  }
@@ -1225,7 +1377,7 @@ var MfePackageSelector = ({
1225
1377
  /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1226
1378
  DropdownButton,
1227
1379
  {
1228
- variant: ButtonVariant.Outline,
1380
+ variant: "outline" /* Outline */,
1229
1381
  disabled: packages.length <= 1,
1230
1382
  children: activePackage || "No package"
1231
1383
  }
@@ -1254,7 +1406,7 @@ var ThemeSelector = ({
1254
1406
  return /* @__PURE__ */ jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
1255
1407
  /* @__PURE__ */ jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.theme") }),
1256
1408
  /* @__PURE__ */ jsxs(DropdownMenu, { children: [
1257
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownButton, { variant: ButtonVariant.Outline, children: formatThemeName(currentTheme || "") }) }),
1409
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownButton, { variant: "outline" /* Outline */, children: formatThemeName(currentTheme || "") }) }),
1258
1410
  /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: themes.map((theme) => /* @__PURE__ */ jsx(
1259
1411
  DropdownMenuItem,
1260
1412
  {
@@ -1278,7 +1430,7 @@ function LanguageSelector({
1278
1430
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
1279
1431
  /* @__PURE__ */ jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.language") }),
1280
1432
  /* @__PURE__ */ jsxs(DropdownMenu, { children: [
1281
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: ButtonVariant.Outline, children: currentLanguage ? displayMode === LanguageDisplayMode.Native ? currentLanguage.name : currentLanguage.englishName : FALLBACK_SELECT_LANGUAGE_TEXT }) }),
1433
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline" /* Outline */, children: currentLanguage ? displayMode === LanguageDisplayMode.Native ? currentLanguage.name : currentLanguage.englishName : FALLBACK_SELECT_LANGUAGE_TEXT }) }),
1282
1434
  /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: SUPPORTED_LANGUAGES.map((lang) => /* @__PURE__ */ jsxs(
1283
1435
  DropdownMenuItem,
1284
1436
  {
@@ -1293,6 +1445,32 @@ function LanguageSelector({
1293
1445
  ] })
1294
1446
  ] });
1295
1447
  }
1448
+ var Switch = ({
1449
+ ref,
1450
+ className,
1451
+ ...props
1452
+ }) => /* @__PURE__ */ jsx(
1453
+ SwitchPrimitives.Root,
1454
+ {
1455
+ className: cn(
1456
+ "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",
1457
+ className
1458
+ ),
1459
+ ...props,
1460
+ ref,
1461
+ children: /* @__PURE__ */ jsx(
1462
+ SwitchPrimitives.Thumb,
1463
+ {
1464
+ className: cn(
1465
+ "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform",
1466
+ "data-[state=checked]:ltr:translate-x-4 data-[state=checked]:rtl:-translate-x-4",
1467
+ "data-[state=unchecked]:translate-x-0"
1468
+ )
1469
+ }
1470
+ )
1471
+ }
1472
+ );
1473
+ Switch.displayName = SwitchPrimitives.Root.displayName;
1296
1474
  var ApiModeToggle = ({
1297
1475
  className
1298
1476
  }) => {
@@ -1380,8 +1558,8 @@ var StudioPanel = () => {
1380
1558
  /* @__PURE__ */ jsx(
1381
1559
  Button,
1382
1560
  {
1383
- variant: ButtonVariant.Ghost,
1384
- size: ButtonSize.Sm,
1561
+ variant: "ghost" /* Ghost */,
1562
+ size: "sm" /* Sm */,
1385
1563
  onClick: toggleCollapsed,
1386
1564
  className: "h-7 w-7 p-0",
1387
1565
  "aria-label": t("studio:aria.collapseButton"),
@@ -1460,7 +1638,7 @@ var GlassmorphicButton = ({
1460
1638
  return /* @__PURE__ */ jsx(
1461
1639
  Button,
1462
1640
  {
1463
- variant: ButtonVariant.Ghost,
1641
+ variant: "ghost" /* Ghost */,
1464
1642
  onMouseDown,
1465
1643
  onClick,
1466
1644
  title,
@@ -1533,6 +1711,278 @@ var CollapsedButton = ({ toggleCollapsed }) => {
1533
1711
  );
1534
1712
  };
1535
1713
  CollapsedButton.displayName = "CollapsedButton";
1714
+
1715
+ // src/styles/studioStyles.ts
1716
+ var STUDIO_STYLE_ID = "hai3-studio-styles";
1717
+ var STUDIO_CSS = (
1718
+ /* css */
1719
+ `
1720
+ /* ============================================================
1721
+ HAI3 Studio \u2014 Self-contained utility styles
1722
+ ============================================================ */
1723
+
1724
+ /* --- Base normalization (Preflight may be absent in no-uikit hosts) ---
1725
+ :where() keeps specificity at 0-0-0 so utility classes always win. */
1726
+ .studio-panel,
1727
+ .studio-portal-container {
1728
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1729
+ line-height: 1.5;
1730
+ }
1731
+ :where(.studio-panel *, .studio-portal-container *) { box-sizing: border-box; }
1732
+ :where(.studio-panel button, .studio-portal-container button) {
1733
+ font-family: inherit;
1734
+ font-size: inherit;
1735
+ line-height: inherit;
1736
+ color: inherit;
1737
+ border: 0 solid transparent;
1738
+ background: transparent;
1739
+ padding: 0;
1740
+ margin: 0;
1741
+ cursor: pointer;
1742
+ }
1743
+ :where(.studio-panel h2, .studio-panel h3, .studio-portal-container h2, .studio-portal-container h3) {
1744
+ font-size: inherit;
1745
+ font-weight: inherit;
1746
+ margin: 0;
1747
+ }
1748
+
1749
+ /* --- Layout --- */
1750
+ .fixed { position: fixed; }
1751
+ .absolute { position: absolute; }
1752
+ .relative { position: relative; }
1753
+ .flex { display: flex; }
1754
+ .inline-flex { display: inline-flex; }
1755
+ .block { display: block; }
1756
+ .peer { /* Radix peer marker \u2014 no CSS needed */ }
1757
+ .flex-col { flex-direction: column; }
1758
+ .flex-1 { flex: 1 1 0%; }
1759
+ .shrink-0 { flex-shrink: 0; }
1760
+ .items-center { align-items: center; }
1761
+ .justify-between { justify-content: space-between; }
1762
+ .justify-center { justify-content: center; }
1763
+ .gap-2 { gap: 0.5rem; }
1764
+ .overflow-hidden { overflow: hidden; }
1765
+ .overflow-y-auto { overflow-y: auto; }
1766
+ .overflow-x-hidden { overflow-x: hidden; }
1767
+
1768
+ /* --- Sizing --- */
1769
+ .h-full { height: 100%; }
1770
+ .w-full { width: 100%; }
1771
+ .h-4 { height: 1rem; }
1772
+ .w-4 { width: 1rem; }
1773
+ .h-5 { height: 1.25rem; }
1774
+ .w-5 { width: 1.25rem; }
1775
+ .w-9 { width: 2.25rem; }
1776
+ .h-6 { height: 1.5rem; }
1777
+ .w-6 { width: 1.5rem; }
1778
+ .h-7 { height: 1.75rem; }
1779
+ .w-7 { width: 1.75rem; }
1780
+ .h-8 { height: 2rem; }
1781
+ .h-9 { height: 2.25rem; }
1782
+ .h-10 { height: 2.5rem; }
1783
+ .h-12 { height: 3rem; }
1784
+ .w-12 { width: 3rem; }
1785
+ .min-w-\\[8rem\\] { min-width: 8rem; }
1786
+ .min-w-40 { min-width: 10rem; }
1787
+
1788
+ /* --- Spacing --- */
1789
+ .p-0 { padding: 0; }
1790
+ .p-1 { padding: 0.25rem; }
1791
+ .p-4 { padding: 1rem; }
1792
+ .px-2 { padding-left: 0.5rem; padding-right: 0.5rem; }
1793
+ .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
1794
+ .px-4 { padding-left: 1rem; padding-right: 1rem; }
1795
+ .px-8 { padding-left: 2rem; padding-right: 2rem; }
1796
+ .py-1\\.5 { padding-top: 0.375rem; padding-bottom: 0.375rem; }
1797
+ .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
1798
+ .py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; }
1799
+ .pl-8 { padding-left: 2rem; }
1800
+ .bottom-1 { bottom: 0.25rem; }
1801
+ .right-1 { right: 0.25rem; }
1802
+ .space-y-3 > :not([hidden]) ~ :not([hidden]) { margin-top: 0.75rem; }
1803
+ .space-y-4 > :not([hidden]) ~ :not([hidden]) { margin-top: 1rem; }
1804
+
1805
+ /* --- Typography --- */
1806
+ .text-xs { font-size: 0.75rem; line-height: 1rem; }
1807
+ .text-sm { font-size: 0.875rem; line-height: 1.25rem; }
1808
+ .font-medium { font-weight: 500; }
1809
+ .font-semibold { font-weight: 600; }
1810
+ .uppercase { text-transform: uppercase; }
1811
+ .tracking-wider { letter-spacing: 0.05em; }
1812
+ .whitespace-nowrap { white-space: nowrap; }
1813
+
1814
+ /* --- Colors (theme-aware via CSS variables) ---
1815
+ Some theme variables (--popover-foreground, --card-foreground) may have
1816
+ incorrect values in third-party themes. The Studio maps all component
1817
+ colors to --foreground / --background which are always correct (body uses them).
1818
+ :where() ensures host-app Tailwind utilities take precedence when available. */
1819
+ .text-foreground { color: hsl(var(--foreground)); }
1820
+ .text-muted-foreground { color: hsl(var(--muted-foreground)); }
1821
+ .text-muted-foreground\\/70 { color: hsl(var(--muted-foreground) / 0.7); }
1822
+ :where(.bg-popover) { background-color: hsl(var(--background)); }
1823
+ :where(.text-popover-foreground) { color: hsl(var(--foreground)); }
1824
+ :where(.bg-accent) { background-color: hsl(var(--foreground) / 0.1); }
1825
+ :where(.text-accent-foreground) { color: hsl(var(--foreground)); }
1826
+ :where(.bg-background) { background-color: hsl(var(--background)); }
1827
+ :where(.bg-card) { background-color: hsl(var(--background)); }
1828
+ :where(.text-card-foreground) { color: hsl(var(--foreground)); }
1829
+ :where(.bg-primary) { background-color: hsl(var(--foreground)); }
1830
+ :where(.text-primary-foreground) { color: hsl(var(--background)); }
1831
+ :where(.bg-input) { background-color: hsl(var(--foreground) / 0.15); }
1832
+ :where(.border-input) { border-color: hsl(var(--foreground) / 0.2); }
1833
+ :where(.ring-ring) { --tw-ring-color: hsl(var(--foreground) / 0.5); }
1834
+ .border-transparent { border-color: transparent; }
1835
+
1836
+ /* --- Borders --- */
1837
+ .border { border-width: 1px; }
1838
+ .border-2 { border-width: 2px; }
1839
+ .border-b { border-bottom-width: 1px; }
1840
+ :where(.border-border\\/50) { border-color: hsl(var(--foreground) / 0.15); }
1841
+ .rounded-full { border-radius: 9999px; }
1842
+ .rounded-xl { border-radius: 0.75rem; }
1843
+ .rounded-md { border-radius: calc(var(--radius, 0.5rem) - 2px); }
1844
+ .rounded-sm { border-radius: calc(var(--radius, 0.5rem) - 4px); }
1845
+
1846
+ /* --- Interaction --- */
1847
+ .select-none { -webkit-user-select: none; user-select: none; }
1848
+ .cursor-pointer { cursor: pointer; }
1849
+ .cursor-default { cursor: default; }
1850
+ .cursor-nwse-resize { cursor: nwse-resize; }
1851
+ .pointer-events-none { pointer-events: none; }
1852
+ .pointer-events-auto { pointer-events: auto; }
1853
+ .outline-none { outline: 2px solid transparent; outline-offset: 2px; }
1854
+ .transition-colors {
1855
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
1856
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1857
+ transition-duration: 150ms;
1858
+ }
1859
+ .transition-transform {
1860
+ transition-property: transform;
1861
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1862
+ transition-duration: 150ms;
1863
+ }
1864
+
1865
+ /* --- Z-index (arbitrary values) --- */
1866
+ .z-\\[10000\\] { z-index: 10000; }
1867
+ .z-\\[99999\\] { z-index: 99999; }
1868
+
1869
+ /* --- Glassmorphic: background with opacity --- */
1870
+ .bg-white\\/20 { background-color: rgb(255 255 255 / 0.2); }
1871
+ .bg-white\\/30 { background-color: rgb(255 255 255 / 0.3); }
1872
+ .dark .dark\\:bg-black\\/50 { background-color: rgb(0 0 0 / 0.5); }
1873
+ .dark .dark\\:bg-black\\/60 { background-color: rgb(0 0 0 / 0.6); }
1874
+
1875
+ /* --- Glassmorphic: border with opacity --- */
1876
+ .border-white\\/30 { border-color: rgb(255 255 255 / 0.3); }
1877
+ .dark .dark\\:border-white\\/20 { border-color: rgb(255 255 255 / 0.2); }
1878
+
1879
+ /* --- Glassmorphic: backdrop filters --- */
1880
+ .backdrop-blur-md {
1881
+ --tw-backdrop-blur: blur(12px);
1882
+ -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, );
1883
+ 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, );
1884
+ }
1885
+ .backdrop-saturate-\\[180\\%\\] {
1886
+ --tw-backdrop-saturate: saturate(1.8);
1887
+ -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, );
1888
+ 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, );
1889
+ }
1890
+
1891
+ /* --- Glassmorphic: box shadow (arbitrary) --- */
1892
+ .shadow-\\[0_8px_32px_rgba\\(0\\,0\\,0\\,0\\.2\\)\\] {
1893
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
1894
+ }
1895
+
1896
+ /* --- Shadows --- */
1897
+ .shadow { box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); }
1898
+ .shadow-sm { box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); }
1899
+ .shadow-md { box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); }
1900
+ .shadow-lg { box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); }
1901
+ .ring-0 { box-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width, 0px)) var(--tw-ring-color, transparent); }
1902
+
1903
+ /* --- Hover states --- */
1904
+ .hover\\:bg-white\\/30:hover { background-color: rgb(255 255 255 / 0.3); }
1905
+ .dark .dark\\:hover\\:bg-black\\/60:hover { background-color: rgb(0 0 0 / 0.6); }
1906
+ .hover\\:text-muted-foreground:hover { color: hsl(var(--muted-foreground)); }
1907
+ :where(.hover\\:bg-accent:hover) { background-color: hsl(var(--foreground) / 0.1); }
1908
+ :where(.hover\\:bg-primary\\/90:hover) { background-color: hsl(var(--foreground) / 0.85); }
1909
+ :where(.hover\\:bg-secondary\\/80:hover) { background-color: hsl(var(--foreground) / 0.08); }
1910
+ :where(.hover\\:bg-destructive\\/90:hover) { background-color: hsl(0 60% 50% / 0.9); }
1911
+
1912
+ /* --- Focus states --- */
1913
+ :where(.focus\\:bg-accent:focus) { background-color: hsl(var(--foreground) / 0.1); }
1914
+ :where(.focus\\:text-foreground:focus) { color: hsl(var(--foreground)); }
1915
+ :where(.focus\\:text-accent-foreground:focus) { color: hsl(var(--foreground)); }
1916
+ .focus-visible\\:outline-none:focus-visible { outline: 2px solid transparent; outline-offset: 2px; }
1917
+ :where(.focus-visible\\:ring-1:focus-visible) {
1918
+ 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));
1919
+ }
1920
+ :where(.focus-visible\\:ring-2:focus-visible) {
1921
+ 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));
1922
+ }
1923
+ :where(.focus-visible\\:ring-ring:focus-visible) { --tw-ring-color: hsl(var(--foreground) / 0.5); }
1924
+ :where(.focus-visible\\:ring-offset-2:focus-visible) { --tw-ring-offset-width: 2px; }
1925
+ :where(.focus-visible\\:ring-offset-background:focus-visible) { --tw-ring-offset-color: hsl(var(--background)); }
1926
+
1927
+ /* --- Data-attribute & disabled states --- */
1928
+ :where(.data-\\[state\\=open\\]\\:bg-accent[data-state=open]) { background-color: hsl(var(--foreground) / 0.1); }
1929
+ :where(.data-\\[state\\=checked\\]\\:bg-primary[data-state=checked]) { background-color: hsl(var(--foreground)); }
1930
+ :where(.data-\\[state\\=unchecked\\]\\:bg-input[data-state=unchecked]) { background-color: hsl(var(--foreground) / 0.15); }
1931
+ .data-\\[disabled\\]\\:pointer-events-none[data-disabled] { pointer-events: none; }
1932
+ .data-\\[disabled\\]\\:opacity-50[data-disabled] { opacity: 0.5; }
1933
+ .disabled\\:pointer-events-none:disabled { pointer-events: none; }
1934
+ .disabled\\:opacity-50:disabled { opacity: 0.5; }
1935
+ .disabled\\:cursor-not-allowed:disabled { cursor: not-allowed; }
1936
+
1937
+ /* --- SVG child selectors --- */
1938
+ [class*="[&>svg]:size-4"] > svg,
1939
+ [class*="[&_svg]:size-4"] svg { width: 1rem; height: 1rem; }
1940
+ [class*="[&>svg]:shrink-0"] > svg,
1941
+ [class*="[&_svg]:shrink-0"] svg { flex-shrink: 0; }
1942
+ [class*="[&_svg]:pointer-events-none"] svg { pointer-events: none; }
1943
+
1944
+ /* --- RTL support --- */
1945
+ .rtl\\:flex-row-reverse:where([dir=rtl], [dir=rtl] *) { flex-direction: row-reverse; }
1946
+ .data-\\[state\\=checked\\]\\:ltr\\:translate-x-4[data-state=checked]:where([dir=ltr], [dir=ltr] *) { transform: translateX(1rem); }
1947
+ .data-\\[state\\=checked\\]\\:rtl\\:-translate-x-4[data-state=checked]:where([dir=rtl], [dir=rtl] *) { transform: translateX(-1rem); }
1948
+ .data-\\[state\\=unchecked\\]\\:translate-x-0[data-state=unchecked] { transform: translateX(0); }
1949
+
1950
+ /* --- Radix animation (minimal enter/exit for dropdown) --- */
1951
+ @keyframes hai3-fade-in { from { opacity: 0; } to { opacity: 1; } }
1952
+ @keyframes hai3-fade-out { from { opacity: 1; } to { opacity: 0; } }
1953
+ @keyframes hai3-zoom-in { from { transform: scale(0.95); } to { transform: scale(1); } }
1954
+ @keyframes hai3-zoom-out { from { transform: scale(1); } to { transform: scale(0.95); } }
1955
+ .data-\\[state\\=open\\]\\:animate-in[data-state=open] { animation: hai3-fade-in 150ms ease-out, hai3-zoom-in 150ms ease-out; }
1956
+ .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; }
1957
+
1958
+ /* --- Studio portal: scoped dropdown color overrides ---
1959
+ Dropdown content portaled here inherits host-app Tailwind utilities that
1960
+ may reference broken theme variables (e.g. --popover-foreground identical
1961
+ to --popover in some third-party themes). Scoped rules (specificity 0-2-0)
1962
+ beat host-app Tailwind (0-1-0) and map everything to --foreground / --background. */
1963
+ .studio-portal-container .bg-popover { background-color: hsl(var(--background, 0 0% 100%)); }
1964
+ .studio-portal-container .text-popover-foreground { color: hsl(var(--foreground, 0 0% 0%)); }
1965
+ .studio-portal-container .focus\\:bg-accent:focus { background-color: hsl(var(--foreground) / 0.1); }
1966
+ .studio-portal-container .focus\\:text-foreground:focus { color: hsl(var(--foreground)); }
1967
+
1968
+ /* --- Z-index (dropdown content) --- */
1969
+ .z-50 { z-index: 50; }
1970
+ `
1971
+ );
1972
+ function injectStudioStyles() {
1973
+ if (typeof document === "undefined") return () => {
1974
+ };
1975
+ let styleEl = document.getElementById(STUDIO_STYLE_ID);
1976
+ if (styleEl) return () => {
1977
+ };
1978
+ styleEl = document.createElement("style");
1979
+ styleEl.id = STUDIO_STYLE_ID;
1980
+ styleEl.textContent = STUDIO_CSS;
1981
+ document.head.appendChild(styleEl);
1982
+ return () => {
1983
+ styleEl?.remove();
1984
+ };
1985
+ }
1536
1986
  var StudioContent = () => {
1537
1987
  const { collapsed, toggleCollapsed } = useStudioContext();
1538
1988
  useKeyboardShortcut(toggleCollapsed);
@@ -1542,6 +1992,9 @@ var StudioContent = () => {
1542
1992
  return /* @__PURE__ */ jsx(StudioPanel, {});
1543
1993
  };
1544
1994
  var StudioOverlay = () => {
1995
+ useEffect(() => {
1996
+ return injectStudioStyles();
1997
+ }, []);
1545
1998
  return /* @__PURE__ */ jsx(StudioProvider, { children: /* @__PURE__ */ jsx(StudioContent, {}) });
1546
1999
  };
1547
2000
  StudioOverlay.displayName = "StudioOverlay";