@tutti-os/workspace-app-center 0.0.12 → 0.0.14

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/ui/index.js CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  } from "../chunk-2HXFGEJS.js";
8
8
 
9
9
  // src/ui/AppCard.tsx
10
+ import { memo, useCallback, useMemo } from "react";
10
11
  import {
11
12
  Button,
12
13
  ChatIcon,
@@ -25,21 +26,30 @@ import {
25
26
  cn
26
27
  } from "@tutti-os/ui-system";
27
28
  import { jsx, jsxs } from "react/jsx-runtime";
28
- function AppCard({
29
+ var AppCard = memo(function AppCard2({
29
30
  actions,
30
31
  app,
31
32
  className,
32
33
  copy
33
34
  }) {
34
35
  const statusLabel = copy.t(app.statusLabelKey);
35
- const primaryActionLabel = app.primaryAction === "install" ? copy.t("actions.installApp") : app.primaryAction === "retry" ? copy.t("actions.retryApp") : app.primaryAction === "update" ? copy.t("actions.updateApp") : copy.t("actions.openApp");
36
+ const installBusy = app.installProgress != null || app.status === "installing";
37
+ const busyStatusLabel = installBusy ? copy.t("status.installing") : statusLabel;
38
+ const showInstallProgressRing = installBusy;
39
+ const statusButtonTitle = app.installProgress ? resolveInstallProgressTitle(copy, app.installProgress, busyStatusLabel) : statusLabel;
40
+ const primaryActionLabel = app.primaryAction === "install" ? copy.t("actions.installApp") : app.primaryAction === "retry" ? copy.t("actions.retryApp") : app.primaryAction === "update" ? app.availableVersion ? copy.t("labels.updateAvailable", {
41
+ version: app.availableVersion
42
+ }) : copy.t("actions.updateApp") : copy.t("actions.openApp");
36
43
  const canExecutePrimaryAction = app.primaryAction !== "none";
37
44
  const canOpenFromCard = app.canOpen;
38
45
  const canPublishFactoryUpdate = app.canPublishFactoryUpdate && !!app.factoryJobId;
39
46
  const canOpenFactorySession = app.canOpenFactorySession && !!app.factoryAgentSessionId && !!app.factoryJobId;
40
- const actionContext = createWorkspaceAppActionContext(app);
47
+ const actionContext = useMemo(
48
+ () => createWorkspaceAppActionContext(app),
49
+ [app]
50
+ );
41
51
  const hasMoreActions = canPublishFactoryUpdate || canOpenFactorySession || app.canExport || app.canDelete || app.canReplaceIcon || app.canOpenFolder || app.canOpenPackageFolder || app.canUninstall;
42
- const executePrimaryAction = () => {
52
+ const executePrimaryAction = useCallback(() => {
43
53
  if (app.primaryAction === "retry") {
44
54
  void actions.retryApp?.(app.id);
45
55
  return;
@@ -55,12 +65,25 @@ function AppCard({
55
65
  if (app.primaryAction === "open") {
56
66
  void actions.openApp?.(app.id, actionContext);
57
67
  }
58
- };
59
- const executeCardAction = () => {
68
+ }, [actionContext, actions, app.id, app.primaryAction]);
69
+ const executeCardAction = useCallback(() => {
60
70
  if (canOpenFromCard) {
61
71
  void actions.openApp?.(app.id, actionContext);
62
72
  }
63
- };
73
+ }, [actionContext, actions, app.id, canOpenFromCard]);
74
+ const handleCardKeyDown = useCallback(
75
+ (event) => {
76
+ if (!canOpenFromCard || event.key !== "Enter" && event.key !== " ") {
77
+ return;
78
+ }
79
+ event.preventDefault();
80
+ executeCardAction();
81
+ },
82
+ [canOpenFromCard, executeCardAction]
83
+ );
84
+ const handleReplaceIcon = useCallback(() => {
85
+ void actions.replaceAppIcon?.(app.id);
86
+ }, [actions, app.id]);
64
87
  return /* @__PURE__ */ jsxs(
65
88
  "article",
66
89
  {
@@ -74,13 +97,7 @@ function AppCard({
74
97
  role: "listitem",
75
98
  tabIndex: canOpenFromCard ? 0 : -1,
76
99
  onClick: executeCardAction,
77
- onKeyDown: (event) => {
78
- if (!canOpenFromCard || event.key !== "Enter" && event.key !== " ") {
79
- return;
80
- }
81
- event.preventDefault();
82
- executeCardAction();
83
- },
100
+ onKeyDown: handleCardKeyDown,
84
101
  children: [
85
102
  /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
86
103
  /* @__PURE__ */ jsx(
@@ -88,13 +105,11 @@ function AppCard({
88
105
  {
89
106
  app,
90
107
  replaceIconLabel: copy.t("actions.replaceIcon"),
91
- onReplaceIcon: () => {
92
- void actions.replaceAppIcon?.(app.id);
93
- }
108
+ onReplaceIcon: handleReplaceIcon
94
109
  }
95
110
  ),
96
111
  /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
97
- hasMoreActions ? /* @__PURE__ */ jsx(
112
+ /* @__PURE__ */ jsx("div", { className: "flex size-8 shrink-0 items-center justify-center", children: hasMoreActions ? /* @__PURE__ */ jsx(
98
113
  AppCardMoreActions,
99
114
  {
100
115
  actions,
@@ -103,27 +118,37 @@ function AppCard({
103
118
  canPublishFactoryUpdate,
104
119
  copy
105
120
  }
106
- ) : null,
107
- /* @__PURE__ */ jsx(
108
- Button,
109
- {
110
- className: cn(
111
- "min-w-[56px]",
112
- !canExecutePrimaryAction ? "cursor-default" : null,
113
- canExecutePrimaryAction ? app.primaryAction === "retry" ? statusClassName(app.status) : "text-[var(--text-primary)]" : statusClassName(app.status)
114
- ),
115
- disabled: !canExecutePrimaryAction,
116
- size: "default",
117
- title: statusLabel,
118
- type: "button",
119
- variant: "ghost",
120
- onClick: (event) => {
121
- event.stopPropagation();
122
- executePrimaryAction();
123
- },
124
- children: canExecutePrimaryAction ? primaryActionLabel : statusLabel
125
- }
126
- )
121
+ ) : null }),
122
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
123
+ /* @__PURE__ */ jsx(
124
+ Button,
125
+ {
126
+ className: cn(
127
+ "min-w-[56px] shrink-0",
128
+ !canExecutePrimaryAction ? "cursor-default" : null,
129
+ canExecutePrimaryAction ? app.primaryAction === "retry" ? statusClassName(app.status) : "text-[var(--text-primary)]" : statusClassName(app.status)
130
+ ),
131
+ disabled: !canExecutePrimaryAction,
132
+ size: "default",
133
+ title: statusButtonTitle,
134
+ type: "button",
135
+ variant: "ghost",
136
+ onClick: (event) => {
137
+ event.stopPropagation();
138
+ executePrimaryAction();
139
+ },
140
+ children: canExecutePrimaryAction ? primaryActionLabel : busyStatusLabel
141
+ }
142
+ ),
143
+ showInstallProgressRing ? /* @__PURE__ */ jsx(
144
+ AppInstallProgressRing,
145
+ {
146
+ ariaLabel: copy.t("status.installProgress.progressAria"),
147
+ fallbackPercent: 0,
148
+ progress: app.installProgress
149
+ }
150
+ ) : null
151
+ ] })
127
152
  ] })
128
153
  ] }),
129
154
  /* @__PURE__ */ jsxs("div", { className: "mt-5 flex min-h-0 min-w-0 flex-1 flex-col p-1", children: [
@@ -132,52 +157,21 @@ function AppCard({
132
157
  /* @__PURE__ */ jsx("h3", { className: "block min-w-0 truncate text-[15px] font-semibold leading-6 tracking-[0] text-[var(--text-primary)]", children: app.name }),
133
158
  app.version ? /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-none text-[11px] leading-4 text-[var(--text-tertiary)] opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100", children: copy.t("labels.version", { version: app.version }) }) : null
134
159
  ] }),
135
- app.updateAvailable && app.availableVersion ? /* @__PURE__ */ jsx(
136
- "button",
137
- {
138
- className: cn(
139
- "mt-1 inline-flex max-w-full items-center rounded-[4px] bg-[color-mix(in_srgb,var(--state-warning)_12%,transparent)] px-2 py-0.5 text-[11px] leading-4 text-[var(--state-warning)] outline-none transition-colors hover:bg-[color-mix(in_srgb,var(--state-warning)_18%,transparent)] focus-visible:ring-2 focus-visible:ring-[color-mix(in_srgb,var(--state-warning)_42%,transparent)]",
140
- app.canUpdate ? "cursor-pointer" : "cursor-default"
141
- ),
142
- disabled: !app.canUpdate,
143
- title: copy.t("actions.updateApp"),
144
- type: "button",
145
- onClick: (event) => {
146
- event.stopPropagation();
147
- if (app.canUpdate) {
148
- void actions.updateApp?.(app.id, "badge_button");
149
- }
150
- },
151
- children: /* @__PURE__ */ jsx("span", { className: "truncate", children: copy.t("labels.updateAvailable", {
152
- version: app.availableVersion
153
- }) })
154
- }
155
- ) : null,
156
160
  app.description ? /* @__PURE__ */ jsx("p", { className: "mt-2 line-clamp-3 text-[13px] font-normal leading-[1.3] text-[var(--text-secondary)]", children: app.description }) : null
157
161
  ] }),
158
- app.errorMessage || app.tags.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "mt-auto flex min-w-0 flex-col gap-3 pt-3", children: [
159
- app.errorMessage ? /* @__PURE__ */ jsx(
160
- "p",
161
- {
162
- className: "min-w-0 rounded-[6px] bg-[color-mix(in_srgb,var(--state-danger)_10%,transparent)] px-2 py-1 text-[11px] leading-4 text-[var(--state-danger)]",
163
- title: app.errorMessage,
164
- children: copy.t("messages.appRuntimeFailed")
165
- }
166
- ) : null,
167
- app.tags.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-wrap gap-1.5", children: app.tags.slice(0, 3).map((tag) => /* @__PURE__ */ jsx(
168
- "span",
169
- {
170
- className: "inline-flex h-5 max-w-full items-center rounded-[4px] bg-[var(--transparency-block)] px-2 text-[11px] leading-4 text-[var(--text-secondary)]",
171
- children: /* @__PURE__ */ jsx("span", { className: "truncate", children: tag })
172
- },
173
- tag
174
- )) }) : null
175
- ] }) : null
162
+ app.errorMessage ? /* @__PURE__ */ jsx("div", { className: "mt-auto flex min-w-0 flex-col gap-3 pt-3", children: /* @__PURE__ */ jsx(
163
+ "p",
164
+ {
165
+ className: "min-w-0 rounded-[6px] bg-[color-mix(in_srgb,var(--state-danger)_10%,transparent)] px-2 py-1 text-[11px] leading-4 text-[var(--state-danger)]",
166
+ title: app.errorMessage,
167
+ children: copy.t("messages.appRuntimeFailed")
168
+ }
169
+ ) }) : null
176
170
  ] })
