@hai3/studio 0.3.0-alpha.2 → 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.cjs CHANGED
@@ -1,14 +1,39 @@
1
1
  'use strict';
2
2
 
3
- var React3 = require('react');
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
 
11
- var React3__default = /*#__PURE__*/_interopDefault(React3);
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
+
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;
@@ -51,7 +76,8 @@ var require_en = __commonJS({
51
76
  screenset: "Screenset:",
52
77
  theme: "Theme:",
53
78
  language: "Language:",
54
- mockApi: "Mock API"
79
+ mockApi: "Mock API",
80
+ gts_package: "GTS Package"
55
81
  }
56
82
  };
57
83
  }
@@ -72,7 +98,8 @@ var require_ar = __commonJS({
72
98
  screenset: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0627\u0644\u0634\u0627\u0634\u0627\u062A:",
73
99
  theme: "\u0627\u0644\u0633\u0645\u0629:",
74
100
  language: "\u0627\u0644\u0644\u063A\u0629:",
75
- mockApi: "\u0648\u0627\u062C\u0647\u0629 \u0628\u0631\u0645\u062C\u064A\u0629 \u0648\u0647\u0645\u064A\u0629"
101
+ mockApi: "\u0648\u0627\u062C\u0647\u0629 \u0628\u0631\u0645\u062C\u064A\u0629 \u0648\u0647\u0645\u064A\u0629",
102
+ gts_package: "GTS Package"
76
103
  }
77
104
  };
78
105
  }
@@ -93,7 +120,8 @@ var require_bn = __commonJS({
93
120
  screenset: "\u09B8\u09CD\u0995\u09CD\u09B0\u09BF\u09A8\u09B8\u09C7\u099F:",
94
121
  theme: "\u09A5\u09BF\u09AE:",
95
122
  language: "\u09AD\u09BE\u09B7\u09BE:",
96
- mockApi: "\u09AE\u0995 API"
123
+ mockApi: "\u09AE\u0995 API",
124
+ gts_package: "GTS Package"
97
125
  }
98
126
  };
99
127
  }
@@ -114,7 +142,8 @@ var require_cs = __commonJS({
114
142
  screenset: "Sada obrazovek:",
115
143
  theme: "Motiv:",
116
144
  language: "Jazyk:",
117
- mockApi: "Simulovan\xE9 API"
145
+ mockApi: "Simulovan\xE9 API",
146
+ gts_package: "GTS Package"
118
147
  }
119
148
  };
120
149
  }
@@ -135,7 +164,8 @@ var require_da = __commonJS({
135
164
  screenset: "Sk\xE6rms\xE6t:",
136
165
  theme: "Tema:",
137
166
  language: "Sprog:",
138
- mockApi: "Mock-API"
167
+ mockApi: "Mock-API",
168
+ gts_package: "GTS Package"
139
169
  }
140
170
  };
141
171
  }
@@ -156,7 +186,8 @@ var require_de = __commonJS({
156
186
  screenset: "Bildschirmset:",
157
187
  theme: "Design:",
158
188
  language: "Sprache:",
159
- mockApi: "Mock-API"
189
+ mockApi: "Mock-API",
190
+ gts_package: "GTS Package"
160
191
  }
161
192
  };
162
193
  }
@@ -177,7 +208,8 @@ var require_el = __commonJS({
177
208
  screenset: "\u03A3\u03CD\u03BD\u03BF\u03BB\u03BF \u039F\u03B8\u03BF\u03BD\u03CE\u03BD:",
178
209
  theme: "\u0398\u03AD\u03BC\u03B1:",
179
210
  language: "\u0393\u03BB\u03CE\u03C3\u03C3\u03B1:",
180
- mockApi: "Mock API"
211
+ mockApi: "Mock API",
212
+ gts_package: "GTS Package"
181
213
  }
182
214
  };
183
215
  }
@@ -198,7 +230,8 @@ var require_es = __commonJS({
198
230
  screenset: "Conjunto de Pantallas:",
199
231
  theme: "Tema:",
200
232
  language: "Idioma:",
201
- mockApi: "API Simulada"
233
+ mockApi: "API Simulada",
234
+ gts_package: "GTS Package"
202
235
  }
203
236
  };
204
237
  }
@@ -219,7 +252,8 @@ var require_fa = __commonJS({
219
252
  screenset: "\u0645\u062C\u0645\u0648\u0639\u0647 \u0635\u0641\u062D\u0647\u200C\u0646\u0645\u0627\u06CC\u0634:",
220
253
  theme: "\u067E\u0648\u0633\u062A\u0647:",
221
254
  language: "\u0632\u0628\u0627\u0646:",
222
- mockApi: "API \u0633\u0627\u062E\u062A\u06AF\u06CC"
255
+ mockApi: "API \u0633\u0627\u062E\u062A\u06AF\u06CC",
256
+ gts_package: "GTS Package"
223
257
  }
224
258
  };
225
259
  }
@@ -240,7 +274,8 @@ var require_fi = __commonJS({
240
274
  screenset: "N\xE4ytt\xF6sarja:",
241
275
  theme: "Teema:",
242
276
  language: "Kieli:",
243
- mockApi: "Mock-API"
277
+ mockApi: "Mock-API",
278
+ gts_package: "GTS Package"
244
279
  }
245
280
  };
246
281
  }
@@ -261,7 +296,8 @@ var require_fr = __commonJS({
261
296
  screenset: "Ensemble d'\xC9crans:",
262
297
  theme: "Th\xE8me:",
263
298
  language: "Langue:",
264
- mockApi: "API Simul\xE9e"
299
+ mockApi: "API Simul\xE9e",
300
+ gts_package: "GTS Package"
265
301
  }
266
302
  };
