@sckyzo/cosmos-react 0.0.3 → 0.2.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.
package/dist/index.cjs CHANGED
@@ -170,6 +170,7 @@ var Shell = ({
170
170
  defaultSidebarCollapsed = false,
171
171
  sidebarCollapsed: controlledCollapsed,
172
172
  onSidebarToggle,
173
+ collapseControl = "topbar",
173
174
  className
174
175
  }) => {
175
176
  const [internalCollapsed, setInternalCollapsed] = react.useState(defaultSidebarCollapsed);
@@ -179,12 +180,22 @@ var Shell = ({
179
180
  if (controlledCollapsed === void 0) setInternalCollapsed(next);
180
181
  onSidebarToggle?.(next);
181
182
  };
182
- const enhancedTopbar = topbar && sidebar ? react.cloneElement(topbar, {
183
- sidebarCollapsed: topbar.props.sidebarCollapsed ?? collapsed,
184
- onToggleSidebar: topbar.props.onToggleSidebar ?? handleToggle
185
- }) : topbar;
183
+ const inSidebar = collapseControl === "sidebar";
184
+ const enhancedTopbar = topbar && sidebar ? react.cloneElement(
185
+ topbar,
186
+ inSidebar ? (
187
+ // The control moved to the sidebar: no hamburger unless asked for.
188
+ { sidebarCollapsed: topbar.props.sidebarCollapsed ?? null }
189
+ ) : {
190
+ sidebarCollapsed: topbar.props.sidebarCollapsed ?? collapsed,
191
+ onToggleSidebar: topbar.props.onToggleSidebar ?? handleToggle
192
+ }
193
+ ) : topbar;
186
194
  const enhancedSidebar = sidebar ? react.cloneElement(sidebar, {
187
- collapsed: sidebar.props.collapsed ?? collapsed
195
+ collapsed: sidebar.props.collapsed ?? collapsed,
196
+ ...inSidebar && {
197
+ onCollapsedChange: sidebar.props.onCollapsedChange ?? handleToggle
198
+ }
188
199
  }) : sidebar;
189
200
  return /* @__PURE__ */ jsxRuntime.jsxs(
190
201
  "div",
@@ -269,17 +280,200 @@ var Topbar = ({
269
280
  ]
270
281
  }
271
282
  );
283
+ var PopoverContext = react.createContext(null);
284
+ var useCtx = () => {
285
+ const ctx = react.useContext(PopoverContext);
286
+ if (!ctx) throw new Error("Popover.* must be used inside <Popover>");
287
+ return ctx;
288
+ };
289
+ var PopoverRoot = ({
290
+ open: openProp,
291
+ defaultOpen = false,
292
+ onOpenChange,
293
+ children
294
+ }) => {
295
+ const [internalOpen, setInternalOpen] = react.useState(defaultOpen);
296
+ const isControlled = openProp !== void 0;
297
+ const open = isControlled ? openProp : internalOpen;
298
+ const triggerRef = react.useRef(null);
299
+ const [triggerRect, setTriggerRect] = react.useState(null);
300
+ const refreshRect = react.useCallback(() => {
301
+ if (triggerRef.current) setTriggerRect(triggerRef.current.getBoundingClientRect());
302
+ }, []);
303
+ const setOpen = react.useCallback(
304
+ (v) => {
305
+ if (v) refreshRect();
306
+ if (!isControlled) setInternalOpen(v);
307
+ onOpenChange?.(v);
308
+ },
309
+ [isControlled, onOpenChange, refreshRect]
310
+ );
311
+ react.useEffect(() => {
312
+ if (!open) return;
313
+ const handler = () => refreshRect();
314
+ window.addEventListener("resize", handler);
315
+ window.addEventListener("scroll", handler, true);
316
+ const observer = new ResizeObserver(handler);
317
+ if (triggerRef.current) observer.observe(triggerRef.current, { box: "border-box" });
318
+ return () => {
319
+ window.removeEventListener("resize", handler);
320
+ window.removeEventListener("scroll", handler, true);
321
+ observer.disconnect();
322
+ };
323
+ }, [open, refreshRect]);
324
+ react.useEffect(() => {
325
+ if (!open) return;
326
+ const handler = (e) => {
327
+ if (e.key === "Escape") setOpen(false);
328
+ };
329
+ document.addEventListener("keydown", handler);
330
+ return () => document.removeEventListener("keydown", handler);
331
+ }, [open, setOpen]);
332
+ return /* @__PURE__ */ jsxRuntime.jsx(PopoverContext.Provider, { value: { open, setOpen, triggerRef, triggerRect, refreshRect }, children });
333
+ };
334
+ var PopoverTrigger = react.forwardRef(function PopoverTrigger2({ onClick, children, ...rest }, forwardedRef) {
335
+ const { open, setOpen, triggerRef, refreshRect } = useCtx();
336
+ const setRef = (node) => {
337
+ triggerRef.current = node;
338
+ if (typeof forwardedRef === "function") forwardedRef(node);
339
+ else if (forwardedRef) forwardedRef.current = node;
340
+ };
341
+ react.useEffect(() => {
342
+ if (open) refreshRect();
343
+ }, [open, refreshRect]);
344
+ return /* @__PURE__ */ jsxRuntime.jsx(
345
+ "button",
346
+ {
347
+ ref: setRef,
348
+ type: "button",
349
+ "aria-haspopup": "dialog",
350
+ "aria-expanded": open,
351
+ onClick: (e) => {
352
+ onClick?.(e);
353
+ setOpen(!open);
354
+ },
355
+ ...rest,
356
+ children
357
+ }
358
+ );
359
+ });
360
+ var VIEWPORT_MARGIN = 16;
361
+ var positionStyle = (position, align, rect, offset) => {
362
+ const left = align === "end" ? rect.right : rect.left + rect.width / 2;
363
+ const shiftX = align === "end" ? "-100%" : "-50%";
364
+ const maxWidth = align === "end" ? rect.right - VIEWPORT_MARGIN : void 0;
365
+ switch (position) {
366
+ case "top":
367
+ return {
368
+ top: rect.top - offset,
369
+ left,
370
+ maxWidth,
371
+ transform: `translate(${shiftX}, -100%)`
372
+ };
373
+ case "right":
374
+ return {
375
+ top: rect.top + rect.height / 2,
376
+ left: rect.right + offset,
377
+ transform: "translateY(-50%)"
378
+ };
379
+ case "left":
380
+ return {
381
+ top: rect.top + rect.height / 2,
382
+ left: rect.left - offset,
383
+ transform: "translate(-100%, -50%)"
384
+ };
385
+ case "bottom":
386
+ default:
387
+ return {
388
+ top: rect.bottom + offset,
389
+ left,
390
+ maxWidth,
391
+ transform: `translateX(${shiftX})`
392
+ };
393
+ }
394
+ };
395
+ var arrowStyle = (position, align, rect) => {
396
+ const base = {
397
+ position: "absolute",
398
+ width: 8,
399
+ height: 8,
400
+ transform: "rotate(45deg)"
401
+ };
402
+ const x = align === "end" ? { right: rect.width / 2 - 1, marginRight: -4 } : { left: "50%", marginLeft: -4 };
403
+ switch (position) {
404
+ case "top":
405
+ return { ...base, bottom: -4, ...x };
406
+ case "right":
407
+ return { ...base, left: -4, top: "50%", marginTop: -4 };
408
+ case "left":
409
+ return { ...base, right: -4, top: "50%", marginTop: -4 };
410
+ case "bottom":
411
+ default:
412
+ return { ...base, top: -4, ...x };
413
+ }
414
+ };
415
+ var PopoverContent = ({
416
+ position = "bottom",
417
+ align = "center",
418
+ "aria-label": ariaLabel,
419
+ offset = 8,
420
+ arrow = false,
421
+ width = "w-64",
422
+ className,
423
+ children
424
+ }) => {
425
+ const { open, setOpen, triggerRect } = useCtx();
426
+ if (!open || !triggerRect) return null;
427
+ return reactDom.createPortal(
428
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
429
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-[9998]", onClick: () => setOpen(false) }),
430
+ /* @__PURE__ */ jsxRuntime.jsxs(
431
+ "div",
432
+ {
433
+ role: "dialog",
434
+ "aria-label": ariaLabel,
435
+ style: positionStyle(position, align, triggerRect, offset),
436
+ className: clsx.clsx(
437
+ "fixed z-[9999] rounded-xl border border-gray-200 bg-white p-4 text-sm shadow-xl dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100",
438
+ width,
439
+ className
440
+ ),
441
+ children: [
442
+ arrow && /* @__PURE__ */ jsxRuntime.jsx(
443
+ "span",
444
+ {
445
+ "aria-hidden": true,
446
+ style: arrowStyle(position, align, triggerRect),
447
+ className: "border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900"
448
+ }
449
+ ),
450
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children })
451
+ ]
452
+ }
453
+ )
454
+ ] }),
455
+ document.body
456
+ );
457
+ };
458
+ var Popover = Object.assign(PopoverRoot, {
459
+ Trigger: PopoverTrigger,
460
+ Content: PopoverContent
461
+ });
272
462
  var SidebarContext = react.createContext({ collapsed: false });
273
463
  var useSidebarCollapsed = (override) => {
274
464
  const ctx = react.useContext(SidebarContext);
275
465
  return override ?? ctx.collapsed;
276
466
  };
467
+ var SidebarDepthContext = react.createContext(0);
468
+ var rowPadding = (depth) => 12 + depth * 20;
469
+ var guideLeft = (depth) => 8 + rowPadding(depth) + 10;
277
470
  var SidebarRoot = ({
278
471
  collapsed = false,
279
472
  width = 264,
280
473
  collapsedWidth = 72,
281
474
  children,
282
475
  footer,
476
+ onCollapsedChange,
283
477
  className
284
478
  }) => /* @__PURE__ */ jsxRuntime.jsx(SidebarContext.Provider, { value: { collapsed }, children: /* @__PURE__ */ jsxRuntime.jsxs(
285
479
  "nav",
@@ -293,10 +487,32 @@ var SidebarRoot = ({
293
487
  ),
294
488
  children: [
295
489
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-x-hidden overflow-y-auto", children }),
296
- footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 overflow-hidden border-t border-[var(--color-border)] p-3", children: footer })
490
+ footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 overflow-hidden border-t border-[var(--color-border)] p-3", children: footer }),
491
+ onCollapsedChange && /* @__PURE__ */ jsxRuntime.jsx(CollapseButton, { collapsed, onClick: () => onCollapsedChange(!collapsed) })
297
492
  ]
298
493
  }
299
494
  ) });
495
+ var CollapseButton = ({ collapsed, onClick }) => {
496
+ const Icon2 = collapsed ? lucideReact.PanelLeftOpen : lucideReact.PanelLeftClose;
497
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-t border-[var(--color-border)] py-2", children: /* @__PURE__ */ jsxRuntime.jsxs(
498
+ "button",
499
+ {
500
+ type: "button",
501
+ onClick,
502
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
503
+ "aria-expanded": !collapsed,
504
+ title: collapsed ? "Expand sidebar" : void 0,
505
+ className: clsx.clsx(
506
+ "focus-visible:ring-brand-500 mx-2 flex w-[calc(100%-1rem)] items-center gap-3 rounded-lg py-2 text-sm font-medium text-[var(--color-text-secondary)] transition-colors hover:bg-black/5 hover:text-[var(--color-text-primary)] focus:outline-none focus-visible:ring-2 dark:hover:bg-white/5",
507
+ collapsed ? "justify-center px-2" : "px-3"
508
+ ),
509
+ children: [
510
+ /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-5 w-5 shrink-0", "aria-hidden": true }),
511
+ !collapsed && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Collapse" })
512
+ ]
513
+ }
514
+ ) });
515
+ };
300
516
  var SidebarBrand = ({
301
517
  logo,
302
518
  title,
@@ -339,17 +555,19 @@ var SidebarItem = ({
339
555
  onClick,
340
556
  badge,
341
557
  collapsed: collapsedProp,
342
- depth = 0
558
+ depth: depthProp
343
559
  }) => {
344
560
  const collapsed = useSidebarCollapsed(collapsedProp);
561
+ const contextDepth = react.useContext(SidebarDepthContext);
562
+ const depth = depthProp ?? contextDepth;
345
563
  const baseClass = clsx.clsx(
346
564
  "group mx-2 flex items-center gap-3 rounded-lg py-2 text-sm font-medium transition-colors",
347
565
  collapsed ? "justify-center px-2" : "px-3",
348
- active ? "bg-brand-500/10 text-brand-500" : "text-[var(--color-text-secondary)] hover:bg-black/5 hover:text-[var(--color-text-primary)] dark:hover:bg-white/5"
566
+ active ? "bg-brand-500/10 text-brand-600 dark:text-brand-400" : "text-[var(--color-text-secondary)] hover:bg-black/5 hover:text-[var(--color-text-primary)] dark:hover:bg-white/5"
349
567
  );
350
- const style = !collapsed && depth > 0 ? { paddingLeft: 12 + depth * 20 } : void 0;
568
+ const style = !collapsed && depth > 0 ? { paddingLeft: rowPadding(depth) } : void 0;
351
569
  const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
352
- /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: clsx.clsx("h-5 w-5 shrink-0", active && "text-brand-500") }),
570
+ /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-5 w-5 shrink-0" }),
353
571
  !collapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
354
572
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: label }),
355
573
  badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: badge })
@@ -364,6 +582,7 @@ var SidebarItem = ({
364
582
  className: baseClass,
365
583
  style,
366
584
  "aria-current": active ? "page" : void 0,
585
+ "data-sidebar-item": "",
367
586
  children: content
368
587
  }
369
588
  );
@@ -377,10 +596,15 @@ var SidebarItem = ({
377
596
  className: clsx.clsx(baseClass, "w-[calc(100%-1rem)] text-left"),
378
597
  style,
379
598
  "aria-current": active ? "page" : void 0,
599
+ "data-sidebar-item": "",
380
600
  children: content
381
601
  }
382
602
  );
383
603
  };
604
+ var SUBMENU_ROW = (active) => clsx.clsx(
605
+ "group mx-2 flex w-[calc(100%-1rem)] items-center rounded-lg py-2 text-sm font-medium transition-colors",
606
+ active ? "bg-brand-500/10 text-brand-600 dark:text-brand-400" : "text-[var(--color-text-secondary)] hover:bg-black/5 hover:text-[var(--color-text-primary)] dark:hover:bg-white/5"
607
+ );
384
608
  var SidebarSubMenu = ({
385
609
  icon: Icon2,
386
610
  label,
@@ -391,20 +615,35 @@ var SidebarSubMenu = ({
391
615
  children
392
616
  }) => {
393
617
  const collapsed = useSidebarCollapsed(collapsedProp);
618
+ const depth = react.useContext(SidebarDepthContext);
394
619
  const [open, setOpen] = react.useState(defaultOpen || active);
620
+ const [flyoutOpen, setFlyoutOpen] = react.useState(false);
395
621
  if (collapsed) {
396
- return /* @__PURE__ */ jsxRuntime.jsx(
397
- "button",
398
- {
399
- type: "button",
400
- title: label,
401
- className: clsx.clsx(
402
- "group mx-2 flex w-[calc(100%-1rem)] items-center justify-center rounded-lg px-2 py-2 text-sm font-medium transition-colors",
403
- active ? "bg-brand-500/10 text-brand-500" : "text-[var(--color-text-secondary)] hover:bg-black/5 hover:text-[var(--color-text-primary)] dark:hover:bg-white/5"
404
- ),
405
- children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: clsx.clsx("h-5 w-5 shrink-0", active && "text-brand-500") })
406
- }
407
- );
622
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: flyoutOpen, onOpenChange: setFlyoutOpen, children: [
623
+ /* @__PURE__ */ jsxRuntime.jsx(
624
+ Popover.Trigger,
625
+ {
626
+ title: label,
627
+ "aria-label": label,
628
+ className: clsx.clsx(SUBMENU_ROW(active), "justify-center px-2"),
629
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-5 w-5 shrink-0" })
630
+ }
631
+ ),
632
+ /* @__PURE__ */ jsxRuntime.jsx(Popover.Content, { position: "right", "aria-label": label, width: "w-64", className: "p-2!", children: /* @__PURE__ */ jsxRuntime.jsx(SidebarContext.Provider, { value: { collapsed: false }, children: /* @__PURE__ */ jsxRuntime.jsxs(SidebarDepthContext.Provider, { value: 0, children: [
633
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pt-1 pb-2 text-xs font-semibold tracking-wider text-[var(--color-text-muted)] uppercase", children: label }),
634
+ /* @__PURE__ */ jsxRuntime.jsx(
635
+ "div",
636
+ {
637
+ className: "-mx-2 space-y-0.5",
638
+ onClick: (e) => {
639
+ if (e.target.closest("[data-sidebar-item]"))
640
+ setFlyoutOpen(false);
641
+ },
642
+ children
643
+ }
644
+ )
645
+ ] }) }) })
646
+ ] });
408
647
  }
