react-os-shell 0.2.1 → 0.2.18

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.
Files changed (43) hide show
  1. package/dist/{Browser-IAQ5N3LL.js → Browser-EBBYHPBS.js} +3 -3
  2. package/dist/{Browser-IAQ5N3LL.js.map → Browser-EBBYHPBS.js.map} +1 -1
  3. package/dist/{Calculator-7MIONNJK.js → Calculator-CAKKD24W.js} +4 -4
  4. package/dist/{Calculator-7MIONNJK.js.map → Calculator-CAKKD24W.js.map} +1 -1
  5. package/dist/{Calendar-2R2DWXTG.js → Calendar-DHAUIE7N.js} +3 -3
  6. package/dist/{Calendar-2R2DWXTG.js.map → Calendar-DHAUIE7N.js.map} +1 -1
  7. package/dist/{CurrencyConverter-BMTB7FLA.js → CurrencyConverter-5LWH5WLH.js} +4 -4
  8. package/dist/{CurrencyConverter-BMTB7FLA.js.map → CurrencyConverter-5LWH5WLH.js.map} +1 -1
  9. package/dist/{Documents-CBNJAM3Q.js → Documents-LECUPQZ4.js} +3 -3
  10. package/dist/{Documents-CBNJAM3Q.js.map → Documents-LECUPQZ4.js.map} +1 -1
  11. package/dist/{Email-BS6MESSZ.js → Email-AJYKU4M7.js} +3 -3
  12. package/dist/{Email-BS6MESSZ.js.map → Email-AJYKU4M7.js.map} +1 -1
  13. package/dist/Files-RPYWW7CV.js +7 -0
  14. package/dist/{Files-U3BSTCC3.js.map → Files-RPYWW7CV.js.map} +1 -1
  15. package/dist/{Minesweeper-XOSH6BW2.js → Minesweeper-JKDGSZMW.js} +3 -3
  16. package/dist/{Minesweeper-XOSH6BW2.js.map → Minesweeper-JKDGSZMW.js.map} +1 -1
  17. package/dist/{Notepad-DMSBGGMS.js → Notepad-VL2E3ZAM.js} +3 -3
  18. package/dist/{Notepad-DMSBGGMS.js.map → Notepad-VL2E3ZAM.js.map} +1 -1
  19. package/dist/{PomodoroTimer-3XLLIDV3.js → PomodoroTimer-5WFFVIXI.js} +4 -4
  20. package/dist/{PomodoroTimer-3XLLIDV3.js.map → PomodoroTimer-5WFFVIXI.js.map} +1 -1
  21. package/dist/Preview-WE6TMZ2L.js +6 -0
  22. package/dist/{Preview-Y2LMO2DL.js.map → Preview-WE6TMZ2L.js.map} +1 -1
  23. package/dist/{Spreadsheet-IRPGCABR.js → Spreadsheet-COXQUNF6.js} +3 -3
  24. package/dist/{Spreadsheet-IRPGCABR.js.map → Spreadsheet-COXQUNF6.js.map} +1 -1
  25. package/dist/{Weather-5IW43PAQ.js → Weather-4ZPRC6CB.js} +4 -4
  26. package/dist/{Weather-5IW43PAQ.js.map → Weather-4ZPRC6CB.js.map} +1 -1
  27. package/dist/apps/index.js +16 -16
  28. package/dist/{chunk-DIJ46HNS.js → chunk-CXR7YLO7.js} +3 -3
  29. package/dist/{chunk-DIJ46HNS.js.map → chunk-CXR7YLO7.js.map} +1 -1
  30. package/dist/{chunk-JEJHECSO.js → chunk-HTNCG36G.js} +4 -4
  31. package/dist/{chunk-JEJHECSO.js.map → chunk-HTNCG36G.js.map} +1 -1
  32. package/dist/{chunk-7P6DO3NC.js → chunk-IDUZR4KY.js} +27 -12
  33. package/dist/chunk-IDUZR4KY.js.map +1 -0
  34. package/dist/{chunk-IQV6QQBQ.js → chunk-QF5IZXIA.js} +3 -3
  35. package/dist/{chunk-IQV6QQBQ.js.map → chunk-QF5IZXIA.js.map} +1 -1
  36. package/dist/index.d.ts +9 -2
  37. package/dist/index.js +206 -197
  38. package/dist/index.js.map +1 -1
  39. package/dist/styles.css +11 -0
  40. package/package.json +1 -1
  41. package/dist/Files-U3BSTCC3.js +0 -7
  42. package/dist/Preview-Y2LMO2DL.js +0 -6
  43. package/dist/chunk-7P6DO3NC.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -633,6 +633,11 @@ declare function useShellEntityFetcher(): EntityFetcher;
633
633
  * Outside calls (anything not hitting `/auth/me/`) need the consumer to mount
634
634
  * <ShellEntityFetcherProvider> and wire `entityFetcher` on <WindowManager>.
635
635
  *
636
+ * When `setShellApiClient` has not been called, HTTP methods resolve with an
637
+ * empty payload instead of throwing — so consumers without a backend (the
638
+ * Pages demo, for instance) can still mount the shell. A one-time console
639
+ * warning surfaces the missing wiring without crashing the app.
640
+ *
636
641
  * Long-term this file is removed when each call site migrates to
637
642
  * `useShellPrefs()` directly.
638
643
  */