267
303
  }
@@ -282,7 +318,8 @@ var require_he = __commonJS({
282
318
  screenset: "\u05E2\u05E8\u05DB\u05EA \u05DE\u05E1\u05DB\u05D9\u05DD:",
283
319
  theme: "\u05E2\u05E8\u05DB\u05EA \u05E0\u05D5\u05E9\u05D0:",
284
320
  language: "\u05E9\u05E4\u05D4:",
285
- mockApi: "API \u05DE\u05D3\u05D5\u05DE\u05D4"
321
+ mockApi: "API \u05DE\u05D3\u05D5\u05DE\u05D4",
322
+ gts_package: "GTS Package"
286
323
  }
287
324
  };
288
325
  }
@@ -303,7 +340,8 @@ var require_hi = __commonJS({
303
340
  screenset: "\u0938\u094D\u0915\u094D\u0930\u0940\u0928\u0938\u0947\u091F:",
304
341
  theme: "\u0925\u0940\u092E:",
305
342
  language: "\u092D\u093E\u0937\u093E:",
306
- mockApi: "\u092E\u0949\u0915 API"
343
+ mockApi: "\u092E\u0949\u0915 API",
344
+ gts_package: "GTS Package"
307
345
  }
308
346
  };
309
347
  }
@@ -324,7 +362,8 @@ var require_hu = __commonJS({
324
362
  screenset: "K\xE9perny\u0151k\xE9szlet:",
325
363
  theme: "T\xE9ma:",
326
364
  language: "Nyelv:",
327
- mockApi: "Mock API"
365
+ mockApi: "Mock API",
366
+ gts_package: "GTS Package"
328
367
  }
329
368
  };
330
369
  }
@@ -345,7 +384,8 @@ var require_id = __commonJS({
345
384
  screenset: "Set Layar:",
346
385
  theme: "Tema:",
347
386
  language: "Bahasa:",
348
- mockApi: "API Tiruan"
387
+ mockApi: "API Tiruan",
388
+ gts_package: "GTS Package"
349
389
  }
350
390
  };
351
391
  }
@@ -366,7 +406,8 @@ var require_it = __commonJS({
366
406
  screenset: "Set di Schermate:",
367
407
  theme: "Tema:",
368
408
  language: "Lingua:",
369
- mockApi: "API Simulata"
409
+ mockApi: "API Simulata",
410
+ gts_package: "GTS Package"
370
411
  }
371
412
  };
372
413
  }
@@ -387,7 +428,8 @@ var require_ja = __commonJS({
387
428
  screenset: "\u30B9\u30AF\u30EA\u30FC\u30F3\u30BB\u30C3\u30C8:",
388
429
  theme: "\u30C6\u30FC\u30DE:",
389
430
  language: "\u8A00\u8A9E:",
390
- mockApi: "\u30E2\u30C3\u30AF API"
431
+ mockApi: "\u30E2\u30C3\u30AF API",
432
+ gts_package: "GTS Package"
391
433
  }
392
434
  };
393
435
  }
@@ -408,7 +450,8 @@ var require_ko = __commonJS({
408
450
  screenset: "\uD654\uBA74 \uC138\uD2B8:",
409
451
  theme: "\uD14C\uB9C8:",
410
452
  language: "\uC5B8\uC5B4:",
411
- mockApi: "\uBAA8\uC758 API"
453
+ mockApi: "\uBAA8\uC758 API",
454
+ gts_package: "GTS Package"
412
455
  }
413
456
  };
414
457
  }
@@ -429,7 +472,8 @@ var require_ms = __commonJS({
429
472
  screenset: "Set Skrin:",
430
473
  theme: "Tema:",
431
474
  language: "Bahasa:",
432
- mockApi: "API Palsu"
475
+ mockApi: "API Palsu",
476
+ gts_package: "GTS Package"
433
477
  }
434
478
  };
435
479
  }
@@ -450,7 +494,8 @@ var require_nl = __commonJS({
450
494
  screenset: "Schermset:",
451
495
  theme: "Thema:",
452
496
  language: "Taal:",
453
- mockApi: "Nep-API"
497
+ mockApi: "Nep-API",
498
+ gts_package: "GTS Package"
454
499
  }
455
500
  };
456
501
  }
@@ -471,7 +516,8 @@ var require_no = __commonJS({
471
516
  screenset: "Skjermsett:",
472
517
  theme: "Tema:",
473
518
  language: "Spr\xE5k:",
474
- mockApi: "Mock-API"
519
+ mockApi: "Mock-API",
520
+ gts_package: "GTS Package"
475
521
  }
476
522
  };
477
523
  }
@@ -492,7 +538,8 @@ var require_pl = __commonJS({
492
538
  screenset: "Zestaw ekran\xF3w:",
493
539
  theme: "Motyw:",
494
540
  language: "J\u0119zyk:",
495
- mockApi: "Fikcyjne API"
541
+ mockApi: "Fikcyjne API",
542
+ gts_package: "GTS Package"
496
543
  }
497
544
  };
498
545
  }
@@ -513,7 +560,8 @@ var require_pt = __commonJS({
513
560
  screenset: "Conjunto de Telas:",
514
561
  theme: "Tema:",
515
562
  language: "Idioma:",
516
- mockApi: "API Simulada"
563
+ mockApi: "API Simulada",
564
+ gts_package: "GTS Package"
517
565
  }
518
566
  };
519
567
  }