409
648
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
410
649
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -413,12 +652,10 @@ var SidebarSubMenu = ({
413
652
  type: "button",
414
653
  onClick: () => setOpen((v) => !v),
415
654
  "aria-expanded": open,
416
- className: clsx.clsx(
417
- "group mx-2 flex w-[calc(100%-1rem)] items-center gap-3 rounded-lg px-3 py-2 text-left text-sm font-medium transition-colors",
418
- active ? "bg-brand-500/10 text-brand-500" : "text-[var(--color-text-secondary)] hover:bg-black/5 hover:text-[var(--color-text-primary)] dark:hover:bg-white/5"
419
- ),
655
+ className: clsx.clsx(SUBMENU_ROW(active), "gap-3 px-3 text-left"),
656
+ style: depth > 0 ? { paddingLeft: rowPadding(depth) } : void 0,
420
657
  children: [
421
- /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: clsx.clsx("h-5 w-5 shrink-0", active && "text-brand-500") }),
658
+ /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-5 w-5 shrink-0" }),
422
659
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: label }),
423
660
  badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: badge }),
424
661
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -433,7 +670,17 @@ var SidebarSubMenu = ({
433
670
  ]
434
671
  }
435
672
  ),
436
- open && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 space-y-0.5", children })
673
+ open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative mt-0.5 space-y-0.5", children: [
674
+ /* @__PURE__ */ jsxRuntime.jsx(
675
+ "span",
676
+ {
677
+ "aria-hidden": true,
678
+ className: "absolute top-0 bottom-0 w-px bg-[var(--color-border)]",
679
+ style: { left: guideLeft(depth) }
680
+ }
681
+ ),
682
+ /* @__PURE__ */ jsxRuntime.jsx(SidebarDepthContext.Provider, { value: depth + 1, children })
683
+ ] })
437
684
  ] });
438
685
  };
439
686
  var SidebarGroup = ({
@@ -453,7 +700,7 @@ var SidebarGroup = ({
453
700
  {
454
701
  type: "button",
455
702
  onClick: () => setOpen((v) => !v),
456
- className: "mx-2 flex w-[calc(100%-1rem)] items-center gap-2 px-3 py-1.5 text-[10px] font-bold tracking-wider text-[var(--color-text-muted)] uppercase hover:text-[var(--color-text-secondary)]",
703
+ className: "text-3xs mx-2 flex w-[calc(100%-1rem)] items-center gap-2 px-3 py-1.5 font-bold tracking-wider text-[var(--color-text-muted)] uppercase hover:text-[var(--color-text-secondary)]",
457
704
  children: [
458
705
  open ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3 w-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-3 w-3" }),
459
706
  label
@@ -466,7 +713,7 @@ var SidebarGroup = ({
466
713
  var SidebarSection = ({ label, collapsed: collapsedProp, children }) => {
467
714
  const collapsed = useSidebarCollapsed(collapsedProp);
468
715
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-2 border-t border-[var(--color-border)] pt-2", children: [
469
- label && !collapsed && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-5 py-1.5 text-[10px] font-bold tracking-wider text-[var(--color-text-muted)] uppercase", children: label }),
716
+ label && !collapsed && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-3xs px-5 py-1.5 font-bold tracking-wider text-[var(--color-text-muted)] uppercase", children: label }),
470
717
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children })
471
718
  ] });
472
719
  };
@@ -479,7 +726,7 @@ Sidebar.SubMenu = SidebarSubMenu;
479
726
  var PageBreadcrumb = ({ items, className }) => /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Breadcrumb", className, children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex flex-wrap items-center gap-1 text-sm", children: items.map((item, i) => {
480
727
  const isFirst = i === 0;
481
728
  const isLast = i === items.length - 1;
482
- const linkClass = "hover:text-brand-500 dark:hover:text-brand-400 flex items-center gap-1 text-[var(--color-text-secondary)] transition-colors";
729
+ const linkClass = "hover:text-brand-600 dark:hover:text-brand-400 flex items-center gap-1 text-[var(--color-text-secondary)] transition-colors";
483
730
  const renderInner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
484
731
  isFirst && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Home, { className: "h-4 w-4" }),
485
732
  item.label
@@ -489,17 +736,22 @@ var PageBreadcrumb = ({ items, className }) => /* @__PURE__ */ jsxRuntime.jsx("n
489
736
  isLast ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-[var(--color-text-primary)]", children: item.label }) : item.onClick ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: item.onClick, className: linkClass, children: renderInner }) : /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.href ?? "#", className: clsx.clsx(linkClass), children: renderInner })
490
737
  ] }, item.label);
491
738
  }) }) });
492
- var Root3 = ({ title, description, breadcrumb, meta, actions, className }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-start justify-between gap-4 ${className ?? ""}`, children: [
493
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
494
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-[var(--color-text-primary)]", children: title }),
495
- breadcrumb && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1.5", children: breadcrumb }),
496
- !breadcrumb && description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-[var(--color-text-secondary)]", children: description }),
497
- meta && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex flex-wrap items-center gap-x-6 gap-y-1 text-sm text-[var(--color-text-secondary)]", children: meta })
498
- ] }),
499
- actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
500
- ] });
739
+ var Root3 = ({ title, description, breadcrumb, meta, actions, className }) => (
740
+ // The title column asks for 16rem: when that and the actions don't both fit
741
+ // (a phone, a narrow pane), the actions wrap under the title instead of
742
+ // squeezing it until its words run under the buttons.
743
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-wrap items-start justify-between gap-4 ${className ?? ""}`, children: [
744
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 grow basis-64", children: [
745
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-[var(--color-text-primary)]", children: title }),
746
+ breadcrumb && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1.5", children: breadcrumb }),
747
+ !breadcrumb && description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-[var(--color-text-secondary)]", children: description }),
748
+ meta && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex flex-wrap items-center gap-x-6 gap-y-1 text-sm text-[var(--color-text-secondary)]", children: meta })
749
+ ] }),
750
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
751
+ ] })
752
+ );
501
753
  var MetaItem = ({ icon: Icon2, children }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center", children: [
502
- Icon2 && /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "mr-1.5 size-5 text-[var(--color-text-muted)]", "aria-hidden": true }),
754
+ Icon2 && /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "mr-1.5 size-5 shrink-0 text-[var(--color-text-muted)]", "aria-hidden": true }),
503
755
  children
504
756
  ] });
505
757
  var PageHeader = Object.assign(Root3, { MetaItem });
@@ -575,16 +827,6 @@ var SectionCard = ({
575
827
  }
576
828
  );
577
829
  };
578
- var PageCard = ({ children, className }) => /* @__PURE__ */ jsxRuntime.jsx(
579
- "div",
580
- {
581
- className: clsx.clsx(
582
- "min-h-[60vh] rounded-2xl border border-[var(--color-border)] bg-[var(--color-bg-panel)] px-5 py-8 xl:px-10 xl:py-12",
583
- className
584
- ),
585
- children
586
- }
587
- );
588
830
  var ContentNarrow = ({ children, maxWidth = 680, className }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `mx-auto w-full ${className ?? ""}`, style: { maxWidth }, children });
589
831
  var ColBox = ({ label, height = 80, className }) => /* @__PURE__ */ jsxRuntime.jsx(
590
832
  "div",
@@ -623,7 +865,7 @@ var ErrorState = ({
623
865
  {
624
866
  type: "button",
625
867
  onClick: onRetry,
626
- className: "text-brand-500 hover:text-brand-600 text-xs font-medium hover:underline",
868
+ className: "text-brand-600 hover:text-brand-700 dark:text-brand-400 dark:hover:text-brand-300 text-xs font-medium hover:underline",
627
869
  children: "Try again"
628
870
  }
629
871
  )
@@ -689,7 +931,7 @@ var SkeletonList = ({ rows = 4, showAction = true, className }) => /* @__PURE__
689
931
  i
690
932
  )) });
691
933
  var SIZE_CLASS = {
692
- sm: "px-1.5 py-0.5 text-[10px]",
934
+ sm: "px-1.5 py-0.5 text-3xs",
693
935
  md: "px-2 py-0.5 text-xs",
694
936
  lg: "px-3 py-1 text-sm"
695
937
  };
@@ -829,7 +1071,7 @@ var StackedListItem = react.forwardRef(function StackedListItem2({ avatar, title
829
1071
  ] }),
830
1072
  (meta || trailing || isLinked && chevron) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-x-4", children: [
831
1073
  meta && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:flex sm:flex-col sm:items-end", children: meta }),
832
- trailing,
1074
+ trailing && (isLinked ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex items-center gap-x-4", children: trailing }) : trailing),
833
1075
  isLinked && chevron && /* @__PURE__ */ jsxRuntime.jsx(
834
1076
  lucideReact.ChevronRight,
835
1077
  {
@@ -875,9 +1117,9 @@ var ContentStackedListItem = react.forwardRef(
875
1117
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm/6 font-semibold text-gray-900 dark:text-white", children: titleEl }),
876
1118
  badge
877
1119
  ] }),
878
- hasMeta && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 flex items-center gap-x-2 text-xs/5 text-gray-500 dark:text-gray-400", children: react.Children.toArray(metaItems).map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
1120
+ hasMeta && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 flex items-center gap-x-2 text-xs/5 text-gray-500 dark:text-gray-400", children: react.Children.toArray(metaItems).map((item, i, items) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
879
1121
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(Dot, {}),
880
- item
1122
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: i === items.length - 1 ? "truncate" : "whitespace-nowrap", children: item })
881
1123
  ] }, i)) })
882
1124
  ] }),
883
1125
  trailing && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-none items-center gap-x-4", children: trailing })
@@ -934,7 +1176,7 @@ var NarrowStackedListHeader = react.forwardRef(
934
1176
  {
935
1177
  ref,
936
1178
  className: clsx.clsx(
937
- "border-t border-b border-t-gray-200 border-b-gray-200 bg-gray-50 px-3 py-1.5 text-sm/6 font-semibold text-gray-900 dark:border-t-white/10 dark:border-b-white/10 dark:bg-gray-800/60 dark:text-white",
1179
+ "border-t border-b border-t-gray-200 border-b-gray-200 bg-gray-50 px-3 py-1.5 text-sm/6 font-semibold text-gray-900 dark:border-t-white/10 dark:border-b-white/10 dark:bg-gray-800 dark:text-white",
938
1180
  sticky && "sticky top-0 z-10",
939
1181
  className
940
1182
  ),
@@ -957,7 +1199,8 @@ var NarrowStackedListItem = react.forwardRef(
957
1199
  ] }),
958
1200
  description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 line-clamp-2 text-sm/6 text-gray-600 dark:text-gray-400", children: description }),
959
1201
  !description && subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 truncate text-xs/5 text-gray-500 dark:text-gray-400", children: subtitle })
960
- ] })
1202
+ ] }),
1203
+ trailing && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-none items-center", children: trailing })
961
1204
  ] });
962
1205
  }
963
1206
  if (trailing) {
@@ -1058,7 +1301,7 @@ var StatusRow = ({
1058
1301
  "span",
1059
1302
  {
1060
1303
  className: clsx.clsx(
1061
- "shrink-0 rounded-full px-2 py-0.5 text-[10px] font-bold",
1304
+ "text-3xs shrink-0 rounded-full px-2 py-0.5 font-bold",
1062
1305
  STATUS_CLASS2[status]
1063
1306
  ),
1064
1307
  children: status
@@ -1163,18 +1406,21 @@ var Footer = react.forwardRef(function GridListFooter({ className, children, ...
1163
1406
  });
1164
1407
  var FooterAction = react.forwardRef(
1165
1408
  function GridListFooterAction({ index = 0, className, children, ...rest }, ref) {
1166
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("flex w-0 flex-1", index > 0 && "-ml-px"), children: /* @__PURE__ */ jsxRuntime.jsx(
1167
- "a",
1168
- {
1169
- ref,
1170
- className: clsx.clsx(
1171
- "relative inline-flex w-0 flex-1 items-center justify-center gap-x-3 rounded-bl-lg border border-transparent py-4 text-sm font-semibold text-gray-900 hover:bg-gray-50 dark:text-white dark:hover:bg-white/5",
1172
- className
1173
- ),
1174
- ...rest,
1175
- children
1176
- }
1177
- ) });
1409
+ return (
1410
+ // The cell's position picks the card corner it rounds: first bottom-left, last bottom-right.
1411
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("group/action flex w-0 flex-1", index > 0 && "-ml-px"), children: /* @__PURE__ */ jsxRuntime.jsx(
1412
+ "a",
1413
+ {
1414
+ ref,
1415
+ className: clsx.clsx(
1416
+ "relative inline-flex w-0 flex-1 items-center justify-center gap-x-3 border border-transparent py-4 text-sm font-semibold text-gray-900 group-first/action:rounded-bl-lg group-last/action:rounded-br-lg hover:bg-gray-50 dark:text-white dark:hover:bg-white/5",
1417
+ className
1418
+ ),
1419
+ ...rest,
1420
+ children
1421
+ }
1422
+ ) })
1423
+ );
1178
1424
  }
1179
1425
  );
1180
1426
  var GridList = Object.assign(Root5, {
@@ -1238,74 +1484,73 @@ var Breadcrumb = ({ items, separator = "chevron", className }) => /* @__PURE__ *
1238
1484
  );
1239
1485
  var ROOT_BG = {
1240
1486
  light: "bg-white shadow-sm border-b border-gray-200 dark:bg-gray-800 dark:border-white/10",
1241
- dark: "bg-gray-800"
1487
+ dark: "bg-gray-800 text-white"
1242
1488
  };
1243
- var ITEM_BASE = {
1244
- light: "rounded-md px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-white/5",
1245
- dark: "rounded-md px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white"
1489
+ var ITEM_BASE = "rounded-md px-3 py-2 text-sm font-medium";
1490
+ var ITEM_IDLE = {
1491
+ light: "text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-white/5",
1492
+ dark: "text-gray-300 hover:bg-gray-700 hover:text-white"
1246
1493
  };
1247
1494
  var ITEM_ACTIVE = {
1248
1495
  light: "bg-gray-100 text-gray-900 dark:bg-white/10 dark:text-white",
1249
1496
  dark: "bg-gray-900 text-white"
1250
1497
  };
1498
+ var NavbarThemeContext = react.createContext("light");
1251
1499
  var RootCmp = react.forwardRef(function NavbarRoot({ theme = "light", maxWidth = "7xl", heightClassName = "h-16", className, children, ...rest }, ref) {
1252
- return /* @__PURE__ */ jsxRuntime.jsx("nav", { ref, className: clsx.clsx(ROOT_BG[theme], className), "data-theme": theme, ...rest, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("px-4 sm:px-6 lg:px-8", maxWidth === "7xl" && "mx-auto max-w-7xl"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("flex items-center justify-between", heightClassName), children }) }) });
1500
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { ref, className: clsx.clsx(ROOT_BG[theme], className), "data-theme": theme, ...rest, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("px-4 sm:px-6 lg:px-8", maxWidth === "7xl" && "mx-auto max-w-7xl"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("flex items-center justify-between", heightClassName), children: /* @__PURE__ */ jsxRuntime.jsx(NavbarThemeContext.Provider, { value: theme, children }) }) }) });
1253
1501
  });
1254
1502
  var Brand = ({ className, children, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("flex shrink-0 items-center", className), ...rest, children });
