@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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { clsx } from 'clsx';
2
2
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
3
- import { forwardRef, createContext, Children, Fragment, cloneElement, isValidElement, useState, useRef, useCallback, useEffect, useId, useContext, useMemo } from 'react';
4
- import { ChevronRight, Check, Copy, BellOff, Bell, CheckCircle2, Info, AlertTriangle, XCircle, ChevronDown, Sun, Moon, MoonStar, ExternalLink, Search, EyeOff, Eye, Minus, Paperclip, Clock, X, ChevronLeft, Dot as Dot$1, ArrowRight, HelpCircle, Home, Inbox, AlertCircle, CheckCircle, RefreshCw, Loader2, Save, Megaphone, Cookie, ArrowUp, ChevronUp, Plus, Maximize2, RotateCcw, Camera, Trash2, Upload, File, ChevronsUpDown, Filter, MailCheck, ArrowLeft, Mail, User, ShieldCheck, Quote, Calendar as Calendar$1 } from 'lucide-react';
3
+ import { forwardRef, createContext, useEffect, Children, Fragment, cloneElement, isValidElement, useState, useRef, useCallback, useId, useContext, useMemo } from 'react';
4
+ import { ChevronRight, Check, Copy, BellOff, Bell, CheckCircle2, Info, AlertTriangle, XCircle, ChevronDown, Sun, Moon, MoonStar, ExternalLink, Search, EyeOff, Eye, Minus, Paperclip, Clock, X, ChevronLeft, Dot as Dot$1, ArrowRight, HelpCircle, PanelLeftOpen, PanelLeftClose, Home, Inbox, AlertCircle, CheckCircle, RefreshCw, Loader2, Save, Megaphone, Cookie, ArrowUp, ChevronUp, Plus, Maximize2, RotateCcw, Camera, Trash2, Upload, File, ChevronsUpDown, Filter, MailCheck, ArrowLeft, Mail, User, ShieldCheck, Palette, Quote, Calendar as Calendar$1 } from 'lucide-react';
5
5
  import { createPortal } from 'react-dom';
6
6
  import Autoplay from 'embla-carousel-autoplay';
7
7
  import useEmblaCarousel from 'embla-carousel-react';
@@ -145,6 +145,7 @@ var Shell = ({
145
145
  defaultSidebarCollapsed = false,
146
146
  sidebarCollapsed: controlledCollapsed,
147
147
  onSidebarToggle,
148
+ collapseControl = "topbar",
148
149
  className
149
150
  }) => {
150
151
  const [internalCollapsed, setInternalCollapsed] = useState(defaultSidebarCollapsed);
@@ -154,12 +155,22 @@ var Shell = ({
154
155
  if (controlledCollapsed === void 0) setInternalCollapsed(next);
155
156
  onSidebarToggle?.(next);
156
157
  };
157
- const enhancedTopbar = topbar && sidebar ? cloneElement(topbar, {
158
- sidebarCollapsed: topbar.props.sidebarCollapsed ?? collapsed,
159
- onToggleSidebar: topbar.props.onToggleSidebar ?? handleToggle
160
- }) : topbar;
158
+ const inSidebar = collapseControl === "sidebar";
159
+ const enhancedTopbar = topbar && sidebar ? cloneElement(
160
+ topbar,
161
+ inSidebar ? (
162
+ // The control moved to the sidebar: no hamburger unless asked for.
163
+ { sidebarCollapsed: topbar.props.sidebarCollapsed ?? null }
164
+ ) : {
165
+ sidebarCollapsed: topbar.props.sidebarCollapsed ?? collapsed,
166
+ onToggleSidebar: topbar.props.onToggleSidebar ?? handleToggle
167
+ }
168
+ ) : topbar;
161
169
  const enhancedSidebar = sidebar ? cloneElement(sidebar, {
162
- collapsed: sidebar.props.collapsed ?? collapsed
170
+ collapsed: sidebar.props.collapsed ?? collapsed,
171
+ ...inSidebar && {
172
+ onCollapsedChange: sidebar.props.onCollapsedChange ?? handleToggle
173
+ }
163
174
  }) : sidebar;
164
175
  return /* @__PURE__ */ jsxs(
165
176
  "div",
@@ -244,17 +255,200 @@ var Topbar = ({
244
255
  ]
245
256
  }
246
257
  );
258
+ var PopoverContext = createContext(null);
259
+ var useCtx = () => {
260
+ const ctx = useContext(PopoverContext);
261
+ if (!ctx) throw new Error("Popover.* must be used inside <Popover>");
262
+ return ctx;
263
+ };
264
+ var PopoverRoot = ({
265
+ open: openProp,
266
+ defaultOpen = false,
267
+ onOpenChange,
268
+ children
269
+ }) => {
270
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
271
+ const isControlled = openProp !== void 0;
272
+ const open = isControlled ? openProp : internalOpen;
273
+ const triggerRef = useRef(null);
274
+ const [triggerRect, setTriggerRect] = useState(null);
275
+ const refreshRect = useCallback(() => {
276
+ if (triggerRef.current) setTriggerRect(triggerRef.current.getBoundingClientRect());
277
+ }, []);
278
+ const setOpen = useCallback(
279
+ (v) => {
280
+ if (v) refreshRect();
281
+ if (!isControlled) setInternalOpen(v);
282
+ onOpenChange?.(v);
283
+ },
284
+ [isControlled, onOpenChange, refreshRect]
285
+ );
286
+ useEffect(() => {
287
+ if (!open) return;
288
+ const handler = () => refreshRect();
289
+ window.addEventListener("resize", handler);
290
+ window.addEventListener("scroll", handler, true);
291
+ const observer = new ResizeObserver(handler);
292
+ if (triggerRef.current) observer.observe(triggerRef.current, { box: "border-box" });
293
+ return () => {
294
+ window.removeEventListener("resize", handler);
295
+ window.removeEventListener("scroll", handler, true);
296
+ observer.disconnect();
297
+ };
298
+ }, [open, refreshRect]);
299
+ useEffect(() => {
300
+ if (!open) return;
301
+ const handler = (e) => {
302
+ if (e.key === "Escape") setOpen(false);
303
+ };
304
+ document.addEventListener("keydown", handler);
305
+ return () => document.removeEventListener("keydown", handler);
306
+ }, [open, setOpen]);
307
+ return /* @__PURE__ */ jsx(PopoverContext.Provider, { value: { open, setOpen, triggerRef, triggerRect, refreshRect }, children });
308
+ };
309
+ var PopoverTrigger = forwardRef(function PopoverTrigger2({ onClick, children, ...rest }, forwardedRef) {
310
+ const { open, setOpen, triggerRef, refreshRect } = useCtx();
311
+ const setRef = (node) => {
312
+ triggerRef.current = node;
313
+ if (typeof forwardedRef === "function") forwardedRef(node);
314
+ else if (forwardedRef) forwardedRef.current = node;
315
+ };
316
+ useEffect(() => {
317
+ if (open) refreshRect();
318
+ }, [open, refreshRect]);
319
+ return /* @__PURE__ */ jsx(
320
+ "button",
321
+ {
322
+ ref: setRef,
323
+ type: "button",
324
+ "aria-haspopup": "dialog",
325
+ "aria-expanded": open,
326
+ onClick: (e) => {
327
+ onClick?.(e);
328
+ setOpen(!open);
329
+ },
330
+ ...rest,
331
+ children
332
+ }
333
+ );
334
+ });
335
+ var VIEWPORT_MARGIN = 16;
336
+ var positionStyle = (position, align, rect, offset) => {
337
+ const left = align === "end" ? rect.right : rect.left + rect.width / 2;
338
+ const shiftX = align === "end" ? "-100%" : "-50%";
339
+ const maxWidth = align === "end" ? rect.right - VIEWPORT_MARGIN : void 0;
340
+ switch (position) {
341
+ case "top":
342
+ return {
343
+ top: rect.top - offset,
344
+ left,
345
+ maxWidth,
346
+ transform: `translate(${shiftX}, -100%)`
347
+ };
348
+ case "right":
349
+ return {
350
+ top: rect.top + rect.height / 2,
351
+ left: rect.right + offset,
352
+ transform: "translateY(-50%)"
353
+ };
354
+ case "left":
355
+ return {
356
+ top: rect.top + rect.height / 2,
357
+ left: rect.left - offset,
358
+ transform: "translate(-100%, -50%)"
359
+ };
360
+ case "bottom":
361
+ default:
362
+ return {
363
+ top: rect.bottom + offset,
364
+ left,
365
+ maxWidth,
366
+ transform: `translateX(${shiftX})`
367
+ };
368
+ }
369
+ };
370
+ var arrowStyle = (position, align, rect) => {
371
+ const base = {
372
+ position: "absolute",
373
+ width: 8,
374
+ height: 8,
375
+ transform: "rotate(45deg)"
376
+ };
377
+ const x = align === "end" ? { right: rect.width / 2 - 1, marginRight: -4 } : { left: "50%", marginLeft: -4 };
378
+ switch (position) {
379
+ case "top":
380
+ return { ...base, bottom: -4, ...x };
381
+ case "right":
382
+ return { ...base, left: -4, top: "50%", marginTop: -4 };
383
+ case "left":
384
+ return { ...base, right: -4, top: "50%", marginTop: -4 };
385
+ case "bottom":
386
+ default:
387
+ return { ...base, top: -4, ...x };
388
+ }
389
+ };
390
+ var PopoverContent = ({
391
+ position = "bottom",
392
+ align = "center",
393
+ "aria-label": ariaLabel,
394
+ offset = 8,
395
+ arrow = false,
396
+ width = "w-64",
397
+ className,
398
+ children
399
+ }) => {
400
+ const { open, setOpen, triggerRect } = useCtx();
401
+ if (!open || !triggerRect) return null;
402
+ return createPortal(
403
+ /* @__PURE__ */ jsxs(Fragment$1, { children: [
404
+ /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-[9998]", onClick: () => setOpen(false) }),
405
+ /* @__PURE__ */ jsxs(
406
+ "div",
407
+ {
408
+ role: "dialog",
409
+ "aria-label": ariaLabel,
410
+ style: positionStyle(position, align, triggerRect, offset),
411
+ className: clsx(
412
+ "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",
413
+ width,
414
+ className
415
+ ),
416
+ children: [
417
+ arrow && /* @__PURE__ */ jsx(
418
+ "span",
419
+ {
420
+ "aria-hidden": true,
421
+ style: arrowStyle(position, align, triggerRect),
422
+ className: "border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900"
423
+ }
424
+ ),
425
+ /* @__PURE__ */ jsx("div", { className: "relative", children })
426
+ ]
427
+ }
428
+ )
429
+ ] }),
430
+ document.body
431
+ );
432
+ };
433
+ var Popover = Object.assign(PopoverRoot, {
434
+ Trigger: PopoverTrigger,
435
+ Content: PopoverContent
436
+ });
247
437
  var SidebarContext = createContext({ collapsed: false });
248
438
  var useSidebarCollapsed = (override) => {
249
439
  const ctx = useContext(SidebarContext);
250
440
  return override ?? ctx.collapsed;
251
441
  };
442
+ var SidebarDepthContext = createContext(0);
443
+ var rowPadding = (depth) => 12 + depth * 20;
444
+ var guideLeft = (depth) => 8 + rowPadding(depth) + 10;
252
445
  var SidebarRoot = ({
253
446
  collapsed = false,
254
447
  width = 264,
255
448
  collapsedWidth = 72,
256
449
  children,
257
450
  footer,
451
+ onCollapsedChange,
258
452
  className
259
453
  }) => /* @__PURE__ */ jsx(SidebarContext.Provider, { value: { collapsed }, children: /* @__PURE__ */ jsxs(
260
454
  "nav",
@@ -268,10 +462,32 @@ var SidebarRoot = ({
268
462
  ),
269
463
  children: [
270
464
  /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-x-hidden overflow-y-auto", children }),
271
- footer && /* @__PURE__ */ jsx("div", { className: "shrink-0 overflow-hidden border-t border-[var(--color-border)] p-3", children: footer })
465
+ footer && /* @__PURE__ */ jsx("div", { className: "shrink-0 overflow-hidden border-t border-[var(--color-border)] p-3", children: footer }),
466
+ onCollapsedChange && /* @__PURE__ */ jsx(CollapseButton, { collapsed, onClick: () => onCollapsedChange(!collapsed) })
272
467
  ]
273
468
  }
274
469
  ) });
470
+ var CollapseButton = ({ collapsed, onClick }) => {
471
+ const Icon2 = collapsed ? PanelLeftOpen : PanelLeftClose;
472
+ return /* @__PURE__ */ jsx("div", { className: "shrink-0 border-t border-[var(--color-border)] py-2", children: /* @__PURE__ */ jsxs(
473
+ "button",
474
+ {
475
+ type: "button",
476
+ onClick,
477
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
478
+ "aria-expanded": !collapsed,
479
+ title: collapsed ? "Expand sidebar" : void 0,
480
+ className: clsx(
481
+ "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",
482
+ collapsed ? "justify-center px-2" : "px-3"
483
+ ),
484
+ children: [
485
+ /* @__PURE__ */ jsx(Icon2, { className: "h-5 w-5 shrink-0", "aria-hidden": true }),
486
+ !collapsed && /* @__PURE__ */ jsx("span", { children: "Collapse" })
487
+ ]
488
+ }
489
+ ) });
490
+ };
275
491
  var SidebarBrand = ({
276
492
  logo,
277
493
  title,
@@ -314,17 +530,19 @@ var SidebarItem = ({
314
530
  onClick,
315
531
  badge,
316
532
  collapsed: collapsedProp,
317
- depth = 0
533
+ depth: depthProp
318
534
  }) => {
319
535
  const collapsed = useSidebarCollapsed(collapsedProp);
536
+ const contextDepth = useContext(SidebarDepthContext);
537
+ const depth = depthProp ?? contextDepth;
320
538
  const baseClass = clsx(
321
539
  "group mx-2 flex items-center gap-3 rounded-lg py-2 text-sm font-medium transition-colors",
322
540
  collapsed ? "justify-center px-2" : "px-3",
323
- 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"
541
+ 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"
324
542
  );
325
- const style = !collapsed && depth > 0 ? { paddingLeft: 12 + depth * 20 } : void 0;
543
+ const style = !collapsed && depth > 0 ? { paddingLeft: rowPadding(depth) } : void 0;
326
544
  const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
327
- /* @__PURE__ */ jsx(Icon2, { className: clsx("h-5 w-5 shrink-0", active && "text-brand-500") }),
545
+ /* @__PURE__ */ jsx(Icon2, { className: "h-5 w-5 shrink-0" }),
328
546
  !collapsed && /* @__PURE__ */ jsxs(Fragment$1, { children: [
329
547
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: label }),
330
548
  badge && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: badge })
@@ -339,6 +557,7 @@ var SidebarItem = ({
339
557
  className: baseClass,
340
558
  style,
341
559
  "aria-current": active ? "page" : void 0,
560
+ "data-sidebar-item": "",
342
561
  children: content
343
562
  }
344
563
  );
@@ -352,10 +571,15 @@ var SidebarItem = ({
352
571
  className: clsx(baseClass, "w-[calc(100%-1rem)] text-left"),
353
572
  style,
354
573
  "aria-current": active ? "page" : void 0,
574
+ "data-sidebar-item": "",
355
575
  children: content
356
576
  }
357
577
  );
358
578
  };
579
+ var SUBMENU_ROW = (active) => clsx(
580
+ "group mx-2 flex w-[calc(100%-1rem)] items-center rounded-lg py-2 text-sm font-medium transition-colors",
581
+ 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"
582
+ );
359
583
  var SidebarSubMenu = ({
360
584
  icon: Icon2,
361
585
  label,
@@ -366,20 +590,35 @@ var SidebarSubMenu = ({
366
590
  children
367
591
  }) => {
368
592
  const collapsed = useSidebarCollapsed(collapsedProp);
593
+ const depth = useContext(SidebarDepthContext);
369
594
  const [open, setOpen] = useState(defaultOpen || active);
595
+ const [flyoutOpen, setFlyoutOpen] = useState(false);
370
596
  if (collapsed) {
371
- return /* @__PURE__ */ jsx(
372
- "button",
373
- {
374
- type: "button",
375
- title: label,
376
- className: clsx(
377
- "group mx-2 flex w-[calc(100%-1rem)] items-center justify-center rounded-lg px-2 py-2 text-sm font-medium transition-colors",
378
- 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"
379
- ),
380
- children: /* @__PURE__ */ jsx(Icon2, { className: clsx("h-5 w-5 shrink-0", active && "text-brand-500") })
381
- }
382
- );
597
+ return /* @__PURE__ */ jsxs(Popover, { open: flyoutOpen, onOpenChange: setFlyoutOpen, children: [
598
+ /* @__PURE__ */ jsx(
599
+ Popover.Trigger,
600
+ {
601
+ title: label,
602
+ "aria-label": label,
603
+ className: clsx(SUBMENU_ROW(active), "justify-center px-2"),
604
+ children: /* @__PURE__ */ jsx(Icon2, { className: "h-5 w-5 shrink-0" })
605
+ }
606
+ ),
607
+ /* @__PURE__ */ jsx(Popover.Content, { position: "right", "aria-label": label, width: "w-64", className: "p-2!", children: /* @__PURE__ */ jsx(SidebarContext.Provider, { value: { collapsed: false }, children: /* @__PURE__ */ jsxs(SidebarDepthContext.Provider, { value: 0, children: [
608
+ /* @__PURE__ */ jsx("p", { className: "px-3 pt-1 pb-2 text-xs font-semibold tracking-wider text-[var(--color-text-muted)] uppercase", children: label }),
609
+ /* @__PURE__ */ jsx(
610
+ "div",
611
+ {
612
+ className: "-mx-2 space-y-0.5",
613
+ onClick: (e) => {
614
+ if (e.target.closest("[data-sidebar-item]"))
615
+ setFlyoutOpen(false);
616
+ },
617
+ children
618
+ }
619
+ )
620
+ ] }) }) })
621
+ ] });
383
622
  }
384
623
  return /* @__PURE__ */ jsxs("div", { children: [
385
624
  /* @__PURE__ */ jsxs(
@@ -388,12 +627,10 @@ var SidebarSubMenu = ({
388
627
  type: "button",
389
628
  onClick: () => setOpen((v) => !v),
390
629
  "aria-expanded": open,
391
- className: clsx(
392
- "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",
393
- 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"
394
- ),
630
+ className: clsx(SUBMENU_ROW(active), "gap-3 px-3 text-left"),
631
+ style: depth > 0 ? { paddingLeft: rowPadding(depth) } : void 0,
395
632
  children: [
396
- /* @__PURE__ */ jsx(Icon2, { className: clsx("h-5 w-5 shrink-0", active && "text-brand-500") }),
633
+ /* @__PURE__ */ jsx(Icon2, { className: "h-5 w-5 shrink-0" }),
397
634
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: label }),
398
635
  badge && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: badge }),
399
636
  /* @__PURE__ */ jsx(
@@ -408,7 +645,17 @@ var SidebarSubMenu = ({
408
645
  ]
409
646
  }
410
647
  ),
411
- open && /* @__PURE__ */ jsx("div", { className: "mt-0.5 space-y-0.5", children })
648
+ open && /* @__PURE__ */ jsxs("div", { className: "relative mt-0.5 space-y-0.5", children: [
649
+ /* @__PURE__ */ jsx(
650
+ "span",
651
+ {
652
+ "aria-hidden": true,
653
+ className: "absolute top-0 bottom-0 w-px bg-[var(--color-border)]",
654
+ style: { left: guideLeft(depth) }
655
+ }
656
+ ),
657
+ /* @__PURE__ */ jsx(SidebarDepthContext.Provider, { value: depth + 1, children })
658
+ ] })
412
659
  ] });
413
660
  };
414
661
  var SidebarGroup = ({
@@ -428,7 +675,7 @@ var SidebarGroup = ({
428
675
  {
429
676
  type: "button",
430
677
  onClick: () => setOpen((v) => !v),
431
- 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)]",
678
+ 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)]",
432
679
  children: [
433
680
  open ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3" }),
434
681
  label
@@ -441,7 +688,7 @@ var SidebarGroup = ({
441
688
  var SidebarSection = ({ label, collapsed: collapsedProp, children }) => {
442
689
  const collapsed = useSidebarCollapsed(collapsedProp);
443
690
  return /* @__PURE__ */ jsxs("div", { className: "my-2 border-t border-[var(--color-border)] pt-2", children: [
444
- label && !collapsed && /* @__PURE__ */ jsx("p", { className: "px-5 py-1.5 text-[10px] font-bold tracking-wider text-[var(--color-text-muted)] uppercase", children: label }),
691
+ label && !collapsed && /* @__PURE__ */ jsx("p", { className: "text-3xs px-5 py-1.5 font-bold tracking-wider text-[var(--color-text-muted)] uppercase", children: label }),
445
692
  /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children })
446
693
  ] });
447
694
  };
@@ -454,7 +701,7 @@ Sidebar.SubMenu = SidebarSubMenu;
454
701
  var PageBreadcrumb = ({ items, className }) => /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className, children: /* @__PURE__ */ jsx("ol", { className: "flex flex-wrap items-center gap-1 text-sm", children: items.map((item, i) => {
455
702
  const isFirst = i === 0;
456
703
  const isLast = i === items.length - 1;
457
- const linkClass = "hover:text-brand-500 dark:hover:text-brand-400 flex items-center gap-1 text-[var(--color-text-secondary)] transition-colors";
704
+ const linkClass = "hover:text-brand-600 dark:hover:text-brand-400 flex items-center gap-1 text-[var(--color-text-secondary)] transition-colors";
458
705
  const renderInner = /* @__PURE__ */ jsxs(Fragment$1, { children: [
459
706
  isFirst && /* @__PURE__ */ jsx(Home, { className: "h-4 w-4" }),
460
707
  item.label
@@ -464,17 +711,22 @@ var PageBreadcrumb = ({ items, className }) => /* @__PURE__ */ jsx("nav", { "ari
464
711
  isLast ? /* @__PURE__ */ jsx("span", { className: "font-medium text-[var(--color-text-primary)]", children: item.label }) : item.onClick ? /* @__PURE__ */ jsx("button", { type: "button", onClick: item.onClick, className: linkClass, children: renderInner }) : /* @__PURE__ */ jsx("a", { href: item.href ?? "#", className: clsx(linkClass), children: renderInner })
465
712
  ] }, item.label);
466
713
  }) }) });
467
- var Root3 = ({ title, description, breadcrumb, meta, actions, className }) => /* @__PURE__ */ jsxs("div", { className: `flex items-start justify-between gap-4 ${className ?? ""}`, children: [
468
- /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
469
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-[var(--color-text-primary)]", children: title }),
470
- breadcrumb && /* @__PURE__ */ jsx("div", { className: "mt-1.5", children: breadcrumb }),
471
- !breadcrumb && description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-[var(--color-text-secondary)]", children: description }),
472
- meta && /* @__PURE__ */ 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 })
473
- ] }),
474
- actions && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
475
- ] });
714
+ var Root3 = ({ title, description, breadcrumb, meta, actions, className }) => (
715
+ // The title column asks for 16rem: when that and the actions don't both fit
716
+ // (a phone, a narrow pane), the actions wrap under the title instead of
717
+ // squeezing it until its words run under the buttons.
718
+ /* @__PURE__ */ jsxs("div", { className: `flex flex-wrap items-start justify-between gap-4 ${className ?? ""}`, children: [
719
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 grow basis-64", children: [
720
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-[var(--color-text-primary)]", children: title }),
721
+ breadcrumb && /* @__PURE__ */ jsx("div", { className: "mt-1.5", children: breadcrumb }),
722
+ !breadcrumb && description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-[var(--color-text-secondary)]", children: description }),
723
+ meta && /* @__PURE__ */ 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 })
724
+ ] }),
725
+ actions && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
726
+ ] })
727
+ );
476
728
  var MetaItem = ({ icon: Icon2, children }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
477
- Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "mr-1.5 size-5 text-[var(--color-text-muted)]", "aria-hidden": true }),
729
+ Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "mr-1.5 size-5 shrink-0 text-[var(--color-text-muted)]", "aria-hidden": true }),
478
730
  children