@@ -659,8 +664,10 @@ declare function setShellAuthBridge(bridge: {
659
664
  declare function glassStyle(opacity?: number): CSSProperties;
660
665
  /** Glass divider border color */
661
666
  declare const GLASS_DIVIDER = "border-white/20";
662
- /** Glass input/search bar background */
663
- declare const GLASS_INPUT_BG = "bg-white/15";
667
+ /** Glass input/search bar background — declared in styles.css so it can adapt
668
+ * to dark mode (a flat `bg-white/15` reads as a too-bright tile on the dark
669
+ * glass gradient). */
670
+ declare const GLASS_INPUT_BG = "glass-input-bg";
664
671
 
665
672
  declare function reportBug(submit: BugReportConfig['submit']): Promise<void>;
666
673
 
package/dist/index.js CHANGED
@@ -5,11 +5,11 @@ import { useGoogleAuth } from './chunk-46LICZUM.js';
5
5
  import { useShellPrefs } from './chunk-36VM54SC.js';
6
6
  export { ShellPrefsProvider, useLocalStoragePrefs, useShellPrefs } from './chunk-36VM54SC.js';
7
7
  import { playNotification, playStartup, soundsEnabled, getSoundConfig, SOUND_PACK_KEYS, SOUND_PACKS, SOUND_TYPES, SOUND_TYPE_LABELS, playLogout, setSoundForType, previewSound, setAllSounds } from './chunk-D7PYW2QS.js';
8
- import { setPdfPreview } from './chunk-IQV6QQBQ.js';
8
+ import { setPdfPreview } from './chunk-QF5IZXIA.js';
9
9
  import { toast_default } from './chunk-WIJ45SYD.js';
10
10
  export { toast_default as toast } from './chunk-WIJ45SYD.js';
11
- import { useWindowManager, glassStyle, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, Modal, startMenuCategories, useIsMobile, navSections, isSection, GLASS_INPUT_BG, navIcons, sectionIcons, ModalActions, useModalActive, subscribeMobileMode, getMobileMode, setMobileMode, WINDOW_REGISTRY, isPageEntry, LoadingSpinner, ThumbCard, activateModal } from './chunk-7P6DO3NC.js';
12
- export { CancelButton, CopyButton, DocFavStar, GLASS_DIVIDER, GLASS_INPUT_BG, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, WindowManagerProvider, WindowTitle, glassStyle, isEntityEntry, isPageEntry, setShellApiClient, setShellNavIcons, setShellWindowRegistry, useModalActive, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-7P6DO3NC.js';
11
+ import { useWindowManager, glassStyle, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, Modal, startMenuCategories, useIsMobile, navSections, isSection, GLASS_INPUT_BG, navIcons, sectionIcons, ModalActions, useModalActive, subscribeMobileMode, getMobileMode, WINDOW_REGISTRY, isPageEntry, setMobileMode, LoadingSpinner, ThumbCard, activateModal } from './chunk-IDUZR4KY.js';
12
+ export { CancelButton, CopyButton, DocFavStar, GLASS_DIVIDER, GLASS_INPUT_BG, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, WindowManagerProvider, WindowTitle, glassStyle, isEntityEntry, isPageEntry, setShellApiClient, setShellNavIcons, setShellWindowRegistry, useModalActive, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-IDUZR4KY.js';
13
13
  export { ConfirmProvider, confirm, confirmDestructive, prompt } from './chunk-PLGHQ7QW.js';
14
14
  import { createContext, useState, useRef, useEffect, useCallback, useLayoutEffect, useContext, isValidElement, cloneElement, useSyncExternalStore, useMemo, Suspense } from 'react';
15
15
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -706,7 +706,7 @@ function StatusBadge({ status }) {
706
706
  }
707
707
 
708
708
  // src/version.ts
709
- var VERSION = "0.2.1" ;
709
+ var VERSION = "0.2.17" ;
710
710
  var APP_VERSION = VERSION;
711
711
 
712
712
  // src/changelog.ts
@@ -2794,6 +2794,28 @@ function StartMenu({
2794
2794
  var MOBILE_WIDGET_ORDER_KEY = "erp_mobile_widget_order";
2795
2795
  var MOBILE_HOME_ORDER_KEY = "erp_mobile_home_order";
2796
2796
  var LONG_PRESS_MS = 400;
2797
+ var ICON_GRADIENTS = [
2798
+ "from-blue-500 to-blue-700",
2799
+ "from-indigo-500 to-purple-600",
2800
+ "from-purple-500 to-pink-600",
2801
+ "from-pink-500 to-rose-600",
2802
+ "from-red-500 to-rose-600",
2803
+ "from-orange-500 to-red-600",
2804
+ "from-amber-500 to-orange-600",
2805
+ "from-yellow-500 to-amber-500",
2806
+ "from-lime-500 to-green-600",
2807
+ "from-green-500 to-emerald-600",
2808
+ "from-emerald-500 to-teal-600",
2809
+ "from-teal-500 to-cyan-600",
2810
+ "from-cyan-500 to-sky-600",
2811
+ "from-sky-500 to-blue-600",
2812
+ "from-violet-500 to-fuchsia-600"
2813
+ ];
2814
+ function hashGradient(seed) {
2815
+ let h = 0;
2816
+ for (let i = 0; i < seed.length; i++) h = (h << 5) - h + seed.charCodeAt(i);
2817
+ return ICON_GRADIENTS[Math.abs(h) % ICON_GRADIENTS.length];
2818
+ }
2797
2819
  function loadOrder(key) {
2798
2820
  try {
2799
2821
  const raw = localStorage.getItem(key);
@@ -2811,7 +2833,6 @@ function saveOrder(key, order) {
2811
2833
  } catch {
2812
2834
  }
2813
2835
  }
2814
- var FALLBACK_FOLDER_ICON = /* @__PURE__ */ jsx("svg", { className: "h-10 w-10", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3.75 9.776c.112-.017.227-.026.344-.026h15.812c.117 0 .232.009.344.026m-16.5 0a2.25 2.25 0 00-1.883 2.542l.857 6a2.25 2.25 0 002.227 1.932H19.05a2.25 2.25 0 002.227-1.932l.857-6a2.25 2.25 0 00-1.883-2.542m-16.5 0V6A2.25 2.25 0 016 3.75h3.879a1.5 1.5 0 011.06.44l2.122 2.12a1.5 1.5 0 001.06.44H18A2.25 2.25 0 0120.25 9v.776" }) });
2815
2836
  var FALLBACK_APP_ICON = /* @__PURE__ */ jsx("svg", { className: "h-10 w-10", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3.75 6.75A2.25 2.25 0 016 4.5h12a2.25 2.25 0 012.25 2.25v10.5A2.25 2.25 0 0118 19.5H6a2.25 2.25 0 01-2.25-2.25V6.75z" }) });
2816
2837
  function sizeIcon(node, fallback, sizeClass = "h-10 w-10") {
2817
2838
  if (!node) return fallback;
@@ -2822,6 +2843,23 @@ function sizeIcon(node, fallback, sizeClass = "h-10 w-10") {
2822
2843
  }
2823
2844
  return node;
2824
2845
  }
2846
+ function AppTile({ route, icon }) {
2847
+ return /* @__PURE__ */ jsx("span", { className: `relative aspect-square w-full rounded-2xl bg-gradient-to-br ${hashGradient(route)} flex items-center justify-center text-white shadow-sm border border-white/30`, children: sizeIcon(icon, FALLBACK_APP_ICON, "h-11 w-11") });
2848
+ }
2849
+ function FolderTile({ section, navIcons: navIcons2 }) {
2850
+ const previewItems = section.items.slice(0, 4);
2851
+ return /* @__PURE__ */ jsxs("span", { className: "relative aspect-square w-full rounded-2xl bg-white/30 backdrop-blur-sm border border-white/40 p-1.5 grid grid-cols-2 gap-1 shadow-sm", children: [
2852
+ previewItems.map((item) => /* @__PURE__ */ jsx(
2853
+ "span",
2854
+ {
2855
+ className: `rounded-md bg-gradient-to-br ${hashGradient(item.to)} flex items-center justify-center text-white`,
2856
+ children: sizeIcon(navIcons2[item.to], FALLBACK_APP_ICON, "h-3.5 w-3.5")
2857
+ },
2858
+ item.to
2859
+ )),
2860
+ Array.from({ length: Math.max(0, 4 - previewItems.length) }).map((_, i) => /* @__PURE__ */ jsx("span", { className: "rounded-md bg-white/20" }, `empty-${i}`))
2861
+ ] });
2862
+ }
2825
2863
  function MobileHome({
2826
2864
  navSections: navSections2,
2827
2865
  navIcons: navIcons2,
@@ -2943,7 +2981,7 @@ function MobileHome({
2943
2981
  if (icon.kind === "app") onOpenApp(icon.route);
2944
2982
  else setSelectedFolder(icon.section);
2945
2983
  };
2946
- const [widgetOrder, setWidgetOrder] = useState(() => loadOrder(MOBILE_WIDGET_ORDER_KEY));
2984
+ const [widgetOrder, _setWidgetOrder] = useState(() => loadOrder(MOBILE_WIDGET_ORDER_KEY));
2947
2985
  const widgetWindows = useMemo(() => {
2948
2986
  const widgets = openWindows.filter((w) => {
2949
2987
  if (!w.route) return false;
@@ -2963,23 +3001,11 @@ function MobileHome({
2963
3001
  ...visibleRoutes.filter((r) => !widgetOrder.includes(r))
2964
3002
  ];
2965
3003
  if (next.length !== widgetOrder.length || next.some((r, i) => r !== widgetOrder[i])) {
2966
- setWidgetOrder(next);
3004
+ _setWidgetOrder(next);
2967
3005
  saveOrder(MOBILE_WIDGET_ORDER_KEY, next);
2968
3006
  }
2969
3007
  }, [widgetWindows, widgetOrder]);
2970
- const moveWidget = (route, dir) => {
2971
- setWidgetOrder((prev) => {
2972
- const i = prev.indexOf(route);
2973
- if (i === -1) return prev;
2974
- const j = i + dir;
2975
- if (j < 0 || j >= prev.length) return prev;
2976
- const next = prev.slice();
2977
- [next[i], next[j]] = [next[j], next[i]];
2978
- saveOrder(MOBILE_WIDGET_ORDER_KEY, next);
2979
- return next;
2980
- });
2981
- };
2982
- const openCountByRoute = useMemo(() => {
3008
+ useMemo(() => {
2983
3009
  const map = /* @__PURE__ */ new Map();
2984
3010
  for (const w of openWindows) {
2985
3011
  if (!w.route) continue;
@@ -2987,85 +3013,56 @@ function MobileHome({
2987
3013
  }
2988
3014
  return map;
2989
3015
  }, [openWindows]);
2990
- const openInFolder = (folder) => {
2991
- const routes = new Set(folder.items.map((i) => i.to));
2992
- return openWindows.filter((w) => w.route && routes.has(w.route));
2993
- };
2994
3016
  const draggedIcon = dragId ? homeIcons.find((i) => i.id === dragId) : null;
2995
3017
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2996
- /* @__PURE__ */ jsxs("div", { className: "h-full overflow-y-auto px-3 pt-4 pb-4", children: [
2997
- widgetWindows.length > 0 && /* @__PURE__ */ jsx("section", { className: "mb-4", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: widgetWindows.map((w, i) => {
2998
- const entry = WINDOW_REGISTRY[w.route];
2999
- if (!entry) return null;
3000
- const Component = entry.component;
3001
- const isFirst = i === 0;
3002
- const isLast = i === widgetWindows.length - 1;
3003
- return /* @__PURE__ */ jsxs(
3004
- "div",
3005
- {
3006
- className: "relative rounded-2xl bg-white/85 backdrop-blur border border-white/40 shadow-md overflow-hidden aspect-square",
3007
- children: [
3008
- /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsx(LoadingSpinner, {}) }), children: /* @__PURE__ */ jsx(Component, {}) }),
3009
- widgetWindows.length > 1 && /* @__PURE__ */ jsxs("div", { className: "absolute top-1.5 right-1.5 flex flex-col gap-0.5 z-10", children: [
3010
- /* @__PURE__ */ jsx(
3011
- "button",
3012
- {
3013
- onClick: () => moveWidget(w.route, -1),
3014
- disabled: isFirst,
3015
- className: "h-6 w-6 rounded-md bg-white/90 backdrop-blur border border-gray-200 shadow-sm flex items-center justify-center text-gray-700 disabled:opacity-30 active:bg-gray-100",
3016
- "aria-label": "Move up",
3017
- children: /* @__PURE__ */ jsx("svg", { className: "h-3.5 w-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4.5 15.75l7.5-7.5 7.5 7.5" }) })
3018
- }
3019
- ),
3020
- /* @__PURE__ */ jsx(
3021
- "button",
3022
- {
3023
- onClick: () => moveWidget(w.route, 1),
3024
- disabled: isLast,
3025
- className: "h-6 w-6 rounded-md bg-white/90 backdrop-blur border border-gray-200 shadow-sm flex items-center justify-center text-gray-700 disabled:opacity-30 active:bg-gray-100",
3026
- "aria-label": "Move down",
3027
- children: /* @__PURE__ */ jsx("svg", { className: "h-3.5 w-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19.5 8.25l-7.5 7.5-7.5-7.5" }) })
3028
- }
3029
- )
3030
- ] })
3031
- ]
3032
- },
3033
- w.id
3034
- );
3035
- }) }) }),
3036
- homeIcons.length > 0 && /* @__PURE__ */ jsx("section", { children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-4 gap-3", children: homeIcons.map((icon) => {
3037
- const isFolder = icon.kind === "folder";
3038
- const openCount = isFolder ? openInFolder(icon.section).length : openCountByRoute.get(icon.route) ?? 0;
3039
- const isBeingDragged = dragId === icon.id;
3040
- return /* @__PURE__ */ jsxs(
3041
- "button",
3042
- {
3043
- "data-home-icon-id": icon.id,
3044
- onPointerDown: (e) => beginLongPress(icon.id, e),
3045
- onPointerUp: cancelLongPress,
3046
- onPointerCancel: cancelLongPress,
3047
- onPointerLeave: cancelLongPress,
3048
- onClick: () => handleIconClick(icon),
3049
- style: { touchAction: "none", visibility: isBeingDragged ? "hidden" : "visible" },
3050
- className: `flex flex-col items-center gap-1 py-1 rounded-lg active:bg-white/40 ${dragId && !isBeingDragged ? "transition-transform" : ""}`,
3051
- children: [
3052
- /* @__PURE__ */ jsxs(
3053
- "span",
3054
- {
3055
- className: `relative h-[72px] w-[72px] rounded-2xl flex items-center justify-center shadow-sm border ${isFolder ? "bg-white/70 backdrop-blur border-white/40 text-blue-700" : "bg-white/85 backdrop-blur border-white/40 text-gray-800"}`,
3056
- children: [
3057
- isFolder ? sizeIcon(sectionIcons2[icon.label], FALLBACK_FOLDER_ICON) : sizeIcon(navIcons2[icon.route], FALLBACK_APP_ICON),
3058
- openCount > 0 && (isFolder ? /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 min-w-[18px] h-[18px] px-1 rounded-full bg-blue-500 text-white text-[10px] font-bold leading-[18px] text-center border-2 border-white", children: openCount }) : /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 h-2 w-2 rounded-full bg-blue-500 border-2 border-white" }))
3059
- ]
3060
- }
3061
- ),
3062
- /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-white drop-shadow-sm truncate w-full text-center", children: icon.label })
3063
- ]
3064
- },
3065
- icon.id
3066
- );
3067
- }) }) })
3068
- ] }),
3018
+ /* @__PURE__ */ jsx(
3019
+ "div",
3020
+ {
3021
+ className: "h-full overflow-y-auto px-4 pt-4 pb-4 select-none",
3022
+ style: {
3023
+ // Disable iOS long-press text-selection / "Copy" callout on icon labels.
3024
+ WebkitUserSelect: "none",
3025
+ WebkitTouchCallout: "none"
3026
+ },
3027
+ children: /* @__PURE__ */ jsxs("div", { children: [
3028
+ widgetWindows.length > 0 && /* @__PURE__ */ jsx("section", { className: "mb-4", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-4 gap-4", children: widgetWindows.map((w) => {
3029
+ const entry = WINDOW_REGISTRY[w.route];
3030
+ if (!entry) return null;
3031
+ const Component = entry.component;
3032
+ return /* @__PURE__ */ jsx(
3033
+ "div",
3034
+ {
3035
+ className: "col-span-2 relative rounded-2xl bg-white/85 backdrop-blur border border-white/40 shadow-md overflow-hidden aspect-square",
3036
+ children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsx(LoadingSpinner, {}) }), children: /* @__PURE__ */ jsx(Component, {}) })
3037
+ },
3038
+ w.id
3039
+ );
3040
+ }) }) }),
3041
+ homeIcons.length > 0 && /* @__PURE__ */ jsx("section", { children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-4 gap-4", children: homeIcons.map((icon) => {
3042
+ const isFolder = icon.kind === "folder";
3043
+ const isBeingDragged = dragId === icon.id;
3044
+ return /* @__PURE__ */ jsxs(
3045
+ "button",
3046
+ {
3047
+ "data-home-icon-id": icon.id,
3048
+ onPointerDown: (e) => beginLongPress(icon.id, e),
3049
+ onPointerUp: cancelLongPress,
3050
+ onPointerCancel: cancelLongPress,
3051
+ onPointerLeave: cancelLongPress,
3052
+ onClick: () => handleIconClick(icon),
3053
+ style: { touchAction: "none", visibility: isBeingDragged ? "hidden" : "visible" },
3054
+ className: `flex flex-col items-center gap-1 py-1 rounded-lg active:bg-white/20 ${dragId && !isBeingDragged ? "transition-transform" : ""}`,
3055
+ children: [
3056
+ isFolder ? /* @__PURE__ */ jsx(FolderTile, { section: icon.section, navIcons: navIcons2 }) : /* @__PURE__ */ jsx(AppTile, { route: icon.route, icon: navIcons2[icon.route] }),
3057
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-white drop-shadow-sm truncate w-full text-center", children: icon.label })
3058
+ ]
3059
+ },
3060
+ icon.id
3061
+ );
3062
+ }) }) })
3063
+ ] })
3064
+ }
3065
+ ),
3069
3066
  draggedIcon && dragPos && /* @__PURE__ */ jsx(
3070
3067
  "div",
3071
3068
  {
@@ -3075,15 +3072,9 @@ function MobileHome({
3075
3072
  top: dragPos.y - dragOffsetRef.current.y,
3076
3073
  transform: "scale(1.12)"
3077
3074
  },
3078
- children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1 py-1", children: [
3079
- /* @__PURE__ */ jsx(
3080
- "span",
3081
- {
3082
- className: `relative h-[72px] w-[72px] rounded-2xl flex items-center justify-center shadow-2xl border ${draggedIcon.kind === "folder" ? "bg-white backdrop-blur border-white/40 text-blue-700" : "bg-white backdrop-blur border-white/40 text-gray-800"}`,
3083
- children: draggedIcon.kind === "folder" ? sizeIcon(sectionIcons2[draggedIcon.label], FALLBACK_FOLDER_ICON) : sizeIcon(navIcons2[draggedIcon.route], FALLBACK_APP_ICON)
3084
- }
3085
- ),
3086
- /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-white drop-shadow-md truncate max-w-[80px] text-center", children: draggedIcon.label })
3075
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1 py-1 w-20", children: [
3076
+ draggedIcon.kind === "folder" ? /* @__PURE__ */ jsx(FolderTile, { section: draggedIcon.section, navIcons: navIcons2 }) : /* @__PURE__ */ jsx(AppTile, { route: draggedIcon.route, icon: navIcons2[draggedIcon.route] }),
3077
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-white drop-shadow-md truncate w-full text-center", children: draggedIcon.label })
3087
3078
  ] })