1255
1503
  var Items = ({ className, children, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("hidden md:ml-10 md:block", className), ...rest, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-baseline space-x-4", children }) });
1256
- var Item2 = ({
1257
- active = false,
1258
- theme = "light",
1259
- className,
1260
- children,
1261
- ...rest
1262
- }) => /* @__PURE__ */ jsxRuntime.jsx(
1263
- "a",
1264
- {
1265
- "aria-current": active ? "page" : void 0,
1266
- className: clsx.clsx(ITEM_BASE[theme], active && ITEM_ACTIVE[theme], className),
1267
- ...rest,
1268
- children
1269
- }
1270
- );
1504
+ var Item2 = ({ active = false, theme, className, children, ...rest }) => {
1505
+ const inherited = react.useContext(NavbarThemeContext);
1506
+ const resolved = theme ?? inherited;
1507
+ return /* @__PURE__ */ jsxRuntime.jsx(
1508
+ "a",
1509
+ {
1510
+ "aria-current": active ? "page" : void 0,
1511
+ className: clsx.clsx(ITEM_BASE, active ? ITEM_ACTIVE[resolved] : ITEM_IDLE[resolved], className),
1512
+ ...rest,
1513
+ children
1514
+ }
1515
+ );
1516
+ };
1271
1517
  var Actions = ({ className, children, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("hidden md:block", className), ...rest, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-4 flex items-center gap-3 md:ml-6", children }) });
1272
- var MobileMenuButton = ({
1273
- theme = "light",
1274
- className,
1275
- children,
1276
- ...rest
1277
- }) => /* @__PURE__ */ jsxRuntime.jsx(
1278
- "button",
1279
- {
1280
- type: "button",
1281
- "aria-label": "Toggle menu",
1282
- className: clsx.clsx(
1283
- "relative inline-flex size-10 items-center justify-center rounded-md md:hidden",
1284
- theme === "dark" ? "text-gray-400 hover:bg-gray-700 hover:text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-white" : "text-gray-500 hover:bg-gray-100 hover:text-gray-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-indigo-500",
1285
- className
1286
- ),
1287
- ...rest,
1288
- children: children ?? /* @__PURE__ */ jsxRuntime.jsx(
1289
- "svg",
1290
- {
1291
- className: "size-6",
1292
- fill: "none",
1293
- viewBox: "0 0 24 24",
1294
- strokeWidth: "1.5",
1295
- stroke: "currentColor",
1296
- "aria-hidden": true,
1297
- children: /* @__PURE__ */ jsxRuntime.jsx(
1298
- "path",
1299
- {
1300
- strokeLinecap: "round",
1301
- strokeLinejoin: "round",
1302
- d: "M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"
1303
- }
1304
- )
1305
- }
1306
- )
1307
- }
1308
- );
1518
+ var MobileMenuButton = ({ theme, className, children, ...rest }) => {
1519
+ const inherited = react.useContext(NavbarThemeContext);
1520
+ const resolved = theme ?? inherited;
1521
+ return /* @__PURE__ */ jsxRuntime.jsx(
1522
+ "button",
1523
+ {
1524
+ type: "button",
1525
+ "aria-label": "Toggle menu",
1526
+ className: clsx.clsx(
1527
+ "relative inline-flex size-10 items-center justify-center rounded-md md:hidden",
1528
+ resolved === "dark" ? "text-gray-400 hover:bg-gray-700 hover:text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-white" : "focus-visible:outline-brand-500 text-gray-500 hover:bg-gray-100 hover:text-gray-700 focus-visible:outline focus-visible:outline-2 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-white",
1529
+ className
1530
+ ),
1531
+ ...rest,
1532
+ children: children ?? /* @__PURE__ */ jsxRuntime.jsx(
1533
+ "svg",
1534
+ {
1535
+ className: "size-6",
1536
+ fill: "none",
1537
+ viewBox: "0 0 24 24",
1538
+ strokeWidth: "1.5",
1539
+ stroke: "currentColor",
1540
+ "aria-hidden": true,
1541
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1542
+ "path",
1543
+ {
1544
+ strokeLinecap: "round",
1545
+ strokeLinejoin: "round",
1546
+ d: "M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"
1547
+ }
1548
+ )
1549
+ }
1550
+ )
1551
+ }
1552
+ );
1553
+ };
1309
1554
  var Navbar = Object.assign(RootCmp, {
1310
1555
  Brand,
1311
1556
  Items,
@@ -1622,7 +1867,7 @@ var StepperRoot = ({
1622
1867
  react.isValidElement
1623
1868
  );
1624
1869
  const effectiveOrientation = variant === "indicators" ? orientation : "horizontal";
1625
- const rootClass = variant === "panels" ? "divide-y divide-gray-200 overflow-hidden rounded-md border border-gray-300 md:flex md:divide-x md:divide-y-0 dark:divide-white/10 dark:border-white/10" : variant === "bars" ? "space-y-4 md:flex md:space-y-0 md:space-x-8" : effectiveOrientation === "horizontal" ? "flex w-full items-start" : "flex flex-col";
1870
+ const rootClass = variant === "panels" ? "divide-y divide-gray-200 overflow-hidden rounded-md border border-gray-300 md:flex md:divide-y-0 dark:divide-white/10 dark:border-white/10" : variant === "bars" ? "space-y-4 md:flex md:space-y-0 md:space-x-8" : effectiveOrientation === "horizontal" ? "flex w-full items-start" : "flex flex-col";
1626
1871
  return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: clsx.clsx(rootClass, className), "aria-label": "Progress", children: steps.map((step, i) => {
1627
1872
  const status = i < current ? "done" : i === current ? "active" : "pending";
1628
1873
  return react.cloneElement(step, {
@@ -1707,18 +1952,25 @@ var VARIANT_CLASS = {
1707
1952
  soft: "bg-brand-50 text-brand-700 hover:bg-brand-100 disabled:opacity-50 disabled:cursor-not-allowed dark:bg-brand-500/10 dark:text-brand-300 dark:hover:bg-brand-500/20"
1708
1953
  };
1709
1954
  var SIZE_CLASS2 = {
1710
- xs: "h-7 px-2 text-xs gap-1",
1711
- sm: "h-8 px-3 text-xs gap-1.5",
1712
- md: "h-9 px-3.5 text-sm gap-2",
1713
- lg: "h-11 px-5 text-base gap-2",
1714
- xl: "h-12 px-6 text-base gap-2.5"
1955
+ xs: "h-7 text-xs gap-1",
1956
+ sm: "h-8 text-xs gap-1.5",
1957
+ md: "h-9 text-sm gap-2",
1958
+ lg: "h-11 text-base gap-2",
1959
+ xl: "h-12 text-base gap-2.5"
1960
+ };
1961
+ var PADDING_X = {
1962
+ xs: "px-2",
1963
+ sm: "px-3",
1964
+ md: "px-3.5",
1965
+ lg: "px-5",
1966
+ xl: "px-6"
1715
1967
  };
1716
1968
  var CIRCLE_SQUARE = {
1717
- xs: "w-7 px-0",
1718
- sm: "w-8 px-0",
1719
- md: "w-9 px-0",
1720
- lg: "w-11 px-0",
1721
- xl: "w-12 px-0"
1969
+ xs: "w-7",
1970
+ sm: "w-8",
1971
+ md: "w-9",
1972
+ lg: "w-11",
1973
+ xl: "w-12"
1722
1974
  };
1723
1975
  var SHAPE_CLASS = {
1724
1976
  rounded: "rounded-lg",
@@ -1754,7 +2006,7 @@ var Button = ({
1754
2006
  VARIANT_CLASS[variant],
1755
2007
  SIZE_CLASS2[size],
1756
2008
  SHAPE_CLASS[shape],
1757
- shape === "circle" && CIRCLE_SQUARE[size],
2009
+ shape === "circle" ? CIRCLE_SQUARE[size] : PADDING_X[size],
1758
2010
  className
1759
2011
  ),
1760
2012
  ...rest,
@@ -1856,7 +2108,7 @@ var VARIANT_SOLID = {
1856
2108
  info: "bg-blue-500 text-white"
1857
2109
  };
1858
2110
  var SIZE_CLASS3 = {
1859
- sm: "px-1.5 py-0.5 text-[10px] gap-1",
2111
+ sm: "px-1.5 py-0.5 text-3xs gap-1",
1860
2112
  md: "px-2 py-0.5 text-xs gap-1.5"
1861
2113
  };
1862
2114
  var ICON_SIZE2 = {
@@ -1892,7 +2144,7 @@ var Badge = ({
1892
2144
  );
1893
2145
  };
1894
2146
  var SIZE_CLASS4 = {
1895
- xs: "h-6 w-6 text-[10px]",
2147
+ xs: "h-6 w-6 text-3xs",
1896
2148
  sm: "h-8 w-8 text-xs",
1897
2149
  md: "h-10 w-10 text-sm",
1898
2150
  lg: "h-12 w-12 text-base",
@@ -1929,6 +2181,21 @@ var Avatar = ({ src, alt, name, size = "md", className }) => {
1929
2181
  }
1930
2182
  );
1931
2183
  };
2184
+ var SIZE = {
2185
+ sm: "h-5 min-w-[20px] px-1.5 text-3xs",
2186
+ md: "h-6 min-w-[24px] px-2 text-xs"
2187
+ };
2188
+ var Kbd = ({ children, size = "md", className }) => /* @__PURE__ */ jsxRuntime.jsx(
2189
+ "kbd",
2190
+ {
2191
+ className: clsx.clsx(
2192
+ "inline-flex shrink-0 items-center justify-center rounded border border-gray-200 bg-gray-50 font-mono font-medium text-gray-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.04)] dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200 dark:shadow-[inset_0_-1px_0_0_rgba(255,255,255,0.04)]",
2193
+ SIZE[size],
2194
+ className
2195
+ ),
2196
+ children
2197
+ }
2198
+ );
1932
2199
  var BOX_POS = {
1933
2200
  top: "bottom-full left-1/2 -translate-x-1/2 mb-2.5",
1934
2201
  bottom: "top-full left-1/2 -translate-x-1/2 mt-2.5",
@@ -1944,54 +2211,124 @@ var ARROW_POS = {
1944
2211
  var VARIANT_BOX = {
1945
2212
  dark: "bg-gray-900 text-white shadow-[0_0_20px_rgba(0,0,0,0.35)] dark:bg-gray-700",
1946
2213
  white: "bg-white text-gray-700 border border-gray-200 shadow-[0_0_20px_rgba(0,0,0,0.15)] dark:bg-gray-800 dark:text-gray-200 dark:border-gray-700",
1947
- brand: "bg-brand-500 text-white shadow-[0_0_20px_rgba(0,0,0,0.25)]"
2214
+ brand: "bg-brand-500 text-white shadow-[0_0_20px_rgba(0,0,0,0.25)]",
2215
+ // Shades picked for 4.5:1 text contrast; amber is too light for white text.
2216
+ success: "bg-green-700 text-white shadow-[0_0_20px_rgba(0,0,0,0.25)]",
2217
+ warning: "bg-amber-400 text-gray-900 shadow-[0_0_20px_rgba(0,0,0,0.25)]",
2218
+ danger: "bg-red-600 text-white shadow-[0_0_20px_rgba(0,0,0,0.25)]"
1948
2219
  };
1949
2220
  var VARIANT_ARROW = {
1950
2221
  dark: "bg-gray-900 dark:bg-gray-700",
1951
2222
  white: "bg-white border border-gray-200 dark:bg-gray-800 dark:border-gray-700",
1952
- brand: "bg-brand-500"
2223
+ brand: "bg-brand-500",
2224
+ success: "bg-green-700",
2225
+ warning: "bg-amber-400",
2226
+ danger: "bg-red-600"
1953
2227
  };
1954
2228
  var Tooltip = ({
1955
2229
  content,
1956
2230
  children,
1957
2231
  position = "top",
1958
2232
  variant = "dark",
1959
- maxWidth = "max-w-xs"
1960
- }) => (
1961
- // `inline-block w-fit` keeps the wrapper exactly the size of the children even
1962
- // inside grid/flex parents, so the absolute-positioned tooltip stays anchored
1963
- // on the trigger rather than on the parent cell.
1964
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "group relative inline-block w-fit align-middle", children: [
1965
- children,
2233
+ maxWidth = "max-w-xs",
2234
+ shortcut,
2235
+ title,
2236
+ arrow = true,
2237
+ delay = 0
2238
+ }) => {
2239
+ const id = react.useId();
2240
+ const [open, setOpen] = react.useState(false);
2241
+ const [engaged, setEngaged] = react.useState(false);
2242
+ const timer = react.useRef(void 0);
2243
+ react.useEffect(() => () => clearTimeout(timer.current), []);
2244
+ const show = () => {
2245
+ setEngaged(true);
2246
+ clearTimeout(timer.current);
2247
+ if (delay > 0) timer.current = setTimeout(() => setOpen(true), delay);
2248
+ else setOpen(true);
2249
+ };
2250
+ const hide = () => {
2251
+ setEngaged(false);
2252
+ clearTimeout(timer.current);
2253
+ setOpen(false);
2254
+ };
2255
+ react.useEffect(() => {
2256
+ if (!engaged) return;
2257
+ const onKeyDown = (e) => {
2258
+ if (e.key !== "Escape") return;
2259
+ if (open) e.stopPropagation();
2260
+ clearTimeout(timer.current);
2261
+ setEngaged(false);
2262
+ setOpen(false);
2263
+ };
2264
+ document.addEventListener("keydown", onKeyDown, true);
2265
+ return () => document.removeEventListener("keydown", onKeyDown, true);
2266
+ }, [engaged, open]);
2267
+ const trigger = react.isValidElement(children) ? react.cloneElement(children, {
2268
+ "aria-describedby": [children.props["aria-describedby"], id].filter(Boolean).join(" ")
2269
+ }) : children;
2270
+ return (
2271
+ // `inline-block w-fit` keeps the wrapper exactly the size of the children even
2272
+ // inside grid/flex parents, so the absolute-positioned tooltip stays anchored
2273
+ // on the trigger rather than on the parent cell.
1966
2274
  /* @__PURE__ */ jsxRuntime.jsxs(
1967
2275
  "span",
1968
2276
  {
1969
- role: "tooltip",
1970
- className: clsx.clsx(
1971
- "pointer-events-none absolute z-50 block w-max rounded-lg px-3 py-2 text-xs leading-relaxed font-normal whitespace-normal opacity-0 transition-opacity duration-150 group-hover:opacity-100",
1972
- maxWidth,
1973
- BOX_POS[position],
1974
- VARIANT_BOX[variant]
1975
- ),
2277
+ className: "relative inline-block w-fit align-middle",
2278
+ onMouseEnter: show,
2279
+ onMouseLeave: hide,
2280
+ onFocus: show,
2281
+ onBlur: hide,
1976
2282
  children: [
1977
- content,
1978
- /* @__PURE__ */ jsxRuntime.jsx(
2283
+ trigger,
2284
+ /* @__PURE__ */ jsxRuntime.jsxs(
1979
2285
  "span",
1980
2286
  {
1981
- "aria-hidden": true,
1982
- className: clsx.clsx("absolute h-2 w-2 rotate-45", ARROW_POS[position], VARIANT_ARROW[variant])
2287
+ id,
2288
+ role: "tooltip",
2289
+ className: clsx.clsx(
2290
+ "pointer-events-none absolute z-50 block w-max rounded-lg px-3 py-2 text-xs leading-relaxed font-normal whitespace-normal transition-opacity duration-150",
2291
+ open ? "opacity-100" : "opacity-0",
2292
+ maxWidth,
2293
+ BOX_POS[position],
2294
+ VARIANT_BOX[variant]
2295
+ ),
2296
+ children: [
2297
+ title && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block font-semibold", children: title }),
2298
+ title ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5 block opacity-80", children: content }) : content,
2299
+ shortcut && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 inline-flex gap-0.5 align-middle", children: shortcut.map((key, i) => /* @__PURE__ */ jsxRuntime.jsx(Kbd, { size: "sm", children: key }, i)) }),
2300
+ arrow && /* @__PURE__ */ jsxRuntime.jsx(
2301
+ "span",
2302
+ {
2303
+ "aria-hidden": true,
2304
+ className: clsx.clsx(
2305
+ "absolute h-2 w-2 rotate-45",
2306
+ ARROW_POS[position],
2307
+ VARIANT_ARROW[variant]
2308
+ )
2309
+ }
2310
+ )
2311
+ ]
1983
2312
  }
1984
2313
  )
1985
2314
  ]
1986
2315
  }
1987
2316
  )
1988
- ] })
1989
- );
2317
+ );
2318
+ };
1990
2319
  var TooltipHelp = ({
1991
2320
  text,
1992
2321
  position = "top",
1993
2322
  variant = "dark"
1994
- }) => /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { content: text, position, variant, maxWidth: "max-w-[260px]", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HelpCircle, { className: "h-3.5 w-3.5 cursor-help text-gray-400 transition-colors hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300" }) });
2323
+ }) => /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { content: text, position, variant, maxWidth: "max-w-[260px]", children: /* @__PURE__ */ jsxRuntime.jsx(
2324
+ "button",
2325
+ {
2326
+ type: "button",
2327
+ "aria-label": "Help",
2328
+ className: "focus-visible:ring-brand-500 inline-flex cursor-help rounded-full text-gray-400 transition-colors hover:text-gray-600 focus:outline-none focus-visible:ring-2 dark:text-gray-500 dark:hover:text-gray-300",
2329
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HelpCircle, { className: "h-3.5 w-3.5", "aria-hidden": true })
2330
+ }
2331
+ ) });
1995
2332
  var isDivider = (item) => item.divider === true;
1996
2333
  var Dropdown = ({
1997
2334
  label,
@@ -2554,25 +2891,91 @@ var useTabs = () => {
2554
2891
  if (!ctx) throw new Error("Tabs.* must be used inside <Tabs>");
2555
2892
  return ctx;
2556
2893
  };
2557
- var Root10 = ({ value, onChange, orientation = "horizontal", children, className }) => /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value, onChange, orientation }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx(orientation === "vertical" ? "flex gap-6" : "", className), children }) });
2894
+ var LIST_CLASSES = {
2895
+ underline: {
2896
+ horizontal: "flex items-center gap-1 border-b border-gray-200 dark:border-gray-800",
2897
+ vertical: "flex shrink-0 flex-col gap-1 border-r border-gray-200 dark:border-gray-800"
2898
+ },
2899
+ // The list's border is the panel's edge: it runs under the inactive tabs and
2900
+ // the active tab covers it.
2901
+ folder: {
2902
+ horizontal: "flex items-end gap-1 border-b border-[var(--color-border)]",
2903
+ vertical: "flex shrink-0 flex-col gap-1 border-r border-[var(--color-border)]"
2904
+ }
2905
+ };
2906
+ var TRIGGER_CLASSES = {
2907
+ underline: {
2908
+ horizontal: {
2909
+ base: "-mb-px border-b-2 px-3 py-2",
2910
+ active: "border-brand-500 text-brand-600 dark:text-brand-400",
2911
+ inactive: "border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
2912
+ },
2913
+ vertical: {
2914
+ base: "-mr-px justify-start rounded-l-lg border-r-2 px-3 py-2 text-left whitespace-nowrap",
2915
+ active: "border-brand-500 bg-brand-50 text-brand-600 dark:bg-brand-500/10 dark:text-brand-400",
2916
+ inactive: "border-transparent text-gray-500 hover:bg-gray-50 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-gray-200"
2917
+ }
2918
+ },
2919
+ // Every tab overlaps the list's border by 1px. The active one has the
2920
+ // panel's background and a transparent edge on the panel side, so it covers
2921
+ // the line and opens into the panel; it is also 4px taller (wider when
2922
+ // vertical) than the inactive ones, which sit on the line with the page's
2923
+ // background. The padding moves with the size so the labels don't shift.
2924
+ folder: {
2925
+ horizontal: {
2926
+ base: "-mb-px rounded-t-lg border border-[var(--color-border)] px-3 pb-2",
2927
+ active: "border-b-transparent bg-[var(--color-bg-panel)] pt-3 text-brand-600 dark:text-brand-400",
2928
+ inactive: "bg-[var(--color-bg-base)] pt-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
2929
+ },
2930
+ vertical: {
2931
+ base: "-mr-px justify-start rounded-l-lg border border-[var(--color-border)] py-2 pr-3 text-left whitespace-nowrap",
2932
+ active: "border-r-transparent bg-[var(--color-bg-panel)] pl-4 text-brand-600 dark:text-brand-400",
2933
+ inactive: "ml-1 bg-[var(--color-bg-base)] pl-3 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
2934
+ }
2935
+ }
2936
+ };
2937
+ var PANEL_CLASSES = {
2938
+ underline: { horizontal: "pt-5", vertical: "flex-1" },
2939
+ // Bordered on three sides: the list's border closes the side facing the tabs.
2940
+ folder: {
2941
+ horizontal: "rounded-b-xl border border-t-0 border-[var(--color-border)] bg-[var(--color-bg-panel)] p-5",
2942
+ vertical: "flex-1 rounded-r-xl border border-l-0 border-[var(--color-border)] bg-[var(--color-bg-panel)] p-5"
2943
+ }
2944
+ };
2945
+ var Root10 = ({
2946
+ value,
2947
+ onChange,
2948
+ orientation = "horizontal",
2949
+ variant = "underline",
2950
+ children,
2951
+ className
2952
+ }) => /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value, onChange, orientation, variant }, children: /* @__PURE__ */ jsxRuntime.jsx(
2953
+ "div",
2954
+ {
2955
+ className: clsx.clsx(
2956
+ // Folder tabs touch their panel, so no gap between list and panel.
2957
+ orientation === "vertical" && (variant === "folder" ? "flex" : "flex gap-6"),
2958
+ className
2959
+ ),
2960
+ children
2961
+ }
2962
+ ) });
2558
2963
  var List = ({ children, className }) => {
2559
- const { orientation } = useTabs();
2964
+ const { orientation, variant } = useTabs();
2560
2965
  return /* @__PURE__ */ jsxRuntime.jsx(
2561
2966
  "div",
2562
2967
  {
2563
2968
  role: "tablist",
2564
2969
  "aria-orientation": orientation,
2565
- className: clsx.clsx(
2566
- orientation === "vertical" ? "flex shrink-0 flex-col gap-1 border-r border-gray-200 dark:border-gray-800" : "flex items-center gap-1 border-b border-gray-200 dark:border-gray-800",
2567
- className
2568
- ),
2970
+ className: clsx.clsx(LIST_CLASSES[variant][orientation], className),
2569
2971
  children
2570
2972
  }
2571
2973
  );
2572
2974
  };