@@ -534,7 +582,8 @@ var require_ro = __commonJS({
534
582
  screenset: "Set de Ecrane:",
535
583
  theme: "Tem\u0103:",
536
584
  language: "Limb\u0103:",
537
- mockApi: "API Simulat"
585
+ mockApi: "API Simulat",
586
+ gts_package: "GTS Package"
538
587
  }
539
588
  };
540
589
  }
@@ -555,7 +604,8 @@ var require_ru = __commonJS({
555
604
  screenset: "\u041D\u0430\u0431\u043E\u0440 \u044D\u043A\u0440\u0430\u043D\u043E\u0432:",
556
605
  theme: "\u0422\u0435\u043C\u0430:",
557
606
  language: "\u042F\u0437\u044B\u043A:",
558
- mockApi: "\u0424\u0438\u043A\u0442\u0438\u0432\u043D\u044B\u0439 API"
607
+ mockApi: "\u0424\u0438\u043A\u0442\u0438\u0432\u043D\u044B\u0439 API",
608
+ gts_package: "GTS Package"
559
609
  }
560
610
  };
561
611
  }
@@ -576,7 +626,8 @@ var require_sv = __commonJS({
576
626
  screenset: "Sk\xE4rmupps\xE4ttning:",
577
627
  theme: "Tema:",
578
628
  language: "Spr\xE5k:",
579
- mockApi: "Mock-API"
629
+ mockApi: "Mock-API",
630
+ gts_package: "GTS Package"
580
631
  }
581
632
  };
582
633
  }
@@ -597,7 +648,8 @@ var require_sw = __commonJS({
597
648
  screenset: "Seti ya Skrini:",
598
649
  theme: "Mandhari:",
599
650
  language: "Lugha:",
600
- mockApi: "API ya Majaribio"
651
+ mockApi: "API ya Majaribio",
652
+ gts_package: "GTS Package"
601
653
  }
602
654
  };
603
655
  }
@@ -618,7 +670,8 @@ var require_ta = __commonJS({
618
670
  screenset: "\u0BA4\u0BBF\u0BB0\u0BC8\u0BA4\u0BCD \u0BA4\u0BCA\u0B95\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1:",
619
671
  theme: "\u0BA4\u0BC0\u0BAE\u0BCD:",
620
672
  language: "\u0BAE\u0BCA\u0BB4\u0BBF:",
621
- mockApi: "\u0BAA\u0BCB\u0BB2\u0BBF API"
673
+ mockApi: "\u0BAA\u0BCB\u0BB2\u0BBF API",
674
+ gts_package: "GTS Package"
622
675
  }
623
676
  };
624
677
  }
@@ -639,7 +692,8 @@ var require_th = __commonJS({
639
692
  screenset: "\u0E0A\u0E38\u0E14\u0E2B\u0E19\u0E49\u0E32\u0E08\u0E2D:",
640
693
  theme: "\u0E18\u0E35\u0E21:",
641
694
  language: "\u0E20\u0E32\u0E29\u0E32:",
642
- mockApi: "API \u0E08\u0E33\u0E25\u0E2D\u0E07"
695
+ mockApi: "API \u0E08\u0E33\u0E25\u0E2D\u0E07",
696
+ gts_package: "GTS Package"
643
697
  }
644
698
  };
645
699
  }
@@ -660,7 +714,8 @@ var require_tl = __commonJS({
660
714
  screenset: "Hanay ng Screen:",
661
715
  theme: "Tema:",
662
716
  language: "Wika:",
663
- mockApi: "Mock API"
717
+ mockApi: "Mock API",
718
+ gts_package: "GTS Package"
664
719
  }
665
720
  };
666
721
  }
@@ -681,7 +736,8 @@ var require_tr = __commonJS({
681
736
  screenset: "Ekran Seti:",
682
737
  theme: "Tema:",
683
738
  language: "Dil:",
684
- mockApi: "Sahte API"
739
+ mockApi: "Sahte API",
740
+ gts_package: "GTS Package"
685
741
  }
686
742
  };
687
743
  }
@@ -702,7 +758,8 @@ var require_uk = __commonJS({
702
758
  screenset: "\u041D\u0430\u0431\u0456\u0440 \u0435\u043A\u0440\u0430\u043D\u0456\u0432:",
703
759
  theme: "\u0422\u0435\u043C\u0430:",
704
760
  language: "\u041C\u043E\u0432\u0430:",
705
- mockApi: "\u0424\u0456\u043A\u0442\u0438\u0432\u043D\u0438\u0439 API"
761
+ mockApi: "\u0424\u0456\u043A\u0442\u0438\u0432\u043D\u0438\u0439 API",
762
+ gts_package: "GTS Package"
706
763
  }
707
764
  };
708
765
  }
@@ -723,7 +780,8 @@ var require_ur = __commonJS({
723
780
  screenset: "\u0627\u0633\u06A9\u0631\u06CC\u0646 \u0633\u06CC\u0679:",
724
781
  theme: "\u062A\u06BE\u06CC\u0645:",
725
782
  language: "\u0632\u0628\u0627\u0646:",
726
- mockApi: "\u0641\u0631\u0636\u06CC API"
783
+ mockApi: "\u0641\u0631\u0636\u06CC API",
784
+ gts_package: "GTS Package"
727
785
  }
728
786
  };
729
787
  }