3088
3079
  }
3089
3080
  ),
@@ -3092,16 +3083,10 @@ function MobileHome({
3092
3083
  {
3093
3084
  folder: selectedFolder,
3094
3085
  navIcons: navIcons2,
3095
- openInFolder: openInFolder(selectedFolder),
3096
- openCountByRoute,
3097
3086
  onClose: () => setSelectedFolder(null),
3098
3087
  onOpenApp: (path) => {
3099
3088
  setSelectedFolder(null);
3100
3089
  onOpenApp(path);
3101
- },
3102
- onActivateWindow: (id) => {
3103
- setSelectedFolder(null);
3104
- onActivateWindow(id);
3105
3090
  }
3106
3091
  }
3107
3092
  )
@@ -3110,67 +3095,70 @@ function MobileHome({
3110
3095
  function FolderPopup({
3111
3096
  folder,
3112
3097
  navIcons: navIcons2,
3113
- openInFolder,
3114
- openCountByRoute,
3115
3098
  onClose,
3116
- onOpenApp,
3117
- onActivateWindow
3099
+ onOpenApp
3118
3100
  }) {
3101
+ const [closing, setClosing] = useState(false);
3102
+ const beginClose = () => {
3103
+ if (closing) return;
3104
+ setClosing(true);
3105
+ setTimeout(onClose, 200);
3106
+ };
3107
+ const closeThen = (after) => {
3108
+ if (closing) return;
3109
+ setClosing(true);
3110
+ setTimeout(after, 200);
3111
+ };
3119
3112
  return /* @__PURE__ */ jsxs(
3120
3113
  "div",
3121
3114
  {
3122
- className: "fixed inset-0 z-[210] flex flex-col items-center justify-center px-6 bg-black/45 backdrop-blur-xl",
3123
- style: { paddingBottom: "calc(var(--mobile-bottom-nav, 56px) + 16px)" },
3124
- onClick: onClose,
3115
+ className: "fixed inset-0 z-[210] flex flex-col items-center justify-center px-6 bg-black/45 backdrop-blur-xl select-none",
3116
+ style: {
3117
+ paddingBottom: "calc(var(--mobile-bottom-nav, 70px) + 16px)",
3118
+ animation: closing ? "folder-fade-out 200ms ease-in forwards" : "folder-fade-in 220ms ease-out",
3119
+ WebkitUserSelect: "none",
3120
+ WebkitTouchCallout: "none"
3121
+ },
3122
+ onClick: beginClose,
3125
3123
  children: [
3126
- /* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold text-white drop-shadow-md mb-4 self-start", children: folder.label }),
3127
- /* @__PURE__ */ jsx(
3128
- "div",
3129
- {
3130
- className: "w-full max-w-md max-h-[70vh] flex flex-col rounded-3xl bg-white/15 backdrop-blur-xl border border-white/25 shadow-2xl overflow-hidden",
3131
- onClick: (e) => e.stopPropagation(),
3132
- children: /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-4 py-5", children: [
3133
- openInFolder.length > 0 && /* @__PURE__ */ jsxs("section", { className: "mb-4", children: [
3134
- /* @__PURE__ */ jsx("h3", { className: "text-[11px] font-semibold uppercase tracking-wide text-white/70 mb-2", children: "Open" }),
3135
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-2", children: openInFolder.map((w) => /* @__PURE__ */ jsxs(
3136
- "button",
3137
- {
3138
- onClick: () => onActivateWindow(w.id),
3139
- className: "flex items-center gap-2 p-2 rounded-lg bg-white/15 active:bg-white/25 text-left",
3140
- children: [
3141
- /* @__PURE__ */ jsx("span", { className: "h-7 w-7 rounded bg-white/20 flex items-center justify-center text-white shrink-0", children: sizeIcon(w.route ? navIcons2[w.route] : null, FALLBACK_APP_ICON, "h-5 w-5") }),
3142
- /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-white truncate flex-1", children: w.label })
3143
- ]
3144
- },
3145
- w.id
3146
- )) })
3147
- ] }),
3148
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-3", children: folder.items.map((item) => {
3149
- const openCount = openCountByRoute.get(item.to) ?? 0;
3124
+ /* @__PURE__ */ jsx("style", { children: `
3125
+ @keyframes folder-fade-in { from { opacity: 0; } to { opacity: 1; } }
3126
+ @keyframes folder-fade-out { from { opacity: 1; } to { opacity: 0; } }
3127
+ @keyframes folder-pop-in { from { opacity: 0; transform: scale(0.86) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } }
3128
+ @keyframes folder-pop-out { from { opacity: 1; transform: scale(1) translateY(0); } to { opacity: 0; transform: scale(0.9) translateY(4px); } }
3129
+ ` }),
3130
+ /* @__PURE__ */ jsxs("div", { className: "w-full max-w-[304px]", children: [
3131
+ /* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold text-white drop-shadow-md mb-4 ml-4", children: folder.label }),
3132
+ /* @__PURE__ */ jsx(
3133
+ "div",
3134
+ {
3135
+ className: "max-h-[70vh] flex flex-col rounded-3xl bg-white/15 backdrop-blur-xl border border-white/25 shadow-2xl overflow-hidden",
3136
+ style: {
3137
+ animation: closing ? "folder-pop-out 180ms ease-in forwards" : "folder-pop-in 240ms cubic-bezier(0.34, 1.56, 0.64, 1)"
3138
+ },
3139
+ onClick: (e) => e.stopPropagation(),
3140
+ children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto px-4 py-5", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-4", children: folder.items.map((item) => {
3150
3141
  return /* @__PURE__ */ jsxs(
3151
3142
  "button",
3152
3143
  {
3153
- onClick: () => onOpenApp(item.to),
3154
- className: "flex flex-col items-center gap-1.5 p-1 rounded-lg active:bg-white/15",
3144
+ onClick: () => closeThen(() => onOpenApp(item.to)),
3145
+ className: "flex flex-col items-center gap-1 py-1 rounded-lg active:bg-white/15",
3155
3146
  children: [
3156
- /* @__PURE__ */ jsxs("span", { className: "relative h-16 w-16 rounded-2xl bg-white/85 backdrop-blur border border-white/40 flex items-center justify-center text-gray-800 shadow-sm", children: [
3157
- sizeIcon(navIcons2[item.to], FALLBACK_APP_ICON),
3158
- openCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 h-2 w-2 rounded-full bg-blue-500 border-2 border-white" })
3159
- ] }),
3147
+ /* @__PURE__ */ jsx(AppTile, { route: item.to, icon: navIcons2[item.to] }),
3160
3148
  /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-white drop-shadow-sm truncate w-full text-center", children: item.label })
3161
3149
  ]
3162
3150
  },
3163
3151
  item.to
3164
3152
  );
3165
- }) })
3166
- ] })
3167
- }
3168
- )
3153
+ }) }) })
3154
+ }
3155
+ )
3156
+ ] })
3169
3157
  ]