2573
2975
  var Trigger = ({ value, children, icon: Icon2, badge, disabled, className }) => {
2574
- const { value: active, onChange, orientation } = useTabs();
2976
+ const { value: active, onChange, orientation, variant } = useTabs();
2575
2977
  const isActive = value === active;
2978
+ const styles = TRIGGER_CLASSES[variant][orientation];
2576
2979
  return /* @__PURE__ */ jsxRuntime.jsxs(
2577
2980
  "button",
2578
2981
  {
@@ -2583,13 +2986,8 @@ var Trigger = ({ value, children, icon: Icon2, badge, disabled, className }) =>
2583
2986
  onClick: () => onChange(value),
2584
2987
  className: clsx.clsx(
2585
2988
  "flex items-center gap-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
2586
- orientation === "vertical" ? clsx.clsx(
2587
- "-mr-px justify-start rounded-l-lg border-r-2 px-3 py-2 text-left whitespace-nowrap",
2588
- isActive ? "border-brand-500 bg-brand-50 text-brand-600 dark:bg-brand-500/10 dark:text-brand-400" : "border-transparent text-gray-500 hover:bg-gray-50 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-gray-200"
2589
- ) : clsx.clsx(
2590
- "-mb-px border-b-2 px-3 py-2",
2591
- isActive ? "border-brand-500 text-brand-600 dark:text-brand-400" : "border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
2592
- ),
2989
+ styles.base,
2990
+ isActive ? styles.active : styles.inactive,
2593
2991
  className
2594
2992
  ),
2595
2993
  children: [
@@ -2599,7 +2997,7 @@ var Trigger = ({ value, children, icon: Icon2, badge, disabled, className }) =>
2599
2997
  "span",
2600
2998
  {
2601
2999
  className: clsx.clsx(
2602
- "ms-auto rounded-full px-1.5 py-0.5 text-[10px] font-bold",
3000
+ "text-3xs ms-auto rounded-full px-1.5 py-0.5 font-bold",
2603
3001
  isActive ? "bg-brand-100 text-brand-600 dark:bg-brand-500/20 dark:text-brand-400" : "bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400"
2604
3002
  ),
2605
3003
  children: badge
@@ -2614,16 +3012,9 @@ var Panel = ({
2614
3012
  children,
2615
3013
  className
2616
3014
  }) => {
2617
- const { value: active, orientation } = useTabs();
3015
+ const { value: active, orientation, variant } = useTabs();
2618
3016
  if (value !== active) return null;
2619
- return /* @__PURE__ */ jsxRuntime.jsx(
2620
- "div",
2621
- {
2622
- role: "tabpanel",
2623
- className: clsx.clsx(orientation === "vertical" ? "flex-1" : "pt-5", className),
2624
- children
2625
- }
2626
- );
3017
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "tabpanel", className: clsx.clsx(PANEL_CLASSES[variant][orientation], className), children });
2627
3018
  };
2628
3019
  var Tabs = Object.assign(Root10, { List, Trigger, Panel });
2629
3020
  var SIZE_ICON = {
@@ -2713,7 +3104,13 @@ var Clipboard = react.forwardRef(function Clipboard2({
2713
3104
  }
2714
3105
  );
2715
3106
  });
2716
- var CodeBlock = ({ code, language, showCopy = true, className }) => /* @__PURE__ */ jsxRuntime.jsxs(
3107
+ var CodeBlock = ({
3108
+ code,
3109
+ language,
3110
+ highlight,
3111
+ showCopy = true,
3112
+ className
3113
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(
2717
3114
  "div",
2718
3115
  {
2719
3116
  className: clsx.clsx(
@@ -2722,10 +3119,10 @@ var CodeBlock = ({ code, language, showCopy = true, className }) => /* @__PURE__
2722
3119
  ),
2723
3120
  children: [
2724
3121
  language && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 px-4 py-1.5 dark:border-gray-800", children: [
2725
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400", children: language }),
3122
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-3xs font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400", children: language }),
2726
3123
  showCopy && /* @__PURE__ */ jsxRuntime.jsx(Clipboard, { value: code, floating: true })
2727
3124
  ] }),
2728
- /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "overflow-x-auto p-4 text-xs leading-relaxed text-gray-800 dark:text-gray-200", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code }) }),
3125
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "overflow-x-auto p-4 text-xs leading-relaxed text-gray-800 dark:text-gray-200", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: highlight ? highlight(code, language) : code }) }),
2729
3126
  showCopy && !language && /* @__PURE__ */ jsxRuntime.jsx(Clipboard, { value: code, floating: true, className: "absolute top-2 right-2" })
2730
3127
  ]
2731
3128
  }