@@ -744,7 +802,8 @@ var require_vi = __commonJS({
744
802
  screenset: "B\u1ED9 M\xE0n h\xECnh:",
745
803
  theme: "Ch\u1EE7 \u0111\u1EC1:",
746
804
  language: "Ng\xF4n ng\u1EEF:",
747
- mockApi: "API Gi\u1EA3 l\u1EADp"
805
+ mockApi: "API Gi\u1EA3 l\u1EADp",
806
+ gts_package: "GTS Package"
748
807
  }
749
808
  };
750
809
  }
@@ -765,7 +824,8 @@ var require_zh_TW = __commonJS({
765
824
  screenset: "\u87A2\u5E55\u96C6:",
766
825
  theme: "\u4E3B\u984C:",
767
826
  language: "\u8A9E\u8A00:",
768
- mockApi: "\u6A21\u64EC API"
827
+ mockApi: "\u6A21\u64EC API",
828
+ gts_package: "GTS Package"
769
829
  }
770
830
  };
771
831
  }
@@ -786,7 +846,8 @@ var require_zh = __commonJS({
786
846
  screenset: "\u5C4F\u5E55\u96C6:",
787
847
  theme: "\u4E3B\u9898:",
788
848
  language: "\u8BED\u8A00:",
789
- mockApi: "\u6A21\u62DF API"
849
+ mockApi: "\u6A21\u62DF API",
850
+ gts_package: "GTS Package"
790
851
  }
791
852
  };
792
853
  }
@@ -828,14 +889,19 @@ var STORAGE_KEYS = {
828
889
  POSITION: `${STORAGE_PREFIX}position`,
829
890
  SIZE: `${STORAGE_PREFIX}size`,
830
891
  COLLAPSED: `${STORAGE_PREFIX}collapsed`,
831
- BUTTON_POSITION: `${STORAGE_PREFIX}buttonPosition`
892
+ BUTTON_POSITION: `${STORAGE_PREFIX}buttonPosition`,
893
+ THEME: `${STORAGE_PREFIX}theme`,
894
+ LANGUAGE: `${STORAGE_PREFIX}language`,
895
+ MOCK_ENABLED: `${STORAGE_PREFIX}mockEnabled`,
896
+ ACTIVE_PACKAGE_ID: `${STORAGE_PREFIX}activePackageId`
832
897
  };
833
898
 
834
899
  // src/events/studioEvents.ts
835
900
  var StudioEvents = {
836
901
  PositionChanged: "studio/positionChanged",
837
902
  SizeChanged: "studio/sizeChanged",
838
- ButtonPositionChanged: "studio/buttonPositionChanged"
903
+ ButtonPositionChanged: "studio/buttonPositionChanged",
904
+ ActivePackageChanged: "studio/activePackageChanged"
839
905
  };
840
906
 
841
907
  // src/effects/persistenceEffects.ts
@@ -858,12 +924,82 @@ var initPersistenceEffects = () => {
858
924
  saveStudioState(STORAGE_KEYS.BUTTON_POSITION, position);
859
925
  }
860
926
  );
927
+ const themeSubscription = react.eventBus.on("theme/changed", (payload) => {
928
+ saveStudioState(STORAGE_KEYS.THEME, payload.themeId);
929
+ });
930
+ const languageSubscription = react.eventBus.on("i18n/language/changed", (payload) => {
931
+ saveStudioState(STORAGE_KEYS.LANGUAGE, payload.language);
932
+ });
933
+ const mockSubscription = react.eventBus.on("mock/toggle", (payload) => {
934
+ saveStudioState(STORAGE_KEYS.MOCK_ENABLED, payload.enabled);
935
+ });
936
+ const activePackageSubscription = react.eventBus.on(
937
+ StudioEvents.ActivePackageChanged,
938
+ ({ activePackageId }) => {
939
+ saveStudioState(STORAGE_KEYS.ACTIVE_PACKAGE_ID, activePackageId);
940
+ }
941
+ );
861
942
  return () => {
862
943
  positionSubscription.unsubscribe();
863
944
  sizeSubscription.unsubscribe();
864
945
  buttonPositionSubscription.unsubscribe();
946
+ themeSubscription.unsubscribe();
947
+ languageSubscription.unsubscribe();
948
+ mockSubscription.unsubscribe();
949
+ activePackageSubscription.unsubscribe();
865
950
  };
866
951
  };