3170
3158
  }
3171
3159
  );
3172
3160
  }
3173
- function MobileSwitcher({ windows, onActivate, onClose }) {
3161
+ function MobileSwitcher({ windows, onActivate, onClose, onCloseAll }) {
3174
3162
  const [cardSize, setCardSize] = useState(() => computeCardSize());
3175
3163
  useEffect(() => {
3176
3164
  const onResize = () => setCardSize(computeCardSize());
@@ -3189,26 +3177,36 @@ function MobileSwitcher({ windows, onActivate, onClose }) {
3189
3177
  /* @__PURE__ */ jsx("p", { className: "text-xs text-white/50", children: "Tap Home to launch one." })
3190
3178
  ] });
3191
3179
  }
3192
- return /* @__PURE__ */ jsxs("div", { className: "h-full overflow-y-auto px-3 pt-4 pb-4", children: [
3193
- /* @__PURE__ */ jsxs("h1", { className: "text-white text-base font-semibold mb-3 px-1", children: [
3194
- "Open apps \xB7 ",
3195
- windows.length
3180
+ return /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col", children: [
3181
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-3 pt-4 pb-4", children: [
3182
+ /* @__PURE__ */ jsxs("h1", { className: "text-white text-base font-semibold mb-3 px-1", children: [
3183
+ "Open apps \xB7 ",
3184
+ windows.length
3185
+ ] }),
3186
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: windows.map((w) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-stretch gap-1", children: [
3187
+ /* @__PURE__ */ jsx(
3188
+ ThumbCard,
3189
+ {
3190
+ id: w.id,
3191
+ label: w.label,
3192
+ maxW: cardSize.w,
3193
+ maxH: cardSize.h,
3194
+ titleAbove: true,
3195
+ onClick: () => onActivate(w.id),
3196
+ onClose: () => onClose(w.id)
3197
+ }
3198
+ ),
3199
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] text-white/80 truncate px-1", children: w.label })
3200
+ ] }, w.id)) })
3196
3201
  ] }),
