@sckyzo/cosmos-react 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -37,93 +37,6 @@ var Autoplay__default = /*#__PURE__*/_interopDefault(Autoplay);
37
37
  var useEmblaCarousel__default = /*#__PURE__*/_interopDefault(useEmblaCarousel);
38
38
  var RadixAccordion__namespace = /*#__PURE__*/_interopNamespace(RadixAccordion);
39
39
 
40
- // src/storybook-avatars.ts
41
- var PALETTE = [
42
- ["#6366f1", "#ffffff"],
43
- // indigo
44
- ["#8b5cf6", "#ffffff"],
45
- // violet
46
- ["#0ea5e9", "#ffffff"],
47
- // sky
48
- ["#10b981", "#ffffff"],
49
- // emerald
50
- ["#f59e0b", "#1f2937"],
51
- // amber (dark text on warm bg)
52
- ["#f43f5e", "#ffffff"],
53
- // rose
54
- ["#14b8a6", "#ffffff"],
55
- // teal
56
- ["#ec4899", "#ffffff"],
57
- // pink
58
- ["#64748b", "#ffffff"],
59
- // slate
60
- ["#a855f7", "#ffffff"]
61
- // purple
62
- ];
63
- var hashSeed = (seed) => {
64
- let h = 5381;
65
- for (let i = 0; i < seed.length; i += 1) {
66
- h = (h << 5) + h + seed.charCodeAt(i) | 0;
67
- }
68
- return Math.abs(h);
69
- };
70
- var extractInitials = (seed) => {
71
- const cleaned = seed.replace(/[^\p{L}\p{N}\s'.-]/gu, " ").trim();
72
- if (!cleaned) return "?";
73
- const parts = cleaned.split(/[\s.'-]+/).filter(Boolean);
74
- if (parts.length >= 2) {
75
- return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
76
- }
77
- return cleaned.slice(0, 2).toUpperCase();
78
- };
79
- var buildSvg = (initials, bg, fg, size) => {
80
- const fontSize = initials.length === 1 ? 56 : 42;
81
- return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 100 100"><rect width="100" height="100" fill="${bg}"/><text x="50" y="50" font-family="ui-sans-serif,system-ui,sans-serif" font-size="${fontSize}" font-weight="600" fill="${fg}" text-anchor="middle" dominant-baseline="central">${initials}</text></svg>`;
82
- };
83
- var placeholderAvatar = (seed, size = 64, opts = {}) => {
84
- const initials = extractInitials(seed);
85
- const [defaultBg, defaultFg] = PALETTE[hashSeed(seed) % PALETTE.length];
86
- const bg = opts.bg ?? defaultBg;
87
- const fg = opts.fg ?? defaultFg;
88
- const svg = buildSvg(initials, bg, fg, size);
89
- return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;
90
- };
91
- var buildCoverSvg = (seed, from, to, width, height) => {
92
- const h = hashSeed(seed);
93
- const angle = h % 180;
94
- const cx1 = h % 60 + 20;
95
- const cy1 = (h >> 3) % 60 + 20;
96
- const r1 = (h >> 5) % 35 + 25;
97
- const cx2 = (h >> 7) % 60 + 20;
98
- const cy2 = (h >> 9) % 60 + 20;
99
- const r2 = (h >> 11) % 25 + 15;
100
- const gradientId = `g-${(h % 1e5).toString(36)}`;
101
- return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 100 100" preserveAspectRatio="none"><defs><linearGradient id="${gradientId}" gradientTransform="rotate(${angle})"><stop offset="0" stop-color="${from}"/><stop offset="1" stop-color="${to}"/></linearGradient></defs><rect width="100" height="100" fill="url(#${gradientId})"/><circle cx="${cx1}" cy="${cy1}" r="${r1}" fill="rgba(255,255,255,0.08)"/><circle cx="${cx2}" cy="${cy2}" r="${r2}" fill="rgba(0,0,0,0.10)"/></svg>`;
102
- };
103
- var placeholderCover = (seed, width = 1600, height = 700, opts = {}) => {
104
- const h = hashSeed(seed);
105
- const [from] = PALETTE[h % PALETTE.length];
106
- const [to] = PALETTE[(h + 3) % PALETTE.length];
107
- const svg = buildCoverSvg(seed, opts.from ?? from, opts.to ?? to, width, height);
108
- return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;
109
- };
110
-
111
- // src/storybook-helpers.ts
112
- var buildParams = (height) => ({
113
- layout: "fullscreen",
114
- docs: {
115
- story: {
116
- inline: false,
117
- iframeHeight: `${height}px`
118
- }
119
- }
120
- });
121
- var fn = ((height = 480) => buildParams(height));
122
- fn.sm = () => buildParams(320);
123
- fn.md = () => buildParams(480);
124
- fn.lg = () => buildParams(640);
125
- fn.full = () => buildParams(800);
126
- var portalDocsParams = fn;
127
40
  var Root = ({
128
41
  inset,
129
42
  align = "center",
@@ -432,11 +345,11 @@ var SidebarItem = ({
432
345
  const baseClass = clsx.clsx(
433
346
  "group mx-2 flex items-center gap-3 rounded-lg py-2 text-sm font-medium transition-colors",
434
347
  collapsed ? "justify-center px-2" : "px-3",
435
- 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"
348
+ 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"
436
349
  );
437
350
  const style = !collapsed && depth > 0 ? { paddingLeft: 12 + depth * 20 } : void 0;
438
351
  const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
439
- /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: clsx.clsx("h-5 w-5 shrink-0", active && "text-brand-500") }),
352
+ /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-5 w-5 shrink-0" }),
440
353
  !collapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
441
354
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: label }),
442
355
  badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: badge })
@@ -487,9 +400,9 @@ var SidebarSubMenu = ({
487
400
  title: label,
488
401
  className: clsx.clsx(
489
402
  "group mx-2 flex w-[calc(100%-1rem)] items-center justify-center rounded-lg px-2 py-2 text-sm font-medium transition-colors",
490
- 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"
403
+ 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"
491
404
  ),
492
- children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: clsx.clsx("h-5 w-5 shrink-0", active && "text-brand-500") })
405
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-5 w-5 shrink-0" })
493
406
  }
494
407
  );
495
408
  }
@@ -502,10 +415,10 @@ var SidebarSubMenu = ({
502
415
  "aria-expanded": open,
503
416
  className: clsx.clsx(
504
417
  "group mx-2 flex w-[calc(100%-1rem)] items-center gap-3 rounded-lg px-3 py-2 text-left text-sm font-medium transition-colors",
505
- 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"
418
+ 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"
506
419
  ),
507
420
  children: [
508
- /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: clsx.clsx("h-5 w-5 shrink-0", active && "text-brand-500") }),
421
+ /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-5 w-5 shrink-0" }),
509
422
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: label }),
510
423
  badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: badge }),