952
+ function isScreenExtension(ext) {
953
+ return "presentation" in ext && typeof ext.presentation === "object";
954
+ }
955
+ var useRestoreStudioSettings = () => {
956
+ const restoredRef = React2.useRef(false);
957
+ React2.useEffect(() => {
958
+ if (restoredRef.current) return;
959
+ restoredRef.current = true;
960
+ const themeId = loadStudioState(STORAGE_KEYS.THEME, null);
961
+ if (themeId != null && typeof themeId === "string" && themeId.length > 0) {
962
+ react.eventBus.emit("theme/changed", { themeId });
963
+ }
964
+ const language = loadStudioState(STORAGE_KEYS.LANGUAGE, null);
965
+ if (language != null && typeof language === "string" && language.length > 0) {
966
+ react.eventBus.emit("i18n/language/changed", { language });
967
+ }
968
+ const mockEnabled = loadStudioState(STORAGE_KEYS.MOCK_ENABLED, null);
969
+ if (typeof mockEnabled === "boolean") {
970
+ react.eventBus.emit("mock/toggle", { enabled: mockEnabled });
971
+ }
972
+ }, []);
973
+ };
974
+ var useRestoreGtsPackage = (registry) => {
975
+ const restoredRef = React2.useRef(false);
976
+ React2.useEffect(() => {
977
+ if (restoredRef.current || !registry) return;
978
+ const activePackageId = loadStudioState(STORAGE_KEYS.ACTIVE_PACKAGE_ID, null);
979
+ if (!activePackageId || typeof activePackageId !== "string") return;
980
+ restoredRef.current = true;
981
+ const restore = async () => {
982
+ try {
983
+ const extensions = registry.getExtensionsForPackage(activePackageId);
984
+ const screenExtensions = extensions.filter(
985
+ (ext) => ext.domain === react.HAI3_SCREEN_DOMAIN && isScreenExtension(ext)
986
+ );
987
+ if (screenExtensions.length === 0) return;
988
+ screenExtensions.sort((a, b) => (a.presentation.order ?? 0) - (b.presentation.order ?? 0));
989
+ const firstExtension = screenExtensions[0];
990
+ await registry.executeActionsChain({
991
+ action: {
992
+ type: react.HAI3_ACTION_MOUNT_EXT,
993
+ target: react.HAI3_SCREEN_DOMAIN,
994
+ payload: { extensionId: firstExtension.id }
995
+ }
996
+ });
997
+ } catch {
998
+ }
999
+ };
1000
+ void restore();
1001
+ }, [registry]);
1002
+ };
867
1003
  var studioTranslations = react.I18nRegistry.createLoader({
868
1004
  [react.Language.English]: () => Promise.resolve().then(() => __toESM(require_en())),
869
1005
  [react.Language.Arabic]: () => Promise.resolve().then(() => __toESM(require_ar())),
@@ -903,31 +1039,37 @@ var studioTranslations = react.I18nRegistry.createLoader({
903
1039
  [react.Language.ChineseSimplified]: () => Promise.resolve().then(() => __toESM(require_zh()))
904
1040
  });
905
1041
  react.i18nRegistry.registerLoader("studio", studioTranslations);
906
- var StudioContext = React3.createContext(void 0);
1042
+ var StudioContext = React2.createContext(void 0);
1043
+ var RestoreGtsPackageOnMount = () => {
1044
+ const app = react.useHAI3();
1045
+ useRestoreGtsPackage(app.screensetsRegistry);
1046
+ return null;
1047
+ };
907
1048
  var useStudioContext = () => {
908
- const context = React3.useContext(StudioContext);
1049
+ const context = React2.useContext(StudioContext);
909
1050
  if (!context) {
910
1051
  throw new Error("useStudioContext must be used within StudioProvider");
911
1052
  }
912
1053
  return context;
913
1054
  };
914
1055
  var StudioProvider = ({ children }) => {
915
- const [collapsed, setCollapsed] = React3.useState(
1056
+ const [collapsed, setCollapsed] = React2.useState(
916
1057
  () => loadStudioState(STORAGE_KEYS.COLLAPSED, false)
917
1058
  );
918
- const [portalContainer, setPortalContainer] = React3.useState(null);
919
- React3.useEffect(() => {
1059
+ const [portalContainer, setPortalContainer] = React2.useState(null);
1060
+ React2.useEffect(() => {
920
1061
  const cleanup = initPersistenceEffects();
921
1062
  return cleanup;
922
1063
  }, []);
923
- const toggleCollapsed = React3.useCallback(() => {
1064
+ useRestoreStudioSettings();
1065
+ const toggleCollapsed = React2.useCallback(() => {
924
1066
  setCollapsed((prev) => {
925
1067
  const newValue = !prev;
926
1068
  saveStudioState(STORAGE_KEYS.COLLAPSED, newValue);
927
1069
  return newValue;
928
1070
  });
929
1071
  }, []);
930
- return /* @__PURE__ */ jsxRuntime.jsx(
1072
+ return /* @__PURE__ */ jsxRuntime.jsxs(
931
1073
  StudioContext.Provider,
932
1074
  {
933
1075
  value: {
@@ -936,11 +1078,77 @@ var StudioProvider = ({ children }) => {
936
1078
  portalContainer,
937
1079
  setPortalContainer
938
1080
  },
939
- children
1081
+ children: [
1082
+ /* @__PURE__ */ jsxRuntime.jsx(RestoreGtsPackageOnMount, {}),
1083
+ children
1084
+ ]
940
1085
  }
941
1086
  );
942
1087
  };
943
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";
944
1152
  var VIEWPORT_MARGIN = 20;
945
1153
  function clampToViewport(pos, size) {
946
1154
  const maxX = Math.max(VIEWPORT_MARGIN, window.innerWidth - size.width - VIEWPORT_MARGIN);
@@ -955,19 +1163,19 @@ var useDraggable = ({ panelSize, storageKey = STORAGE_KEYS.POSITION }) => {
955
1163
  x: window.innerWidth - panelSize.width - VIEWPORT_MARGIN,
956
1164
  y: window.innerHeight - panelSize.height - VIEWPORT_MARGIN
957
1165
  });
958
- const [position, setPosition] = React3.useState(
1166
+ const [position, setPosition] = React2.useState(
959
1167
  () => clampToViewport(loadStudioState(storageKey, getDefaultPosition()), panelSize)
960
1168
  );
961
- const [isDragging, setIsDragging] = React3.useState(false);
962
- const dragStartPos = React3.useRef({ x: 0, y: 0 });
963
- const handleMouseDown = React3.useCallback((e) => {
1169
+ const [isDragging, setIsDragging] = React2.useState(false);
1170
+ const dragStartPos = React2.useRef({ x: 0, y: 0 });
1171
+ const handleMouseDown = React2.useCallback((e) => {
964
1172
  setIsDragging(true);
965
1173
  dragStartPos.current = {
966
1174
  x: e.clientX - position.x,
967
1175
  y: e.clientY - position.y
968
1176
  };
969
1177
  }, [position]);
970
- React3.useEffect(() => {
1178
+ React2.useEffect(() => {
971
1179
  if (!isDragging) return;
972
1180
  const handleMouseMove = (e) => {
973
1181
  const maxX = Math.max(VIEWPORT_MARGIN, window.innerWidth - panelSize.width - VIEWPORT_MARGIN);
@@ -989,7 +1197,7 @@ var useDraggable = ({ panelSize, storageKey = STORAGE_KEYS.POSITION }) => {
989
1197
  window.removeEventListener("mouseup", handleMouseUp);
990
1198
  };
991
1199
  }, [isDragging, panelSize.width, panelSize.height, storageKey]);
992
- React3.useEffect(() => {
1200
+ React2.useEffect(() => {
993
1201
  const handleResize = () => {
994
1202
  setPosition((prev) => {
995
1203
  const clamped = clampToViewport(prev, panelSize);
@@ -1009,15 +1217,15 @@ var useDraggable = ({ panelSize, storageKey = STORAGE_KEYS.POSITION }) => {
1009
1217
  };
1010
1218
  };
1011
1219
  var useResizable = () => {
1012
- const [size, setSize] = React3.useState(
1220
+ const [size, setSize] = React2.useState(
1013
1221
  () => loadStudioState(STORAGE_KEYS.SIZE, {
1014
1222
  width: PANEL_CONSTRAINTS.DEFAULT_WIDTH,
1015
1223
  height: PANEL_CONSTRAINTS.DEFAULT_HEIGHT
1016
1224
  })
1017
1225
  );
1018
- const [isResizing, setIsResizing] = React3.useState(false);
1019
- const resizeStartRef = React3.useRef(null);
1020
- const handleMouseDown = React3.useCallback((e) => {
1226
+ const [isResizing, setIsResizing] = React2.useState(false);
1227
+ const resizeStartRef = React2.useRef(null);
1228
+ const handleMouseDown = React2.useCallback((e) => {
1021
1229
  e.stopPropagation();
1022
1230
  resizeStartRef.current = {
1023
1231
  mouseX: e.clientX,
@@ -1027,7 +1235,7 @@ var useResizable = () => {
1027
1235
  };
1028
1236
  setIsResizing(true);
1029
1237
  }, [size.width, size.height]);
1030
- React3.useEffect(() => {
1238
+ React2.useEffect(() => {
1031
1239
  if (!isResizing || !resizeStartRef.current) return;
1032
1240
  const startState = resizeStartRef.current;
1033
1241
  document.body.style.userSelect = "none";
@@ -1070,6 +1278,148 @@ var useResizable = () => {
1070
1278
  handleMouseDown
1071
1279
  };
1072
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";
1365
+ function isScreenExtension2(ext) {
1366
+ return "presentation" in ext && typeof ext.presentation === "object";
1367
+ }
1368
+ var MfePackageSelector = ({
1369
+ className = ""
1370
+ }) => {
1371
+ const app = react.useHAI3();
1372
+ const registry = app.screensetsRegistry;
1373
+ const { portalContainer } = useStudioContext();
1374
+ const { t } = react.useTranslation();
1375
+ const packages = react.useRegisteredPackages();
1376
+ const activePackage = react.useActivePackage();
1377
+ if (!registry) {
1378
+ return null;
1379
+ }
1380
+ const handlePackageChange = async (selectedPackageId) => {
1381
+ const extensions = registry.getExtensionsForPackage(selectedPackageId);
1382
+ const screenExtensions = extensions.filter(
1383
+ (ext) => ext.domain === react.HAI3_SCREEN_DOMAIN && isScreenExtension2(ext)
1384
+ );
1385
+ if (screenExtensions.length === 0) {
1386
+ console.warn(`No screen extensions found for package: ${selectedPackageId}`);
1387
+ return;
1388
+ }
1389
+ screenExtensions.sort((a, b) => (a.presentation.order ?? 0) - (b.presentation.order ?? 0));
1390
+ const firstExtension = screenExtensions[0];
1391
+ await registry.executeActionsChain({
1392
+ action: {
1393
+ type: react.HAI3_ACTION_MOUNT_EXT,
1394
+ target: react.HAI3_SCREEN_DOMAIN,
1395
+ payload: { extensionId: firstExtension.id }
1396
+ }
1397
+ });
1398
+ react.eventBus.emit(StudioEvents.ActivePackageChanged, { activePackageId: selectedPackageId });
1399
+ };
1400
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
1401
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.gts_package") }),
1402
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
1403
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1404
+ DropdownButton,
1405
+ {
1406
+ variant: "outline" /* Outline */,
1407
+ disabled: packages.length <= 1,
1408
+ children: activePackage || "No package"
1409
+ }
1410
+ ) }),
1411
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: packages.map((pkg) => /* @__PURE__ */ jsxRuntime.jsx(
1412
+ DropdownMenuItem,
1413
+ {
1414
+ onClick: () => handlePackageChange(pkg),
1415
+ children: pkg
1416
+ },
1417
+ pkg
1418
+ )) })
1419
+ ] })
1420
+ ] });
1421
+ };
1422
+ MfePackageSelector.displayName = "MfePackageSelector";
1073
1423
  var ThemeSelector = ({
1074
1424
  className = ""
1075
1425
  }) => {
@@ -1081,10 +1431,10 @@ var ThemeSelector = ({
1081
1431
  };
1082
1432
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
1083
1433
  /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.theme") }),
1084
- /* @__PURE__ */ jsxRuntime.jsxs(uikit.DropdownMenu, { children: [
1085
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownButton, { variant: uikit.ButtonVariant.Outline, children: formatThemeName(currentTheme || "") }) }),
1086
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: themes.map((theme) => /* @__PURE__ */ jsxRuntime.jsx(
1087
- 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,
1088
1438
  {
1089
1439
  onClick: () => setTheme(theme.id),
1090
1440
  children: formatThemeName(theme.name || theme.id)
@@ -1095,46 +1445,6 @@ var ThemeSelector = ({
1095
1445
  ] });
1096
1446
  };
1097
1447
  ThemeSelector.displayName = "ThemeSelector";
1098
- var ScreensetSelector = ({
1099
- options,
1100
- currentValue,
1101
- onChange,
1102
- className = ""
1103
- }) => {
1104
- const { portalContainer } = useStudioContext();
1105
- const { t, isRTL } = react.useTranslation();
1106
- const formatName = (name) => {
1107
- return name.split(/[-_]/).map((word) => lodash.upperFirst(word)).join(" ");
1108
- };
1109
- const getCurrentDisplay = () => {
1110
- const [category, itemId] = currentValue.split(":");
1111
- if (!category || !itemId) return "Select";
1112
- const categoryGroup = options.find((opt) => opt.category === category);
1113
- const item = categoryGroup?.screensets.find((i) => i.id === itemId);
1114
- return item ? item.name : "Select";
1115
- };
1116
- const handleItemClick = (category, itemId) => {
1117
- onChange(`${category}:${itemId}`);
1118
- };
1119
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
1120
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.screenset") }),
1121
- /* @__PURE__ */ jsxRuntime.jsxs(uikit.DropdownMenu, { dir: isRTL ? "rtl" : "ltr", children: [
1122
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownButton, { variant: uikit.ButtonVariant.Outline, children: formatName(getCurrentDisplay()) }) }),
1123
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: options.map((categoryGroup) => /* @__PURE__ */ jsxRuntime.jsxs(uikit.DropdownMenuSub, { children: [
1124
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuSubTrigger, { disabled: categoryGroup.screensets.length === 0, children: formatName(categoryGroup.category) }),
1125
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuSubContent, { container: portalContainer, className: "z-[99999] pointer-events-auto", children: categoryGroup.screensets.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
1126
- uikit.DropdownMenuItem,
1127
- {
1128
- onClick: () => handleItemClick(categoryGroup.category, item.id),
1129
- children: formatName(item.name)
1130
- },
1131
- item.id
1132
- )) })
1133
- ] }, categoryGroup.category)) })
1134
- ] })
1135
- ] });
1136
- };
1137
- ScreensetSelector.displayName = "ScreensetSelector";
1138
1448
  var FALLBACK_SELECT_LANGUAGE_TEXT = "Select language";
1139
1449
  var RTL_INDICATOR_SUFFIX = " (RTL)";
1140
1450
  function LanguageSelector({
@@ -1145,10 +1455,10 @@ function LanguageSelector({
1145
1455
  const currentLanguage = language ? react.getLanguageMetadata(language) : null;
1146
1456
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
1147
1457
  /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.language") }),
1148
- /* @__PURE__ */ jsxRuntime.jsxs(uikit.DropdownMenu, { children: [
1149
- /* @__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 }) }),
1150
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: react.SUPPORTED_LANGUAGES.map((lang) => /* @__PURE__ */ jsxRuntime.jsxs(
1151
- 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,
1152
1462
  {
1153
1463
  onClick: () => setLanguage(lang.code),
1154
1464
  children: [
@@ -1161,6 +1471,32 @@ function LanguageSelector({
1161
1471
  ] })
1162
1472
  ] });
1163
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;
1164
1500
  var ApiModeToggle = ({
1165
1501
  className
1166
1502
  }) => {
@@ -1182,7 +1518,7 @@ var ApiModeToggle = ({
1182
1518
  }
1183
1519
  ),
1184
1520
  /* @__PURE__ */ jsxRuntime.jsx(
1185
- uikit.Switch,
1521
+ Switch,
1186
1522
  {
1187
1523
  id: "api-mode-toggle",
1188
1524
  checked: enabled,
@@ -1192,48 +1528,12 @@ var ApiModeToggle = ({
1192
1528
  ] });
1193
1529
  };
1194
1530
  ApiModeToggle.displayName = "ApiModeToggle";
1195
- var ALL_CATEGORIES = [react.ScreensetCategory.Drafts, react.ScreensetCategory.Mockups, react.ScreensetCategory.Production];
1196
- var buildScreensetOptions = () => {
1197
- const allScreensets = react.screensetRegistry.getAll();
1198
- return ALL_CATEGORIES.map((category) => ({
1199
- category,
1200
- screensets: allScreensets.filter((s) => s.category === category).map((s) => ({
1201
- id: s.id,
1202
- name: s.name
1203
- }))
1204
- }));
1205
- };
1206
1531
  var ControlPanel = () => {
1207
- const { currentScreenset, navigateToScreenset } = react.useNavigation();
1208
- const [screensetOptions, setScreensetOptions] = React3.useState([]);
1209
1532
  const { t } = react.useTranslation();
1210
- React3.useEffect(() => {
1211
- const options = buildScreensetOptions();
1212
- setScreensetOptions(options);
1213
- }, []);
1214
- const getCurrentValue = () => {
1215
- if (!currentScreenset) return "";
1216
- const screenset = react.screensetRegistry.get(currentScreenset);
1217
- if (!screenset) return "";
1218
- return `${screenset.category}:${screenset.id}`;
1219
- };
1220
- const handleScreensetChange = (value) => {
1221
- const [, screensetId] = value.split(":");
1222
- if (screensetId) {
1223
- navigateToScreenset(screensetId);
1224
- }
1225
- };
1226
1533
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1227
1534
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: t("studio:controls.heading") }),
1228
1535
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1229
- screensetOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1230
- ScreensetSelector,
1231
- {
1232
- options: screensetOptions,
1233
- currentValue: getCurrentValue(),
1234
- onChange: handleScreensetChange
1235
- }
1236
- ),
1536
+ /* @__PURE__ */ jsxRuntime.jsx(MfePackageSelector, {}),
1237
1537
  /* @__PURE__ */ jsxRuntime.jsx(ApiModeToggle, {}),
1238
1538
  /* @__PURE__ */ jsxRuntime.jsx(ThemeSelector, {}),
1239
1539
  /* @__PURE__ */ jsxRuntime.jsx(LanguageSelector, {})
@@ -1244,13 +1544,13 @@ ControlPanel.displayName = "ControlPanel";
1244
1544
  var StudioPanel = () => {
1245
1545
  const { toggleCollapsed, setPortalContainer } = useStudioContext();
1246
1546
  const { t } = react.useTranslation();
1247
- const portalRef = React3__default.default.useRef(null);
1547
+ const portalRef = React2__default.default.useRef(null);
1248
1548
  const { size, handleMouseDown: handleResizeMouseDown } = useResizable();
1249
1549
  const { position, isDragging, handleMouseDown: handleDragMouseDown } = useDraggable({
1250
1550
  panelSize: size,
1251
1551
  storageKey: STORAGE_KEYS.POSITION
1252
1552
  });
1253
- React3__default.default.useEffect(() => {
1553
+ React2__default.default.useEffect(() => {
1254
1554
  setPortalContainer(portalRef.current);
1255
1555
  return () => setPortalContainer(null);
1256
1556
  }, [setPortalContainer]);
@@ -1272,7 +1572,7 @@ var StudioPanel = () => {
1272
1572
  width: `${size.width}px`,
1273
1573
  height: `${size.height}px`
1274
1574
  },
1275
- 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: [
1276
1576
  /* @__PURE__ */ jsxRuntime.jsxs(
1277
1577
  "div",
1278
1578
  {
@@ -1282,10 +1582,10 @@ var StudioPanel = () => {
1282
1582
  children: [
1283
1583
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold text-foreground", children: t("studio:title") }),
1284
1584
  /* @__PURE__ */ jsxRuntime.jsx(
1285
- uikit.Button,
1585
+ Button,
1286
1586
  {
1287
- variant: uikit.ButtonVariant.Ghost,
1288
- size: uikit.ButtonSize.Sm,
1587
+ variant: "ghost" /* Ghost */,
1588
+ size: "sm" /* Sm */,
1289
1589
  onClick: toggleCollapsed,
1290
1590
  className: "h-7 w-7 p-0",
1291
1591
  "aria-label": t("studio:aria.collapseButton"),
@@ -1341,7 +1641,7 @@ var StudioPanel = () => {
1341
1641
  };
1342
1642
  StudioPanel.displayName = "StudioPanel";
1343
1643
  var useKeyboardShortcut = (handler) => {
1344
- React3.useEffect(() => {
1644
+ React2.useEffect(() => {
1345
1645
  const handleKeyDown = (e) => {
1346
1646
  if (e.shiftKey && e.code === "Backquote") {
1347
1647
  e.preventDefault();
@@ -1362,9 +1662,9 @@ var GlassmorphicButton = ({
1362
1662
  isDragging = false
1363
1663
  }) => {
1364
1664
  return /* @__PURE__ */ jsxRuntime.jsx(
1365
- uikit.Button,
1665
+ Button,
1366
1666
  {
1367
- variant: uikit.ButtonVariant.Ghost,
1667
+ variant: "ghost" /* Ghost */,
1368
1668
  onMouseDown,
1369
1669
  onClick,
1370
1670
  title,
@@ -1401,7 +1701,7 @@ var CollapsedButton = ({ toggleCollapsed }) => {
1401
1701
  panelSize: BUTTON_SIZE,
1402
1702
  storageKey: STORAGE_KEYS.BUTTON_POSITION
1403
1703
  });
1404
- const dragStartPosition = React3.useRef(null);
1704
+ const dragStartPosition = React2.useRef(null);
1405
1705
  const handleButtonMouseDown = (e) => {
1406
1706
  dragStartPosition.current = { x: e.clientX, y: e.clientY };
1407
1707
  handleMouseDown(e);
@@ -1437,6 +1737,278 @@ var CollapsedButton = ({ toggleCollapsed }) => {
1437
1737
  );
1438
1738
  };
1439
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
+ }
1440
2012
  var StudioContent = () => {
1441
2013
  const { collapsed, toggleCollapsed } = useStudioContext();
1442
2014
  useKeyboardShortcut(toggleCollapsed);
@@ -1446,6 +2018,9 @@ var StudioContent = () => {
1446
2018
  return /* @__PURE__ */ jsxRuntime.jsx(StudioPanel, {});
1447
2019
  };
1448
2020
  var StudioOverlay = () => {
2021
+ React2.useEffect(() => {
2022
+ return injectStudioStyles();
2023
+ }, []);
1449
2024
  return /* @__PURE__ */ jsxRuntime.jsx(StudioProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(StudioContent, {}) });
1450
2025
  };
1451
2026
  StudioOverlay.displayName = "StudioOverlay";