177
171
  ]
178
172
  }
179
173
  );
180
- }
174
+ });
181
175
  function createWorkspaceAppActionContext(app) {
182
176
  return {
183
177
  installationId: app.installationId ?? null,
@@ -210,6 +204,13 @@ function AppCardMoreActions({
210
204
  key: "modify-app-with-agent",
211
205
  label: copy.t("actions.modifyAppWithAgent"),
212
206
  onSelect: () => {
207
+ if (app.factoryEditAction === "open_session") {
208
+ void actions.openFactoryJobAgentSession?.(
209
+ app.factoryAgentSessionId ?? "",
210
+ app.factoryProvider
211
+ );
212
+ return;
213
+ }
213
214
  void actions.modifyAppWithAgent?.(
214
215
  app.factoryJobId ?? "",
215
216
  app.factoryAgentSessionId ?? "",
@@ -403,6 +404,72 @@ function AppIcon({
403
404
  ) : null
404
405
  ] });
405
406
  }
407
+ function AppInstallProgressRing({
408
+ ariaLabel,
409
+ fallbackPercent,
410
+ progress
411
+ }) {
412
+ const percent = progress == null ? Math.max(0, Math.min(100, Math.round(fallbackPercent))) : Math.max(0, Math.min(100, Math.round(progress.overallPercent)));
413
+ return /* @__PURE__ */ jsx(
414
+ "span",
415
+ {
416
+ "aria-label": ariaLabel,
417
+ "aria-valuemax": 100,
418
+ "aria-valuemin": 0,
419
+ "aria-valuenow": percent,
420
+ className: "relative inline-flex size-[14px] shrink-0 items-center justify-center rounded-full",
421
+ role: "progressbar",
422
+ style: {
423
+ background: `conic-gradient(var(--text-secondary) ${percent}%, color-mix(in srgb, var(--text-secondary) 24%, transparent) 0)`
424
+ },
425
+ children: /* @__PURE__ */ jsx(
426
+ "span",
427
+ {
428
+ "aria-hidden": "true",
429
+ className: "absolute inset-[2px] rounded-full bg-[var(--surface-panel)]"
430
+ }
431
+ )
432
+ }
433
+ );
434
+ }
435
+ function resolveInstallProgressTitle(copy, progress, statusLabel) {
436
+ const byteLabel = formatInstallProgressBytes(copy, progress);
437
+ const percent = Math.max(
438
+ 0,
439
+ Math.min(100, Math.round(progress.overallPercent))
440
+ );
441
+ if (byteLabel) {
442
+ return `${statusLabel} \xB7 ${byteLabel} \xB7 ${percent}%`;
443
+ }
444
+ return `${statusLabel} \xB7 ${percent}%`;
445
+ }
446
+ function formatInstallProgressBytes(copy, progress) {
447
+ if (progress.userPhase !== "downloading" || progress.downloadedBytes == null) {
448
+ return null;
449
+ }
450
+ const downloaded = formatByteSize(progress.downloadedBytes);
451
+ if (progress.totalBytes == null || progress.totalBytes <= 0) {
452
+ return downloaded;
453
+ }
454
+ return copy.t("status.installProgress.downloadedOfTotal", {
455
+ downloaded,
456
+ total: formatByteSize(progress.totalBytes)
457
+ });
458
+ }
459
+ function formatByteSize(value) {
460
+ if (!Number.isFinite(value) || value <= 0) {
461
+ return "0 B";
462
+ }
463
+ const units = ["B", "KB", "MB", "GB"];
464
+ let size = value;
465
+ let unitIndex = 0;
466
+ while (size >= 1024 && unitIndex < units.length - 1) {
467
+ size /= 1024;
468
+ unitIndex += 1;
469
+ }
470
+ const precision = size >= 10 || unitIndex === 0 ? 0 : 1;
471
+ return `${size.toFixed(precision)} ${units[unitIndex]}`;
472
+ }
406
473
  function statusClassName(status) {
407
474
  if (status === "failed") {
408
475
  return "text-[var(--state-danger)]";
@@ -417,7 +484,7 @@ function statusClassName(status) {
417
484
  }
418
485
 
419
486
  // src/ui/AppCenterPanel.tsx
420
- import { useEffect, useId, useMemo, useState } from "react";
487
+ import { useEffect, useId, useMemo as useMemo2, useState } from "react";
421
488
  import {
422
489
  Badge,
423
490
  BareIconButton,
@@ -491,10 +558,10 @@ var factoryTemplates = [
491
558
  ];
492
559
  var recommendedCategoryTabDefinitions = [
493
560
  { id: "all", labelKey: null },
494
- { id: "tools", labelKey: "categories.tools" },
495
- { id: "content-creation", labelKey: "categories.contentCreation" },
496
561
  { id: "product-design", labelKey: "categories.productDesign" },
497
- { id: "office", labelKey: "categories.office" }
562
+ { id: "content-creation", labelKey: "categories.contentCreation" },
563
+ { id: "office", labelKey: "categories.office" },
564
+ { id: "tools", labelKey: "categories.tools" }
498
565
  ];
499
566
  function AppCenterPanel({
500
567
  actions,
@@ -517,6 +584,8 @@ function AppCenterPanel({
517
584
  const [pendingDeleteApp, setPendingDeleteApp] = useState(null);
518
585
  const [uninstallAppBusy, setUninstallAppBusy] = useState(false);
519
586
  const [pendingUninstallApp, setPendingUninstallApp] = useState(null);
587
+ const [updateAppBusy, setUpdateAppBusy] = useState(false);
588
+ const [pendingUpdateApp, setPendingUpdateApp] = useState(null);
520
589
  const [displayName, setDisplayName] = useState("");
521
590
  const [prompt, setPrompt] = useState("");
522
591
  const [providerConfiguration, setProviderConfiguration] = useState(null);
@@ -525,7 +594,7 @@ function AppCenterPanel({
525
594
  const [selectedModel, setSelectedModel] = useState("");
526
595
  const [selectedPermissionModeId, setSelectedPermissionModeId] = useState("");
527
596
  const [selectedReasoningEffort, setSelectedReasoningEffort] = useState("");
528
- const normalizedProviderOptions = useMemo(
597
+ const normalizedProviderOptions = useMemo2(
529
598
  () => providerOptions.map((option) => {
530
599
  const provider = option.provider.trim();
531
600
  const label = option.label.trim() || provider;
@@ -695,27 +764,45 @@ function AppCenterPanel({
695
764
  }
696
765
  void actions.openFactoryJobAgentSession?.(agentSessionId, job.provider);
697
766
  };
698
- const cardActions = {
699
- ...actions,
700
- deleteApp: (appId, appName) => {
701
- setPendingDeleteApp({
702
- id: appId,
703
- installed: viewModel.apps.find((app) => app.id === appId)?.installed ?? false,
704
- name: appName
705
- });
706
- },
707
- uninstallApp: (appId) => {
708
- const app = viewModel.apps.find((item) => item.id === appId);
709
- if (!app) {
710
- return;
767
+ const cardActions = useMemo2(
768
+ () => ({
769
+ ...actions,
770
+ deleteApp: (appId, appName) => {
771
+ setPendingDeleteApp({
772
+ id: appId,
773
+ installed: viewModel.apps.find((app) => app.id === appId)?.installed ?? false,
774
+ name: appName
775
+ });
776
+ },
777
+ uninstallApp: (appId) => {
778
+ const app = viewModel.apps.find((item) => item.id === appId);
779
+ if (!app) {
780
+ return;
781
+ }
782
+ setPendingUninstallApp({
783
+ id: app.id,
784
+ name: app.name,
785
+ sourceKind: app.sourceKind
786
+ });
787
+ },
788
+ updateApp: (appId, trigger) => {
789
+ const app = viewModel.apps.find((item) => item.id === appId);
790
+ if (!app) {
791
+ return;
792
+ }
793
+ if (app.installed && app.status === "running") {
794
+ setPendingUpdateApp({
795
+ id: app.id,
796
+ name: app.name,
797
+ trigger
798
+ });
799
+ return;
800
+ }
801
+ void actions.updateApp?.(appId, trigger);
711
802
  }
712
- setPendingUninstallApp({
713
- id: app.id,
714
- name: app.name,
715
- sourceKind: app.sourceKind
716
- });
717
- }
718
- };
803
+ }),
804
+ [actions, viewModel.apps]
805
+ );
719
806
  const loadingMessage = catalogStatus === "loading" ? copy.t("messages.catalogLoading") : null;
720
807
  const catalogLoading = catalogStatus === "loading";
721
808
  const failedMessage = catalogStatus === "failed" ? copy.t("messages.catalogFailed") : null;
@@ -775,6 +862,9 @@ function AppCenterPanel({
775
862
  const uninstallAppConfirmTitle = copy.t("confirmations.uninstallAppTitle", {
776
863
  name: pendingUninstallApp?.name ?? ""
777
864
  });
865
+ const updateAppConfirmTitle = copy.t("confirmations.updateAppTitle", {
866
+ name: pendingUpdateApp?.name ?? ""
867
+ });
778
868
  return /* @__PURE__ */ jsxs2(
779
869
  "section",
780
870
  {
@@ -785,7 +875,7 @@ function AppCenterPanel({
785
875
  ),
786
876
  children: [
787
877
  statusToast ? /* @__PURE__ */ jsx2(AppCenterStatusToast, { toast: statusToast }) : null,
788
- /* @__PURE__ */ jsx2("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-auto px-6 pb-6 pt-5 [container-type:inline-size]", children: /* @__PURE__ */ jsxs2("section", { className: "flex min-w-0 flex-col gap-3", children: [
878
+ /* @__PURE__ */ jsx2("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-auto px-6 pb-6 pt-5 [container-type:inline-size]", children: /* @__PURE__ */ jsxs2("section", { className: "flex min-h-0 min-w-0 flex-1 flex-col gap-3", children: [
789
879
  /* @__PURE__ */ jsxs2("div", { className: "flex h-8 min-w-0 items-center justify-between gap-3", children: [
790
880
  /* @__PURE__ */ jsx2(
791
881
  SectionTabs,
@@ -1024,6 +1114,35 @@ function AppCenterPanel({
1024
1114
  }
1025
1115
  }
1026
1116
  ),
1117
+ /* @__PURE__ */ jsx2(
1118
+ ConfirmationDialog,
1119
+ {
1120
+ cancelLabel: copy.t("actions.cancel"),
1121
+ confirmBusy: updateAppBusy,
1122
+ confirmLabel: copy.t("actions.updateApp"),
1123
+ description: copy.t("confirmations.updateRunningAppDescription"),
1124
+ open: pendingUpdateApp != null,
1125
+ title: updateAppConfirmTitle,
1126
+ onConfirm: () => {
1127
+ const app = pendingUpdateApp;
1128
+ if (!app) {
1129
+ return;
1130
+ }
1131
+ setUpdateAppBusy(true);
1132
+ void Promise.resolve(
1133
+ actions.updateApp?.(app.id, app.trigger)
1134
+ ).finally(() => {
1135
+ setUpdateAppBusy(false);
1136
+ setPendingUpdateApp(null);
1137
+ });
1138
+ },
1139
+ onOpenChange: (nextOpen) => {
1140
+ if (!nextOpen && !updateAppBusy) {
1141
+ setPendingUpdateApp(null);
1142
+ }
1143
+ }
1144
+ }
1145
+ ),
1027
1146
  /* @__PURE__ */ jsx2(
1028
1147
  Dialog,
1029
1148
  {
@@ -1471,7 +1590,7 @@ function AppCardGrid({
1471
1590
  "div",
1472
1591
  {
1473
1592
  "aria-label": title,
1474
- className: "flex min-h-[min(360px,45vh)] min-w-0 flex-1 items-center justify-center rounded-[8px] px-6 text-center text-[13px] leading-5 text-[var(--text-secondary)]",
1593
+ className: "flex min-h-0 min-w-0 flex-1 items-center justify-center rounded-[8px] px-6 text-center text-[13px] leading-5 text-[var(--text-secondary)]",
1475
1594
  role: "status",
1476
1595
  children: emptyMessage
1477
1596
  }
@@ -1524,7 +1643,7 @@ function RecommendedCategoryTabs({
1524
1643
  "div",
1525
1644
  {
1526
1645
  "aria-label": copy.t("labels.appCategories"),
1527
- className: "-mx-1 flex min-w-0 items-center gap-2 overflow-x-auto px-1 py-1",
1646
+ className: "-mx-1 flex min-h-10 min-w-0 items-center gap-2 overflow-x-auto px-1 py-1",
1528
1647
  role: "tablist",
1529
1648
  children: tabs.map((tab) => {
1530
1649
  const selected = tab.id === value;
@@ -1533,8 +1652,8 @@ function RecommendedCategoryTabs({
1533
1652
  {
1534
1653
  "aria-selected": selected,
1535
1654
  className: cn2(
1536
- "flex h-8 shrink-0 items-center rounded-[8px] px-3 text-[13px] font-semibold leading-5 tracking-[0] transition-colors duration-150 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--border-focus)]",
1537
- selected ? "border border-[color:var(--line-1)] bg-[var(--background-fronted)] text-[var(--text-primary)]" : "border border-transparent text-[var(--text-tertiary)] hover:text-[var(--text-primary)]"
1655
+ "flex h-8 shrink-0 items-center rounded-[8px] px-3 text-[13px] font-semibold leading-5 tracking-[0] transition-colors duration-150 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-[var(--border-focus)]",
1656
+ selected ? "bg-[var(--background-fronted)] text-[var(--text-primary)] shadow-[inset_0_0_0_1px_var(--line-1)]" : "text-[var(--text-tertiary)] hover:text-[var(--text-primary)]"
1538
1657
  ),
1539
1658
  role: "tab",
1540
1659
  type: "button",