@fayz-ai/ui 0.42.0 → 0.43.0

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 (37) hide show
  1. package/dist/{chunk-47B6ISJ6.js → chunk-3HGLZIQT.js} +140 -344
  2. package/dist/chunk-3HGLZIQT.js.map +1 -0
  3. package/dist/{chunk-W7CIJU5U.js → chunk-4BP33MTZ.js} +4 -4
  4. package/dist/{chunk-W7CIJU5U.js.map → chunk-4BP33MTZ.js.map} +1 -1
  5. package/dist/{chunk-UKMRHO5B.js → chunk-L6PNGGHM.js} +713 -244
  6. package/dist/chunk-L6PNGGHM.js.map +1 -0
  7. package/dist/{chunk-GG5XY6SF.js → chunk-ZMS7TNJD.js} +149 -196
  8. package/dist/chunk-ZMS7TNJD.js.map +1 -0
  9. package/dist/dashboard/index.js +3 -3
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +8 -8
  13. package/dist/layout/AppShell.d.ts +4 -1
  14. package/dist/layout/AppShell.d.ts.map +1 -1
  15. package/dist/layout/index.js +1 -1
  16. package/dist/primitives/bulk-action-bar.d.ts +3 -1
  17. package/dist/primitives/bulk-action-bar.d.ts.map +1 -1
  18. package/dist/primitives/data-table.d.ts +8 -1
  19. package/dist/primitives/data-table.d.ts.map +1 -1
  20. package/dist/primitives/dropdown.d.ts +2 -2
  21. package/dist/primitives/dropdown.d.ts.map +1 -1
  22. package/dist/primitives/index.d.ts +1 -1
  23. package/dist/primitives/index.d.ts.map +1 -1
  24. package/dist/primitives/index.js +3 -3
  25. package/dist/primitives/list-view.d.ts +3 -1
  26. package/dist/primitives/list-view.d.ts.map +1 -1
  27. package/dist/primitives/mobile-scrim.d.ts +29 -0
  28. package/dist/primitives/mobile-scrim.d.ts.map +1 -0
  29. package/dist/primitives/page-actions.d.ts +5 -14
  30. package/dist/primitives/page-actions.d.ts.map +1 -1
  31. package/dist/primitives/use-row-selection.d.ts +2 -0
  32. package/dist/primitives/use-row-selection.d.ts.map +1 -1
  33. package/dist/styles.css +55 -0
  34. package/package.json +2 -2
  35. package/dist/chunk-47B6ISJ6.js.map +0 -1
  36. package/dist/chunk-GG5XY6SF.js.map +0 -1
  37. package/dist/chunk-UKMRHO5B.js.map +0 -1
@@ -1,10 +1,11 @@
1
- import { cn, ConfirmDialog } from './chunk-FKYFYGAS.js';
1
+ import { cn, ConfirmDialog, Button } from './chunk-FKYFYGAS.js';
2
2
  import { ICON_MAP } from './chunk-ZTS5S6BZ.js';
3
- import * as React12 from 'react';
3
+ import * as React16 from 'react';
4
4
  import * as DialogPrimitive from '@radix-ui/react-dialog';
5
- import { X, Loader2, ChevronLeft, ArrowLeft, Bell, PanelLeft, PanelLeftClose, Search, CornerDownLeft, Menu, Crown, ChevronsRight, ChevronsLeft, ChevronDown, ChevronRight, Info, ExternalLink, CreditCard, Sparkles, Home, ChevronUp, Plus, Settings, UserCog, LogOut } from 'lucide-react';
5
+ import { X, ChevronRight, Check, Circle, Loader2, ChevronLeft, ArrowLeft, ChevronDown, MoreHorizontal, Bell, PanelLeft, PanelLeftClose, Search, CornerDownLeft, Menu, Crown, ChevronsRight, ChevronsLeft, Info, ExternalLink, CreditCard, Sparkles, Home, ChevronUp, Plus, Settings, SlidersHorizontal, MoreVertical, UserCog, LogOut } from 'lucide-react';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
  import { createPortal } from 'react-dom';
8
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
8
9
  import { useTranslation, useNavReferrer, routeModule, navHistoryBack, recordNavigation } from '@fayz-ai/core';
9
10
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
10
11
  import { create } from 'zustand';
@@ -28,11 +29,11 @@ var Modal = DialogPrimitive.Root;
28
29
  var ModalTrigger = DialogPrimitive.Trigger;
29
30
  var ModalClose = DialogPrimitive.Close;
30
31
  var ModalPortal = DialogPrimitive.Portal;
31
- var ModalHostContext = React12.createContext(null);
32
+ var ModalHostContext = React16.createContext(null);
32
33
  function useModalHost() {
33
- return React12.useContext(ModalHostContext);
34
+ return React16.useContext(ModalHostContext);
34
35
  }
35
- var ModalOverlay = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36
+ var ModalOverlay = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
36
37
  DialogPrimitive.Overlay,