@@ -2934,7 +3331,7 @@ var SectionLabel = ({ children, className }) => /* @__PURE__ */ jsxRuntime.jsx(
2934
3331
  "p",
2935
3332
  {
2936
3333
  className: clsx.clsx(
2937
- "text-[10px] font-semibold tracking-wider text-gray-400 uppercase dark:text-gray-600",
3334
+ "text-3xs font-semibold tracking-wider text-gray-400 uppercase dark:text-gray-600",
2938
3335
  className
2939
3336
  ),
2940
3337
  children
@@ -3230,7 +3627,7 @@ var BADGE_BG = {
3230
3627
  success: "bg-green-500"
3231
3628
  };
3232
3629
  var NotificationsPanelContext = react.createContext(null);
3233
- var useCtx = () => {
3630
+ var useCtx2 = () => {
3234
3631
  const ctx = react.useContext(NotificationsPanelContext);
3235
3632
  if (!ctx) throw new Error("NotificationsPanel.* must be used inside <NotificationsPanel>");
3236
3633
  return ctx;
@@ -3288,7 +3685,7 @@ var NotificationsPanelRoot = ({
3288
3685
  };
3289
3686
  var NotificationsPanelTrigger = react.forwardRef(
3290
3687
  function NotificationsPanelTrigger2({ count = 0, muted = false, ping, className, ...rest }, forwardedRef) {
3291
- const { open, setOpen, triggerRef, refreshRect } = useCtx();
3688
+ const { open, setOpen, triggerRef, refreshRect } = useCtx2();
3292
3689
  const setRef = (node) => {
3293
3690
  triggerRef.current = node;
3294
3691
  if (typeof forwardedRef === "function") forwardedRef(node);
@@ -3330,7 +3727,7 @@ var NotificationsPanelContent = ({
3330
3727
  className,
3331
3728
  children
3332
3729
  }) => {
3333
- const { open, setOpen, triggerRect, align } = useCtx();
3730
+ const { open, setOpen, triggerRect, align } = useCtx2();
3334
3731
  if (!open || !triggerRect) return null;
3335
3732
  const top = triggerRect.bottom + 8;
3336
3733
  const positionStyle2 = align === "right" ? { top, right: window.innerWidth - triggerRect.right } : { top, left: triggerRect.left };
@@ -3429,7 +3826,7 @@ var NotificationsPanelItem = react.forwardRef(
3429
3826
  className,
3430
3827
  ...rest
3431
3828
  }, ref) {
3432
- const { setOpen } = useCtx();
3829
+ const { setOpen } = useCtx2();
3433
3830
  const meta = SEVERITY_META[severity];
3434
3831
  const Icon2 = meta.icon;
3435
3832
  const defaultLabel = severity === "success" ? "OK" : severity.toUpperCase();
@@ -3461,13 +3858,13 @@ var NotificationsPanelItem = react.forwardRef(
3461
3858
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
3462
3859
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-sm font-semibold text-gray-900 dark:text-white", children: title }),
3463
3860
  subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-xs text-gray-500 dark:text-gray-400", children: subtitle }),
3464
- caption && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 truncate font-mono text-[10px] text-gray-400", children: caption })
3861
+ caption && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-3xs mt-0.5 truncate font-mono text-gray-400", children: caption })
3465
3862
  ] }),
3466
3863
  /* @__PURE__ */ jsxRuntime.jsx(
3467
3864
  "span",
3468
3865
  {
3469
3866
  className: clsx.clsx(
3470
- "mt-0.5 shrink-0 rounded-full px-2 py-0.5 text-[10px] font-bold text-white",
3867
+ "text-3xs mt-0.5 shrink-0 rounded-full px-2 py-0.5 font-bold text-white",
3471
3868
  BADGE_BG[severity]
3472
3869
  ),
3473
3870
  children: badgeLabel ?? defaultLabel
@@ -3494,7 +3891,7 @@ var NotificationsPanelFooter = ({
3494
3891
  className,
3495
3892
  ...rest
3496
3893
  }) => {
3497
- const { setOpen } = useCtx();
3894
+ const { setOpen } = useCtx2();
3498
3895
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-gray-100 p-2 dark:border-gray-800", children: /* @__PURE__ */ jsxRuntime.jsx(
3499
3896
  "button",
3500
3897
  {
@@ -3504,7 +3901,7 @@ var NotificationsPanelFooter = ({
3504
3901
  if (closeOnClick && !e.defaultPrevented) setOpen(false);
3505
3902
  },
3506
3903
  className: clsx.clsx(
3507
- "text-brand-500 w-full rounded-lg py-2 text-center text-sm font-medium transition-colors hover:bg-gray-50 dark:hover:bg-white/5",
3904
+ "text-brand-600 dark:text-brand-400 w-full rounded-lg py-2 text-center text-sm font-medium transition-colors hover:bg-gray-50 dark:hover:bg-white/5",
3508
3905
  className
3509
3906
  ),
3510
3907
  ...rest,
@@ -3616,7 +4013,7 @@ var NotificationCard = Object.assign(Root11, {
3616
4013
  Condensed: CondensedVariant
3617
4014
  });
3618
4015
  var UserMenuContext = react.createContext(null);
3619
- var useCtx2 = () => {
4016
+ var useCtx3 = () => {
3620
4017
  const ctx = react.useContext(UserMenuContext);
3621
4018
  if (!ctx) throw new Error("UserMenu.* must be used inside <UserMenu>");
3622
4019
  return ctx;
@@ -3672,7 +4069,7 @@ var UserMenuRoot = ({
3672
4069
  };
3673
4070
  var UserMenuTrigger = react.forwardRef(
3674
4071
  function UserMenuTrigger2({ name, avatarSrc, hideName = false, className, ...rest }, forwardedRef) {
3675
- const { open, setOpen, triggerRef, refreshRect } = useCtx2();
4072
+ const { open, setOpen, triggerRef, refreshRect } = useCtx3();
3676
4073
  const setRef = (node) => {
3677
4074
  triggerRef.current = node;
3678
4075
  if (typeof forwardedRef === "function") forwardedRef(node);
@@ -3713,7 +4110,7 @@ var UserMenuTrigger = react.forwardRef(
3713
4110
  }
3714
4111
  );
3715
4112
  var UserMenuContent = ({ width = "w-56", className, children }) => {
3716
- const { open, setOpen, triggerRect, align } = useCtx2();
4113
+ const { open, setOpen, triggerRect, align } = useCtx3();
3717
4114
  if (!open || !triggerRect) return null;
3718
4115
  const top = triggerRect.bottom + 8;
3719
4116
  const positionStyle2 = align === "right" ? { top, right: window.innerWidth - triggerRect.right } : { top, left: triggerRect.left };
@@ -3756,7 +4153,7 @@ var UserMenuHeader = ({ name, email, avatarSrc, className }) => /* @__PURE__ */
3756
4153
  );
3757
4154
  var UserMenuItems = ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { role: "group", className: "py-1", children });
3758
4155
  var UserMenuItem = react.forwardRef(function UserMenuItem2({ icon: Icon2, variant = "default", closeOnClick = true, onClick, className, children, ...rest }, ref) {
3759
- const { setOpen } = useCtx2();
4156
+ const { setOpen } = useCtx3();
3760
4157
  return /* @__PURE__ */ jsxRuntime.jsxs(
3761
4158
  "button",
3762
4159
  {
@@ -3837,7 +4234,7 @@ var SIZE_CLASS9 = {
3837
4234
  sm: { box: "h-8 w-8", icon: "h-4 w-4" },
3838
4235
  md: { box: "h-10 w-10", icon: "h-5 w-5" }
3839
4236
  };
3840
- var TRI_ORDER = ["light", "dark", "oled"];
4237
+ var TRI_ORDER = ["light", "dark", "deep-blue"];
3841
4238
  var nextInCycle = (current) => {
3842
4239
  const idx = TRI_ORDER.indexOf(current);
3843
4240
  return TRI_ORDER[(idx + 1) % TRI_ORDER.length];
@@ -3845,7 +4242,7 @@ var nextInCycle = (current) => {
3845
4242
  var ICON_FOR = {
3846
4243
  light: lucideReact.Sun,
3847
4244
  dark: lucideReact.Moon,
3848
- oled: lucideReact.MoonStar
4245
+ "deep-blue": lucideReact.MoonStar
3849
4246
  };
3850
4247
  var ThemeToggleTri = react.forwardRef(
3851
4248
  function ThemeToggleTri2({
@@ -3854,12 +4251,12 @@ var ThemeToggleTri = react.forwardRef(
3854
4251
  size = "md",
3855
4252
  lightLabel = "Switch to light mode",
3856
4253
  darkLabel = "Switch to dark mode",
3857
- oledLabel = "Switch to OLED mode",
4254
+ deepBlueLabel = "Switch to deep blue mode",
3858
4255
  className,
3859
4256
  ...rest
3860
4257
  }, ref) {
3861
4258
  const next = nextInCycle(theme);
3862
- const label = next === "light" ? lightLabel : next === "dark" ? darkLabel : oledLabel;
4259
+ const label = next === "light" ? lightLabel : next === "dark" ? darkLabel : deepBlueLabel;
3863
4260
  const Icon2 = ICON_FOR[theme];
3864
4261
  const { box, icon } = SIZE_CLASS9[size];
3865
4262
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -3933,7 +4330,7 @@ var ButtonGroup = ({
3933
4330
  );
3934
4331
  };
3935
4332
  var CarouselContext = react.createContext(null);
3936
- var useCtx3 = () => {
4333
+ var useCtx4 = () => {
3937
4334
  const ctx = react.useContext(CarouselContext);
3938
4335
  if (!ctx) throw new Error("Carousel.* must be used inside <Carousel>");
3939
4336
  return ctx;
@@ -3989,7 +4386,7 @@ var CarouselRoot = ({
3989
4386
  );
3990
4387
  };
3991
4388
  var CarouselViewport = ({ children, className }) => {
3992
- const { emblaRef } = useCtx3();
4389
+ const { emblaRef } = useCtx4();
3993
4390
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: emblaRef, className: clsx.clsx("overflow-hidden", className), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex", children }) });
3994
4391
  };
3995
4392
  var CarouselSlide = ({ basis = "basis-full", className, children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("min-w-0 shrink-0 grow-0 px-1", basis, className), children });
@@ -3999,7 +4396,7 @@ var CarouselControls = ({
3999
4396
  prevLabel = "Previous slide",
4000
4397
  nextLabel = "Next slide"
4001
4398
  }) => {
4002
- const { scrollPrev, scrollNext, canScrollPrev, canScrollNext } = useCtx3();
4399
+ const { scrollPrev, scrollNext, canScrollPrev, canScrollNext } = useCtx4();
4003
4400
  const baseBtn = "flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 bg-white text-gray-600 shadow-sm transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700";
4004
4401
  if (position === "outside") {
4005
4402
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx.clsx("mt-3 flex items-center justify-center gap-2", className), children: [
@@ -4052,197 +4449,31 @@ var CarouselControls = ({
4052
4449
  )
4053
4450
  ] });
4054
4451
  };
4055
- var CarouselIndicators = ({ className }) => {
4056
- const { scrollSnaps, selectedIndex, scrollTo } = useCtx3();
4057
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("mt-3 flex items-center justify-center gap-2", className), children: scrollSnaps.map((_, i) => {
4058
- const active = i === selectedIndex;
4059
- return /* @__PURE__ */ jsxRuntime.jsx(
4060
- "button",
4061
- {
4062
- type: "button",
4063
- "aria-label": `Go to slide ${i + 1}`,
4064
- "aria-current": active,
4065
- onClick: () => scrollTo(i),
4066
- className: clsx.clsx(
4067
- "h-2 rounded-full transition-all",
4068
- active ? "bg-brand-500 w-6" : "w-2 bg-gray-300 dark:bg-gray-600"
4069
- )
4070
- },
4071
- i
4072
- );
4073
- }) });
4074
- };
4075
- var Carousel = Object.assign(CarouselRoot, {
4076
- Viewport: CarouselViewport,
4077
- Slide: CarouselSlide,
4078
- Controls: CarouselControls,
4079
- Indicators: CarouselIndicators
4080
- });
4081
- var PopoverContext = react.createContext(null);
4082
- var useCtx4 = () => {
4083
- const ctx = react.useContext(PopoverContext);
4084
- if (!ctx) throw new Error("Popover.* must be used inside <Popover>");
4085
- return ctx;
4086
- };
4087
- var PopoverRoot = ({
4088
- open: openProp,
4089
- defaultOpen = false,
4090
- onOpenChange,
4091
- children
4092
- }) => {
4093
- const [internalOpen, setInternalOpen] = react.useState(defaultOpen);
4094
- const isControlled = openProp !== void 0;
4095
- const open = isControlled ? openProp : internalOpen;
4096
- const triggerRef = react.useRef(null);
4097
- const [triggerRect, setTriggerRect] = react.useState(null);
4098
- const refreshRect = react.useCallback(() => {
4099
- if (triggerRef.current) setTriggerRect(triggerRef.current.getBoundingClientRect());
4100
- }, []);
4101
- const setOpen = react.useCallback(
4102
- (v) => {
4103
- if (v) refreshRect();
4104
- if (!isControlled) setInternalOpen(v);
4105
- onOpenChange?.(v);
4106
- },
4107
- [isControlled, onOpenChange, refreshRect]
4108
- );
4109
- react.useEffect(() => {
4110
- if (!open) return;
4111
- const handler = () => refreshRect();
4112
- window.addEventListener("resize", handler);
4113
- window.addEventListener("scroll", handler, true);
4114
- return () => {
4115
- window.removeEventListener("resize", handler);
4116
- window.removeEventListener("scroll", handler, true);
4117
- };
4118
- }, [open, refreshRect]);
4119
- react.useEffect(() => {
4120
- if (!open) return;
4121
- const handler = (e) => {
4122
- if (e.key === "Escape") setOpen(false);
4123
- };
4124
- document.addEventListener("keydown", handler);
4125
- return () => document.removeEventListener("keydown", handler);
4126
- }, [open, setOpen]);
4127
- return /* @__PURE__ */ jsxRuntime.jsx(PopoverContext.Provider, { value: { open, setOpen, triggerRef, triggerRect, refreshRect }, children });
4128
- };
4129
- var PopoverTrigger = react.forwardRef(function PopoverTrigger2({ onClick, children, ...rest }, forwardedRef) {
4130
- const { open, setOpen, triggerRef, refreshRect } = useCtx4();
4131
- const setRef = (node) => {
4132
- triggerRef.current = node;
4133
- if (typeof forwardedRef === "function") forwardedRef(node);
4134
- else if (forwardedRef) forwardedRef.current = node;
4135
- };
4136
- react.useEffect(() => {
4137
- if (open) refreshRect();
4138
- }, [open, refreshRect]);
4139
- return /* @__PURE__ */ jsxRuntime.jsx(
4140
- "button",
4141
- {
4142
- ref: setRef,
4143
- type: "button",
4144
- "aria-haspopup": "dialog",
4145
- "aria-expanded": open,
4146
- onClick: (e) => {
4147
- onClick?.(e);
4148
- setOpen(!open);
4149
- },
4150
- ...rest,
4151
- children
4152
- }
4153
- );
4154
- });
4155
- var positionStyle = (position, rect, offset) => {
4156
- switch (position) {
4157
- case "top":
4158
- return {
4159
- top: rect.top - offset,
4160
- left: rect.left + rect.width / 2,
4161
- transform: "translate(-50%, -100%)"
4162
- };
4163
- case "right":
4164
- return {
4165
- top: rect.top + rect.height / 2,
4166
- left: rect.right + offset,
4167
- transform: "translateY(-50%)"
4168
- };
4169
- case "left":
4170
- return {
4171
- top: rect.top + rect.height / 2,
4172
- left: rect.left - offset,
4173
- transform: "translate(-100%, -50%)"
4174
- };
4175
- case "bottom":
4176
- default:
4177
- return {
4178
- top: rect.bottom + offset,
4179
- left: rect.left + rect.width / 2,
4180
- transform: "translateX(-50%)"
4181
- };
4182
- }
4183
- };
4184
- var arrowStyle = (position) => {
4185
- const base = {
4186
- position: "absolute",
4187
- width: 8,
4188
- height: 8,
4189
- transform: "rotate(45deg)"
4190
- };
4191
- switch (position) {
4192
- case "top":
4193
- return { ...base, bottom: -4, left: "50%", marginLeft: -4 };
4194
- case "right":
4195
- return { ...base, left: -4, top: "50%", marginTop: -4 };
4196
- case "left":
4197
- return { ...base, right: -4, top: "50%", marginTop: -4 };
4198
- case "bottom":
4199
- default:
4200
- return { ...base, top: -4, left: "50%", marginLeft: -4 };
4201
- }
4202
- };
4203
- var PopoverContent = ({
4204
- position = "bottom",
4205
- offset = 8,
4206
- arrow = false,
4207
- width = "w-64",
4208
- className,
4209
- children
4210
- }) => {
4211
- const { open, setOpen, triggerRect } = useCtx4();
4212
- if (!open || !triggerRect) return null;
4213
- return reactDom.createPortal(
4214
- /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4215
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-[9998]", onClick: () => setOpen(false) }),
4216
- /* @__PURE__ */ jsxRuntime.jsxs(
4217
- "div",
4218
- {
4219
- role: "dialog",
4220
- style: positionStyle(position, triggerRect, offset),
4221
- className: clsx.clsx(
4222
- "fixed z-[9999] rounded-xl border border-gray-200 bg-white p-4 text-sm shadow-xl dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100",
4223
- width,
4224
- className
4225
- ),
4226
- children: [
4227
- arrow && /* @__PURE__ */ jsxRuntime.jsx(
4228
- "span",
4229
- {
4230
- "aria-hidden": true,
4231
- style: arrowStyle(position),
4232
- className: "border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900"
4233
- }
4234
- ),
4235
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children })
4236
- ]
4237
- }
4238
- )
4239
- ] }),
4240
- document.body
4241
- );
4242
- };
4243
- var Popover = Object.assign(PopoverRoot, {
4244
- Trigger: PopoverTrigger,
4245
- Content: PopoverContent
4452
+ var CarouselIndicators = ({ className }) => {
4453
+ const { scrollSnaps, selectedIndex, scrollTo } = useCtx4();
4454
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("mt-3 flex items-center justify-center gap-2", className), children: scrollSnaps.map((_, i) => {
4455
+ const active = i === selectedIndex;
4456
+ return /* @__PURE__ */ jsxRuntime.jsx(
4457
+ "button",
4458
+ {
4459
+ type: "button",
4460
+ "aria-label": `Go to slide ${i + 1}`,
4461
+ "aria-current": active,
4462
+ onClick: () => scrollTo(i),
4463
+ className: clsx.clsx(
4464
+ "h-2 rounded-full transition-all",
4465
+ active ? "bg-brand-500 w-6" : "w-2 bg-gray-300 dark:bg-gray-600"
4466
+ )
4467
+ },
4468
+ i
4469
+ );
4470
+ }) });
4471
+ };
4472
+ var Carousel = Object.assign(CarouselRoot, {
4473
+ Viewport: CarouselViewport,
4474
+ Slide: CarouselSlide,
4475
+ Controls: CarouselControls,
4476
+ Indicators: CarouselIndicators
4246
4477
  });
4247
4478
  var SIZE_TRACK = {
4248
4479
  xs: "h-1",
@@ -4312,7 +4543,7 @@ var ProgressBar = ({
4312
4543
  INTENT_BG2[intent],
4313
4544
  striped && "motion-safe:animate-[progressStripes_1s_linear_infinite]"
4314
4545
  ),
4315
- children: showInsideLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-2 text-[10px] leading-none font-bold text-white", children: labelText })
4546
+ children: showInsideLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-3xs px-2 leading-none font-bold text-white", children: labelText })
4316
4547
  }
4317
4548
  )
4318
4549
  }
@@ -4369,7 +4600,7 @@ var Ribbon = ({
4369
4600
  "span",
4370
4601
  {
4371
4602
  className: clsx.clsx(
4372
- "absolute z-10 w-40 px-2 py-1 text-center text-[11px] font-bold tracking-wide uppercase shadow-md",
4603
+ "text-2xs absolute z-10 w-40 px-2 py-1 text-center font-bold tracking-wide uppercase shadow-md",
4373
4604
  INTENT_BG3[intent],
4374
4605
  ANGLED_POSITION[position],
4375
4606
  className
@@ -4382,7 +4613,7 @@ var Ribbon = ({
4382
4613
  "span",
4383
4614
  {
4384
4615
  className: clsx.clsx(
4385
- "absolute z-10 px-2.5 py-1 text-[11px] font-bold tracking-wide uppercase shadow",
4616
+ "text-2xs absolute z-10 px-2.5 py-1 font-bold tracking-wide uppercase shadow",
4386
4617
  INTENT_BG3[intent],
4387
4618
  FLAT_POSITION[position],
4388
4619
  className
@@ -4949,7 +5180,7 @@ var CommandPaletteGroup = react.forwardRef(
4949
5180
  {
4950
5181
  ref,
4951
5182
  className: clsx.clsx(
4952
- "px-1 pb-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pt-2 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:text-[11px] [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:tracking-wider [&_[cmdk-group-heading]]:text-gray-400 [&_[cmdk-group-heading]]:uppercase dark:[&_[cmdk-group-heading]]:text-gray-500",
5183
+ "[&_[cmdk-group-heading]]:text-2xs px-1 pb-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pt-2 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:tracking-wider [&_[cmdk-group-heading]]:text-gray-400 [&_[cmdk-group-heading]]:uppercase dark:[&_[cmdk-group-heading]]:text-gray-500",
4953
5184
  className
4954
5185
  ),
4955
5186
  ...rest
@@ -4974,7 +5205,7 @@ var CommandPaletteItem = react.forwardRef(
4974
5205
  children: [
4975
5206
  Icon2 && /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-4 w-4 shrink-0 text-gray-400", "aria-hidden": true }),
4976
5207
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children }),
4977
- shortcut && /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "shrink-0 rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 font-mono text-[10px] font-medium text-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400", children: shortcut })
5208
+ shortcut && /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "text-3xs shrink-0 rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 font-mono font-medium text-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400", children: shortcut })
4978
5209
  ]
4979
5210
  }
4980
5211
  );
@@ -5014,7 +5245,7 @@ var CommandPaletteFooter = ({ className, children }) => /* @__PURE__ */ jsxRunti
5014
5245
  "div",
5015
5246
  {
5016
5247
  className: clsx.clsx(
5017
- "flex items-center justify-between border-t border-gray-100 px-4 py-2 text-[11px] text-gray-500 dark:border-gray-800 dark:text-gray-400",
5248
+ "text-2xs flex items-center justify-between border-t border-gray-100 px-4 py-2 text-gray-500 dark:border-gray-800 dark:text-gray-400",
5018
5249
  className
5019
5250
  ),
5020
5251
  children
@@ -5139,11 +5370,11 @@ var formatKey = (raw, isMac) => {
5139
5370
  if (KEY_LABEL[key]) return KEY_LABEL[key];
5140
5371
  return raw.length === 1 ? raw.toUpperCase() : raw;
5141
5372
  };
5142
- var Kbd = ({ children, className }) => /* @__PURE__ */ jsxRuntime.jsx(
5373
+ var Kbd2 = ({ children, className }) => /* @__PURE__ */ jsxRuntime.jsx(
5143
5374
  "kbd",
5144
5375
  {
5145
5376
  className: clsx.clsx(
5146
- "inline-flex h-6 min-w-[1.5rem] items-center justify-center rounded border border-gray-200 bg-gray-50 px-1.5 font-mono text-[11px] font-medium text-gray-700 shadow-[0_1px_0_0_rgba(0,0,0,0.05)] dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300",
5377
+ "text-2xs inline-flex h-6 min-w-[1.5rem] items-center justify-center rounded border border-gray-200 bg-gray-50 px-1.5 font-mono font-medium text-gray-700 shadow-[0_1px_0_0_rgba(0,0,0,0.05)] dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300",
5147
5378
  className
5148
5379
  ),
5149
5380
  children
@@ -5233,7 +5464,7 @@ var HelpOverlayRoot = ({
5233
5464
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-x-8 gap-y-6 overflow-y-auto px-5 py-5 sm:grid-cols-2", children }),
5234
5465
  (footer ?? true) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end gap-2 border-t border-gray-200 bg-gray-50 px-5 py-2.5 text-xs text-gray-500 dark:border-gray-800 dark:bg-gray-800/50 dark:text-gray-400", children: footer ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5235
5466
  "Press ",
5236
- /* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "Esc" }),
5467
+ /* @__PURE__ */ jsxRuntime.jsx(Kbd2, { children: "Esc" }),
5237
5468
  " to close"
5238
5469
  ] }) })
5239
5470
  ]
@@ -5244,7 +5475,7 @@ var HelpOverlayRoot = ({
5244
5475
  );
5245
5476
  };
5246
5477
  var HelpOverlaySection = ({ title, className, children }) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: clsx.clsx("space-y-2", className), children: [
5247
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[11px] font-semibold tracking-wider text-gray-400 uppercase dark:text-gray-500", children: title }),
5478
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-2xs font-semibold tracking-wider text-gray-400 uppercase dark:text-gray-500", children: title }),
5248
5479
  /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "divide-y divide-gray-100 dark:divide-gray-800", children })
5249
5480
  ] });
5250
5481
  var HelpOverlayShortcut = ({ keys, description, className }) => {
@@ -5255,10 +5486,10 @@ var HelpOverlayShortcut = ({ keys, description, className }) => {
5255
5486
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 items-center gap-1", children: sequence.map((combo, idx) => {
5256
5487
  const parts = combo.split("+");
5257
5488
  return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
5258
- idx > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-0.5 text-[10px] text-gray-400 uppercase dark:text-gray-500", children: "then" }),
5489
+ idx > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-3xs px-0.5 text-gray-400 uppercase dark:text-gray-500", children: "then" }),
5259
5490
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center gap-1", children: parts.map((part, pIdx) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
5260
5491
  pIdx > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-400 dark:text-gray-500", children: "+" }),
5261
- /* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: formatKey(part, isMac) })
5492
+ /* @__PURE__ */ jsxRuntime.jsx(Kbd2, { children: formatKey(part, isMac) })
5262
5493
  ] }, `${part}-${pIdx}`)) })
5263
5494
  ] }, `${combo}-${idx}`);
5264
5495
  }) })
@@ -5518,13 +5749,14 @@ var StepperInput = ({
5518
5749
  className
5519
5750
  }) => {
5520
5751
  const clamp = (v) => Math.min(max, Math.max(min, v));
5521
- const arrowBtn = "flex flex-1 items-center justify-center px-1.5 transition-colors hover:bg-gray-50 dark:hover:bg-white/5 disabled:cursor-not-allowed disabled:opacity-40";
5752
+ const arrowBtn = "flex flex-1 items-center justify-center text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 active:bg-gray-200 disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent dark:text-gray-400 dark:hover:bg-white/10 dark:hover:text-gray-200 dark:active:bg-white/15";
5522
5753
  return /* @__PURE__ */ jsxRuntime.jsxs(
5523
5754
  "div",
5524
5755
  {
5525
5756
  className: clsx.clsx(
5526
5757
  fullWidth ? "flex w-full" : "inline-flex",
5527
- "h-9 overflow-hidden rounded-lg border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800",
5758
+ // dark:focus-within: is explicit, dark:border-gray-700 would win otherwise.
5759
+ "focus-within:border-brand-500 dark:focus-within:border-brand-500 h-9 overflow-hidden rounded-lg border border-gray-200 bg-white transition-colors dark:border-gray-700 dark:bg-gray-800",
5528
5760
  disabled && "opacity-50",
5529
5761
  className
5530
5762
  ),
@@ -5543,13 +5775,14 @@ var StepperInput = ({
5543
5775
  max,
5544
5776
  step,
5545
5777
  className: clsx.clsx(
5546
- "h-full [appearance:textfield] bg-transparent pr-1 pl-3 text-sm font-medium text-gray-700 focus:outline-none disabled:cursor-not-allowed dark:text-gray-200 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
5778
+ // min-w-0: in a narrower container the input gives way, not the arrows.
5779
+ "h-full min-w-0 [appearance:textfield] bg-transparent pr-1 pl-3 text-sm font-medium text-gray-700 focus:outline-none disabled:cursor-not-allowed dark:text-gray-200 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
5547
5780
  fullWidth ? "flex-1" : width
5548
5781
  )
5549
5782
  }
5550
5783
  ),
5551
- unit && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center pr-1.5 text-xs text-gray-400 select-none dark:text-gray-500", children: unit }),
5552
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col border-l border-gray-200 dark:border-gray-700", children: [
5784
+ unit && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex shrink-0 items-center pr-1.5 text-xs text-gray-400 select-none dark:text-gray-500", children: unit }),
5785
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-7 shrink-0 flex-col border-l border-gray-200 dark:border-gray-700", children: [
5553
5786
  /* @__PURE__ */ jsxRuntime.jsx(
5554
5787
  "button",
5555
5788
  {
@@ -5559,7 +5792,7 @@ var StepperInput = ({
5559
5792
  tabIndex: -1,
5560
5793
  "aria-label": "Increase",
5561
5794
  className: arrowBtn,
5562
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "h-3.5 w-3.5 text-gray-500 dark:text-gray-400", strokeWidth: 2.5 })
5795
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "h-3 w-3", strokeWidth: 2.25, "aria-hidden": true })
5563
5796
  }
5564
5797
  ),
5565
5798
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -5571,7 +5804,7 @@ var StepperInput = ({
5571
5804
  tabIndex: -1,
5572
5805
  "aria-label": "Decrease",
5573
5806
  className: clsx.clsx("border-t border-gray-200 dark:border-gray-700", arrowBtn),
5574
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3.5 w-3.5 text-gray-500 dark:text-gray-400", strokeWidth: 2.5 })
5807
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3 w-3", strokeWidth: 2.25, "aria-hidden": true })
5575
5808
  }
5576
5809
  )
5577
5810
  ] })
@@ -6648,7 +6881,7 @@ var Calendar = ({ classNames, components, className, ...rest }) => {
6648
6881
  months_dropdown: "",
6649
6882
  years_dropdown: "",
6650
6883
  weekdays: clsx.clsx(def.weekdays, ""),
6651
- weekday: "h-8 w-8 text-center text-[11px] font-medium text-gray-400 dark:text-gray-500",
6884
+ weekday: "h-8 w-8 text-center text-2xs font-medium text-gray-400 dark:text-gray-500",
6652
6885
  week: clsx.clsx(def.week, ""),
6653
6886
  day: "h-8 w-8 p-0 text-center align-middle",
6654
6887
  day_button: "inline-flex h-8 w-8 items-center justify-center rounded-md text-sm text-gray-700 transition-colors hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-white/5",
@@ -7004,7 +7237,7 @@ var OtpInput = ({
7004
7237
  }) => {
7005
7238
  const refs = react.useRef([]);
7006
7239
  react.useEffect(() => {
7007
- if (autoFocus) refs.current[0]?.focus();
7240
+ if (autoFocus) refs.current[0]?.focus({ preventScroll: true });
7008
7241
  }, [autoFocus]);
7009
7242
  const setCell = (idx, char) => {
7010
7243
  const cleaned = sanitize(char, alphanumeric).slice(0, 1);
@@ -7366,30 +7599,84 @@ var StepperIndicator = ({
7366
7599
  children: Icon2 ? /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-5 w-5" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2 w-2 rounded-full bg-current" })
7367
7600
  }
7368
7601
  );
7602
+ var Meta = ({ meta }) => meta ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: meta }) : null;
7369
7603
  var Body5 = ({ item }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 pb-2 last:pb-0", children: [
7370
7604
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: item.title }),
7371
7605
  item.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: item.description }),
7372
- item.time && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 font-mono text-[10px] text-gray-400 uppercase", children: item.time })
7606
+ /* @__PURE__ */ jsxRuntime.jsx(Meta, { meta: item.meta }),
7607
+ item.time && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-3xs mt-0.5 font-mono text-gray-400 uppercase", children: item.time })
7373
7608
  ] });