3197
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: windows.map((w) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-stretch gap-1", children: [
3198
- /* @__PURE__ */ jsx(
3199
- ThumbCard,
3200
- {
3201
- id: w.id,
3202
- label: w.label,
3203
- maxW: cardSize.w,
3204
- maxH: cardSize.h,
3205
- titleAbove: true,
3206
- onClick: () => onActivate(w.id),
3207
- onClose: () => onClose(w.id)
3208
- }
3209
- ),
3210
- /* @__PURE__ */ jsx("span", { className: "text-[11px] text-white/80 truncate px-1", children: w.label })
3211
- ] }, w.id)) })
3202
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 px-3 py-3 flex justify-center", children: /* @__PURE__ */ jsx(
3203
+ "button",
3204
+ {
3205
+ onClick: onCloseAll,
3206
+ className: "px-5 py-2.5 rounded-full bg-white/15 backdrop-blur-md border border-white/25 text-white text-sm font-medium active:bg-white/25 shadow-lg",
3207
+ children: "Close All"
3208
+ }
3209
+ ) })
3212
3210
  ] });
3213
3211
  }
3214
3212
  function computeCardSize() {
@@ -3383,6 +3381,14 @@ function MobileShell({
3383
3381
  const mode = useSyncExternalStore(subscribeMobileMode, getMobileMode);
3384
3382
  const [sheet, setSheet] = useState(null);
3385
3383
  const unreadCount = notifications?.useUnreadCount() ?? 0;
3384
+ const switcherWindows = useMemo(() => {
3385
+ return openWindows.filter((w) => {
3386
+ if (!w.route) return true;
3387
+ const entry = WINDOW_REGISTRY[w.route];
3388
+ if (!entry || !isPageEntry(entry)) return true;
3389
+ return !entry.widget;
3390
+ });
3391
+ }, [openWindows]);
3386
3392
  const prevOpenCountRef = useRef(openWindows.length);
3387
3393
  useEffect(() => {
3388
3394
  if (openWindows.length < prevOpenCountRef.current && mode === "app") {
@@ -3429,9 +3435,10 @@ function MobileShell({
3429
3435
  mode === "switcher" && /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-[200] bg-gray-900/95 backdrop-blur-sm", style: { paddingBottom: "var(--mobile-bottom-nav, 70px)" }, children: /* @__PURE__ */ jsx(
3430
3436
  MobileSwitcher,
3431
3437
  {
3432
- windows: openWindows,
3438
+ windows: switcherWindows,
3433
3439
  onActivate: handleActivateWindow,
3434
- onClose: (id) => closeEntity(id)
3440
+ onClose: (id) => closeEntity(id),
3441
+ onCloseAll: () => switcherWindows.forEach((w) => closeEntity(w.id))
3435
3442
  }
3436
3443
  ) }),
3437
3444
  sheet === "notifications" && notifications && /* @__PURE__ */ jsx(MobileNotificationSheet, { config: notifications, onClose: closeSheet }),
@@ -3451,7 +3458,6 @@ function MobileShell({
3451
3458
  MobileBottomNav,
3452
3459
  {
3453
3460
  mode,
3454
- openCount: openWindows.length,
3455
3461
  unreadCount,
3456
3462
  showNotifications: !!notifications,
3457
3463
  profileAvatar: profile?.avatar_url,
@@ -3472,7 +3478,6 @@ function MobileShell({
3472
3478
  }
3473
3479
  function MobileBottomNav({
3474
3480
  mode,
3475
- openCount,
3476
3481
  unreadCount,
3477
3482
  showNotifications,
3478
3483
  profileAvatar,
@@ -3482,39 +3487,43 @@ function MobileBottomNav({
3482
3487
  onNotifications,
3483
3488
  onProfile
3484
3489
  }) {
3485
- const btnClass = (active) => `flex-1 flex flex-col items-center justify-center gap-0.5 py-2 transition-colors ${active ? "text-blue-600" : "text-gray-500 active:text-gray-700"}`;
3490
+ const btnClass = (active) => `flex-1 flex flex-col items-center justify-center gap-0.5 py-2 transition-colors select-none ${active ? "text-blue-600" : "text-gray-700 active:text-gray-900"}`;
3486
3491
  return /* @__PURE__ */ jsxs(
3487
3492
  "nav",
3488
3493
  {
3489
- className: "fixed bottom-0 inset-x-0 z-[300] flex items-stretch bg-white/95 backdrop-blur border-t border-gray-200",
3490
- style: { height: "var(--mobile-bottom-nav, 70px)", paddingBottom: "env(safe-area-inset-bottom)" },
3494
+ className: "fixed bottom-0 inset-x-0 z-[300] flex items-stretch border-t border-white/40",
3495
+ style: {
3496
+ height: "var(--mobile-bottom-nav, 70px)",
3497
+ paddingBottom: "env(safe-area-inset-bottom)",
3498
+ WebkitBackdropFilter: "blur(28px) saturate(1.8)",
3499
+ backdropFilter: "blur(28px) saturate(1.8)",
3500
+ background: "linear-gradient(135deg, rgba(255,255,255,0.65) 0%, rgba(255,255,255,0.45) 50%, rgba(255,255,255,0.55) 100%)",
3501
+ boxShadow: "inset 0 1px 0 rgba(255,255,255,0.6), 0 -2px 12px rgba(0,0,0,0.08)"
3502
+ },
3491
3503
  children: [
3492
3504
  /* @__PURE__ */ jsxs("button", { onClick: onHome, className: btnClass(mode === "home"), "aria-label": "Home", children: [
3493
- /* @__PURE__ */ jsx("svg", { className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.7, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" }) }),
3494
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium", children: "Home" })
3505
+ /* @__PURE__ */ jsx("svg", { className: "h-8 w-8", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.7, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" }) }),
3506
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium", children: "Home" })
3495
3507
  ] }),
3496
3508
  /* @__PURE__ */ jsxs("button", { onClick: onSwitcher, className: btnClass(mode === "switcher"), "aria-label": "App switcher", children: [
3497
- /* @__PURE__ */ jsxs("span", { className: "relative", children: [
3498
- /* @__PURE__ */ jsxs("svg", { className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.7, children: [
3499
- /* @__PURE__ */ jsx("rect", { x: "3.5", y: "3.5", width: "7", height: "7", rx: "1.25" }),
3500
- /* @__PURE__ */ jsx("rect", { x: "13.5", y: "3.5", width: "7", height: "7", rx: "1.25" }),
3501
- /* @__PURE__ */ jsx("rect", { x: "3.5", y: "13.5", width: "7", height: "7", rx: "1.25" }),
3502
- /* @__PURE__ */ jsx("rect", { x: "13.5", y: "13.5", width: "7", height: "7", rx: "1.25" })
3503
- ] }),
3504
- openCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-2 min-w-[16px] h-4 px-1 rounded-full bg-blue-500 text-white text-[10px] font-bold leading-4 text-center", children: openCount })
3509
+ /* @__PURE__ */ jsxs("svg", { className: "h-8 w-8", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.7, children: [
3510
+ /* @__PURE__ */ jsx("rect", { x: "3.5", y: "3.5", width: "7", height: "7", rx: "1.25" }),
3511
+ /* @__PURE__ */ jsx("rect", { x: "13.5", y: "3.5", width: "7", height: "7", rx: "1.25" }),
3512
+ /* @__PURE__ */ jsx("rect", { x: "3.5", y: "13.5", width: "7", height: "7", rx: "1.25" }),
3513
+ /* @__PURE__ */ jsx("rect", { x: "13.5", y: "13.5", width: "7", height: "7", rx: "1.25" })
3505
3514
  ] }),
3506
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium", children: "Apps" })
3515
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium", children: "Apps" })
3507
3516
  ] }),
3508
3517
  showNotifications && /* @__PURE__ */ jsxs("button", { onClick: onNotifications, className: btnClass(false), "aria-label": "Notifications", children: [
3509
3518
  /* @__PURE__ */ jsxs("span", { className: "relative", children: [
3510
- /* @__PURE__ */ jsx("svg", { className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.7, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" }) }),
3511
- unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-2 min-w-[16px] h-4 px-1 rounded-full bg-red-500 text-white text-[10px] font-bold leading-4 text-center", children: unreadCount > 99 ? "99+" : unreadCount })
3519
+ /* @__PURE__ */ jsx("svg", { className: "h-8 w-8", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.7, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" }) }),
3520
+ unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1.5 -right-2 min-w-[18px] h-[18px] px-1 rounded-full bg-red-500 text-white text-[10px] font-bold leading-[18px] text-center", children: unreadCount > 99 ? "99+" : unreadCount })
3512
3521
  ] }),
3513
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium", children: "Alerts" })
3522
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium", children: "Alerts" })
3514
3523
  ] }),
3515
3524
  /* @__PURE__ */ jsxs("button", { onClick: onProfile, className: btnClass(false), "aria-label": "Profile", children: [
3516
- profileAvatar ? /* @__PURE__ */ jsx("img", { src: profileAvatar, alt: "", className: "h-6 w-6 rounded-full object-cover border border-gray-200" }) : /* @__PURE__ */ jsx("div", { className: "h-6 w-6 rounded-full bg-blue-100 flex items-center justify-center text-[10px] font-bold text-blue-700", children: profileInitial }),
3517
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium", children: "Profile" })
3525
+ profileAvatar ? /* @__PURE__ */ jsx("img", { src: profileAvatar, alt: "", className: "h-8 w-8 rounded-full object-cover border border-gray-200" }) : /* @__PURE__ */ jsx("div", { className: "h-8 w-8 rounded-full bg-blue-100 flex items-center justify-center text-xs font-bold text-blue-700", children: profileInitial }),
3526
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium", children: "Profile" })
3518
3527
  ] })
3519
3528
  ]
3520
3529
  }
@@ -3855,7 +3864,7 @@ function Layout({
3855
3864
  root.style.setProperty("--window-tab-font-size", sv.tabFont);
3856
3865
  }, [inactiveHeaderOpacity, inactiveContentOpacity, activeHeaderOpacity, activeContentOpacity, taskbarH, taskbarPosition, prefs.default_window_size, prefs.window_position, prefs.menu_density, prefs.start_menu_size]);
3857
3866
  useEffect(() => {
3858
- document.documentElement.style.setProperty("--mobile-bottom-nav", isMobile ? "70px" : "0px");
3867
+ document.documentElement.style.setProperty("--mobile-bottom-nav", isMobile ? "100px" : "0px");
3859
3868
  }, [isMobile]);
3860
3869
  const [balloonDismissed, setBalloonDismissed] = useState(false);
3861
3870
  const [isFullscreen, setIsFullscreen] = useState(!!document.fullscreenElement);