479
731
  ] });
480
732
  var PageHeader = Object.assign(Root3, { MetaItem });
@@ -550,16 +802,6 @@ var SectionCard = ({
550
802
  }
551
803
  );
552
804
  };
553
- var PageCard = ({ children, className }) => /* @__PURE__ */ jsx(
554
- "div",
555
- {
556
- className: clsx(
557
- "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",
558
- className
559
- ),
560
- children
561
- }
562
- );
563
805
  var ContentNarrow = ({ children, maxWidth = 680, className }) => /* @__PURE__ */ jsx("div", { className: `mx-auto w-full ${className ?? ""}`, style: { maxWidth }, children });
564
806
  var ColBox = ({ label, height = 80, className }) => /* @__PURE__ */ jsx(
565
807
  "div",
@@ -598,7 +840,7 @@ var ErrorState = ({
598
840
  {
599
841
  type: "button",
600
842
  onClick: onRetry,
601
- className: "text-brand-500 hover:text-brand-600 text-xs font-medium hover:underline",
843
+ className: "text-brand-600 hover:text-brand-700 dark:text-brand-400 dark:hover:text-brand-300 text-xs font-medium hover:underline",
602
844
  children: "Try again"
603
845
  }
604
846
  )
@@ -664,7 +906,7 @@ var SkeletonList = ({ rows = 4, showAction = true, className }) => /* @__PURE__
664
906
  i
665
907
  )) });
666
908
  var SIZE_CLASS = {
667
- sm: "px-1.5 py-0.5 text-[10px]",
909
+ sm: "px-1.5 py-0.5 text-3xs",
668
910
  md: "px-2 py-0.5 text-xs",
669
911
  lg: "px-3 py-1 text-sm"
670
912
  };
@@ -804,7 +1046,7 @@ var StackedListItem = forwardRef(function StackedListItem2({ avatar, title, subt
804
1046
  ] }),
805
1047
  (meta || trailing || isLinked && chevron) && /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-x-4", children: [
806
1048
  meta && /* @__PURE__ */ jsx("div", { className: "hidden sm:flex sm:flex-col sm:items-end", children: meta }),
807
- trailing,
1049
+ trailing && (isLinked ? /* @__PURE__ */ jsx("div", { className: "relative flex items-center gap-x-4", children: trailing }) : trailing),
808
1050
  isLinked && chevron && /* @__PURE__ */ jsx(
809
1051
  ChevronRight,
810
1052
  {
@@ -850,9 +1092,9 @@ var ContentStackedListItem = forwardRef(
850
1092
  /* @__PURE__ */ jsx("p", { className: "text-sm/6 font-semibold text-gray-900 dark:text-white", children: titleEl }),
851
1093
  badge
852
1094
  ] }),
853
- hasMeta && /* @__PURE__ */ jsx("div", { className: "mt-1 flex items-center gap-x-2 text-xs/5 text-gray-500 dark:text-gray-400", children: Children.toArray(metaItems).map((item, i) => /* @__PURE__ */ jsxs(Fragment, { children: [
1095
+ hasMeta && /* @__PURE__ */ jsx("div", { className: "mt-1 flex items-center gap-x-2 text-xs/5 text-gray-500 dark:text-gray-400", children: Children.toArray(metaItems).map((item, i, items) => /* @__PURE__ */ jsxs(Fragment, { children: [
854
1096
  i > 0 && /* @__PURE__ */ jsx(Dot, {}),
855
- item
1097
+ /* @__PURE__ */ jsx("span", { className: i === items.length - 1 ? "truncate" : "whitespace-nowrap", children: item })
856
1098
  ] }, i)) })
857
1099
  ] }),
858
1100
  trailing && /* @__PURE__ */ jsx("div", { className: "flex flex-none items-center gap-x-4", children: trailing })
@@ -909,7 +1151,7 @@ var NarrowStackedListHeader = forwardRef(
909
1151
  {
910
1152
  ref,
911
1153
  className: clsx(
912
- "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",
1154
+ "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",
913
1155
  sticky && "sticky top-0 z-10",
914
1156
  className
915
1157
  ),
@@ -932,7 +1174,8 @@ var NarrowStackedListItem = forwardRef(
932
1174
  ] }),
933
1175
  description && /* @__PURE__ */ jsx("p", { className: "mt-1 line-clamp-2 text-sm/6 text-gray-600 dark:text-gray-400", children: description }),
934
1176
  !description && subtitle && /* @__PURE__ */ jsx("p", { className: "mt-1 truncate text-xs/5 text-gray-500 dark:text-gray-400", children: subtitle })
935
- ] })
1177
+ ] }),
1178
+ trailing && /* @__PURE__ */ jsx("div", { className: "flex flex-none items-center", children: trailing })
936
1179
  ] });
937
1180
  }