37
38
  {
38
39
  ref,
@@ -45,9 +46,9 @@ var ModalOverlay = React12.forwardRef(({ className, ...props }, ref) => /* @__PU
45
46
  }
46
47
  ));
47
48
  ModalOverlay.displayName = "ModalOverlay";
48
- var ModalContent = React12.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => {
49
- const [host, setHost] = React12.useState(null);
50
- const attach = React12.useCallback((node) => {
49
+ var ModalContent = React16.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => {
50
+ const [host, setHost] = React16.useState(null);
51
+ const attach = React16.useCallback((node) => {
51
52
  setHost(node);
52
53
  if (typeof ref === "function") ref(node);
53
54
  else if (ref) ref.current = node;
@@ -132,13 +133,229 @@ function ModalFooter({ className, variant = "inline", start, children, ...props
132
133
  }
133
134
  return /* @__PURE__ */ jsx("div", { className: cn("mt-auto flex flex-col-reverse gap-2 pb-[env(safe-area-inset-bottom)] sm:mt-0 sm:flex-row sm:justify-end sm:gap-0 sm:space-x-2 sm:pb-0 shrink-0", className), ...props, children });
134
135
  }
135
- var ModalTitle = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
136
+ var ModalTitle = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
136
137
  ModalTitle.displayName = "ModalTitle";
137
- var ModalDescription = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
138
+ var ModalDescription = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
138
139
  ModalDescription.displayName = "ModalDescription";
140
+ function useScrim(open) {
141
+ const [mounted, setMounted] = React16.useState(open);
142
+ const [visible, setVisible] = React16.useState(open);
143
+ React16.useEffect(() => {
144
+ if (open) {
145
+ setMounted(true);
146
+ let frame = requestAnimationFrame(() => {
147
+ frame = requestAnimationFrame(() => setVisible(true));
148
+ });
149
+ return () => cancelAnimationFrame(frame);
150
+ }
151
+ setVisible(false);
152
+ const timer = window.setTimeout(() => setMounted(false), SCRIM_MS);
153
+ return () => window.clearTimeout(timer);
154
+ }, [open]);
155
+ return { mounted, visible };
156
+ }
157
+ var SCRIM_MS = 200;
158
+ function MobileScrim({ open, onClose, focus }) {
159
+ const scrim = useScrim(open);
160
+ const [box, setBox] = React16.useState(null);
161
+ React16.useEffect(() => {
162
+ if (open) setBox(focus ? focus.getBoundingClientRect() : null);
163
+ }, [open, focus]);
164
+ if (!scrim.mounted || typeof document === "undefined") return null;
165
+ const fade = cn("transition-opacity duration-200 motion-reduce:transition-none", scrim.visible ? "opacity-100" : "opacity-0");
166
+ return createPortal(
167
+ box ? /* @__PURE__ */ jsx("div", { "aria-hidden": true, onClick: onClose, className: cn("fixed inset-0 z-[100] overflow-hidden md:hidden", fade), children: /* @__PURE__ */ jsx(
168
+ "div",
169
+ {
170
+ className: cn(
171
+ "absolute rounded-xl ring-1 ring-foreground/10 transition-transform duration-200 ease-out motion-reduce:transition-none",
172
+ scrim.visible ? "scale-100" : "scale-[1.04]"
173
+ ),
174
+ style: {
175
+ left: box.left,
176
+ top: box.top,
177
+ width: box.width,
178
+ height: box.height,
179
+ boxShadow: "0 0 0 200vmax hsl(var(--foreground) / 0.4)"
180
+ }
181
+ }
182
+ ) }) : /* @__PURE__ */ jsx("div", { "aria-hidden": true, onClick: onClose, className: cn("fixed inset-0 z-[100] bg-foreground/40 md:hidden", fade) }),
183
+ document.body
184
+ );
185
+ }
186
+ function Dropdown({ open: openProp, defaultOpen, onOpenChange, ...props }) {
187
+ const [own, setOwn] = React16.useState(defaultOpen ?? false);
188
+ const open = openProp ?? own;
189
+ const change = (next) => {
190
+ setOwn(next);
191
+ onOpenChange?.(next);
192
+ };
193
+ const [trigger, setTrigger] = React16.useState(null);
194
+ const focus = open ? trigger?.closest("[data-scrim-focus]") ?? null : null;
195
+ return /* @__PURE__ */ jsxs(DropdownTriggerContext.Provider, { value: setTrigger, children: [
196
+ /* @__PURE__ */ jsx(MobileScrim, { open, onClose: () => change(false), focus }),
197
+ /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { open, onOpenChange: change, ...props })
198
+ ] });
199
+ }
200
+ var DropdownTriggerContext = React16.createContext(null);
201
+ var DropdownTrigger = React16.forwardRef((props, ref) => {
202
+ const register = React16.useContext(DropdownTriggerContext);
203
+ const setRef = React16.useCallback((el) => {
204
+ register?.(el);
205
+ if (typeof ref === "function") ref(el);
206
+ else if (ref) ref.current = el;
207
+ }, [register, ref]);
208
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Trigger, { ref: setRef, ...props });
209
+ });
210
+ DropdownTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName;
211
+ var DropdownGroup = DropdownMenuPrimitive.Group;
212
+ var DropdownPortal = DropdownMenuPrimitive.Portal;
213
+ var DropdownSub = DropdownMenuPrimitive.Sub;
214
+ var DropdownRadioGroup = DropdownMenuPrimitive.RadioGroup;
215
+ var DropdownSubTrigger = React16.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
216
+ DropdownMenuPrimitive.SubTrigger,
217
+ {
218
+ ref,
219
+ className: cn(
220
+ "flex cursor-default select-none items-center rounded-button px-2 py-1.5 text-sm outline-none focus:bg-muted data-[state=open]:bg-muted",
221
+ inset && "pl-8",
222
+ className
223
+ ),
224
+ ...props,
225
+ children: [
226
+ children,
227
+ /* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto h-4 w-4" })
228
+ ]
229
+ }
230
+ ));
231
+ DropdownSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
232
+ var DropdownSubContent = React16.forwardRef(({ className, ...props }, ref) => (
233
+ // Portaled, like DropdownContent. Without it the submenu renders inside the
234
+ // parent panel's DOM — and that panel is `overflow-hidden`, so the submenu
235
+ // was clipped to its box: a flyout you could open and never reach.
236
+ /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
237
+ DropdownMenuPrimitive.SubContent,
238
+ {
239
+ ref,
240
+ className: cn(
241
+ "fayz-glass-surface fz-menu-glass z-[110] min-w-[8rem] overflow-hidden rounded-card border bg-popover p-1 text-popover-foreground shadow-lg 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",
242
+ className
243
+ ),
244
+ ...props
245
+ }
246
+ ) })
247
+ ));
248
+ DropdownSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
249
+ var DropdownContent = React16.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
250
+ DropdownMenuPrimitive.Content,
251
+ {
252
+ ref,
253
+ sideOffset,
254
+ className: cn(
255
+ "fayz-glass-surface fz-menu-glass z-[110] min-w-[8rem] overflow-hidden rounded-card border bg-popover p-1 text-popover-foreground shadow-md 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",
256
+ className
257
+ ),
258
+ ...props
259
+ }
260
+ ) }));
261
+ DropdownContent.displayName = DropdownMenuPrimitive.Content.displayName;
262
+ var DropdownItem = React16.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
263
+ DropdownMenuPrimitive.Item,
264
+ {
265
+ ref,
266
+ className: cn(
267
+ "relative flex cursor-default select-none items-center rounded-button px-2 py-1.5 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
268
+ inset && "pl-8",
269
+ className
270
+ ),
271
+ ...props
272
+ }
273
+ ));
274
+ DropdownItem.displayName = DropdownMenuPrimitive.Item.displayName;
275
+ var DropdownCheckboxItem = React16.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
276
+ DropdownMenuPrimitive.CheckboxItem,
277
+ {
278
+ ref,
279
+ className: cn(
280
+ "relative flex cursor-default select-none items-center rounded-button py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
281
+ className
282
+ ),
283
+ checked,
284
+ ...props,
285
+ children: [
286
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
287
+ children
288
+ ]
289
+ }
290
+ ));
291
+ DropdownCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
292
+ var DropdownRadioItem = React16.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
293
+ DropdownMenuPrimitive.RadioItem,
294
+ {
295
+ ref,
296
+ className: cn(
297
+ "relative flex cursor-default select-none items-center rounded-button py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
298
+ className
299
+ ),
300
+ ...props,
301
+ children: [
302
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Circle, { className: "h-2 w-2 fill-current" }) }) }),
303
+ children
304
+ ]
305
+ }
306
+ ));
307
+ DropdownRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
308
+ var DropdownLabel = React16.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
309
+ DropdownMenuPrimitive.Label,
310
+ {
311
+ ref,
312
+ className: cn(
313
+ "px-2 py-1.5 text-sm font-semibold",
314
+ inset && "pl-8",
315
+ className
316
+ ),
317
+ ...props
318
+ }
319
+ ));
320
+ DropdownLabel.displayName = DropdownMenuPrimitive.Label.displayName;
321
+ var DropdownSeparator = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
322
+ DropdownMenuPrimitive.Separator,
323
+ {
324
+ ref,
325
+ className: cn("-mx-1 my-1 h-px bg-muted", className),
326
+ ...props
327
+ }
328
+ ));
329
+ DropdownSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
330
+ var DropdownShortcut = ({
331
+ className,
332
+ ...props
333
+ }) => {
334
+ return /* @__PURE__ */ jsx(
335
+ "span",
336
+ {
337
+ className: cn("ml-auto text-xs tracking-widest opacity-60", className),
338
+ ...props
339
+ }
340
+ );
341
+ };
342
+ DropdownShortcut.displayName = "DropdownShortcut";
343
+ var WIDE_QUERY = "(min-width: 768px)";
344
+ function useIsWide(query = WIDE_QUERY) {
345
+ const [wide, setWide] = React16.useState(
346
+ () => typeof window === "undefined" ? true : window.matchMedia(query).matches
347
+ );
348
+ React16.useEffect(() => {
349
+ const mq = window.matchMedia(query);
350
+ const onChange = () => setWide(mq.matches);
351
+ mq.addEventListener("change", onChange);
352
+ return () => mq.removeEventListener("change", onChange);
353
+ }, [query]);
354
+ return wide;
355
+ }
139
356
  var HIDDEN = { visible: false, saving: false };
140
- var SaveBarApiContext = React12.createContext(null);
141
- var SaveBarStateContext = React12.createContext({ visible: false, saving: false });
357
+ var SaveBarApiContext = React16.createContext(null);
358
+ var SaveBarStateContext = React16.createContext({ visible: false, saving: false });
142
359
  var _saveBarVisible = false;
143
360
  var saveFlow = { current: null };
144
361
  var requestSave = (onSave) => {
@@ -157,7 +374,7 @@ function setSaveBarVisibleSignal(v) {
157
374
  _saveBarSubs.forEach((fn) => fn());
158
375
  }
159
376
  function useSaveBarVisible() {
160
- return React12.useSyncExternalStore(
377
+ return React16.useSyncExternalStore(
161
378
  (cb) => {
162
379
  _saveBarSubs.add(cb);
163
380
  return () => {
@@ -169,10 +386,10 @@ function useSaveBarVisible() {
169
386
  );
170
387
  }
171
388
  function SaveBarProvider({ children }) {
172
- const [state, setState] = React12.useState({ visible: false, saving: false });
173
- const handlers = React12.useRef({});
174
- const entries = React12.useRef([]);
175
- const api = React12.useMemo(() => ({
389
+ const [state, setState] = React16.useState({ visible: false, saving: false });
390
+ const handlers = React16.useRef({});
391
+ const entries = React16.useRef([]);
392
+ const api = React16.useMemo(() => ({
176
393
  setState,
177
394
  handlers,
178
395
  entries,
@@ -182,16 +399,16 @@ function SaveBarProvider({ children }) {
182
399
  setState(top ? top.state : HIDDEN);
183
400
  }
184
401
  }), []);
185
- const backStack = React12.useRef([]);
186
- const backApi = React12.useMemo(() => ({ stack: backStack }), []);
187
- React12.useEffect(() => {
402
+ const backStack = React16.useRef([]);
403
+ const backApi = React16.useMemo(() => ({ stack: backStack }), []);
404
+ React16.useEffect(() => {
188
405
  setSaveBarVisibleSignal(state.visible);
189
406
  }, [state.visible]);
190
- const [leaveTo, setLeaveTo] = React12.useState(null);
191
- const bypass = React12.useRef(false);
407
+ const [leaveTo, setLeaveTo] = React16.useState(null);
408
+ const bypass = React16.useRef(false);
192
409
  if (state.saving && saveFlow.current) saveFlow.current.started = true;
193
410
  const t = useTranslation();
194
- React12.useEffect(() => {
411
+ React16.useEffect(() => {
195
412
  if (!state.dirty || state.host || typeof window === "undefined") return;
196
413
  const guarded = window.location.href;
197
414
  const onNav = (e) => {
@@ -226,7 +443,7 @@ function SaveBarProvider({ children }) {
226
443
  bypass.current = false;
227
444
  }, 0);
228
445
  };
229
- React12.useEffect(() => {
446
+ React16.useEffect(() => {
230
447
  function onKey(e) {
231
448
  if (state.visible && !state.saving) {
232
449
  if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
@@ -269,7 +486,7 @@ function SaveBarProvider({ children }) {
269
486
  )
270
487
  ] }) }) });
271
488
  }
272
- var BackNavApiContext = React12.createContext(null);
489
+ var BackNavApiContext = React16.createContext(null);
273
490
  function isEditableTarget(target) {
274
491
  const el = target;
275
492
  if (!el || !el.tagName) return false;
@@ -277,12 +494,12 @@ function isEditableTarget(target) {
277
494
  return tag === "input" || tag === "textarea" || tag === "select" || el.isContentEditable;
278
495
  }
279
496
  function useBackHandler(onBack) {
280
- const api = React12.useContext(BackNavApiContext);
281
- const ref = React12.useRef(onBack);
282
- React12.useEffect(() => {
497
+ const api = React16.useContext(BackNavApiContext);
498
+ const ref = React16.useRef(onBack);
499
+ React16.useEffect(() => {
283
500
  ref.current = onBack;
284
501
  });
285
- React12.useEffect(() => {
502
+ React16.useEffect(() => {
286
503
  if (!api) return;
287
504
  const stack = api.stack.current;
288
505
  stack.push(ref);
@@ -293,16 +510,16 @@ function useBackHandler(onBack) {
293
510
  }, [api]);
294
511
  }
295
512
  function useSaveBar({ dirty, alwaysVisible, saving = false, onSave, onDiscard, message, saveLabel, discardLabel }) {
296
- const api = React12.useContext(SaveBarApiContext);
513
+ const api = React16.useContext(SaveBarApiContext);
297
514
  const host = useModalHost();
298
- const entry = React12.useRef({ state: HIDDEN, handlers: {} });
299
- React12.useEffect(() => {
515
+ const entry = React16.useRef({ state: HIDDEN, handlers: {} });
516
+ React16.useEffect(() => {
300
517
  entry.current.handlers = { onSave, onDiscard };
301
518
  if (api && api.entries.current[api.entries.current.length - 1] === entry.current) {
302
519
  api.handlers.current = entry.current.handlers;
303
520
  }
304
521
  });
305
- React12.useEffect(() => {
522
+ React16.useEffect(() => {
306
523
  if (!api) return;
307
524
  const list = api.entries.current;
308
525
  list.push(entry.current);
@@ -313,19 +530,19 @@ function useSaveBar({ dirty, alwaysVisible, saving = false, onSave, onDiscard, m
313
530
  api.sync();
314
531
  };
315
532
  }, [api]);
316
- React12.useEffect(() => {
533
+ React16.useEffect(() => {
317
534
  if (!api) return;
318
535
  entry.current.state = { visible: dirty || !!alwaysVisible, dirty, saving, message, saveLabel, discardLabel, host };
319
536
  if (api.entries.current[api.entries.current.length - 1] === entry.current) api.sync();
320
537
  }, [api, dirty, alwaysVisible, saving, message, saveLabel, discardLabel, host]);
321
538
  }
322
539
  function SaveBar({ className }) {
323
- const state = React12.useContext(SaveBarStateContext);
324
- const api = React12.useContext(SaveBarApiContext);
540
+ const state = React16.useContext(SaveBarStateContext);
541
+ const api = React16.useContext(SaveBarApiContext);
325
542
  const t = useTranslation();
326
- const [rendered, setRendered] = React12.useState(state.visible);
327
- const [closing, setClosing] = React12.useState(false);
328
- React12.useEffect(() => {
543
+ const [rendered, setRendered] = React16.useState(state.visible);
544
+ const [closing, setClosing] = React16.useState(false);
545
+ React16.useEffect(() => {
329
546
  if (state.visible) {
330
547
  setRendered(true);
331
548
  setClosing(false);
@@ -391,7 +608,7 @@ function SaveBar({ className }) {
391
608
  var TooltipProvider = TooltipPrimitive.Provider;
392
609
  var Tooltip = TooltipPrimitive.Root;
393
610
  var TooltipTrigger = TooltipPrimitive.Trigger;
394
- var TooltipContent = React12.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (
611
+ var TooltipContent = React16.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (
395
612
  // Portaled: inside a scroll box (a table, a modal body) the tip was clipped by its container.
396
613
  /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
397
614
  TooltipPrimitive.Content,
@@ -436,7 +653,7 @@ var usePageHeaderStore = create((set, get) => ({
436
653
  function useRegisterPageActions() {
437
654
  const add = usePageHeaderStore((s) => s.addActions);
438
655
  const remove = usePageHeaderStore((s) => s.removeActions);
439
- React12.useEffect(() => {
656
+ React16.useEffect(() => {
440
657
  add();
441
658
  return remove;
442
659
  }, [add, remove]);
@@ -459,7 +676,7 @@ function usePageTitleSlotHost() {
459
676
  function usePageHeaderHost() {
460
677
  const addHost = usePageHeaderStore((s) => s.addHost);
461
678
  const removeHost = usePageHeaderStore((s) => s.removeHost);
462
- React12.useEffect(() => {
679
+ React16.useEffect(() => {
463
680
  addHost();
464
681
  return removeHost;
465
682
  }, [addHost, removeHost]);
@@ -477,30 +694,30 @@ function PageHeaderOutlet({ className, active = true }) {
477
694
  const hasActions = usePageHeaderStore((s) => s.actions > 0);
478
695
  const addOutlet = usePageHeaderStore((s) => s.addOutlet);
479
696
  const removeOutlet = usePageHeaderStore((s) => s.removeOutlet);
480
- React12.useEffect(() => {
697
+ React16.useEffect(() => {
481
698
  if (!active) return;
482
699
  addOutlet();
483
700
  return removeOutlet;
484
701
  }, [active, addOutlet, removeOutlet]);
485
- React12.useEffect(() => {
702
+ React16.useEffect(() => {
486
703
  if (active) return;
487
704
  setOutletSlot(null);
488
705
  setOutletActionsSlot(null);
489
706
  }, [active, setOutletSlot, setOutletActionsSlot]);
490
707
  if (!active) return null;
491
- return React12.createElement(
708
+ return React16.createElement(
492
709
  "div",
493
710
  { className: `flex min-h-9 items-center justify-between gap-3${claimed || hasActions ? "" : " hidden"} ${className ?? "mb-3"}` },
494
- React12.createElement("div", { ref: setOutletSlot, className: "flex min-w-0 flex-1 items-center" }),
495
- React12.createElement("div", { ref: setOutletActionsSlot, className: "flex shrink-0 items-center gap-2" })
711
+ React16.createElement("div", { ref: setOutletSlot, className: "flex min-w-0 flex-1 items-center" }),
712
+ React16.createElement("div", { ref: setOutletActionsSlot, className: "flex shrink-0 items-center gap-2" })
496
713
  );
497
714
  }
498
715
  function usePageHeader(active, options) {
499
- const id = React12.useId();
716
+ const id = React16.useId();
500
717
  const claim = usePageHeaderStore((s) => s.claim);
501
718
  const release = usePageHeaderStore((s) => s.release);
502
719
  const back = options?.back ?? false;
503
- React12.useEffect(() => {
720
+ React16.useEffect(() => {
504
721
  if (!active) {
505
722
  release(id);
506
723
  return;
@@ -517,18 +734,18 @@ function useModuleViewLabel() {
517
734
  }
518
735
  function usePublishModuleViewLabel(label) {
519
736
  const setLabel = usePageHeaderStore((s) => s.setModuleViewLabel);
520
- React12.useEffect(() => {
737
+ React16.useEffect(() => {
521
738
  setLabel(label ?? null);
522
739
  return () => setLabel(null);
523
740
  }, [label, setLabel]);
524
741
  }
525
742
  function PageTitlePortal({ children }) {
526
743
  const slot = usePageTitleSlot();
527
- if (!slot) return React12.createElement(React12.Fragment, null, children);
744
+ if (!slot) return React16.createElement(React16.Fragment, null, children);
528
745
  return createPortal(children, slot);
529
746
  }
530
- var Hint = React12.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
531
- if (!label) return React12.cloneElement(children, { ...rest, ref });
747
+ var Hint = React16.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
748
+ if (!label) return React16.cloneElement(children, { ...rest, ref });
532
749
  return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
533
750
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, ...rest, ref, children }),
534
751
  /* @__PURE__ */ jsx(TooltipContent, { side, className: "px-2 py-1 text-xs font-medium", children: label })
@@ -617,7 +834,7 @@ function PageHeader({ title, onBack, parentLabel, backLabel }) {
617
834
  const hasHost = useHasPageHeaderHost();
618
835
  const { onBack: effectiveOnBack, parentLabel: effectiveParent } = useCrossModuleBack(onBack, parentLabel);
619
836
  useBackHandler(effectiveOnBack);
620
- const node = React12.useMemo(() => /* @__PURE__ */ jsx(
837
+ const node = React16.useMemo(() => /* @__PURE__ */ jsx(
621
838
  PageHeaderCrumb,
622
839
  {
623
840
  title,
@@ -629,17 +846,198 @@ function PageHeader({ title, onBack, parentLabel, backLabel }) {
629
846
  if (hasHost) return /* @__PURE__ */ jsx(PageTitlePortal, { children: node });
630
847
  return /* @__PURE__ */ jsx("div", { className: "mb-4", children: node });
631
848
  }
849
+ function iconOf(action, className) {
850
+ const Icon = action.icon;
851
+ return Icon ? /* @__PURE__ */ jsx(Icon, { className }) : null;
852
+ }
853
+ function PageActionBar({ actions, className }) {
854
+ const wide = useIsWide();
855
+ const visible = actions.filter((a) => !a.hidden);
856
+ if (visible.length === 0) return null;
857
+ if (!wide) {
858
+ const usable = visible.filter((a) => !a.desktopOnly);
859
+ if (usable.length === 0) return null;
860
+ const fab = /* @__PURE__ */ jsx(PageActionFab, { actions: usable });
861
+ const fabHost = typeof document !== "undefined" ? document.querySelector(".shell-enter") ?? document.body : null;
862
+ return fabHost ? createPortal(fab, fabHost) : fab;
863
+ }
864
+ let seenPrimary = false;
865
+ const primary = [];
866
+ const secondary = [];
867
+ const utility = [];
868
+ const danger = [];
869
+ for (const a of visible) {
870
+ const intent = a.intent ?? "secondary";
871
+ if (intent === "primary" && !seenPrimary) {
872
+ seenPrimary = true;
873
+ primary.push(a);
874
+ continue;
875
+ }
876
+ if (intent === "danger") {
877
+ danger.push(a);
878
+ continue;
879
+ }
880
+ if (intent === "utility") {
881
+ utility.push(a);
882
+ continue;
883
+ }
884
+ secondary.push(a);
885
+ }
886
+ const head = primary[0];
887
+ const menu = [...secondary, ...danger];
888
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 items-center gap-2", className), children: [
889
+ utility.map((a) => (
890
+ // Um botão só de ícone não diz o que faz. `title=` parecia resolver e
891
+ // não resolve: espera ~1s que ninguém controla, sai na pintura do
892
+ // sistema operacional, nunca aparece no toque e vários leitores de tela
893
+ // pulam. Hint é o tooltip do design system, e o texto é ANUNCIADO.
894
+ /* @__PURE__ */ jsx(Hint, { label: a.label, children: /* @__PURE__ */ jsx(
895
+ Button,
896
+ {
897
+ variant: "ghost",
898
+ size: "icon",
899
+ onClick: () => void a.onSelect(),
900
+ disabled: a.disabled,
901
+ "aria-label": a.label,
902
+ "data-testid": a.testId,
903
+ "data-tour": `action.${a.id}`,
904
+ children: iconOf(a, "h-4 w-4")
905
+ }
906
+ ) }, a.id)
907
+ )),
908
+ head && menu.length === 0 && /* @__PURE__ */ jsxs(Button, { className: head.ai ? "fz-ai-button" : void 0, onClick: () => void head.onSelect(), disabled: head.disabled, "data-testid": head.testId, "data-tour": `action.${head.id}`, children: [
909
+ iconOf(head, "mr-1.5 h-4 w-4"),
910
+ head.label
911
+ ] }),
912
+ head && menu.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
913
+ /* @__PURE__ */ jsxs(Button, { className: "rounded-r-none", onClick: () => void head.onSelect(), disabled: head.disabled, "data-testid": head.testId, "data-tour": `action.${head.id}`, children: [
914
+ iconOf(head, "mr-1.5 h-4 w-4"),
915
+ head.label
916
+ ] }),
917
+ /* @__PURE__ */ jsxs(Dropdown, { children: [
918
+ /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Hint, { label: `${head.label}\u2026`, children: /* @__PURE__ */ jsx(
919
+ Button,
920
+ {
921
+ className: "-ml-px rounded-l-none px-2",
922
+ "aria-label": `${head.label}\u2026`,
923
+ "data-tour": menu.map((a) => `action.${a.id}`).join(" "),
924
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
925
+ }
926
+ ) }) }),
927
+ /* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
928
+ ] })
929
+ ] }),
930
+ !head && menu.length > 0 && /* @__PURE__ */ jsxs(Dropdown, { children: [
931
+ /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Hint, { label: "A\xE7\xF5es", children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "icon", "aria-label": "A\xE7\xF5es", children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" }) }) }) }),
932
+ /* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
933
+ ] })
934
+ ] });
935
+ }
936
+ function ActionItems({ actions, stagger }) {
937
+ const out = [];
938
+ actions.forEach((a, i) => {
939
+ const isDanger = a.intent === "danger";
940
+ const prevSafe = i > 0 && actions[i - 1].intent !== "danger";
941
+ if (isDanger && prevSafe) out.push(/* @__PURE__ */ jsx(DropdownSeparator, {}, `${a.id}-sep`));
942
+ out.push(
943
+ /* @__PURE__ */ jsxs(
944
+ DropdownItem,
945
+ {
946
+ disabled: a.disabled,
947
+ onSelect: () => void a.onSelect(),
948
+ "data-testid": a.testId,
949
+ style: stagger ? { ["--i"]: i } : void 0,
950
+ className: cn("gap-2", stagger && "fz-fab-item min-h-12 gap-3 px-3 text-[15px]", isDanger && "text-destructive focus:text-destructive", a.ai && "fz-ai-action"),
951
+ children: [
952
+ iconOf(a, "h-4 w-4 shrink-0"),
953
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
954
+ /* @__PURE__ */ jsx("span", { className: "block truncate", children: a.label }),
955
+ a.description && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-muted-foreground", children: a.description })
956
+ ] })
957
+ ]
958
+ },
959
+ a.id
960
+ )
961
+ );
962
+ });
963
+ return /* @__PURE__ */ jsx(Fragment, { children: out });
964
+ }
965
+ function PageActionFab({ actions }) {
966
+ const byIntent = (i) => actions.filter((a) => (a.intent ?? "secondary") === i);
967
+ const utility = byIntent("utility");
968
+ const main = [...byIntent("primary"), ...byIntent("secondary"), ...byIntent("danger")];
969
+ if (main.length === 0) return /* @__PURE__ */ jsx(FabButton, { actions: utility, tone: "neutral" });
970
+ const isCreate = main.every((a) => a.creates ?? a.icon === Plus);
971
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
972
+ utility.length > 0 && /* @__PURE__ */ jsx(FabButton, { actions: utility, tone: "neutral", mini: true }),
973
+ /* @__PURE__ */ jsx(FabButton, { actions: main, tone: isCreate ? "primary" : "neutral" })
974
+ ] });
975
+ }
976
+ function FabButton({ actions, tone, mini }) {
977
+ const [open, setOpen] = React16.useState(false);
978
+ if (actions.length === 0) return null;
979
+ const isCreate = tone === "primary";
980
+ const FabIcon = isCreate ? Plus : MoreVertical;
981
+ const style = {
982
+ bottom: mini ? "calc(var(--fz-bottom-bar, 0px) + 4.75rem)" : "calc(var(--fz-bottom-bar, 0px) + 1rem)"
983
+ };
984
+ const shell = cn(
985
+ "fz-tap fixed z-40 flex items-center justify-center rounded-full",
986
+ "transition-transform active:scale-95 md:hidden",
987
+ // Centred on the main circle's column, so the two read as one stack.
988
+ mini ? "right-5 h-12 w-12" : "right-4 h-14 w-14",
989
+ // Glass, like the bars it floats between: a tinted fill over a heavy blur,
990
+ // lit on the top edge. The blur is what keeps the glyph legible over
991
+ // whatever scrolls beneath — the fill alone would not.
992
+ "backdrop-blur-xl backdrop-saturate-150",
993
+ isCreate ? "bg-primary/75 text-primary-foreground ring-1 ring-white/25 shadow-[inset_0_1px_0_rgb(255_255_255/0.35),0_10px_24px_-8px_hsl(var(--primary)/0.5)]" : "bg-card/60 text-foreground ring-1 ring-border/60 shadow-[inset_0_1px_0_rgb(255_255_255/0.5),0_10px_24px_-10px_rgb(0_0_0/0.35)]"
994
+ );
995
+ if (actions.length === 1) {
996
+ const only = actions[0];
997
+ const Icon = only.icon ?? FabIcon;
998
+ return /* @__PURE__ */ jsx(
999
+ "button",
1000
+ {
1001
+ type: "button",
1002
+ style,
1003
+ className: shell,
1004
+ onClick: () => void only.onSelect(),
1005
+ disabled: only.disabled,
1006
+ "aria-label": only.label,
1007
+ "data-testid": only.testId,
1008
+ children: /* @__PURE__ */ jsx(Icon, { className: mini ? "h-5 w-5" : "h-6 w-6" })
1009
+ }
1010
+ );
1011
+ }
1012
+ return /* @__PURE__ */ jsxs(Dropdown, { open, onOpenChange: setOpen, children: [
1013
+ /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1014
+ "button",
1015
+ {
1016
+ type: "button",
1017
+ style,
1018
+ className: cn(shell, open && "z-[105]", isCreate && "fz-fab-trigger"),
1019
+ "aria-label": actionsMenuLabel,
1020
+ children: /* @__PURE__ */ jsx(FabIcon, { className: mini ? "h-5 w-5" : "h-6 w-6" })
1021
+ }
1022
+ ) }),
1023
+ /* @__PURE__ */ jsx(DropdownContent, { side: "top", align: "end", sideOffset: 12, className: "fz-fab-menu w-72 p-1.5 md:hidden", children: /* @__PURE__ */ jsx(ActionItems, { actions, stagger: true }) })
1024
+ ] });
1025
+ }
1026
+ var actionsMenuLabel = "A\xE7\xF5es";
1027
+ function setActionsMenuLabel(label) {
1028
+ actionsMenuLabel = label;
1029
+ }
632
1030
  var GUTTER_PX = 8;
633
1031
  var CLOSE_DELAY_MS = 140;
634
- var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React12.useLayoutEffect : React12.useEffect;
635
- function iconOf(name) {
1032
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React16.useLayoutEffect : React16.useEffect;
1033
+ function iconOf2(name) {
636
1034
  if (!name) return null;
637
1035
  return ICON_MAP[name] ?? null;
638
1036
  }
639
- var RailFlyoutContext = React12.createContext(null);
1037
+ var RailFlyoutContext = React16.createContext(null);
640
1038
  var RailFlyoutProvider = RailFlyoutContext.Provider;
641
1039
  function useRailRow(content) {
642
- const flyout = React12.useContext(RailFlyoutContext);
1040
+ const flyout = React16.useContext(RailFlyoutContext);
643
1041
  if (!flyout || !content) return {};
644
1042
  return flyout.rowProps(content);
645
1043
  }
@@ -649,19 +1047,19 @@ function useRailFlyout({
649
1047
  activeRoute,
650
1048
  onNavigate
651
1049
  }) {
652
- const [state, setState] = React12.useState(null);
653
- const [pos, setPos] = React12.useState({ top: 0, arrow: 20 });
654
- const [animate, setAnimate] = React12.useState(false);
655
- const panelRef = React12.useRef(null);
656
- const closeTimer = React12.useRef(null);
657
- const lastContent = React12.useRef(null);
658
- const cancelClose = React12.useCallback(() => {
1050
+ const [state, setState] = React16.useState(null);
1051
+ const [pos, setPos] = React16.useState({ top: 0, arrow: 20 });
1052
+ const [animate, setAnimate] = React16.useState(false);
1053
+ const panelRef = React16.useRef(null);
1054
+ const closeTimer = React16.useRef(null);
1055
+ const lastContent = React16.useRef(null);
1056
+ const cancelClose = React16.useCallback(() => {
659
1057
  if (closeTimer.current) {
660
1058
  clearTimeout(closeTimer.current);
661
1059
  closeTimer.current = null;
662
1060
  }
663
1061
  }, []);
664
- const show = React12.useCallback(
1062
+ const show = React16.useCallback(
665
1063
  (anchor, content2) => {
666
1064
  if (!enabled) return;
667
1065
  cancelClose();
@@ -669,19 +1067,19 @@ function useRailFlyout({
669
1067
  },
670
1068
  [enabled, cancelClose]
671
1069
  );
672
- const hide = React12.useCallback(() => {
1070
+ const hide = React16.useCallback(() => {
673
1071
  cancelClose();
674
1072
  closeTimer.current = setTimeout(() => setState(null), CLOSE_DELAY_MS);
675
1073
  }, [cancelClose]);
676
- const dismiss = React12.useCallback(() => {
1074
+ const dismiss = React16.useCallback(() => {
677
1075
  cancelClose();
678
1076
  setState(null);
679
1077
  }, [cancelClose]);
680
- React12.useEffect(() => () => cancelClose(), [cancelClose]);
681
- React12.useEffect(() => {
1078
+ React16.useEffect(() => () => cancelClose(), [cancelClose]);
1079
+ React16.useEffect(() => {
682
1080
  if (!enabled) dismiss();
683
1081
  }, [enabled, dismiss]);
684
- const reposition = React12.useCallback(() => {
1082
+ const reposition = React16.useCallback(() => {
685
1083
  const rail = railRef.current;
686
1084
  const anchor = state?.anchor;
687
1085
  if (!rail || !anchor) return;
@@ -696,7 +1094,7 @@ function useRailFlyout({
696
1094
  setPos({ top, arrow });
697
1095
  }, [railRef, state]);
698
1096
  useIsomorphicLayoutEffect(reposition, [reposition, state?.content.key]);
699
- React12.useEffect(() => {
1097
+ React16.useEffect(() => {
700
1098
  if (!state) return;
701
1099
  const rail = railRef.current;
702
1100
  const onScroll = () => reposition();
@@ -708,7 +1106,7 @@ function useRailFlyout({
708
1106
  };
709
1107
  }, [state, railRef, reposition]);
710
1108
  const visible = !!state;
711
- React12.useEffect(() => {
1109
+ React16.useEffect(() => {
712
1110
  if (!visible) {
713
1111
  setAnimate(false);
714
1112
  return;
@@ -716,7 +1114,7 @@ function useRailFlyout({
716
1114
  const id = requestAnimationFrame(() => setAnimate(true));
717
1115
  return () => cancelAnimationFrame(id);
718
1116
  }, [visible]);
719
- React12.useEffect(() => {
1117
+ React16.useEffect(() => {
720
1118
  if (!visible) return;
721
1119
  const onKey = (event) => {
722
1120
  if (event.key === "Escape") dismiss();
@@ -724,7 +1122,7 @@ function useRailFlyout({
724
1122
  window.addEventListener("keydown", onKey);
725
1123
  return () => window.removeEventListener("keydown", onKey);
726
1124
  }, [visible, dismiss]);
727
- const rowProps = React12.useCallback(
1125
+ const rowProps = React16.useCallback(
728
1126
  (content2) => ({
729
1127
  onMouseEnter: (event) => show(event.currentTarget, content2),
730
1128
  onFocus: (event) => show(event.currentTarget, content2),
@@ -834,7 +1232,7 @@ function FlyoutBody({
834
1232
  hasEntries && /* @__PURE__ */ jsxs(Fragment, { children: [
835
1233
  /* @__PURE__ */ jsx("div", { className: "my-1 h-px bg-sidebar-border" }),
836
1234
  /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: entries.map((entry) => {
837
- const EntryIcon = iconOf(entry.icon);
1235
+ const EntryIcon = iconOf2(entry.icon);
838
1236
  const isActive = !!entry.route && entry.route === activeRoute;
839
1237
  return /* @__PURE__ */ jsxs(
840
1238
  "button",
@@ -905,7 +1303,7 @@ function NavChildConnector({ onPath, active }) {
905
1303
  ] });
906
1304
  }
907
1305
  var RAIL_PUSH_MS = 260;
908
- var useIsomorphicLayoutEffect2 = typeof window !== "undefined" ? React12.useLayoutEffect : React12.useEffect;
1306
+ var useIsomorphicLayoutEffect2 = typeof window !== "undefined" ? React16.useLayoutEffect : React16.useEffect;
909
1307
  function getIcon(name) {
910
1308
  return ICON_MAP[name] ?? Home;
911
1309
  }
@@ -1116,7 +1514,7 @@ function NavGroup({
1116
1514
  // case in an app that groups its rail).
1117
1515
  /* @__PURE__ */ jsx("button", { "data-tour": `nav.${child.route}`, onClick: () => onNavigate(child.route), className: childClass, children: childInner })
1118
1516
  );
1119
- if (!childConnector) return /* @__PURE__ */ jsx(React12.Fragment, { children: row }, child.id);
1517
+ if (!childConnector) return /* @__PURE__ */ jsx(React16.Fragment, { children: row }, child.id);
1120
1518
  const activeIndex = item.children.findIndex((c) => c.route === activeRoute);
1121
1519
  const onPath = activeIndex >= 0 && childIndex < activeIndex;
1122
1520
  return (
@@ -1138,9 +1536,9 @@ function NavGroup({
1138
1536
  ] });
1139
1537
  }
1140
1538
  function withCollapsed(slot, collapsed) {
1141
- if (!React12.isValidElement(slot)) return slot;
1539
+ if (!React16.isValidElement(slot)) return slot;
1142
1540
  if (typeof slot.type === "string") return slot;
1143
- return React12.cloneElement(slot, { collapsed });
1541
+ return React16.cloneElement(slot, { collapsed });
1144
1542
  }
1145
1543
  var SKELETON_ROWS = [
1146
1544
  { width: 56, group: false },
@@ -1182,7 +1580,7 @@ function Sidebar({
1182
1580
  }) {
1183
1581
  const currentPath = currentPathProp;
1184
1582
  const activeRoute = resolveActiveRoute(navigation, currentPath);
1185
- const railRef = React12.useRef(null);
1583
+ const railRef = React16.useRef(null);
1186
1584
  const flyout = useRailFlyout({
1187
1585
  enabled: collapsed,
1188
1586
  railRef,
@@ -1195,14 +1593,14 @@ function Sidebar({
1195
1593
  const handleNavigate = (route) => {
1196
1594
  onNavigate?.(route);
1197
1595
  };
1198
- const groupWithActiveRoute = React12.useMemo(() => {
1596
+ const groupWithActiveRoute = React16.useMemo(() => {
1199
1597
  const groups = navigation.filter((item) => item.children && item.children.length > 0);
1200
1598
  return groups.find(
1201
1599
  (item) => item.route === activeRoute || item.children.some((child) => child.route === activeRoute)
1202
1600
  )?.id ?? null;
1203
1601
  }, [navigation, activeRoute]);
1204
- const [openGroup, setOpenGroup] = React12.useState(groupWithActiveRoute);
1205
- React12.useEffect(() => {
1602
+ const [openGroup, setOpenGroup] = React16.useState(groupWithActiveRoute);
1603
+ React16.useEffect(() => {
1206
1604
  if (groupWithActiveRoute) setOpenGroup(groupWithActiveRoute);
1207
1605
  }, [groupWithActiveRoute]);
1208
1606
  const sectionHeading = (label) => label && !collapsed ? /* @__PURE__ */ jsx("p", { className: "px-2.5 pb-0.5 pt-1 text-[10px] font-semibold uppercase tracking-wider text-sidebar-muted", children: label }) : null;
@@ -1254,10 +1652,10 @@ function Sidebar({
1254
1652
  mainItems.length > 0 && renderSection(mainItems, sectionLabels?.main),
1255
1653
  secondaryItems.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-6", children: renderSection(secondaryItems, sectionLabels?.secondary) })
1256
1654
  ] });
1257
- const [outgoing, setOutgoing] = React12.useState(null);
1258
- const lastBodyRef = React12.useRef(null);
1259
- const lastKeyRef = React12.useRef(navKey);
1260
- const timerRef = React12.useRef(null);
1655
+ const [outgoing, setOutgoing] = React16.useState(null);
1656
+ const lastBodyRef = React16.useRef(null);
1657
+ const lastKeyRef = React16.useRef(navKey);
1658
+ const timerRef = React16.useRef(null);
1261
1659
  useIsomorphicLayoutEffect2(() => {
1262
1660
  if (lastKeyRef.current !== navKey) {
1263
1661
  const previousBody = lastBodyRef.current;
@@ -1270,7 +1668,7 @@ function Sidebar({
1270
1668
  }
1271
1669
  lastBodyRef.current = navBody;
1272
1670
  });
1273
- React12.useEffect(() => () => {
1671
+ React16.useEffect(() => () => {
1274
1672
  if (timerRef.current) clearTimeout(timerRef.current);
1275
1673
  }, []);
1276
1674
  return (
@@ -1514,7 +1912,7 @@ function ShellSearch({
1514
1912
  const rail = tone === "rail";
1515
1913
  const contextual = !!onValueChange && !collapsed;
1516
1914
  const query = value ?? "";
1517
- const inputRef = React12.useRef(null);
1915
+ const inputRef = React16.useRef(null);
1518
1916
  const escalate = () => setCommandPaletteOpen(true, query);
1519
1917
  const surface = rail ? "bg-sidebar-accent/40 text-sidebar-muted hover:bg-sidebar-accent/70 hover:text-sidebar-foreground" : "bg-accent/40 text-muted-foreground hover:bg-accent/70 hover:text-foreground";
1520
1918
  const ring = rail ? "focus-within:bg-sidebar-accent/70 focus-within:ring-1 focus-within:ring-sidebar-accent-foreground/25" : "focus-within:bg-accent/70 focus-within:ring-1 focus-within:ring-ring/40";
@@ -1625,7 +2023,7 @@ function TopbarUserMenu({
1625
2023
  onBilling,
1626
2024
  userMenuExtras
1627
2025
  }) {
1628
- const [open, setOpen] = React12.useState(false);
2026
+ const [open, setOpen] = React16.useState(false);
1629
2027
  if (!user) return null;
1630
2028
  const initial = (user.fullName?.trim()?.[0] ?? user.email?.[0] ?? "?").toUpperCase();
1631
2029
  const item = (label, onClick, Icon) => onClick ? /* @__PURE__ */ jsxs(
@@ -1709,7 +2107,7 @@ function getIcon2(name) {
1709
2107
  return ICON_MAP[name] ?? Home;
1710
2108
  }
1711
2109
  function NavDropdown({ item, currentPath, onNavigate }) {
1712
- const [open, setOpen] = React12.useState(false);
2110
+ const [open, setOpen] = React16.useState(false);
1713
2111
  const Icon = getIcon2(item.icon);
1714
2112
  const isChildActive = item.children?.some(
1715
2113
  (child) => currentPath === child.route || currentPath.startsWith(child.route + "/")
@@ -1877,9 +2275,9 @@ function Topbar({
1877
2275
  ] });
1878
2276
  }
1879
2277
  function useSheetDrag({ onDismiss, canDrag }) {
1880
- const [offset, setOffset] = React12.useState(0);
1881
- const [dragging, setDragging] = React12.useState(false);
1882
- const start = React12.useRef(null);
2278
+ const [offset, setOffset] = React16.useState(0);
2279
+ const [dragging, setDragging] = React16.useState(false);
2280
+ const start = React16.useRef(null);
1883
2281
  const onPointerDown = (e) => {
1884
2282
  if (e.pointerType === "mouse") return;
1885
2283
  if (canDrag && !canDrag()) return;
@@ -1913,9 +2311,9 @@ function useSheetDrag({ onDismiss, canDrag }) {
1913
2311
  handlers: { onPointerDown, onPointerMove, onPointerUp: end, onPointerCancel: end }
1914
2312
  };
1915
2313
  }
1916
- var SheetCloseContext = React12.createContext(null);
2314
+ var SheetCloseContext = React16.createContext(null);
1917
2315
  function useSheetClose() {
1918
- const close = React12.useContext(SheetCloseContext);
2316
+ const close = React16.useContext(SheetCloseContext);
1919
2317
  return close ?? (() => {
1920
2318
  });
1921
2319
  }
@@ -1929,9 +2327,9 @@ function BottomSheet({
1929
2327
  className,
1930
2328
  label
1931
2329
  }) {
1932
- const [leaving, setLeaving] = React12.useState(false);
1933
- const scroller = React12.useRef(null);
1934
- const close = React12.useCallback(() => {
2330
+ const [leaving, setLeaving] = React16.useState(false);
2331
+ const scroller = React16.useRef(null);
2332
+ const close = React16.useCallback(() => {
1935
2333
  setLeaving(true);
1936
2334
  window.setTimeout(onClose, 200);
1937
2335
  }, [onClose]);
@@ -1939,7 +2337,7 @@ function BottomSheet({
1939
2337
  onDismiss: close,
1940
2338
  canDrag: () => (scroller.current?.scrollTop ?? 0) <= 0
1941
2339
  });
1942
- React12.useEffect(() => {
2340
+ React16.useEffect(() => {
1943
2341
  const onKey = (e) => {
1944
2342
  if (e.key !== "Escape") return;
1945
2343
  if (onBack) onBack();
@@ -1948,15 +2346,15 @@ function BottomSheet({
1948
2346
  window.addEventListener("keydown", onKey);
1949
2347
  return () => window.removeEventListener("keydown", onKey);
1950
2348
  }, [close, onBack]);
1951
- React12.useEffect(() => {
2349
+ React16.useEffect(() => {
1952
2350
  const previous = document.body.style.overflow;
1953
2351
  document.body.style.overflow = "hidden";
1954
2352
  return () => {
1955
2353
  document.body.style.overflow = previous;
1956
2354
  };
1957
2355
  }, []);
1958
- const [host, setHost] = React12.useState(null);
1959
- React12.useEffect(() => {
2356
+ const [host, setHost] = React16.useState(null);
2357
+ React16.useEffect(() => {
1960
2358
  setHost(document.body);
1961
2359
  }, []);
1962
2360
  if (!host) return null;
@@ -2071,17 +2469,17 @@ function SheetRow({
2071
2469
  }
2072
2470
  );
2073
2471
  }
2074
- var ModuleHeaderSlotContext = React12.createContext(null);
2472
+ var ModuleHeaderSlotContext = React16.createContext(null);
2075
2473
  function useModuleHeaderSlot() {
2076
- return React12.useContext(ModuleHeaderSlotContext);
2474
+ return React16.useContext(ModuleHeaderSlotContext);
2077
2475
  }
2078
- var ModuleHeaderActionsSlotContext = React12.createContext(null);
2476
+ var ModuleHeaderActionsSlotContext = React16.createContext(null);
2079
2477
  function useModuleHeaderActionsSlot() {
2080
- return React12.useContext(ModuleHeaderActionsSlotContext);
2478
+ return React16.useContext(ModuleHeaderActionsSlotContext);
2081
2479
  }
2082
- var PageRailSlotContext = React12.createContext(null);
2480
+ var PageRailSlotContext = React16.createContext(null);
2083
2481
  function usePageRailSlot() {
2084
- return React12.useContext(PageRailSlotContext);
2482
+ return React16.useContext(PageRailSlotContext);
2085
2483
  }
2086
2484
  function isCreateRoute(route) {
2087
2485
  return !!route && /\/(new|create)$/.test(route);
@@ -2108,6 +2506,62 @@ function ShellPageTitle({
2108
2506
  }
2109
2507
  );
2110
2508
  }
2509
+ function MobileQuickControls({ children }) {
2510
+ const [open, setOpen] = React16.useState(false);
2511
+ const [hasItems, setHasItems] = React16.useState(false);
2512
+ const rootRef = React16.useRef(null);
2513
+ const panelRef = React16.useRef(null);
2514
+ React16.useEffect(() => {
2515
+ const panel = panelRef.current;
2516
+ if (!panel) return;
2517
+ const read2 = () => setHasItems(!!panel.querySelector("button, a, input, select, [role]"));
2518
+ read2();
2519
+ const observer = new MutationObserver(read2);
2520
+ observer.observe(panel, { childList: true, subtree: true });
2521
+ return () => observer.disconnect();
2522
+ }, []);
2523
+ React16.useEffect(() => {
2524
+ if (!open) return;
2525
+ const onDown = (e) => {
2526
+ const target = e.target;
2527
+ if (!target || rootRef.current?.contains(target)) return;
2528
+ if (target.closest('[data-radix-popper-content-wrapper], [role="dialog"]')) return;
2529
+ setOpen(false);
2530
+ };
2531
+ document.addEventListener("pointerdown", onDown);
2532
+ return () => document.removeEventListener("pointerdown", onDown);
2533
+ }, [open]);
2534
+ return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: cn("relative", open && "z-[105]", !hasItems && "hidden"), children: [
2535
+ /* @__PURE__ */ jsx(MobileScrim, { open, onClose: () => setOpen(false) }),
2536
+ /* @__PURE__ */ jsx(
2537
+ "button",
2538
+ {
2539
+ type: "button",
2540
+ onClick: () => setOpen((v) => !v),
2541
+ "aria-label": "Ajustes r\xE1pidos",
2542
+ "aria-expanded": open,
2543
+ className: cn(
2544
+ "inline-flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent",
2545
+ open && "bg-accent text-foreground"
2546
+ ),
2547
+ children: /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-5 w-5" })
2548
+ }
2549
+ ),
2550
+ /* @__PURE__ */ jsx(
2551
+ "div",
2552
+ {
2553
+ ref: panelRef,
2554
+ className: cn(
2555
+ "absolute right-0 top-full z-30 mt-2 flex w-[min(20rem,calc(100vw-2rem))] flex-col items-stretch gap-1.5 rounded-2xl border border-border bg-popover p-3 text-[15px] text-popover-foreground shadow-lg fz-menu-glass [&>*]:min-h-11",
2556
+ // Rail-shaped controls are written in the rail's tokens; here they sit on paper.
2557
+ "[--sidebar-accent-foreground:var(--accent-foreground)] [--sidebar-accent:var(--accent)] [--sidebar-foreground:var(--foreground)] [--sidebar-muted:var(--muted-foreground)]",
2558
+ !open && "hidden"
2559
+ ),
2560
+ children
2561
+ }
2562
+ )
2563
+ ] });
2564
+ }
2111
2565
  function SidebarLayout({
2112
2566
  navigation = [],
2113
2567
  navLoading = false,
@@ -2169,10 +2623,11 @@ function SidebarLayout({
2169
2623
  const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
2170
2624
  const mobileMenuOpen = useLayoutStore((st) => st.mobileDrawerOpen);
2171
2625
  const setMobileMenuOpen = useLayoutStore((st) => st.setMobileDrawerOpen);
2172
- const [headerSlot, setHeaderSlot] = React12.useState(null);
2173
- const [actionsSlot, setActionsSlot] = React12.useState(null);
2174
- const [pageRailSlot, setPageRailSlot] = React12.useState(null);
2626
+ const [headerSlot, setHeaderSlot] = React16.useState(null);
2627
+ const [actionsSlot, setActionsSlot] = React16.useState(null);
2628
+ const [pageRailSlot, setPageRailSlot] = React16.useState(null);
2175
2629
  const hasPageActions = useHasPageActions();
2630
+ const wide = useIsWide();
2176
2631
  return /* @__PURE__ */ jsx(SaveBarProvider, { children: /* @__PURE__ */ jsx(ModuleHeaderSlotContext.Provider, { value: headerSlot, children: /* @__PURE__ */ jsx(ModuleHeaderActionsSlotContext.Provider, { value: actionsSlot, children: /* @__PURE__ */ jsx(PageRailSlotContext.Provider, { value: pageRailSlot, children: /* @__PURE__ */ jsxs("div", { className: cn(
2177
2632
  "shell-enter fz-viewport-h flex overflow-hidden bg-background",
2178
2633
  hasBottomNav && "fz-has-bottom-bar",
@@ -2227,7 +2682,7 @@ function SidebarLayout({
2227
2682
  // 44px on a phone — the height every other bar in this product now
2228
2683
  // uses (the "Mais" screen, a sheet's header) and the height a phone's
2229
2684
  // own navigation bar has. Desktop keeps its 56px band.
2230
- "min-h-[44px] md:min-h-14 border-b border-border",
2685
+ "min-h-[44px] md:min-h-14 md:border-b md:border-border",
2231
2686
  // On a phone this band IS the navigation bar, so it is made of the
2232
2687
  // same glass as the tab bar below it and the sheets between them —
2233
2688
  // one material for the chrome, the page reading through all of it.
@@ -2279,11 +2734,12 @@ function SidebarLayout({
2279
2734
  }
2280
2735
  ),
2281
2736
  topbarStart,
2737
+ barOwnsNav && pagePrimary && pageTitle && /* @__PURE__ */ jsx("h1", { className: "absolute left-1/2 top-1/2 max-w-[50%] -translate-x-1/2 -translate-y-1/2 truncate text-[15px] font-semibold text-foreground md:hidden", children: pageTitle }),
2282
2738
  /* @__PURE__ */ jsx("div", { ref: setHeaderSlot, className: "flex min-w-0 flex-1 items-center" })
2283
2739
  ] }),
2284
2740
  /* @__PURE__ */ jsx("div", { className: "hidden min-w-0 flex-1 justify-center px-2 md:flex", children: /* @__PURE__ */ jsx(ShellSearch, { tone: "bar", label: searchLabel, className: "w-full max-w-[280px]" }) }),
2285
2741
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 shrink-0 items-center justify-end gap-2 md:flex-1", children: [
2286
- topbarEnd,
2742
+ wide ? topbarEnd : /* @__PURE__ */ jsx(MobileQuickControls, { children: topbarEnd }),
2287
2743
  notificationSlot
2288
2744
  ] })
2289
2745
  ] }),
@@ -2453,9 +2909,9 @@ function TopbarLayout({
2453
2909
  const saveBarVisible = useSaveBarVisible();
2454
2910
  const mobileMenuOpen = useLayoutStore((st) => st.mobileDrawerOpen);
2455
2911
  const setMobileMenuOpen = useLayoutStore((st) => st.setMobileDrawerOpen);
2456
- const [headerSlot, setHeaderSlot] = React12.useState(null);
2457
- const [actionsSlot, setActionsSlot] = React12.useState(null);
2458
- const [pageRailSlot, setPageRailSlot] = React12.useState(null);
2912
+ const [headerSlot, setHeaderSlot] = React16.useState(null);
2913
+ const [actionsSlot, setActionsSlot] = React16.useState(null);
2914
+ const [pageRailSlot, setPageRailSlot] = React16.useState(null);
2459
2915
  const rawClaimed = usePageHeaderClaimed();
2460
2916
  const setTitleSlot = usePageTitleSlotHost();
2461
2917
  const hasOutlet = useHasPageHeaderOutlet();
@@ -2594,10 +3050,10 @@ function MobileMoreScreen({
2594
3050
  onDismiss,
2595
3051
  onClose
2596
3052
  }) {
2597
- const [pushed, setPushed] = React12.useState(null);
2598
- const [query, setQuery] = React12.useState("");
2599
- const scroller = React12.useRef(null);
2600
- const close = React12.useCallback(() => {
3053
+ const [pushed, setPushed] = React16.useState(null);
3054
+ const [query, setQuery] = React16.useState("");
3055
+ const scroller = React16.useRef(null);
3056
+ const close = React16.useCallback(() => {
2601
3057
  onClose();
2602
3058
  }, [onClose]);
2603
3059
  const drag = useSheetDrag({
@@ -2606,7 +3062,7 @@ function MobileMoreScreen({
2606
3062
  // a pushed section would dismiss the screen the back button is for.
2607
3063
  canDrag: () => !pushed && (scroller.current?.scrollTop ?? 0) <= 0
2608
3064
  });
2609
- React12.useEffect(() => {
3065
+ React16.useEffect(() => {
2610
3066
  const onKey = (e) => {
2611
3067
  if (e.key !== "Escape") return;
2612
3068
  if (pushed) setPushed(null);
@@ -2615,7 +3071,7 @@ function MobileMoreScreen({
2615
3071
  window.addEventListener("keydown", onKey);
2616
3072
  return () => window.removeEventListener("keydown", onKey);
2617
3073
  }, [close, pushed]);
2618
- React12.useEffect(() => {
3074
+ React16.useEffect(() => {
2619
3075
  const previous = document.body.style.overflow;
2620
3076
  document.body.style.overflow = "hidden";
2621
3077
  return () => {
@@ -2635,13 +3091,13 @@ function MobileMoreScreen({
2635
3091
  else onNavigate?.(route);
2636
3092
  };
2637
3093
  const q = query.trim().toLowerCase();
2638
- const flat = React12.useMemo(
3094
+ const flat = React16.useMemo(
2639
3095
  () => navigation.flatMap((n) => n.children?.length ? n.children : [n]),
2640
3096
  [navigation]
2641
3097
  );
2642
3098
  const searching = q.length > 0;
2643
3099
  const hits = searching ? flat.filter((n) => n.label.toLowerCase().includes(q)) : [];
2644
- const sections = React12.useMemo(() => {
3100
+ const sections = React16.useMemo(() => {
2645
3101
  const out = [];
2646
3102
  for (const key of ["main", "secondary", "settings"]) {
2647
3103
  const items = navigation.filter((n) => n.section === key);
@@ -2910,23 +3366,23 @@ function MinimalLayout({
2910
3366
  ] });
2911
3367
  }
2912
3368
  function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
2913
- const [visible, setVisible] = React12.useState(false);
2914
- React12.useEffect(() => {
3369
+ const [visible, setVisible] = React16.useState(false);
3370
+ React16.useEffect(() => {
2915
3371
  const id = requestAnimationFrame(() => setVisible(true));
2916
3372
  return () => cancelAnimationFrame(id);
2917
3373
  }, []);
2918
- const close = React12.useCallback(() => {
3374
+ const close = React16.useCallback(() => {
2919
3375
  setVisible(false);
2920
3376
  window.setTimeout(onClose, 250);
2921
3377
  }, [onClose]);
2922
- React12.useEffect(() => {
3378
+ React16.useEffect(() => {
2923
3379
  const previous = document.body.style.overflow;
2924
3380
  document.body.style.overflow = "hidden";
2925
3381
  return () => {
2926
3382
  document.body.style.overflow = previous;
2927
3383
  };
2928
3384
  }, []);
2929
- React12.useEffect(() => {
3385
+ React16.useEffect(() => {
2930
3386
  const onKey = (e) => {
2931
3387
  if (e.key === "Escape") close();
2932
3388
  };
@@ -3026,14 +3482,16 @@ function MobileBottomNav({
3026
3482
  onAssistant,
3027
3483
  assistantOpen,
3028
3484
  moreOpen,
3029
- retracted
3485
+ retracted,
3486
+ frame,
3487
+ assistantFace
3030
3488
  }) {
3031
3489
  const path = currentPath ?? "";
3032
- const [openSheet, setOpenSheet] = React12.useState(null);
3033
- React12.useEffect(() => {
3490
+ const [openSheet, setOpenSheet] = React16.useState(null);
3491
+ React16.useEffect(() => {
3034
3492
  setOpenSheet(null);
3035
3493
  }, [currentPath]);
3036
- React12.useEffect(() => {
3494
+ React16.useEffect(() => {
3037
3495
  if (retracted) setOpenSheet(null);
3038
3496
  }, [retracted]);
3039
3497
  const sheetItem = openSheet != null ? items[openSheet] : void 0;
@@ -3045,9 +3503,13 @@ function MobileBottomNav({
3045
3503
  "aria-hidden": retracted || void 0,
3046
3504
  className: cn(
3047
3505
  "fz-safe-b fixed inset-x-0 bottom-0 z-50 flex min-h-16 items-stretch justify-around md:hidden",
3048
- "border-t border-sidebar-border bg-sidebar text-sidebar-foreground shadow-[0_-8px_24px_hsl(var(--sidebar)/0.18)]",
3506
+ "fz-glass-tabbar text-sidebar-foreground",
3049
3507
  "motion-safe:transition-transform motion-safe:duration-200 motion-safe:ease-out",
3050
- retracted && "pointer-events-none translate-y-full"
3508
+ // The framed shell rounds its content card; the bar is the phone's
3509
+ // piece of that same frame.
3510
+ frame && "rounded-t-[28px]",
3511
+ // Past its own height: the assistant button stands above the bar's edge.
3512
+ retracted && "pointer-events-none translate-y-[calc(100%+2.5rem)]"
3051
3513
  ),
3052
3514
  children: items.map((item, i) => {
3053
3515
  if ("kind" in item && item.kind === "action") {
@@ -3063,18 +3525,36 @@ function MobileBottomNav({
3063
3525
  }
3064
3526
  ) }, item.id);
3065
3527
  }
3528
+ if ("kind" in item && item.kind === "assistant") {
3529
+ const AssistantIcon = bottomNavIcon(item.icon, Sparkles);
3530
+ const label2 = item.label ?? "IA";
3531
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-start justify-center", children: /* @__PURE__ */ jsx(
3532
+ "button",
3533
+ {
3534
+ type: "button",
3535
+ onClick: () => {
3536
+ setOpenSheet(null);
3537
+ onAssistant?.();
3538
+ },
3539
+ "aria-label": label2,
3540
+ "aria-expanded": !!assistantOpen,
3541
+ className: cn(
3542
+ "-mt-3 flex h-[60px] w-[60px] items-center justify-center rounded-full shadow-lg ring-[5px] ring-sidebar transition-transform active:scale-95",
3543
+ assistantFace ? "bg-card" : "bg-primary text-primary-foreground",
3544
+ assistantOpen && "ring-sidebar-accent-foreground"
3545
+ ),
3546
+ children: assistantFace ?? /* @__PURE__ */ jsx(AssistantIcon, { className: "h-6 w-6" })
3547
+ }
3548
+ ) }, "assistant");
3549
+ }
3066
3550
  const isMore = "kind" in item && item.kind === "more";
3067
- const isAssistant = "kind" in item && item.kind === "assistant";
3068
- const label = isMore ? item.label ?? "Mais" : isAssistant ? item.label ?? "IA" : item.label;
3069
- const Icon = bottomNavIcon(
3070
- item.icon,
3071
- isMore ? Menu : isAssistant ? Sparkles : Home
3072
- );
3073
- const route = isMore || isAssistant ? void 0 : item.route;
3074
- const children = isMore || isAssistant ? void 0 : item.children?.filter((c) => !isCreateRoute(c.route));
3551
+ const label = isMore ? item.label ?? "Mais" : item.label;
3552
+ const Icon = bottomNavIcon(item.icon, isMore ? Menu : Home);
3553
+ const route = isMore ? void 0 : item.route;
3554
+ const children = isMore ? void 0 : item.children?.filter((c) => !isCreateRoute(c.route));
3075
3555
  const hasChoices = !!children && children.length > 1;
3076
3556
  const sheetOpen = openSheet === i;
3077
- const isActive = isMore ? !!moreOpen : isAssistant ? !!assistantOpen : sheetOpen ? true : route === "/" ? path === "/" || path === "" : !!route && (path === route || path.startsWith(route + "/"));
3557
+ const isActive = isMore ? !!moreOpen : sheetOpen ? true : route === "/" ? path === "/" || path === "" : !!route && (path === route || path.startsWith(route + "/"));
3078
3558
  return /* @__PURE__ */ jsxs(
3079
3559
  "button",
3080
3560
  {
@@ -3084,15 +3564,11 @@ function MobileBottomNav({
3084
3564
  setOpenSheet(null);
3085
3565
  return onMore?.();
3086
3566
  }
3087
- if (isAssistant) {
3088
- setOpenSheet(null);
3089
- return onAssistant?.();
3090
- }
3091
3567
  if (hasChoices) return setOpenSheet(sheetOpen ? null : i);
3092
3568
  onNavigate?.(children?.[0]?.route ?? route);
3093
3569
  },
3094
3570
  "aria-current": isActive && route && !hasChoices ? "page" : void 0,
3095
- "aria-expanded": isMore || isAssistant ? isActive : hasChoices ? sheetOpen : void 0,
3571
+ "aria-expanded": isMore ? isActive : hasChoices ? sheetOpen : void 0,
3096
3572
  "aria-haspopup": hasChoices ? "menu" : void 0,
3097
3573
  className: cn(
3098
3574
  // min-h-[44px] is the floor a finger needs; the bar was letting
@@ -3101,16 +3577,6 @@ function MobileBottomNav({
3101
3577
  isActive ? "text-sidebar-accent-foreground" : "text-sidebar-muted"
3102
3578
  ),
3103
3579
  children: [
3104
- /* @__PURE__ */ jsx(
3105
- "span",
3106
- {
3107
- "aria-hidden": true,
3108
- className: cn(
3109
- "absolute inset-x-3 top-0 h-0.5 rounded-full transition-opacity",
3110
- isActive ? "bg-sidebar-accent-foreground opacity-100" : "opacity-0"
3111
- )
3112
- }
3113
- ),
3114
3580
  /* @__PURE__ */ jsxs("span", { className: "relative flex items-center", children: [
3115
3581
  /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5 shrink-0" }),
3116
3582
  hasChoices && /* @__PURE__ */ jsx(
@@ -3124,10 +3590,10 @@ function MobileBottomNav({
3124
3590
  }
3125
3591
  )
3126
3592
  ] }),
3127
- /* @__PURE__ */ jsx("span", { className: "max-w-full truncate text-[11px] leading-tight", children: label })
3593
+ /* @__PURE__ */ jsx("span", { className: cn("max-w-full truncate text-[11px] leading-tight", isActive && "font-semibold"), children: label })
3128
3594
  ]
3129
3595
  },
3130
- isMore ? "more" : isAssistant ? "assistant" : `${route}-${i}`
3596
+ isMore ? "more" : `${route}-${i}`
3131
3597
  );
3132
3598
  })
3133
3599
  }
@@ -3183,6 +3649,7 @@ function AppShell({
3183
3649
  onBottomNavAction,
3184
3650
  onAssistantToggle,
3185
3651
  assistantOpen,
3652
+ assistantFace,
3186
3653
  mobileHeader = "minimal",
3187
3654
  immersive = false,
3188
3655
  userMenuSlot,
@@ -3205,7 +3672,7 @@ function AppShell({
3205
3672
  const hasBottomNav = !!bottomNav?.length;
3206
3673
  const barOwnsNav = bottomNavReachesAll(bottomNav);
3207
3674
  const menuNavigation = appNavigation ?? navigation;
3208
- const routeLabel = React12.useCallback((path) => {
3675
+ const routeLabel = React16.useCallback((path) => {
3209
3676
  let best;
3210
3677
  const consider = (route, label) => {
3211
3678
  if (!route || !label) return;
@@ -3220,14 +3687,14 @@ function AppShell({
3220
3687
  }
3221
3688
  return best?.label ?? pageTitle ?? "";
3222
3689
  }, [menuNavigation, pageTitle]);
3223
- React12.useEffect(() => {
3690
+ React16.useEffect(() => {
3224
3691
  if (!currentPath) return;
3225
3692
  if (currentPath === MENU_ROUTE) return;
3226
3693
  const label = routeLabel(currentPath);
3227
3694
  if (!label) return;
3228
3695
  recordNavigation(currentPath, label);
3229
3696
  }, [currentPath, routeLabel]);
3230
- const destinationRoutes = React12.useMemo(() => {
3697
+ const destinationRoutes = React16.useMemo(() => {
3231
3698
  const routes = [];
3232
3699
  for (const item of menuNavigation) {
3233
3700
  if (item.route) routes.push(item.route);
@@ -3236,7 +3703,7 @@ function AppShell({
3236
3703
  return routes;
3237
3704
  }, [menuNavigation]);
3238
3705
  const isDestination = !!currentPath && destinationRoutes.includes(currentPath);
3239
- React12.useEffect(() => {
3706
+ React16.useEffect(() => {
3240
3707
  setDestinationRoutes(destinationRoutes);
3241
3708
  }, [destinationRoutes]);
3242
3709
  const pageClaimedBack = useHasPageHeaderBack();
@@ -3244,7 +3711,7 @@ function AppShell({
3244
3711
  const barRetracted = !!pageBack || pageClaimedBack || inSettings;
3245
3712
  const mobileDrawerOpen = useLayoutStore((st) => st.mobileDrawerOpen);
3246
3713
  const setMobileDrawerOpen = useLayoutStore((st) => st.setMobileDrawerOpen);
3247
- React12.useEffect(() => {
3714
+ React16.useEffect(() => {
3248
3715
  if (useLayoutStore.getState().drawerKeepOpenOnce) {
3249
3716
  useLayoutStore.setState({ drawerKeepOpenOnce: false });
3250
3717
  return;
@@ -3252,12 +3719,12 @@ function AppShell({
3252
3719
  setMobileDrawerOpen(false);
3253
3720
  }, [currentPath]);
3254
3721
  const menuRouteOpen = barOwnsNav && currentPath === MENU_ROUTE;
3255
- const firstDestination = React12.useMemo(() => {
3722
+ const firstDestination = React16.useMemo(() => {
3256
3723
  const first = bottomNav?.find((i) => !("kind" in i) || i.kind === "route");
3257
3724
  return first?.route ?? "/";
3258
3725
  }, [bottomNav]);
3259
- const menuOrigin = React12.useRef(void 0);
3260
- const openMenu = React12.useCallback(() => {
3726
+ const menuOrigin = React16.useRef(void 0);
3727
+ const openMenu = React16.useCallback(() => {
3261
3728
  if (!barOwnsNav) {
3262
3729
  setMobileDrawerOpen(true);
3263
3730
  return;
@@ -3268,10 +3735,10 @@ function AppShell({
3268
3735
  menuOrigin.current = currentPath;
3269
3736
  onNavigate?.(MENU_ROUTE);
3270
3737
  }, [barOwnsNav, currentPath, onNavigate, setMobileDrawerOpen]);
3271
- const [menuLeaving, setMenuLeaving] = React12.useState(false);
3272
- const [menuLingering, setMenuLingering] = React12.useState(false);
3273
- const menuTimer = React12.useRef(void 0);
3274
- const dismissMenu = React12.useCallback((navigate) => {
3738
+ const [menuLeaving, setMenuLeaving] = React16.useState(false);
3739
+ const [menuLingering, setMenuLingering] = React16.useState(false);
3740
+ const menuTimer = React16.useRef(void 0);
3741
+ const dismissMenu = React16.useCallback((navigate) => {
3275
3742
  window.clearTimeout(menuTimer.current);
3276
3743
  setMenuLingering(true);
3277
3744
  setMenuLeaving(true);
@@ -3281,8 +3748,8 @@ function AppShell({
3281
3748
  setMenuLingering(false);
3282
3749
  }, 240);
3283
3750
  }, []);
3284
- React12.useEffect(() => () => window.clearTimeout(menuTimer.current), []);
3285
- const closeMenu = React12.useCallback(() => {
3751
+ React16.useEffect(() => () => window.clearTimeout(menuTimer.current), []);
3752
+ const closeMenu = React16.useCallback(() => {
3286
3753
  if (!barOwnsNav) {
3287
3754
  setMobileDrawerOpen(false);
3288
3755
  return;
@@ -3295,7 +3762,7 @@ function AppShell({
3295
3762
  onNavigate?.(back);
3296
3763
  });
3297
3764
  }, [barOwnsNav, setMobileDrawerOpen, onNavigate, firstDestination, dismissMenu]);
3298
- React12.useEffect(() => {
3765
+ React16.useEffect(() => {
3299
3766
  if (!menuRouteOpen || typeof window === "undefined") return;
3300
3767
  const wide = window.matchMedia("(min-width: 768px)");
3301
3768
  const settle = () => {
@@ -3317,6 +3784,8 @@ function AppShell({
3317
3784
  moreOpen: barOwnsNav ? menuRouteOpen : mobileDrawerOpen,
3318
3785
  onAssistant: onAssistantToggle,
3319
3786
  assistantOpen,
3787
+ assistantFace,
3788
+ frame: contentFrame,
3320
3789
  retracted: barRetracted
3321
3790
  }
3322
3791
  ) : null;
@@ -3456,13 +3925,13 @@ function SplitWithRightRail({
3456
3925
  maxWidth = 720,
3457
3926
  resizeLabel = "Resize panel"
3458
3927
  }) {
3459
- const [width, setWidth] = React12.useState(defaultWidth);
3460
- const [dragging, setDragging] = React12.useState(false);
3461
- const clamp = React12.useCallback(
3928
+ const [width, setWidth] = React16.useState(defaultWidth);
3929
+ const [dragging, setDragging] = React16.useState(false);
3930
+ const clamp = React16.useCallback(
3462
3931
  (value) => Math.min(maxWidth, Math.max(minWidth, value)),
3463
3932
  [minWidth, maxWidth]
3464
3933
  );
3465
- React12.useEffect(() => {
3934
+ React16.useEffect(() => {
3466
3935
  if (!dragging) return;
3467
3936
  const onMove = (event) => {
3468
3937
  event.preventDefault();
@@ -3484,7 +3953,7 @@ function SplitWithRightRail({
3484
3953
  document.body.style.cursor = previousCursor;
3485
3954
  };
3486
3955
  }, [dragging, clamp]);
3487
- React12.useEffect(() => {
3956
+ React16.useEffect(() => {
3488
3957
  if (dragging) return;
3489
3958
  onWidthChange?.(width);
3490
3959
  }, [dragging]);
@@ -3699,12 +4168,12 @@ function ViewTabs({ value, onChange, options, "aria-label": ariaLabel, className
3699
4168
  );
3700
4169
  }) });
3701
4170
  }
3702
- var NavTransitionContext = React12.createContext("slide");
4171
+ var NavTransitionContext = React16.createContext("slide");
3703
4172
  function NavTransitionProvider({ value, children }) {
3704
4173
  return /* @__PURE__ */ jsx(NavTransitionContext.Provider, { value, children });
3705
4174
  }
3706
4175
  function useNavTransition() {
3707
- return React12.useContext(NavTransitionContext);
4176
+ return React16.useContext(NavTransitionContext);
3708
4177
  }
3709
4178
  function resolveTransitionClass(transition, direction) {
3710
4179
  if (transition === "none") return "";
@@ -3724,26 +4193,26 @@ function PageTransition({
3724
4193
  return /* @__PURE__ */ jsx("div", { className: cn(animClass, className), children }, transitionKey);
3725
4194
  }
3726
4195
  var EMPTY = [];
3727
- var PageTrailContext = React12.createContext(EMPTY);
4196
+ var PageTrailContext = React16.createContext(EMPTY);
3728
4197
  function PageTrail({
3729
4198
  label,
3730
4199
  href,
3731
4200
  onNavigate,
3732
4201
  children
3733
4202
  }) {
3734
- const parent = React12.useContext(PageTrailContext);
3735
- const trail = React12.useMemo(
4203
+ const parent = React16.useContext(PageTrailContext);
4204
+ const trail = React16.useMemo(
3736
4205
  () => [...parent, { label, href, onNavigate }],
3737
4206
  [parent, label, href, onNavigate]
3738
4207
  );
3739
4208
  return /* @__PURE__ */ jsx(PageTrailContext.Provider, { value: trail, children });
3740
4209
  }
3741
4210
  function usePageTrail() {
3742
- return React12.useContext(PageTrailContext);
4211
+ return React16.useContext(PageTrailContext);
3743
4212
  }
3744
4213
  function usePageTrailParent(href) {
3745
- const trail = React12.useContext(PageTrailContext);
3746
- return React12.useMemo(() => {
4214
+ const trail = React16.useContext(PageTrailContext);
4215
+ return React16.useMemo(() => {
3747
4216
  const above = href ? trail.filter((c) => c.href !== href) : trail;
3748
4217
  return above[above.length - 1];
3749
4218
  }, [trail, href]);
@@ -3759,8 +4228,8 @@ function useCurrentRouteHref() {
3759
4228
  const clean = hash.split("?")[0];
3760
4229
  return clean.startsWith("/") ? clean : `/${clean}`;
3761
4230
  };
3762
- const [href, setHref] = React12.useState(read2);
3763
- React12.useEffect(() => {
4231
+ const [href, setHref] = React16.useState(read2);
4232
+ React16.useEffect(() => {
3764
4233
  const handler = () => setHref(read2());
3765
4234
  window.addEventListener("hashchange", handler);
3766
4235
  handler();
@@ -3771,7 +4240,7 @@ function useCurrentRouteHref() {
3771
4240
  function useTrailBack(href) {
3772
4241
  const current = useCurrentRouteHref();
3773
4242
  const parent = usePageTrailParent(href ?? current);
3774
- return React12.useMemo(
4243
+ return React16.useMemo(
3775
4244
  () => parent ? { onBack: () => navigateToCrumb(parent), parentLabel: parent.label } : {},
3776
4245
  [parent]
3777
4246
  );
@@ -3798,23 +4267,23 @@ function CollapsibleColumn({
3798
4267
  "aria-label": ariaLabel
3799
4268
  }) {
3800
4269
  const pinnedKey = `${storageKey}.pinned`;
3801
- const [collapsed, setCollapsed] = React12.useState(() => read(storageKey));
3802
- const [pinned, setPinned] = React12.useState(() => read(pinnedKey));
3803
- const [hovering, setHovering] = React12.useState(false);
3804
- const hoveringRef = React12.useRef(false);
3805
- const collapsedRef = React12.useRef(collapsed);
4270
+ const [collapsed, setCollapsed] = React16.useState(() => read(storageKey));
4271
+ const [pinned, setPinned] = React16.useState(() => read(pinnedKey));
4272
+ const [hovering, setHovering] = React16.useState(false);
4273
+ const hoveringRef = React16.useRef(false);
4274
+ const collapsedRef = React16.useRef(collapsed);
3806
4275
  collapsedRef.current = collapsed;
3807
- const autoRef = React12.useRef(false);
4276
+ const autoRef = React16.useRef(false);
3808
4277
  const open = !collapsed || hovering;
3809
4278
  const width = open ? COLUMN_WIDTH : COLUMN_COLLAPSED_WIDTH;
3810
4279
  const setHover = (on) => {
3811
4280
  hoveringRef.current = on;
3812
4281
  setHovering(on);
3813
4282
  };
3814
- React12.useEffect(() => {
4283
+ React16.useEffect(() => {
3815
4284
  onWidth?.(width);
3816
4285
  }, [width, onWidth]);
3817
- const setOpenState = React12.useCallback((nextCollapsed) => {
4286
+ const setOpenState = React16.useCallback((nextCollapsed) => {
3818
4287
  setCollapsed(nextCollapsed);
3819
4288
  setPinned(!nextCollapsed);
3820
4289
  autoRef.current = false;
@@ -3825,7 +4294,7 @@ function CollapsibleColumn({
3825
4294
  }
3826
4295
  if (nextCollapsed) setHover(false);
3827
4296
  }, [storageKey, pinnedKey]);
3828
- React12.useEffect(() => {
4297
+ React16.useEffect(() => {
3829
4298
  if (squeezed === void 0) return;
3830
4299
  if (squeezed) {
3831
4300
  if (!collapsedRef.current) {
@@ -3837,8 +4306,8 @@ function CollapsibleColumn({
3837
4306
  setCollapsed(false);
3838
4307
  }
3839
4308
  }, [squeezed]);
3840
- const seen = React12.useRef(null);
3841
- React12.useEffect(() => {
4309
+ const seen = React16.useRef(null);
4310
+ React16.useEffect(() => {
3842
4311
  if (autoCollapseKey === void 0) return;
3843
4312
  if (seen.current === null) {
3844
4313
  seen.current = autoCollapseKey;
@@ -3852,14 +4321,14 @@ function CollapsibleColumn({
3852
4321
  }, autoCollapseMs);
3853
4322
  return () => clearTimeout(t);
3854
4323
  }, [autoCollapseKey, collapsed, pinned, autoCollapseMs]);
3855
- const scrollRef = React12.useRef(null);
3856
- const [hasMore, setHasMore] = React12.useState(false);
3857
- const onScroll = React12.useCallback(() => {
4324
+ const scrollRef = React16.useRef(null);
4325
+ const [hasMore, setHasMore] = React16.useState(false);
4326
+ const onScroll = React16.useCallback(() => {
3858
4327
  const el = scrollRef.current;
3859
4328
  if (!el) return;
3860
4329
  setHasMore(el.scrollHeight - el.scrollTop - el.clientHeight > 4);
3861
4330
  }, []);
3862
- React12.useEffect(() => {
4331
+ React16.useEffect(() => {
3863
4332
  onScroll();
3864
4333
  const el = scrollRef.current;
3865
4334
  if (!el) return;
@@ -3869,11 +4338,11 @@ function CollapsibleColumn({
3869
4338
  ro.disconnect();
3870
4339
  };
3871
4340
  }, [onScroll, open, children]);
3872
- const boxRef = React12.useRef(null);
3873
- const panelRef = React12.useRef(null);
3874
- const [seamed, setSeamed] = React12.useState(false);
3875
- const armedRef = React12.useRef(false);
3876
- const publish = React12.useCallback(() => {
4341
+ const boxRef = React16.useRef(null);
4342
+ const panelRef = React16.useRef(null);
4343
+ const [seamed, setSeamed] = React16.useState(false);
4344
+ const armedRef = React16.useRef(false);
4345
+ const publish = React16.useCallback(() => {
3877
4346
  if (!seamTop) return;
3878
4347
  const el = panelRef.current;
3879
4348
  const card = el?.closest(".fz-page-surface");
@@ -3896,10 +4365,10 @@ function CollapsibleColumn({
3896
4365
  });
3897
4366
  }
3898
4367
  }, [seamTop]);
3899
- React12.useEffect(() => {
4368
+ React16.useEffect(() => {
3900
4369
  publish();
3901
4370
  }, [publish, width]);
3902
- React12.useEffect(() => {
4371
+ React16.useEffect(() => {
3903
4372
  if (!seamTop) return;
3904
4373
  const el = panelRef.current;
3905
4374
  const card = el?.closest(".fz-page-surface");
@@ -4029,7 +4498,7 @@ function viewBarSubscribe(l) {
4029
4498
  };
4030
4499
  }
4031
4500
  function ViewBarHost() {
4032
- const active = React12.useSyncExternalStore(viewBarSubscribe, () => viewBarCount > 0);
4501
+ const active = React16.useSyncExternalStore(viewBarSubscribe, () => viewBarCount > 0);
4033
4502
  return /* @__PURE__ */ jsx(
4034
4503
  "div",
4035
4504
  {
@@ -4042,8 +4511,8 @@ function ViewBarHost() {
4042
4511
  );
4043
4512
  }
4044
4513
  function PageViewBar({ children }) {
4045
- const slot = React12.useSyncExternalStore(viewBarSubscribe, () => viewBarSlot);
4046
- React12.useEffect(() => {
4514
+ const slot = React16.useSyncExternalStore(viewBarSubscribe, () => viewBarSlot);
4515
+ React16.useEffect(() => {
4047
4516
  viewBarCount++;
4048
4517
  viewBarNotify();
4049
4518
  return () => {
@@ -4080,9 +4549,9 @@ function RailSections({ sections, search, collapsed }) {
4080
4549
  }
4081
4550
  var RAIL_COLLAPSED_KEY = "fayz.subnav.collapsed";
4082
4551
  function RailColumn({ className, "aria-label": ariaLabel, sections, search, footer }) {
4083
- const boxRef = React12.useRef(null);
4084
- const [squeezed, setSqueezed] = React12.useState(void 0);
4085
- React12.useEffect(() => {
4552
+ const boxRef = React16.useRef(null);
4553
+ const [squeezed, setSqueezed] = React16.useState(void 0);
4554
+ React16.useEffect(() => {
4086
4555
  if (typeof window === "undefined") return;
4087
4556
  const row = boxRef.current?.parentElement?.parentElement;
4088
4557
  if (!row) return;
@@ -4142,10 +4611,10 @@ function unpublishSubNav(id) {
4142
4611
  subNavNotify();
4143
4612
  }
4144
4613
  function useSubNavPublished() {
4145
- return React12.useSyncExternalStore(subNavSubscribe, () => published, () => published);
4614
+ return React16.useSyncExternalStore(subNavSubscribe, () => published, () => published);
4146
4615
  }
4147
4616
  function useSubNavHost() {
4148
- React12.useEffect(() => {
4617
+ React16.useEffect(() => {
4149
4618
  subNavHosts++;
4150
4619
  subNavNotify();
4151
4620
  return () => {
@@ -4155,7 +4624,7 @@ function useSubNavHost() {
4155
4624
  }, []);
4156
4625
  }
4157
4626
  function useHasSubNavHost() {
4158
- return React12.useSyncExternalStore(subNavSubscribe, () => subNavHosts > 0, () => false);
4627
+ return React16.useSyncExternalStore(subNavSubscribe, () => subNavHosts > 0, () => false);
4159
4628
  }
4160
4629
  function SubNavBand({ sections, "aria-label": ariaLabel, className }) {
4161
4630
  const items = sections.flatMap((s) => s.items);
@@ -4187,13 +4656,13 @@ function SubNavBandHost({ leading, label }) {
4187
4656
  );
4188
4657
  }
4189
4658
  function PageSubNav({ items, sections, search, footer, style, "aria-label": ariaLabel }) {
4190
- const id = React12.useId();
4659
+ const id = React16.useId();
4191
4660
  const hasHost = useHasSubNavHost();
4192
4661
  const resolved = sections ?? (items ? [{ items }] : []);
4193
- const ref = React12.useRef(resolved);
4662
+ const ref = React16.useRef(resolved);
4194
4663
  ref.current = resolved;
4195
4664
  const signature = JSON.stringify(resolved.map((s) => [s.key, s.heading, s.items.map((i) => [i.id, i.label, i.icon, !!i.active, !!i.premium])]));
4196
- React12.useEffect(() => {
4665
+ React16.useEffect(() => {
4197
4666
  publishSubNav({ id, label: ariaLabel, sections: ref.current });
4198
4667
  return () => unpublishSubNav(id);
4199
4668
  }, [id, ariaLabel, signature]);
@@ -4221,16 +4690,16 @@ function PremiumBadge({ className }) {
4221
4690
  const tip = t("upgrade.badgeTooltip");
4222
4691
  return /* @__PURE__ */ jsx("span", { title: tip, "aria-label": tip, className: cn("inline-flex shrink-0", className), children: /* @__PURE__ */ jsx(Crown, { className: "h-3.5 w-3.5 text-amber-500", "aria-hidden": true }) });
4223
4692
  }
4224
- var ModuleLayoutContext = React12.createContext("rail");
4693
+ var ModuleLayoutContext = React16.createContext("rail");
4225
4694
  function ModuleLayoutProvider({ variant, children }) {
4226
4695
  return /* @__PURE__ */ jsx(ModuleLayoutContext.Provider, { value: variant, children });
4227
4696
  }
4228
4697
  function useModuleLayout() {
4229
- return React12.useContext(ModuleLayoutContext);
4698
+ return React16.useContext(ModuleLayoutContext);
4230
4699
  }
4231
4700
  function RailNavItem({ item, collapsed }) {
4232
- const [expanded, setExpanded] = React12.useState(false);
4233
- React12.useEffect(() => {
4701
+ const [expanded, setExpanded] = React16.useState(false);
4702
+ React16.useEffect(() => {
4234
4703
  if (collapsed) setExpanded(false);
4235
4704
  }, [collapsed]);
4236
4705
  const Icon = item.icon ? ICON_MAP[item.icon] ?? null : null;
@@ -4297,9 +4766,9 @@ function defaultChildOf(item) {
4297
4766
  return kids.find((c) => c.defaultChild) ?? kids.find((c) => /(^|-)list$/i.test(c.id)) ?? kids.find((c) => !/(^|-)(new|novo|nova|create)$/i.test(c.id)) ?? kids[0];
4298
4767
  }
4299
4768
  function MobileTabs({ nav }) {
4300
- const scrollRef = React12.useRef(null);
4301
- const [expandedId, setExpandedId] = React12.useState(null);
4302
- React12.useEffect(() => {
4769
+ const scrollRef = React16.useRef(null);
4770
+ const [expandedId, setExpandedId] = React16.useState(null);
4771
+ React16.useEffect(() => {
4303
4772
  const container = scrollRef.current;
4304
4773
  if (!container) return;
4305
4774
  const activeEl = container.querySelector('[data-active="true"]');
@@ -4372,12 +4841,12 @@ function MobileTabs({ nav }) {
4372
4841
  })()
4373
4842
  ] });
4374
4843
  }
4375
- var BackStyleContext = React12.createContext("link");
4844
+ var BackStyleContext = React16.createContext("link");
4376
4845
  function BackStyleProvider({ style, children }) {
4377
4846
  return /* @__PURE__ */ jsx(BackStyleContext.Provider, { value: style, children });
4378
4847
  }
4379
4848
  function useBackStyle() {
4380
- return React12.useContext(BackStyleContext);
4849
+ return React16.useContext(BackStyleContext);
4381
4850
  }
4382
4851
  function SubpageHeader({ title, subtitle, description, icon, onBack, parentLabel, actions, backStyle, inline }) {
4383
4852
  const t = useTranslation();
@@ -4533,8 +5002,8 @@ function ModuleHeader({ nav }) {
4533
5002
  function ModulePage({ title: _title, subtitle, nav, children, className, headerAction, showHeader = true, sidebarFooter, navVariant, viewKey, direction, navFilterPlaceholder }) {
4534
5003
  const ctxVariant = useModuleLayout();
4535
5004
  const variant = navVariant ?? ctxVariant;
4536
- const [navQuery, setNavQuery] = React12.useState("");
4537
- const filteredNav = React12.useMemo(() => {
5005
+ const [navQuery, setNavQuery] = React16.useState("");
5006
+ const filteredNav = React16.useMemo(() => {
4538
5007
  const q = navQuery.trim().toLowerCase();
4539
5008
  if (!q) return nav;
4540
5009
  const hit = (label) => label.toLowerCase().includes(q);
@@ -4546,7 +5015,7 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
4546
5015
  }, [nav, navQuery]);
4547
5016
  const transitionKey = viewKey ?? "view";
4548
5017
  const onSubpage = useHasPageHeaderBack();
4549
- const activeLabel = React12.useMemo(() => {
5018
+ const activeLabel = React16.useMemo(() => {
4550
5019
  if (onSubpage) return null;
4551
5020
  for (const item of nav) {
4552
5021
  const kid = item.children?.find((c) => c.active);
@@ -4587,6 +5056,6 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
4587
5056
  ] });
4588
5057
  }
4589
5058
 
4590
- export { AppShell, BackStyleProvider, BottomSheet, COLUMN_WIDTH, CollapsibleColumn, HeaderTabs, Hint, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, ModuleLayoutProvider, ModulePage, NavTransitionProvider, PageHeader, PageHeaderActions, PageHeaderCrumb, PageHeaderOutlet, PageRail, PageSubNav, PageTabs, PageTitlePortal, PageTrail, PageTransition, PageViewBar, RailColumn, RailNavItem, SUB_NAV_STYLE, SaveBar, SaveBarProvider, SheetCard, SheetRow, ShellSearch, Sidebar, SubpageHeader, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Topbar, ViewTabs, bottomNavReachesAll, isCreateRoute, navigateToCrumb, useBackHandler, useBackStyle, useCrossModuleBack, useCurrentRouteHref, useHasPageActions, useHasPageHeaderBack, useHasPageHeaderHost, useHasPageHeaderOutlet, useLayoutStore, useModalHost, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useModuleViewLabel, useNavTransition, usePageHeader, usePageHeaderClaimed, usePageHeaderHost, usePageTrail, usePageTrailParent, usePublishModuleViewLabel, useRailRow, useRegisterPageActions, useSaveBar, useSaveBarVisible, useSheetClose, useSheetDrag, useTrailBack };
4591
- //# sourceMappingURL=chunk-UKMRHO5B.js.map
4592
- //# sourceMappingURL=chunk-UKMRHO5B.js.map
5059
+ export { AppShell, BackStyleProvider, BottomSheet, COLUMN_WIDTH, CollapsibleColumn, Dropdown, DropdownCheckboxItem, DropdownContent, DropdownGroup, DropdownItem, DropdownLabel, DropdownPortal, DropdownRadioGroup, DropdownRadioItem, DropdownSeparator, DropdownShortcut, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownTrigger, HeaderTabs, Hint, MobileScrim, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, ModuleLayoutProvider, ModulePage, NavTransitionProvider, PageActionBar, PageHeader, PageHeaderActions, PageHeaderCrumb, PageHeaderOutlet, PageRail, PageSubNav, PageTabs, PageTitlePortal, PageTrail, PageTransition, PageViewBar, RailColumn, RailNavItem, SUB_NAV_STYLE, SaveBar, SaveBarProvider, SheetCard, SheetRow, ShellSearch, Sidebar, SubpageHeader, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Topbar, ViewTabs, WIDE_QUERY, bottomNavReachesAll, isCreateRoute, navigateToCrumb, setActionsMenuLabel, useBackHandler, useBackStyle, useCrossModuleBack, useCurrentRouteHref, useHasPageActions, useHasPageHeaderBack, useHasPageHeaderHost, useHasPageHeaderOutlet, useIsWide, useLayoutStore, useModalHost, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useModuleViewLabel, useNavTransition, usePageHeader, usePageHeaderClaimed, usePageHeaderHost, usePageTrail, usePageTrailParent, usePublishModuleViewLabel, useRailRow, useRegisterPageActions, useSaveBar, useSaveBarVisible, useSheetClose, useSheetDrag, useTrailBack };
5060
+ //# sourceMappingURL=chunk-L6PNGGHM.js.map
5061
+ //# sourceMappingURL=chunk-L6PNGGHM.js.map