511
424
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -566,7 +479,7 @@ Sidebar.SubMenu = SidebarSubMenu;
566
479
  var PageBreadcrumb = ({ items, className }) => /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Breadcrumb", className, children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex flex-wrap items-center gap-1 text-sm", children: items.map((item, i) => {
567
480
  const isFirst = i === 0;
568
481
  const isLast = i === items.length - 1;
569
- const linkClass = "hover:text-brand-500 dark:hover:text-brand-400 flex items-center gap-1 text-[var(--color-text-secondary)] transition-colors";
482
+ const linkClass = "hover:text-brand-600 dark:hover:text-brand-400 flex items-center gap-1 text-[var(--color-text-secondary)] transition-colors";
570
483
  const renderInner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
571
484
  isFirst && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Home, { className: "h-4 w-4" }),
572
485
  item.label
@@ -710,7 +623,7 @@ var ErrorState = ({
710
623
  {
711
624
  type: "button",
712
625
  onClick: onRetry,
713
- className: "text-brand-500 hover:text-brand-600 text-xs font-medium hover:underline",
626
+ className: "text-brand-600 hover:text-brand-700 dark:text-brand-400 dark:hover:text-brand-300 text-xs font-medium hover:underline",
714
627
  children: "Try again"
715
628
  }
716
629
  )
@@ -2093,6 +2006,8 @@ var Dropdown = ({
2093
2006
  }) => {
2094
2007
  const [open, setOpen] = react.useState(false);
2095
2008
  const ref = react.useRef(null);
2009
+ const triggerRef = react.useRef(null);
2010
+ const menuRef = react.useRef(null);
2096
2011
  react.useEffect(() => {
2097
2012
  if (!open) return;
2098
2013
  const handler = (e) => {
@@ -2101,15 +2016,47 @@ var Dropdown = ({
2101
2016
  document.addEventListener("mousedown", handler);
2102
2017
  return () => document.removeEventListener("mousedown", handler);
2103
2018
  }, [open]);
2019
+ react.useEffect(() => {
2020
+ if (!open) return;
2021
+ const first = menuRef.current?.querySelector('[role="menuitem"]:not(:disabled)');
2022
+ first?.focus();
2023
+ }, [open]);
2024
+ const closeAndRefocus = () => {
2025
+ setOpen(false);
2026
+ triggerRef.current?.focus();
2027
+ };
2028
+ const onMenuKeyDown = (e) => {
2029
+ if (e.key === "Escape") {
2030
+ e.preventDefault();
2031
+ closeAndRefocus();
2032
+ return;
2033
+ }
2034
+ const items = Array.from(
2035
+ menuRef.current?.querySelectorAll('[role="menuitem"]:not(:disabled)') ?? []
2036
+ );
2037
+ if (items.length === 0) return;
2038
+ const currentIndex = items.indexOf(document.activeElement);
2039
+ const focusAt = (i) => {
2040
+ e.preventDefault();
2041
+ items[(i + items.length) % items.length]?.focus();
2042
+ };
2043
+ if (e.key === "ArrowDown") focusAt(currentIndex + 1);
2044
+ else if (e.key === "ArrowUp") focusAt(currentIndex - 1);
2045
+ else if (e.key === "Home") focusAt(0);
2046
+ else if (e.key === "End") focusAt(items.length - 1);
2047
+ };
2104
2048
  const selected = options.find((o) => !isDivider(o) && o.value === value);
2105
2049
  const displayLabel = selected?.label ?? placeholder ?? label ?? "Select\u2026";
2106
2050
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: clsx.clsx("relative inline-block", className), children: [
2107
2051
  /* @__PURE__ */ jsxRuntime.jsxs(
2108
2052
  "button",
2109
2053
  {
2054
+ ref: triggerRef,
2110
2055
  type: "button",
2111
2056
  onClick: () => !disabled && setOpen((v) => !v),
2112
2057
  disabled,
2058
+ "aria-haspopup": "menu",
2059
+ "aria-expanded": open,
2113
2060
  className: clsx.clsx(
2114
2061
  "flex h-9 items-center gap-2 rounded-lg border border-gray-200 bg-white px-3 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700",
2115
2062
  open && "ring-brand-500/30 ring-2"
@@ -2134,6 +2081,10 @@ var Dropdown = ({
2134
2081
  /* @__PURE__ */ jsxRuntime.jsx(
2135
2082
  "div",
2136
2083
  {
2084
+ ref: menuRef,
2085
+ role: "menu",
2086
+ "aria-label": label,
2087
+ onKeyDown: onMenuKeyDown,
2137
2088
  className: clsx.clsx(
2138
2089
  "absolute top-full z-50 mt-1 min-w-[180px] overflow-hidden rounded-xl border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-800",
2139
2090
  align === "right" ? "right-0" : "left-0"
@@ -2155,10 +2106,11 @@ var Dropdown = ({
2155
2106
  "button",
2156
2107
  {
2157
2108
  type: "button",
2109
+ role: "menuitem",
2158
2110
  disabled: opt.disabled,
2159
2111
  onClick: () => {
2160
2112
  onChange?.(opt.value);
2161
- setOpen(false);
2113
+ closeAndRefocus();
2162
2114
  },
2163
2115
  className: clsx.clsx(
2164
2116
  "flex w-full items-center gap-2 px-4 py-2 text-left text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-50",
@@ -2178,6 +2130,51 @@ var Dropdown = ({
2178
2130
  ] })
2179
2131
  ] });
2180
2132
  };
2133
+ var FOCUSABLE_SELECTOR = [
2134
+ "a[href]",
2135
+ "button:not([disabled])",
2136
+ "textarea:not([disabled])",
2137
+ "input:not([disabled])",
2138
+ "select:not([disabled])",
2139
+ '[tabindex]:not([tabindex="-1"])'
2140
+ ].join(",");
2141
+ function useFocusTrap(active) {
2142
+ const ref = react.useRef(null);
2143
+ react.useEffect(() => {
2144
+ if (!active) return;
2145
+ const node = ref.current;
2146
+ if (!node) return;
2147
+ const previouslyFocused = document.activeElement;
2148
+ const focusables = () => Array.from(node.querySelectorAll(FOCUSABLE_SELECTOR));
2149
+ (focusables()[0] ?? node).focus();
2150
+ const onKeyDown = (e) => {
2151
+ if (e.key !== "Tab") return;
2152
+ const items = focusables();
2153
+ if (items.length === 0) {
2154
+ e.preventDefault();
2155
+ return;
2156
+ }
2157
+ const first = items[0];
2158
+ const last = items[items.length - 1];
2159
+ if (e.shiftKey && document.activeElement === first) {
2160
+ e.preventDefault();
2161
+ last.focus();
2162
+ } else if (!e.shiftKey && document.activeElement === last) {
2163
+ e.preventDefault();
2164
+ first.focus();
2165
+ }
2166
+ };
2167
+ node.addEventListener("keydown", onKeyDown);
2168
+ return () => {
2169
+ node.removeEventListener("keydown", onKeyDown);
2170
+ previouslyFocused?.focus?.();
2171
+ };
2172
+ }, [active]);
2173
+ return ref;
2174
+ }
2175
+ var DialogTitleContext = react.createContext(void 0);
2176
+ var DialogTitleProvider = DialogTitleContext.Provider;
2177
+ var useDialogTitleId = () => react.useContext(DialogTitleContext);
2181
2178
  var SIZE_CLASS5 = {
2182
2179
  sm: "max-w-sm",
2183
2180
  md: "max-w-md",
@@ -2185,7 +2182,9 @@ var SIZE_CLASS5 = {
2185
2182
  xl: "max-w-2xl",
2186
2183
  full: "h-full w-full max-w-none rounded-none"
2187
2184
  };
2188
- var Root8 = ({ open, onClose, size = "md", className, children }) => {
2185
+ var Root8 = ({ open, onClose, size = "md", className, ariaLabel, children }) => {
2186
+ const titleId = react.useId();
2187
+ const trapRef = useFocusTrap(open);
2189
2188
  react.useEffect(() => {
2190
2189
  if (!open) return;
2191
2190
  const handler = (e) => {
@@ -2200,12 +2199,16 @@ var Root8 = ({ open, onClose, size = "md", className, children }) => {
2200
2199
  /* @__PURE__ */ jsxRuntime.jsxs(
2201
2200
  "div",
2202
2201
  {
2202
+ ref: trapRef,
2203
+ tabIndex: -1,
2203
2204
  className: clsx.clsx(
2204
2205
  "fixed inset-0 z-50 flex",
2205
2206
  isFull ? "items-stretch justify-stretch" : "items-center justify-center p-4"
2206
2207
  ),
2207
2208
  role: "dialog",
2208
2209
  "aria-modal": "true",
2210
+ "aria-label": ariaLabel,
2211
+ "aria-labelledby": ariaLabel ? void 0 : titleId,
2209
2212
  children: [
2210
2213
  /* @__PURE__ */ jsxRuntime.jsx(
2211
2214
  "div",
@@ -2224,7 +2227,7 @@ var Root8 = ({ open, onClose, size = "md", className, children }) => {
2224
2227
  SIZE_CLASS5[size],
2225
2228
  className
2226
2229
  ),
2227
- children
2230
+ children: /* @__PURE__ */ jsxRuntime.jsx(DialogTitleProvider, { value: titleId, children })
2228
2231
  }
2229
2232
  )
2230
2233
  ]
@@ -2233,32 +2236,35 @@ var Root8 = ({ open, onClose, size = "md", className, children }) => {
2233
2236
  document.body
2234
2237
  );
2235
2238
  };
2236
- var Header2 = ({ title, description, onClose, className, children }) => /* @__PURE__ */ jsxRuntime.jsxs(
2237
- "div",
2238
- {
2239
- className: clsx.clsx(
2240
- "flex items-start justify-between gap-4 border-b border-gray-200 px-5 py-4 dark:border-gray-800",
2241
- className
2242
- ),
2243
- children: [
2244
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
2245
- title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: title }),
2246
- description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: description }),
2247
- children
2248
- ] }),
2249
- onClose && /* @__PURE__ */ jsxRuntime.jsx(
2250
- "button",
2251
- {
2252
- type: "button",
2253
- onClick: onClose,
2254
- "aria-label": "Close modal",
2255
- className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-600 dark:hover:bg-white/5 dark:hover:text-gray-300",
2256
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
2257
- }
2258
- )
2259
- ]
2260
- }
2261
- );
2239
+ var Header2 = ({ title, description, onClose, className, children }) => {
2240
+ const titleId = useDialogTitleId();
2241
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2242
+ "div",
2243
+ {
2244
+ className: clsx.clsx(
2245
+ "flex items-start justify-between gap-4 border-b border-gray-200 px-5 py-4 dark:border-gray-800",
2246
+ className
2247
+ ),
2248
+ children: [
2249
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
2250
+ title && /* @__PURE__ */ jsxRuntime.jsx("h2", { id: titleId, className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: title }),
2251
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: description }),
2252
+ children
2253
+ ] }),
2254
+ onClose && /* @__PURE__ */ jsxRuntime.jsx(
2255
+ "button",
2256
+ {
2257
+ type: "button",
2258
+ onClick: onClose,
2259
+ "aria-label": "Close modal",
2260
+ className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-600 dark:hover:bg-white/5 dark:hover:text-gray-300",
2261
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
2262
+ }
2263
+ )
2264
+ ]
2265
+ }
2266
+ );
2267
+ };
2262
2268
  var Body3 = ({ children, className }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("px-5 py-4", className), children });
2263
2269
  var Footer3 = ({ children, className }) => /* @__PURE__ */ jsxRuntime.jsx(
2264
2270
  "div",
@@ -2307,7 +2313,7 @@ var Alert = ({
2307
2313
  const handleConfirm = () => onConfirm ? onConfirm() : onClose();
2308
2314
  const handleCancel = () => onCancel ? onCancel() : onClose();
2309
2315
  if (layout === "horizontal") {
2310
- return /* @__PURE__ */ jsxRuntime.jsxs(Root8, { open, onClose, size: "lg", children: [
2316
+ return /* @__PURE__ */ jsxRuntime.jsxs(Root8, { open, onClose, size: "lg", ariaLabel: title, children: [
2311
2317
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white sm:flex sm:items-start sm:p-6 dark:bg-gray-900", children: [
2312
2318
  /* @__PURE__ */ jsxRuntime.jsx(
2313
2319
  "div",
@@ -2339,7 +2345,7 @@ var Alert = ({
2339
2345
  ] })
2340
2346
  ] });
2341
2347
  }
2342
- return /* @__PURE__ */ jsxRuntime.jsx(Root8, { open, onClose, size: "sm", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 text-center", children: [
2348
+ return /* @__PURE__ */ jsxRuntime.jsx(Root8, { open, onClose, size: "sm", ariaLabel: title, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 text-center", children: [
2343
2349
  /* @__PURE__ */ jsxRuntime.jsx(
2344
2350
  "div",
2345
2351
  {
@@ -2417,9 +2423,12 @@ var Root9 = ({
2417
2423
  size = "md",
2418
2424
  withBackdrop = true,
2419
2425
  closeOutside = false,
2426
+ ariaLabel,
2420
2427
  className,
2421
2428
  children
2422
2429
  }) => {
2430
+ const titleId = react.useId();
2431
+ const trapRef = useFocusTrap(open);
2423
2432
  react.useEffect(() => {
2424
2433
  if (!open) return;
2425
2434
  const handler = (e) => {
@@ -2459,6 +2468,8 @@ var Root9 = ({
2459
2468
  /* @__PURE__ */ jsxRuntime.jsx(
2460
2469
  "aside",
2461
2470
  {
2471
+ ref: trapRef,
2472
+ tabIndex: -1,
2462
2473
  className: clsx.clsx(
2463
2474
  "fixed top-0 bottom-0 z-50 flex flex-col border-gray-200 bg-white shadow-2xl transition-transform duration-300 ease-in-out dark:border-gray-800 dark:bg-gray-900",
2464
2475
  SIDE_CLASS[side],
@@ -2468,7 +2479,9 @@ var Root9 = ({
2468
2479
  ),
2469
2480
  role: "dialog",
2470
2481
  "aria-modal": "true",
2471
- children
2482
+ "aria-label": ariaLabel,
2483
+ "aria-labelledby": ariaLabel ? void 0 : titleId,
2484
+ children: /* @__PURE__ */ jsxRuntime.jsx(DialogTitleProvider, { value: titleId, children })
2472
2485
  }
2473
2486
  )
2474
2487
  ] }),
@@ -2482,37 +2495,47 @@ var Header3 = ({
2482
2495
  onClose,
2483
2496
  className,
2484
2497
  children
2485
- }) => /* @__PURE__ */ jsxRuntime.jsxs(
2486
- "div",
2487
- {
2488
- className: clsx.clsx(
2489
- "flex shrink-0 items-center justify-between border-b border-gray-200 p-5 dark:border-gray-800",
2490
- className
2491
- ),
2492
- children: [
2493
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [
2494
- Icon2 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-100 dark:bg-gray-800", children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-4 w-4 text-gray-500 dark:text-gray-400" }) }),
2495
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
2496
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "truncate text-base font-semibold text-gray-900 dark:text-white", children: title }),
2497
- description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 truncate text-sm text-gray-500 dark:text-gray-400", children: description })
2498
+ }) => {
2499
+ const titleId = useDialogTitleId();
2500
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2501
+ "div",
2502
+ {
2503
+ className: clsx.clsx(
2504
+ "flex shrink-0 items-center justify-between border-b border-gray-200 p-5 dark:border-gray-800",
2505
+ className
2506
+ ),
2507
+ children: [
2508
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [
2509
+ Icon2 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-100 dark:bg-gray-800", children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "h-4 w-4 text-gray-500 dark:text-gray-400" }) }),
2510
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
2511
+ /* @__PURE__ */ jsxRuntime.jsx(
2512
+ "h3",
2513
+ {
2514
+ id: titleId,
2515
+ className: "truncate text-base font-semibold text-gray-900 dark:text-white",
2516
+ children: title
2517
+ }
2518
+ ),
2519
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 truncate text-sm text-gray-500 dark:text-gray-400", children: description })
2520
+ ] })
2521
+ ] }),
2522
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2523
+ children,
2524
+ onClose && /* @__PURE__ */ jsxRuntime.jsx(
2525
+ "button",
2526
+ {
2527
+ type: "button",
2528
+ onClick: onClose,
2529
+ "aria-label": "Close drawer",
2530
+ className: "text-gray-400 transition-colors hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300",
2531
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-5 w-5" })
2532
+ }
2533
+ )
2498
2534
  ] })
2499
- ] }),
2500
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2501
- children,
2502
- onClose && /* @__PURE__ */ jsxRuntime.jsx(
2503
- "button",
2504
- {
2505
- type: "button",
2506
- onClick: onClose,
2507
- "aria-label": "Close drawer",
2508
- className: "text-gray-400 transition-colors hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300",
2509
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-5 w-5" })
2510
- }
2511
- )
2512
- ] })
2513
- ]
2514
- }
2515
- );
2535
+ ]
2536
+ }
2537
+ );
2538
+ };
2516
2539
  var Body4 = ({ children, className }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx("flex-1 overflow-y-auto p-5", className), children });
2517
2540
  var Footer4 = ({ children, className }) => /* @__PURE__ */ jsxRuntime.jsx(
2518
2541
  "div",
@@ -3097,6 +3120,8 @@ var ConfirmationModal = ({
3097
3120
  saveLabel = "Save & go",
3098
3121
  hideSave = false
3099
3122
  }) => {
3123
+ const titleId = react.useId();
3124
+ const trapRef = useFocusTrap(open);
3100
3125
  react.useEffect(() => {
3101
3126
  if (!open) return;
3102
3127
  const handler = (e) => {
@@ -3110,24 +3135,19 @@ var ConfirmationModal = ({
3110
3135
  /* @__PURE__ */ jsxRuntime.jsxs(
3111
3136
  "div",
3112
3137
  {
3138
+ ref: trapRef,
3139
+ tabIndex: -1,
3113
3140
  className: "fixed inset-0 z-50 flex items-center justify-center p-4",
3114
3141
  role: "dialog",
3115
3142
  "aria-modal": "true",
3116
- "aria-labelledby": "cosmos-confirmation-title",
3143
+ "aria-labelledby": titleId,
3117
3144
  children: [
3118
3145
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", onClick: onStay, "aria-hidden": true }),
3119
3146
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full max-w-md overflow-hidden rounded-2xl border border-gray-200 bg-white shadow-2xl dark:border-gray-700 dark:bg-gray-900", children: [
3120
3147
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-4 p-6", children: [
3121
3148
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-amber-50 dark:bg-amber-500/10", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-5 w-5 text-amber-500" }) }),
3122
3149
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
3123
- /* @__PURE__ */ jsxRuntime.jsx(
3124
- "h3",
3125
- {
3126
- id: "cosmos-confirmation-title",
3127
- className: "font-semibold text-gray-900 dark:text-white",
3128
- children: title
3129
- }
3130
- ),
3150
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { id: titleId, className: "font-semibold text-gray-900 dark:text-white", children: title }),
3131
3151
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: message })
3132
3152
  ] }),
3133
3153
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -3484,7 +3504,7 @@ var NotificationsPanelFooter = ({
3484
3504
  if (closeOnClick && !e.defaultPrevented) setOpen(false);
3485
3505
  },
3486
3506
  className: clsx.clsx(
3487
- "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",
3507
+ "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",
3488
3508
  className
3489
3509
  ),
3490
3510
  ...rest,
@@ -3817,7 +3837,7 @@ var SIZE_CLASS9 = {
3817
3837
  sm: { box: "h-8 w-8", icon: "h-4 w-4" },
3818
3838
  md: { box: "h-10 w-10", icon: "h-5 w-5" }
3819
3839
  };
3820
- var TRI_ORDER = ["light", "dark", "oled"];
3840
+ var TRI_ORDER = ["light", "dark", "deep-blue"];
3821
3841
  var nextInCycle = (current) => {
3822
3842
  const idx = TRI_ORDER.indexOf(current);
3823
3843
  return TRI_ORDER[(idx + 1) % TRI_ORDER.length];
@@ -3825,7 +3845,7 @@ var nextInCycle = (current) => {
3825
3845
  var ICON_FOR = {
3826
3846
  light: lucideReact.Sun,
3827
3847
  dark: lucideReact.Moon,
3828
- oled: lucideReact.MoonStar
3848
+ "deep-blue": lucideReact.MoonStar
3829
3849
  };
3830
3850
  var ThemeToggleTri = react.forwardRef(
3831
3851
  function ThemeToggleTri2({
@@ -3834,12 +3854,12 @@ var ThemeToggleTri = react.forwardRef(
3834
3854
  size = "md",
3835
3855
  lightLabel = "Switch to light mode",
3836
3856
  darkLabel = "Switch to dark mode",
3837
- oledLabel = "Switch to OLED mode",
3857
+ deepBlueLabel = "Switch to deep blue mode",
3838
3858
  className,
3839
3859
  ...rest
3840
3860
  }, ref) {
3841
3861
  const next = nextInCycle(theme);
3842
- const label = next === "light" ? lightLabel : next === "dark" ? darkLabel : oledLabel;
3862
+ const label = next === "light" ? lightLabel : next === "dark" ? darkLabel : deepBlueLabel;
3843
3863
  const Icon2 = ICON_FOR[theme];
3844
3864
  const { box, icon } = SIZE_CLASS9[size];
3845
3865
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -4091,9 +4111,12 @@ var PopoverRoot = ({
4091
4111
  const handler = () => refreshRect();
4092
4112
  window.addEventListener("resize", handler);
4093
4113
  window.addEventListener("scroll", handler, true);
4114
+ const observer = new ResizeObserver(handler);
4115
+ if (triggerRef.current) observer.observe(triggerRef.current, { box: "border-box" });
4094
4116
  return () => {
4095
4117
  window.removeEventListener("resize", handler);
4096
4118
  window.removeEventListener("scroll", handler, true);
4119
+ observer.disconnect();
4097
4120
  };
4098
4121
  }, [open, refreshRect]);
4099
4122
  react.useEffect(() => {
@@ -4132,13 +4155,18 @@ var PopoverTrigger = react.forwardRef(function PopoverTrigger2({ onClick, childr
4132
4155
  }
4133
4156
  );
4134
4157
  });
4135
- var positionStyle = (position, rect, offset) => {
4158
+ var VIEWPORT_MARGIN = 16;
4159
+ var positionStyle = (position, align, rect, offset) => {
4160
+ const left = align === "end" ? rect.right : rect.left + rect.width / 2;
4161
+ const shiftX = align === "end" ? "-100%" : "-50%";
4162
+ const maxWidth = align === "end" ? rect.right - VIEWPORT_MARGIN : void 0;
4136
4163
  switch (position) {
4137
4164
  case "top":
4138
4165
  return {
4139
4166
  top: rect.top - offset,
4140
- left: rect.left + rect.width / 2,
4141
- transform: "translate(-50%, -100%)"
4167
+ left,
4168
+ maxWidth,
4169
+ transform: `translate(${shiftX}, -100%)`
4142
4170
  };
4143
4171
  case "right":
4144
4172
  return {
@@ -4156,32 +4184,36 @@ var positionStyle = (position, rect, offset) => {
4156
4184
  default:
4157
4185
  return {
4158
4186
  top: rect.bottom + offset,
4159
- left: rect.left + rect.width / 2,
4160
- transform: "translateX(-50%)"
4187
+ left,
4188
+ maxWidth,
4189
+ transform: `translateX(${shiftX})`
4161
4190
  };
4162
4191
  }
4163
4192
  };
4164
- var arrowStyle = (position) => {
4193
+ var arrowStyle = (position, align, rect) => {
4165
4194
  const base = {
4166
4195
  position: "absolute",
4167
4196
  width: 8,
4168
4197
  height: 8,
4169
4198
  transform: "rotate(45deg)"
4170
4199
  };
4200
+ const x = align === "end" ? { right: rect.width / 2 - 1, marginRight: -4 } : { left: "50%", marginLeft: -4 };
4171
4201
  switch (position) {
4172
4202
  case "top":
4173
- return { ...base, bottom: -4, left: "50%", marginLeft: -4 };
4203
+ return { ...base, bottom: -4, ...x };
4174
4204
  case "right":
4175
4205
  return { ...base, left: -4, top: "50%", marginTop: -4 };
4176
4206
  case "left":
4177
4207
  return { ...base, right: -4, top: "50%", marginTop: -4 };
4178
4208
  case "bottom":
4179
4209
  default:
4180
- return { ...base, top: -4, left: "50%", marginLeft: -4 };
4210
+ return { ...base, top: -4, ...x };
4181
4211
  }
4182
4212
  };
4183
4213
  var PopoverContent = ({
4184
4214
  position = "bottom",
4215
+ align = "center",
4216
+ "aria-label": ariaLabel,
4185
4217
  offset = 8,
4186
4218
  arrow = false,
4187
4219
  width = "w-64",
@@ -4197,7 +4229,8 @@ var PopoverContent = ({
4197
4229
  "div",
4198
4230
  {
4199
4231
  role: "dialog",
4200
- style: positionStyle(position, triggerRect, offset),
4232
+ "aria-label": ariaLabel,
4233
+ style: positionStyle(position, align, triggerRect, offset),
4201
4234
  className: clsx.clsx(
4202
4235
  "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",
4203
4236
  width,
@@ -4208,7 +4241,7 @@ var PopoverContent = ({
4208
4241
  "span",
4209
4242
  {
4210
4243
  "aria-hidden": true,
4211
- style: arrowStyle(position),
4244
+ style: arrowStyle(position, align, triggerRect),
4212
4245
  className: "border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900"
4213
4246
  }
4214
4247
  ),
@@ -7629,7 +7662,7 @@ var ColumnHeader = ({
7629
7662
  "aria-label": "Filter column",
7630
7663
  className: clsx.clsx(
7631
7664
  "flex items-center gap-1 rounded p-0.5 transition-colors hover:bg-gray-200 dark:hover:bg-white/10",
7632
- filterCount > 0 && "text-brand-500"
7665
+ filterCount > 0 && "text-brand-600 dark:text-brand-400"
7633
7666
  ),
7634
7667
  children: [
7635
7668
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "h-3 w-3" }),
@@ -8136,6 +8169,34 @@ var DataTable = ({
8136
8169
  }
8137
8170
  );
8138
8171
  };
8172
+ var AuthLayout = ({
8173
+ logo: Logo,
8174
+ title,
8175
+ subtitle,
8176
+ brand,
8177
+ children,
8178
+ className
8179
+ }) => {
8180
+ const showBuiltInBrand = brand === void 0 && (Logo || title || subtitle);
8181
+ const renderBrand = brand !== void 0 ? brand : showBuiltInBrand ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8 flex flex-col items-center gap-2 text-center", children: [
8182
+ Logo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-brand-500 flex h-12 w-12 items-center justify-center rounded-xl text-white", children: /* @__PURE__ */ jsxRuntime.jsx(Logo, { className: "h-6 w-6" }) }),
8183
+ title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-bold text-gray-900 dark:text-white", children: title }),
8184
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: subtitle })
8185
+ ] }) : null;
8186
+ return /* @__PURE__ */ jsxRuntime.jsx(
8187
+ "div",
8188
+ {
8189
+ className: clsx.clsx(
8190
+ "flex min-h-screen items-center justify-center bg-gray-50 p-4 dark:bg-gray-950",
8191
+ className
8192
+ ),
8193
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full max-w-md", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-2xl border border-gray-200 bg-white p-8 shadow-sm dark:border-gray-800 dark:bg-gray-900", children: [
8194
+ renderBrand,
8195
+ children
8196
+ ] }) })
8197
+ }
8198
+ );
8199
+ };
8139
8200
  var ErrorPage = ({
8140
8201
  code,
8141
8202
  title,
@@ -8159,6 +8220,462 @@ var ErrorPage = ({
8159
8220
  ]
8160
8221
  }
8161
8222
  );
8223
+ var STATUS_LABEL2 = {
8224
+ connected: "Connected",
8225
+ available: "Available",
8226
+ error: "Error",
8227
+ pending: "Pending"
8228
+ };
8229
+ var STATUS_VARIANT = {
8230
+ connected: "success",
8231
+ available: "neutral",
8232
+ error: "danger",
8233
+ pending: "warning"
8234
+ };
8235
+ var IntegrationCard = ({
8236
+ logo,
8237
+ name,
8238
+ description,
8239
+ status,
8240
+ category,
8241
+ actionLabel,
8242
+ actionVariant = "primary",
8243
+ onAction,
8244
+ secondaryLabel,
8245
+ onSecondary,
8246
+ loading = false,
8247
+ className
8248
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(
8249
+ "div",
8250
+ {
8251
+ className: clsx.clsx(
8252
+ "flex h-full flex-col rounded-2xl border border-gray-200 bg-white p-5 transition-shadow hover:shadow-md dark:border-gray-700 dark:bg-gray-800",
8253
+ className
8254
+ ),
8255
+ children: [
8256
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
8257
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center overflow-hidden rounded-xl border border-gray-100 bg-white dark:border-gray-700 dark:bg-gray-900 [&_img]:h-full [&_img]:w-full [&_img]:object-contain [&_svg]:h-7 [&_svg]:w-7", children: logo }),
8258
+ status && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: STATUS_VARIANT[status], appearance: "light", children: STATUS_LABEL2[status] })
8259
+ ] }),
8260
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 min-w-0 flex-1", children: [
8261
+ category && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-[10px] tracking-wide text-gray-400 uppercase dark:text-gray-500", children: category }),
8262
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mt-0.5 truncate text-sm font-semibold text-gray-900 dark:text-white", children: name }),
8263
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 line-clamp-2 text-xs text-gray-600 dark:text-gray-400", children: description })
8264
+ ] }),
8265
+ (actionLabel || secondaryLabel) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex items-center justify-end gap-2", children: [
8266
+ secondaryLabel && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", onClick: onSecondary, disabled: loading, children: secondaryLabel }),
8267
+ actionLabel && /* @__PURE__ */ jsxRuntime.jsx(
8268
+ Button,
8269
+ {
8270
+ variant: actionVariant,
8271
+ size: "sm",
8272
+ onClick: onAction,
8273
+ loading,
8274
+ disabled: loading,
8275
+ children: actionLabel
8276
+ }
8277
+ )
8278
+ ] })
8279
+ ]
8280
+ }
8281
+ );
8282
+ var ResetPasswordForm = ({
8283
+ onSubmit,
8284
+ signInHref,
8285
+ signInLabel = "Back to sign in",
8286
+ sent = false,
8287
+ sentEmail,
8288
+ loading = false,
8289
+ error,
8290
+ title = "Reset your password",
8291
+ description = "Enter your email and we\u2019ll send you a link to reset your password.",
8292
+ submitLabel = "Send reset link",
8293
+ onResend,
8294
+ resendLabel = "Resend",
8295
+ className
8296
+ }) => {
8297
+ const [email, setEmail] = react.useState("");
8298
+ const handleSubmit = (e) => {
8299
+ e.preventDefault();
8300
+ if (loading || email.length === 0) return;
8301
+ void onSubmit(email);
8302
+ };
8303
+ if (sent) {
8304
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
8305
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-brand-500/10 text-brand-600 dark:text-brand-400 mx-auto flex h-12 w-12 items-center justify-center rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MailCheck, { className: "h-6 w-6", "aria-hidden": true }) }),
8306
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-4 text-center text-xl font-semibold text-gray-900 dark:text-white", children: "Check your inbox" }),
8307
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-2 text-center text-sm text-gray-500 dark:text-gray-400", children: [
8308
+ "We've sent a reset link to",
8309
+ " ",
8310
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-700 dark:text-gray-200", children: sentEmail ?? email }),
8311
+ ". The link expires in 1 hour."
8312
+ ] }),
8313
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 flex flex-col items-stretch gap-2", children: [
8314
+ onResend && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", loading, disabled: loading, onClick: onResend, children: resendLabel }),
8315
+ signInHref && /* @__PURE__ */ jsxRuntime.jsxs(Link, { href: signInHref, variant: "subtle", className: "justify-center", children: [
8316
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "h-3.5 w-3.5", "aria-hidden": true }),
8317
+ signInLabel
8318
+ ] })
8319
+ ] })
8320
+ ] });
8321
+ }
8322
+ return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className, children: [
8323
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
8324
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-gray-900 dark:text-white", children: title }),
8325
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: description })
8326
+ ] }),
8327
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(AlertBanner, { variant: "error", children: error }) }),
8328
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
8329
+ /* @__PURE__ */ jsxRuntime.jsx(
8330
+ Input,
8331
+ {
8332
+ label: "Email",
8333
+ type: "email",
8334
+ icon: lucideReact.Mail,
8335
+ autoComplete: "email",
8336
+ required: true,
8337
+ placeholder: "john@example.com",
8338
+ value: email,
8339
+ onChange: (e) => setEmail(e.target.value),
8340
+ disabled: loading
8341
+ }
8342
+ ),
8343
+ /* @__PURE__ */ jsxRuntime.jsx(
8344
+ Button,
8345
+ {
8346
+ type: "submit",
8347
+ loading,
8348
+ disabled: loading || email.length === 0,
8349
+ className: "w-full",
8350
+ children: submitLabel
8351
+ }
8352
+ )
8353
+ ] }),
8354
+ signInHref && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-5 text-center text-xs text-[var(--color-text-muted)]", children: /* @__PURE__ */ jsxRuntime.jsxs(Link, { href: signInHref, variant: "colored", children: [
8355
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "h-3.5 w-3.5", "aria-hidden": true }),
8356
+ signInLabel
8357
+ ] }) })
8358
+ ] });
8359
+ };
8360
+ var SignInForm = ({
8361
+ onSubmit,
8362
+ onForgotPassword,
8363
+ signUpHref,
8364
+ signUpLabel = "Create one",
8365
+ title = "Sign in",
8366
+ description = "Welcome back \u2014 enter your credentials below.",
8367
+ emailLabel = "Email",
8368
+ passwordLabel = "Password",
8369
+ rememberLabel = "Keep me signed in",
8370
+ submitLabel = "Sign in",
8371
+ forgotLabel = "Forgot password?",
8372
+ loading = false,
8373
+ error,
8374
+ extraTop,
8375
+ className
8376
+ }) => {
8377
+ const [email, setEmail] = react.useState("");
8378
+ const [password, setPassword] = react.useState("");
8379
+ const [remember, setRemember] = react.useState(false);
8380
+ const handleSubmit = (e) => {
8381
+ e.preventDefault();
8382
+ if (loading) return;
8383
+ void onSubmit({ email, password, remember });
8384
+ };
8385
+ return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className, children: [
8386
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
8387
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-gray-900 dark:text-white", children: title }),
8388
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: description })
8389
+ ] }),
8390
+ extraTop && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-5", children: extraTop }),
8391
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(AlertBanner, { variant: "error", children: error }) }),
8392
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
8393
+ /* @__PURE__ */ jsxRuntime.jsx(
8394
+ Input,
8395
+ {
8396
+ label: emailLabel,
8397
+ type: "email",
8398
+ icon: lucideReact.Mail,
8399
+ autoComplete: "email",
8400
+ required: true,
8401
+ placeholder: "john@example.com",
8402
+ value: email,
8403
+ onChange: (e) => setEmail(e.target.value),
8404
+ disabled: loading
8405
+ }
8406
+ ),
8407
+ /* @__PURE__ */ jsxRuntime.jsx(
8408
+ PasswordInput,
8409
+ {
8410
+ label: passwordLabel,
8411
+ autoComplete: "current-password",
8412
+ required: true,
8413
+ value: password,
8414
+ onChange: (e) => setPassword(e.target.value),
8415
+ disabled: loading
8416
+ }
8417
+ ),
8418
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8419
+ /* @__PURE__ */ jsxRuntime.jsx(
8420
+ Checkbox,
8421
+ {
8422
+ label: rememberLabel,
8423
+ checked: remember,
8424
+ onChange: (c) => setRemember(c),
8425
+ disabled: loading
8426
+ }
8427
+ ),
8428
+ onForgotPassword && /* @__PURE__ */ jsxRuntime.jsx(
8429
+ "button",
8430
+ {
8431
+ type: "button",
8432
+ onClick: onForgotPassword,
8433
+ className: "text-brand-600 hover:text-brand-700 dark:text-brand-400 dark:hover:text-brand-300 text-xs font-medium transition-colors",
8434
+ children: forgotLabel
8435
+ }
8436
+ )
8437
+ ] }),
8438
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", loading, disabled: loading, className: "w-full", children: submitLabel })
8439
+ ] }),
8440
+ signUpHref && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-5 text-center text-xs text-[var(--color-text-muted)]", children: [
8441
+ "No account?",
8442
+ " ",
8443
+ /* @__PURE__ */ jsxRuntime.jsx(Link, { href: signUpHref, variant: "colored", children: signUpLabel })
8444
+ ] })
8445
+ ] });
8446
+ };
8447
+ var SignUpForm = ({
8448
+ onSubmit,
8449
+ signInHref,
8450
+ signInLabel = "Sign in",
8451
+ termsHref = "#",
8452
+ privacyHref = "#",
8453
+ showPolicy = true,
8454
+ loading = false,
8455
+ error,
8456
+ title = "Create your account",
8457
+ description = "A few details to get you started.",
8458
+ submitLabel = "Create account",
8459
+ extraTop,
8460
+ className
8461
+ }) => {
8462
+ const [firstName, setFirstName] = react.useState("");
8463
+ const [lastName, setLastName] = react.useState("");
8464
+ const [email, setEmail] = react.useState("");
8465
+ const [password, setPassword] = react.useState("");
8466
+ const [agreedToTerms, setAgreedToTerms] = react.useState(false);
8467
+ const rules = react.useMemo(() => defaultPasswordRules(password), [password]);
8468
+ const allRulesPass = rules.every((r) => r.ok);
8469
+ const canSubmit = firstName.length > 0 && lastName.length > 0 && email.length > 0 && (showPolicy ? allRulesPass : password.length > 0) && agreedToTerms && !loading;
8470
+ const handleSubmit = (e) => {
8471
+ e.preventDefault();
8472
+ if (!canSubmit) return;
8473
+ void onSubmit({ firstName, lastName, email, password, agreedToTerms });
8474
+ };
8475
+ return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className, children: [
8476
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
8477
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-gray-900 dark:text-white", children: title }),
8478
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: description })
8479
+ ] }),
8480
+ extraTop && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-5", children: extraTop }),
8481
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(AlertBanner, { variant: "error", children: error }) }),
8482
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
8483
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
8484
+ /* @__PURE__ */ jsxRuntime.jsx(
8485
+ Input,
8486
+ {
8487
+ label: "First name",
8488
+ icon: lucideReact.User,
8489
+ autoComplete: "given-name",
8490
+ required: true,
8491
+ placeholder: "John",
8492
+ value: firstName,
8493
+ onChange: (e) => setFirstName(e.target.value),
8494
+ disabled: loading
8495
+ }
8496
+ ),
8497
+ /* @__PURE__ */ jsxRuntime.jsx(
8498
+ Input,
8499
+ {
8500
+ label: "Last name",
8501
+ autoComplete: "family-name",
8502
+ required: true,
8503
+ placeholder: "Doe",
8504
+ value: lastName,
8505
+ onChange: (e) => setLastName(e.target.value),
8506
+ disabled: loading
8507
+ }
8508
+ )
8509
+ ] }),
8510
+ /* @__PURE__ */ jsxRuntime.jsx(
8511
+ Input,
8512
+ {
8513
+ label: "Email",
8514
+ type: "email",
8515
+ icon: lucideReact.Mail,
8516
+ autoComplete: "email",
8517
+ required: true,
8518
+ placeholder: "john@example.com",
8519
+ value: email,
8520
+ onChange: (e) => setEmail(e.target.value),
8521
+ disabled: loading
8522
+ }
8523
+ ),
8524
+ /* @__PURE__ */ jsxRuntime.jsx(
8525
+ PasswordInput,
8526
+ {
8527
+ label: "Password",
8528
+ autoComplete: "new-password",
8529
+ required: true,
8530
+ value: password,
8531
+ onChange: (e) => setPassword(e.target.value),
8532
+ disabled: loading
8533
+ }
8534
+ ),
8535
+ showPolicy && password.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(PasswordPolicyChecker, { rules }),
8536
+ /* @__PURE__ */ jsxRuntime.jsx(
8537
+ Checkbox,
8538
+ {
8539
+ label: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
8540
+ "I agree to the",
8541
+ " ",
8542
+ /* @__PURE__ */ jsxRuntime.jsx(Link, { href: termsHref, variant: "underline", className: "text-current", children: "terms" }),
8543
+ " ",
8544
+ "and",
8545
+ " ",
8546
+ /* @__PURE__ */ jsxRuntime.jsx(Link, { href: privacyHref, variant: "underline", className: "text-current", children: "privacy policy" }),
8547
+ "."
8548
+ ] }),
8549
+ checked: agreedToTerms,
8550
+ onChange: (c) => setAgreedToTerms(c),
8551
+ disabled: loading
8552
+ }
8553
+ ),
8554
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", loading, disabled: !canSubmit, className: "w-full", children: submitLabel })
8555
+ ] }),
8556
+ signInHref && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-5 text-center text-xs text-[var(--color-text-muted)]", children: [
8557
+ "Already have an account?",
8558
+ " ",
8559
+ /* @__PURE__ */ jsxRuntime.jsx(Link, { href: signInHref, variant: "colored", children: signInLabel })
8560
+ ] })
8561
+ ] });
8562
+ };
8563
+ var PROVIDER_NAME = {
8564
+ google: "Google",
8565
+ github: "GitHub",
8566
+ x: "X",
8567
+ facebook: "Facebook",
8568
+ apple: "Apple",
8569
+ microsoft: "Microsoft"
8570
+ };
8571
+ var GoogleIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", "aria-hidden": true, children: [
8572
+ /* @__PURE__ */ jsxRuntime.jsx(
8573
+ "path",
8574
+ {
8575
+ fill: "#4285F4",
8576
+ d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
8577
+ }
8578
+ ),
8579
+ /* @__PURE__ */ jsxRuntime.jsx(
8580
+ "path",
8581
+ {
8582
+ fill: "#34A853",
8583
+ d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84A10.99 10.99 0 0 0 12 23z"
8584
+ }
8585
+ ),
8586
+ /* @__PURE__ */ jsxRuntime.jsx(
8587
+ "path",
8588
+ {
8589
+ fill: "#FBBC05",
8590
+ d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18a10.99 10.99 0 0 0 0 9.86l3.66-2.84z"
8591
+ }
8592
+ ),
8593
+ /* @__PURE__ */ jsxRuntime.jsx(
8594
+ "path",
8595
+ {
8596
+ fill: "#EA4335",
8597
+ d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1a10.99 10.99 0 0 0-9.82 6.07l3.66 2.84C6.71 7.31 9.14 5.38 12 5.38z"
8598
+ }
8599
+ )
8600
+ ] });
8601
+ var GithubIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", className: "h-4 w-4 fill-current", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
8602
+ "path",
8603
+ {
8604
+ fillRule: "evenodd",
8605
+ clipRule: "evenodd",
8606
+ d: "M12 2C6.48 2 2 6.58 2 12.26c0 4.49 2.87 8.3 6.84 9.65.5.09.68-.22.68-.49 0-.24-.01-.88-.01-1.73-2.78.62-3.37-1.36-3.37-1.36-.46-1.18-1.11-1.5-1.11-1.5-.91-.63.07-.62.07-.62 1 .07 1.53 1.05 1.53 1.05.89 1.56 2.34 1.11 2.91.85.09-.66.35-1.11.63-1.36-2.22-.26-4.55-1.13-4.55-5.04 0-1.11.39-2.02 1.03-2.74-.1-.26-.45-1.3.1-2.71 0 0 .84-.27 2.75 1.05A9.4 9.4 0 0 1 12 6.99c.85 0 1.71.12 2.51.34 1.91-1.32 2.75-1.05 2.75-1.05.55 1.41.2 2.45.1 2.71.64.72 1.03 1.63 1.03 2.74 0 3.92-2.34 4.78-4.57 5.03.36.32.68.94.68 1.9 0 1.37-.01 2.48-.01 2.81 0 .27.18.59.69.49A10.04 10.04 0 0 0 22 12.26C22 6.58 17.52 2 12 2z"
8607
+ }
8608
+ ) });
8609
+ var XIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", className: "h-4 w-4 fill-current", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231 5.45-6.231Zm-1.161 17.52h1.833L7.084 4.126H5.117l11.966 15.644Z" }) });
8610
+ var FacebookIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
8611
+ "path",
8612
+ {
8613
+ fill: "#1877F2",
8614
+ d: "M24 12.07C24 5.41 18.63 0 12 0S0 5.41 0 12.07c0 6.02 4.39 11.01 10.13 11.93v-8.44H7.08v-3.49h3.05V9.41c0-3.02 1.79-4.69 4.53-4.69 1.31 0 2.69.23 2.69.23v2.97h-1.51c-1.49 0-1.96.93-1.96 1.89v2.26h3.33l-.53 3.49h-2.8V24C19.61 23.08 24 18.09 24 12.07Z"
8615
+ }
8616
+ ) });
8617
+ var AppleIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", className: "h-4 w-4 fill-current", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M17.05 12.04c-.03-2.97 2.43-4.4 2.54-4.47-1.39-2.03-3.55-2.31-4.32-2.34-1.83-.19-3.59 1.08-4.52 1.08-.95 0-2.38-1.06-3.92-1.03-2.01.03-3.88 1.18-4.92 2.97-2.1 3.65-.54 9.05 1.51 12.01 1 1.45 2.18 3.07 3.74 3.01 1.51-.06 2.07-.97 3.89-.97 1.81 0 2.32.97 3.92.94 1.62-.03 2.65-1.46 3.62-2.92 1.15-1.67 1.62-3.32 1.65-3.4-.04-.01-3.16-1.21-3.19-4.81zM14.06 3.74c.81-1 1.36-2.39 1.21-3.78-1.17.05-2.6.79-3.44 1.78-.74.87-1.4 2.28-1.23 3.64 1.31.1 2.65-.66 3.46-1.65z" }) });
8618
+ var MicrosoftIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", "aria-hidden": true, children: [
8619
+ /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#F25022", d: "M11.4 11.4H1V1h10.4v10.4Z" }),
8620
+ /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#7FBA00", d: "M23 11.4H12.6V1H23v10.4Z" }),
8621
+ /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#00A4EF", d: "M11.4 23H1V12.6h10.4V23Z" }),
8622
+ /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#FFB900", d: "M23 23H12.6V12.6H23V23Z" })
8623
+ ] });
8624
+ var PROVIDER_ICON = {
8625
+ google: GoogleIcon,
8626
+ github: GithubIcon,
8627
+ x: XIcon,
8628
+ facebook: FacebookIcon,
8629
+ apple: AppleIcon,
8630
+ microsoft: MicrosoftIcon
8631
+ };
8632
+ var SocialAuthButtons = ({
8633
+ providers,
8634
+ onProviderClick,
8635
+ loading,
8636
+ divider = true,
8637
+ dividerLabel = "OR continue with",
8638
+ layout = "stacked",
8639
+ labelFor,
8640
+ position = "above",
8641
+ className
8642
+ }) => {
8643
+ if (providers.length === 0) return null;
8644
+ const buttonsList = /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx(layout === "grid" ? "grid grid-cols-2 gap-2" : "flex flex-col gap-2"), children: providers.map((provider) => {
8645
+ const Icon2 = PROVIDER_ICON[provider];
8646
+ const isLoading = loading === provider;
8647
+ const isDisabled = loading !== void 0 && loading !== null;
8648
+ const label = labelFor ? labelFor(provider) : `Continue with ${PROVIDER_NAME[provider]}`;
8649
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8650
+ "button",
8651
+ {
8652
+ type: "button",
8653
+ onClick: () => onProviderClick(provider),
8654
+ disabled: isDisabled,
8655
+ "aria-label": label,
8656
+ className: "flex h-10 items-center justify-center gap-2 rounded-lg border border-gray-200 bg-white text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700",
8657
+ children: [
8658
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(Icon2, {}),
8659
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: label })
8660
+ ]
8661
+ },
8662
+ provider
8663
+ );
8664
+ }) });
8665
+ if (!divider) return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: buttonsList });
8666
+ const dividerNode = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-4 flex items-center gap-3", children: [
8667
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" }),
8668
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs tracking-wide text-gray-400 uppercase dark:text-gray-500", children: dividerLabel }),
8669
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" })
8670
+ ] });
8671
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: position === "above" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8672
+ buttonsList,
8673
+ dividerNode
8674
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8675
+ dividerNode,
8676
+ buttonsList
8677
+ ] }) });
8678
+ };
8162
8679
  var StickyScrollNav = ({
8163
8680
  sections,
8164
8681
  onNavigate,
@@ -8194,6 +8711,80 @@ var StickyScrollNav = ({
8194
8711
  }
8195
8712
  );
8196
8713
  };
8714
+ var TwoStepVerificationForm = ({
8715
+ onSubmit,
8716
+ onResend,
8717
+ sentTo,
8718
+ length = 6,
8719
+ loading = false,
8720
+ error,
8721
+ autoSubmit = true,
8722
+ cancelHref,
8723
+ cancelLabel = "Back to sign in",
8724
+ title = "Two-step verification",
8725
+ submitLabel = "Verify my account",
8726
+ resendLabel = "Resend code",
8727
+ className
8728
+ }) => {
8729
+ const [code, setCode] = react.useState("");
8730
+ const description = sentTo ? `Enter the ${length}-digit code we sent to ${sentTo}.` : `Enter the ${length}-digit verification code from your authenticator app.`;
8731
+ const handleSubmit = (e) => {
8732
+ e.preventDefault();
8733
+ if (loading || code.length !== length) return;
8734
+ void onSubmit(code);
8735
+ };
8736
+ const handleComplete = (value) => {
8737
+ if (autoSubmit && !loading) void onSubmit(value);
8738
+ };
8739
+ return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className, children: [
8740
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-brand-500/10 text-brand-600 dark:text-brand-400 mx-auto flex h-12 w-12 items-center justify-center rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShieldCheck, { className: "h-6 w-6", "aria-hidden": true }) }),
8741
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-4 text-center text-xl font-semibold text-gray-900 dark:text-white", children: title }),
8742
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-center text-sm text-gray-500 dark:text-gray-400", children: description }),
8743
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: /* @__PURE__ */ jsxRuntime.jsx(AlertBanner, { variant: "error", children: error }) }),
8744
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-6 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
8745
+ OtpInput,
8746
+ {
8747
+ length,
8748
+ value: code,
8749
+ onChange: setCode,
8750
+ onComplete: handleComplete,
8751
+ disabled: loading,
8752
+ error: !!error,
8753
+ autoFocus: true
8754
+ }
8755
+ ) }),
8756
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 space-y-2", children: [
8757
+ /* @__PURE__ */ jsxRuntime.jsx(
8758
+ Button,
8759
+ {
8760
+ type: "submit",
8761
+ loading,
8762
+ disabled: loading || code.length !== length,
8763
+ className: "w-full",
8764
+ children: submitLabel
8765
+ }
8766
+ ),
8767
+ onResend && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-center text-xs text-[var(--color-text-muted)]", children: [
8768
+ "Didn't get a code?",
8769
+ " ",
8770
+ /* @__PURE__ */ jsxRuntime.jsx(
8771
+ "button",
8772
+ {
8773
+ type: "button",
8774
+ onClick: onResend,
8775
+ disabled: loading,
8776
+ 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",
8777
+ children: resendLabel
8778
+ }
8779
+ )
8780
+ ] }),
8781
+ cancelHref && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(Link, { href: cancelHref, variant: "subtle", children: [
8782
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "h-3.5 w-3.5", "aria-hidden": true }),
8783
+ cancelLabel
8784
+ ] }) })
8785
+ ] })
8786
+ ] });
8787
+ };
8197
8788
  var ColorSwatch = ({
8198
8789
  hex,
8199
8790
  label,
@@ -8298,7 +8889,7 @@ var PaletteCard = ({ meta, active = false, onClick, className }) => /* @__PURE__
8298
8889
  /* @__PURE__ */ jsxRuntime.jsxs(
8299
8890
  "div",
8300
8891
  {
8301
- className: "flex items-center justify-between px-2.5 py-1.5",
8892
+ className: "flex flex-1 items-center justify-between px-2.5 py-1.5",
8302
8893
  style: {
8303
8894
  backgroundColor: meta.preview.surface,
8304
8895
  borderTop: `1px solid ${meta.preview.border}`
@@ -8309,11 +8900,11 @@ var PaletteCard = ({ meta, active = false, onClick, className }) => /* @__PURE__
8309
8900
  "span",
8310
8901
  {
8311
8902
  className: "block text-xs font-semibold",
8312
- style: { color: active ? void 0 : "#6b7280" },
8903
+ style: { color: meta.preview.text ?? (active ? void 0 : "#6b7280") },
8313
8904
  children: meta.label
8314
8905
  }
8315
8906
  ),
8316
- meta.desc && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-[10px]", style: { color: "#9ca3af" }, children: meta.desc })
8907
+ meta.desc && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-[10px]", style: { color: meta.preview.text ?? "#9ca3af" }, children: meta.desc })
8317
8908
  ] }),
8318
8909
  active && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-brand-500 flex h-4 w-4 shrink-0 items-center justify-center rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-2.5 w-2.5 text-white", "aria-hidden": true }) })
8319
8910
  ]
@@ -8363,7 +8954,7 @@ var OptionCard = ({
8363
8954
  {
8364
8955
  className: clsx.clsx(
8365
8956
  "text-xs font-semibold",
8366
- active ? "text-brand-500" : "text-gray-700 dark:text-gray-300"
8957
+ active ? "text-brand-600 dark:text-brand-400" : "text-gray-700 dark:text-gray-300"
8367
8958
  ),
8368
8959
  children: label
8369
8960
  }
@@ -8399,6 +8990,129 @@ var OptionPicker = ({
8399
8990
  ))
8400
8991
  }
8401
8992
  );
8993
+
8994
+ // src/settings/appearance.ts
8995
+ var COSMOS_THEMES = [
8996
+ {
8997
+ id: "light",
8998
+ label: "Light",
8999
+ dark: false,
9000
+ preview: { bg: "#f9fafb", surface: "#ffffff", border: "#e5e7eb", text: "#667085" }
9001
+ },
9002
+ {
9003
+ id: "sand",
9004
+ label: "Sand",
9005
+ dark: false,
9006
+ preview: { bg: "#f9f5eb", surface: "#fffcf7", border: "#e7dfd0", text: "#746656" }
9007
+ },
9008
+ {
9009
+ id: "dark",
9010
+ label: "Dark",
9011
+ dark: true,
9012
+ preview: { bg: "#0a0a0a", surface: "#141414", border: "#3d3d3d", text: "#a3a3a3" }
9013
+ },
9014
+ {
9015
+ id: "deep-blue",
9016
+ label: "Deep Blue",
9017
+ dark: true,
9018
+ preview: { bg: "#0c111d", surface: "#101828", border: "#344054", text: "#98a2b3" }
9019
+ }
9020
+ ];
9021
+ var COSMOS_ACCENTS = [
9022
+ { id: "blue", label: "Blue", hex: "#465fff" },
9023
+ { id: "indigo", label: "Indigo", hex: "#5963e9" },
9024
+ { id: "violet", label: "Violet", hex: "#8745f1" },
9025
+ { id: "purple", label: "Purple", hex: "#ad2ecf" },
9026
+ { id: "rose", label: "Rose", hex: "#d4166d" },
9027
+ { id: "teal", label: "Teal", hex: "#038378" },
9028
+ { id: "cyan", label: "Cyan", hex: "#017f9d" },
9029
+ { id: "graphite", label: "Graphite", hex: "#707580" },
9030
+ { id: "red", label: "Red", hex: "#db192a" },
9031
+ { id: "orange", label: "Orange", hex: "#c04f01" },
9032
+ { id: "amber", label: "Amber", hex: "#a46800" },
9033
+ { id: "green", label: "Green", hex: "#02863c" }
9034
+ ];
9035
+ var THEME_CLASSES = COSMOS_THEMES.map((t) => t.id).filter((id) => id !== "light");
9036
+ var isDarkTheme = (theme) => COSMOS_THEMES.some((t) => t.id === theme && t.dark);
9037
+ var applyAppearance = ({ theme, accent }, root) => {
9038
+ const el = root ?? (typeof document === "undefined" ? void 0 : document.documentElement);
9039
+ if (!el) return;
9040
+ el.classList.remove(...THEME_CLASSES);
9041
+ if (theme !== "light") el.classList.add(theme);
9042
+ if (accent === "blue") delete el.dataset.accent;
9043
+ else el.dataset.accent = accent;
9044
+ };
9045
+ var AppearanceSettings = ({
9046
+ theme,
9047
+ accent,
9048
+ onThemeChange,
9049
+ onAccentChange,
9050
+ themeLabel = "Theme",
9051
+ accentLabel = "Accent color",
9052
+ themes = COSMOS_THEMES,
9053
+ accents = COSMOS_ACCENTS,
9054
+ themeColumns = 4,
9055
+ className
9056
+ }) => {
9057
+ const themeHeadingId = react.useId();
9058
+ const accentHeadingId = react.useId();
9059
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx.clsx("space-y-6", className), children: [
9060
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-labelledby": themeHeadingId, children: [
9061
+ /* @__PURE__ */ jsxRuntime.jsx("p", { id: themeHeadingId, className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: themeLabel }),
9062
+ /* @__PURE__ */ jsxRuntime.jsx(
9063
+ PalettePicker,
9064
+ {
9065
+ className: "mt-3",
9066
+ palettes: themes,
9067
+ value: theme,
9068
+ cols: themeColumns,
9069
+ onChange: (id) => onThemeChange(id)
9070
+ }
9071
+ )
9072
+ ] }),
9073
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-labelledby": accentHeadingId, children: [
9074
+ /* @__PURE__ */ jsxRuntime.jsx("p", { id: accentHeadingId, className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: accentLabel }),
9075
+ /* @__PURE__ */ jsxRuntime.jsx(
9076
+ AccentPicker,
9077
+ {
9078
+ className: "mt-3",
9079
+ colors: accents,
9080
+ value: accent,
9081
+ onChange: (id) => onAccentChange(id),
9082
+ cols: 6
9083
+ }
9084
+ )
9085
+ ] })
9086
+ ] });
9087
+ };
9088
+ var SIZE_CLASS12 = {
9089
+ sm: { box: "h-8 w-8", icon: "h-4 w-4" },
9090
+ md: { box: "h-10 w-10", icon: "h-5 w-5" }
9091
+ };
9092
+ var AppearanceMenu = ({
9093
+ label = "Appearance",
9094
+ size = "md",
9095
+ className,
9096
+ ...settings
9097
+ }) => {
9098
+ const { box, icon } = SIZE_CLASS12[size];
9099
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { children: [
9100
+ /* @__PURE__ */ jsxRuntime.jsx(
9101
+ Popover.Trigger,
9102
+ {
9103
+ title: label,
9104
+ "aria-label": label,
9105
+ className: clsx.clsx(
9106
+ "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",
9107
+ box,
9108
+ className
9109
+ ),
9110
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Palette, { className: icon, "aria-hidden": true })
9111
+ }
9112
+ ),
9113
+ /* @__PURE__ */ jsxRuntime.jsx(Popover.Content, { align: "end", width: "w-96", "aria-label": label, children: /* @__PURE__ */ jsxRuntime.jsx(AppearanceSettings, { themeColumns: 2, ...settings }) })
9114
+ ] });
9115
+ };
8402
9116
  var SIZE = {
8403
9117
  sm: "text-base leading-relaxed",
8404
9118
  md: "text-lg leading-relaxed",
@@ -8577,6 +9291,9 @@ exports.ActiveFiltersBar = ActiveFiltersBar;
8577
9291
  exports.ActivityFeed = ActivityFeed;
8578
9292
  exports.AlertBanner = AlertBanner;
8579
9293
  exports.AnnouncementBar = AnnouncementBar;
9294
+ exports.AppearanceMenu = AppearanceMenu;
9295
+ exports.AppearanceSettings = AppearanceSettings;
9296
+ exports.AuthLayout = AuthLayout;
8580
9297
  exports.Avatar = Avatar;
8581
9298
  exports.AvatarUploader = AvatarUploader;
8582
9299
  exports.BackToTopFab = BackToTopFab;
@@ -8586,6 +9303,8 @@ exports.Blockquote = Blockquote;
8586
9303
  exports.Breadcrumb = Breadcrumb;
8587
9304
  exports.Button = Button;
8588
9305
  exports.ButtonGroup = ButtonGroup;
9306
+ exports.COSMOS_ACCENTS = COSMOS_ACCENTS;
9307
+ exports.COSMOS_THEMES = COSMOS_THEMES;
8589
9308
  exports.Calendar = Calendar;
8590
9309
  exports.Card = Card2;
8591
9310
  exports.Carousel = Carousel;
@@ -8627,6 +9346,7 @@ exports.HelpOverlay = HelpOverlay;
8627
9346
  exports.IconBox = IconBox;
8628
9347
  exports.ImageGrid = ImageGrid;
8629
9348
  exports.Input = Input;
9349
+ exports.IntegrationCard = IntegrationCard;
8630
9350
  exports.Kbd = Kbd2;
8631
9351
  exports.KpiCard = KpiCard;
8632
9352
  exports.Link = Link;
@@ -8659,6 +9379,7 @@ exports.REFRESH_OPTIONS = REFRESH_OPTIONS;
8659
9379
  exports.Radio = Radio;
8660
9380
  exports.RadioGroup = RadioGroup;
8661
9381
  exports.RefreshButton = RefreshButton;
9382
+ exports.ResetPasswordForm = ResetPasswordForm;
8662
9383
  exports.Ribbon = Ribbon;
8663
9384
  exports.RowActionButton = RowActionButton;
8664
9385
  exports.STATUS_COLOR = STATUS_COLOR;
@@ -8671,11 +9392,14 @@ exports.Select = Select;
8671
9392
  exports.SelectInput = SelectInput;
8672
9393
  exports.Shell = Shell;
8673
9394
  exports.Sidebar = Sidebar;
9395
+ exports.SignInForm = SignInForm;
9396
+ exports.SignUpForm = SignUpForm;
8674
9397
  exports.SimpleRow = SimpleRow;
8675
9398
  exports.Sk = Sk;
8676
9399
  exports.SkeletonList = SkeletonList;
8677
9400
  exports.SkeletonTable = SkeletonTable;
8678
9401
  exports.SkeletonText = SkeletonText;
9402
+ exports.SocialAuthButtons = SocialAuthButtons;
8679
9403
  exports.Spinner = Spinner;
8680
9404
  exports.StackedList = StackedList;
8681
9405
  exports.StackedListInCard = StackedListInCard;
@@ -8697,15 +9421,15 @@ exports.Toggle = Toggle;
8697
9421
  exports.Tooltip = Tooltip;
8698
9422
  exports.TooltipHelp = TooltipHelp;
8699
9423
  exports.Topbar = Topbar;
9424
+ exports.TwoStepVerificationForm = TwoStepVerificationForm;
8700
9425
  exports.UnsavedIndicator = UnsavedIndicator;
8701
9426
  exports.UserMenu = UserMenu;
8702
9427
  exports.VerticalNavigation = VerticalNavigation;
8703
9428
  exports.VideoEmbed = VideoEmbed;
8704
9429
  exports.ZoomBar = ZoomBar;
9430
+ exports.applyAppearance = applyAppearance;
8705
9431
  exports.defaultPasswordRules = defaultPasswordRules;
8706
- exports.placeholderAvatar = placeholderAvatar;
8707
- exports.placeholderCover = placeholderCover;
8708
- exports.portalDocsParams = portalDocsParams;
9432
+ exports.isDarkTheme = isDarkTheme;
8709
9433
  exports.useAutoRefresh = useAutoRefresh;
8710
9434
  //# sourceMappingURL=index.cjs.map
8711
9435
  //# sourceMappingURL=index.cjs.map