938
1181
  if (trailing) {
@@ -1033,7 +1276,7 @@ var StatusRow = ({
1033
1276
  "span",
1034
1277
  {
1035
1278
  className: clsx(
1036
- "shrink-0 rounded-full px-2 py-0.5 text-[10px] font-bold",
1279
+ "text-3xs shrink-0 rounded-full px-2 py-0.5 font-bold",
1037
1280
  STATUS_CLASS2[status]
1038
1281
  ),
1039
1282
  children: status
@@ -1138,18 +1381,21 @@ var Footer = forwardRef(function GridListFooter({ className, children, ...rest }
1138
1381
  });
1139
1382
  var FooterAction = forwardRef(
1140
1383
  function GridListFooterAction({ index = 0, className, children, ...rest }, ref) {
1141
- return /* @__PURE__ */ jsx("div", { className: clsx("flex w-0 flex-1", index > 0 && "-ml-px"), children: /* @__PURE__ */ jsx(
1142
- "a",
1143
- {
1144
- ref,
1145
- className: clsx(
1146
- "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",
1147
- className
1148
- ),
1149
- ...rest,
1150
- children
1151
- }
1152
- ) });
1384
+ return (
1385
+ // The cell's position picks the card corner it rounds: first bottom-left, last bottom-right.
1386
+ /* @__PURE__ */ jsx("div", { className: clsx("group/action flex w-0 flex-1", index > 0 && "-ml-px"), children: /* @__PURE__ */ jsx(
1387
+ "a",
1388
+ {
1389
+ ref,
1390
+ className: clsx(
1391
+ "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",
1392
+ className
1393
+ ),
1394
+ ...rest,
1395
+ children
1396
+ }
1397
+ ) })
1398
+ );
1153
1399
  }
1154
1400
  );
1155
1401
  var GridList = Object.assign(Root5, {
@@ -1213,74 +1459,73 @@ var Breadcrumb = ({ items, separator = "chevron", className }) => /* @__PURE__ *
1213
1459
  );
1214
1460
  var ROOT_BG = {
1215
1461
  light: "bg-white shadow-sm border-b border-gray-200 dark:bg-gray-800 dark:border-white/10",
1216
- dark: "bg-gray-800"
1462
+ dark: "bg-gray-800 text-white"
1217
1463
  };
1218
- var ITEM_BASE = {
1219
- 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",
1220
- dark: "rounded-md px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white"
1464
+ var ITEM_BASE = "rounded-md px-3 py-2 text-sm font-medium";
1465
+ var ITEM_IDLE = {
1466
+ light: "text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-white/5",
1467
+ dark: "text-gray-300 hover:bg-gray-700 hover:text-white"
1221
1468
  };
1222
1469
  var ITEM_ACTIVE = {
1223
1470
  light: "bg-gray-100 text-gray-900 dark:bg-white/10 dark:text-white",
1224
1471
  dark: "bg-gray-900 text-white"
1225
1472
  };
1473
+ var NavbarThemeContext = createContext("light");
1226
1474
  var RootCmp = forwardRef(function NavbarRoot({ theme = "light", maxWidth = "7xl", heightClassName = "h-16", className, children, ...rest }, ref) {
1227
- return /* @__PURE__ */ jsx("nav", { ref, className: clsx(ROOT_BG[theme], className), "data-theme": theme, ...rest, children: /* @__PURE__ */ jsx("div", { className: clsx("px-4 sm:px-6 lg:px-8", maxWidth === "7xl" && "mx-auto max-w-7xl"), children: /* @__PURE__ */ jsx("div", { className: clsx("flex items-center justify-between", heightClassName), children }) }) });
1475
+ return /* @__PURE__ */ jsx("nav", { ref, className: clsx(ROOT_BG[theme], className), "data-theme": theme, ...rest, children: /* @__PURE__ */ jsx("div", { className: clsx("px-4 sm:px-6 lg:px-8", maxWidth === "7xl" && "mx-auto max-w-7xl"), children: /* @__PURE__ */ jsx("div", { className: clsx("flex items-center justify-between", heightClassName), children: /* @__PURE__ */ jsx(NavbarThemeContext.Provider, { value: theme, children }) }) }) });
1228
1476
  });
1229
1477
  var Brand = ({ className, children, ...rest }) => /* @__PURE__ */ jsx("div", { className: clsx("flex shrink-0 items-center", className), ...rest, children });
1230
1478
  var Items = ({ className, children, ...rest }) => /* @__PURE__ */ jsx("div", { className: clsx("hidden md:ml-10 md:block", className), ...rest, children: /* @__PURE__ */ jsx("div", { className: "flex items-baseline space-x-4", children }) });
1231
- var Item2 = ({
1232
- active = false,
1233
- theme = "light",
1234
- className,
1235
- children,
1236
- ...rest
1237
- }) => /* @__PURE__ */ jsx(
1238
- "a",
1239
- {
1240
- "aria-current": active ? "page" : void 0,
1241
- className: clsx(ITEM_BASE[theme], active && ITEM_ACTIVE[theme], className),
1242
- ...rest,
1243
- children
1244
- }
1245
- );
1479
+ var Item2 = ({ active = false, theme, className, children, ...rest }) => {
1480
+ const inherited = useContext(NavbarThemeContext);
1481
+ const resolved = theme ?? inherited;
1482
+ return /* @__PURE__ */ jsx(
1483
+ "a",
1484
+ {
1485
+ "aria-current": active ? "page" : void 0,
1486
+ className: clsx(ITEM_BASE, active ? ITEM_ACTIVE[resolved] : ITEM_IDLE[resolved], className),
1487
+ ...rest,
1488
+ children
1489
+ }
1490
+ );
1491
+ };
1246
1492
  var Actions = ({ className, children, ...rest }) => /* @__PURE__ */ jsx("div", { className: clsx("hidden md:block", className), ...rest, children: /* @__PURE__ */ jsx("div", { className: "ml-4 flex items-center gap-3 md:ml-6", children }) });
1247
- var MobileMenuButton = ({
1248
- theme = "light",
1249
- className,
1250
- children,
1251
- ...rest
1252
- }) => /* @__PURE__ */ jsx(
1253
- "button",
1254
- {
1255
- type: "button",
1256
- "aria-label": "Toggle menu",
1257
- className: clsx(
1258
- "relative inline-flex size-10 items-center justify-center rounded-md md:hidden",
1259
- 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",
1260
- className
1261
- ),
1262
- ...rest,
1263
- children: children ?? /* @__PURE__ */ jsx(
1264
- "svg",
1265
- {
1266
- className: "size-6",
1267
- fill: "none",
1268
- viewBox: "0 0 24 24",
1269
- strokeWidth: "1.5",
1270
- stroke: "currentColor",
1271
- "aria-hidden": true,
1272
- children: /* @__PURE__ */ jsx(
1273
- "path",
1274
- {
1275
- strokeLinecap: "round",
1276
- strokeLinejoin: "round",
1277
- d: "M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"
1278
- }
1279
- )
1280
- }
1281
- )
1282
- }
1283
- );
1493
+ var MobileMenuButton = ({ theme, className, children, ...rest }) => {
1494
+ const inherited = useContext(NavbarThemeContext);
1495
+ const resolved = theme ?? inherited;
1496
+ return /* @__PURE__ */ jsx(
1497
+ "button",
1498
+ {
1499
+ type: "button",
1500
+ "aria-label": "Toggle menu",
1501
+ className: clsx(
1502
+ "relative inline-flex size-10 items-center justify-center rounded-md md:hidden",
1503
+ 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",
1504
+ className
1505
+ ),
1506
+ ...rest,
1507
+ children: children ?? /* @__PURE__ */ jsx(
1508
+ "svg",
1509
+ {
1510
+ className: "size-6",
1511
+ fill: "none",
1512
+ viewBox: "0 0 24 24",
1513
+ strokeWidth: "1.5",
1514
+ stroke: "currentColor",
1515
+ "aria-hidden": true,
1516
+ children: /* @__PURE__ */ jsx(
1517
+ "path",
1518
+ {
1519
+ strokeLinecap: "round",
1520
+ strokeLinejoin: "round",
1521
+ d: "M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"
1522
+ }
1523
+ )
1524
+ }
1525
+ )
1526
+ }
1527
+ );
1528
+ };
1284
1529
  var Navbar = Object.assign(RootCmp, {
1285
1530
  Brand,
1286
1531
  Items,
@@ -1597,7 +1842,7 @@ var StepperRoot = ({
1597
1842
  isValidElement
1598
1843
  );
1599
1844
  const effectiveOrientation = variant === "indicators" ? orientation : "horizontal";
1600
- 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";
1845
+ 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";
1601
1846
  return /* @__PURE__ */ jsx("ol", { className: clsx(rootClass, className), "aria-label": "Progress", children: steps.map((step, i) => {
1602
1847
  const status = i < current ? "done" : i === current ? "active" : "pending";
1603
1848
  return cloneElement(step, {
@@ -1682,18 +1927,25 @@ var VARIANT_CLASS = {
1682
1927
  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"
1683
1928
  };
1684
1929
  var SIZE_CLASS2 = {
1685
- xs: "h-7 px-2 text-xs gap-1",
1686
- sm: "h-8 px-3 text-xs gap-1.5",
1687
- md: "h-9 px-3.5 text-sm gap-2",
1688
- lg: "h-11 px-5 text-base gap-2",
1689
- xl: "h-12 px-6 text-base gap-2.5"
1930
+ xs: "h-7 text-xs gap-1",
1931
+ sm: "h-8 text-xs gap-1.5",
1932
+ md: "h-9 text-sm gap-2",
1933
+ lg: "h-11 text-base gap-2",
1934
+ xl: "h-12 text-base gap-2.5"
1935
+ };
1936
+ var PADDING_X = {
1937
+ xs: "px-2",
1938
+ sm: "px-3",
1939
+ md: "px-3.5",
1940
+ lg: "px-5",
1941
+ xl: "px-6"
1690
1942
  };
1691
1943
  var CIRCLE_SQUARE = {
1692
- xs: "w-7 px-0",
1693
- sm: "w-8 px-0",
1694
- md: "w-9 px-0",
1695
- lg: "w-11 px-0",
1696
- xl: "w-12 px-0"
1944
+ xs: "w-7",
1945
+ sm: "w-8",
1946
+ md: "w-9",
1947
+ lg: "w-11",
1948
+ xl: "w-12"
1697
1949
  };
1698
1950
  var SHAPE_CLASS = {
1699
1951
  rounded: "rounded-lg",
@@ -1729,7 +1981,7 @@ var Button = ({
1729
1981
  VARIANT_CLASS[variant],
1730
1982
  SIZE_CLASS2[size],
1731
1983
  SHAPE_CLASS[shape],
1732
- shape === "circle" && CIRCLE_SQUARE[size],
1984
+ shape === "circle" ? CIRCLE_SQUARE[size] : PADDING_X[size],
1733
1985
  className
1734
1986
  ),
1735
1987
  ...rest,
@@ -1831,7 +2083,7 @@ var VARIANT_SOLID = {
1831
2083
  info: "bg-blue-500 text-white"
1832
2084
  };
1833
2085
  var SIZE_CLASS3 = {
1834
- sm: "px-1.5 py-0.5 text-[10px] gap-1",
2086
+ sm: "px-1.5 py-0.5 text-3xs gap-1",
1835
2087
  md: "px-2 py-0.5 text-xs gap-1.5"
1836
2088
  };
1837
2089
  var ICON_SIZE2 = {
@@ -1867,7 +2119,7 @@ var Badge = ({
1867
2119
  );
1868
2120
  };
1869
2121
  var SIZE_CLASS4 = {
1870
- xs: "h-6 w-6 text-[10px]",
2122
+ xs: "h-6 w-6 text-3xs",
1871
2123
  sm: "h-8 w-8 text-xs",
1872
2124
  md: "h-10 w-10 text-sm",
1873
2125
  lg: "h-12 w-12 text-base",
@@ -1904,6 +2156,21 @@ var Avatar = ({ src, alt, name, size = "md", className }) => {
1904
2156
  }
1905
2157
  );
1906
2158
  };
2159
+ var SIZE = {
2160
+ sm: "h-5 min-w-[20px] px-1.5 text-3xs",
2161
+ md: "h-6 min-w-[24px] px-2 text-xs"
2162
+ };
2163
+ var Kbd = ({ children, size = "md", className }) => /* @__PURE__ */ jsx(
2164
+ "kbd",
2165
+ {
2166
+ className: clsx(
2167
+ "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)]",
2168
+ SIZE[size],
2169
+ className
2170
+ ),
2171
+ children
2172
+ }
2173
+ );
1907
2174
  var BOX_POS = {
1908
2175
  top: "bottom-full left-1/2 -translate-x-1/2 mb-2.5",
1909
2176
  bottom: "top-full left-1/2 -translate-x-1/2 mt-2.5",
@@ -1919,54 +2186,124 @@ var ARROW_POS = {
1919
2186
  var VARIANT_BOX = {
1920
2187
  dark: "bg-gray-900 text-white shadow-[0_0_20px_rgba(0,0,0,0.35)] dark:bg-gray-700",
1921
2188
  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",
1922
- brand: "bg-brand-500 text-white shadow-[0_0_20px_rgba(0,0,0,0.25)]"
2189
+ brand: "bg-brand-500 text-white shadow-[0_0_20px_rgba(0,0,0,0.25)]",
2190
+ // Shades picked for 4.5:1 text contrast; amber is too light for white text.
2191
+ success: "bg-green-700 text-white shadow-[0_0_20px_rgba(0,0,0,0.25)]",
2192
+ warning: "bg-amber-400 text-gray-900 shadow-[0_0_20px_rgba(0,0,0,0.25)]",
2193
+ danger: "bg-red-600 text-white shadow-[0_0_20px_rgba(0,0,0,0.25)]"
1923
2194
  };
1924
2195
  var VARIANT_ARROW = {
1925
2196
  dark: "bg-gray-900 dark:bg-gray-700",
1926
2197
  white: "bg-white border border-gray-200 dark:bg-gray-800 dark:border-gray-700",
1927
- brand: "bg-brand-500"
2198
+ brand: "bg-brand-500",
2199
+ success: "bg-green-700",
2200
+ warning: "bg-amber-400",
2201
+ danger: "bg-red-600"
1928
2202
  };
1929
2203
  var Tooltip = ({
1930
2204
  content,
1931
2205
  children,
1932
2206
  position = "top",
1933
2207
  variant = "dark",
1934
- maxWidth = "max-w-xs"
1935
- }) => (
1936
- // `inline-block w-fit` keeps the wrapper exactly the size of the children even
1937
- // inside grid/flex parents, so the absolute-positioned tooltip stays anchored
1938
- // on the trigger rather than on the parent cell.
1939
- /* @__PURE__ */ jsxs("span", { className: "group relative inline-block w-fit align-middle", children: [
1940
- children,
2208
+ maxWidth = "max-w-xs",
2209
+ shortcut,
2210
+ title,
2211
+ arrow = true,
2212
+ delay = 0
2213
+ }) => {
2214
+ const id = useId();
2215
+ const [open, setOpen] = useState(false);
2216
+ const [engaged, setEngaged] = useState(false);
2217
+ const timer = useRef(void 0);
2218
+ useEffect(() => () => clearTimeout(timer.current), []);
2219
+ const show = () => {
2220
+ setEngaged(true);
2221
+ clearTimeout(timer.current);
2222
+ if (delay > 0) timer.current = setTimeout(() => setOpen(true), delay);
2223
+ else setOpen(true);
2224
+ };
2225
+ const hide = () => {
2226
+ setEngaged(false);
2227
+ clearTimeout(timer.current);
2228
+ setOpen(false);
2229
+ };
2230
+ useEffect(() => {
2231
+ if (!engaged) return;
2232
+ const onKeyDown = (e) => {
2233
+ if (e.key !== "Escape") return;
2234
+ if (open) e.stopPropagation();
2235
+ clearTimeout(timer.current);
2236
+ setEngaged(false);
2237
+ setOpen(false);
2238
+ };
2239
+ document.addEventListener("keydown", onKeyDown, true);
2240
+ return () => document.removeEventListener("keydown", onKeyDown, true);
2241
+ }, [engaged, open]);
2242
+ const trigger = isValidElement(children) ? cloneElement(children, {
2243
+ "aria-describedby": [children.props["aria-describedby"], id].filter(Boolean).join(" ")
2244
+ }) : children;
2245
+ return (
2246
+ // `inline-block w-fit` keeps the wrapper exactly the size of the children even
2247
+ // inside grid/flex parents, so the absolute-positioned tooltip stays anchored
2248
+ // on the trigger rather than on the parent cell.
1941
2249
  /* @__PURE__ */ jsxs(
1942
2250
  "span",
1943
2251
  {
1944
- role: "tooltip",
1945
- className: clsx(
1946
- "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",
1947
- maxWidth,
1948
- BOX_POS[position],
1949
- VARIANT_BOX[variant]
1950
- ),
2252
+ className: "relative inline-block w-fit align-middle",
2253
+ onMouseEnter: show,
2254
+ onMouseLeave: hide,
2255
+ onFocus: show,
2256
+ onBlur: hide,
1951
2257
  children: [
1952
- content,
1953
- /* @__PURE__ */ jsx(
2258
+ trigger,
2259
+ /* @__PURE__ */ jsxs(
1954
2260
  "span",
1955
2261
  {
1956
- "aria-hidden": true,
1957
- className: clsx("absolute h-2 w-2 rotate-45", ARROW_POS[position], VARIANT_ARROW[variant])
2262
+ id,
2263
+ role: "tooltip",
2264
+ className: clsx(
2265
+ "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",
2266
+ open ? "opacity-100" : "opacity-0",
2267
+ maxWidth,
2268
+ BOX_POS[position],
2269
+ VARIANT_BOX[variant]
2270
+ ),
2271
+ children: [
2272
+ title && /* @__PURE__ */ jsx("span", { className: "block font-semibold", children: title }),
2273
+ title ? /* @__PURE__ */ jsx("span", { className: "mt-0.5 block opacity-80", children: content }) : content,
2274
+ shortcut && /* @__PURE__ */ jsx("span", { className: "ml-2 inline-flex gap-0.5 align-middle", children: shortcut.map((key, i) => /* @__PURE__ */ jsx(Kbd, { size: "sm", children: key }, i)) }),
2275
+ arrow && /* @__PURE__ */ jsx(
2276
+ "span",
2277
+ {
2278
+ "aria-hidden": true,
2279
+ className: clsx(
2280
+ "absolute h-2 w-2 rotate-45",
2281
+ ARROW_POS[position],
2282
+ VARIANT_ARROW[variant]
2283
+ )
2284
+ }
2285
+ )
2286
+ ]
1958
2287
  }
1959
2288
  )
1960
2289
  ]
1961
2290
  }
1962
2291
  )
1963
- ] })
1964
- );
2292
+ );
2293
+ };
1965
2294
  var TooltipHelp = ({
1966
2295
  text,
1967
2296
  position = "top",
1968
2297
  variant = "dark"
1969
- }) => /* @__PURE__ */ jsx(Tooltip, { content: text, position, variant, maxWidth: "max-w-[260px]", children: /* @__PURE__ */ jsx(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" }) });
2298
+ }) => /* @__PURE__ */ jsx(Tooltip, { content: text, position, variant, maxWidth: "max-w-[260px]", children: /* @__PURE__ */ jsx(
2299
+ "button",
2300
+ {
2301
+ type: "button",
2302
+ "aria-label": "Help",
2303
+ 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",
2304
+ children: /* @__PURE__ */ jsx(HelpCircle, { className: "h-3.5 w-3.5", "aria-hidden": true })
2305
+ }
2306
+ ) });
1970
2307
  var isDivider = (item) => item.divider === true;
1971
2308
  var Dropdown = ({
1972
2309
  label,
@@ -2529,25 +2866,91 @@ var useTabs = () => {
2529
2866
  if (!ctx) throw new Error("Tabs.* must be used inside <Tabs>");
2530
2867
  return ctx;
2531
2868
  };
2532
- var Root10 = ({ value, onChange, orientation = "horizontal", children, className }) => /* @__PURE__ */ jsx(TabsContext.Provider, { value: { value, onChange, orientation }, children: /* @__PURE__ */ jsx("div", { className: clsx(orientation === "vertical" ? "flex gap-6" : "", className), children }) });
2869
+ var LIST_CLASSES = {
2870
+ underline: {
2871
+ horizontal: "flex items-center gap-1 border-b border-gray-200 dark:border-gray-800",
2872
+ vertical: "flex shrink-0 flex-col gap-1 border-r border-gray-200 dark:border-gray-800"
2873
+ },
2874
+ // The list's border is the panel's edge: it runs under the inactive tabs and
2875
+ // the active tab covers it.
2876
+ folder: {
2877
+ horizontal: "flex items-end gap-1 border-b border-[var(--color-border)]",
2878
+ vertical: "flex shrink-0 flex-col gap-1 border-r border-[var(--color-border)]"
2879
+ }
2880
+ };
2881
+ var TRIGGER_CLASSES = {
2882
+ underline: {
2883
+ horizontal: {
2884
+ base: "-mb-px border-b-2 px-3 py-2",
2885
+ active: "border-brand-500 text-brand-600 dark:text-brand-400",
2886
+ inactive: "border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
2887
+ },
2888
+ vertical: {
2889
+ base: "-mr-px justify-start rounded-l-lg border-r-2 px-3 py-2 text-left whitespace-nowrap",
2890
+ active: "border-brand-500 bg-brand-50 text-brand-600 dark:bg-brand-500/10 dark:text-brand-400",
2891
+ 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"
2892
+ }
2893
+ },
2894
+ // Every tab overlaps the list's border by 1px. The active one has the
2895
+ // panel's background and a transparent edge on the panel side, so it covers
2896
+ // the line and opens into the panel; it is also 4px taller (wider when
2897
+ // vertical) than the inactive ones, which sit on the line with the page's
2898
+ // background. The padding moves with the size so the labels don't shift.
2899
+ folder: {
2900
+ horizontal: {
2901
+ base: "-mb-px rounded-t-lg border border-[var(--color-border)] px-3 pb-2",
2902
+ active: "border-b-transparent bg-[var(--color-bg-panel)] pt-3 text-brand-600 dark:text-brand-400",
2903
+ inactive: "bg-[var(--color-bg-base)] pt-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
2904
+ },
2905
+ vertical: {
2906
+ base: "-mr-px justify-start rounded-l-lg border border-[var(--color-border)] py-2 pr-3 text-left whitespace-nowrap",
2907
+ active: "border-r-transparent bg-[var(--color-bg-panel)] pl-4 text-brand-600 dark:text-brand-400",
2908
+ 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"
2909
+ }
2910
+ }
2911
+ };
2912
+ var PANEL_CLASSES = {
2913
+ underline: { horizontal: "pt-5", vertical: "flex-1" },
2914
+ // Bordered on three sides: the list's border closes the side facing the tabs.
2915
+ folder: {
2916
+ horizontal: "rounded-b-xl border border-t-0 border-[var(--color-border)] bg-[var(--color-bg-panel)] p-5",
2917
+ vertical: "flex-1 rounded-r-xl border border-l-0 border-[var(--color-border)] bg-[var(--color-bg-panel)] p-5"
2918
+ }
2919
+ };
2920
+ var Root10 = ({
2921
+ value,
2922
+ onChange,
2923
+ orientation = "horizontal",
2924
+ variant = "underline",
2925
+ children,
2926
+ className
2927
+ }) => /* @__PURE__ */ jsx(TabsContext.Provider, { value: { value, onChange, orientation, variant }, children: /* @__PURE__ */ jsx(
2928
+ "div",
2929
+ {
2930
+ className: clsx(
2931
+ // Folder tabs touch their panel, so no gap between list and panel.
2932
+ orientation === "vertical" && (variant === "folder" ? "flex" : "flex gap-6"),
2933
+ className
2934
+ ),
2935
+ children
2936
+ }
2937
+ ) });
2533
2938
  var List = ({ children, className }) => {
2534
- const { orientation } = useTabs();
2939
+ const { orientation, variant } = useTabs();
2535
2940
  return /* @__PURE__ */ jsx(
2536
2941
  "div",
2537
2942
  {
2538
2943
  role: "tablist",
2539
2944
  "aria-orientation": orientation,
2540
- className: clsx(
2541
- 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",
2542
- className
2543
- ),
2945
+ className: clsx(LIST_CLASSES[variant][orientation], className),
2544
2946
  children
2545
2947
  }
2546
2948
  );
2547
2949
  };
2548
2950
  var Trigger = ({ value, children, icon: Icon2, badge, disabled, className }) => {
2549
- const { value: active, onChange, orientation } = useTabs();
2951
+ const { value: active, onChange, orientation, variant } = useTabs();
2550
2952
  const isActive = value === active;
2953
+ const styles = TRIGGER_CLASSES[variant][orientation];
2551
2954
  return /* @__PURE__ */ jsxs(
2552
2955
  "button",
2553
2956
  {
@@ -2558,13 +2961,8 @@ var Trigger = ({ value, children, icon: Icon2, badge, disabled, className }) =>
2558
2961
  onClick: () => onChange(value),
2559
2962
  className: clsx(
2560
2963
  "flex items-center gap-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
2561
- orientation === "vertical" ? clsx(
2562
- "-mr-px justify-start rounded-l-lg border-r-2 px-3 py-2 text-left whitespace-nowrap",
2563
- 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"
2564
- ) : clsx(
2565
- "-mb-px border-b-2 px-3 py-2",
2566
- 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"
2567
- ),
2964
+ styles.base,
2965
+ isActive ? styles.active : styles.inactive,
2568
2966
  className
2569
2967
  ),
2570
2968
  children: [
@@ -2574,7 +2972,7 @@ var Trigger = ({ value, children, icon: Icon2, badge, disabled, className }) =>
2574
2972
  "span",
2575
2973
  {
2576
2974
  className: clsx(
2577
- "ms-auto rounded-full px-1.5 py-0.5 text-[10px] font-bold",
2975
+ "text-3xs ms-auto rounded-full px-1.5 py-0.5 font-bold",
2578
2976
  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"
2579
2977
  ),
2580
2978
  children: badge
@@ -2589,16 +2987,9 @@ var Panel = ({
2589
2987
  children,
2590
2988
  className
2591
2989
  }) => {
2592
- const { value: active, orientation } = useTabs();
2990
+ const { value: active, orientation, variant } = useTabs();
2593
2991
  if (value !== active) return null;
2594
- return /* @__PURE__ */ jsx(
2595
- "div",
2596
- {
2597
- role: "tabpanel",
2598
- className: clsx(orientation === "vertical" ? "flex-1" : "pt-5", className),
2599
- children
2600
- }
2601
- );
2992
+ return /* @__PURE__ */ jsx("div", { role: "tabpanel", className: clsx(PANEL_CLASSES[variant][orientation], className), children });
2602
2993
  };
2603
2994
  var Tabs = Object.assign(Root10, { List, Trigger, Panel });
2604
2995
  var SIZE_ICON = {
@@ -2688,7 +3079,13 @@ var Clipboard = forwardRef(function Clipboard2({
2688
3079
  }
2689
3080
  );
2690
3081
  });
2691
- var CodeBlock = ({ code, language, showCopy = true, className }) => /* @__PURE__ */ jsxs(
3082
+ var CodeBlock = ({
3083
+ code,
3084
+ language,
3085
+ highlight,
3086
+ showCopy = true,
3087
+ className
3088
+ }) => /* @__PURE__ */ jsxs(
2692
3089
  "div",
2693
3090
  {
2694
3091
  className: clsx(
@@ -2697,10 +3094,10 @@ var CodeBlock = ({ code, language, showCopy = true, className }) => /* @__PURE__
2697
3094
  ),
2698
3095
  children: [
2699
3096
  language && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 px-4 py-1.5 dark:border-gray-800", children: [
2700
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400", children: language }),
3097
+ /* @__PURE__ */ jsx("span", { className: "text-3xs font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400", children: language }),
2701
3098
  showCopy && /* @__PURE__ */ jsx(Clipboard, { value: code, floating: true })
2702
3099
  ] }),
2703
- /* @__PURE__ */ jsx("pre", { className: "overflow-x-auto p-4 text-xs leading-relaxed text-gray-800 dark:text-gray-200", children: /* @__PURE__ */ jsx("code", { children: code }) }),
3100
+ /* @__PURE__ */ jsx("pre", { className: "overflow-x-auto p-4 text-xs leading-relaxed text-gray-800 dark:text-gray-200", children: /* @__PURE__ */ jsx("code", { children: highlight ? highlight(code, language) : code }) }),
2704
3101
  showCopy && !language && /* @__PURE__ */ jsx(Clipboard, { value: code, floating: true, className: "absolute top-2 right-2" })
2705
3102
  ]
2706
3103
  }
@@ -2909,7 +3306,7 @@ var SectionLabel = ({ children, className }) => /* @__PURE__ */ jsx(
2909
3306
  "p",
2910
3307
  {
2911
3308
  className: clsx(
2912
- "text-[10px] font-semibold tracking-wider text-gray-400 uppercase dark:text-gray-600",
3309
+ "text-3xs font-semibold tracking-wider text-gray-400 uppercase dark:text-gray-600",
2913
3310
  className
2914
3311
  ),
2915
3312
  children
@@ -3205,7 +3602,7 @@ var BADGE_BG = {
3205
3602
  success: "bg-green-500"
3206
3603
  };
3207
3604
  var NotificationsPanelContext = createContext(null);
3208
- var useCtx = () => {
3605
+ var useCtx2 = () => {
3209
3606
  const ctx = useContext(NotificationsPanelContext);
3210
3607
  if (!ctx) throw new Error("NotificationsPanel.* must be used inside <NotificationsPanel>");
3211
3608
  return ctx;
@@ -3263,7 +3660,7 @@ var NotificationsPanelRoot = ({
3263
3660
  };
3264
3661
  var NotificationsPanelTrigger = forwardRef(
3265
3662
  function NotificationsPanelTrigger2({ count = 0, muted = false, ping, className, ...rest }, forwardedRef) {
3266
- const { open, setOpen, triggerRef, refreshRect } = useCtx();
3663
+ const { open, setOpen, triggerRef, refreshRect } = useCtx2();
3267
3664
  const setRef = (node) => {
3268
3665
  triggerRef.current = node;
3269
3666
  if (typeof forwardedRef === "function") forwardedRef(node);
@@ -3305,7 +3702,7 @@ var NotificationsPanelContent = ({
3305
3702
  className,
3306
3703
  children
3307
3704
  }) => {
3308
- const { open, setOpen, triggerRect, align } = useCtx();
3705
+ const { open, setOpen, triggerRect, align } = useCtx2();
3309
3706
  if (!open || !triggerRect) return null;
3310
3707
  const top = triggerRect.bottom + 8;
3311
3708
  const positionStyle2 = align === "right" ? { top, right: window.innerWidth - triggerRect.right } : { top, left: triggerRect.left };
@@ -3404,7 +3801,7 @@ var NotificationsPanelItem = forwardRef(
3404
3801
  className,
3405
3802
  ...rest
3406
3803
  }, ref) {
3407
- const { setOpen } = useCtx();
3804
+ const { setOpen } = useCtx2();
3408
3805
  const meta = SEVERITY_META[severity];
3409
3806
  const Icon2 = meta.icon;
3410
3807
  const defaultLabel = severity === "success" ? "OK" : severity.toUpperCase();
@@ -3436,13 +3833,13 @@ var NotificationsPanelItem = forwardRef(
3436
3833
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
3437
3834
  /* @__PURE__ */ jsx("p", { className: "truncate text-sm font-semibold text-gray-900 dark:text-white", children: title }),
3438
3835
  subtitle && /* @__PURE__ */ jsx("p", { className: "truncate text-xs text-gray-500 dark:text-gray-400", children: subtitle }),
3439
- caption && /* @__PURE__ */ jsx("p", { className: "mt-0.5 truncate font-mono text-[10px] text-gray-400", children: caption })
3836
+ caption && /* @__PURE__ */ jsx("p", { className: "text-3xs mt-0.5 truncate font-mono text-gray-400", children: caption })
3440
3837
  ] }),
3441
3838
  /* @__PURE__ */ jsx(
3442
3839
  "span",
3443
3840
  {
3444
3841
  className: clsx(
3445
- "mt-0.5 shrink-0 rounded-full px-2 py-0.5 text-[10px] font-bold text-white",
3842
+ "text-3xs mt-0.5 shrink-0 rounded-full px-2 py-0.5 font-bold text-white",
3446
3843
  BADGE_BG[severity]
3447
3844
  ),
3448
3845
  children: badgeLabel ?? defaultLabel
@@ -3469,7 +3866,7 @@ var NotificationsPanelFooter = ({
3469
3866
  className,
3470
3867
  ...rest
3471
3868
  }) => {
3472
- const { setOpen } = useCtx();
3869
+ const { setOpen } = useCtx2();
3473
3870
  return /* @__PURE__ */ jsx("div", { className: "border-t border-gray-100 p-2 dark:border-gray-800", children: /* @__PURE__ */ jsx(
3474
3871
  "button",
3475
3872
  {
@@ -3479,7 +3876,7 @@ var NotificationsPanelFooter = ({
3479
3876
  if (closeOnClick && !e.defaultPrevented) setOpen(false);
3480
3877
  },
3481
3878
  className: clsx(
3482
- "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",
3879
+ "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",
3483
3880
  className
3484
3881
  ),
3485
3882
  ...rest,
@@ -3591,7 +3988,7 @@ var NotificationCard = Object.assign(Root11, {
3591
3988
  Condensed: CondensedVariant
3592
3989
  });
3593
3990
  var UserMenuContext = createContext(null);
3594
- var useCtx2 = () => {
3991
+ var useCtx3 = () => {
3595
3992
  const ctx = useContext(UserMenuContext);
3596
3993
  if (!ctx) throw new Error("UserMenu.* must be used inside <UserMenu>");
3597
3994
  return ctx;
@@ -3647,7 +4044,7 @@ var UserMenuRoot = ({
3647
4044
  };
3648
4045
  var UserMenuTrigger = forwardRef(
3649
4046
  function UserMenuTrigger2({ name, avatarSrc, hideName = false, className, ...rest }, forwardedRef) {
3650
- const { open, setOpen, triggerRef, refreshRect } = useCtx2();
4047
+ const { open, setOpen, triggerRef, refreshRect } = useCtx3();
3651
4048
  const setRef = (node) => {
3652
4049
  triggerRef.current = node;
3653
4050
  if (typeof forwardedRef === "function") forwardedRef(node);
@@ -3688,7 +4085,7 @@ var UserMenuTrigger = forwardRef(
3688
4085
  }
3689
4086
  );
3690
4087
  var UserMenuContent = ({ width = "w-56", className, children }) => {
3691
- const { open, setOpen, triggerRect, align } = useCtx2();
4088
+ const { open, setOpen, triggerRect, align } = useCtx3();
3692
4089
  if (!open || !triggerRect) return null;
3693
4090
  const top = triggerRect.bottom + 8;
3694
4091
  const positionStyle2 = align === "right" ? { top, right: window.innerWidth - triggerRect.right } : { top, left: triggerRect.left };
@@ -3731,7 +4128,7 @@ var UserMenuHeader = ({ name, email, avatarSrc, className }) => /* @__PURE__ */
3731
4128
  );
3732
4129
  var UserMenuItems = ({ children }) => /* @__PURE__ */ jsx("div", { role: "group", className: "py-1", children });
3733
4130
  var UserMenuItem = forwardRef(function UserMenuItem2({ icon: Icon2, variant = "default", closeOnClick = true, onClick, className, children, ...rest }, ref) {
3734
- const { setOpen } = useCtx2();
4131
+ const { setOpen } = useCtx3();
3735
4132
  return /* @__PURE__ */ jsxs(
3736
4133
  "button",
3737
4134
  {
@@ -3812,7 +4209,7 @@ var SIZE_CLASS9 = {
3812
4209
  sm: { box: "h-8 w-8", icon: "h-4 w-4" },
3813
4210
  md: { box: "h-10 w-10", icon: "h-5 w-5" }
3814
4211
  };
3815
- var TRI_ORDER = ["light", "dark", "oled"];
4212
+ var TRI_ORDER = ["light", "dark", "deep-blue"];
3816
4213
  var nextInCycle = (current) => {
3817
4214
  const idx = TRI_ORDER.indexOf(current);
3818
4215
  return TRI_ORDER[(idx + 1) % TRI_ORDER.length];
@@ -3820,7 +4217,7 @@ var nextInCycle = (current) => {
3820
4217
  var ICON_FOR = {
3821
4218
  light: Sun,
3822
4219
  dark: Moon,
3823
- oled: MoonStar
4220
+ "deep-blue": MoonStar
3824
4221
  };
3825
4222
  var ThemeToggleTri = forwardRef(
3826
4223
  function ThemeToggleTri2({
@@ -3829,12 +4226,12 @@ var ThemeToggleTri = forwardRef(
3829
4226
  size = "md",
3830
4227
  lightLabel = "Switch to light mode",
3831
4228
  darkLabel = "Switch to dark mode",
3832
- oledLabel = "Switch to OLED mode",
4229
+ deepBlueLabel = "Switch to deep blue mode",
3833
4230
  className,
3834
4231
  ...rest
3835
4232
  }, ref) {
3836
4233
  const next = nextInCycle(theme);
3837
- const label = next === "light" ? lightLabel : next === "dark" ? darkLabel : oledLabel;
4234
+ const label = next === "light" ? lightLabel : next === "dark" ? darkLabel : deepBlueLabel;
3838
4235
  const Icon2 = ICON_FOR[theme];
3839
4236
  const { box, icon } = SIZE_CLASS9[size];
3840
4237
  return /* @__PURE__ */ jsx(
@@ -3908,7 +4305,7 @@ var ButtonGroup = ({
3908
4305
  );
3909
4306
  };
3910
4307
  var CarouselContext = createContext(null);
3911
- var useCtx3 = () => {
4308
+ var useCtx4 = () => {
3912
4309
  const ctx = useContext(CarouselContext);
3913
4310
  if (!ctx) throw new Error("Carousel.* must be used inside <Carousel>");
3914
4311
  return ctx;
@@ -3964,7 +4361,7 @@ var CarouselRoot = ({
3964
4361
  );
3965
4362
  };
3966
4363
  var CarouselViewport = ({ children, className }) => {
3967
- const { emblaRef } = useCtx3();
4364
+ const { emblaRef } = useCtx4();
3968
4365
  return /* @__PURE__ */ jsx("div", { ref: emblaRef, className: clsx("overflow-hidden", className), children: /* @__PURE__ */ jsx("div", { className: "flex", children }) });
3969
4366
  };
3970
4367
  var CarouselSlide = ({ basis = "basis-full", className, children }) => /* @__PURE__ */ jsx("div", { className: clsx("min-w-0 shrink-0 grow-0 px-1", basis, className), children });
@@ -3974,7 +4371,7 @@ var CarouselControls = ({
3974
4371
  prevLabel = "Previous slide",
3975
4372
  nextLabel = "Next slide"
3976
4373
  }) => {
3977
- const { scrollPrev, scrollNext, canScrollPrev, canScrollNext } = useCtx3();
4374
+ const { scrollPrev, scrollNext, canScrollPrev, canScrollNext } = useCtx4();
3978
4375
  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";
3979
4376
  if (position === "outside") {
3980
4377
  return /* @__PURE__ */ jsxs("div", { className: clsx("mt-3 flex items-center justify-center gap-2", className), children: [
@@ -4027,197 +4424,31 @@ var CarouselControls = ({
4027
4424
  )
4028
4425
  ] });
4029
4426
  };
4030
- var CarouselIndicators = ({ className }) => {
4031
- const { scrollSnaps, selectedIndex, scrollTo } = useCtx3();
4032
- return /* @__PURE__ */ jsx("div", { className: clsx("mt-3 flex items-center justify-center gap-2", className), children: scrollSnaps.map((_, i) => {
4033
- const active = i === selectedIndex;
4034
- return /* @__PURE__ */ jsx(
4035
- "button",
4036
- {
4037
- type: "button",
4038
- "aria-label": `Go to slide ${i + 1}`,
4039
- "aria-current": active,
4040
- onClick: () => scrollTo(i),
4041
- className: clsx(
4042
- "h-2 rounded-full transition-all",
4043
- active ? "bg-brand-500 w-6" : "w-2 bg-gray-300 dark:bg-gray-600"
4044
- )
4045
- },
4046
- i
4047
- );
4048
- }) });
4049
- };
4050
- var Carousel = Object.assign(CarouselRoot, {
4051
- Viewport: CarouselViewport,
4052
- Slide: CarouselSlide,
4053
- Controls: CarouselControls,
4054
- Indicators: CarouselIndicators
4055
- });
4056
- var PopoverContext = createContext(null);
4057
- var useCtx4 = () => {
4058
- const ctx = useContext(PopoverContext);
4059
- if (!ctx) throw new Error("Popover.* must be used inside <Popover>");
4060
- return ctx;
4061
- };
4062
- var PopoverRoot = ({
4063
- open: openProp,
4064
- defaultOpen = false,
4065
- onOpenChange,
4066
- children
4067
- }) => {
4068
- const [internalOpen, setInternalOpen] = useState(defaultOpen);
4069
- const isControlled = openProp !== void 0;
4070
- const open = isControlled ? openProp : internalOpen;
4071
- const triggerRef = useRef(null);
4072
- const [triggerRect, setTriggerRect] = useState(null);
4073
- const refreshRect = useCallback(() => {
4074
- if (triggerRef.current) setTriggerRect(triggerRef.current.getBoundingClientRect());
4075
- }, []);
4076
- const setOpen = useCallback(
4077
- (v) => {
4078
- if (v) refreshRect();
4079
- if (!isControlled) setInternalOpen(v);
4080
- onOpenChange?.(v);
4081
- },
4082
- [isControlled, onOpenChange, refreshRect]
4083
- );
4084
- useEffect(() => {
4085
- if (!open) return;
4086
- const handler = () => refreshRect();
4087
- window.addEventListener("resize", handler);
4088
- window.addEventListener("scroll", handler, true);
4089
- return () => {
4090
- window.removeEventListener("resize", handler);
4091
- window.removeEventListener("scroll", handler, true);
4092
- };
4093
- }, [open, refreshRect]);
4094
- useEffect(() => {
4095
- if (!open) return;
4096
- const handler = (e) => {
4097
- if (e.key === "Escape") setOpen(false);
4098
- };
4099
- document.addEventListener("keydown", handler);
4100
- return () => document.removeEventListener("keydown", handler);
4101
- }, [open, setOpen]);
4102
- return /* @__PURE__ */ jsx(PopoverContext.Provider, { value: { open, setOpen, triggerRef, triggerRect, refreshRect }, children });
4103
- };
4104
- var PopoverTrigger = forwardRef(function PopoverTrigger2({ onClick, children, ...rest }, forwardedRef) {
4105
- const { open, setOpen, triggerRef, refreshRect } = useCtx4();
4106
- const setRef = (node) => {
4107
- triggerRef.current = node;
4108
- if (typeof forwardedRef === "function") forwardedRef(node);
4109
- else if (forwardedRef) forwardedRef.current = node;
4110
- };
4111
- useEffect(() => {
4112
- if (open) refreshRect();
4113
- }, [open, refreshRect]);
4114
- return /* @__PURE__ */ jsx(
4115
- "button",
4116
- {
4117
- ref: setRef,
4118
- type: "button",
4119
- "aria-haspopup": "dialog",
4120
- "aria-expanded": open,
4121
- onClick: (e) => {
4122
- onClick?.(e);
4123
- setOpen(!open);
4124
- },
4125
- ...rest,
4126
- children
4127
- }
4128
- );
4129
- });
4130
- var positionStyle = (position, rect, offset) => {
4131
- switch (position) {
4132
- case "top":
4133
- return {
4134
- top: rect.top - offset,
4135
- left: rect.left + rect.width / 2,
4136
- transform: "translate(-50%, -100%)"
4137
- };
4138
- case "right":
4139
- return {
4140
- top: rect.top + rect.height / 2,
4141
- left: rect.right + offset,
4142
- transform: "translateY(-50%)"
4143
- };
4144
- case "left":
4145
- return {
4146
- top: rect.top + rect.height / 2,
4147
- left: rect.left - offset,
4148
- transform: "translate(-100%, -50%)"
4149
- };
4150
- case "bottom":
4151
- default:
4152
- return {
4153
- top: rect.bottom + offset,
4154
- left: rect.left + rect.width / 2,
4155
- transform: "translateX(-50%)"
4156
- };
4157
- }
4158
- };
4159
- var arrowStyle = (position) => {
4160
- const base = {
4161
- position: "absolute",
4162
- width: 8,
4163
- height: 8,
4164
- transform: "rotate(45deg)"
4165
- };
4166
- switch (position) {
4167
- case "top":
4168
- return { ...base, bottom: -4, left: "50%", marginLeft: -4 };
4169
- case "right":
4170
- return { ...base, left: -4, top: "50%", marginTop: -4 };
4171
- case "left":
4172
- return { ...base, right: -4, top: "50%", marginTop: -4 };
4173
- case "bottom":
4174
- default:
4175
- return { ...base, top: -4, left: "50%", marginLeft: -4 };
4176
- }
4177
- };
4178
- var PopoverContent = ({
4179
- position = "bottom",
4180
- offset = 8,
4181
- arrow = false,
4182
- width = "w-64",
4183
- className,
4184
- children
4185
- }) => {
4186
- const { open, setOpen, triggerRect } = useCtx4();
4187
- if (!open || !triggerRect) return null;
4188
- return createPortal(
4189
- /* @__PURE__ */ jsxs(Fragment$1, { children: [
4190
- /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-[9998]", onClick: () => setOpen(false) }),
4191
- /* @__PURE__ */ jsxs(
4192
- "div",
4193
- {
4194
- role: "dialog",
4195
- style: positionStyle(position, triggerRect, offset),
4196
- className: clsx(
4197
- "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",
4198
- width,
4199
- className
4200
- ),
4201
- children: [
4202
- arrow && /* @__PURE__ */ jsx(
4203
- "span",
4204
- {
4205
- "aria-hidden": true,
4206
- style: arrowStyle(position),
4207
- className: "border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900"
4208
- }
4209
- ),
4210
- /* @__PURE__ */ jsx("div", { className: "relative", children })
4211
- ]
4212
- }
4213
- )
4214
- ] }),
4215
- document.body
4216
- );
4217
- };
4218
- var Popover = Object.assign(PopoverRoot, {
4219
- Trigger: PopoverTrigger,
4220
- Content: PopoverContent
4427
+ var CarouselIndicators = ({ className }) => {
4428
+ const { scrollSnaps, selectedIndex, scrollTo } = useCtx4();
4429
+ return /* @__PURE__ */ jsx("div", { className: clsx("mt-3 flex items-center justify-center gap-2", className), children: scrollSnaps.map((_, i) => {
4430
+ const active = i === selectedIndex;
4431
+ return /* @__PURE__ */ jsx(
4432
+ "button",
4433
+ {
4434
+ type: "button",
4435
+ "aria-label": `Go to slide ${i + 1}`,
4436
+ "aria-current": active,
4437
+ onClick: () => scrollTo(i),
4438
+ className: clsx(
4439
+ "h-2 rounded-full transition-all",
4440
+ active ? "bg-brand-500 w-6" : "w-2 bg-gray-300 dark:bg-gray-600"
4441
+ )
4442
+ },
4443
+ i
4444
+ );
4445
+ }) });
4446
+ };
4447
+ var Carousel = Object.assign(CarouselRoot, {
4448
+ Viewport: CarouselViewport,
4449
+ Slide: CarouselSlide,
4450
+ Controls: CarouselControls,
4451
+ Indicators: CarouselIndicators
4221
4452
  });
4222
4453
  var SIZE_TRACK = {
4223
4454
  xs: "h-1",
@@ -4287,7 +4518,7 @@ var ProgressBar = ({
4287
4518
  INTENT_BG2[intent],
4288
4519
  striped && "motion-safe:animate-[progressStripes_1s_linear_infinite]"
4289
4520
  ),
4290
- children: showInsideLabel && /* @__PURE__ */ jsx("span", { className: "px-2 text-[10px] leading-none font-bold text-white", children: labelText })
4521
+ children: showInsideLabel && /* @__PURE__ */ jsx("span", { className: "text-3xs px-2 leading-none font-bold text-white", children: labelText })
4291
4522
  }
4292
4523
  )
4293
4524
  }
@@ -4344,7 +4575,7 @@ var Ribbon = ({
4344
4575
  "span",
4345
4576
  {
4346
4577
  className: clsx(
4347
- "absolute z-10 w-40 px-2 py-1 text-center text-[11px] font-bold tracking-wide uppercase shadow-md",
4578
+ "text-2xs absolute z-10 w-40 px-2 py-1 text-center font-bold tracking-wide uppercase shadow-md",
4348
4579
  INTENT_BG3[intent],
4349
4580
  ANGLED_POSITION[position],
4350
4581
  className
@@ -4357,7 +4588,7 @@ var Ribbon = ({
4357
4588
  "span",
4358
4589
  {
4359
4590
  className: clsx(
4360
- "absolute z-10 px-2.5 py-1 text-[11px] font-bold tracking-wide uppercase shadow",
4591
+ "text-2xs absolute z-10 px-2.5 py-1 font-bold tracking-wide uppercase shadow",
4361
4592
  INTENT_BG3[intent],
4362
4593
  FLAT_POSITION[position],
4363
4594
  className
@@ -4924,7 +5155,7 @@ var CommandPaletteGroup = forwardRef(
4924
5155
  {
4925
5156
  ref,
4926
5157
  className: clsx(
4927
- "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",
5158
+ "[&_[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",
4928
5159
  className
4929
5160
  ),
4930
5161
  ...rest
@@ -4949,7 +5180,7 @@ var CommandPaletteItem = forwardRef(
4949
5180
  children: [
4950
5181
  Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "h-4 w-4 shrink-0 text-gray-400", "aria-hidden": true }),
4951
5182
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children }),
4952
- shortcut && /* @__PURE__ */ 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 })
5183
+ shortcut && /* @__PURE__ */ 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 })
4953
5184
  ]
4954
5185
  }
4955
5186
  );
@@ -4989,7 +5220,7 @@ var CommandPaletteFooter = ({ className, children }) => /* @__PURE__ */ jsx(
4989
5220
  "div",
4990
5221
  {
4991
5222
  className: clsx(
4992
- "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",
5223
+ "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",
4993
5224
  className
4994
5225
  ),
4995
5226
  children
@@ -5114,11 +5345,11 @@ var formatKey = (raw, isMac) => {
5114
5345
  if (KEY_LABEL[key]) return KEY_LABEL[key];
5115
5346
  return raw.length === 1 ? raw.toUpperCase() : raw;
5116
5347
  };
5117
- var Kbd = ({ children, className }) => /* @__PURE__ */ jsx(
5348
+ var Kbd2 = ({ children, className }) => /* @__PURE__ */ jsx(
5118
5349
  "kbd",
5119
5350
  {
5120
5351
  className: clsx(
5121
- "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",
5352
+ "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",
5122
5353
  className
5123
5354
  ),
5124
5355
  children
@@ -5208,7 +5439,7 @@ var HelpOverlayRoot = ({
5208
5439
  /* @__PURE__ */ 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 }),
5209
5440
  (footer ?? true) && /* @__PURE__ */ 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__ */ jsxs(Fragment$1, { children: [
5210
5441
  "Press ",
5211
- /* @__PURE__ */ jsx(Kbd, { children: "Esc" }),
5442
+ /* @__PURE__ */ jsx(Kbd2, { children: "Esc" }),
5212
5443
  " to close"
5213
5444
  ] }) })
5214
5445
  ]
@@ -5219,7 +5450,7 @@ var HelpOverlayRoot = ({
5219
5450
  );
5220
5451
  };
5221
5452
  var HelpOverlaySection = ({ title, className, children }) => /* @__PURE__ */ jsxs("section", { className: clsx("space-y-2", className), children: [
5222
- /* @__PURE__ */ jsx("h3", { className: "text-[11px] font-semibold tracking-wider text-gray-400 uppercase dark:text-gray-500", children: title }),
5453
+ /* @__PURE__ */ jsx("h3", { className: "text-2xs font-semibold tracking-wider text-gray-400 uppercase dark:text-gray-500", children: title }),
5223
5454
  /* @__PURE__ */ jsx("ul", { className: "divide-y divide-gray-100 dark:divide-gray-800", children })
5224
5455
  ] });
5225
5456
  var HelpOverlayShortcut = ({ keys, description, className }) => {
@@ -5230,10 +5461,10 @@ var HelpOverlayShortcut = ({ keys, description, className }) => {
5230
5461
  /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center gap-1", children: sequence.map((combo, idx) => {
5231
5462
  const parts = combo.split("+");
5232
5463
  return /* @__PURE__ */ jsxs(Fragment, { children: [
5233
- idx > 0 && /* @__PURE__ */ jsx("span", { className: "px-0.5 text-[10px] text-gray-400 uppercase dark:text-gray-500", children: "then" }),
5464
+ idx > 0 && /* @__PURE__ */ jsx("span", { className: "text-3xs px-0.5 text-gray-400 uppercase dark:text-gray-500", children: "then" }),
5234
5465
  /* @__PURE__ */ jsx("span", { className: "flex items-center gap-1", children: parts.map((part, pIdx) => /* @__PURE__ */ jsxs(Fragment, { children: [
5235
5466
  pIdx > 0 && /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-400 dark:text-gray-500", children: "+" }),
5236
- /* @__PURE__ */ jsx(Kbd, { children: formatKey(part, isMac) })
5467
+ /* @__PURE__ */ jsx(Kbd2, { children: formatKey(part, isMac) })
5237
5468
  ] }, `${part}-${pIdx}`)) })
5238
5469
  ] }, `${combo}-${idx}`);
5239
5470
  }) })
@@ -5493,13 +5724,14 @@ var StepperInput = ({
5493
5724
  className
5494
5725
  }) => {
5495
5726
  const clamp = (v) => Math.min(max, Math.max(min, v));
5496
- 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";
5727
+ 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";
5497
5728
  return /* @__PURE__ */ jsxs(
5498
5729
  "div",
5499
5730
  {
5500
5731
  className: clsx(
5501
5732
  fullWidth ? "flex w-full" : "inline-flex",
5502
- "h-9 overflow-hidden rounded-lg border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800",
5733
+ // dark:focus-within: is explicit, dark:border-gray-700 would win otherwise.
5734
+ "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",
5503
5735
  disabled && "opacity-50",
5504
5736
  className
5505
5737
  ),
@@ -5518,13 +5750,14 @@ var StepperInput = ({
5518
5750
  max,
5519
5751
  step,
5520
5752
  className: clsx(
5521
- "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",
5753
+ // min-w-0: in a narrower container the input gives way, not the arrows.
5754
+ "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",
5522
5755
  fullWidth ? "flex-1" : width
5523
5756
  )
5524
5757
  }
5525
5758
  ),
5526
- unit && /* @__PURE__ */ jsx("span", { className: "flex items-center pr-1.5 text-xs text-gray-400 select-none dark:text-gray-500", children: unit }),
5527
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col border-l border-gray-200 dark:border-gray-700", children: [
5759
+ unit && /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center pr-1.5 text-xs text-gray-400 select-none dark:text-gray-500", children: unit }),
5760
+ /* @__PURE__ */ jsxs("div", { className: "flex w-7 shrink-0 flex-col border-l border-gray-200 dark:border-gray-700", children: [
5528
5761
  /* @__PURE__ */ jsx(
5529
5762
  "button",
5530
5763
  {
@@ -5534,7 +5767,7 @@ var StepperInput = ({
5534
5767
  tabIndex: -1,
5535
5768
  "aria-label": "Increase",
5536
5769
  className: arrowBtn,
5537
- children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-3.5 w-3.5 text-gray-500 dark:text-gray-400", strokeWidth: 2.5 })
5770
+ children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-3 w-3", strokeWidth: 2.25, "aria-hidden": true })
5538
5771
  }
5539
5772
  ),
5540
5773
  /* @__PURE__ */ jsx(
@@ -5546,7 +5779,7 @@ var StepperInput = ({
5546
5779
  tabIndex: -1,
5547
5780
  "aria-label": "Decrease",
5548
5781
  className: clsx("border-t border-gray-200 dark:border-gray-700", arrowBtn),
5549
- children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5 text-gray-500 dark:text-gray-400", strokeWidth: 2.5 })
5782
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3", strokeWidth: 2.25, "aria-hidden": true })
5550
5783
  }
5551
5784
  )
5552
5785
  ] })
@@ -6623,7 +6856,7 @@ var Calendar = ({ classNames, components, className, ...rest }) => {
6623
6856
  months_dropdown: "",
6624
6857
  years_dropdown: "",
6625
6858
  weekdays: clsx(def.weekdays, ""),
6626
- weekday: "h-8 w-8 text-center text-[11px] font-medium text-gray-400 dark:text-gray-500",
6859
+ weekday: "h-8 w-8 text-center text-2xs font-medium text-gray-400 dark:text-gray-500",
6627
6860
  week: clsx(def.week, ""),
6628
6861
  day: "h-8 w-8 p-0 text-center align-middle",
6629
6862
  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",
@@ -6979,7 +7212,7 @@ var OtpInput = ({
6979
7212
  }) => {
6980
7213
  const refs = useRef([]);
6981
7214
  useEffect(() => {
6982
- if (autoFocus) refs.current[0]?.focus();
7215
+ if (autoFocus) refs.current[0]?.focus({ preventScroll: true });
6983
7216
  }, [autoFocus]);
6984
7217
  const setCell = (idx, char) => {
6985
7218
  const cleaned = sanitize(char, alphanumeric).slice(0, 1);
@@ -7341,30 +7574,84 @@ var StepperIndicator = ({
7341
7574
  children: Icon2 ? /* @__PURE__ */ jsx(Icon2, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx("span", { className: "h-2 w-2 rounded-full bg-current" })
7342
7575
  }
7343
7576
  );
7577
+ var Meta = ({ meta }) => meta ? /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: meta }) : null;
7344
7578
  var Body5 = ({ item }) => /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 pb-2 last:pb-0", children: [
7345
7579
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: item.title }),
7346
7580
  item.description && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: item.description }),
7347
- item.time && /* @__PURE__ */ jsx("p", { className: "mt-0.5 font-mono text-[10px] text-gray-400 uppercase", children: item.time })
7581
+ /* @__PURE__ */ jsx(Meta, { meta: item.meta }),
7582
+ item.time && /* @__PURE__ */ jsx("p", { className: "text-3xs mt-0.5 font-mono text-gray-400 uppercase", children: item.time })
7348
7583
  ] });
7349
- var Timeline = ({ items, variant = "dot", className }) => {
7584
+ var TimelineList = ({
7585
+ items,
7586
+ variant = "dot",
7587
+ className,
7588
+ startIndex = 0,
7589
+ labelledBy
7590
+ }) => {
7350
7591
  if (variant === "card") {
7351
- return /* @__PURE__ */ jsx("ol", { className: clsx("space-y-3", className), children: items.map((item) => /* @__PURE__ */ jsx(
7592
+ return /* @__PURE__ */ jsx("ol", { "aria-labelledby": labelledBy, className: clsx("space-y-3", className), children: items.map((item) => /* @__PURE__ */ jsx(
7352
7593
  "li",
7353
7594
  {
7354
7595
  className: "rounded-xl border border-gray-200 bg-white p-3 dark:border-gray-800 dark:bg-gray-900",
7355
7596
  children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
7356
7597
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
7357
7598
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: item.title }),
7358
- item.description && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: item.description })
7599
+ item.description && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: item.description }),
7600
+ /* @__PURE__ */ jsx(Meta, { meta: item.meta })
7359
7601
  ] }),
7360
- item.time && /* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-[10px] text-gray-400 uppercase", children: item.time })
7602
+ item.time && /* @__PURE__ */ jsx("span", { className: "text-3xs shrink-0 font-mono text-gray-400 uppercase", children: item.time })
7361
7603
  ] })
7362
7604
  },
7363
7605
  item.id
7364
7606
  )) });
7365
7607
  }
7608
+ if (variant === "alternating") {
7609
+ return /* @__PURE__ */ jsx("ol", { "aria-labelledby": labelledBy, className: clsx("flex flex-col", className), children: items.map((item, i) => {
7610
+ const isLast = i === items.length - 1;
7611
+ const left = (startIndex + i) % 2 === 0;
7612
+ return /* @__PURE__ */ jsxs(
7613
+ "li",
7614
+ {
7615
+ className: "grid grid-cols-[2.5rem_minmax(0,1fr)] gap-x-4 md:grid-cols-[minmax(0,1fr)_2.5rem_minmax(0,1fr)]",
7616
+ children: [
7617
+ /* @__PURE__ */ jsxs("div", { className: "col-start-1 row-start-1 flex flex-col items-center md:col-start-2", children: [
7618
+ /* @__PURE__ */ jsx(StepperIndicator, { icon: item.icon, tone: item.tone }),
7619
+ !isLast && /* @__PURE__ */ jsx("span", { className: "my-1 w-px flex-1 bg-gray-200 dark:bg-gray-700" })
7620
+ ] }),
7621
+ /* @__PURE__ */ jsx(
7622
+ "div",
7623
+ {
7624
+ className: clsx(
7625
+ "col-start-2 row-start-1",
7626
+ left ? "md:col-start-1" : "md:col-start-3",
7627
+ !isLast && "pb-6"
7628
+ ),
7629
+ children: /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900", children: [
7630
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: item.title }),
7631
+ item.description && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: item.description }),
7632
+ /* @__PURE__ */ jsx(Meta, { meta: item.meta }),
7633
+ item.time && /* @__PURE__ */ jsx("p", { className: "text-3xs mt-2 font-mono text-gray-400 uppercase md:hidden", children: item.time })
7634
+ ] })
7635
+ }
7636
+ ),
7637
+ item.time && /* @__PURE__ */ jsx(
7638
+ "p",
7639
+ {
7640
+ className: clsx(
7641
+ "text-3xs row-start-1 hidden pt-3 font-mono text-gray-400 uppercase md:block",
7642
+ left ? "md:col-start-3" : "md:col-start-1 md:text-right"
7643
+ ),
7644
+ children: item.time
7645
+ }
7646
+ )
7647
+ ]
7648
+ },
7649
+ item.id
7650
+ );
7651
+ }) });
7652
+ }
7366
7653
  const gap = variant === "stepper" ? "gap-x-4" : "gap-x-3";
7367
- return /* @__PURE__ */ jsx("ol", { className: clsx("flex flex-col", className), children: items.map((item, i) => {
7654
+ return /* @__PURE__ */ jsx("ol", { "aria-labelledby": labelledBy, className: clsx("flex flex-col", className), children: items.map((item, i) => {
7368
7655
  const isLast = i === items.length - 1;
7369
7656
  return /* @__PURE__ */ jsxs("li", { className: clsx("flex", gap), children: [
7370
7657
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center", children: [
@@ -7375,7 +7662,50 @@ var Timeline = ({ items, variant = "dot", className }) => {
7375
7662
  ] }, item.id);
7376
7663
  }) });
7377
7664
  };
7378
- var WEEK_DAYS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
7665
+ var groupRuns = (items) => {
7666
+ const runs = [];
7667
+ items.forEach((item, i) => {
7668
+ const last = runs[runs.length - 1];
7669
+ if (last && last.group === item.group) last.items.push(item);
7670
+ else runs.push({ group: item.group, start: i, items: [item] });
7671
+ });
7672
+ return runs;
7673
+ };
7674
+ var GroupHeader = ({ id, label, centred }) => centred ? (
7675
+ // A pill on the line; it moves to the left with the line below `md`.
7676
+ /* @__PURE__ */ jsx("h3", { id, className: "mb-4 flex md:justify-center", children: /* @__PURE__ */ 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 }) })
7677
+ ) : /* @__PURE__ */ jsx(
7678
+ "h3",
7679
+ {
7680
+ id,
7681
+ className: "mb-3 text-xs font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400",
7682
+ children: label
7683
+ }
7684
+ );
7685
+ var Timeline = ({ items, variant = "dot", className }) => {
7686
+ const baseId = useId();
7687
+ const runs = groupRuns(items);
7688
+ if (runs.every((run) => !run.group)) {
7689
+ return /* @__PURE__ */ jsx(TimelineList, { items, variant, className });
7690
+ }
7691
+ return /* @__PURE__ */ jsx("div", { className: clsx("space-y-6", className), children: runs.map((run, i) => {
7692
+ const headerId = `${baseId}-group-${i}`;
7693
+ return /* @__PURE__ */ jsxs("div", { children: [
7694
+ run.group && /* @__PURE__ */ jsx(GroupHeader, { id: headerId, label: run.group, centred: variant === "alternating" }),
7695
+ /* @__PURE__ */ jsx(
7696
+ TimelineList,
7697
+ {
7698
+ items: run.items,
7699
+ variant,
7700
+ startIndex: run.start,
7701
+ labelledBy: run.group ? headerId : void 0
7702
+ }
7703
+ )
7704
+ ] }, run.start);
7705
+ }) });
7706
+ };
7707
+
7708
+ // src/data/calendar-dates.ts
7379
7709
  var MONTHS = [
7380
7710
  "January",
7381
7711
  "February",
@@ -7392,6 +7722,8 @@ var MONTHS = [
7392
7722
  ];
7393
7723
  var isoDate = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
7394
7724
  var sameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
7725
+ var isoWeekday = (d) => (d.getDay() + 6) % 7;
7726
+ var WEEK_DAYS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
7395
7727
  var MiniCalendar = ({
7396
7728
  today = /* @__PURE__ */ new Date(),
7397
7729
  selected,
@@ -7403,7 +7735,7 @@ var MiniCalendar = ({
7403
7735
  const cells = useMemo(() => {
7404
7736
  const firstOfMonth = new Date(view.getFullYear(), view.getMonth(), 1);
7405
7737
  const daysInMonth = new Date(view.getFullYear(), view.getMonth() + 1, 0).getDate();
7406
- const isoOffset = (firstOfMonth.getDay() + 6) % 7;
7738
+ const isoOffset = isoWeekday(firstOfMonth);
7407
7739
  const arr = Array(isoOffset).fill(null);
7408
7740
  for (let d = 1; d <= daysInMonth; d++)
7409
7741
  arr.push(new Date(view.getFullYear(), view.getMonth(), d));
@@ -7460,7 +7792,7 @@ var MiniCalendar = ({
7460
7792
  WEEK_DAYS.map((d) => /* @__PURE__ */ jsx(
7461
7793
  "span",
7462
7794
  {
7463
- className: "py-1 text-[10px] font-semibold tracking-wider text-gray-400 uppercase",
7795
+ className: "text-3xs py-1 font-semibold tracking-wider text-gray-400 uppercase",
7464
7796
  children: d
7465
7797
  },
7466
7798
  d
@@ -7500,6 +7832,275 @@ var MiniCalendar = ({
7500
7832
  }
7501
7833
  );
7502
7834
  };
7835
+ var WEEK_DAYS2 = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
7836
+ var WEEK_DAYS_LONG = [
7837
+ "Monday",
7838
+ "Tuesday",
7839
+ "Wednesday",
7840
+ "Thursday",
7841
+ "Friday",
7842
+ "Saturday",
7843
+ "Sunday"
7844
+ ];
7845
+ var MAX_CHIPS = 3;
7846
+ var TONE_DOT = {
7847
+ brand: "bg-brand-500",
7848
+ success: "bg-green-500",
7849
+ warning: "bg-amber-500",
7850
+ danger: "bg-red-500",
7851
+ info: "bg-blue-500",
7852
+ violet: "bg-violet-500"
7853
+ };
7854
+ var TONE_CHIP = {
7855
+ brand: "bg-brand-50 dark:bg-brand-500/15",
7856
+ success: "bg-green-50 dark:bg-green-500/15",
7857
+ warning: "bg-amber-50 dark:bg-amber-500/15",
7858
+ danger: "bg-red-50 dark:bg-red-500/15",
7859
+ info: "bg-blue-50 dark:bg-blue-500/15",
7860
+ violet: "bg-violet-50 dark:bg-violet-500/15"
7861
+ };
7862
+ var TONE_CHIP_HOVER = {
7863
+ brand: "hover:bg-brand-100 dark:hover:bg-brand-500/25",
7864
+ success: "hover:bg-green-100 dark:hover:bg-green-500/25",
7865
+ warning: "hover:bg-amber-100 dark:hover:bg-amber-500/25",
7866
+ danger: "hover:bg-red-100 dark:hover:bg-red-500/25",
7867
+ info: "hover:bg-blue-100 dark:hover:bg-blue-500/25",
7868
+ violet: "hover:bg-violet-100 dark:hover:bg-violet-500/25"
7869
+ };
7870
+ var FOCUS_RING = "focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-500";
7871
+ var addDays = (d, n) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + n);
7872
+ var startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
7873
+ var startOfMonth = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
7874
+ var dayLabel = (d) => `${WEEK_DAYS_LONG[isoWeekday(d)]} ${d.getDate()} ${MONTHS[d.getMonth()]} ${d.getFullYear()}`;
7875
+ var monthGrid = (month) => {
7876
+ const first = startOfMonth(month);
7877
+ const last = new Date(first.getFullYear(), first.getMonth() + 1, 0);
7878
+ const end = addDays(last, 6 - isoWeekday(last));
7879
+ const days = [];
7880
+ for (let d = addDays(first, -isoWeekday(first)); d <= end; d = addDays(d, 1)) days.push(d);
7881
+ return days;
7882
+ };
7883
+ var indexByDay = (events, first, last) => {
7884
+ const byDay = /* @__PURE__ */ new Map();
7885
+ const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime());
7886
+ for (const event of sorted) {
7887
+ const start = startOfDay(event.start);
7888
+ const end = event.end && event.end > event.start ? startOfDay(event.end) : start;
7889
+ const to = end < last ? end : last;
7890
+ for (let d = start < first ? first : start; d <= to; d = addDays(d, 1)) {
7891
+ const key = isoDate(d);
7892
+ const list = byDay.get(key);
7893
+ if (list) list.push(event);
7894
+ else byDay.set(key, [event]);
7895
+ }
7896
+ }
7897
+ return byDay;
7898
+ };
7899
+ var EventChip = ({
7900
+ event,
7901
+ onClick,
7902
+ compact = false
7903
+ }) => {
7904
+ const tone = event.tone ?? "brand";
7905
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
7906
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: clsx("h-1.5 w-1.5 shrink-0 rounded-full", TONE_DOT[tone]) }),
7907
+ /* @__PURE__ */ jsx("span", { className: clsx("truncate", compact && "max-sm:sr-only"), children: event.title })
7908
+ ] });
7909
+ const className = clsx(
7910
+ "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",
7911
+ TONE_CHIP[tone],
7912
+ compact ? "max-sm:bg-transparent max-sm:px-1 sm:w-full max-sm:dark:bg-transparent" : "w-full"
7913
+ );
7914
+ if (!onClick) {
7915
+ return /* @__PURE__ */ jsx("div", { title: event.title, className, children: content });
7916
+ }
7917
+ return /* @__PURE__ */ jsx(
7918
+ "button",
7919
+ {
7920
+ type: "button",
7921
+ title: event.title,
7922
+ onClick: () => onClick(event),
7923
+ className: clsx(className, TONE_CHIP_HOVER[tone], FOCUS_RING),
7924
+ children: content
7925
+ }
7926
+ );
7927
+ };
7928
+ var EventCalendar = ({
7929
+ events,
7930
+ month,
7931
+ defaultMonth,
7932
+ onMonthChange,
7933
+ today = /* @__PURE__ */ new Date(),
7934
+ onEventClick,
7935
+ onDayClick,
7936
+ className
7937
+ }) => {
7938
+ const [internalMonth, setInternalMonth] = useState(() => startOfMonth(defaultMonth ?? today));
7939
+ const [openDay, setOpenDay] = useState(null);
7940
+ const shown = startOfMonth(month ?? internalMonth);
7941
+ const { days, byDay } = useMemo(() => {
7942
+ const grid = monthGrid(month ?? internalMonth);
7943
+ return { days: grid, byDay: indexByDay(events, grid[0], grid[grid.length - 1]) };
7944
+ }, [events, month, internalMonth]);
7945
+ const goTo = (next) => {
7946
+ if (month === void 0) setInternalMonth(next);
7947
+ onMonthChange?.(next);
7948
+ };
7949
+ const isTodayMonth = shown.getFullYear() === today.getFullYear() && shown.getMonth() === today.getMonth();
7950
+ return /* @__PURE__ */ jsxs(
7951
+ "div",
7952
+ {
7953
+ className: clsx(
7954
+ "overflow-hidden rounded-2xl border border-gray-200 bg-white dark:border-gray-800 dark:bg-gray-900",
7955
+ className
7956
+ ),
7957
+ children: [
7958
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 px-4 py-3", children: [
7959
+ /* @__PURE__ */ jsxs("h3", { "aria-live": "polite", className: "text-base font-semibold text-[var(--color-text-primary)]", children: [
7960
+ MONTHS[shown.getMonth()],
7961
+ " ",
7962
+ shown.getFullYear()
7963
+ ] }),
7964
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
7965
+ /* @__PURE__ */ jsx(
7966
+ Button,
7967
+ {
7968
+ variant: "secondary",
7969
+ size: "sm",
7970
+ onClick: () => goTo(startOfMonth(today)),
7971
+ disabled: isTodayMonth,
7972
+ className: "mr-1",
7973
+ children: "Today"
7974
+ }
7975
+ ),
7976
+ /* @__PURE__ */ jsx(
7977
+ "button",
7978
+ {
7979
+ type: "button",
7980
+ onClick: () => goTo(new Date(shown.getFullYear(), shown.getMonth() - 1, 1)),
7981
+ "aria-label": "Previous month",
7982
+ className: clsx(
7983
+ "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",
7984
+ FOCUS_RING
7985
+ ),
7986
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4", "aria-hidden": true })
7987
+ }
7988
+ ),
7989
+ /* @__PURE__ */ jsx(
7990
+ "button",
7991
+ {
7992
+ type: "button",
7993
+ onClick: () => goTo(new Date(shown.getFullYear(), shown.getMonth() + 1, 1)),
7994
+ "aria-label": "Next month",
7995
+ className: clsx(
7996
+ "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",
7997
+ FOCUS_RING
7998
+ ),
7999
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4", "aria-hidden": true })
8000
+ }
8001
+ )
8002
+ ] })
8003
+ ] }),
8004
+ /* @__PURE__ */ 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__ */ jsx(
8005
+ "span",
8006
+ {
8007
+ className: "text-2xs py-2 text-center font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400",
8008
+ children: d
8009
+ },
8010
+ d
8011
+ )) }),
8012
+ /* @__PURE__ */ jsx("div", { className: "-mb-px grid grid-cols-7", children: days.map((day, i) => {
8013
+ const key = isoDate(day);
8014
+ const label = dayLabel(day);
8015
+ const dayEvents = byDay.get(key) ?? [];
8016
+ const hidden = dayEvents.length - MAX_CHIPS;
8017
+ const outside = day.getMonth() !== shown.getMonth();
8018
+ const isToday = sameDay(day, today);
8019
+ const numberClass = clsx(
8020
+ "inline-flex h-6 min-w-6 items-center justify-center rounded-full px-1 text-xs font-medium",
8021
+ isToday ? "bg-brand-500 text-white" : outside ? "text-gray-400 dark:text-gray-500" : "text-gray-700 dark:text-gray-200"
8022
+ );
8023
+ return /* @__PURE__ */ jsxs(
8024
+ "div",
8025
+ {
8026
+ role: "group",
8027
+ "aria-label": label,
8028
+ className: clsx(
8029
+ "min-h-20 min-w-0 border-b border-gray-200 p-1.5 sm:min-h-28 dark:border-gray-800",
8030
+ i % 7 !== 6 && "border-r",
8031
+ outside && "bg-gray-50 dark:bg-white/[0.02]"
8032
+ ),
8033
+ children: [
8034
+ onDayClick ? /* @__PURE__ */ jsx(
8035
+ "button",
8036
+ {
8037
+ type: "button",
8038
+ "aria-label": label,
8039
+ "aria-current": isToday ? "date" : void 0,
8040
+ onClick: () => onDayClick(day),
8041
+ className: clsx(
8042
+ numberClass,
8043
+ !isToday && "hover:bg-gray-100 dark:hover:bg-white/5",
8044
+ FOCUS_RING
8045
+ ),
8046
+ children: day.getDate()
8047
+ }
8048
+ ) : /* @__PURE__ */ jsx(
8049
+ "time",
8050
+ {
8051
+ dateTime: key,
8052
+ "aria-current": isToday ? "date" : void 0,
8053
+ className: numberClass,
8054
+ children: day.getDate()
8055
+ }
8056
+ ),
8057
+ dayEvents.length > 0 && /* @__PURE__ */ 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__ */ jsx("li", { className: "min-w-0", children: /* @__PURE__ */ jsx(EventChip, { event, onClick: onEventClick, compact: true }) }, event.id)) }),
8058
+ hidden > 0 && /* @__PURE__ */ jsxs(
8059
+ Popover,
8060
+ {
8061
+ open: openDay === key,
8062
+ onOpenChange: (open) => setOpenDay(open ? key : null),
8063
+ children: [
8064
+ /* @__PURE__ */ jsxs(
8065
+ Popover.Trigger,
8066
+ {
8067
+ "aria-label": `+${hidden} more on ${label}`,
8068
+ className: clsx(
8069
+ "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",
8070
+ FOCUS_RING
8071
+ ),
8072
+ children: [
8073
+ "+",
8074
+ hidden,
8075
+ /* @__PURE__ */ jsx("span", { className: "max-sm:sr-only", children: " more" })
8076
+ ]
8077
+ }
8078
+ ),
8079
+ /* @__PURE__ */ jsxs(Popover.Content, { "aria-label": `Events on ${label}`, width: "w-60", children: [
8080
+ /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-semibold text-[var(--color-text-primary)]", children: label }),
8081
+ /* @__PURE__ */ jsx("ul", { className: "space-y-1", children: dayEvents.map((event) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
8082
+ EventChip,
8083
+ {
8084
+ event,
8085
+ onClick: onEventClick && ((e) => {
8086
+ setOpenDay(null);
8087
+ onEventClick(e);
8088
+ })
8089
+ }
8090
+ ) }, event.id)) })
8091
+ ] })
8092
+ ]
8093
+ }
8094
+ )
8095
+ ]
8096
+ },
8097
+ key
8098
+ );
8099
+ }) })
8100
+ ]
8101
+ }
8102
+ );
8103
+ };
7503
8104
  var ColumnFilterDropdown = ({
7504
8105
  values,
7505
8106
  selected,
@@ -7564,6 +8165,16 @@ var ColumnFilterDropdown = ({
7564
8165
  }
7565
8166
  );
7566
8167
  };
8168
+
8169
+ // src/table/density.ts
8170
+ var HEADER_CELL_PADDING = {
8171
+ default: "py-3",
8172
+ comfortable: "py-4"
8173
+ };
8174
+ var BODY_CELL_PADDING = {
8175
+ default: "py-3.5",
8176
+ comfortable: "py-5"
8177
+ };
7567
8178
  var ALIGN_CLASS2 = {
7568
8179
  left: "text-left",
7569
8180
  right: "text-right",
@@ -7580,6 +8191,7 @@ var ColumnHeader = ({
7580
8191
  filterSelected,
7581
8192
  onFilterToggle,
7582
8193
  onFilterClear,
8194
+ density = "default",
7583
8195
  className
7584
8196
  }) => {
7585
8197
  const [open, setOpen] = useState(false);
@@ -7597,7 +8209,9 @@ var ColumnHeader = ({
7597
8209
  "th",
7598
8210
  {
7599
8211
  className: clsx(
7600
- "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",
8212
+ "bg-gray-50 px-4",
8213
+ HEADER_CELL_PADDING[density],
8214
+ "text-xs font-semibold tracking-wider text-gray-500 uppercase dark:bg-gray-800 dark:text-gray-400",
7601
8215
  ALIGN_CLASS2[align],
7602
8216
  className
7603
8217
  ),
@@ -7624,11 +8238,11 @@ var ColumnHeader = ({
7624
8238
  "aria-label": "Filter column",
7625
8239
  className: clsx(
7626
8240
  "flex items-center gap-1 rounded p-0.5 transition-colors hover:bg-gray-200 dark:hover:bg-white/10",
7627
- filterCount > 0 && "text-brand-500"
8241
+ filterCount > 0 && "text-brand-600 dark:text-brand-400"
7628
8242
  ),
7629
8243
  children: [
7630
8244
  /* @__PURE__ */ jsx(Filter, { className: "h-3 w-3" }),
7631
- filterCount > 0 && /* @__PURE__ */ jsx("span", { className: "text-[10px]", children: filterCount })
8245
+ filterCount > 0 && /* @__PURE__ */ jsx("span", { className: "text-3xs", children: filterCount })
7632
8246
  ]
7633
8247
  }
7634
8248
  ),
@@ -7828,6 +8442,7 @@ var DataTable = ({
7828
8442
  onRetry,
7829
8443
  emptyTitle = "No results",
7830
8444
  emptyDescription,
8445
+ density = "default",
7831
8446
  selectable = false,
7832
8447
  selection: selectionProp,
7833
8448
  defaultSelection,
@@ -8054,15 +8669,25 @@ var DataTable = ({
8054
8669
  renderRowAction && /* @__PURE__ */ jsx("col", { style: { width: "8%" } })
8055
8670
  ] }),
8056
8671
  /* @__PURE__ */ jsx("thead", { className: "sticky top-0 z-10", children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-gray-100 dark:border-gray-800", children: [
8057
- selectable && /* @__PURE__ */ jsx("th", { className: "bg-gray-50 px-4 py-3 dark:bg-gray-800", children: /* @__PURE__ */ jsx(
8058
- Checkbox,
8672
+ selectable && /* @__PURE__ */ jsx(
8673
+ "th",
8059
8674
  {
8060
- "aria-label": "Select all rows",
8061
- checked: allVisibleSelected,
8062
- indeterminate: someVisibleSelected,
8063
- onChange: toggleAllVisible
8675
+ className: clsx(
8676
+ "bg-gray-50 px-4",
8677
+ HEADER_CELL_PADDING[density],
8678
+ "dark:bg-gray-800"
8679
+ ),
8680
+ children: /* @__PURE__ */ jsx(
8681
+ Checkbox,
8682
+ {
8683
+ "aria-label": "Select all rows",
8684
+ checked: allVisibleSelected,
8685
+ indeterminate: someVisibleSelected,
8686
+ onChange: toggleAllVisible
8687
+ }
8688
+ )
8064
8689
  }
8065
- ) }),
8690
+ ),
8066
8691
  columns.map((col) => /* @__PURE__ */ jsx(
8067
8692
  ColumnHeader,
8068
8693
  {
@@ -8075,11 +8700,22 @@ var DataTable = ({
8075
8700
  filterValues: columnFilterValues[col.key],
8076
8701
  filterSelected: filters[col.key],
8077
8702
  onFilterToggle: (v) => handleFilterToggle(col.key, v),
8078
- onFilterClear: () => clearFilter(col.key)
8703
+ onFilterClear: () => clearFilter(col.key),
8704
+ density
8079
8705
  },
8080
8706
  col.key
8081
8707
  )),
8082
- renderRowAction && /* @__PURE__ */ 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" })
8708
+ renderRowAction && /* @__PURE__ */ jsx(
8709
+ "th",
8710
+ {
8711
+ className: clsx(
8712
+ "bg-gray-50 px-4",
8713
+ HEADER_CELL_PADDING[density],
8714
+ "text-right text-xs font-semibold tracking-wider text-gray-500 uppercase dark:bg-gray-800 dark:text-gray-400"
8715
+ ),
8716
+ children: "Action"
8717
+ }
8718
+ )
8083
8719
  ] }) }),
8084
8720
  /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-100 dark:divide-gray-800", children: pageRows.map((row) => {
8085
8721
  const key = rowKey(row);
@@ -8092,7 +8728,7 @@ var DataTable = ({
8092
8728
  isSelected && "bg-brand-50/40 dark:bg-brand-500/5"
8093
8729
  ),
8094
8730
  children: [
8095
- selectable && /* @__PURE__ */ jsx("td", { className: "px-4 py-3.5", children: /* @__PURE__ */ jsx(
8731
+ selectable && /* @__PURE__ */ jsx("td", { className: clsx("px-4", BODY_CELL_PADDING[density]), children: /* @__PURE__ */ jsx(
8096
8732
  Checkbox,
8097
8733
  {
8098
8734
  "aria-label": `Select row ${key}`,
@@ -8103,12 +8739,17 @@ var DataTable = ({
8103
8739
  columns.map((col) => /* @__PURE__ */ jsx(
8104
8740
  "td",
8105
8741
  {
8106
- className: clsx("px-4 py-3.5 text-sm", ALIGN_CELL[col.align ?? "left"]),
8742
+ className: clsx(
8743
+ "px-4",
8744
+ BODY_CELL_PADDING[density],
8745
+ "text-sm",
8746
+ ALIGN_CELL[col.align ?? "left"]
8747
+ ),
8107
8748
  children: col.render(row)
8108
8749
  },
8109
8750
  col.key
8110
8751
  )),
8111
- renderRowAction && /* @__PURE__ */ jsx("td", { className: "px-4 py-3.5 text-right", children: renderRowAction(row) })
8752
+ renderRowAction && /* @__PURE__ */ jsx("td", { className: clsx("px-4", BODY_CELL_PADDING[density], "text-right"), children: renderRowAction(row) })
8112
8753
  ]
8113
8754
  },
8114
8755
  key
@@ -8220,7 +8861,7 @@ var IntegrationCard = ({
8220
8861
  status && /* @__PURE__ */ jsx(Badge, { variant: STATUS_VARIANT[status], appearance: "light", children: STATUS_LABEL2[status] })
8221
8862
  ] }),
8222
8863
  /* @__PURE__ */ jsxs("div", { className: "mt-4 min-w-0 flex-1", children: [
8223
- category && /* @__PURE__ */ jsx("p", { className: "font-mono text-[10px] tracking-wide text-gray-400 uppercase dark:text-gray-500", children: category }),
8864
+ category && /* @__PURE__ */ jsx("p", { className: "text-3xs font-mono tracking-wide text-gray-400 uppercase dark:text-gray-500", children: category }),
8224
8865
  /* @__PURE__ */ jsx("h3", { className: "mt-0.5 truncate text-sm font-semibold text-gray-900 dark:text-white", children: name }),
8225
8866
  description && /* @__PURE__ */ jsx("p", { className: "mt-1 line-clamp-2 text-xs text-gray-600 dark:text-gray-400", children: description })
8226
8867
  ] }),
@@ -8392,7 +9033,7 @@ var SignInForm = ({
8392
9033
  {
8393
9034
  type: "button",
8394
9035
  onClick: onForgotPassword,
8395
- className: "text-brand-500 hover:text-brand-600 text-xs font-medium transition-colors",
9036
+ className: "text-brand-600 hover:text-brand-700 dark:text-brand-400 dark:hover:text-brand-300 text-xs font-medium transition-colors",
8396
9037
  children: forgotLabel
8397
9038
  }
8398
9039
  )
@@ -8735,7 +9376,7 @@ var TwoStepVerificationForm = ({
8735
9376
  type: "button",
8736
9377
  onClick: onResend,
8737
9378
  disabled: loading,
8738
- className: "text-brand-500 hover:text-brand-600 font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50",
9379
+ 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",
8739
9380
  children: resendLabel
8740
9381
  }
8741
9382
  )
@@ -8779,7 +9420,7 @@ var ColorSwatch = ({
8779
9420
  "span",
8780
9421
  {
8781
9422
  className: clsx(
8782
- "text-[10px] leading-none font-medium",
9423
+ "text-3xs leading-none font-medium",
8783
9424
  active ? "text-gray-700 dark:text-gray-200" : "text-gray-400 dark:text-gray-500"
8784
9425
  ),
8785
9426
  children: label
@@ -8851,7 +9492,7 @@ var PaletteCard = ({ meta, active = false, onClick, className }) => /* @__PURE__
8851
9492
  /* @__PURE__ */ jsxs(
8852
9493
  "div",
8853
9494
  {
8854
- className: "flex items-center justify-between px-2.5 py-1.5",
9495
+ className: "flex flex-1 items-center justify-between px-2.5 py-1.5",
8855
9496
  style: {
8856
9497
  backgroundColor: meta.preview.surface,
8857
9498
  borderTop: `1px solid ${meta.preview.border}`
@@ -8862,11 +9503,11 @@ var PaletteCard = ({ meta, active = false, onClick, className }) => /* @__PURE__
8862
9503
  "span",
8863
9504
  {
8864
9505
  className: "block text-xs font-semibold",
8865
- style: { color: active ? void 0 : "#6b7280" },
9506
+ style: { color: meta.preview.text ?? (active ? void 0 : "#6b7280") },
8866
9507
  children: meta.label
8867
9508
  }
8868
9509
  ),
8869
- meta.desc && /* @__PURE__ */ jsx("span", { className: "block text-[10px]", style: { color: "#9ca3af" }, children: meta.desc })
9510
+ meta.desc && /* @__PURE__ */ jsx("span", { className: "text-3xs block", style: { color: meta.preview.text ?? "#9ca3af" }, children: meta.desc })
8870
9511
  ] }),
8871
9512
  active && /* @__PURE__ */ jsx("span", { className: "bg-brand-500 flex h-4 w-4 shrink-0 items-center justify-center rounded-full", children: /* @__PURE__ */ jsx(Check, { className: "h-2.5 w-2.5 text-white", "aria-hidden": true }) })
8872
9513
  ]
@@ -8916,12 +9557,12 @@ var OptionCard = ({
8916
9557
  {
8917
9558
  className: clsx(
8918
9559
  "text-xs font-semibold",
8919
- active ? "text-brand-500" : "text-gray-700 dark:text-gray-300"
9560
+ active ? "text-brand-600 dark:text-brand-400" : "text-gray-700 dark:text-gray-300"
8920
9561
  ),
8921
9562
  children: label
8922
9563
  }
8923
9564
  ),
8924
- desc && /* @__PURE__ */ jsx("p", { className: "text-[10px] text-gray-400 dark:text-gray-500", children: desc })
9565
+ desc && /* @__PURE__ */ jsx("p", { className: "text-3xs text-gray-400 dark:text-gray-500", children: desc })
8925
9566
  ] }),
8926
9567
  active && /* @__PURE__ */ 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__ */ jsx(Check, { className: "h-2.5 w-2.5 text-white", "aria-hidden": true }) })
8927
9568
  ]
@@ -8952,7 +9593,220 @@ var OptionPicker = ({
8952
9593
  ))
8953
9594
  }
8954
9595
  );
8955
- var SIZE = {
9596
+
9597
+ // src/settings/appearance.ts
9598
+ var COSMOS_THEMES = [
9599
+ {
9600
+ id: "light",
9601
+ label: "Light",
9602
+ dark: false,
9603
+ preview: { bg: "#f9fafb", surface: "#ffffff", border: "#e5e7eb", text: "#667085" }
9604
+ },
9605
+ {
9606
+ id: "sand",
9607
+ label: "Sand",
9608
+ dark: false,
9609
+ preview: { bg: "#f9f5eb", surface: "#fffcf7", border: "#e7dfd0", text: "#746656" }
9610
+ },
9611
+ {
9612
+ id: "dark",
9613
+ label: "Dark",
9614
+ dark: true,
9615
+ preview: { bg: "#0a0a0a", surface: "#141414", border: "#3d3d3d", text: "#a3a3a3" }
9616
+ },
9617
+ {
9618
+ id: "deep-blue",
9619
+ label: "Deep Blue",
9620
+ dark: true,
9621
+ preview: { bg: "#0c111d", surface: "#101828", border: "#344054", text: "#98a2b3" }
9622
+ }
9623
+ ];
9624
+ var COSMOS_ACCENTS = [
9625
+ { id: "blue", label: "Blue", hex: "#465fff" },
9626
+ { id: "indigo", label: "Indigo", hex: "#5963e9" },
9627
+ { id: "violet", label: "Violet", hex: "#8745f1" },
9628
+ { id: "purple", label: "Purple", hex: "#ad2ecf" },
9629
+ { id: "rose", label: "Rose", hex: "#d4166d" },
9630
+ { id: "teal", label: "Teal", hex: "#038378" },
9631
+ { id: "cyan", label: "Cyan", hex: "#017f9d" },
9632
+ { id: "graphite", label: "Graphite", hex: "#707580" },
9633
+ { id: "red", label: "Red", hex: "#db192a" },
9634
+ { id: "orange", label: "Orange", hex: "#c04f01" },
9635
+ { id: "amber", label: "Amber", hex: "#a46800" },
9636
+ { id: "green", label: "Green", hex: "#02863c" }
9637
+ ];
9638
+ var COSMOS_FONTS = [
9639
+ { id: "outfit", label: "Outfit", family: "'Outfit', system-ui, sans-serif" },
9640
+ { id: "inter", label: "Inter", family: "'Inter Variable', system-ui, sans-serif" },
9641
+ { id: "plex", label: "IBM Plex Sans", family: "'IBM Plex Sans Variable', system-ui, sans-serif" },
9642
+ { id: "montserrat", label: "Montserrat", family: "'Montserrat Variable', system-ui, sans-serif" },
9643
+ { id: "open-sans", label: "Open Sans", family: "'Open Sans Variable', system-ui, sans-serif" },
9644
+ {
9645
+ id: "system",
9646
+ label: "System",
9647
+ family: "system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif"
9648
+ }
9649
+ ];
9650
+ var COSMOS_TEXT_SIZES = [
9651
+ { id: "sm", label: "Small", scale: 0.9375 },
9652
+ { id: "md", label: "Default", scale: 1 },
9653
+ { id: "lg", label: "Large", scale: 1.125 },
9654
+ { id: "xl", label: "Extra large", scale: 1.25 }
9655
+ ];
9656
+ var THEME_CLASSES = COSMOS_THEMES.map((t) => t.id).filter((id) => id !== "light");
9657
+ var isDarkTheme = (theme) => COSMOS_THEMES.some((t) => t.id === theme && t.dark);
9658
+ var applyAppearance = ({ theme, accent, font, textSize }, root) => {
9659
+ const el = root ?? (typeof document === "undefined" ? void 0 : document.documentElement);
9660
+ if (!el) return;
9661
+ el.classList.remove(...THEME_CLASSES);
9662
+ if (theme !== "light") el.classList.add(theme);
9663
+ if (accent === "blue") delete el.dataset.accent;
9664
+ else el.dataset.accent = accent;
9665
+ if (font === "outfit") delete el.dataset.font;
9666
+ else if (font) el.dataset.font = font;
9667
+ if (textSize === "md") delete el.dataset.textSize;
9668
+ else if (textSize) el.dataset.textSize = textSize;
9669
+ };
9670
+ var AppearanceSettings = ({
9671
+ theme,
9672
+ accent,
9673
+ onThemeChange,
9674
+ onAccentChange,
9675
+ themeLabel = "Theme",
9676
+ accentLabel = "Accent color",
9677
+ themes = COSMOS_THEMES,
9678
+ accents = COSMOS_ACCENTS,
9679
+ themeColumns = 4,
9680
+ font = "outfit",
9681
+ onFontChange,
9682
+ textSize = "md",
9683
+ onTextSizeChange,
9684
+ fontLabel = "Font",
9685
+ textSizeLabel = "Text size",
9686
+ fonts = COSMOS_FONTS,
9687
+ textSizes = COSMOS_TEXT_SIZES,
9688
+ className
9689
+ }) => {
9690
+ const themeHeadingId = useId();
9691
+ const accentHeadingId = useId();
9692
+ const fontHeadingId = useId();
9693
+ const textSizeHeadingId = useId();
9694
+ return /* @__PURE__ */ jsxs("div", { className: clsx("space-y-6", className), children: [
9695
+ /* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": themeHeadingId, children: [
9696
+ /* @__PURE__ */ jsx("p", { id: themeHeadingId, className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: themeLabel }),
9697
+ /* @__PURE__ */ jsx(
9698
+ PalettePicker,
9699
+ {
9700
+ className: "mt-3",
9701
+ palettes: themes,
9702
+ value: theme,
9703
+ cols: themeColumns,
9704
+ onChange: (id) => onThemeChange(id)
9705
+ }
9706
+ )
9707
+ ] }),
9708
+ /* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": accentHeadingId, children: [
9709
+ /* @__PURE__ */ jsx("p", { id: accentHeadingId, className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: accentLabel }),
9710
+ /* @__PURE__ */ jsx(
9711
+ AccentPicker,
9712
+ {
9713
+ className: "mt-3",
9714
+ colors: accents,
9715
+ value: accent,
9716
+ onChange: (id) => onAccentChange(id),
9717
+ cols: 6
9718
+ }
9719
+ )
9720
+ ] }),
9721
+ onFontChange && /* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": fontHeadingId, children: [
9722
+ /* @__PURE__ */ jsx("p", { id: fontHeadingId, className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: fontLabel }),
9723
+ /* @__PURE__ */ jsx(
9724
+ OptionPicker,
9725
+ {
9726
+ className: "mt-3",
9727
+ cols: 3,
9728
+ value: font,
9729
+ onChange: (id) => onFontChange(id),
9730
+ options: fonts.map((f) => ({
9731
+ id: f.id,
9732
+ label: f.label,
9733
+ preview: /* @__PURE__ */ jsx(
9734
+ "span",
9735
+ {
9736
+ "aria-hidden": true,
9737
+ style: { fontFamily: f.family },
9738
+ className: "text-xl text-gray-900 dark:text-gray-100",
9739
+ children: "Aa"
9740
+ }
9741
+ )
9742
+ }))
9743
+ }
9744
+ )
9745
+ ] }),
9746
+ onTextSizeChange && /* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": textSizeHeadingId, children: [
9747
+ /* @__PURE__ */ jsx(
9748
+ "p",
9749
+ {
9750
+ id: textSizeHeadingId,
9751
+ className: "text-sm font-medium text-gray-700 dark:text-gray-300",
9752
+ children: textSizeLabel
9753
+ }
9754
+ ),
9755
+ /* @__PURE__ */ jsx(
9756
+ OptionPicker,
9757
+ {
9758
+ className: "mt-3",
9759
+ cols: 4,
9760
+ value: textSize,
9761
+ onChange: (id) => onTextSizeChange(id),
9762
+ options: textSizes.map((t) => ({
9763
+ id: t.id,
9764
+ label: t.label,
9765
+ // Pixel sizes, so the previews don't scale with the setting.
9766
+ preview: /* @__PURE__ */ jsx(
9767
+ "span",
9768
+ {
9769
+ "aria-hidden": true,
9770
+ style: { fontSize: `${16 * t.scale}px` },
9771
+ className: "text-gray-900 dark:text-gray-100",
9772
+ children: "Aa"
9773
+ }
9774
+ )
9775
+ }))
9776
+ }
9777
+ )
9778
+ ] })
9779
+ ] });
9780
+ };
9781
+ var SIZE_CLASS12 = {
9782
+ sm: { box: "h-8 w-8", icon: "h-4 w-4" },
9783
+ md: { box: "h-10 w-10", icon: "h-5 w-5" }
9784
+ };
9785
+ var AppearanceMenu = ({
9786
+ label = "Appearance",
9787
+ size = "md",
9788
+ className,
9789
+ ...settings
9790
+ }) => {
9791
+ const { box, icon } = SIZE_CLASS12[size];
9792
+ return /* @__PURE__ */ jsxs(Popover, { children: [
9793
+ /* @__PURE__ */ jsx(
9794
+ Popover.Trigger,
9795
+ {
9796
+ title: label,
9797
+ "aria-label": label,
9798
+ className: clsx(
9799
+ "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",
9800
+ box,
9801
+ className
9802
+ ),
9803
+ children: /* @__PURE__ */ jsx(Palette, { className: icon, "aria-hidden": true })
9804
+ }
9805
+ ),
9806
+ /* @__PURE__ */ jsx(Popover.Content, { align: "end", width: "w-96", "aria-label": label, children: /* @__PURE__ */ jsx("div", { className: "-m-4 max-h-[calc(100dvh-6rem)] overflow-y-auto p-4", children: /* @__PURE__ */ jsx(AppearanceSettings, { themeColumns: 2, ...settings }) }) })
9807
+ ] });
9808
+ };
9809
+ var SIZE2 = {
8956
9810
  sm: "text-base leading-relaxed",
8957
9811
  md: "text-lg leading-relaxed",
8958
9812
  lg: "text-2xl leading-snug"
@@ -8972,7 +9826,7 @@ var Blockquote = ({
8972
9826
  authorAvatar,
8973
9827
  className
8974
9828
  }) => {
8975
- const text = /* @__PURE__ */ jsx("p", { className: clsx("font-medium text-gray-700 italic dark:text-gray-200", SIZE[size]), children });
9829
+ const text = /* @__PURE__ */ jsx("p", { className: clsx("font-medium text-gray-700 italic dark:text-gray-200", SIZE2[size]), children });
8976
9830
  if (variant === "icon") {
8977
9831
  return /* @__PURE__ */ jsxs("blockquote", { className: clsx(ALIGN[align], className), children: [
8978
9832
  /* @__PURE__ */ jsx(
@@ -9054,21 +9908,6 @@ var Blockquote = ({
9054
9908
  }
9055
9909
  );
9056
9910
  };
9057
- var SIZE2 = {
9058
- sm: "h-5 min-w-[20px] px-1.5 text-[10px]",
9059
- md: "h-6 min-w-[24px] px-2 text-xs"
9060
- };
9061
- var Kbd2 = ({ children, size = "md", className }) => /* @__PURE__ */ jsx(
9062
- "kbd",
9063
- {
9064
- className: clsx(
9065
- "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)]",
9066
- SIZE2[size],
9067
- className
9068
- ),
9069
- children
9070
- }
9071
- );
9072
9911
  var SIZE3 = {
9073
9912
  xs: "max-w-xs",
9074
9913
  sm: "max-w-sm",
@@ -9119,6 +9958,6 @@ var Figure = ({
9119
9958
  caption && /* @__PURE__ */ jsx("figcaption", { className: "mt-2 text-center text-xs text-gray-500 italic dark:text-gray-400", children: caption })
9120
9959
  ] });
9121
9960
 
9122
- export { AccentPicker, Accordion2 as Accordion, ActionPanel, ActiveFiltersBar, ActivityFeed, AlertBanner, AnnouncementBar, AuthLayout, Avatar, AvatarUploader, BackToTopFab, Backdrop, Badge, Blockquote, Breadcrumb, Button, ButtonGroup, Calendar, Card2 as Card, Carousel, CarouselRoot, Checkbox, CheckboxGroup, ClickableRow, Clipboard, CodeBlock, ColBox, ColorSwatch, ColumnFilterDropdown, ColumnHeader, Combobox, CommandPalette, ConfirmationModal, ContentNarrow, ContentStackedList, CookieBanner, DataTable, DatePicker, DescriptionList, Divider, Drawer, Dropdown, Dropzone, EmptyState, ErrorPage, ErrorState, Figure, FileInput, FilterPills, FormFooter, FormRow, GridList, HealthBadge, HealthDot, HelpOverlay, IconBox, ImageGrid, Input, IntegrationCard, Kbd2 as Kbd, KpiCard, Link, List2 as List, LoadingState, MediaObject, MiniCalendar, Modal, NarrowStackedList, Navbar, NotificationCard, NotificationsPanel, NumberInput, OptionCard, OptionPicker, OtpInput, PageActionButton, PageActionIconButton, PageBreadcrumb, PageCard, PageHeader, Pagination, PaletteCard, PalettePicker, PasswordInput, PasswordPolicyChecker, Popover, ProgressBar, REFRESH_OPTIONS, Radio, RadioGroup, RefreshButton, ResetPasswordForm, Ribbon, RowActionButton, STATUS_COLOR, STATUS_PILL, SearchInput, SectionCard, SectionLabel, SegmentedControl, Select, SelectInput, Shell, Sidebar, SignInForm, SignUpForm, SimpleRow, Sk, SkeletonList, SkeletonTable, SkeletonText, SocialAuthButtons, Spinner, StackedList, StackedListInCard, StatefulSaveButton, StatusBadge, StatusRow, Stepper, StepperInput, StepperRoot, StickyScrollNav, Tabs, Textarea, ThemeToggle, ThemeToggleTri, TimePicker, Timeline, Toaster, Toggle, Tooltip, TooltipHelp, Topbar, TwoStepVerificationForm, UnsavedIndicator, UserMenu, VerticalNavigation, VideoEmbed, ZoomBar, defaultPasswordRules, useAutoRefresh };
9961
+ export { AccentPicker, Accordion2 as Accordion, ActionPanel, ActiveFiltersBar, ActivityFeed, AlertBanner, AnnouncementBar, AppearanceMenu, AppearanceSettings, AuthLayout, Avatar, AvatarUploader, BackToTopFab, Backdrop, Badge, Blockquote, Breadcrumb, Button, ButtonGroup, COSMOS_ACCENTS, COSMOS_FONTS, COSMOS_TEXT_SIZES, COSMOS_THEMES, Calendar, Card2 as Card, Carousel, CarouselRoot, Checkbox, CheckboxGroup, ClickableRow, Clipboard, CodeBlock, ColBox, ColorSwatch, ColumnFilterDropdown, ColumnHeader, Combobox, CommandPalette, ConfirmationModal, ContentNarrow, ContentStackedList, CookieBanner, DataTable, DatePicker, DescriptionList, Divider, Drawer, Dropdown, Dropzone, EmptyState, ErrorPage, ErrorState, EventCalendar, Figure, FileInput, FilterPills, FormFooter, FormRow, GridList, HealthBadge, HealthDot, HelpOverlay, IconBox, ImageGrid, Input, IntegrationCard, Kbd, KpiCard, Link, List2 as List, LoadingState, MediaObject, MiniCalendar, Modal, NarrowStackedList, Navbar, NotificationCard, NotificationsPanel, NumberInput, OptionCard, OptionPicker, OtpInput, PageActionButton, PageActionIconButton, PageBreadcrumb, PageHeader, Pagination, PaletteCard, PalettePicker, PasswordInput, PasswordPolicyChecker, Popover, ProgressBar, REFRESH_OPTIONS, Radio, RadioGroup, RefreshButton, ResetPasswordForm, Ribbon, RowActionButton, STATUS_COLOR, STATUS_PILL, SearchInput, SectionCard, SectionLabel, SegmentedControl, Select, SelectInput, Shell, Sidebar, SignInForm, SignUpForm, SimpleRow, Sk, SkeletonList, SkeletonTable, SkeletonText, SocialAuthButtons, Spinner, StackedList, StackedListInCard, StatefulSaveButton, StatusBadge, StatusRow, Stepper, StepperInput, StepperRoot, StickyScrollNav, Tabs, Textarea, ThemeToggle, ThemeToggleTri, TimePicker, Timeline, Toaster, Toggle, Tooltip, TooltipHelp, Topbar, TwoStepVerificationForm, UnsavedIndicator, UserMenu, VerticalNavigation, VideoEmbed, ZoomBar, applyAppearance, defaultPasswordRules, isDarkTheme, useAutoRefresh };
9123
9962
  //# sourceMappingURL=index.js.map
9124
9963
  //# sourceMappingURL=index.js.map