@raxrai/stylelab-ui 0.3.1 → 0.4.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
@@ -61,6 +61,7 @@ __export(index_exports, {
61
61
  cn: () => cn,
62
62
  getNextListIndex: () => getNextListIndex,
63
63
  getThemeClass: () => getThemeClass,
64
+ mergeRefs: () => mergeRefs,
64
65
  useClickOutside: () => useClickOutside,
65
66
  useFocusTrap: () => useFocusTrap,
66
67
  useKeyboardNavigation: () => useKeyboardNavigation,
@@ -74,13 +75,13 @@ var import_react = require("react");
74
75
  // lib/theme-resolver.ts
75
76
  var themeMap = {
76
77
  minimal: {
77
- button: { primary: "bg-zinc-900 text-white border border-zinc-200 transition-colors duration-200 hover:bg-zinc-800 hover:border-zinc-300 hover:shadow-md", secondary: "bg-transparent border border-zinc-200 text-zinc-900 hover:bg-zinc-100", ghost: "text-zinc-700 hover:bg-zinc-100" },
78
+ button: { primary: "bg-zinc-900 text-white border border-zinc-200 transition-colors duration-200 hover:bg-zinc-800 hover:border-zinc-300 hover:shadow-md", secondary: "bg-transparent border border-zinc-200 text-zinc-900 hover:bg-zinc-100", ghost: "text-inherit hover:bg-zinc-100" },
78
79
  input: { default: "border border-zinc-200 text-zinc-900 placeholder:text-zinc-400 focus:ring-1 focus:ring-zinc-400 focus:border-zinc-400" },
79
80
  toggle: { default: "bg-zinc-200 data-[state=on]:bg-zinc-900" },
80
81
  badge: { default: "bg-zinc-100 text-zinc-700 border border-zinc-200" },
81
82
  slider: { default: "bg-zinc-200 [&_.slider-thumb]:bg-zinc-900" },
82
83
  tabs: { default: "border-b border-zinc-200", triggerActive: "border-zinc-900 font-semibold", triggerInactive: "opacity-70" },
83
- card: { default: "bg-white text-zinc-900 border border-zinc-200 shadow-none" },
84
+ card: { default: "bg-white border border-zinc-200 shadow-none" },
84
85
  bento: { default: "gap-4" },
85
86
  navbar: { default: "bg-white text-zinc-900 border-b border-zinc-200" },
86
87
  sidebar: { default: "bg-white text-zinc-900 border-r border-zinc-200" },
@@ -103,13 +104,13 @@ var themeMap = {
103
104
  timeline: { default: "border-l-2 border-zinc-200 text-zinc-900" }
104
105
  },
105
106
  night: {
106
- button: { primary: "bg-white text-zinc-950 border border-white/10 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.1)] transition-colors duration-200 hover:bg-zinc-100 hover:shadow-md hover:border-white/20", secondary: "bg-zinc-900 border border-white/10 text-white hover:bg-zinc-800", ghost: "text-zinc-300 hover:bg-white/5" },
107
+ button: { primary: "bg-white text-zinc-950 border border-white/10 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.1)] transition-colors duration-200 hover:bg-zinc-100 hover:shadow-md hover:border-white/20", secondary: "bg-zinc-900 border border-white/10 text-white hover:bg-zinc-800", ghost: "text-inherit hover:bg-white/5" },
107
108
  input: { default: "bg-zinc-900 text-zinc-100 border border-white/10 placeholder:text-zinc-500 focus:ring-1 focus:ring-white/20 shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]" },
108
109
  toggle: { default: "bg-zinc-800 data-[state=on]:bg-white shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]" },
109
110
  badge: { default: "bg-zinc-800 text-zinc-300 border border-white/10" },
110
111
  slider: { default: "bg-zinc-800 [&_.slider-thumb]:bg-white shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]" },
111
112
  tabs: { default: "border-b border-white/10", triggerActive: "border-white font-semibold", triggerInactive: "opacity-70" },
112
- card: { default: "bg-zinc-950 text-zinc-100 border border-white/10 shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]" },
113
+ card: { default: "bg-zinc-950 border border-white/10 shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]" },
113
114
  bento: { default: "gap-4" },
114
115
  navbar: { default: "bg-zinc-950 text-zinc-100 border-b border-white/10" },
115
116
  sidebar: { default: "bg-zinc-950 text-zinc-100 border-r border-white/10" },
@@ -132,13 +133,13 @@ var themeMap = {
132
133
  timeline: { default: "border-l-2 border-white/20 text-zinc-100" }
133
134
  },
134
135
  glass: {
135
- button: { primary: "rounded-xl bg-white/70 backdrop-blur-2xl border border-white/60 text-slate-800 shadow-glass-soft transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/80 hover:border-white/80 hover:shadow-glass-button-hover active:translate-y-0 active:shadow-glass-soft", secondary: "rounded-xl bg-white/50 backdrop-blur-2xl border border-white/60 text-slate-800 shadow-glass-soft transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/60 hover:border-white/80 hover:shadow-glass-button-hover active:translate-y-0 active:shadow-glass-soft", ghost: "rounded-xl text-slate-700 backdrop-blur-xl transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/40 hover:shadow-glass-soft hover:border hover:border-white/60" },
136
+ button: { primary: "rounded-xl bg-white/70 backdrop-blur-2xl border border-white/60 text-slate-800 shadow-glass-soft transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/80 hover:border-white/80 hover:shadow-glass-button-hover active:translate-y-0 active:shadow-glass-soft", secondary: "rounded-xl bg-white/50 backdrop-blur-2xl border border-white/60 text-slate-800 shadow-glass-soft transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/60 hover:border-white/80 hover:shadow-glass-button-hover active:translate-y-0 active:shadow-glass-soft", ghost: "rounded-xl text-inherit backdrop-blur-xl transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/40 hover:shadow-glass-soft hover:border hover:border-white/60" },
136
137
  input: { default: "rounded-xl bg-white/50 backdrop-blur-2xl border border-slate-200/80 text-slate-800 shadow-glass-soft placeholder:text-slate-500 focus:ring-2 focus:ring-slate-300/50 focus:border-slate-300" },
137
138
  toggle: { default: "rounded-full bg-white/50 data-[state=on]:bg-white/80 backdrop-blur-2xl border border-white/60 shadow-glass-soft" },
138
139
  badge: { default: "rounded-xl bg-white/60 backdrop-blur-2xl text-slate-700 border border-white/60 shadow-glass-soft" },
139
140
  slider: { default: "rounded-full bg-white/50 [&_.slider-thumb]:bg-white [&_.slider-thumb]:border-slate-200 [&_.slider-thumb]:shadow-glass-soft backdrop-blur-2xl border border-white/60 shadow-glass-soft" },
140
141
  tabs: { default: "border-b border-slate-200/60", triggerActive: "border-slate-700 font-semibold", triggerInactive: "opacity-70" },
141
- card: { default: "rounded-2xl bg-white/60 backdrop-blur-2xl border border-white/60 text-slate-800 shadow-glass-lift" },
142
+ card: { default: "rounded-2xl bg-white/60 backdrop-blur-2xl border border-white/60 shadow-glass-lift" },
142
143
  bento: { default: "gap-4" },
143
144
  navbar: { default: "rounded-none bg-white/50 backdrop-blur-2xl border-b border-white/60 text-slate-800 shadow-glass-soft" },
144
145
  sidebar: { default: "rounded-none bg-white/50 backdrop-blur-2xl border-r border-white/60 text-slate-800 shadow-glass-soft" },
@@ -161,13 +162,13 @@ var themeMap = {
161
162
  timeline: { default: "border-l-2 border-slate-200/60 text-slate-800" }
162
163
  },
163
164
  neubrutal: {
164
- button: { primary: "rounded-none bg-[#FFD600] text-black border-4 border-black shadow-neubrutal hover:translate-x-1 hover:translate-y-1 hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)]", secondary: "rounded-none bg-[#FF5733] text-black border-4 border-black shadow-neubrutal hover:translate-x-1 hover:translate-y-1", ghost: "rounded-none border-4 border-transparent hover:border-black hover:bg-zinc-100 text-black" },
165
+ button: { primary: "rounded-none bg-[#FFD600] text-black border-4 border-black shadow-neubrutal hover:translate-x-1 hover:translate-y-1 hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)]", secondary: "rounded-none bg-[#FF5733] text-black border-4 border-black shadow-neubrutal hover:translate-x-1 hover:translate-y-1", ghost: "rounded-none text-inherit border-4 border-transparent hover:border-black hover:bg-zinc-100" },
165
166
  input: { default: "rounded-none border-4 border-black text-black placeholder:text-zinc-600 focus:ring-4 focus:ring-black/20 bg-white" },
166
167
  toggle: { default: "rounded-none border-4 border-black bg-white data-[state=on]:bg-[#FFD600] shadow-neubrutal" },
167
168
  badge: { default: "rounded-none bg-[#FFD600] text-black border-4 border-black" },
168
169
  slider: { default: "rounded-none border-4 border-black bg-white [&_.slider-thumb]:bg-[#FF5733] [&_.slider-thumb]:border-4 [&_.slider-thumb]:border-black" },
169
170
  tabs: { default: "border-b-4 border-black", triggerActive: "bg-[#FFD600] border-b-4 border-black font-bold -mb-[3px] pb-[5px] shadow-neubrutal", triggerInactive: "opacity-80" },
170
- card: { default: "rounded-none bg-white text-black border-4 border-black shadow-neubrutal" },
171
+ card: { default: "rounded-none bg-white border-4 border-black shadow-neubrutal" },
171
172
  bento: { default: "gap-4" },
172
173
  navbar: { default: "rounded-none bg-[#FFD600] text-black border-b-4 border-black shadow-neubrutal" },
173
174
  sidebar: { default: "rounded-none bg-[#FFD600]/30 border-r-4 border-black shadow-neubrutal text-black" },
@@ -190,13 +191,13 @@ var themeMap = {
190
191
  timeline: { default: "border-l-4 border-black text-black" }
191
192
  },
192
193
  clay: {
193
- button: { primary: "rounded-[40px] bg-rose-200 text-rose-900 border border-rose-300 shadow-clay-outer hover:shadow-[10px_10px_20px_rgba(0,0,0,0.08),inset_-8px_-8px_15px_rgba(0,0,0,0.2),inset_8px_8px_15px_rgba(255,255,255,0.4)]", secondary: "rounded-[40px] bg-sky-100 text-sky-900 shadow-clay-outer", ghost: "rounded-[40px] hover:bg-zinc-100 text-zinc-800" },
194
+ button: { primary: "rounded-[40px] bg-rose-200 text-rose-900 border border-rose-300 shadow-clay-outer hover:shadow-[10px_10px_20px_rgba(0,0,0,0.08),inset_-8px_-8px_15px_rgba(0,0,0,0.2),inset_8px_8px_15px_rgba(255,255,255,0.4)]", secondary: "rounded-[40px] bg-sky-100 text-sky-900 shadow-clay-outer", ghost: "rounded-[40px] text-inherit hover:bg-zinc-100" },
194
195
  input: { default: "rounded-[40px] border border-zinc-200 bg-zinc-50 text-zinc-900 placeholder:text-zinc-500 focus:ring-2 focus:ring-sky-300" },
195
196
  toggle: { default: "rounded-full bg-sky-100 data-[state=on]:bg-sky-300 data-[state=on]:shadow-clay-outer" },
196
197
  badge: { default: "rounded-[40px] bg-amber-100 text-amber-900" },
197
198
  slider: { default: "rounded-full bg-sky-100 [&_.slider-thumb]:rounded-full [&_.slider-thumb]:bg-rose-300" },
198
199
  tabs: { default: "border-b-2 border-zinc-200/80", triggerActive: "border-rose-600 font-semibold", triggerInactive: "opacity-70" },
199
- card: { default: "rounded-[40px] bg-rose-50 text-zinc-900 shadow-clay-outer border border-rose-100" },
200
+ card: { default: "rounded-[40px] bg-rose-50 shadow-clay-outer border border-rose-100" },
200
201
  bento: { default: "gap-4" },
201
202
  navbar: { default: "rounded-b-3xl bg-white/80 text-zinc-900 backdrop-blur-md shadow-clay-outer border-b border-zinc-200" },
202
203
  sidebar: { default: "rounded-r-3xl bg-sky-50 text-zinc-900 shadow-clay-outer border-r border-sky-100" },
@@ -219,13 +220,13 @@ var themeMap = {
219
220
  timeline: { default: "border-l-2 border-rose-200 text-zinc-900" }
220
221
  },
221
222
  cyberpunk: {
222
- button: { primary: "bg-transparent border-2 border-[#22d3ee] text-[#22d3ee] font-mono shadow-neon-glow hover:animate-glitch-anim", secondary: "bg-transparent border-2 border-[#ec4899] text-[#ec4899] font-mono hover:animate-glitch-anim", ghost: "text-[#22d3ee] font-mono hover:bg-[#22d3ee]/10" },
223
+ button: { primary: "bg-transparent border-2 border-[#22d3ee] text-[#22d3ee] font-mono shadow-neon-glow hover:animate-glitch-anim", secondary: "bg-transparent border-2 border-[#ec4899] text-[#ec4899] font-mono hover:animate-glitch-anim", ghost: "text-inherit font-mono hover:bg-[#22d3ee]/10" },
223
224
  input: { default: "bg-black border-2 border-[#22d3ee] text-[#22d3ee] placeholder:text-[#22d3ee]/50 font-mono focus:shadow-neon-glow" },
224
225
  toggle: { default: "bg-zinc-900 border-2 border-[#22d3ee] data-[state=on]:bg-[#22d3ee] data-[state=on]:shadow-neon-glow" },
225
226
  badge: { default: "bg-black border-2 border-[#ec4899] text-[#ec4899] font-mono" },
226
227
  slider: { default: "bg-zinc-900 [&_.slider-thumb]:border-2 [&_.slider-thumb]:border-[#22d3ee] [&_.slider-thumb]:bg-[#22d3ee] [&_.slider-thumb]:shadow-neon-glow" },
227
228
  tabs: { default: "border-b-2 border-[#22d3ee]", triggerActive: "text-[#22d3ee] border-[#22d3ee] font-bold shadow-neon-glow", triggerInactive: "opacity-50 text-[#22d3ee]/70" },
228
- card: { default: "bg-black text-[#22d3ee] border-2 border-[#22d3ee] shadow-neon-glow font-mono" },
229
+ card: { default: "bg-black border-2 border-[#22d3ee] shadow-neon-glow font-mono" },
229
230
  bento: { default: "gap-4" },
230
231
  navbar: { default: "bg-black text-[#22d3ee] border-b-2 border-[#22d3ee] font-mono" },
231
232
  sidebar: { default: "bg-black text-[#22d3ee] border-r-2 border-[#22d3ee] font-mono" },
@@ -248,13 +249,13 @@ var themeMap = {
248
249
  timeline: { default: "border-l-2 border-[#22d3ee] text-[#22d3ee] font-mono" }
249
250
  },
250
251
  retro: {
251
- button: { primary: "rounded-none bg-lime-500 text-black border-2 border-black font-mono shadow-[4px_4px_0_0_rgba(0,0,0,1)] hover:bg-lime-400 active:shadow-[2px_2px_0_0_rgba(0,0,0,1)]", secondary: "rounded-none bg-white text-black border-2 border-black font-mono shadow-[4px_4px_0_0_rgba(0,0,0,1)] hover:bg-zinc-100 active:shadow-[2px_2px_0_0_rgba(0,0,0,1)]", ghost: "rounded-none font-mono text-black border-2 border-transparent hover:border-black hover:bg-zinc-100" },
252
+ button: { primary: "rounded-none bg-lime-500 text-black border-2 border-black font-mono shadow-[4px_4px_0_0_rgba(0,0,0,1)] hover:bg-lime-400 active:shadow-[2px_2px_0_0_rgba(0,0,0,1)]", secondary: "rounded-none bg-white text-black border-2 border-black font-mono shadow-[4px_4px_0_0_rgba(0,0,0,1)] hover:bg-zinc-100 active:shadow-[2px_2px_0_0_rgba(0,0,0,1)]", ghost: "rounded-none font-mono text-inherit border-2 border-transparent hover:border-black hover:bg-zinc-100" },
252
253
  input: { default: "rounded-none border-2 border-black text-black placeholder:text-zinc-500 font-mono focus:ring-2 focus:ring-black focus:ring-offset-0 bg-white" },
253
254
  toggle: { default: "rounded-none border-2 border-black bg-zinc-200 data-[state=on]:bg-lime-500 shadow-[3px_3px_0_0_rgba(0,0,0,1)]" },
254
255
  badge: { default: "rounded-none bg-lime-500 text-black border-2 border-black font-mono" },
255
256
  slider: { default: "rounded-none border-2 border-black bg-zinc-200 [&_.slider-thumb]:rounded-none [&_.slider-thumb]:border-2 [&_.slider-thumb]:border-black [&_.slider-thumb]:bg-lime-500 [&_.slider-thumb]:shadow-[2px_2px_0_0_rgba(0,0,0,1)]" },
256
257
  tabs: { default: "border-b-2 border-black font-mono", triggerActive: "border-b-2 border-black font-bold bg-lime-500/20 text-black -mb-[2px] pb-[6px]", triggerInactive: "opacity-70 text-black" },
257
- card: { default: "rounded-none bg-white text-black border-2 border-black shadow-[6px_6px_0_0_rgba(0,0,0,1)] font-mono" },
258
+ card: { default: "rounded-none bg-white border-2 border-black shadow-[6px_6px_0_0_rgba(0,0,0,1)] font-mono" },
258
259
  bento: { default: "gap-4" },
259
260
  navbar: { default: "rounded-none bg-zinc-100 text-black border-b-2 border-black font-mono shadow-[0_4px_0_0_rgba(0,0,0,1)]" },
260
261
  sidebar: { default: "rounded-none bg-zinc-100 text-black border-r-2 border-black font-mono" },
@@ -277,13 +278,13 @@ var themeMap = {
277
278
  timeline: { default: "border-l-2 border-black text-black font-mono" }
278
279
  },
279
280
  motion: {
280
- button: { primary: "rounded-xl bg-indigo-500 text-white border-0 shadow-lg transition-all duration-300 ease-out hover:scale-105 hover:-translate-y-0.5 hover:shadow-xl hover:bg-indigo-600 active:scale-100 active:translate-y-0 focus:ring-2 focus:ring-indigo-400 focus:ring-offset-2", secondary: "rounded-xl bg-white text-indigo-600 border-2 border-indigo-200 shadow-md transition-all duration-300 ease-out hover:scale-105 hover:-translate-y-0.5 hover:border-indigo-300 hover:shadow-lg active:scale-100 active:translate-y-0 focus:ring-2 focus:ring-indigo-300 focus:ring-offset-2", ghost: "rounded-xl text-indigo-600 transition-all duration-300 ease-out hover:scale-105 hover:bg-indigo-50 hover:-translate-y-0.5 active:scale-100 active:translate-y-0" },
281
+ button: { primary: "rounded-xl bg-indigo-500 text-white border-0 shadow-lg transition-all duration-300 ease-out hover:scale-105 hover:-translate-y-0.5 hover:shadow-xl hover:bg-indigo-600 active:scale-100 active:translate-y-0 focus:ring-2 focus:ring-indigo-400 focus:ring-offset-2", secondary: "rounded-xl bg-white text-indigo-600 border-2 border-indigo-200 shadow-md transition-all duration-300 ease-out hover:scale-105 hover:-translate-y-0.5 hover:border-indigo-300 hover:shadow-lg active:scale-100 active:translate-y-0 focus:ring-2 focus:ring-indigo-300 focus:ring-offset-2", ghost: "rounded-xl text-inherit transition-all duration-300 ease-out hover:scale-105 hover:bg-indigo-50 hover:-translate-y-0.5 active:scale-100 active:translate-y-0" },
281
282
  input: { default: "rounded-xl border-2 border-indigo-200 bg-white text-zinc-900 transition-all duration-300 ease-out placeholder:text-zinc-400 focus:scale-[1.01] focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 focus:ring-offset-0" },
282
283
  toggle: { default: "rounded-full bg-zinc-200 transition-all duration-300 ease-out data-[state=on]:bg-indigo-500 [&_.slider-thumb]:transition-transform [&_.slider-thumb]:duration-300 [&_.slider-thumb]:data-[state=on]:scale-110" },
283
284
  badge: { default: "rounded-full bg-indigo-100 text-indigo-700 border border-indigo-200 transition-all duration-300 ease-out hover:scale-110 hover:bg-indigo-200" },
284
285
  slider: { default: "rounded-full bg-zinc-200 transition-all duration-300 [&_.slider-thumb]:rounded-full [&_.slider-thumb]:bg-indigo-500 [&_.slider-thumb]:transition-transform [&_.slider-thumb]:duration-300 [&_.slider-thumb]:hover:scale-125 [&_.slider-thumb]:active:scale-110" },
285
286
  tabs: { default: "border-b-2 border-indigo-200 transition-colors duration-300", triggerActive: "border-indigo-500 font-semibold text-indigo-600 transition-all duration-300", triggerInactive: "opacity-70 transition-opacity duration-300 hover:opacity-100" },
286
- card: { default: "rounded-2xl bg-white text-zinc-900 border-2 border-indigo-100 shadow-lg transition-all duration-300 ease-out hover:scale-[1.02] hover:shadow-xl hover:border-indigo-200 hover:-translate-y-1" },
287
+ card: { default: "rounded-2xl bg-white border-2 border-indigo-100 shadow-lg transition-all duration-300 ease-out hover:scale-[1.02] hover:shadow-xl hover:border-indigo-200 hover:-translate-y-1" },
287
288
  bento: { default: "gap-4" },
288
289
  navbar: { default: "rounded-none bg-white/95 backdrop-blur-md text-zinc-900 border-b-2 border-indigo-100 shadow-sm transition-all duration-300" },
289
290
  sidebar: { default: "rounded-none bg-white/95 backdrop-blur-md text-zinc-900 border-r-2 border-indigo-100 transition-all duration-300" },
@@ -341,12 +342,14 @@ function getStoredTheme(storageKey, defaultTheme) {
341
342
  function ThemeProvider({
342
343
  children,
343
344
  defaultTheme = "minimal",
344
- storageKey = "stylelab-theme"
345
+ storageKey = "stylelab-theme",
346
+ persistTheme = true
345
347
  }) {
346
348
  const [theme, setThemeState] = (0, import_react.useState)(defaultTheme);
347
349
  (0, import_react.useEffect)(() => {
350
+ if (!persistTheme) return;
348
351
  setThemeState((prev) => getStoredTheme(storageKey, prev));
349
- }, [storageKey]);
352
+ }, [storageKey, persistTheme]);
350
353
  (0, import_react.useEffect)(() => {
351
354
  if (typeof document !== "undefined") {
352
355
  try {
@@ -361,12 +364,12 @@ function ThemeProvider({
361
364
  if (typeof document !== "undefined") {
362
365
  try {
363
366
  document.documentElement.dataset.stylelabTheme = next;
364
- localStorage.setItem(storageKey, next);
367
+ if (persistTheme) localStorage.setItem(storageKey, next);
365
368
  } catch (_) {
366
369
  }
367
370
  }
368
371
  },
369
- [storageKey]
372
+ [storageKey, persistTheme]
370
373
  );
371
374
  const value = (0, import_react.useMemo)(
372
375
  () => ({ theme, setTheme }),
@@ -3580,6 +3583,14 @@ var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
3580
3583
  function cn(...inputs) {
3581
3584
  return twMerge(clsx(inputs));
3582
3585
  }
3586
+ function mergeRefs(...refs) {
3587
+ return (node) => {
3588
+ refs.forEach((ref) => {
3589
+ if (typeof ref === "function") ref(node);
3590
+ else if (ref != null) ref.current = node;
3591
+ });
3592
+ };
3593
+ }
3583
3594
 
3584
3595
  // node_modules/lucide-react/dist/esm/createLucideIcon.js
3585
3596
  var import_react3 = require("react");
@@ -3789,14 +3800,14 @@ function AccordionPanel({
3789
3800
  )
3790
3801
  ] });
3791
3802
  }
3792
- function Accordion({
3803
+ var Accordion = (0, import_react4.forwardRef)(function Accordion2({
3793
3804
  items,
3794
3805
  allowMultiple = false,
3795
3806
  defaultOpenIds,
3796
3807
  className,
3797
3808
  style,
3798
3809
  theme: themeProp
3799
- }) {
3810
+ }, ref) {
3800
3811
  const [open, setOpen] = (0, import_react4.useState)(
3801
3812
  () => new Set(defaultOpenIds ?? [])
3802
3813
  );
@@ -3817,7 +3828,7 @@ function Accordion({
3817
3828
  },
3818
3829
  [allowMultiple]
3819
3830
  );
3820
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(themeClass, className), style, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3831
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className: cn(themeClass, className), style, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3821
3832
  AccordionPanel,
3822
3833
  {
3823
3834
  item,
@@ -3827,7 +3838,7 @@ function Accordion({
3827
3838
  },
3828
3839
  item.id
3829
3840
  )) });
3830
- }
3841
+ });
3831
3842
 
3832
3843
  // components/Alert.tsx
3833
3844
  var import_react5 = require("react");
@@ -4072,17 +4083,15 @@ var Badge = (0, import_react7.forwardRef)(function Badge2({
4072
4083
  });
4073
4084
 
4074
4085
  // components/BentoGrid.tsx
4086
+ var import_react8 = require("react");
4075
4087
  var import_jsx_runtime6 = require("react/jsx-runtime");
4076
- function BentoGrid({
4077
- children,
4078
- className,
4079
- style
4080
- }) {
4088
+ var BentoGrid = (0, import_react8.forwardRef)(function BentoGrid2({ children, className, style }, ref) {
4081
4089
  const { theme } = useTheme();
4082
4090
  const themeClass = getThemeClass(theme, "bento", "default");
4083
4091
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4084
4092
  "div",
4085
4093
  {
4094
+ ref,
4086
4095
  className: cn(
4087
4096
  "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
4088
4097
  themeClass,
@@ -4092,9 +4101,10 @@ function BentoGrid({
4092
4101
  children
4093
4102
  }
4094
4103
  );
4095
- }
4104
+ });
4096
4105
 
4097
4106
  // components/Breadcrumbs.tsx
4107
+ var import_react9 = require("react");
4098
4108
  var import_jsx_runtime7 = require("react/jsx-runtime");
4099
4109
  var defaultSeparators = {
4100
4110
  minimal: "/",
@@ -4106,24 +4116,19 @@ var defaultSeparators = {
4106
4116
  retro: ">",
4107
4117
  motion: "\u203A"
4108
4118
  };
4109
- function Breadcrumbs({
4110
- items,
4111
- separator,
4112
- className,
4113
- theme: themeProp
4114
- }) {
4119
+ var Breadcrumbs = (0, import_react9.forwardRef)(function Breadcrumbs2({ items, separator, className, style, theme: themeProp }, ref) {
4115
4120
  const { theme: contextTheme } = useTheme();
4116
4121
  const theme = themeProp ?? contextTheme;
4117
4122
  const themeClass = getThemeClass(theme, "breadcrumbs", "default");
4118
4123
  const sep = separator ?? defaultSeparators[theme] ?? "/";
4119
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("nav", { "aria-label": "Breadcrumb", className: cn("flex flex-wrap items-center gap-1.5 text-sm", themeClass, className), children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
4124
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("nav", { ref, "aria-label": "Breadcrumb", className: cn("flex flex-wrap items-center gap-1.5 text-sm", themeClass, className), style, children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
4120
4125
  i > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "data-sep": true, className: "shrink-0 opacity-70", "aria-hidden": true, children: sep }),
4121
4126
  item.href != null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href: item.href, className: "hover:underline", children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "font-medium", "aria-current": i === items.length - 1 ? "page" : void 0, children: item.label })
4122
4127
  ] }, i)) });
4123
- }
4128
+ });
4124
4129
 
4125
4130
  // components/Button.tsx
4126
- var import_react8 = require("react");
4131
+ var import_react10 = require("react");
4127
4132
  var import_jsx_runtime8 = require("react/jsx-runtime");
4128
4133
  var buttonVariants = cva(
4129
4134
  "inline-flex items-center justify-center font-medium transition-colors disabled:opacity-50 disabled:pointer-events-none",
@@ -4204,10 +4209,10 @@ function ButtonInner(props, ref) {
4204
4209
  }
4205
4210
  );
4206
4211
  }
4207
- var Button = (0, import_react8.forwardRef)(ButtonInner);
4212
+ var Button = (0, import_react10.forwardRef)(ButtonInner);
4208
4213
 
4209
4214
  // components/Calendar.tsx
4210
- var import_react9 = require("react");
4215
+ var import_react11 = require("react");
4211
4216
  var import_jsx_runtime9 = require("react/jsx-runtime");
4212
4217
  function getDaysInMonth(year, month) {
4213
4218
  return new Date(year, month + 1, 0).getDate();
@@ -4238,16 +4243,17 @@ var MONTHS = [
4238
4243
  "November",
4239
4244
  "December"
4240
4245
  ];
4241
- function Calendar({
4246
+ var Calendar = (0, import_react11.forwardRef)(function Calendar2({
4242
4247
  value: controlledValue,
4243
4248
  defaultValue,
4244
4249
  onSelect,
4245
4250
  min,
4246
4251
  max,
4247
4252
  className,
4253
+ style,
4248
4254
  theme: themeProp
4249
- }) {
4250
- const [uncontrolled, setUncontrolled] = (0, import_react9.useState)(
4255
+ }, ref) {
4256
+ const [uncontrolled, setUncontrolled] = (0, import_react11.useState)(
4251
4257
  () => defaultValue ?? null
4252
4258
  );
4253
4259
  const isControlled = controlledValue !== void 0;
@@ -4255,11 +4261,11 @@ function Calendar({
4255
4261
  const { theme: contextTheme } = useTheme();
4256
4262
  const theme = themeProp ?? contextTheme;
4257
4263
  const themeClass = getThemeClass(theme, "calendar", "default");
4258
- const [view2, setView] = (0, import_react9.useState)(() => {
4264
+ const [view2, setView] = (0, import_react11.useState)(() => {
4259
4265
  const d = value ?? /* @__PURE__ */ new Date();
4260
4266
  return { year: d.getFullYear(), month: d.getMonth() };
4261
4267
  });
4262
- const grid = (0, import_react9.useMemo)(
4268
+ const grid = (0, import_react11.useMemo)(
4263
4269
  () => buildMonthGrid(view2.year, view2.month),
4264
4270
  [view2.year, view2.month]
4265
4271
  );
@@ -4294,7 +4300,9 @@ function Calendar({
4294
4300
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4295
4301
  "div",
4296
4302
  {
4303
+ ref,
4297
4304
  className: cn("inline-block max-w-full min-w-0 border p-3 sm:p-4 rounded-xl", themeClass, className),
4305
+ style,
4298
4306
  children: [
4299
4307
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [
4300
4308
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -4347,10 +4355,10 @@ function Calendar({
4347
4355
  ]
4348
4356
  }
4349
4357
  );
4350
- }
4358
+ });
4351
4359
 
4352
4360
  // components/Card.tsx
4353
- var import_react10 = require("react");
4361
+ var import_react12 = require("react");
4354
4362
  var import_jsx_runtime10 = require("react/jsx-runtime");
4355
4363
  var cardVariants = cva("rounded-xl", {
4356
4364
  variants: {
@@ -4369,7 +4377,7 @@ var cardVariants = cva("rounded-xl", {
4369
4377
  isHoverable: false
4370
4378
  }
4371
4379
  });
4372
- var Card = (0, import_react10.forwardRef)(function Card2({
4380
+ var Card = (0, import_react12.forwardRef)(function Card2({
4373
4381
  header,
4374
4382
  footer,
4375
4383
  padding = "md",
@@ -4390,8 +4398,8 @@ var Card = (0, import_react10.forwardRef)(function Card2({
4390
4398
  className: cn(
4391
4399
  cardVariants({ padding, isHoverable }),
4392
4400
  themeClass,
4393
- className,
4394
- classNames.root
4401
+ classNames.root,
4402
+ className
4395
4403
  ),
4396
4404
  ...props,
4397
4405
  children: [
@@ -4427,9 +4435,160 @@ var Card = (0, import_react10.forwardRef)(function Card2({
4427
4435
  );
4428
4436
  });
4429
4437
 
4430
- // components/DashboardShell.tsx
4431
- var import_react11 = require("react");
4438
+ // components/CommandPalette.tsx
4439
+ var import_react13 = require("react");
4432
4440
  var import_jsx_runtime11 = require("react/jsx-runtime");
4441
+ var CommandPalette = (0, import_react13.forwardRef)(function CommandPalette2({
4442
+ open,
4443
+ onClose,
4444
+ commands,
4445
+ placeholder = "Type a command...",
4446
+ className,
4447
+ style,
4448
+ theme: themeProp
4449
+ }, ref) {
4450
+ const [query, setQuery] = (0, import_react13.useState)("");
4451
+ const [selected, setSelected] = (0, import_react13.useState)(0);
4452
+ const listRef = (0, import_react13.useRef)(null);
4453
+ const { theme: contextTheme } = useTheme();
4454
+ const theme = themeProp ?? contextTheme;
4455
+ const themeClass = getThemeClass(theme, "commandPalette", "default");
4456
+ const filtered = (0, import_react13.useMemo)(() => {
4457
+ if (!query.trim()) return commands;
4458
+ const q = query.toLowerCase();
4459
+ return commands.filter((c) => c.label.toLowerCase().includes(q));
4460
+ }, [commands, query]);
4461
+ const safeSelected = Math.min(selected, Math.max(0, filtered.length - 1));
4462
+ (0, import_react13.useEffect)(() => {
4463
+ if (open) {
4464
+ setQuery("");
4465
+ setSelected(0);
4466
+ }
4467
+ }, [open]);
4468
+ (0, import_react13.useEffect)(() => {
4469
+ setSelected((s) => Math.min(s, Math.max(0, filtered.length - 1)));
4470
+ }, [filtered.length]);
4471
+ const runSelected = (0, import_react13.useCallback)(() => {
4472
+ const item = filtered[safeSelected];
4473
+ if (item) {
4474
+ item.onSelect();
4475
+ onClose();
4476
+ }
4477
+ }, [filtered, safeSelected, onClose]);
4478
+ (0, import_react13.useEffect)(() => {
4479
+ if (!open) return;
4480
+ const handler = (e) => {
4481
+ if (e.key === "Escape") {
4482
+ e.preventDefault();
4483
+ onClose();
4484
+ return;
4485
+ }
4486
+ if (e.key === "ArrowDown") {
4487
+ e.preventDefault();
4488
+ setSelected((s) => (s + 1) % Math.max(1, filtered.length));
4489
+ return;
4490
+ }
4491
+ if (e.key === "ArrowUp") {
4492
+ e.preventDefault();
4493
+ setSelected(
4494
+ (s) => (s - 1 + filtered.length) % Math.max(1, filtered.length)
4495
+ );
4496
+ return;
4497
+ }
4498
+ if (e.key === "Enter") {
4499
+ e.preventDefault();
4500
+ runSelected();
4501
+ }
4502
+ };
4503
+ document.addEventListener("keydown", handler, true);
4504
+ return () => document.removeEventListener("keydown", handler, true);
4505
+ }, [open, onClose, filtered.length, runSelected]);
4506
+ (0, import_react13.useEffect)(() => {
4507
+ const el = listRef.current;
4508
+ if (!el) return;
4509
+ const item = el.querySelector(`[data-index="${safeSelected}"]`);
4510
+ if (item && typeof item.scrollIntoView === "function") {
4511
+ item.scrollIntoView({ block: "nearest", behavior: "smooth" });
4512
+ }
4513
+ }, [safeSelected]);
4514
+ if (!open) return null;
4515
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
4516
+ "div",
4517
+ {
4518
+ ref,
4519
+ className: "fixed inset-0 z-50 flex items-start justify-center pt-[20vh] p-4",
4520
+ role: "dialog",
4521
+ "aria-modal": "true",
4522
+ "aria-label": "Command palette",
4523
+ children: [
4524
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4525
+ "div",
4526
+ {
4527
+ className: "absolute inset-0 bg-black/50 backdrop-blur-sm",
4528
+ onClick: onClose,
4529
+ "aria-hidden": true
4530
+ }
4531
+ ),
4532
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
4533
+ "div",
4534
+ {
4535
+ className: cn("relative z-10 w-full max-w-[calc(100vw-2rem)] sm:max-w-xl overflow-hidden rounded-xl mx-2 sm:mx-0", themeClass, className),
4536
+ style,
4537
+ children: [
4538
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 border-b border-inherit px-3 py-2", children: [
4539
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Search, { className: "size-4 shrink-0 opacity-60", "aria-hidden": true }),
4540
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4541
+ "input",
4542
+ {
4543
+ type: "text",
4544
+ value: query,
4545
+ onChange: (e) => setQuery(e.target.value),
4546
+ placeholder,
4547
+ className: "flex-1 bg-transparent outline-none placeholder:opacity-60",
4548
+ autoFocus: true,
4549
+ "aria-autocomplete": "list",
4550
+ "aria-controls": "command-palette-list",
4551
+ "aria-expanded": "true"
4552
+ }
4553
+ ),
4554
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("kbd", { className: "rounded border border-inherit px-1.5 py-0.5 text-xs opacity-60", children: "ESC" })
4555
+ ] }),
4556
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4557
+ "ul",
4558
+ {
4559
+ ref: listRef,
4560
+ id: "command-palette-list",
4561
+ role: "listbox",
4562
+ className: "max-h-72 overflow-auto py-2",
4563
+ children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("li", { className: "px-4 py-3 text-sm opacity-60", children: "No results." }) : filtered.map((cmd, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("li", { role: "option", "aria-selected": i === safeSelected, "data-index": i, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
4564
+ "button",
4565
+ {
4566
+ type: "button",
4567
+ onClick: () => {
4568
+ cmd.onSelect();
4569
+ onClose();
4570
+ },
4571
+ onMouseEnter: () => setSelected(i),
4572
+ className: `flex w-full items-center justify-between px-4 py-2 text-left text-sm ${i === safeSelected ? "bg-current/10" : ""}`,
4573
+ children: [
4574
+ cmd.label,
4575
+ cmd.shortcut ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("kbd", { className: "rounded border border-inherit px-1.5 py-0.5 text-xs opacity-60", children: cmd.shortcut }) : null
4576
+ ]
4577
+ }
4578
+ ) }, cmd.id))
4579
+ }
4580
+ )
4581
+ ]
4582
+ }
4583
+ )
4584
+ ]
4585
+ }
4586
+ );
4587
+ });
4588
+
4589
+ // components/DashboardShell.tsx
4590
+ var import_react14 = require("react");
4591
+ var import_jsx_runtime12 = require("react/jsx-runtime");
4433
4592
  var SHELL_BG_BY_THEME = {
4434
4593
  minimal: "bg-gradient-to-br from-slate-50 via-zinc-50 to-slate-100",
4435
4594
  night: "bg-zinc-950 text-zinc-100",
@@ -4461,7 +4620,7 @@ function mobileNavLinkStateClasses(theme, active) {
4461
4620
  }
4462
4621
  return active ? "bg-black/5 text-zinc-900" : "text-zinc-600 hover:bg-black/5 hover:text-zinc-900";
4463
4622
  }
4464
- function DashboardShell({
4623
+ var DashboardShell = (0, import_react14.forwardRef)(function DashboardShell2({
4465
4624
  children,
4466
4625
  navItems,
4467
4626
  adminNavItems,
@@ -4470,19 +4629,20 @@ function DashboardShell({
4470
4629
  userRole,
4471
4630
  onLogout,
4472
4631
  logo,
4473
- className
4474
- }) {
4475
- const [mobileOpen, setMobileOpen] = (0, import_react11.useState)(false);
4632
+ className,
4633
+ style
4634
+ }, ref) {
4635
+ const [mobileOpen, setMobileOpen] = (0, import_react14.useState)(false);
4476
4636
  const isAdmin = userRole === "ADMIN";
4477
4637
  const { theme } = useTheme();
4478
4638
  const shellBg = SHELL_BG_BY_THEME[theme];
4479
4639
  const isDarkHeader = darkHeaderThemes.includes(theme);
4480
4640
  const isActive = (href) => currentPath ? currentPath === href || currentPath.startsWith(href) : false;
4481
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: cn("min-h-screen", shellBg, className), children: [
4482
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("header", { className: cn("sticky top-0 z-40", headerClasses(theme)), children: [
4483
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mx-auto flex h-14 max-w-7xl items-center justify-between px-4 sm:px-6 lg:px-8", children: [
4484
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2", children: [
4485
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4641
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { ref, className: cn("min-h-screen", shellBg, className), style, children: [
4642
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("header", { className: cn("sticky top-0 z-40", headerClasses(theme)), children: [
4643
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mx-auto flex h-14 max-w-7xl items-center justify-between px-4 sm:px-6 lg:px-8", children: [
4644
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2", children: [
4645
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4486
4646
  "button",
4487
4647
  {
4488
4648
  type: "button",
@@ -4493,10 +4653,10 @@ function DashboardShell({
4493
4653
  ),
4494
4654
  "aria-label": "Toggle navigation",
4495
4655
  "aria-expanded": mobileOpen,
4496
- children: mobileOpen ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-lg leading-none", children: "\xD7" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-xl leading-none", children: "\u2630" })
4656
+ children: mobileOpen ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-lg leading-none", children: "\xD7" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-xl leading-none", children: "\u2630" })
4497
4657
  }
4498
4658
  ),
4499
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex items-center gap-2", children: logo ?? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4659
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex items-center gap-2", children: logo ?? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4500
4660
  "span",
4501
4661
  {
4502
4662
  className: cn(
@@ -4506,8 +4666,8 @@ function DashboardShell({
4506
4666
  children: "Dashboard"
4507
4667
  }
4508
4668
  ) }),
4509
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("nav", { className: "ml-6 hidden items-center gap-1 text-sm sm:flex", children: [
4510
- navItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4669
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("nav", { className: "ml-6 hidden items-center gap-1 text-sm sm:flex", children: [
4670
+ navItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4511
4671
  "a",
4512
4672
  {
4513
4673
  href: item.href,
@@ -4516,8 +4676,8 @@ function DashboardShell({
4516
4676
  },
4517
4677
  item.href
4518
4678
  )),
4519
- isAdmin && adminNavItems && adminNavItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
4520
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4679
+ isAdmin && adminNavItems && adminNavItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
4680
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4521
4681
  "span",
4522
4682
  {
4523
4683
  className: cn(
@@ -4526,7 +4686,7 @@ function DashboardShell({
4526
4686
  )
4527
4687
  }
4528
4688
  ),
4529
- adminNavItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4689
+ adminNavItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4530
4690
  "a",
4531
4691
  {
4532
4692
  href: item.href,
@@ -4541,8 +4701,8 @@ function DashboardShell({
4541
4701
  ] })
4542
4702
  ] })
4543
4703
  ] }),
4544
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 text-sm", children: [
4545
- userEmail && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4704
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2 text-sm", children: [
4705
+ userEmail && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4546
4706
  "span",
4547
4707
  {
4548
4708
  className: cn(
@@ -4552,7 +4712,7 @@ function DashboardShell({
4552
4712
  children: userEmail
4553
4713
  }
4554
4714
  ),
4555
- onLogout && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4715
+ onLogout && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4556
4716
  "button",
4557
4717
  {
4558
4718
  type: "button",
@@ -4566,8 +4726,8 @@ function DashboardShell({
4566
4726
  )
4567
4727
  ] })
4568
4728
  ] }),
4569
- mobileOpen && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: mobilePanelClasses(theme), children: [
4570
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-1", children: navItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4729
+ mobileOpen && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: mobilePanelClasses(theme), children: [
4730
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-1", children: navItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4571
4731
  "a",
4572
4732
  {
4573
4733
  href: item.href,
@@ -4579,8 +4739,8 @@ function DashboardShell({
4579
4739
  },
4580
4740
  item.href
4581
4741
  )) }),
4582
- isAdmin && adminNavItems && adminNavItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
4583
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4742
+ isAdmin && adminNavItems && adminNavItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
4743
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4584
4744
  "div",
4585
4745
  {
4586
4746
  className: cn(
@@ -4589,7 +4749,7 @@ function DashboardShell({
4589
4749
  )
4590
4750
  }
4591
4751
  ),
4592
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-1", children: adminNavItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4752
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-1", children: adminNavItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4593
4753
  "a",
4594
4754
  {
4595
4755
  href: item.href,
@@ -4602,181 +4762,75 @@ function DashboardShell({
4602
4762
  item.href
4603
4763
  )) })
4604
4764
  ] }),
4605
- userEmail && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4765
+ userEmail && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4606
4766
  "div",
4607
4767
  {
4608
4768
  className: cn(
4609
4769
  "mt-3 border-t pt-3 text-xs",
4610
4770
  isDarkHeader ? "border-zinc-700 text-zinc-400" : "border-zinc-200 text-zinc-500"
4611
- ),
4612
- children: userEmail
4613
- }
4614
- ),
4615
- onLogout && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4616
- "button",
4617
- {
4618
- type: "button",
4619
- onClick: onLogout,
4620
- className: cn(
4621
- "mt-2 w-full rounded-lg px-4 py-2.5 text-left text-sm font-medium transition-colors",
4622
- mobileNavLinkStateClasses(theme, false)
4623
- ),
4624
- children: "Logout"
4625
- }
4626
- )
4627
- ] })
4628
- ] }),
4629
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("main", { className: "mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8", children })
4630
- ] });
4631
- }
4632
-
4633
- // components/CommandPalette.tsx
4634
- var import_react12 = require("react");
4635
- var import_jsx_runtime12 = require("react/jsx-runtime");
4636
- function CommandPalette({
4637
- open,
4638
- onClose,
4639
- commands,
4640
- placeholder = "Type a command...",
4641
- theme: themeProp
4642
- }) {
4643
- const [query, setQuery] = (0, import_react12.useState)("");
4644
- const [selected, setSelected] = (0, import_react12.useState)(0);
4645
- const listRef = (0, import_react12.useRef)(null);
4646
- const { theme: contextTheme } = useTheme();
4647
- const theme = themeProp ?? contextTheme;
4648
- const themeClass = getThemeClass(theme, "commandPalette", "default");
4649
- const filtered = (0, import_react12.useMemo)(() => {
4650
- if (!query.trim()) return commands;
4651
- const q = query.toLowerCase();
4652
- return commands.filter((c) => c.label.toLowerCase().includes(q));
4653
- }, [commands, query]);
4654
- const safeSelected = Math.min(selected, Math.max(0, filtered.length - 1));
4655
- (0, import_react12.useEffect)(() => {
4656
- if (open) {
4657
- setQuery("");
4658
- setSelected(0);
4659
- }
4660
- }, [open]);
4661
- (0, import_react12.useEffect)(() => {
4662
- setSelected((s) => Math.min(s, Math.max(0, filtered.length - 1)));
4663
- }, [filtered.length]);
4664
- const runSelected = (0, import_react12.useCallback)(() => {
4665
- const item = filtered[safeSelected];
4666
- if (item) {
4667
- item.onSelect();
4668
- onClose();
4669
- }
4670
- }, [filtered, safeSelected, onClose]);
4671
- (0, import_react12.useEffect)(() => {
4672
- if (!open) return;
4673
- const handler = (e) => {
4674
- if (e.key === "Escape") {
4675
- e.preventDefault();
4676
- onClose();
4677
- return;
4678
- }
4679
- if (e.key === "ArrowDown") {
4680
- e.preventDefault();
4681
- setSelected((s) => (s + 1) % Math.max(1, filtered.length));
4682
- return;
4683
- }
4684
- if (e.key === "ArrowUp") {
4685
- e.preventDefault();
4686
- setSelected(
4687
- (s) => (s - 1 + filtered.length) % Math.max(1, filtered.length)
4688
- );
4689
- return;
4690
- }
4691
- if (e.key === "Enter") {
4692
- e.preventDefault();
4693
- runSelected();
4694
- }
4695
- };
4696
- document.addEventListener("keydown", handler, true);
4697
- return () => document.removeEventListener("keydown", handler, true);
4698
- }, [open, onClose, filtered.length, runSelected]);
4699
- (0, import_react12.useEffect)(() => {
4700
- const el = listRef.current;
4701
- if (!el) return;
4702
- const item = el.querySelector(`[data-index="${safeSelected}"]`);
4703
- item?.scrollIntoView({ block: "nearest", behavior: "smooth" });
4704
- }, [safeSelected]);
4705
- if (!open) return null;
4706
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4707
- "div",
4708
- {
4709
- className: "fixed inset-0 z-50 flex items-start justify-center pt-[20vh] p-4",
4710
- role: "dialog",
4711
- "aria-modal": "true",
4712
- "aria-label": "Command palette",
4713
- children: [
4714
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4715
- "div",
4716
- {
4717
- className: "absolute inset-0 bg-black/50 backdrop-blur-sm",
4718
- onClick: onClose,
4719
- "aria-hidden": true
4720
- }
4721
- ),
4722
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4723
- "div",
4724
- {
4725
- className: `relative z-10 w-full max-w-[calc(100vw-2rem)] sm:max-w-xl overflow-hidden rounded-xl mx-2 sm:mx-0 ${themeClass}`,
4726
- children: [
4727
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2 border-b border-inherit px-3 py-2", children: [
4728
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Search, { className: "size-4 shrink-0 opacity-60", "aria-hidden": true }),
4729
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4730
- "input",
4731
- {
4732
- type: "text",
4733
- value: query,
4734
- onChange: (e) => setQuery(e.target.value),
4735
- placeholder,
4736
- className: "flex-1 bg-transparent outline-none placeholder:opacity-60",
4737
- autoFocus: true,
4738
- "aria-autocomplete": "list",
4739
- "aria-controls": "command-palette-list",
4740
- "aria-expanded": "true"
4741
- }
4742
- ),
4743
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("kbd", { className: "rounded border border-inherit px-1.5 py-0.5 text-xs opacity-60", children: "ESC" })
4744
- ] }),
4745
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4746
- "ul",
4747
- {
4748
- ref: listRef,
4749
- id: "command-palette-list",
4750
- role: "listbox",
4751
- className: "max-h-72 overflow-auto py-2",
4752
- children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { className: "px-4 py-3 text-sm opacity-60", children: "No results." }) : filtered.map((cmd, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { role: "option", "data-index": i, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4753
- "button",
4754
- {
4755
- type: "button",
4756
- onClick: () => {
4757
- cmd.onSelect();
4758
- onClose();
4759
- },
4760
- onMouseEnter: () => setSelected(i),
4761
- className: `flex w-full items-center justify-between px-4 py-2 text-left text-sm ${i === safeSelected ? "bg-current/10" : ""}`,
4762
- children: [
4763
- cmd.label,
4764
- cmd.shortcut ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("kbd", { className: "rounded border border-inherit px-1.5 py-0.5 text-xs opacity-60", children: cmd.shortcut }) : null
4765
- ]
4766
- }
4767
- ) }, cmd.id))
4768
- }
4769
- )
4770
- ]
4771
+ ),
4772
+ children: userEmail
4773
+ }
4774
+ ),
4775
+ onLogout && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4776
+ "button",
4777
+ {
4778
+ type: "button",
4779
+ onClick: onLogout,
4780
+ className: cn(
4781
+ "mt-2 w-full rounded-lg px-4 py-2.5 text-left text-sm font-medium transition-colors",
4782
+ mobileNavLinkStateClasses(theme, false)
4783
+ ),
4784
+ children: "Logout"
4771
4785
  }
4772
4786
  )
4773
- ]
4787
+ ] })
4788
+ ] }),
4789
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("main", { className: "mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8", children })
4790
+ ] });
4791
+ });
4792
+
4793
+ // components/DataTable.tsx
4794
+ var import_react15 = require("react");
4795
+ var import_jsx_runtime13 = require("react/jsx-runtime");
4796
+ function DataTableInner({ columns, data, getRowKey, className, style }, ref) {
4797
+ const { theme } = useTheme();
4798
+ const themeClass = getThemeClass(theme, "dataTable", "default");
4799
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4800
+ "div",
4801
+ {
4802
+ ref,
4803
+ className: cn(
4804
+ "overflow-x-auto rounded-lg -mx-1 px-1 sm:mx-0 sm:px-0",
4805
+ themeClass,
4806
+ className
4807
+ ),
4808
+ style,
4809
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("table", { className: "w-full min-w-[480px] text-left text-sm", children: [
4810
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("tr", { className: "border-b border-inherit", children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4811
+ "th",
4812
+ {
4813
+ className: "px-4 py-3 font-medium",
4814
+ children: col.header
4815
+ },
4816
+ String(col.key)
4817
+ )) }) }),
4818
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("tbody", { children: data.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4819
+ "tr",
4820
+ {
4821
+ className: "border-b border-inherit last:border-0",
4822
+ children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("td", { className: "px-4 py-3", children: col.render ? col.render(row) : String(row[col.key] ?? "") }, String(col.key)))
4823
+ },
4824
+ getRowKey ? getRowKey(row, i) : i
4825
+ )) })
4826
+ ] })
4774
4827
  }