7374
- var Timeline = ({ items, variant = "dot", className }) => {
7609
+ var TimelineList = ({
7610
+ items,
7611
+ variant = "dot",
7612
+ className,
7613
+ startIndex = 0,
7614
+ labelledBy
7615
+ }) => {
7375
7616
  if (variant === "card") {
7376
- return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: clsx.clsx("space-y-3", className), children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
7617
+ return /* @__PURE__ */ jsxRuntime.jsx("ol", { "aria-labelledby": labelledBy, className: clsx.clsx("space-y-3", className), children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
7377
7618
  "li",
7378
7619
  {
7379
7620
  className: "rounded-xl border border-gray-200 bg-white p-3 dark:border-gray-800 dark:bg-gray-900",
7380
7621
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
7381
7622
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
7382
7623
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: item.title }),
7383
- item.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: item.description })
7624
+ item.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: item.description }),
7625
+ /* @__PURE__ */ jsxRuntime.jsx(Meta, { meta: item.meta })
7384
7626
  ] }),
7385
- item.time && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 font-mono text-[10px] text-gray-400 uppercase", children: item.time })
7627
+ item.time && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-3xs shrink-0 font-mono text-gray-400 uppercase", children: item.time })
7386
7628
  ] })
7387
7629
  },
7388
7630
  item.id
7389
7631
  )) });
7390
7632
  }
7633
+ if (variant === "alternating") {
7634
+ return /* @__PURE__ */ jsxRuntime.jsx("ol", { "aria-labelledby": labelledBy, className: clsx.clsx("flex flex-col", className), children: items.map((item, i) => {
7635
+ const isLast = i === items.length - 1;
7636
+ const left = (startIndex + i) % 2 === 0;
7637
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7638
+ "li",
7639
+ {
7640
+ className: "grid grid-cols-[2.5rem_minmax(0,1fr)] gap-x-4 md:grid-cols-[minmax(0,1fr)_2.5rem_minmax(0,1fr)]",
7641
+ children: [
7642
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-start-1 row-start-1 flex flex-col items-center md:col-start-2", children: [
7643
+ /* @__PURE__ */ jsxRuntime.jsx(StepperIndicator, { icon: item.icon, tone: item.tone }),
7644
+ !isLast && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "my-1 w-px flex-1 bg-gray-200 dark:bg-gray-700" })
7645
+ ] }),
7646
+ /* @__PURE__ */ jsxRuntime.jsx(
7647
+ "div",
7648
+ {
7649
+ className: clsx.clsx(
7650
+ "col-start-2 row-start-1",
7651
+ left ? "md:col-start-1" : "md:col-start-3",
7652
+ !isLast && "pb-6"
7653
+ ),
7654
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900", children: [
7655
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: item.title }),
7656
+ item.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: item.description }),
7657
+ /* @__PURE__ */ jsxRuntime.jsx(Meta, { meta: item.meta }),
7658
+ item.time && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-3xs mt-2 font-mono text-gray-400 uppercase md:hidden", children: item.time })
7659
+ ] })
7660
+ }
7661
+ ),
7662
+ item.time && /* @__PURE__ */ jsxRuntime.jsx(
7663
+ "p",
7664
+ {
7665
+ className: clsx.clsx(
7666
+ "text-3xs row-start-1 hidden pt-3 font-mono text-gray-400 uppercase md:block",
7667
+ left ? "md:col-start-3" : "md:col-start-1 md:text-right"
7668
+ ),
7669
+ children: item.time
7670
+ }
7671
+ )
7672
+ ]
7673
+ },
7674
+ item.id
7675
+ );
7676
+ }) });
7677
+ }
7391
7678
  const gap = variant === "stepper" ? "gap-x-4" : "gap-x-3";
7392
- return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: clsx.clsx("flex flex-col", className), children: items.map((item, i) => {
7679
+ return /* @__PURE__ */ jsxRuntime.jsx("ol", { "aria-labelledby": labelledBy, className: clsx.clsx("flex flex-col", className), children: items.map((item, i) => {
7393
7680
  const isLast = i === items.length - 1;
7394
7681
  return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: clsx.clsx("flex", gap), children: [
7395
7682
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
@@ -7400,7 +7687,50 @@ var Timeline = ({ items, variant = "dot", className }) => {
7400
7687
  ] }, item.id);
7401
7688
  }) });
7402
7689
  };
7403
- var WEEK_DAYS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
7690
+ var groupRuns = (items) => {
7691
+ const runs = [];
7692
+ items.forEach((item, i) => {
7693
+ const last = runs[runs.length - 1];
7694
+ if (last && last.group === item.group) last.items.push(item);
7695
+ else runs.push({ group: item.group, start: i, items: [item] });
7696
+ });
7697
+ return runs;
7698
+ };
7699
+ var GroupHeader = ({ id, label, centred }) => centred ? (
7700
+ // A pill on the line; it moves to the left with the line below `md`.
7701
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { id, className: "mb-4 flex md:justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full border border-gray-200 bg-white px-3 py-1 text-xs font-semibold text-gray-700 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-200", children: label }) })
7702
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
7703
+ "h3",
7704
+ {
7705
+ id,
7706
+ className: "mb-3 text-xs font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400",
7707
+ children: label
7708
+ }
7709
+ );
7710
+ var Timeline = ({ items, variant = "dot", className }) => {
7711
+ const baseId = react.useId();
7712
+ const runs = groupRuns(items);
7713
+ if (runs.every((run) => !run.group)) {
7714
+ return /* @__PURE__ */ jsxRuntime.jsx(TimelineList, { items, variant, className });
7715
+ }
7716
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("space-y-6", className), children: runs.map((run, i) => {
7717
+ const headerId = `${baseId}-group-${i}`;
7718
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7719
+ run.group && /* @__PURE__ */ jsxRuntime.jsx(GroupHeader, { id: headerId, label: run.group, centred: variant === "alternating" }),
7720
+ /* @__PURE__ */ jsxRuntime.jsx(
7721
+ TimelineList,
7722
+ {
7723
+ items: run.items,
7724
+ variant,
7725
+ startIndex: run.start,
7726
+ labelledBy: run.group ? headerId : void 0
7727
+ }
7728
+ )
7729
+ ] }, run.start);
7730
+ }) });
7731
+ };
7732
+
7733
+ // src/data/calendar-dates.ts
7404
7734
  var MONTHS = [
7405
7735
  "January",
7406
7736
  "February",
@@ -7417,6 +7747,8 @@ var MONTHS = [
7417
7747
  ];
7418
7748
  var isoDate = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
7419
7749
  var sameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
7750
+ var isoWeekday = (d) => (d.getDay() + 6) % 7;
7751
+ var WEEK_DAYS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
7420
7752
  var MiniCalendar = ({
7421
7753
  today = /* @__PURE__ */ new Date(),
7422
7754
  selected,
@@ -7428,7 +7760,7 @@ var MiniCalendar = ({
7428
7760
  const cells = react.useMemo(() => {
7429
7761
  const firstOfMonth = new Date(view.getFullYear(), view.getMonth(), 1);
7430
7762
  const daysInMonth = new Date(view.getFullYear(), view.getMonth() + 1, 0).getDate();
7431
- const isoOffset = (firstOfMonth.getDay() + 6) % 7;
7763
+ const isoOffset = isoWeekday(firstOfMonth);
7432
7764
  const arr = Array(isoOffset).fill(null);
7433
7765
  for (let d = 1; d <= daysInMonth; d++)
7434
7766
  arr.push(new Date(view.getFullYear(), view.getMonth(), d));
@@ -7485,7 +7817,7 @@ var MiniCalendar = ({
7485
7817
  WEEK_DAYS.map((d) => /* @__PURE__ */ jsxRuntime.jsx(
7486
7818
  "span",
7487
7819
  {
7488
- className: "py-1 text-[10px] font-semibold tracking-wider text-gray-400 uppercase",
7820
+ className: "text-3xs py-1 font-semibold tracking-wider text-gray-400 uppercase",
7489
7821
  children: d
7490
7822
  },
7491
7823
  d
@@ -7525,6 +7857,275 @@ var MiniCalendar = ({
7525
7857
  }
7526
7858
  );
7527
7859
  };
7860
+ var WEEK_DAYS2 = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
7861
+ var WEEK_DAYS_LONG = [
7862
+ "Monday",
7863
+ "Tuesday",
7864
+ "Wednesday",
7865
+ "Thursday",
7866
+ "Friday",
7867
+ "Saturday",
7868
+ "Sunday"
7869
+ ];
7870
+ var MAX_CHIPS = 3;
7871
+ var TONE_DOT = {
7872
+ brand: "bg-brand-500",
7873
+ success: "bg-green-500",
7874
+ warning: "bg-amber-500",
7875
+ danger: "bg-red-500",
7876
+ info: "bg-blue-500",
7877
+ violet: "bg-violet-500"
7878
+ };
7879
+ var TONE_CHIP = {
7880
+ brand: "bg-brand-50 dark:bg-brand-500/15",
7881
+ success: "bg-green-50 dark:bg-green-500/15",
7882
+ warning: "bg-amber-50 dark:bg-amber-500/15",
7883
+ danger: "bg-red-50 dark:bg-red-500/15",
7884
+ info: "bg-blue-50 dark:bg-blue-500/15",
7885
+ violet: "bg-violet-50 dark:bg-violet-500/15"
7886
+ };
7887
+ var TONE_CHIP_HOVER = {
7888
+ brand: "hover:bg-brand-100 dark:hover:bg-brand-500/25",
7889
+ success: "hover:bg-green-100 dark:hover:bg-green-500/25",
7890
+ warning: "hover:bg-amber-100 dark:hover:bg-amber-500/25",
7891
+ danger: "hover:bg-red-100 dark:hover:bg-red-500/25",
7892
+ info: "hover:bg-blue-100 dark:hover:bg-blue-500/25",
7893
+ violet: "hover:bg-violet-100 dark:hover:bg-violet-500/25"
7894
+ };
7895
+ var FOCUS_RING = "focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-500";
7896
+ var addDays = (d, n) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + n);
7897
+ var startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
7898
+ var startOfMonth = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
7899
+ var dayLabel = (d) => `${WEEK_DAYS_LONG[isoWeekday(d)]} ${d.getDate()} ${MONTHS[d.getMonth()]} ${d.getFullYear()}`;
7900
+ var monthGrid = (month) => {
7901
+ const first = startOfMonth(month);
7902
+ const last = new Date(first.getFullYear(), first.getMonth() + 1, 0);
7903
+ const end = addDays(last, 6 - isoWeekday(last));
7904
+ const days = [];
7905
+ for (let d = addDays(first, -isoWeekday(first)); d <= end; d = addDays(d, 1)) days.push(d);
7906
+ return days;
7907
+ };
7908
+ var indexByDay = (events, first, last) => {
7909
+ const byDay = /* @__PURE__ */ new Map();
7910
+ const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime());
7911
+ for (const event of sorted) {
7912
+ const start = startOfDay(event.start);
7913
+ const end = event.end && event.end > event.start ? startOfDay(event.end) : start;
7914
+ const to = end < last ? end : last;
7915
+ for (let d = start < first ? first : start; d <= to; d = addDays(d, 1)) {
7916
+ const key = isoDate(d);
7917
+ const list = byDay.get(key);
7918
+ if (list) list.push(event);
7919
+ else byDay.set(key, [event]);
7920
+ }
7921
+ }
7922
+ return byDay;
7923
+ };
7924
+ var EventChip = ({
7925
+ event,
7926
+ onClick,
7927
+ compact = false
7928
+ }) => {
7929
+ const tone = event.tone ?? "brand";
7930
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7931
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: clsx.clsx("h-1.5 w-1.5 shrink-0 rounded-full", TONE_DOT[tone]) }),
7932
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: clsx.clsx("truncate", compact && "max-sm:sr-only"), children: event.title })
7933
+ ] });
7934
+ const className = clsx.clsx(
7935
+ "flex min-w-0 items-center gap-1.5 rounded-md px-1.5 py-0.5 text-left text-xs text-gray-700 dark:text-gray-200",
7936
+ TONE_CHIP[tone],
7937
+ compact ? "max-sm:bg-transparent max-sm:px-1 sm:w-full max-sm:dark:bg-transparent" : "w-full"
7938
+ );
7939
+ if (!onClick) {
7940
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { title: event.title, className, children: content });
7941
+ }
7942
+ return /* @__PURE__ */ jsxRuntime.jsx(
7943
+ "button",
7944
+ {
7945
+ type: "button",
7946
+ title: event.title,
7947
+ onClick: () => onClick(event),
7948
+ className: clsx.clsx(className, TONE_CHIP_HOVER[tone], FOCUS_RING),
7949
+ children: content
7950
+ }
7951
+ );
7952
+ };
7953
+ var EventCalendar = ({
7954
+ events,
7955
+ month,
7956
+ defaultMonth,
7957
+ onMonthChange,
7958
+ today = /* @__PURE__ */ new Date(),
7959
+ onEventClick,
7960
+ onDayClick,
7961
+ className
7962
+ }) => {
7963
+ const [internalMonth, setInternalMonth] = react.useState(() => startOfMonth(defaultMonth ?? today));
7964
+ const [openDay, setOpenDay] = react.useState(null);
7965
+ const shown = startOfMonth(month ?? internalMonth);
7966
+ const { days, byDay } = react.useMemo(() => {
7967
+ const grid = monthGrid(month ?? internalMonth);
7968
+ return { days: grid, byDay: indexByDay(events, grid[0], grid[grid.length - 1]) };
7969
+ }, [events, month, internalMonth]);
7970
+ const goTo = (next) => {
7971
+ if (month === void 0) setInternalMonth(next);
7972
+ onMonthChange?.(next);
7973
+ };
7974
+ const isTodayMonth = shown.getFullYear() === today.getFullYear() && shown.getMonth() === today.getMonth();
7975
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7976
+ "div",
7977
+ {
7978
+ className: clsx.clsx(
7979
+ "overflow-hidden rounded-2xl border border-gray-200 bg-white dark:border-gray-800 dark:bg-gray-900",
7980
+ className
7981
+ ),
7982
+ children: [
7983
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3 px-4 py-3", children: [
7984
+ /* @__PURE__ */ jsxRuntime.jsxs("h3", { "aria-live": "polite", className: "text-base font-semibold text-[var(--color-text-primary)]", children: [
7985
+ MONTHS[shown.getMonth()],
7986
+ " ",
7987
+ shown.getFullYear()
7988
+ ] }),
7989
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
7990
+ /* @__PURE__ */ jsxRuntime.jsx(
7991
+ Button,
7992
+ {
7993
+ variant: "secondary",
7994
+ size: "sm",
7995
+ onClick: () => goTo(startOfMonth(today)),
7996
+ disabled: isTodayMonth,
7997
+ className: "mr-1",
7998
+ children: "Today"
7999
+ }
8000
+ ),
8001
+ /* @__PURE__ */ jsxRuntime.jsx(
8002
+ "button",
8003
+ {
8004
+ type: "button",
8005
+ onClick: () => goTo(new Date(shown.getFullYear(), shown.getMonth() - 1, 1)),
8006
+ "aria-label": "Previous month",
8007
+ className: clsx.clsx(
8008
+ "flex h-8 w-8 items-center justify-center rounded-lg text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-gray-200",
8009
+ FOCUS_RING
8010
+ ),
8011
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4", "aria-hidden": true })
8012
+ }
8013
+ ),
8014
+ /* @__PURE__ */ jsxRuntime.jsx(
8015
+ "button",
8016
+ {
8017
+ type: "button",
8018
+ onClick: () => goTo(new Date(shown.getFullYear(), shown.getMonth() + 1, 1)),
8019
+ "aria-label": "Next month",
8020
+ className: clsx.clsx(
8021
+ "flex h-8 w-8 items-center justify-center rounded-lg text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-gray-200",
8022
+ FOCUS_RING
8023
+ ),
8024
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4", "aria-hidden": true })
8025
+ }
8026
+ )
8027
+ ] })
8028
+ ] }),
8029
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 border-y border-gray-200 dark:border-gray-800", "aria-hidden": true, children: WEEK_DAYS2.map((d) => /* @__PURE__ */ jsxRuntime.jsx(
8030
+ "span",
8031
+ {
8032
+ className: "text-2xs py-2 text-center font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400",
8033
+ children: d
8034
+ },
8035
+ d
8036
+ )) }),
8037
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "-mb-px grid grid-cols-7", children: days.map((day, i) => {
8038
+ const key = isoDate(day);
8039
+ const label = dayLabel(day);
8040
+ const dayEvents = byDay.get(key) ?? [];
8041
+ const hidden = dayEvents.length - MAX_CHIPS;
8042
+ const outside = day.getMonth() !== shown.getMonth();
8043
+ const isToday = sameDay(day, today);
8044
+ const numberClass = clsx.clsx(
8045
+ "inline-flex h-6 min-w-6 items-center justify-center rounded-full px-1 text-xs font-medium",
8046
+ isToday ? "bg-brand-500 text-white" : outside ? "text-gray-400 dark:text-gray-500" : "text-gray-700 dark:text-gray-200"
8047
+ );
8048
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8049
+ "div",
8050
+ {
8051
+ role: "group",
8052
+ "aria-label": label,
8053
+ className: clsx.clsx(
8054
+ "min-h-20 min-w-0 border-b border-gray-200 p-1.5 sm:min-h-28 dark:border-gray-800",
8055
+ i % 7 !== 6 && "border-r",
8056
+ outside && "bg-gray-50 dark:bg-white/[0.02]"
8057
+ ),
8058
+ children: [
8059
+ onDayClick ? /* @__PURE__ */ jsxRuntime.jsx(
8060
+ "button",
8061
+ {
8062
+ type: "button",
8063
+ "aria-label": label,
8064
+ "aria-current": isToday ? "date" : void 0,
8065
+ onClick: () => onDayClick(day),
8066
+ className: clsx.clsx(
8067
+ numberClass,
8068
+ !isToday && "hover:bg-gray-100 dark:hover:bg-white/5",
8069
+ FOCUS_RING
8070
+ ),
8071
+ children: day.getDate()
8072
+ }
8073
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
8074
+ "time",
8075
+ {
8076
+ dateTime: key,
8077
+ "aria-current": isToday ? "date" : void 0,
8078
+ className: numberClass,
8079
+ children: day.getDate()
8080
+ }
8081
+ ),
8082
+ dayEvents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-1 flex flex-wrap gap-0.5 sm:flex-col sm:flex-nowrap", children: dayEvents.slice(0, MAX_CHIPS).map((event) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(EventChip, { event, onClick: onEventClick, compact: true }) }, event.id)) }),
8083
+ hidden > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
8084
+ Popover,
8085
+ {
8086
+ open: openDay === key,
8087
+ onOpenChange: (open) => setOpenDay(open ? key : null),
8088
+ children: [
8089
+ /* @__PURE__ */ jsxRuntime.jsxs(
8090
+ Popover.Trigger,
8091
+ {
8092
+ "aria-label": `+${hidden} more on ${label}`,
8093
+ className: clsx.clsx(
8094
+ "mt-0.5 rounded px-1.5 text-xs font-medium text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white",
8095
+ FOCUS_RING
8096
+ ),
8097
+ children: [
8098
+ "+",
8099
+ hidden,
8100
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-sm:sr-only", children: " more" })
8101
+ ]
8102
+ }
8103
+ ),
8104
+ /* @__PURE__ */ jsxRuntime.jsxs(Popover.Content, { "aria-label": `Events on ${label}`, width: "w-60", children: [
8105
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-xs font-semibold text-[var(--color-text-primary)]", children: label }),
8106
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", children: dayEvents.map((event) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
8107
+ EventChip,
8108
+ {
8109
+ event,
8110
+ onClick: onEventClick && ((e) => {
8111
+ setOpenDay(null);
8112
+ onEventClick(e);
8113
+ })
8114
+ }
8115
+ ) }, event.id)) })
8116
+ ] })
8117
+ ]
8118
+ }
8119
+ )
8120
+ ]
8121
+ },
8122
+ key
8123
+ );
8124
+ }) })
8125
+ ]
8126
+ }
8127
+ );
8128
+ };
7528
8129
  var ColumnFilterDropdown = ({
7529
8130
  values,
7530
8131
  selected,
@@ -7589,6 +8190,16 @@ var ColumnFilterDropdown = ({
7589
8190
  }
7590
8191
  );
7591
8192
  };
8193
+
8194
+ // src/table/density.ts
8195
+ var HEADER_CELL_PADDING = {
8196
+ default: "py-3",
8197
+ comfortable: "py-4"
8198
+ };
8199
+ var BODY_CELL_PADDING = {
8200
+ default: "py-3.5",
8201
+ comfortable: "py-5"
8202
+ };
7592
8203
  var ALIGN_CLASS2 = {
7593
8204
  left: "text-left",
7594
8205
  right: "text-right",
@@ -7605,6 +8216,7 @@ var ColumnHeader = ({
7605
8216
  filterSelected,
7606
8217
  onFilterToggle,
7607
8218
  onFilterClear,
8219
+ density = "default",
7608
8220
  className
7609
8221
  }) => {
7610
8222
  const [open, setOpen] = react.useState(false);
@@ -7622,7 +8234,9 @@ var ColumnHeader = ({
7622
8234
  "th",
7623
8235
  {
7624
8236
  className: clsx.clsx(
7625
- "bg-gray-50 px-4 py-3 text-xs font-semibold tracking-wider text-gray-500 uppercase dark:bg-gray-800 dark:text-gray-400",
8237
+ "bg-gray-50 px-4",
8238
+ HEADER_CELL_PADDING[density],
8239
+ "text-xs font-semibold tracking-wider text-gray-500 uppercase dark:bg-gray-800 dark:text-gray-400",
7626
8240
  ALIGN_CLASS2[align],
7627
8241
  className
7628
8242
  ),
@@ -7649,11 +8263,11 @@ var ColumnHeader = ({
7649
8263
  "aria-label": "Filter column",
7650
8264
  className: clsx.clsx(
7651
8265
  "flex items-center gap-1 rounded p-0.5 transition-colors hover:bg-gray-200 dark:hover:bg-white/10",
7652
- filterCount > 0 && "text-brand-500"
8266
+ filterCount > 0 && "text-brand-600 dark:text-brand-400"
7653
8267
  ),
7654
8268
  children: [
7655
8269
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "h-3 w-3" }),
7656
- filterCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px]", children: filterCount })
8270
+ filterCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-3xs", children: filterCount })
7657
8271
  ]
7658
8272
  }
7659
8273
  ),
@@ -7853,6 +8467,7 @@ var DataTable = ({
7853
8467
  onRetry,
7854
8468
  emptyTitle = "No results",
7855
8469
  emptyDescription,
8470
+ density = "default",
7856
8471
  selectable = false,
7857
8472
  selection: selectionProp,
7858
8473
  defaultSelection,
@@ -8079,15 +8694,25 @@ var DataTable = ({
8079
8694
  renderRowAction && /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: "8%" } })
8080
8695
  ] }),
8081
8696
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "sticky top-0 z-10", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b border-gray-100 dark:border-gray-800", children: [
8082
- selectable && /* @__PURE__ */ jsxRuntime.jsx("th", { className: "bg-gray-50 px-4 py-3 dark:bg-gray-800", children: /* @__PURE__ */ jsxRuntime.jsx(
8083
- Checkbox,
8697
+ selectable && /* @__PURE__ */ jsxRuntime.jsx(
8698
+ "th",
8084
8699
  {
8085
- "aria-label": "Select all rows",
8086
- checked: allVisibleSelected,
8087
- indeterminate: someVisibleSelected,
8088
- onChange: toggleAllVisible
8700
+ className: clsx.clsx(
8701
+ "bg-gray-50 px-4",
8702
+ HEADER_CELL_PADDING[density],
8703
+ "dark:bg-gray-800"
8704
+ ),
8705
+ children: /* @__PURE__ */ jsxRuntime.jsx(
8706
+ Checkbox,
8707
+ {
8708
+ "aria-label": "Select all rows",
8709
+ checked: allVisibleSelected,
8710
+ indeterminate: someVisibleSelected,
8711
+ onChange: toggleAllVisible
8712
+ }
8713
+ )
8089
8714
  }
8090
- ) }),
8715
+ ),
8091
8716
  columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
8092
8717
  ColumnHeader,
8093
8718
  {
@@ -8100,11 +8725,22 @@ var DataTable = ({
8100
8725
  filterValues: columnFilterValues[col.key],
8101
8726
  filterSelected: filters[col.key],
8102
8727
  onFilterToggle: (v) => handleFilterToggle(col.key, v),
8103
- onFilterClear: () => clearFilter(col.key)
8728
+ onFilterClear: () => clearFilter(col.key),
8729
+ density
8104
8730
  },
8105
8731
  col.key
8106
8732
  )),
8107
- renderRowAction && /* @__PURE__ */ jsxRuntime.jsx("th", { className: "bg-gray-50 px-4 py-3 text-right text-xs font-semibold tracking-wider text-gray-500 uppercase dark:bg-gray-800 dark:text-gray-400", children: "Action" })
8733
+ renderRowAction && /* @__PURE__ */ jsxRuntime.jsx(
8734
+ "th",
8735
+ {
8736
+ className: clsx.clsx(
8737
+ "bg-gray-50 px-4",
8738
+ HEADER_CELL_PADDING[density],
8739
+ "text-right text-xs font-semibold tracking-wider text-gray-500 uppercase dark:bg-gray-800 dark:text-gray-400"
8740
+ ),
8741
+ children: "Action"
8742
+ }
8743
+ )
8108
8744
  ] }) }),
8109
8745
  /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-gray-100 dark:divide-gray-800", children: pageRows.map((row) => {
8110
8746
  const key = rowKey(row);
@@ -8117,7 +8753,7 @@ var DataTable = ({
8117
8753
  isSelected && "bg-brand-50/40 dark:bg-brand-500/5"
8118
8754
  ),
8119
8755
  children: [
8120
- selectable && /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3.5", children: /* @__PURE__ */ jsxRuntime.jsx(
8756
+ selectable && /* @__PURE__ */ jsxRuntime.jsx("td", { className: clsx.clsx("px-4", BODY_CELL_PADDING[density]), children: /* @__PURE__ */ jsxRuntime.jsx(
8121
8757
  Checkbox,
8122
8758
  {
8123
8759
  "aria-label": `Select row ${key}`,
@@ -8128,12 +8764,17 @@ var DataTable = ({
8128
8764
  columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
8129
8765
  "td",
8130
8766
  {
8131
- className: clsx.clsx("px-4 py-3.5 text-sm", ALIGN_CELL[col.align ?? "left"]),
8767
+ className: clsx.clsx(
8768
+ "px-4",
8769
+ BODY_CELL_PADDING[density],
8770
+ "text-sm",
8771
+ ALIGN_CELL[col.align ?? "left"]
8772
+ ),
8132
8773
  children: col.render(row)
8133
8774
  },
8134
8775
  col.key
8135
8776
  )),
8136
- renderRowAction && /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-3.5 text-right", children: renderRowAction(row) })
8777
+ renderRowAction && /* @__PURE__ */ jsxRuntime.jsx("td", { className: clsx.clsx("px-4", BODY_CELL_PADDING[density], "text-right"), children: renderRowAction(row) })
8137
8778
  ]
8138
8779
  },
8139
8780
  key
@@ -8245,7 +8886,7 @@ var IntegrationCard = ({
8245
8886
  status && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: STATUS_VARIANT[status], appearance: "light", children: STATUS_LABEL2[status] })
8246
8887
  ] }),
8247
8888
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 min-w-0 flex-1", children: [
8248
- category && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-[10px] tracking-wide text-gray-400 uppercase dark:text-gray-500", children: category }),
8889
+ category && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-3xs font-mono tracking-wide text-gray-400 uppercase dark:text-gray-500", children: category }),
8249
8890
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mt-0.5 truncate text-sm font-semibold text-gray-900 dark:text-white", children: name }),
8250
8891
  description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 line-clamp-2 text-xs text-gray-600 dark:text-gray-400", children: description })
8251
8892
  ] }),