4775
4828
  );
4776
4829
  }
4830
+ var DataTable = (0, import_react15.forwardRef)(DataTableInner);
4777
4831
 
4778
4832
  // components/DocumentAccordion.tsx
4779
- var import_jsx_runtime13 = require("react/jsx-runtime");
4833
+ var import_jsx_runtime14 = require("react/jsx-runtime");
4780
4834
  function DocumentAccordion({
4781
4835
  title,
4782
4836
  content,
@@ -4791,15 +4845,15 @@ function DocumentAccordion({
4791
4845
  {
4792
4846
  id: "document",
4793
4847
  title,
4794
- content: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4848
+ content: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4795
4849
  "div",
4796
4850
  {
4797
4851
  className: cn(
4798
4852
  "rounded-xl border p-0 shadow-sm backdrop-blur-md",
4799
4853
  theme === "night" || theme === "cyberpunk" ? "border-white/10 bg-zinc-950/80" : "border-black/5 bg-white/60"
4800
4854
  ),
4801
- children: pdfUrl ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3", children: [
4802
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex justify-end px-4 pt-4", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4855
+ children: pdfUrl ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3", children: [
4856
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex justify-end px-4 pt-4", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
4803
4857
  "a",
4804
4858
  {
4805
4859
  href: pdfUrl,
@@ -4810,19 +4864,19 @@ function DocumentAccordion({
4810
4864
  theme === "night" || theme === "cyberpunk" ? "border-white/20 bg-zinc-900/80 text-sky-300 hover:bg-zinc-800/80" : "border-black/5 bg-white/70 text-blue-700 hover:bg-white"
4811
4865
  ),
4812
4866
  children: [
4813
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Open PDF" }),
4814
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { "aria-hidden": true, children: "\u2197" })
4867
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Open PDF" }),
4868
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { "aria-hidden": true, children: "\u2197" })
4815
4869
  ]
4816
4870
  }
4817
4871
  ) }),
4818
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4872
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4819
4873
  "div",
4820
4874
  {
4821
4875
  className: cn(
4822
4876
  "h-[60vh] w-full border-t",
4823
4877
  theme === "night" || theme === "cyberpunk" ? "border-white/10" : "border-black/5"
4824
4878
  ),
4825
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4879
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4826
4880
  "iframe",
4827
4881
  {
4828
4882
  src: `https://docs.google.com/viewer?url=${encodeURIComponent(
@@ -4834,7 +4888,7 @@ function DocumentAccordion({
4834
4888
  )
4835
4889
  }
4836
4890
  )
4837
- ] }) : content ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4891
+ ] }) : content ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4838
4892
  "div",
4839
4893
  {
4840
4894
  className: cn(
@@ -4848,7 +4902,7 @@ function DocumentAccordion({
4848
4902
  )
4849
4903
  }
4850
4904
  ];
4851
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4905
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4852
4906
  Accordion,
4853
4907
  {
4854
4908
  items,
@@ -4860,50 +4914,8 @@ function DocumentAccordion({
4860
4914
  );
4861
4915
  }
4862
4916
 
4863
- // components/DataTable.tsx
4864
- var import_jsx_runtime14 = require("react/jsx-runtime");
4865
- function DataTable({
4866
- columns,
4867
- data,
4868
- getRowKey,
4869
- className,
4870
- style
4871
- }) {
4872
- const { theme } = useTheme();
4873
- const themeClass = getThemeClass(theme, "dataTable", "default");
4874
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4875
- "div",
4876
- {
4877
- className: cn(
4878
- "overflow-x-auto rounded-lg -mx-1 px-1 sm:mx-0 sm:px-0",
4879
- themeClass,
4880
- className
4881
- ),
4882
- style,
4883
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("table", { className: "w-full min-w-[480px] text-left text-sm", children: [
4884
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tr", { className: "border-b border-inherit", children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4885
- "th",
4886
- {
4887
- className: "px-4 py-3 font-medium",
4888
- children: col.header
4889
- },
4890
- String(col.key)
4891
- )) }) }),
4892
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tbody", { children: data.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4893
- "tr",
4894
- {
4895
- className: "border-b border-inherit last:border-0",
4896
- children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("td", { className: "px-4 py-3", children: col.render ? col.render(row) : String(row[col.key] ?? "") }, String(col.key)))
4897
- },
4898
- getRowKey ? getRowKey(row, i) : i
4899
- )) })
4900
- ] })
4901
- }
4902
- );
4903
- }
4904
-
4905
4917
  // src/hooks/useKeyboardNavigation.ts
4906
- var import_react13 = require("react");
4918
+ var import_react16 = require("react");
4907
4919
  function useKeyboardNavigation(options) {
4908
4920
  const {
4909
4921
  onEscape,
@@ -4913,7 +4925,7 @@ function useKeyboardNavigation(options) {
4913
4925
  onArrowRight,
4914
4926
  enabled = true
4915
4927
  } = options;
4916
- const handleKeyDown = (0, import_react13.useCallback)(
4928
+ const handleKeyDown = (0, import_react16.useCallback)(
4917
4929
  (e) => {
4918
4930
  if (!enabled) return;
4919
4931
  if (e.key === "Escape") {
@@ -4938,7 +4950,7 @@ function useKeyboardNavigation(options) {
4938
4950
  },
4939
4951
  [enabled, onEscape, onArrowDown, onArrowUp, onArrowLeft, onArrowRight]
4940
4952
  );
4941
- (0, import_react13.useEffect)(() => {
4953
+ (0, import_react16.useEffect)(() => {
4942
4954
  if (!enabled) return;
4943
4955
  document.addEventListener("keydown", handleKeyDown, true);
4944
4956
  return () => document.removeEventListener("keydown", handleKeyDown, true);
@@ -4953,10 +4965,10 @@ function getNextListIndex(current, direction, length) {
4953
4965
  }
4954
4966
 
4955
4967
  // src/hooks/useClickOutside.ts
4956
- var import_react14 = require("react");
4968
+ var import_react17 = require("react");
4957
4969
  function useClickOutside(ref, handler, options) {
4958
4970
  const enabled = options?.enabled !== false;
4959
- const handle = (0, import_react14.useCallback)(
4971
+ const handle = (0, import_react17.useCallback)(
4960
4972
  (e) => {
4961
4973
  const target = e.target;
4962
4974
  const refs = Array.isArray(ref) ? ref : [ref];
@@ -4967,7 +4979,7 @@ function useClickOutside(ref, handler, options) {
4967
4979
  },
4968
4980
  [ref, handler]
4969
4981
  );
4970
- (0, import_react14.useEffect)(() => {
4982
+ (0, import_react17.useEffect)(() => {
4971
4983
  if (!enabled) return;
4972
4984
  document.addEventListener("mousedown", handle);
4973
4985
  document.addEventListener("touchstart", handle);
@@ -4979,14 +4991,14 @@ function useClickOutside(ref, handler, options) {
4979
4991
  }
4980
4992
 
4981
4993
  // components/Dropdown.tsx
4982
- var import_react15 = require("react");
4994
+ var import_react18 = require("react");
4983
4995
  var import_react_dom = require("react-dom");
4984
4996
  var import_jsx_runtime15 = require("react/jsx-runtime");
4985
4997
  function dropdownItemHighlightClass(theme) {
4986
4998
  const darkThemes = ["night", "cyberpunk"];
4987
4999
  return darkThemes.includes(theme) ? "hover:bg-white/10 focus:bg-white/10" : "hover:bg-black/5 focus:bg-black/5";
4988
5000
  }
4989
- function Dropdown({
5001
+ var Dropdown = (0, import_react18.forwardRef)(function Dropdown2({
4990
5002
  trigger: triggerProp,
4991
5003
  placeholder = "Select\u2026",
4992
5004
  items,
@@ -4998,21 +5010,22 @@ function Dropdown({
4998
5010
  style,
4999
5011
  theme: themeProp,
5000
5012
  classNames = {}
5001
- }) {
5002
- const [open, setOpen] = (0, import_react15.useState)(false);
5003
- const [uncontrolledValue, setUncontrolledValue] = (0, import_react15.useState)(defaultValue ?? "");
5013
+ }, ref) {
5014
+ const [open, setOpen] = (0, import_react18.useState)(false);
5015
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react18.useState)(defaultValue ?? "");
5004
5016
  const isControlled = controlledValue !== void 0;
5005
5017
  const displayValue = isControlled ? controlledValue : uncontrolledValue;
5006
- const [highlightedIndex, setHighlightedIndex] = (0, import_react15.useState)(-1);
5007
- const [popoverStyle, setPopoverStyle] = (0, import_react15.useState)({});
5008
- const listRef = (0, import_react15.useRef)(null);
5009
- const containerRef = (0, import_react15.useRef)(null);
5010
- const triggerRef = (0, import_react15.useRef)(null);
5018
+ const [highlightedIndex, setHighlightedIndex] = (0, import_react18.useState)(-1);
5019
+ const [popoverStyle, setPopoverStyle] = (0, import_react18.useState)({});
5020
+ const listRef = (0, import_react18.useRef)(null);
5021
+ const containerRef = (0, import_react18.useRef)(null);
5022
+ const triggerRef = (0, import_react18.useRef)(null);
5023
+ const mergedContainerRef = mergeRefs(ref, containerRef);
5011
5024
  const { theme: contextTheme } = useTheme();
5012
5025
  const theme = themeProp ?? contextTheme;
5013
5026
  const themeClass = getThemeClass(theme, "card", "default");
5014
5027
  const itemHighlightClass = dropdownItemHighlightClass(theme);
5015
- const updatePosition = (0, import_react15.useCallback)(() => {
5028
+ const updatePosition = (0, import_react18.useCallback)(() => {
5016
5029
  const triggerEl = triggerRef.current;
5017
5030
  if (!triggerEl) return;
5018
5031
  const rect = triggerEl.getBoundingClientRect();
@@ -5028,15 +5041,15 @@ function Dropdown({
5028
5041
  zIndex: 9999
5029
5042
  });
5030
5043
  }, []);
5031
- (0, import_react15.useLayoutEffect)(() => {
5044
+ (0, import_react18.useLayoutEffect)(() => {
5032
5045
  if (open && !disabled) {
5033
5046
  updatePosition();
5034
5047
  }
5035
5048
  }, [open, disabled, updatePosition, items.length]);
5036
- (0, import_react15.useEffect)(() => {
5049
+ (0, import_react18.useEffect)(() => {
5037
5050
  if (disabled && open) setOpen(false);
5038
5051
  }, [disabled, open]);
5039
- (0, import_react15.useEffect)(() => {
5052
+ (0, import_react18.useEffect)(() => {
5040
5053
  if (!open) return;
5041
5054
  const onScrollOrResize = () => updatePosition();
5042
5055
  window.addEventListener("scroll", onScrollOrResize, true);
@@ -5048,17 +5061,17 @@ function Dropdown({
5048
5061
  }, [open, updatePosition]);
5049
5062
  useClickOutside(
5050
5063
  [containerRef, listRef],
5051
- (0, import_react15.useCallback)(() => setOpen(false), []),
5064
+ (0, import_react18.useCallback)(() => setOpen(false), []),
5052
5065
  { enabled: open }
5053
5066
  );
5054
- const setValue = (0, import_react15.useCallback)(
5067
+ const setValue = (0, import_react18.useCallback)(
5055
5068
  (v) => {
5056
5069
  if (!isControlled) setUncontrolledValue(v);
5057
5070
  onValueChange?.(v);
5058
5071
  },
5059
5072
  [isControlled, onValueChange]
5060
5073
  );
5061
- const selectIndex = (0, import_react15.useCallback)(
5074
+ const selectIndex = (0, import_react18.useCallback)(
5062
5075
  (index) => {
5063
5076
  const item = items[index];
5064
5077
  if (item?.disabled) return;
@@ -5068,7 +5081,7 @@ function Dropdown({
5068
5081
  },
5069
5082
  [items, setValue]
5070
5083
  );
5071
- (0, import_react15.useEffect)(() => {
5084
+ (0, import_react18.useEffect)(() => {
5072
5085
  if (!open) {
5073
5086
  setHighlightedIndex(-1);
5074
5087
  return;
@@ -5076,7 +5089,7 @@ function Dropdown({
5076
5089
  const current = items.findIndex((i) => i.value === displayValue);
5077
5090
  setHighlightedIndex(current >= 0 ? current : 0);
5078
5091
  }, [open, displayValue, items]);
5079
- const handleKeyDown = (0, import_react15.useCallback)(
5092
+ const handleKeyDown = (0, import_react18.useCallback)(
5080
5093
  (e) => {
5081
5094
  if (disabled) return;
5082
5095
  if (!open) {
@@ -5167,7 +5180,7 @@ function Dropdown({
5167
5180
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
5168
5181
  "div",
5169
5182
  {
5170
- ref: containerRef,
5183
+ ref: mergedContainerRef,
5171
5184
  className: cn("relative inline-block", className),
5172
5185
  style,
5173
5186
  onKeyDown: handleKeyDown,
@@ -5191,19 +5204,19 @@ function Dropdown({
5191
5204
  ]
5192
5205
  }
5193
5206
  );
5194
- }
5207
+ });
5195
5208
 
5196
5209
  // components/Flashcard.tsx
5197
- var import_react35 = require("react");
5210
+ var import_react38 = require("react");
5198
5211
 
5199
5212
  // node_modules/framer-motion/dist/es/context/LayoutGroupContext.mjs
5200
- var import_react16 = require("react");
5201
- var LayoutGroupContext = (0, import_react16.createContext)({});
5213
+ var import_react19 = require("react");
5214
+ var LayoutGroupContext = (0, import_react19.createContext)({});
5202
5215
 
5203
5216
  // node_modules/framer-motion/dist/es/utils/use-constant.mjs
5204
- var import_react17 = require("react");
5217
+ var import_react20 = require("react");
5205
5218
  function useConstant(init) {
5206
- const ref = (0, import_react17.useRef)(null);
5219
+ const ref = (0, import_react20.useRef)(null);
5207
5220
  if (ref.current === null) {
5208
5221
  ref.current = init();
5209
5222
  }
@@ -5211,41 +5224,41 @@ function useConstant(init) {
5211
5224
  }
5212
5225
 
5213
5226
  // node_modules/framer-motion/dist/es/context/PresenceContext.mjs
5214
- var import_react18 = require("react");
5215
- var PresenceContext = (0, import_react18.createContext)(null);
5227
+ var import_react21 = require("react");
5228
+ var PresenceContext = (0, import_react21.createContext)(null);
5216
5229
 
5217
5230
  // node_modules/framer-motion/dist/es/context/MotionConfigContext.mjs
5218
- var import_react19 = require("react");
5219
- var MotionConfigContext = (0, import_react19.createContext)({
5231
+ var import_react22 = require("react");
5232
+ var MotionConfigContext = (0, import_react22.createContext)({
5220
5233
  transformPagePoint: (p) => p,
5221
5234
  isStatic: false,
5222
5235
  reducedMotion: "never"
5223
5236
  });
5224
5237
 
5225
5238
  // node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.mjs
5226
- var import_react20 = require("react");
5239
+ var import_react23 = require("react");
5227
5240
  function usePresence(subscribe = true) {
5228
- const context = (0, import_react20.useContext)(PresenceContext);
5241
+ const context = (0, import_react23.useContext)(PresenceContext);
5229
5242
  if (context === null)
5230
5243
  return [true, null];
5231
5244
  const { isPresent, onExitComplete, register } = context;
5232
- const id3 = (0, import_react20.useId)();
5233
- (0, import_react20.useEffect)(() => {
5245
+ const id3 = (0, import_react23.useId)();
5246
+ (0, import_react23.useEffect)(() => {
5234
5247
  if (subscribe)
5235
5248
  register(id3);
5236
5249
  }, [subscribe]);
5237
- const safeToRemove = (0, import_react20.useCallback)(() => subscribe && onExitComplete && onExitComplete(id3), [id3, onExitComplete, subscribe]);
5250
+ const safeToRemove = (0, import_react23.useCallback)(() => subscribe && onExitComplete && onExitComplete(id3), [id3, onExitComplete, subscribe]);
5238
5251
  return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
5239
5252
  }
5240
5253
 
5241
5254
  // node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.mjs
5242
- var import_react21 = require("react");
5255
+ var import_react24 = require("react");
5243
5256
 
5244
5257
  // node_modules/framer-motion/dist/es/utils/is-browser.mjs
5245
5258
  var isBrowser = typeof window !== "undefined";
5246
5259
 
5247
5260
  // node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.mjs
5248
- var useIsomorphicLayoutEffect = isBrowser ? import_react21.useLayoutEffect : import_react21.useEffect;
5261
+ var useIsomorphicLayoutEffect = isBrowser ? import_react24.useLayoutEffect : import_react24.useEffect;
5249
5262
 
5250
5263
  // node_modules/motion-utils/dist/es/noop.mjs
5251
5264
  var noop = /* @__NO_SIDE_EFFECTS__ */ (any) => any;
@@ -5431,8 +5444,8 @@ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
5431
5444
  var { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps } = createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
5432
5445
 
5433
5446
  // node_modules/framer-motion/dist/es/context/LazyContext.mjs
5434
- var import_react22 = require("react");
5435
- var LazyContext = (0, import_react22.createContext)({ strict: false });
5447
+ var import_react25 = require("react");
5448
+ var LazyContext = (0, import_react25.createContext)({ strict: false });
5436
5449
 
5437
5450
  // node_modules/framer-motion/dist/es/motion/features/definitions.mjs
5438
5451
  var featureProps = {
@@ -5575,14 +5588,14 @@ function createDOMMotionComponentProxy(componentFactory) {
5575
5588
 
5576
5589
  // node_modules/framer-motion/dist/es/motion/index.mjs
5577
5590
  var import_jsx_runtime16 = require("react/jsx-runtime");
5578
- var import_react28 = require("react");
5591
+ var import_react31 = require("react");
5579
5592
 
5580
5593
  // node_modules/framer-motion/dist/es/context/MotionContext/index.mjs
5581
- var import_react23 = require("react");
5582
- var MotionContext = (0, import_react23.createContext)({});
5594
+ var import_react26 = require("react");
5595
+ var MotionContext = (0, import_react26.createContext)({});
5583
5596
 
5584
5597
  // node_modules/framer-motion/dist/es/context/MotionContext/create.mjs
5585
- var import_react24 = require("react");
5598
+ var import_react27 = require("react");
5586
5599
 
5587
5600
  // node_modules/framer-motion/dist/es/render/utils/is-variant-label.mjs
5588
5601
  function isVariantLabel(v) {
@@ -5628,8 +5641,8 @@ function getCurrentTreeVariants(props, context) {
5628
5641
 
5629
5642
  // node_modules/framer-motion/dist/es/context/MotionContext/create.mjs
5630
5643
  function useCreateMotionContext(props) {
5631
- const { initial, animate } = getCurrentTreeVariants(props, (0, import_react24.useContext)(MotionContext));
5632
- return (0, import_react24.useMemo)(() => ({ initial, animate }), [variantLabelsAsDependency(initial), variantLabelsAsDependency(animate)]);
5644
+ const { initial, animate } = getCurrentTreeVariants(props, (0, import_react27.useContext)(MotionContext));
5645
+ return (0, import_react27.useMemo)(() => ({ initial, animate }), [variantLabelsAsDependency(initial), variantLabelsAsDependency(animate)]);
5633
5646
  }
5634
5647
  function variantLabelsAsDependency(prop) {
5635
5648
  return Array.isArray(prop) ? prop.join(" ") : prop;
@@ -5639,7 +5652,7 @@ function variantLabelsAsDependency(prop) {
5639
5652
  var motionComponentSymbol = /* @__PURE__ */ Symbol.for("motionComponentSymbol");
5640
5653
 
5641
5654
  // node_modules/framer-motion/dist/es/motion/utils/use-motion-ref.mjs
5642
- var import_react25 = require("react");
5655
+ var import_react28 = require("react");
5643
5656
 
5644
5657
  // node_modules/framer-motion/dist/es/utils/is-ref-object.mjs
5645
5658
  function isRefObject(ref) {
@@ -5648,7 +5661,7 @@ function isRefObject(ref) {
5648
5661
 
5649
5662
  // node_modules/framer-motion/dist/es/motion/utils/use-motion-ref.mjs
5650
5663
  function useMotionRef(visualState, visualElement, externalRef) {
5651
- return (0, import_react25.useCallback)(
5664
+ return (0, import_react28.useCallback)(
5652
5665
  (instance) => {
5653
5666
  if (instance) {
5654
5667
  visualState.onMount && visualState.onMount(instance);
@@ -5678,7 +5691,7 @@ function useMotionRef(visualState, visualElement, externalRef) {
5678
5691
  }
5679
5692
 
5680
5693
  // node_modules/framer-motion/dist/es/motion/utils/use-visual-element.mjs
5681
- var import_react27 = require("react");
5694
+ var import_react30 = require("react");
5682
5695
 
5683
5696
  // node_modules/framer-motion/dist/es/render/dom/utils/camel-to-dash.mjs
5684
5697
  var camelToDash = (str) => str.replace(/([a-z])([A-Z])/gu, "$1-$2").toLowerCase();
@@ -5691,17 +5704,17 @@ var optimizedAppearDataAttribute = "data-" + camelToDash(optimizedAppearDataId);
5691
5704
  var { schedule: microtask, cancel: cancelMicrotask } = createRenderBatcher(queueMicrotask, false);
5692
5705
 
5693
5706
  // node_modules/framer-motion/dist/es/context/SwitchLayoutGroupContext.mjs
5694
- var import_react26 = require("react");
5695
- var SwitchLayoutGroupContext = (0, import_react26.createContext)({});
5707
+ var import_react29 = require("react");
5708
+ var SwitchLayoutGroupContext = (0, import_react29.createContext)({});
5696
5709
 
5697
5710
  // node_modules/framer-motion/dist/es/motion/utils/use-visual-element.mjs
5698
5711
  function useVisualElement(Component2, visualState, props, createVisualElement, ProjectionNodeConstructor) {
5699
5712
  var _a, _b;
5700
- const { visualElement: parent } = (0, import_react27.useContext)(MotionContext);
5701
- const lazyContext = (0, import_react27.useContext)(LazyContext);
5702
- const presenceContext = (0, import_react27.useContext)(PresenceContext);
5703
- const reducedMotionConfig = (0, import_react27.useContext)(MotionConfigContext).reducedMotion;
5704
- const visualElementRef = (0, import_react27.useRef)(null);
5713
+ const { visualElement: parent } = (0, import_react30.useContext)(MotionContext);
5714
+ const lazyContext = (0, import_react30.useContext)(LazyContext);
5715
+ const presenceContext = (0, import_react30.useContext)(PresenceContext);
5716
+ const reducedMotionConfig = (0, import_react30.useContext)(MotionConfigContext).reducedMotion;
5717
+ const visualElementRef = (0, import_react30.useRef)(null);
5705
5718
  createVisualElement = createVisualElement || lazyContext.renderer;
5706
5719
  if (!visualElementRef.current && createVisualElement) {
5707
5720
  visualElementRef.current = createVisualElement(Component2, {
@@ -5714,18 +5727,18 @@ function useVisualElement(Component2, visualState, props, createVisualElement, P
5714
5727
  });
5715
5728
  }
5716
5729
  const visualElement = visualElementRef.current;
5717
- const initialLayoutGroupConfig = (0, import_react27.useContext)(SwitchLayoutGroupContext);
5730
+ const initialLayoutGroupConfig = (0, import_react30.useContext)(SwitchLayoutGroupContext);
5718
5731
  if (visualElement && !visualElement.projection && ProjectionNodeConstructor && (visualElement.type === "html" || visualElement.type === "svg")) {
5719
5732
  createProjectionNode(visualElementRef.current, props, ProjectionNodeConstructor, initialLayoutGroupConfig);
5720
5733
  }
5721
- const isMounted = (0, import_react27.useRef)(false);
5722
- (0, import_react27.useInsertionEffect)(() => {
5734
+ const isMounted = (0, import_react30.useRef)(false);
5735
+ (0, import_react30.useInsertionEffect)(() => {
5723
5736
  if (visualElement && isMounted.current) {
5724
5737
  visualElement.update(props, presenceContext);
5725
5738
  }
5726
5739
  });
5727
5740
  const optimisedAppearId = props[optimizedAppearDataAttribute];
5728
- const wantsHandoff = (0, import_react27.useRef)(Boolean(optimisedAppearId) && !((_a = window.MotionHandoffIsComplete) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId)) && ((_b = window.MotionHasOptimisedAnimation) === null || _b === void 0 ? void 0 : _b.call(window, optimisedAppearId)));
5741
+ const wantsHandoff = (0, import_react30.useRef)(Boolean(optimisedAppearId) && !((_a = window.MotionHandoffIsComplete) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId)) && ((_b = window.MotionHasOptimisedAnimation) === null || _b === void 0 ? void 0 : _b.call(window, optimisedAppearId)));
5729
5742
  useIsomorphicLayoutEffect(() => {
5730
5743
  if (!visualElement)
5731
5744
  return;
@@ -5737,7 +5750,7 @@ function useVisualElement(Component2, visualState, props, createVisualElement, P
5737
5750
  visualElement.animationState.animateChanges();
5738
5751
  }
5739
5752
  });
5740
- (0, import_react27.useEffect)(() => {
5753
+ (0, import_react30.useEffect)(() => {
5741
5754
  if (!visualElement)
5742
5755
  return;
5743
5756
  if (!wantsHandoff.current && visualElement.animationState) {
@@ -5787,7 +5800,7 @@ function createRendererMotionComponent({ preloadedFeatures, createVisualElement,
5787
5800
  function MotionComponent(props, externalRef) {
5788
5801
  let MeasureLayout2;
5789
5802
  const configAndProps = {
5790
- ...(0, import_react28.useContext)(MotionConfigContext),
5803
+ ...(0, import_react31.useContext)(MotionConfigContext),
5791
5804
  ...props,
5792
5805
  layoutId: useLayoutId(props)
5793
5806
  };
@@ -5803,16 +5816,16 @@ function createRendererMotionComponent({ preloadedFeatures, createVisualElement,
5803
5816
  return (0, import_jsx_runtime16.jsxs)(MotionContext.Provider, { value: context, children: [MeasureLayout2 && context.visualElement ? (0, import_jsx_runtime16.jsx)(MeasureLayout2, { visualElement: context.visualElement, ...configAndProps }) : null, useRender(Component2, props, useMotionRef(visualState, context.visualElement, externalRef), visualState, isStatic, context.visualElement)] });
5804
5817
  }
5805
5818
  MotionComponent.displayName = `motion.${typeof Component2 === "string" ? Component2 : `create(${(_b = (_a = Component2.displayName) !== null && _a !== void 0 ? _a : Component2.name) !== null && _b !== void 0 ? _b : ""})`}`;
5806
- const ForwardRefMotionComponent = (0, import_react28.forwardRef)(MotionComponent);
5819
+ const ForwardRefMotionComponent = (0, import_react31.forwardRef)(MotionComponent);
5807
5820
  ForwardRefMotionComponent[motionComponentSymbol] = Component2;
5808
5821
  return ForwardRefMotionComponent;
5809
5822
  }
5810
5823
  function useLayoutId({ layoutId }) {
5811
- const layoutGroupId = (0, import_react28.useContext)(LayoutGroupContext).id;
5824
+ const layoutGroupId = (0, import_react31.useContext)(LayoutGroupContext).id;
5812
5825
  return layoutGroupId && layoutId !== void 0 ? layoutGroupId + "-" + layoutId : layoutId;
5813
5826
  }
5814
5827
  function useStrictMode(configAndProps, preloadedFeatures) {
5815
- const isStrict = (0, import_react28.useContext)(LazyContext).strict;
5828
+ const isStrict = (0, import_react31.useContext)(LazyContext).strict;
5816
5829
  if (process.env.NODE_ENV !== "production" && preloadedFeatures && isStrict) {
5817
5830
  const strictMessage = "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.";
5818
5831
  configAndProps.ignoreStrict ? warning(false, strictMessage) : invariant(false, strictMessage);
@@ -5886,7 +5899,7 @@ function isSVGComponent(Component2) {
5886
5899
  }
5887
5900
 
5888
5901
  // node_modules/framer-motion/dist/es/motion/utils/use-visual-state.mjs
5889
- var import_react29 = require("react");
5902
+ var import_react32 = require("react");
5890
5903
 
5891
5904
  // node_modules/framer-motion/dist/es/render/utils/resolve-variants.mjs
5892
5905
  function getValueState(visualElement) {
@@ -5947,8 +5960,8 @@ function makeState({ scrapeMotionValuesFromProps: scrapeMotionValuesFromProps3,
5947
5960
  return state;
5948
5961
  }
5949
5962
  var makeUseVisualState = (config) => (props, isStatic) => {
5950
- const context = (0, import_react29.useContext)(MotionContext);
5951
- const presenceContext = (0, import_react29.useContext)(PresenceContext);
5963
+ const context = (0, import_react32.useContext)(MotionContext);
5964
+ const presenceContext = (0, import_react32.useContext)(PresenceContext);
5952
5965
  const make = () => makeState(config, props, context, presenceContext);
5953
5966
  return isStatic ? make() : useConstant(make);
5954
5967
  };
@@ -6468,10 +6481,10 @@ var htmlMotionConfig = {
6468
6481
  };
6469
6482
 
6470
6483
  // node_modules/framer-motion/dist/es/render/dom/use-render.mjs
6471
- var import_react32 = require("react");
6484
+ var import_react35 = require("react");
6472
6485
 
6473
6486
  // node_modules/framer-motion/dist/es/render/html/use-props.mjs
6474
- var import_react30 = require("react");
6487
+ var import_react33 = require("react");
6475
6488
  function copyRawValuesOnly(target, source, props) {
6476
6489
  for (const key in source) {
6477
6490
  if (!isMotionValue(source[key]) && !isForcedMotionValue(key, props)) {
@@ -6480,7 +6493,7 @@ function copyRawValuesOnly(target, source, props) {
6480
6493
  }
6481
6494
  }
6482
6495
  function useInitialMotionValues({ transformTemplate }, visualState) {
6483
- return (0, import_react30.useMemo)(() => {
6496
+ return (0, import_react33.useMemo)(() => {
6484
6497
  const state = createHtmlRenderState();
6485
6498
  buildHTMLStyles(state, visualState, transformTemplate);
6486
6499
  return Object.assign({}, state.vars, state.style);
@@ -6509,9 +6522,9 @@ function useHTMLProps(props, visualState) {
6509
6522
  }
6510
6523
 
6511
6524
  // node_modules/framer-motion/dist/es/render/svg/use-props.mjs
6512
- var import_react31 = require("react");
6525
+ var import_react34 = require("react");
6513
6526
  function useSVGProps(props, visualState, _isStatic, Component2) {
6514
- const visualProps = (0, import_react31.useMemo)(() => {
6527
+ const visualProps = (0, import_react34.useMemo)(() => {
6515
6528
  const state = createSvgRenderState();
6516
6529
  buildSVGAttrs(state, visualState, isSVGTag(Component2), props.transformTemplate);
6517
6530
  return {
@@ -6533,10 +6546,10 @@ function createUseRender(forwardMotionProps = false) {
6533
6546
  const useVisualProps = isSVGComponent(Component2) ? useSVGProps : useHTMLProps;
6534
6547
  const visualProps = useVisualProps(props, latestValues, isStatic, Component2);
6535
6548
  const filteredProps = filterProps(props, typeof Component2 === "string", forwardMotionProps);
6536
- const elementProps = Component2 !== import_react32.Fragment ? { ...filteredProps, ...visualProps, ref } : {};
6549
+ const elementProps = Component2 !== import_react35.Fragment ? { ...filteredProps, ...visualProps, ref } : {};
6537
6550
  const { children } = props;
6538
- const renderedChildren = (0, import_react32.useMemo)(() => isMotionValue(children) ? children.get() : children, [children]);
6539
- return (0, import_react32.createElement)(Component2, {
6551
+ const renderedChildren = (0, import_react35.useMemo)(() => isMotionValue(children) ? children.get() : children, [children]);
6552
+ return (0, import_react35.createElement)(Component2, {
6540
6553
  ...elementProps,
6541
6554
  children: renderedChildren
6542
6555
  });
@@ -10590,7 +10603,7 @@ var PanGesture = class extends Feature {
10590
10603
 
10591
10604
  // node_modules/framer-motion/dist/es/motion/features/layout/MeasureLayout.mjs
10592
10605
  var import_jsx_runtime17 = require("react/jsx-runtime");
10593
- var import_react33 = require("react");
10606
+ var import_react36 = require("react");
10594
10607
 
10595
10608
  // node_modules/framer-motion/dist/es/projection/node/state.mjs
10596
10609
  var globalProjectionState = {
@@ -10652,7 +10665,7 @@ var correctBoxShadow = {
10652
10665
  };
10653
10666
 
10654
10667
  // node_modules/framer-motion/dist/es/motion/features/layout/MeasureLayout.mjs
10655
- var MeasureLayoutWithContext = class extends import_react33.Component {
10668
+ var MeasureLayoutWithContext = class extends import_react36.Component {
10656
10669
  /**
10657
10670
  * This only mounts projection nodes for components that
10658
10671
  * need measuring, we might want to do it for all components
@@ -10736,8 +10749,8 @@ var MeasureLayoutWithContext = class extends import_react33.Component {
10736
10749
  };
10737
10750
  function MeasureLayout(props) {
10738
10751
  const [isPresent, safeToRemove] = usePresence();
10739
- const layoutGroup = (0, import_react33.useContext)(LayoutGroupContext);
10740
- return (0, import_jsx_runtime17.jsx)(MeasureLayoutWithContext, { ...props, layoutGroup, switchLayoutGroup: (0, import_react33.useContext)(SwitchLayoutGroupContext), isPresent, safeToRemove });
10752
+ const layoutGroup = (0, import_react36.useContext)(LayoutGroupContext);
10753
+ return (0, import_jsx_runtime17.jsx)(MeasureLayoutWithContext, { ...props, layoutGroup, switchLayoutGroup: (0, import_react36.useContext)(SwitchLayoutGroupContext), isPresent, safeToRemove });
10741
10754
  }
10742
10755
  var defaultScaleCorrectors = {
10743
10756
  borderRadius: {
@@ -12359,7 +12372,7 @@ var layout = {
12359
12372
  };
12360
12373
 
12361
12374
  // node_modules/framer-motion/dist/es/render/dom/create-visual-element.mjs
12362
- var import_react34 = require("react");
12375
+ var import_react37 = require("react");
12363
12376
 
12364
12377
  // node_modules/framer-motion/dist/es/utils/reduced-motion/state.mjs
12365
12378
  var prefersReducedMotion = { current: null };
@@ -12872,7 +12885,7 @@ var SVGVisualElement = class extends DOMVisualElement {
12872
12885
  // node_modules/framer-motion/dist/es/render/dom/create-visual-element.mjs
12873
12886
  var createDomVisualElement = (Component2, options) => {
12874
12887
  return isSVGComponent(Component2) ? new SVGVisualElement(options) : new HTMLVisualElement(options, {
12875
- allowProjection: Component2 !== import_react34.Fragment
12888
+ allowProjection: Component2 !== import_react37.Fragment
12876
12889
  });
12877
12890
  };
12878
12891
 
@@ -12888,6 +12901,7 @@ var createMotionComponent = /* @__PURE__ */ createMotionComponentFactory({
12888
12901
  var motion = /* @__PURE__ */ createDOMMotionComponentProxy(createMotionComponent);
12889
12902
 
12890
12903
  // components/Flashcard.tsx
12904
+ var import_react39 = require("react");
12891
12905
  var import_jsx_runtime18 = require("react/jsx-runtime");
12892
12906
  var FRONT_BY_THEME = {
12893
12907
  minimal: "border-black/5 bg-gradient-to-br from-white to-zinc-50 text-zinc-900 shadow-[0_4px_20px_-4px_rgba(0,0,0,0.1)]",
@@ -12909,17 +12923,13 @@ var BACK_BY_THEME = {
12909
12923
  retro: "from-zinc-800 to-black text-lime-400 font-mono",
12910
12924
  motion: "from-indigo-600 via-purple-600 to-indigo-700 text-white transition-all duration-500"
12911
12925
  };
12912
- function Flashcard({
12913
- question,
12914
- answer,
12915
- className,
12916
- ...props
12917
- }) {
12918
- const [isFlipped, setIsFlipped] = (0, import_react35.useState)(false);
12926
+ var Flashcard = (0, import_react39.forwardRef)(function Flashcard2({ question, answer, className, ...props }, ref) {
12927
+ const [isFlipped, setIsFlipped] = (0, import_react38.useState)(false);
12919
12928
  const { theme } = useTheme();
12920
12929
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12921
12930
  "div",
12922
12931
  {
12932
+ ref,
12923
12933
  className: cn(
12924
12934
  "group relative h-64 w-full cursor-pointer [perspective:1000px]",
12925
12935
  className
@@ -12975,9 +12985,10 @@ function Flashcard({
12975
12985
  )
12976
12986
  }
12977
12987
  );
12978
- }
12988
+ });
12979
12989
 
12980
12990
  // components/GraphicCard.tsx
12991
+ var import_react40 = require("react");
12981
12992
  var import_jsx_runtime19 = require("react/jsx-runtime");
12982
12993
  var SURFACE_BY_THEME = {
12983
12994
  minimal: "bg-gradient-to-br from-white to-zinc-50 border-black/5 shadow-[0_4px_20px_-4px_rgba(0,0,0,0.08)] hover:shadow-[0_10px_40px_-6px_rgba(0,0,0,0.18)]",
@@ -12989,11 +13000,7 @@ var SURFACE_BY_THEME = {
12989
13000
  retro: "bg-white border-2 border-black font-mono shadow-[4px_4px_0_0_rgba(0,0,0,1)]",
12990
13001
  motion: "bg-white border-2 border-indigo-200 shadow-lg transition-all duration-300 hover:scale-[1.02] hover:shadow-xl hover:border-indigo-300 hover:-translate-y-0.5"
12991
13002
  };
12992
- function GraphicCard({
12993
- children,
12994
- className,
12995
- ...props
12996
- }) {
13003
+ var GraphicCard = (0, import_react40.forwardRef)(function GraphicCard2({ children, className, ...props }, ref) {
12997
13004
  const { theme } = useTheme();
12998
13005
  const surface = SURFACE_BY_THEME[theme];
12999
13006
  const isDark = theme === "night" || theme === "cyberpunk";
@@ -13002,6 +13009,7 @@ function GraphicCard({
13002
13009
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
13003
13010
  "div",
13004
13011
  {
13012
+ ref,
13005
13013
  className: cn(
13006
13014
  "group relative w-full overflow-hidden rounded-2xl p-6 transition-all duration-300",
13007
13015
  surface,
@@ -13015,10 +13023,10 @@ function GraphicCard({
13015
13023
  ]
13016
13024
  }
13017
13025
  );
13018
- }
13026
+ });
13019
13027
 
13020
13028
  // components/Input.tsx
13021
- var import_react36 = require("react");
13029
+ var import_react41 = require("react");
13022
13030
  var import_jsx_runtime20 = require("react/jsx-runtime");
13023
13031
  var inputVariants = cva(
13024
13032
  "w-full rounded-lg px-3 py-2 text-sm outline-none transition-shadow",
@@ -13035,7 +13043,7 @@ var inputVariants = cva(
13035
13043
  }
13036
13044
  }
13037
13045
  );
13038
- var Input = (0, import_react36.forwardRef)(function Input2({
13046
+ var Input = (0, import_react41.forwardRef)(function Input2({
13039
13047
  label,
13040
13048
  error,
13041
13049
  helperText,
@@ -13043,6 +13051,7 @@ var Input = (0, import_react36.forwardRef)(function Input2({
13043
13051
  suffix,
13044
13052
  size = "md",
13045
13053
  className,
13054
+ style,
13046
13055
  id: idProp,
13047
13056
  disabled,
13048
13057
  theme: themeProp,
@@ -13071,13 +13080,12 @@ var Input = (0, import_react36.forwardRef)(function Input2({
13071
13080
  themeClass,
13072
13081
  error && "border-red-500 focus:ring-red-500 focus:border-red-500",
13073
13082
  hasAddon && "rounded-none first:rounded-l-lg last:rounded-r-lg",
13074
- !hasAddon && "rounded-lg",
13075
- className
13083
+ !hasAddon && "rounded-lg"
13076
13084
  ),
13077
13085
  ...props
13078
13086
  }
13079
13087
  );
13080
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "w-full", children: [
13088
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cn("w-full", className), style, children: [
13081
13089
  label && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
13082
13090
  "label",
13083
13091
  {
@@ -13113,12 +13121,12 @@ var Input = (0, import_react36.forwardRef)(function Input2({
13113
13121
  });
13114
13122
 
13115
13123
  // src/hooks/useFocusTrap.ts
13116
- var import_react37 = require("react");
13124
+ var import_react42 = require("react");
13117
13125
  function useFocusTrap(active, options) {
13118
- const containerRef = (0, import_react37.useRef)(null);
13119
- const previousFocusRef = (0, import_react37.useRef)(null);
13126
+ const containerRef = (0, import_react42.useRef)(null);
13127
+ const previousFocusRef = (0, import_react42.useRef)(null);
13120
13128
  const { returnFocus = true } = options ?? {};
13121
- const getFocusables = (0, import_react37.useCallback)((el) => {
13129
+ const getFocusables = (0, import_react42.useCallback)((el) => {
13122
13130
  const selector = [
13123
13131
  "a[href]",
13124
13132
  "button:not([disabled])",
@@ -13131,7 +13139,7 @@ function useFocusTrap(active, options) {
13131
13139
  (node) => node.offsetParent !== null
13132
13140
  );
13133
13141
  }, []);
13134
- (0, import_react37.useEffect)(() => {
13142
+ (0, import_react42.useEffect)(() => {
13135
13143
  if (!active || !containerRef.current) return;
13136
13144
  previousFocusRef.current = (typeof document !== "undefined" ? document.activeElement : null) ?? null;
13137
13145
  const container = containerRef.current;
@@ -13166,7 +13174,7 @@ function useFocusTrap(active, options) {
13166
13174
  }
13167
13175
 
13168
13176
  // components/Modal.tsx
13169
- var import_react38 = require("react");
13177
+ var import_react43 = require("react");
13170
13178
  var import_jsx_runtime21 = require("react/jsx-runtime");
13171
13179
  var modalVariants = cva(
13172
13180
  "relative z-10 max-h-[90vh] w-full max-w-[calc(100vw-2rem)] overflow-auto rounded-xl p-4 sm:p-6",
@@ -13183,7 +13191,7 @@ var modalVariants = cva(
13183
13191
  }
13184
13192
  }
13185
13193
  );
13186
- function Modal({
13194
+ var Modal = (0, import_react43.forwardRef)(function Modal2({
13187
13195
  open,
13188
13196
  onClose,
13189
13197
  title,
@@ -13192,18 +13200,19 @@ function Modal({
13192
13200
  style,
13193
13201
  children,
13194
13202
  theme: themeProp
13195
- }) {
13203
+ }, ref) {
13196
13204
  const { theme: contextTheme } = useTheme();
13197
13205
  const theme = themeProp ?? contextTheme;
13198
13206
  const themeClass = getThemeClass(theme, "modal", "default");
13199
13207
  const focusTrapRef = useFocusTrap(open, { returnFocus: true });
13200
- const handleEscape = (0, import_react38.useCallback)(
13208
+ const mergedRef = mergeRefs(ref, focusTrapRef);
13209
+ const handleEscape = (0, import_react43.useCallback)(
13201
13210
  (e) => {
13202
13211
  if (e.key === "Escape") onClose();
13203
13212
  },
13204
13213
  [onClose]
13205
13214
  );
13206
- (0, import_react38.useEffect)(() => {
13215
+ (0, import_react43.useEffect)(() => {
13207
13216
  if (!open) return;
13208
13217
  document.addEventListener("keydown", handleEscape);
13209
13218
  document.body.style.overflow = "hidden";
@@ -13233,7 +13242,7 @@ function Modal({
13233
13242
  /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
13234
13243
  "div",
13235
13244
  {
13236
- ref: focusTrapRef,
13245
+ ref: mergedRef,
13237
13246
  className: cn(modalVariants({ size }), themeClass, className),
13238
13247
  style,
13239
13248
  children: [
@@ -13266,27 +13275,21 @@ function Modal({
13266
13275
  ]
13267
13276
  }
13268
13277
  );
13269
- }
13278
+ });
13270
13279
 
13271
13280
  // components/Navbar.tsx
13272
- var import_react39 = require("react");
13281
+ var import_react44 = require("react");
13273
13282
  var import_jsx_runtime22 = require("react/jsx-runtime");
13274
- function Navbar({
13275
- children,
13276
- logo,
13277
- items,
13278
- right,
13279
- className,
13280
- style
13281
- }) {
13282
- const [mobileOpen, setMobileOpen] = (0, import_react39.useState)(false);
13283
- const navRef = (0, import_react39.useRef)(null);
13283
+ var Navbar = (0, import_react44.forwardRef)(function Navbar2({ children, logo, items, right, className, style }, ref) {
13284
+ const [mobileOpen, setMobileOpen] = (0, import_react44.useState)(false);
13285
+ const navRef = (0, import_react44.useRef)(null);
13286
+ const mergedNavRef = mergeRefs(ref, navRef);
13284
13287
  const { theme } = useTheme();
13285
13288
  const themeClass = getThemeClass(theme, "navbar", "default");
13286
13289
  const mobilePanelBgOverride = theme === "glass" ? "bg-white/95 backdrop-blur-xl" : theme === "clay" ? "bg-white/95" : null;
13287
13290
  useClickOutside(
13288
13291
  navRef,
13289
- (0, import_react39.useCallback)(() => setMobileOpen(false), []),
13292
+ (0, import_react44.useCallback)(() => setMobileOpen(false), []),
13290
13293
  { enabled: mobileOpen }
13291
13294
  );
13292
13295
  const hasResponsiveNav = items != null && items.length > 0;
@@ -13294,7 +13297,7 @@ function Navbar({
13294
13297
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
13295
13298
  "nav",
13296
13299
  {
13297
- ref: navRef,
13300
+ ref: mergedNavRef,
13298
13301
  className: cn(
13299
13302
  "relative sticky top-0 z-50 flex h-14 w-full flex-col px-3 sm:px-4",
13300
13303
  themeClass,
@@ -13360,6 +13363,7 @@ function Navbar({
13360
13363
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
13361
13364
  "nav",
13362
13365
  {
13366
+ ref: mergedNavRef,
13363
13367
  className: cn(
13364
13368
  "sticky top-0 z-50 flex h-14 w-full flex-wrap items-center gap-2 px-3 sm:px-4",
13365
13369
  themeClass,
@@ -13369,21 +13373,18 @@ function Navbar({
13369
13373
  children
13370
13374
  }
13371
13375
  );
13372
- }
13376
+ });
13373
13377
 
13374
13378
  // components/PricingCard.tsx
13379
+ var import_react45 = require("react");
13375
13380
  var import_jsx_runtime23 = require("react/jsx-runtime");
13376
- function PricingCard({
13377
- tier,
13378
- onSelect,
13379
- className,
13380
- style
13381
- }) {
13381
+ var PricingCard = (0, import_react45.forwardRef)(function PricingCard2({ tier, onSelect, className, style }, ref) {
13382
13382
  const { theme } = useTheme();
13383
13383
  const themeClass = getThemeClass(theme, "pricingCard", "default");
13384
13384
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
13385
13385
  "div",
13386
13386
  {
13387
+ ref,
13387
13388
  className: cn(
13388
13389
  "flex flex-col rounded-xl p-4 sm:p-6",
13389
13390
  themeClass,
@@ -13411,36 +13412,47 @@ function PricingCard({
13411
13412
  ]
13412
13413
  }
13413
13414
  );
13414
- }
13415
+ });
13415
13416
 
13416
13417
  // components/ProgressBar.tsx
13418
+ var import_react46 = require("react");
13417
13419
  var import_jsx_runtime24 = require("react/jsx-runtime");
13418
- function ProgressBar({
13420
+ var ProgressBar = (0, import_react46.forwardRef)(function ProgressBar2({
13419
13421
  value,
13420
13422
  max = 100,
13421
13423
  segmented = false,
13422
13424
  className,
13423
13425
  style,
13426
+ "aria-label": ariaLabel,
13424
13427
  trackColor,
13425
13428
  activeColor
13426
- }) {
13429
+ }, ref) {
13427
13430
  const { theme } = useTheme();
13428
13431
  const themeClass = getThemeClass(theme, "progress", "default");
13429
13432
  const pct = Math.min(100, Math.max(0, value / max * 100));
13430
13433
  const trackStyle = trackColor ? { backgroundColor: trackColor } : void 0;
13431
13434
  const fillStyle = activeColor ? { width: `${pct}%`, backgroundColor: activeColor } : { width: `${pct}%` };
13435
+ const progressRole = {
13436
+ role: "progressbar",
13437
+ "aria-valuenow": value,
13438
+ "aria-valuemin": 0,
13439
+ "aria-valuemax": max,
13440
+ ...ariaLabel && { "aria-label": ariaLabel }
13441
+ };
13432
13442
  if (segmented) {
13433
13443
  const segments = 10;
13434
13444
  const filled = Math.round(pct / 100 * segments);
13435
13445
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13436
13446
  "div",
13437
13447
  {
13448
+ ref,
13438
13449
  className: cn(
13439
13450
  "flex h-3 w-full gap-0.5 overflow-hidden rounded-full",
13440
13451
  themeClass,
13441
13452
  className
13442
13453
  ),
13443
13454
  style: { ...style, ...trackStyle },
13455
+ ...progressRole,
13444
13456
  children: Array.from({ length: segments }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13445
13457
  "div",
13446
13458
  {
@@ -13458,12 +13470,14 @@ function ProgressBar({
13458
13470
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13459
13471
  "div",
13460
13472
  {
13473
+ ref,
13461
13474
  className: cn(
13462
13475
  "relative h-3 w-full overflow-hidden rounded-full",
13463
13476
  themeClass,
13464
13477
  className
13465
13478
  ),
13466
13479
  style: { ...style, ...trackStyle },
13480
+ ...progressRole,
13467
13481
  children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13468
13482
  "span",
13469
13483
  {
@@ -13473,40 +13487,33 @@ function ProgressBar({
13473
13487
  )
13474
13488
  }
13475
13489
  );
13476
- }
13490
+ });
13477
13491
 
13478
13492
  // components/SectionHeader.tsx
13493
+ var import_react47 = require("react");
13479
13494
  var import_jsx_runtime25 = require("react/jsx-runtime");
13480
- function SectionHeader({
13481
- title,
13482
- subtitle,
13483
- className,
13484
- style
13485
- }) {
13495
+ var SectionHeader = (0, import_react47.forwardRef)(function SectionHeader2({ title, subtitle, className, style }, ref) {
13486
13496
  const { theme } = useTheme();
13487
13497
  const themeClass = getThemeClass(theme, "sectionHeader", "default");
13488
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("header", { className: cn("pb-4", themeClass, className), style, children: [
13498
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("header", { ref, className: cn("pb-4", themeClass, className), style, children: [
13489
13499
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: "text-lg font-semibold sm:text-xl", children: title }),
13490
13500
  subtitle ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "mt-1 text-sm opacity-80", children: subtitle }) : null,
13491
13501
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-3 border-b border-inherit" })
13492
13502
  ] });
13493
- }
13503
+ });
13494
13504
 
13495
13505
  // components/Sidebar.tsx
13496
- var import_react40 = require("react");
13506
+ var import_react48 = require("react");
13497
13507
  var import_jsx_runtime26 = require("react/jsx-runtime");
13498
- function Sidebar({
13499
- children,
13500
- className,
13501
- style
13502
- }) {
13503
- const [collapsed, setCollapsed] = (0, import_react40.useState)(false);
13508
+ var Sidebar = (0, import_react48.forwardRef)(function Sidebar2({ children, className, style }, ref) {
13509
+ const [collapsed, setCollapsed] = (0, import_react48.useState)(false);
13504
13510
  const { theme } = useTheme();
13505
13511
  const themeClass = getThemeClass(theme, "sidebar", "default");
13506
- const toggle = (0, import_react40.useCallback)(() => setCollapsed((c) => !c), []);
13512
+ const toggle = (0, import_react48.useCallback)(() => setCollapsed((c) => !c), []);
13507
13513
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
13508
13514
  "aside",
13509
13515
  {
13516
+ ref,
13510
13517
  className: cn(
13511
13518
  "flex h-full flex-col transition-[width] duration-200",
13512
13519
  collapsed ? "w-12 sm:w-14" : "w-48 max-w-[85vw] sm:w-56 sm:max-w-none",
@@ -13529,10 +13536,10 @@ function Sidebar({
13529
13536
  ]
13530
13537
  }
13531
13538
  );
13532
- }
13539
+ });
13533
13540
 
13534
13541
  // components/Skeleton.tsx
13535
- var import_react41 = require("react");
13542
+ var import_react49 = require("react");
13536
13543
  var import_jsx_runtime27 = require("react/jsx-runtime");
13537
13544
  var skeletonVariants = cva("", {
13538
13545
  variants: {
@@ -13546,7 +13553,7 @@ var skeletonVariants = cva("", {
13546
13553
  variant: "rectangle"
13547
13554
  }
13548
13555
  });
13549
- var Skeleton = (0, import_react41.forwardRef)(
13556
+ var Skeleton = (0, import_react49.forwardRef)(
13550
13557
  function Skeleton2({ variant = "rectangle", className, theme: themeProp, style, ...props }, ref) {
13551
13558
  const { theme: contextTheme } = useTheme();
13552
13559
  const theme = themeProp ?? contextTheme;
@@ -13572,7 +13579,7 @@ var Skeleton = (0, import_react41.forwardRef)(
13572
13579
  );
13573
13580
 
13574
13581
  // components/Slider.tsx
13575
- var import_react42 = require("react");
13582
+ var import_react50 = require("react");
13576
13583
  var import_jsx_runtime28 = require("react/jsx-runtime");
13577
13584
  var sliderVariants = cva(
13578
13585
  "relative flex w-full touch-none items-center overflow-visible py-1",
@@ -13593,7 +13600,7 @@ var trackVariants = cva(
13593
13600
  "relative h-3 w-full rounded-full overflow-visible",
13594
13601
  { variants: {}, defaultVariants: {} }
13595
13602
  );
13596
- var Slider = (0, import_react42.forwardRef)(function Slider2({
13603
+ var Slider = (0, import_react50.forwardRef)(function Slider2({
13597
13604
  min = 0,
13598
13605
  max = 100,
13599
13606
  step = 1,
@@ -13602,17 +13609,18 @@ var Slider = (0, import_react42.forwardRef)(function Slider2({
13602
13609
  onValueChange,
13603
13610
  size = "md",
13604
13611
  className,
13612
+ style,
13605
13613
  theme: themeProp,
13606
13614
  ...props
13607
13615
  }, ref) {
13608
- const [uncontrolled, setUncontrolled] = (0, import_react42.useState)(defaultValue);
13616
+ const [uncontrolled, setUncontrolled] = (0, import_react50.useState)(defaultValue);
13609
13617
  const isControlled = controlledValue !== void 0;
13610
13618
  const value = isControlled ? controlledValue : uncontrolled;
13611
13619
  const { theme: contextTheme } = useTheme();
13612
13620
  const theme = themeProp ?? contextTheme;
13613
13621
  const themeClass = getThemeClass(theme, "slider", "default");
13614
13622
  const pct = (value - min) / (max - min) * 100;
13615
- const handleChange = (0, import_react42.useCallback)(
13623
+ const handleChange = (0, import_react50.useCallback)(
13616
13624
  (e) => {
13617
13625
  const next = Number(e.target.value);
13618
13626
  if (!isControlled) setUncontrolled(next);
@@ -13620,7 +13628,7 @@ var Slider = (0, import_react42.forwardRef)(function Slider2({
13620
13628
  },
13621
13629
  [isControlled, onValueChange]
13622
13630
  );
13623
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(sliderVariants({ size }), className), children: [
13631
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(sliderVariants({ size }), className), style, children: [
13624
13632
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(trackVariants(), themeClass), children: [
13625
13633
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
13626
13634
  "span",
@@ -13658,20 +13666,15 @@ var Slider = (0, import_react42.forwardRef)(function Slider2({
13658
13666
  });
13659
13667
 
13660
13668
  // components/StatsCard.tsx
13669
+ var import_react51 = require("react");
13661
13670
  var import_jsx_runtime29 = require("react/jsx-runtime");
13662
- function StatsCard({
13663
- label,
13664
- value,
13665
- trend,
13666
- className,
13667
- style
13668
- }) {
13671
+ var StatsCard = (0, import_react51.forwardRef)(function StatsCard2({ label, value, trend, className, style }, ref) {
13669
13672
  const { theme } = useTheme();
13670
13673
  const themeClass = getThemeClass(theme, "statsCard", "default");
13671
13674
  const isDark = theme === "night" || theme === "cyberpunk";
13672
13675
  const trendUpClass = trend?.direction === "up" ? isDark ? "text-emerald-400" : "text-emerald-600" : null;
13673
13676
  const trendDownClass = trend?.direction === "down" ? isDark ? "text-rose-400" : "text-rose-600" : null;
13674
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cn("rounded-xl p-6", themeClass, className), style, children: [
13677
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { ref, className: cn("rounded-xl p-6", themeClass, className), style, children: [
13675
13678
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-sm font-medium opacity-80", children: label }),
13676
13679
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mt-2 text-2xl font-bold tracking-tight", children: value }),
13677
13680
  trend ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
@@ -13688,10 +13691,10 @@ function StatsCard({
13688
13691
  }
13689
13692
  ) : null
13690
13693
  ] });
13691
- }
13694
+ });
13692
13695
 
13693
13696
  // components/Tabs.tsx
13694
- var import_react43 = require("react");
13697
+ var import_react52 = require("react");
13695
13698
  var import_jsx_runtime30 = require("react/jsx-runtime");
13696
13699
  var tabsListVariants = cva(
13697
13700
  "flex min-w-0 overflow-x-auto scrollbar-thin -mx-1 px-1 sm:mx-0 sm:overflow-visible",
@@ -13714,7 +13717,7 @@ var tabTriggerVariants = cva(
13714
13717
  }
13715
13718
  }
13716
13719
  );
13717
- function Tabs({
13720
+ var Tabs = (0, import_react52.forwardRef)(function Tabs2({
13718
13721
  items,
13719
13722
  defaultValue,
13720
13723
  value: controlledValue,
@@ -13722,31 +13725,31 @@ function Tabs({
13722
13725
  className,
13723
13726
  style,
13724
13727
  theme: themeProp
13725
- }) {
13726
- const [uncontrolled, setUncontrolled] = (0, import_react43.useState)(
13728
+ }, ref) {
13729
+ const [uncontrolled, setUncontrolled] = (0, import_react52.useState)(
13727
13730
  () => defaultValue ?? items[0]?.value ?? ""
13728
13731
  );
13729
13732
  const isControlled = controlledValue !== void 0;
13730
13733
  const value = isControlled ? controlledValue : uncontrolled;
13731
13734
  const activeIndex = items.findIndex((i) => i.value === value);
13732
13735
  const safeIndex = activeIndex >= 0 ? activeIndex : 0;
13733
- const triggerRefs = (0, import_react43.useRef)([]);
13736
+ const triggerRefs = (0, import_react52.useRef)([]);
13734
13737
  const { theme: contextTheme } = useTheme();
13735
13738
  const theme = themeProp ?? contextTheme;
13736
13739
  const listThemeClass = getThemeClass(theme, "tabs", "default");
13737
13740
  const triggerActiveClass = getThemeClass(theme, "tabs", "triggerActive");
13738
13741
  const triggerInactiveClass = getThemeClass(theme, "tabs", "triggerInactive");
13739
- const setValue = (0, import_react43.useCallback)(
13742
+ const setValue = (0, import_react52.useCallback)(
13740
13743
  (v) => {
13741
13744
  if (!isControlled) setUncontrolled(v);
13742
13745
  onValueChange?.(v);
13743
13746
  },
13744
13747
  [isControlled, onValueChange]
13745
13748
  );
13746
- (0, import_react43.useEffect)(() => {
13749
+ (0, import_react52.useEffect)(() => {
13747
13750
  triggerRefs.current = triggerRefs.current.slice(0, items.length);
13748
13751
  }, [items.length]);
13749
- const handleKeyDown = (0, import_react43.useCallback)(
13752
+ const handleKeyDown = (0, import_react52.useCallback)(
13750
13753
  (e) => {
13751
13754
  if (e.key === "ArrowLeft") {
13752
13755
  e.preventDefault();
@@ -13764,7 +13767,7 @@ function Tabs({
13764
13767
  );
13765
13768
  const activeItem = items[safeIndex];
13766
13769
  const content = activeItem?.content ?? null;
13767
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cn("w-full min-w-0", className), style, children: [
13770
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { ref, className: cn("w-full min-w-0", className), style, children: [
13768
13771
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
13769
13772
  "div",
13770
13773
  {
@@ -13808,22 +13811,19 @@ function Tabs({
13808
13811
  }
13809
13812
  )
13810
13813
  ] });
13811
- }
13814
+ });
13812
13815
 
13813
13816
  // components/Terminal.tsx
13817
+ var import_react53 = require("react");
13814
13818
  var import_jsx_runtime31 = require("react/jsx-runtime");
13815
- function Terminal({
13816
- title = "terminal",
13817
- children,
13818
- className,
13819
- style
13820
- }) {
13819
+ var Terminal = (0, import_react53.forwardRef)(function Terminal2({ title = "terminal", children, className, style }, ref) {
13821
13820
  const { theme } = useTheme();
13822
13821
  const themeClass = getThemeClass(theme, "terminal", "default");
13823
13822
  const isCyberpunk = theme === "cyberpunk";
13824
13823
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
13825
13824
  "div",
13826
13825
  {
13826
+ ref,
13827
13827
  className: cn("overflow-hidden rounded-xl font-mono text-sm", themeClass, className),
13828
13828
  style,
13829
13829
  children: [
@@ -13849,22 +13849,21 @@ function Terminal({
13849
13849
  ]
13850
13850
  }
13851
13851
  );
13852
- }
13852
+ });
13853
13853
 
13854
13854
  // components/Timeline.tsx
13855
+ var import_react54 = require("react");
13855
13856
  var import_jsx_runtime32 = require("react/jsx-runtime");
13856
- function Timeline({
13857
- items,
13858
- className,
13859
- theme: themeProp
13860
- }) {
13857
+ var Timeline = (0, import_react54.forwardRef)(function Timeline2({ items, className, style, theme: themeProp }, ref) {
13861
13858
  const { theme: contextTheme } = useTheme();
13862
13859
  const theme = themeProp ?? contextTheme;
13863
13860
  const themeClass = getThemeClass(theme, "timeline", "default");
13864
13861
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13865
13862
  "div",
13866
13863
  {
13864
+ ref,
13867
13865
  className: cn("relative pl-4", themeClass, className),
13866
+ style,
13868
13867
  role: "list",
13869
13868
  "aria-label": "Timeline",
13870
13869
  children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
@@ -13891,21 +13890,25 @@ function Timeline({
13891
13890
  ))
13892
13891
  }
13893
13892
  );
13894
- }
13893
+ });
13895
13894
 
13896
13895
  // components/Toast.tsx
13896
+ var import_react55 = require("react");
13897
13897
  var import_jsx_runtime33 = require("react/jsx-runtime");
13898
- function Toast({
13899
- message,
13900
- onDismiss,
13901
- className,
13902
- style
13903
- }) {
13898
+ var Toast = (0, import_react55.forwardRef)(function Toast2({ message, onDismiss, className, style }, ref) {
13904
13899
  const { theme } = useTheme();
13905
13900
  const themeClass = getThemeClass(theme, "toast", "default");
13901
+ (0, import_react55.useEffect)(() => {
13902
+ const handler = (e) => {
13903
+ if (e.key === "Escape") onDismiss();
13904
+ };
13905
+ document.addEventListener("keydown", handler);
13906
+ return () => document.removeEventListener("keydown", handler);
13907
+ }, [onDismiss]);
13906
13908
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
13907
13909
  "div",
13908
13910
  {
13911
+ ref,
13909
13912
  role: "alert",
13910
13913
  className: cn(
13911
13914
  "flex items-center justify-between gap-4 rounded-lg px-4 py-3 shadow-lg",
@@ -13928,10 +13931,10 @@ function Toast({
13928
13931
  ]
13929
13932
  }
13930
13933
  );
13931
- }
13934
+ });
13932
13935
 
13933
13936
  // components/Toggle.tsx
13934
- var import_react44 = require("react");
13937
+ var import_react56 = require("react");
13935
13938
  var import_jsx_runtime34 = require("react/jsx-runtime");
13936
13939
  var toggleVariants = cva(
13937
13940
  "relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full px-0.5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 data-[state=off]:justify-start data-[state=on]:justify-end [&:has(input:disabled)]:cursor-not-allowed [&:has(input:disabled)]:opacity-50",
@@ -13940,17 +13943,18 @@ var toggleVariants = cva(
13940
13943
  defaultVariants: {}
13941
13944
  }
13942
13945
  );
13943
- var Toggle = (0, import_react44.forwardRef)(function Toggle2({
13946
+ var Toggle = (0, import_react56.forwardRef)(function Toggle2({
13944
13947
  checked: controlledChecked,
13945
13948
  defaultChecked = false,
13946
13949
  onCheckedChange,
13947
13950
  className,
13951
+ style,
13948
13952
  "aria-label": ariaLabel = "Toggle",
13949
13953
  theme: themeProp,
13950
13954
  disabled,
13951
13955
  ...props
13952
13956
  }, ref) {
13953
- const [uncontrolled, setUncontrolled] = (0, import_react44.useState)(defaultChecked);
13957
+ const [uncontrolled, setUncontrolled] = (0, import_react56.useState)(defaultChecked);
13954
13958
  const isControlled = controlledChecked !== void 0;
13955
13959
  const checked = isControlled ? controlledChecked : uncontrolled;
13956
13960
  const { theme: contextTheme } = useTheme();
@@ -13958,8 +13962,8 @@ var Toggle = (0, import_react44.forwardRef)(function Toggle2({
13958
13962
  const themeClass = getThemeClass(theme, "toggle", "default");
13959
13963
  const thumbOnDark = theme === "night" && checked;
13960
13964
  const thumbClass = thumbOnDark ? "bg-zinc-900 shadow-inner" : "bg-white shadow";
13961
- const id3 = (0, import_react44.useId)();
13962
- const handleChange = (0, import_react44.useCallback)(
13965
+ const id3 = (0, import_react56.useId)();
13966
+ const handleChange = (0, import_react56.useCallback)(
13963
13967
  (e) => {
13964
13968
  const next = e.target.checked;
13965
13969
  if (!isControlled) setUncontrolled(next);
@@ -13972,6 +13976,7 @@ var Toggle = (0, import_react44.forwardRef)(function Toggle2({
13972
13976
  {
13973
13977
  htmlFor: id3,
13974
13978
  className: cn(toggleVariants(), themeClass, className),
13979
+ style,
13975
13980
  "data-state": checked ? "on" : "off",
13976
13981
  children: [
13977
13982
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
@@ -14005,7 +14010,7 @@ var Toggle = (0, import_react44.forwardRef)(function Toggle2({
14005
14010
  });
14006
14011
 
14007
14012
  // components/Tooltip.tsx
14008
- var import_react45 = require("react");
14013
+ var import_react57 = require("react");
14009
14014
  var import_jsx_runtime35 = require("react/jsx-runtime");
14010
14015
  var placementClasses = {
14011
14016
  top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
@@ -14017,34 +14022,31 @@ var tooltipVariants = cva(
14017
14022
  "absolute z-50 whitespace-nowrap rounded-lg px-2 py-1 text-xs shadow-lg",
14018
14023
  { variants: {}, defaultVariants: {} }
14019
14024
  );
14020
- function Tooltip({
14021
- content,
14022
- children,
14023
- placement = "top",
14024
- className,
14025
- style,
14026
- theme: themeProp
14027
- }) {
14028
- const [visible, setVisible] = (0, import_react45.useState)(false);
14025
+ var Tooltip = (0, import_react57.forwardRef)(function Tooltip2({ content, children, placement = "top", className, style, theme: themeProp }, ref) {
14026
+ const [visible, setVisible] = (0, import_react57.useState)(false);
14027
+ const tooltipId = (0, import_react57.useId)();
14029
14028
  const { theme: contextTheme } = useTheme();
14030
14029
  const theme = themeProp ?? contextTheme;
14031
14030
  const themeClass = getThemeClass(theme, "tooltip", "default");
14032
- const show = (0, import_react45.useCallback)(() => setVisible(true), []);
14033
- const hide = (0, import_react45.useCallback)(() => setVisible(false), []);
14031
+ const show = (0, import_react57.useCallback)(() => setVisible(true), []);
14032
+ const hide = (0, import_react57.useCallback)(() => setVisible(false), []);
14034
14033
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
14035
14034
  "span",
14036
14035
  {
14036
+ ref,
14037
14037
  className: cn("relative inline-block", className),
14038
14038
  style,
14039
14039
  onMouseEnter: show,
14040
14040
  onMouseLeave: hide,
14041
14041
  onFocus: show,
14042
14042
  onBlur: hide,
14043
+ "aria-describedby": visible ? tooltipId : void 0,
14043
14044
  children: [
14044
14045
  children,
14045
14046
  visible ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
14046
14047
  "span",
14047
14048
  {
14049
+ id: tooltipId,
14048
14050
  role: "tooltip",
14049
14051
  className: cn(
14050
14052
  tooltipVariants(),
@@ -14057,7 +14059,7 @@ function Tooltip({
14057
14059
  ]
14058
14060
  }
14059
14061
  );
14060
- }
14062
+ });
14061
14063
 
14062
14064
  // lib/theme-recommendations.ts
14063
14065
  var THEME_BACKGROUNDS = {
@@ -14189,6 +14191,7 @@ var THEME_RECOMMENDATIONS = {
14189
14191
  cn,
14190
14192
  getNextListIndex,
14191
14193
  getThemeClass,
14194
+ mergeRefs,
14192
14195
  useClickOutside,
14193
14196
  useFocusTrap,
14194
14197
  useKeyboardNavigation,