@@ -8417,7 +9058,7 @@ var SignInForm = ({
8417
9058
  {
8418
9059
  type: "button",
8419
9060
  onClick: onForgotPassword,
8420
- className: "text-brand-500 hover:text-brand-600 text-xs font-medium transition-colors",
9061
+ className: "text-brand-600 hover:text-brand-700 dark:text-brand-400 dark:hover:text-brand-300 text-xs font-medium transition-colors",
8421
9062
  children: forgotLabel
8422
9063
  }
8423
9064
  )
@@ -8760,7 +9401,7 @@ var TwoStepVerificationForm = ({
8760
9401
  type: "button",
8761
9402
  onClick: onResend,
8762
9403
  disabled: loading,
8763
- className: "text-brand-500 hover:text-brand-600 font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
9404
+ className: "text-brand-600 hover:text-brand-700 dark:text-brand-400 dark:hover:text-brand-300 font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
8764
9405
  children: resendLabel
8765
9406
  }
8766
9407
  )
@@ -8804,7 +9445,7 @@ var ColorSwatch = ({
8804
9445
  "span",
8805
9446
  {
8806
9447
  className: clsx.clsx(
8807
- "text-[10px] leading-none font-medium",
9448
+ "text-3xs leading-none font-medium",
8808
9449
  active ? "text-gray-700 dark:text-gray-200" : "text-gray-400 dark:text-gray-500"
8809
9450
  ),
8810
9451
  children: label
@@ -8876,7 +9517,7 @@ var PaletteCard = ({ meta, active = false, onClick, className }) => /* @__PURE__
8876
9517
  /* @__PURE__ */ jsxRuntime.jsxs(
8877
9518
  "div",
8878
9519
  {
8879
- className: "flex items-center justify-between px-2.5 py-1.5",
9520
+ className: "flex flex-1 items-center justify-between px-2.5 py-1.5",
8880
9521
  style: {
8881
9522
  backgroundColor: meta.preview.surface,
8882
9523
  borderTop: `1px solid ${meta.preview.border}`
@@ -8887,11 +9528,11 @@ var PaletteCard = ({ meta, active = false, onClick, className }) => /* @__PURE__
8887
9528
  "span",
8888
9529
  {
8889
9530
  className: "block text-xs font-semibold",
8890
- style: { color: active ? void 0 : "#6b7280" },
9531
+ style: { color: meta.preview.text ?? (active ? void 0 : "#6b7280") },
8891
9532
  children: meta.label
8892
9533
  }
8893
9534
  ),
8894
- meta.desc && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-[10px]", style: { color: "#9ca3af" }, children: meta.desc })
9535
+ meta.desc && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-3xs block", style: { color: meta.preview.text ?? "#9ca3af" }, children: meta.desc })
8895
9536
  ] }),
8896
9537
  active && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-brand-500 flex h-4 w-4 shrink-0 items-center justify-center rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-2.5 w-2.5 text-white", "aria-hidden": true }) })
8897
9538
  ]
@@ -8941,12 +9582,12 @@ var OptionCard = ({
8941
9582
  {
8942
9583
  className: clsx.clsx(
8943
9584
  "text-xs font-semibold",
8944
- active ? "text-brand-500" : "text-gray-700 dark:text-gray-300"
9585
+ active ? "text-brand-600 dark:text-brand-400" : "text-gray-700 dark:text-gray-300"
8945
9586
  ),
8946
9587
  children: label
8947
9588
  }
8948
9589
  ),
8949
- desc && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-gray-400 dark:text-gray-500", children: desc })
9590
+ desc && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-3xs text-gray-400 dark:text-gray-500", children: desc })
8950
9591
  ] }),
8951
9592
  active && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-brand-500 absolute top-1.5 right-1.5 flex h-4 w-4 items-center justify-center rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-2.5 w-2.5 text-white", "aria-hidden": true }) })
8952
9593
  ]
@@ -8977,7 +9618,220 @@ var OptionPicker = ({
8977
9618
  ))
8978
9619
  }
8979
9620
  );
8980
- var SIZE = {
9621
+
9622
+ // src/settings/appearance.ts
9623
+ var COSMOS_THEMES = [
9624
+ {
9625
+ id: "light",
9626
+ label: "Light",
9627
+ dark: false,
9628
+ preview: { bg: "#f9fafb", surface: "#ffffff", border: "#e5e7eb", text: "#667085" }
9629
+ },
9630
+ {
9631
+ id: "sand",
9632
+ label: "Sand",
9633
+ dark: false,
9634
+ preview: { bg: "#f9f5eb", surface: "#fffcf7", border: "#e7dfd0", text: "#746656" }
9635
+ },
9636
+ {
9637
+ id: "dark",
9638
+ label: "Dark",
9639
+ dark: true,
9640
+ preview: { bg: "#0a0a0a", surface: "#141414", border: "#3d3d3d", text: "#a3a3a3" }
9641
+ },
9642
+ {
9643
+ id: "deep-blue",
9644
+ label: "Deep Blue",
9645
+ dark: true,
9646
+ preview: { bg: "#0c111d", surface: "#101828", border: "#344054", text: "#98a2b3" }
9647
+ }
9648
+ ];
9649
+ var COSMOS_ACCENTS = [
9650
+ { id: "blue", label: "Blue", hex: "#465fff" },
9651
+ { id: "indigo", label: "Indigo", hex: "#5963e9" },
9652
+ { id: "violet", label: "Violet", hex: "#8745f1" },
9653
+ { id: "purple", label: "Purple", hex: "#ad2ecf" },
9654
+ { id: "rose", label: "Rose", hex: "#d4166d" },
9655
+ { id: "teal", label: "Teal", hex: "#038378" },
9656
+ { id: "cyan", label: "Cyan", hex: "#017f9d" },
9657
+ { id: "graphite", label: "Graphite", hex: "#707580" },
9658
+ { id: "red", label: "Red", hex: "#db192a" },
9659
+ { id: "orange", label: "Orange", hex: "#c04f01" },
9660
+ { id: "amber", label: "Amber", hex: "#a46800" },
9661
+ { id: "green", label: "Green", hex: "#02863c" }
9662
+ ];
9663
+ var COSMOS_FONTS = [
9664
+ { id: "outfit", label: "Outfit", family: "'Outfit', system-ui, sans-serif" },
9665
+ { id: "inter", label: "Inter", family: "'Inter Variable', system-ui, sans-serif" },
9666
+ { id: "plex", label: "IBM Plex Sans", family: "'IBM Plex Sans Variable', system-ui, sans-serif" },
9667
+ { id: "montserrat", label: "Montserrat", family: "'Montserrat Variable', system-ui, sans-serif" },
9668
+ { id: "open-sans", label: "Open Sans", family: "'Open Sans Variable', system-ui, sans-serif" },
9669
+ {
9670
+ id: "system",
9671
+ label: "System",
9672
+ family: "system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif"
9673
+ }
9674
+ ];
9675
+ var COSMOS_TEXT_SIZES = [
9676
+ { id: "sm", label: "Small", scale: 0.9375 },
9677
+ { id: "md", label: "Default", scale: 1 },
9678
+ { id: "lg", label: "Large", scale: 1.125 },
9679
+ { id: "xl", label: "Extra large", scale: 1.25 }
9680
+ ];
9681
+ var THEME_CLASSES = COSMOS_THEMES.map((t) => t.id).filter((id) => id !== "light");
9682
+ var isDarkTheme = (theme) => COSMOS_THEMES.some((t) => t.id === theme && t.dark);
9683
+ var applyAppearance = ({ theme, accent, font, textSize }, root) => {
9684
+ const el = root ?? (typeof document === "undefined" ? void 0 : document.documentElement);
9685
+ if (!el) return;
9686
+ el.classList.remove(...THEME_CLASSES);
9687
+ if (theme !== "light") el.classList.add(theme);
9688
+ if (accent === "blue") delete el.dataset.accent;
9689
+ else el.dataset.accent = accent;
9690
+ if (font === "outfit") delete el.dataset.font;
9691
+ else if (font) el.dataset.font = font;
9692
+ if (textSize === "md") delete el.dataset.textSize;
9693
+ else if (textSize) el.dataset.textSize = textSize;
9694
+ };
9695
+ var AppearanceSettings = ({
9696
+ theme,
9697
+ accent,
9698
+ onThemeChange,
9699
+ onAccentChange,
9700
+ themeLabel = "Theme",
9701
+ accentLabel = "Accent color",
9702
+ themes = COSMOS_THEMES,
9703
+ accents = COSMOS_ACCENTS,
9704
+ themeColumns = 4,
9705
+ font = "outfit",
9706
+ onFontChange,
9707
+ textSize = "md",
9708
+ onTextSizeChange,
9709
+ fontLabel = "Font",
9710
+ textSizeLabel = "Text size",
9711
+ fonts = COSMOS_FONTS,
9712
+ textSizes = COSMOS_TEXT_SIZES,
9713
+ className
9714
+ }) => {
9715
+ const themeHeadingId = react.useId();
9716
+ const accentHeadingId = react.useId();
9717
+ const fontHeadingId = react.useId();
9718
+ const textSizeHeadingId = react.useId();
9719
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx.clsx("space-y-6", className), children: [
9720
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-labelledby": themeHeadingId, children: [
9721
+ /* @__PURE__ */ jsxRuntime.jsx("p", { id: themeHeadingId, className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: themeLabel }),
9722
+ /* @__PURE__ */ jsxRuntime.jsx(
9723
+ PalettePicker,
9724
+ {
9725
+ className: "mt-3",
9726
+ palettes: themes,
9727
+ value: theme,
9728
+ cols: themeColumns,
9729
+ onChange: (id) => onThemeChange(id)
9730
+ }
9731
+ )
9732
+ ] }),
9733
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-labelledby": accentHeadingId, children: [
9734
+ /* @__PURE__ */ jsxRuntime.jsx("p", { id: accentHeadingId, className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: accentLabel }),
9735
+ /* @__PURE__ */ jsxRuntime.jsx(
9736
+ AccentPicker,
9737
+ {
9738
+ className: "mt-3",
9739
+ colors: accents,
9740
+ value: accent,
9741
+ onChange: (id) => onAccentChange(id),
9742
+ cols: 6
9743
+ }
9744
+ )
9745
+ ] }),
9746
+ onFontChange && /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-labelledby": fontHeadingId, children: [
9747
+ /* @__PURE__ */ jsxRuntime.jsx("p", { id: fontHeadingId, className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: fontLabel }),
9748
+ /* @__PURE__ */ jsxRuntime.jsx(
9749
+ OptionPicker,
9750
+ {
9751
+ className: "mt-3",
9752
+ cols: 3,
9753
+ value: font,
9754
+ onChange: (id) => onFontChange(id),
9755
+ options: fonts.map((f) => ({
9756
+ id: f.id,
9757
+ label: f.label,
9758
+ preview: /* @__PURE__ */ jsxRuntime.jsx(
9759
+ "span",
9760
+ {
9761
+ "aria-hidden": true,
9762
+ style: { fontFamily: f.family },
9763
+ className: "text-xl text-gray-900 dark:text-gray-100",
9764
+ children: "Aa"
9765
+ }
9766
+ )
9767
+ }))
9768
+ }
9769
+ )
9770
+ ] }),
9771
+ onTextSizeChange && /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-labelledby": textSizeHeadingId, children: [
9772
+ /* @__PURE__ */ jsxRuntime.jsx(
9773
+ "p",
9774
+ {
9775
+ id: textSizeHeadingId,
9776
+ className: "text-sm font-medium text-gray-700 dark:text-gray-300",
9777
+ children: textSizeLabel
9778
+ }
9779
+ ),
9780
+ /* @__PURE__ */ jsxRuntime.jsx(
9781
+ OptionPicker,
9782
+ {
9783
+ className: "mt-3",
9784
+ cols: 4,
9785
+ value: textSize,
9786
+ onChange: (id) => onTextSizeChange(id),
9787
+ options: textSizes.map((t) => ({
9788
+ id: t.id,
9789
+ label: t.label,
9790
+ // Pixel sizes, so the previews don't scale with the setting.
9791
+ preview: /* @__PURE__ */ jsxRuntime.jsx(
9792
+ "span",
9793
+ {
9794
+ "aria-hidden": true,
9795
+ style: { fontSize: `${16 * t.scale}px` },
9796
+ className: "text-gray-900 dark:text-gray-100",
9797
+ children: "Aa"
9798
+ }
9799
+ )
9800
+ }))
9801
+ }
9802
+ )
9803
+ ] })
9804
+ ] });
9805
+ };
9806
+ var SIZE_CLASS12 = {
9807
+ sm: { box: "h-8 w-8", icon: "h-4 w-4" },
9808
+ md: { box: "h-10 w-10", icon: "h-5 w-5" }
9809
+ };
9810
+ var AppearanceMenu = ({
9811
+ label = "Appearance",
9812
+ size = "md",
9813
+ className,
9814
+ ...settings
9815
+ }) => {
9816
+ const { box, icon } = SIZE_CLASS12[size];
9817
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { children: [
9818
+ /* @__PURE__ */ jsxRuntime.jsx(
9819
+ Popover.Trigger,
9820
+ {
9821
+ title: label,
9822
+ "aria-label": label,
9823
+ className: clsx.clsx(
9824
+ "flex items-center justify-center rounded-lg border border-gray-200 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-white",
9825
+ box,
9826
+ className
9827
+ ),
9828
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Palette, { className: icon, "aria-hidden": true })
9829
+ }
9830
+ ),
9831
+ /* @__PURE__ */ jsxRuntime.jsx(Popover.Content, { align: "end", width: "w-96", "aria-label": label, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "-m-4 max-h-[calc(100dvh-6rem)] overflow-y-auto p-4", children: /* @__PURE__ */ jsxRuntime.jsx(AppearanceSettings, { themeColumns: 2, ...settings }) }) })
9832
+ ] });
9833
+ };
9834
+ var SIZE2 = {
8981
9835
  sm: "text-base leading-relaxed",
8982
9836
  md: "text-lg leading-relaxed",
8983
9837
  lg: "text-2xl leading-snug"
@@ -8997,7 +9851,7 @@ var Blockquote = ({
8997
9851
  authorAvatar,
8998
9852
  className
8999
9853
  }) => {
9000
- const text = /* @__PURE__ */ jsxRuntime.jsx("p", { className: clsx.clsx("font-medium text-gray-700 italic dark:text-gray-200", SIZE[size]), children });
9854
+ const text = /* @__PURE__ */ jsxRuntime.jsx("p", { className: clsx.clsx("font-medium text-gray-700 italic dark:text-gray-200", SIZE2[size]), children });
9001
9855
  if (variant === "icon") {
9002
9856
  return /* @__PURE__ */ jsxRuntime.jsxs("blockquote", { className: clsx.clsx(ALIGN[align], className), children: [
9003
9857
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -9079,21 +9933,6 @@ var Blockquote = ({
9079
9933
  }
9080
9934
  );
9081
9935
  };
9082
- var SIZE2 = {
9083
- sm: "h-5 min-w-[20px] px-1.5 text-[10px]",
9084
- md: "h-6 min-w-[24px] px-2 text-xs"
9085
- };
9086
- var Kbd2 = ({ children, size = "md", className }) => /* @__PURE__ */ jsxRuntime.jsx(
9087
- "kbd",
9088
- {
9089
- className: clsx.clsx(
9090
- "inline-flex shrink-0 items-center justify-center rounded border border-gray-200 bg-gray-50 font-mono font-medium text-gray-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.04)] dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200 dark:shadow-[inset_0_-1px_0_0_rgba(255,255,255,0.04)]",
9091
- SIZE2[size],
9092
- className
9093
- ),
9094
- children
9095
- }
9096
- );
9097
9936
  var SIZE3 = {
9098
9937
  xs: "max-w-xs",
9099
9938
  sm: "max-w-sm",
@@ -9155,6 +9994,8 @@ exports.ActiveFiltersBar = ActiveFiltersBar;
9155
9994
  exports.ActivityFeed = ActivityFeed;
9156
9995
  exports.AlertBanner = AlertBanner;
9157
9996
  exports.AnnouncementBar = AnnouncementBar;
9997
+ exports.AppearanceMenu = AppearanceMenu;
9998
+ exports.AppearanceSettings = AppearanceSettings;
9158
9999
  exports.AuthLayout = AuthLayout;
9159
10000
  exports.Avatar = Avatar;
9160
10001
  exports.AvatarUploader = AvatarUploader;
@@ -9165,6 +10006,10 @@ exports.Blockquote = Blockquote;
9165
10006
  exports.Breadcrumb = Breadcrumb;
9166
10007
  exports.Button = Button;
9167
10008
  exports.ButtonGroup = ButtonGroup;
10009
+ exports.COSMOS_ACCENTS = COSMOS_ACCENTS;
10010
+ exports.COSMOS_FONTS = COSMOS_FONTS;
10011
+ exports.COSMOS_TEXT_SIZES = COSMOS_TEXT_SIZES;
10012
+ exports.COSMOS_THEMES = COSMOS_THEMES;
9168
10013
  exports.Calendar = Calendar;
9169
10014
  exports.Card = Card2;
9170
10015
  exports.Carousel = Carousel;
@@ -9194,6 +10039,7 @@ exports.Dropzone = Dropzone;
9194
10039
  exports.EmptyState = EmptyState;
9195
10040
  exports.ErrorPage = ErrorPage;
9196
10041
  exports.ErrorState = ErrorState;
10042
+ exports.EventCalendar = EventCalendar;
9197
10043
  exports.Figure = Figure;
9198
10044
  exports.FileInput = FileInput;
9199
10045
  exports.FilterPills = FilterPills;
@@ -9207,7 +10053,7 @@ exports.IconBox = IconBox;
9207
10053
  exports.ImageGrid = ImageGrid;
9208
10054
  exports.Input = Input;
9209
10055
  exports.IntegrationCard = IntegrationCard;
9210
- exports.Kbd = Kbd2;
10056
+ exports.Kbd = Kbd;
9211
10057
  exports.KpiCard = KpiCard;
9212
10058
  exports.Link = Link;
9213
10059
  exports.List = List2;
@@ -9226,7 +10072,6 @@ exports.OtpInput = OtpInput;
9226
10072
  exports.PageActionButton = PageActionButton;
9227
10073
  exports.PageActionIconButton = PageActionIconButton;
9228
10074
  exports.PageBreadcrumb = PageBreadcrumb;
9229
- exports.PageCard = PageCard;
9230
10075
  exports.PageHeader = PageHeader;
9231
10076
  exports.Pagination = Pagination;
9232
10077
  exports.PaletteCard = PaletteCard;
@@ -9287,7 +10132,9 @@ exports.UserMenu = UserMenu;
9287
10132
  exports.VerticalNavigation = VerticalNavigation;
9288
10133
  exports.VideoEmbed = VideoEmbed;
9289
10134
  exports.ZoomBar = ZoomBar;
10135
+ exports.applyAppearance = applyAppearance;
9290
10136
  exports.defaultPasswordRules = defaultPasswordRules;
10137
+ exports.isDarkTheme = isDarkTheme;
9291
10138
  exports.useAutoRefresh = useAutoRefresh;
9292
10139
  //# sourceMappingURL=index.cjs.map
9293
10140
  //# sourceMappingURL=index.cjs.map