@raxrai/stylelab-ui 0.3.2 → 0.4.1

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" },
@@ -3582,6 +3583,14 @@ var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
3582
3583
  function cn(...inputs) {
3583
3584
  return twMerge(clsx(inputs));
3584
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
+ }
3585
3594
 
3586
3595
  // node_modules/lucide-react/dist/esm/createLucideIcon.js
3587
3596
  var import_react3 = require("react");
@@ -3791,14 +3800,14 @@ function AccordionPanel({
3791
3800
  )
3792
3801
  ] });
3793
3802
  }
3794
- function Accordion({
3803
+ var Accordion = (0, import_react4.forwardRef)(function Accordion2({
3795
3804
  items,
3796
3805
  allowMultiple = false,
3797
3806
  defaultOpenIds,
3798
3807
  className,
3799
3808
  style,
3800
3809
  theme: themeProp
3801
- }) {
3810
+ }, ref) {
3802
3811
  const [open, setOpen] = (0, import_react4.useState)(
3803
3812
  () => new Set(defaultOpenIds ?? [])
3804
3813
  );
@@ -3819,7 +3828,7 @@ function Accordion({
3819
3828
  },
3820
3829
  [allowMultiple]
3821
3830
  );
3822
- 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)(
3823
3832
  AccordionPanel,
3824
3833
  {
3825
3834
  item,
@@ -3829,7 +3838,7 @@ function Accordion({
3829
3838
  },
3830
3839
  item.id
3831
3840
  )) });
3832
- }
3841
+ });
3833
3842
 
3834
3843
  // components/Alert.tsx
3835
3844
  var import_react5 = require("react");
@@ -4074,17 +4083,15 @@ var Badge = (0, import_react7.forwardRef)(function Badge2({
4074
4083
  });
4075
4084
 
4076
4085
  // components/BentoGrid.tsx
4086
+ var import_react8 = require("react");
4077
4087
  var import_jsx_runtime6 = require("react/jsx-runtime");
4078
- function BentoGrid({
4079
- children,
4080
- className,
4081
- style
4082
- }) {
4088
+ var BentoGrid = (0, import_react8.forwardRef)(function BentoGrid2({ children, className, style }, ref) {
4083
4089
  const { theme } = useTheme();
4084
4090
  const themeClass = getThemeClass(theme, "bento", "default");
4085
4091
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4086
4092
  "div",
4087
4093
  {
4094
+ ref,
4088
4095
  className: cn(
4089
4096
  "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
4090
4097
  themeClass,
@@ -4094,9 +4101,10 @@ function BentoGrid({
4094
4101
  children
4095
4102
  }
4096
4103
  );
4097
- }
4104
+ });
4098
4105
 
4099
4106
  // components/Breadcrumbs.tsx
4107
+ var import_react9 = require("react");
4100
4108
  var import_jsx_runtime7 = require("react/jsx-runtime");
4101
4109
  var defaultSeparators = {
4102
4110
  minimal: "/",
@@ -4108,24 +4116,19 @@ var defaultSeparators = {
4108
4116
  retro: ">",
4109
4117
  motion: "\u203A"
4110
4118
  };
4111
- function Breadcrumbs({
4112
- items,
4113
- separator,
4114
- className,
4115
- theme: themeProp
4116
- }) {
4119
+ var Breadcrumbs = (0, import_react9.forwardRef)(function Breadcrumbs2({ items, separator, className, style, theme: themeProp }, ref) {
4117
4120
  const { theme: contextTheme } = useTheme();
4118
4121
  const theme = themeProp ?? contextTheme;
4119
4122
  const themeClass = getThemeClass(theme, "breadcrumbs", "default");
4120
4123
  const sep = separator ?? defaultSeparators[theme] ?? "/";
4121
- 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: [
4122
4125
  i > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "data-sep": true, className: "shrink-0 opacity-70", "aria-hidden": true, children: sep }),
4123
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 })
4124
4127
  ] }, i)) });
4125
- }
4128
+ });
4126
4129
 
4127
4130
  // components/Button.tsx
4128
- var import_react8 = require("react");
4131
+ var import_react10 = require("react");
4129
4132
  var import_jsx_runtime8 = require("react/jsx-runtime");
4130
4133
  var buttonVariants = cva(
4131
4134
  "inline-flex items-center justify-center font-medium transition-colors disabled:opacity-50 disabled:pointer-events-none",
@@ -4206,10 +4209,10 @@ function ButtonInner(props, ref) {
4206
4209
  }
4207
4210
  );
4208
4211
  }
4209
- var Button = (0, import_react8.forwardRef)(ButtonInner);
4212
+ var Button = (0, import_react10.forwardRef)(ButtonInner);
4210
4213
 
4211
4214
  // components/Calendar.tsx
4212
- var import_react9 = require("react");
4215
+ var import_react11 = require("react");
4213
4216
  var import_jsx_runtime9 = require("react/jsx-runtime");
4214
4217
  function getDaysInMonth(year, month) {
4215
4218
  return new Date(year, month + 1, 0).getDate();
@@ -4240,16 +4243,17 @@ var MONTHS = [
4240
4243
  "November",
4241
4244
  "December"
4242
4245
  ];
4243
- function Calendar({
4246
+ var Calendar = (0, import_react11.forwardRef)(function Calendar2({
4244
4247
  value: controlledValue,
4245
4248
  defaultValue,
4246
4249
  onSelect,
4247
4250
  min,
4248
4251
  max,
4249
4252
  className,
4253
+ style,
4250
4254
  theme: themeProp
4251
- }) {
4252
- const [uncontrolled, setUncontrolled] = (0, import_react9.useState)(
4255
+ }, ref) {
4256
+ const [uncontrolled, setUncontrolled] = (0, import_react11.useState)(
4253
4257
  () => defaultValue ?? null
4254
4258
  );
4255
4259
  const isControlled = controlledValue !== void 0;
@@ -4257,11 +4261,11 @@ function Calendar({
4257
4261
  const { theme: contextTheme } = useTheme();
4258
4262
  const theme = themeProp ?? contextTheme;
4259
4263
  const themeClass = getThemeClass(theme, "calendar", "default");
4260
- const [view2, setView] = (0, import_react9.useState)(() => {
4264
+ const [view2, setView] = (0, import_react11.useState)(() => {
4261
4265
  const d = value ?? /* @__PURE__ */ new Date();
4262
4266
  return { year: d.getFullYear(), month: d.getMonth() };
4263
4267
  });
4264
- const grid = (0, import_react9.useMemo)(
4268
+ const grid = (0, import_react11.useMemo)(
4265
4269
  () => buildMonthGrid(view2.year, view2.month),
4266
4270
  [view2.year, view2.month]
4267
4271
  );
@@ -4296,7 +4300,9 @@ function Calendar({
4296
4300
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4297
4301
  "div",
4298
4302
  {
4303
+ ref,
4299
4304
  className: cn("inline-block max-w-full min-w-0 border p-3 sm:p-4 rounded-xl", themeClass, className),
4305
+ style,
4300
4306
  children: [
4301
4307
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [
4302
4308
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -4349,10 +4355,10 @@ function Calendar({
4349
4355
  ]
4350
4356
  }
4351
4357
  );
4352
- }
4358
+ });
4353
4359
 
4354
4360
  // components/Card.tsx
4355
- var import_react10 = require("react");
4361
+ var import_react12 = require("react");
4356
4362
  var import_jsx_runtime10 = require("react/jsx-runtime");
4357
4363
  var cardVariants = cva("rounded-xl", {
4358
4364
  variants: {
@@ -4371,7 +4377,7 @@ var cardVariants = cva("rounded-xl", {
4371
4377
  isHoverable: false
4372
4378
  }
4373
4379
  });
4374
- var Card = (0, import_react10.forwardRef)(function Card2({
4380
+ var Card = (0, import_react12.forwardRef)(function Card2({
4375
4381
  header,
4376
4382
  footer,
4377
4383
  padding = "md",
@@ -4392,8 +4398,8 @@ var Card = (0, import_react10.forwardRef)(function Card2({
4392
4398
  className: cn(
4393
4399
  cardVariants({ padding, isHoverable }),
4394
4400
  themeClass,
4395
- className,
4396
- classNames.root
4401
+ classNames.root,
4402
+ className
4397
4403
  ),
4398
4404
  ...props,
4399
4405
  children: [
@@ -4429,9 +4435,160 @@ var Card = (0, import_react10.forwardRef)(function Card2({
4429
4435
  );
4430
4436
  });
4431
4437
 
4432
- // components/DashboardShell.tsx
4433
- var import_react11 = require("react");
4438
+ // components/CommandPalette.tsx
4439
+ var import_react13 = require("react");
4434
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");
4435
4592
  var SHELL_BG_BY_THEME = {
4436
4593
  minimal: "bg-gradient-to-br from-slate-50 via-zinc-50 to-slate-100",
4437
4594
  night: "bg-zinc-950 text-zinc-100",
@@ -4463,7 +4620,7 @@ function mobileNavLinkStateClasses(theme, active) {
4463
4620
  }
4464
4621
  return active ? "bg-black/5 text-zinc-900" : "text-zinc-600 hover:bg-black/5 hover:text-zinc-900";
4465
4622
  }
4466
- function DashboardShell({
4623
+ var DashboardShell = (0, import_react14.forwardRef)(function DashboardShell2({
4467
4624
  children,
4468
4625
  navItems,
4469
4626
  adminNavItems,
@@ -4472,19 +4629,20 @@ function DashboardShell({
4472
4629
  userRole,
4473
4630
  onLogout,
4474
4631
  logo,
4475
- className
4476
- }) {
4477
- const [mobileOpen, setMobileOpen] = (0, import_react11.useState)(false);
4632
+ className,
4633
+ style
4634
+ }, ref) {
4635
+ const [mobileOpen, setMobileOpen] = (0, import_react14.useState)(false);
4478
4636
  const isAdmin = userRole === "ADMIN";
4479
4637
  const { theme } = useTheme();
4480
4638
  const shellBg = SHELL_BG_BY_THEME[theme];
4481
4639
  const isDarkHeader = darkHeaderThemes.includes(theme);
4482
4640
  const isActive = (href) => currentPath ? currentPath === href || currentPath.startsWith(href) : false;
4483
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: cn("min-h-screen", shellBg, className), children: [
4484
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("header", { className: cn("sticky top-0 z-40", headerClasses(theme)), children: [
4485
- /* @__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: [
4486
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2", children: [
4487
- /* @__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)(
4488
4646
  "button",
4489
4647
  {
4490
4648
  type: "button",
@@ -4495,10 +4653,10 @@ function DashboardShell({
4495
4653
  ),
4496
4654
  "aria-label": "Toggle navigation",
4497
4655
  "aria-expanded": mobileOpen,
4498
- 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" })
4499
4657
  }
4500
4658
  ),
4501
- /* @__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)(
4502
4660
  "span",
4503
4661
  {
4504
4662
  className: cn(
@@ -4508,8 +4666,8 @@ function DashboardShell({
4508
4666
  children: "Dashboard"
4509
4667
  }
4510
4668
  ) }),
4511
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("nav", { className: "ml-6 hidden items-center gap-1 text-sm sm:flex", children: [
4512
- 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)(
4513
4671
  "a",
4514
4672
  {
4515
4673
  href: item.href,
@@ -4518,8 +4676,8 @@ function DashboardShell({
4518
4676
  },
4519
4677
  item.href
4520
4678
  )),
4521
- isAdmin && adminNavItems && adminNavItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
4522
- /* @__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)(
4523
4681
  "span",
4524
4682
  {
4525
4683
  className: cn(
@@ -4528,7 +4686,7 @@ function DashboardShell({
4528
4686
  )
4529
4687
  }
4530
4688
  ),
4531
- adminNavItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4689
+ adminNavItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4532
4690
  "a",
4533
4691
  {
4534
4692
  href: item.href,
@@ -4543,8 +4701,8 @@ function DashboardShell({
4543
4701
  ] })
4544
4702
  ] })
4545
4703
  ] }),
4546
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 text-sm", children: [
4547
- 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)(
4548
4706
  "span",
4549
4707
  {
4550
4708
  className: cn(
@@ -4554,7 +4712,7 @@ function DashboardShell({
4554
4712
  children: userEmail
4555
4713
  }
4556
4714
  ),
4557
- onLogout && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4715
+ onLogout && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4558
4716
  "button",
4559
4717
  {
4560
4718
  type: "button",
@@ -4568,8 +4726,8 @@ function DashboardShell({
4568
4726
  )
4569
4727
  ] })
4570
4728
  ] }),
4571
- mobileOpen && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: mobilePanelClasses(theme), children: [
4572
- /* @__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)(
4573
4731
  "a",
4574
4732
  {
4575
4733
  href: item.href,
@@ -4581,8 +4739,8 @@ function DashboardShell({
4581
4739
  },
4582
4740
  item.href
4583
4741
  )) }),
4584
- isAdmin && adminNavItems && adminNavItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
4585
- /* @__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)(
4586
4744
  "div",
4587
4745
  {
4588
4746
  className: cn(
@@ -4591,7 +4749,7 @@ function DashboardShell({
4591
4749
  )
4592
4750
  }
4593
4751
  ),
4594
- /* @__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)(
4595
4753
  "a",
4596
4754
  {
4597
4755
  href: item.href,
@@ -4604,7 +4762,7 @@ function DashboardShell({
4604
4762
  item.href
4605
4763
  )) })
4606
4764
  ] }),
4607
- userEmail && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4765
+ userEmail && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4608
4766
  "div",
4609
4767
  {
4610
4768
  className: cn(
@@ -4614,7 +4772,7 @@ function DashboardShell({
4614
4772
  children: userEmail
4615
4773
  }
4616
4774
  ),
4617
- onLogout && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4775
+ onLogout && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4618
4776
  "button",
4619
4777
  {
4620
4778
  type: "button",
@@ -4626,159 +4784,53 @@ function DashboardShell({
4626
4784
  children: "Logout"
4627
4785
  }
4628
4786
  )
4629
- ] })
4630
- ] }),
4631
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("main", { className: "mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8", children })
4632
- ] });
4633
- }
4634
-
4635
- // components/CommandPalette.tsx
4636
- var import_react12 = require("react");
4637
- var import_jsx_runtime12 = require("react/jsx-runtime");
4638
- function CommandPalette({
4639
- open,
4640
- onClose,
4641
- commands,
4642
- placeholder = "Type a command...",
4643
- theme: themeProp
4644
- }) {
4645
- const [query, setQuery] = (0, import_react12.useState)("");
4646
- const [selected, setSelected] = (0, import_react12.useState)(0);
4647
- const listRef = (0, import_react12.useRef)(null);
4648
- const { theme: contextTheme } = useTheme();
4649
- const theme = themeProp ?? contextTheme;
4650
- const themeClass = getThemeClass(theme, "commandPalette", "default");
4651
- const filtered = (0, import_react12.useMemo)(() => {
4652
- if (!query.trim()) return commands;
4653
- const q = query.toLowerCase();
4654
- return commands.filter((c) => c.label.toLowerCase().includes(q));
4655
- }, [commands, query]);
4656
- const safeSelected = Math.min(selected, Math.max(0, filtered.length - 1));
4657
- (0, import_react12.useEffect)(() => {
4658
- if (open) {
4659
- setQuery("");
4660
- setSelected(0);
4661
- }
4662
- }, [open]);
4663
- (0, import_react12.useEffect)(() => {
4664
- setSelected((s) => Math.min(s, Math.max(0, filtered.length - 1)));
4665
- }, [filtered.length]);
4666
- const runSelected = (0, import_react12.useCallback)(() => {
4667
- const item = filtered[safeSelected];
4668
- if (item) {
4669
- item.onSelect();
4670
- onClose();
4671
- }
4672
- }, [filtered, safeSelected, onClose]);
4673
- (0, import_react12.useEffect)(() => {
4674
- if (!open) return;
4675
- const handler = (e) => {
4676
- if (e.key === "Escape") {
4677
- e.preventDefault();
4678
- onClose();
4679
- return;
4680
- }
4681
- if (e.key === "ArrowDown") {
4682
- e.preventDefault();
4683
- setSelected((s) => (s + 1) % Math.max(1, filtered.length));
4684
- return;
4685
- }
4686
- if (e.key === "ArrowUp") {
4687
- e.preventDefault();
4688
- setSelected(
4689
- (s) => (s - 1 + filtered.length) % Math.max(1, filtered.length)
4690
- );
4691
- return;
4692
- }
4693
- if (e.key === "Enter") {
4694
- e.preventDefault();
4695
- runSelected();
4696
- }
4697
- };
4698
- document.addEventListener("keydown", handler, true);
4699
- return () => document.removeEventListener("keydown", handler, true);
4700
- }, [open, onClose, filtered.length, runSelected]);
4701
- (0, import_react12.useEffect)(() => {
4702
- const el = listRef.current;
4703
- if (!el) return;
4704
- const item = el.querySelector(`[data-index="${safeSelected}"]`);
4705
- item?.scrollIntoView({ block: "nearest", behavior: "smooth" });
4706
- }, [safeSelected]);
4707
- if (!open) return null;
4708
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4709
- "div",
4710
- {
4711
- className: "fixed inset-0 z-50 flex items-start justify-center pt-[20vh] p-4",
4712
- role: "dialog",
4713
- "aria-modal": "true",
4714
- "aria-label": "Command palette",
4715
- children: [
4716
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4717
- "div",
4718
- {
4719
- className: "absolute inset-0 bg-black/50 backdrop-blur-sm",
4720
- onClick: onClose,
4721
- "aria-hidden": true
4722
- }
4723
- ),
4724
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4725
- "div",
4726
- {
4727
- 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}`,
4728
- children: [
4729
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2 border-b border-inherit px-3 py-2", children: [
4730
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Search, { className: "size-4 shrink-0 opacity-60", "aria-hidden": true }),
4731
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4732
- "input",
4733
- {
4734
- type: "text",
4735
- value: query,
4736
- onChange: (e) => setQuery(e.target.value),
4737
- placeholder,
4738
- className: "flex-1 bg-transparent outline-none placeholder:opacity-60",
4739
- autoFocus: true,
4740
- "aria-autocomplete": "list",
4741
- "aria-controls": "command-palette-list",
4742
- "aria-expanded": "true"
4743
- }
4744
- ),
4745
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("kbd", { className: "rounded border border-inherit px-1.5 py-0.5 text-xs opacity-60", children: "ESC" })
4746
- ] }),
4747
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4748
- "ul",
4749
- {
4750
- ref: listRef,
4751
- id: "command-palette-list",
4752
- role: "listbox",
4753
- className: "max-h-72 overflow-auto py-2",
4754
- 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)(
4755
- "button",
4756
- {
4757
- type: "button",
4758
- onClick: () => {
4759
- cmd.onSelect();
4760
- onClose();
4761
- },
4762
- onMouseEnter: () => setSelected(i),
4763
- className: `flex w-full items-center justify-between px-4 py-2 text-left text-sm ${i === safeSelected ? "bg-current/10" : ""}`,
4764
- children: [
4765
- cmd.label,
4766
- 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
4767
- ]
4768
- }
4769
- ) }, cmd.id))
4770
- }
4771
- )
4772
- ]
4773
- }
4774
- )
4775
- ]
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
+ ] })
4776
4827
  }
4777
4828
  );
4778
4829
  }
4830
+ var DataTable = (0, import_react15.forwardRef)(DataTableInner);
4779
4831
 
4780
4832
  // components/DocumentAccordion.tsx
4781
- var import_jsx_runtime13 = require("react/jsx-runtime");
4833
+ var import_jsx_runtime14 = require("react/jsx-runtime");
4782
4834
  function DocumentAccordion({
4783
4835
  title,
4784
4836
  content,
@@ -4793,15 +4845,15 @@ function DocumentAccordion({
4793
4845
  {
4794
4846
  id: "document",
4795
4847
  title,
4796
- content: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4848
+ content: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4797
4849
  "div",
4798
4850
  {
4799
4851
  className: cn(
4800
4852
  "rounded-xl border p-0 shadow-sm backdrop-blur-md",
4801
4853
  theme === "night" || theme === "cyberpunk" ? "border-white/10 bg-zinc-950/80" : "border-black/5 bg-white/60"
4802
4854
  ),
4803
- children: pdfUrl ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3", children: [
4804
- /* @__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)(
4805
4857
  "a",
4806
4858
  {
4807
4859
  href: pdfUrl,
@@ -4812,19 +4864,19 @@ function DocumentAccordion({
4812
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"
4813
4865
  ),
4814
4866
  children: [
4815
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Open PDF" }),
4816
- /* @__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" })
4817
4869
  ]
4818
4870
  }
4819
4871
  ) }),
4820
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4872
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4821
4873
  "div",
4822
4874
  {
4823
4875
  className: cn(
4824
4876
  "h-[60vh] w-full border-t",
4825
4877
  theme === "night" || theme === "cyberpunk" ? "border-white/10" : "border-black/5"
4826
4878
  ),
4827
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4879
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4828
4880
  "iframe",
4829
4881
  {
4830
4882
  src: `https://docs.google.com/viewer?url=${encodeURIComponent(
@@ -4836,7 +4888,7 @@ function DocumentAccordion({
4836
4888
  )
4837
4889
  }
4838
4890
  )
4839
- ] }) : content ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4891
+ ] }) : content ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4840
4892
  "div",
4841
4893
  {
4842
4894
  className: cn(
@@ -4850,7 +4902,7 @@ function DocumentAccordion({
4850
4902
  )
4851
4903
  }
4852
4904
  ];
4853
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4905
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4854
4906
  Accordion,
4855
4907
  {
4856
4908
  items,
@@ -4862,50 +4914,8 @@ function DocumentAccordion({
4862
4914
  );
4863
4915
  }
4864
4916
 
4865
- // components/DataTable.tsx
4866
- var import_jsx_runtime14 = require("react/jsx-runtime");
4867
- function DataTable({
4868
- columns,
4869
- data,
4870
- getRowKey,
4871
- className,
4872
- style
4873
- }) {
4874
- const { theme } = useTheme();
4875
- const themeClass = getThemeClass(theme, "dataTable", "default");
4876
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4877
- "div",
4878
- {
4879
- className: cn(
4880
- "overflow-x-auto rounded-lg -mx-1 px-1 sm:mx-0 sm:px-0",
4881
- themeClass,
4882
- className
4883
- ),
4884
- style,
4885
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("table", { className: "w-full min-w-[480px] text-left text-sm", children: [
4886
- /* @__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)(
4887
- "th",
4888
- {
4889
- className: "px-4 py-3 font-medium",
4890
- children: col.header
4891
- },
4892
- String(col.key)
4893
- )) }) }),
4894
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tbody", { children: data.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4895
- "tr",
4896
- {
4897
- className: "border-b border-inherit last:border-0",
4898
- 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)))
4899
- },
4900
- getRowKey ? getRowKey(row, i) : i
4901
- )) })
4902
- ] })
4903
- }
4904
- );
4905
- }
4906
-
4907
4917
  // src/hooks/useKeyboardNavigation.ts
4908
- var import_react13 = require("react");
4918
+ var import_react16 = require("react");
4909
4919
  function useKeyboardNavigation(options) {
4910
4920
  const {
4911
4921
  onEscape,
@@ -4915,7 +4925,7 @@ function useKeyboardNavigation(options) {
4915
4925
  onArrowRight,
4916
4926
  enabled = true
4917
4927
  } = options;
4918
- const handleKeyDown = (0, import_react13.useCallback)(
4928
+ const handleKeyDown = (0, import_react16.useCallback)(
4919
4929
  (e) => {
4920
4930
  if (!enabled) return;
4921
4931
  if (e.key === "Escape") {
@@ -4940,7 +4950,7 @@ function useKeyboardNavigation(options) {
4940
4950
  },
4941
4951
  [enabled, onEscape, onArrowDown, onArrowUp, onArrowLeft, onArrowRight]
4942
4952
  );
4943
- (0, import_react13.useEffect)(() => {
4953
+ (0, import_react16.useEffect)(() => {
4944
4954
  if (!enabled) return;
4945
4955
  document.addEventListener("keydown", handleKeyDown, true);
4946
4956
  return () => document.removeEventListener("keydown", handleKeyDown, true);
@@ -4955,10 +4965,10 @@ function getNextListIndex(current, direction, length) {
4955
4965
  }
4956
4966
 
4957
4967
  // src/hooks/useClickOutside.ts
4958
- var import_react14 = require("react");
4968
+ var import_react17 = require("react");
4959
4969
  function useClickOutside(ref, handler, options) {
4960
4970
  const enabled = options?.enabled !== false;
4961
- const handle = (0, import_react14.useCallback)(
4971
+ const handle = (0, import_react17.useCallback)(
4962
4972
  (e) => {
4963
4973
  const target = e.target;
4964
4974
  const refs = Array.isArray(ref) ? ref : [ref];
@@ -4969,7 +4979,7 @@ function useClickOutside(ref, handler, options) {
4969
4979
  },
4970
4980
  [ref, handler]
4971
4981
  );
4972
- (0, import_react14.useEffect)(() => {
4982
+ (0, import_react17.useEffect)(() => {
4973
4983
  if (!enabled) return;
4974
4984
  document.addEventListener("mousedown", handle);
4975
4985
  document.addEventListener("touchstart", handle);
@@ -4981,14 +4991,14 @@ function useClickOutside(ref, handler, options) {
4981
4991
  }
4982
4992
 
4983
4993
  // components/Dropdown.tsx
4984
- var import_react15 = require("react");
4994
+ var import_react18 = require("react");
4985
4995
  var import_react_dom = require("react-dom");
4986
4996
  var import_jsx_runtime15 = require("react/jsx-runtime");
4987
4997
  function dropdownItemHighlightClass(theme) {
4988
4998
  const darkThemes = ["night", "cyberpunk"];
4989
4999
  return darkThemes.includes(theme) ? "hover:bg-white/10 focus:bg-white/10" : "hover:bg-black/5 focus:bg-black/5";
4990
5000
  }
4991
- function Dropdown({
5001
+ var Dropdown = (0, import_react18.forwardRef)(function Dropdown2({
4992
5002
  trigger: triggerProp,
4993
5003
  placeholder = "Select\u2026",
4994
5004
  items,
@@ -5000,21 +5010,22 @@ function Dropdown({
5000
5010
  style,
5001
5011
  theme: themeProp,
5002
5012
  classNames = {}
5003
- }) {
5004
- const [open, setOpen] = (0, import_react15.useState)(false);
5005
- 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 ?? "");
5006
5016
  const isControlled = controlledValue !== void 0;
5007
5017
  const displayValue = isControlled ? controlledValue : uncontrolledValue;
5008
- const [highlightedIndex, setHighlightedIndex] = (0, import_react15.useState)(-1);
5009
- const [popoverStyle, setPopoverStyle] = (0, import_react15.useState)({});
5010
- const listRef = (0, import_react15.useRef)(null);
5011
- const containerRef = (0, import_react15.useRef)(null);
5012
- 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);
5013
5024
  const { theme: contextTheme } = useTheme();
5014
5025
  const theme = themeProp ?? contextTheme;
5015
5026
  const themeClass = getThemeClass(theme, "card", "default");
5016
5027
  const itemHighlightClass = dropdownItemHighlightClass(theme);
5017
- const updatePosition = (0, import_react15.useCallback)(() => {
5028
+ const updatePosition = (0, import_react18.useCallback)(() => {
5018
5029
  const triggerEl = triggerRef.current;
5019
5030
  if (!triggerEl) return;
5020
5031
  const rect = triggerEl.getBoundingClientRect();
@@ -5030,15 +5041,15 @@ function Dropdown({
5030
5041
  zIndex: 9999
5031
5042
  });
5032
5043
  }, []);
5033
- (0, import_react15.useLayoutEffect)(() => {
5044
+ (0, import_react18.useLayoutEffect)(() => {
5034
5045
  if (open && !disabled) {
5035
5046
  updatePosition();
5036
5047
  }
5037
5048
  }, [open, disabled, updatePosition, items.length]);
5038
- (0, import_react15.useEffect)(() => {
5049
+ (0, import_react18.useEffect)(() => {
5039
5050
  if (disabled && open) setOpen(false);
5040
5051
  }, [disabled, open]);
5041
- (0, import_react15.useEffect)(() => {
5052
+ (0, import_react18.useEffect)(() => {
5042
5053
  if (!open) return;
5043
5054
  const onScrollOrResize = () => updatePosition();
5044
5055
  window.addEventListener("scroll", onScrollOrResize, true);
@@ -5050,17 +5061,17 @@ function Dropdown({
5050
5061
  }, [open, updatePosition]);
5051
5062
  useClickOutside(
5052
5063
  [containerRef, listRef],
5053
- (0, import_react15.useCallback)(() => setOpen(false), []),
5064
+ (0, import_react18.useCallback)(() => setOpen(false), []),
5054
5065
  { enabled: open }
5055
5066
  );
5056
- const setValue = (0, import_react15.useCallback)(
5067
+ const setValue = (0, import_react18.useCallback)(
5057
5068
  (v) => {
5058
5069
  if (!isControlled) setUncontrolledValue(v);
5059
5070
  onValueChange?.(v);
5060
5071
  },
5061
5072
  [isControlled, onValueChange]
5062
5073
  );
5063
- const selectIndex = (0, import_react15.useCallback)(
5074
+ const selectIndex = (0, import_react18.useCallback)(
5064
5075
  (index) => {
5065
5076
  const item = items[index];
5066
5077
  if (item?.disabled) return;
@@ -5070,7 +5081,7 @@ function Dropdown({
5070
5081
  },
5071
5082
  [items, setValue]
5072
5083
  );
5073
- (0, import_react15.useEffect)(() => {
5084
+ (0, import_react18.useEffect)(() => {
5074
5085
  if (!open) {
5075
5086
  setHighlightedIndex(-1);
5076
5087
  return;
@@ -5078,7 +5089,7 @@ function Dropdown({
5078
5089
  const current = items.findIndex((i) => i.value === displayValue);
5079
5090
  setHighlightedIndex(current >= 0 ? current : 0);
5080
5091
  }, [open, displayValue, items]);
5081
- const handleKeyDown = (0, import_react15.useCallback)(
5092
+ const handleKeyDown = (0, import_react18.useCallback)(
5082
5093
  (e) => {
5083
5094
  if (disabled) return;
5084
5095
  if (!open) {
@@ -5169,7 +5180,7 @@ function Dropdown({
5169
5180
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
5170
5181
  "div",
5171
5182
  {
5172
- ref: containerRef,
5183
+ ref: mergedContainerRef,
5173
5184
  className: cn("relative inline-block", className),
5174
5185
  style,
5175
5186
  onKeyDown: handleKeyDown,
@@ -5193,19 +5204,19 @@ function Dropdown({
5193
5204
  ]
5194
5205
  }
5195
5206
  );
5196
- }
5207
+ });
5197
5208
 
5198
5209
  // components/Flashcard.tsx
5199
- var import_react35 = require("react");
5210
+ var import_react38 = require("react");
5200
5211
 
5201
5212
  // node_modules/framer-motion/dist/es/context/LayoutGroupContext.mjs
5202
- var import_react16 = require("react");
5203
- var LayoutGroupContext = (0, import_react16.createContext)({});
5213
+ var import_react19 = require("react");
5214
+ var LayoutGroupContext = (0, import_react19.createContext)({});
5204
5215
 
5205
5216
  // node_modules/framer-motion/dist/es/utils/use-constant.mjs
5206
- var import_react17 = require("react");
5217
+ var import_react20 = require("react");
5207
5218
  function useConstant(init) {
5208
- const ref = (0, import_react17.useRef)(null);
5219
+ const ref = (0, import_react20.useRef)(null);
5209
5220
  if (ref.current === null) {
5210
5221
  ref.current = init();
5211
5222
  }
@@ -5213,41 +5224,41 @@ function useConstant(init) {
5213
5224
  }
5214
5225
 
5215
5226
  // node_modules/framer-motion/dist/es/context/PresenceContext.mjs
5216
- var import_react18 = require("react");
5217
- var PresenceContext = (0, import_react18.createContext)(null);
5227
+ var import_react21 = require("react");
5228
+ var PresenceContext = (0, import_react21.createContext)(null);
5218
5229
 
5219
5230
  // node_modules/framer-motion/dist/es/context/MotionConfigContext.mjs
5220
- var import_react19 = require("react");
5221
- var MotionConfigContext = (0, import_react19.createContext)({
5231
+ var import_react22 = require("react");
5232
+ var MotionConfigContext = (0, import_react22.createContext)({
5222
5233
  transformPagePoint: (p) => p,
5223
5234
  isStatic: false,
5224
5235
  reducedMotion: "never"
5225
5236
  });
5226
5237
 
5227
5238
  // node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.mjs
5228
- var import_react20 = require("react");
5239
+ var import_react23 = require("react");
5229
5240
  function usePresence(subscribe = true) {
5230
- const context = (0, import_react20.useContext)(PresenceContext);
5241
+ const context = (0, import_react23.useContext)(PresenceContext);
5231
5242
  if (context === null)
5232
5243
  return [true, null];
5233
5244
  const { isPresent, onExitComplete, register } = context;
5234
- const id3 = (0, import_react20.useId)();
5235
- (0, import_react20.useEffect)(() => {
5245
+ const id3 = (0, import_react23.useId)();
5246
+ (0, import_react23.useEffect)(() => {
5236
5247
  if (subscribe)
5237
5248
  register(id3);
5238
5249
  }, [subscribe]);
5239
- 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]);
5240
5251
  return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
5241
5252
  }
5242
5253
 
5243
5254
  // node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.mjs
5244
- var import_react21 = require("react");
5255
+ var import_react24 = require("react");
5245
5256
 
5246
5257
  // node_modules/framer-motion/dist/es/utils/is-browser.mjs
5247
5258
  var isBrowser = typeof window !== "undefined";
5248
5259
 
5249
5260
  // node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.mjs
5250
- var useIsomorphicLayoutEffect = isBrowser ? import_react21.useLayoutEffect : import_react21.useEffect;
5261
+ var useIsomorphicLayoutEffect = isBrowser ? import_react24.useLayoutEffect : import_react24.useEffect;
5251
5262
 
5252
5263
  // node_modules/motion-utils/dist/es/noop.mjs
5253
5264
  var noop = /* @__NO_SIDE_EFFECTS__ */ (any) => any;
@@ -5433,8 +5444,8 @@ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
5433
5444
  var { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps } = createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
5434
5445
 
5435
5446
  // node_modules/framer-motion/dist/es/context/LazyContext.mjs
5436
- var import_react22 = require("react");
5437
- var LazyContext = (0, import_react22.createContext)({ strict: false });
5447
+ var import_react25 = require("react");
5448
+ var LazyContext = (0, import_react25.createContext)({ strict: false });
5438
5449
 
5439
5450
  // node_modules/framer-motion/dist/es/motion/features/definitions.mjs
5440
5451
  var featureProps = {
@@ -5577,14 +5588,14 @@ function createDOMMotionComponentProxy(componentFactory) {
5577
5588
 
5578
5589
  // node_modules/framer-motion/dist/es/motion/index.mjs
5579
5590
  var import_jsx_runtime16 = require("react/jsx-runtime");
5580
- var import_react28 = require("react");
5591
+ var import_react31 = require("react");
5581
5592
 
5582
5593
  // node_modules/framer-motion/dist/es/context/MotionContext/index.mjs
5583
- var import_react23 = require("react");
5584
- var MotionContext = (0, import_react23.createContext)({});
5594
+ var import_react26 = require("react");
5595
+ var MotionContext = (0, import_react26.createContext)({});
5585
5596
 
5586
5597
  // node_modules/framer-motion/dist/es/context/MotionContext/create.mjs
5587
- var import_react24 = require("react");
5598
+ var import_react27 = require("react");
5588
5599
 
5589
5600
  // node_modules/framer-motion/dist/es/render/utils/is-variant-label.mjs
5590
5601
  function isVariantLabel(v) {
@@ -5630,8 +5641,8 @@ function getCurrentTreeVariants(props, context) {
5630
5641
 
5631
5642
  // node_modules/framer-motion/dist/es/context/MotionContext/create.mjs
5632
5643
  function useCreateMotionContext(props) {
5633
- const { initial, animate } = getCurrentTreeVariants(props, (0, import_react24.useContext)(MotionContext));
5634
- 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)]);
5635
5646
  }
5636
5647
  function variantLabelsAsDependency(prop) {
5637
5648
  return Array.isArray(prop) ? prop.join(" ") : prop;
@@ -5641,7 +5652,7 @@ function variantLabelsAsDependency(prop) {
5641
5652
  var motionComponentSymbol = /* @__PURE__ */ Symbol.for("motionComponentSymbol");
5642
5653
 
5643
5654
  // node_modules/framer-motion/dist/es/motion/utils/use-motion-ref.mjs
5644
- var import_react25 = require("react");
5655
+ var import_react28 = require("react");
5645
5656
 
5646
5657
  // node_modules/framer-motion/dist/es/utils/is-ref-object.mjs
5647
5658
  function isRefObject(ref) {
@@ -5650,7 +5661,7 @@ function isRefObject(ref) {
5650
5661
 
5651
5662
  // node_modules/framer-motion/dist/es/motion/utils/use-motion-ref.mjs
5652
5663
  function useMotionRef(visualState, visualElement, externalRef) {
5653
- return (0, import_react25.useCallback)(
5664
+ return (0, import_react28.useCallback)(
5654
5665
  (instance) => {
5655
5666
  if (instance) {
5656
5667
  visualState.onMount && visualState.onMount(instance);
@@ -5680,7 +5691,7 @@ function useMotionRef(visualState, visualElement, externalRef) {
5680
5691
  }
5681
5692
 
5682
5693
  // node_modules/framer-motion/dist/es/motion/utils/use-visual-element.mjs
5683
- var import_react27 = require("react");
5694
+ var import_react30 = require("react");
5684
5695
 
5685
5696
  // node_modules/framer-motion/dist/es/render/dom/utils/camel-to-dash.mjs
5686
5697
  var camelToDash = (str) => str.replace(/([a-z])([A-Z])/gu, "$1-$2").toLowerCase();
@@ -5693,17 +5704,17 @@ var optimizedAppearDataAttribute = "data-" + camelToDash(optimizedAppearDataId);
5693
5704
  var { schedule: microtask, cancel: cancelMicrotask } = createRenderBatcher(queueMicrotask, false);
5694
5705
 
5695
5706
  // node_modules/framer-motion/dist/es/context/SwitchLayoutGroupContext.mjs
5696
- var import_react26 = require("react");
5697
- var SwitchLayoutGroupContext = (0, import_react26.createContext)({});
5707
+ var import_react29 = require("react");
5708
+ var SwitchLayoutGroupContext = (0, import_react29.createContext)({});
5698
5709
 
5699
5710
  // node_modules/framer-motion/dist/es/motion/utils/use-visual-element.mjs
5700
5711
  function useVisualElement(Component2, visualState, props, createVisualElement, ProjectionNodeConstructor) {
5701
5712
  var _a, _b;
5702
- const { visualElement: parent } = (0, import_react27.useContext)(MotionContext);
5703
- const lazyContext = (0, import_react27.useContext)(LazyContext);
5704
- const presenceContext = (0, import_react27.useContext)(PresenceContext);
5705
- const reducedMotionConfig = (0, import_react27.useContext)(MotionConfigContext).reducedMotion;
5706
- 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);
5707
5718
  createVisualElement = createVisualElement || lazyContext.renderer;
5708
5719
  if (!visualElementRef.current && createVisualElement) {
5709
5720
  visualElementRef.current = createVisualElement(Component2, {
@@ -5716,18 +5727,18 @@ function useVisualElement(Component2, visualState, props, createVisualElement, P
5716
5727
  });
5717
5728
  }
5718
5729
  const visualElement = visualElementRef.current;
5719
- const initialLayoutGroupConfig = (0, import_react27.useContext)(SwitchLayoutGroupContext);
5730
+ const initialLayoutGroupConfig = (0, import_react30.useContext)(SwitchLayoutGroupContext);
5720
5731
  if (visualElement && !visualElement.projection && ProjectionNodeConstructor && (visualElement.type === "html" || visualElement.type === "svg")) {
5721
5732
  createProjectionNode(visualElementRef.current, props, ProjectionNodeConstructor, initialLayoutGroupConfig);
5722
5733
  }
5723
- const isMounted = (0, import_react27.useRef)(false);
5724
- (0, import_react27.useInsertionEffect)(() => {
5734
+ const isMounted = (0, import_react30.useRef)(false);
5735
+ (0, import_react30.useInsertionEffect)(() => {
5725
5736
  if (visualElement && isMounted.current) {
5726
5737
  visualElement.update(props, presenceContext);
5727
5738
  }
5728
5739
  });
5729
5740
  const optimisedAppearId = props[optimizedAppearDataAttribute];
5730
- 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)));
5731
5742
  useIsomorphicLayoutEffect(() => {
5732
5743
  if (!visualElement)
5733
5744
  return;
@@ -5739,7 +5750,7 @@ function useVisualElement(Component2, visualState, props, createVisualElement, P
5739
5750
  visualElement.animationState.animateChanges();
5740
5751
  }
5741
5752
  });
5742
- (0, import_react27.useEffect)(() => {
5753
+ (0, import_react30.useEffect)(() => {
5743
5754
  if (!visualElement)
5744
5755
  return;
5745
5756
  if (!wantsHandoff.current && visualElement.animationState) {
@@ -5789,7 +5800,7 @@ function createRendererMotionComponent({ preloadedFeatures, createVisualElement,
5789
5800
  function MotionComponent(props, externalRef) {
5790
5801
  let MeasureLayout2;
5791
5802
  const configAndProps = {
5792
- ...(0, import_react28.useContext)(MotionConfigContext),
5803
+ ...(0, import_react31.useContext)(MotionConfigContext),
5793
5804
  ...props,
5794
5805
  layoutId: useLayoutId(props)
5795
5806
  };
@@ -5805,16 +5816,16 @@ function createRendererMotionComponent({ preloadedFeatures, createVisualElement,
5805
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)] });
5806
5817
  }
5807
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 : ""})`}`;
5808
- const ForwardRefMotionComponent = (0, import_react28.forwardRef)(MotionComponent);
5819
+ const ForwardRefMotionComponent = (0, import_react31.forwardRef)(MotionComponent);
5809
5820
  ForwardRefMotionComponent[motionComponentSymbol] = Component2;
5810
5821
  return ForwardRefMotionComponent;
5811
5822
  }
5812
5823
  function useLayoutId({ layoutId }) {
5813
- const layoutGroupId = (0, import_react28.useContext)(LayoutGroupContext).id;
5824
+ const layoutGroupId = (0, import_react31.useContext)(LayoutGroupContext).id;
5814
5825
  return layoutGroupId && layoutId !== void 0 ? layoutGroupId + "-" + layoutId : layoutId;
5815
5826
  }
5816
5827
  function useStrictMode(configAndProps, preloadedFeatures) {
5817
- const isStrict = (0, import_react28.useContext)(LazyContext).strict;
5828
+ const isStrict = (0, import_react31.useContext)(LazyContext).strict;
5818
5829
  if (process.env.NODE_ENV !== "production" && preloadedFeatures && isStrict) {
5819
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.";
5820
5831
  configAndProps.ignoreStrict ? warning(false, strictMessage) : invariant(false, strictMessage);
@@ -5888,7 +5899,7 @@ function isSVGComponent(Component2) {
5888
5899
  }
5889
5900
 
5890
5901
  // node_modules/framer-motion/dist/es/motion/utils/use-visual-state.mjs
5891
- var import_react29 = require("react");
5902
+ var import_react32 = require("react");
5892
5903
 
5893
5904
  // node_modules/framer-motion/dist/es/render/utils/resolve-variants.mjs
5894
5905
  function getValueState(visualElement) {
@@ -5949,8 +5960,8 @@ function makeState({ scrapeMotionValuesFromProps: scrapeMotionValuesFromProps3,
5949
5960
  return state;
5950
5961
  }
5951
5962
  var makeUseVisualState = (config) => (props, isStatic) => {
5952
- const context = (0, import_react29.useContext)(MotionContext);
5953
- const presenceContext = (0, import_react29.useContext)(PresenceContext);
5963
+ const context = (0, import_react32.useContext)(MotionContext);
5964
+ const presenceContext = (0, import_react32.useContext)(PresenceContext);
5954
5965
  const make = () => makeState(config, props, context, presenceContext);
5955
5966
  return isStatic ? make() : useConstant(make);
5956
5967
  };
@@ -6470,10 +6481,10 @@ var htmlMotionConfig = {
6470
6481
  };
6471
6482
 
6472
6483
  // node_modules/framer-motion/dist/es/render/dom/use-render.mjs
6473
- var import_react32 = require("react");
6484
+ var import_react35 = require("react");
6474
6485
 
6475
6486
  // node_modules/framer-motion/dist/es/render/html/use-props.mjs
6476
- var import_react30 = require("react");
6487
+ var import_react33 = require("react");
6477
6488
  function copyRawValuesOnly(target, source, props) {
6478
6489
  for (const key in source) {
6479
6490
  if (!isMotionValue(source[key]) && !isForcedMotionValue(key, props)) {
@@ -6482,7 +6493,7 @@ function copyRawValuesOnly(target, source, props) {
6482
6493
  }
6483
6494
  }
6484
6495
  function useInitialMotionValues({ transformTemplate }, visualState) {
6485
- return (0, import_react30.useMemo)(() => {
6496
+ return (0, import_react33.useMemo)(() => {
6486
6497
  const state = createHtmlRenderState();
6487
6498
  buildHTMLStyles(state, visualState, transformTemplate);
6488
6499
  return Object.assign({}, state.vars, state.style);
@@ -6511,9 +6522,9 @@ function useHTMLProps(props, visualState) {
6511
6522
  }
6512
6523
 
6513
6524
  // node_modules/framer-motion/dist/es/render/svg/use-props.mjs
6514
- var import_react31 = require("react");
6525
+ var import_react34 = require("react");
6515
6526
  function useSVGProps(props, visualState, _isStatic, Component2) {
6516
- const visualProps = (0, import_react31.useMemo)(() => {
6527
+ const visualProps = (0, import_react34.useMemo)(() => {
6517
6528
  const state = createSvgRenderState();
6518
6529
  buildSVGAttrs(state, visualState, isSVGTag(Component2), props.transformTemplate);
6519
6530
  return {
@@ -6535,10 +6546,10 @@ function createUseRender(forwardMotionProps = false) {
6535
6546
  const useVisualProps = isSVGComponent(Component2) ? useSVGProps : useHTMLProps;
6536
6547
  const visualProps = useVisualProps(props, latestValues, isStatic, Component2);
6537
6548
  const filteredProps = filterProps(props, typeof Component2 === "string", forwardMotionProps);
6538
- const elementProps = Component2 !== import_react32.Fragment ? { ...filteredProps, ...visualProps, ref } : {};
6549
+ const elementProps = Component2 !== import_react35.Fragment ? { ...filteredProps, ...visualProps, ref } : {};
6539
6550
  const { children } = props;
6540
- const renderedChildren = (0, import_react32.useMemo)(() => isMotionValue(children) ? children.get() : children, [children]);
6541
- 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, {
6542
6553
  ...elementProps,
6543
6554
  children: renderedChildren
6544
6555
  });
@@ -10592,7 +10603,7 @@ var PanGesture = class extends Feature {
10592
10603
 
10593
10604
  // node_modules/framer-motion/dist/es/motion/features/layout/MeasureLayout.mjs
10594
10605
  var import_jsx_runtime17 = require("react/jsx-runtime");
10595
- var import_react33 = require("react");
10606
+ var import_react36 = require("react");
10596
10607
 
10597
10608
  // node_modules/framer-motion/dist/es/projection/node/state.mjs
10598
10609
  var globalProjectionState = {
@@ -10654,7 +10665,7 @@ var correctBoxShadow = {
10654
10665
  };
10655
10666
 
10656
10667
  // node_modules/framer-motion/dist/es/motion/features/layout/MeasureLayout.mjs
10657
- var MeasureLayoutWithContext = class extends import_react33.Component {
10668
+ var MeasureLayoutWithContext = class extends import_react36.Component {
10658
10669
  /**
10659
10670
  * This only mounts projection nodes for components that
10660
10671
  * need measuring, we might want to do it for all components
@@ -10738,8 +10749,8 @@ var MeasureLayoutWithContext = class extends import_react33.Component {
10738
10749
  };
10739
10750
  function MeasureLayout(props) {
10740
10751
  const [isPresent, safeToRemove] = usePresence();
10741
- const layoutGroup = (0, import_react33.useContext)(LayoutGroupContext);
10742
- 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 });
10743
10754
  }
10744
10755
  var defaultScaleCorrectors = {
10745
10756
  borderRadius: {
@@ -12361,7 +12372,7 @@ var layout = {
12361
12372
  };
12362
12373
 
12363
12374
  // node_modules/framer-motion/dist/es/render/dom/create-visual-element.mjs
12364
- var import_react34 = require("react");
12375
+ var import_react37 = require("react");
12365
12376
 
12366
12377
  // node_modules/framer-motion/dist/es/utils/reduced-motion/state.mjs
12367
12378
  var prefersReducedMotion = { current: null };
@@ -12874,7 +12885,7 @@ var SVGVisualElement = class extends DOMVisualElement {
12874
12885
  // node_modules/framer-motion/dist/es/render/dom/create-visual-element.mjs
12875
12886
  var createDomVisualElement = (Component2, options) => {
12876
12887
  return isSVGComponent(Component2) ? new SVGVisualElement(options) : new HTMLVisualElement(options, {
12877
- allowProjection: Component2 !== import_react34.Fragment
12888
+ allowProjection: Component2 !== import_react37.Fragment
12878
12889
  });
12879
12890
  };
12880
12891
 
@@ -12890,6 +12901,7 @@ var createMotionComponent = /* @__PURE__ */ createMotionComponentFactory({
12890
12901
  var motion = /* @__PURE__ */ createDOMMotionComponentProxy(createMotionComponent);
12891
12902
 
12892
12903
  // components/Flashcard.tsx
12904
+ var import_react39 = require("react");
12893
12905
  var import_jsx_runtime18 = require("react/jsx-runtime");
12894
12906
  var FRONT_BY_THEME = {
12895
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)]",
@@ -12911,17 +12923,13 @@ var BACK_BY_THEME = {
12911
12923
  retro: "from-zinc-800 to-black text-lime-400 font-mono",
12912
12924
  motion: "from-indigo-600 via-purple-600 to-indigo-700 text-white transition-all duration-500"
12913
12925
  };
12914
- function Flashcard({
12915
- question,
12916
- answer,
12917
- className,
12918
- ...props
12919
- }) {
12920
- 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);
12921
12928
  const { theme } = useTheme();
12922
12929
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12923
12930
  "div",
12924
12931
  {
12932
+ ref,
12925
12933
  className: cn(
12926
12934
  "group relative h-64 w-full cursor-pointer [perspective:1000px]",
12927
12935
  className
@@ -12977,9 +12985,10 @@ function Flashcard({
12977
12985
  )
12978
12986
  }
12979
12987
  );
12980
- }
12988
+ });
12981
12989
 
12982
12990
  // components/GraphicCard.tsx
12991
+ var import_react40 = require("react");
12983
12992
  var import_jsx_runtime19 = require("react/jsx-runtime");
12984
12993
  var SURFACE_BY_THEME = {
12985
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)]",
@@ -12991,11 +13000,7 @@ var SURFACE_BY_THEME = {
12991
13000
  retro: "bg-white border-2 border-black font-mono shadow-[4px_4px_0_0_rgba(0,0,0,1)]",
12992
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"
12993
13002
  };
12994
- function GraphicCard({
12995
- children,
12996
- className,
12997
- ...props
12998
- }) {
13003
+ var GraphicCard = (0, import_react40.forwardRef)(function GraphicCard2({ children, className, ...props }, ref) {
12999
13004
  const { theme } = useTheme();
13000
13005
  const surface = SURFACE_BY_THEME[theme];
13001
13006
  const isDark = theme === "night" || theme === "cyberpunk";
@@ -13004,6 +13009,7 @@ function GraphicCard({
13004
13009
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
13005
13010
  "div",
13006
13011
  {
13012
+ ref,
13007
13013
  className: cn(
13008
13014
  "group relative w-full overflow-hidden rounded-2xl p-6 transition-all duration-300",
13009
13015
  surface,
@@ -13017,10 +13023,10 @@ function GraphicCard({
13017
13023
  ]
13018
13024
  }
13019
13025
  );
13020
- }
13026
+ });
13021
13027
 
13022
13028
  // components/Input.tsx
13023
- var import_react36 = require("react");
13029
+ var import_react41 = require("react");
13024
13030
  var import_jsx_runtime20 = require("react/jsx-runtime");
13025
13031
  var inputVariants = cva(
13026
13032
  "w-full rounded-lg px-3 py-2 text-sm outline-none transition-shadow",
@@ -13037,7 +13043,7 @@ var inputVariants = cva(
13037
13043
  }
13038
13044
  }
13039
13045
  );
13040
- var Input = (0, import_react36.forwardRef)(function Input2({
13046
+ var Input = (0, import_react41.forwardRef)(function Input2({
13041
13047
  label,
13042
13048
  error,
13043
13049
  helperText,
@@ -13045,6 +13051,7 @@ var Input = (0, import_react36.forwardRef)(function Input2({
13045
13051
  suffix,
13046
13052
  size = "md",
13047
13053
  className,
13054
+ style,
13048
13055
  id: idProp,
13049
13056
  disabled,
13050
13057
  theme: themeProp,
@@ -13073,13 +13080,12 @@ var Input = (0, import_react36.forwardRef)(function Input2({
13073
13080
  themeClass,
13074
13081
  error && "border-red-500 focus:ring-red-500 focus:border-red-500",
13075
13082
  hasAddon && "rounded-none first:rounded-l-lg last:rounded-r-lg",
13076
- !hasAddon && "rounded-lg",
13077
- className
13083
+ !hasAddon && "rounded-lg"
13078
13084
  ),
13079
13085
  ...props
13080
13086
  }
13081
13087
  );
13082
- 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: [
13083
13089
  label && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
13084
13090
  "label",
13085
13091
  {
@@ -13115,12 +13121,12 @@ var Input = (0, import_react36.forwardRef)(function Input2({
13115
13121
  });
13116
13122
 
13117
13123
  // src/hooks/useFocusTrap.ts
13118
- var import_react37 = require("react");
13124
+ var import_react42 = require("react");
13119
13125
  function useFocusTrap(active, options) {
13120
- const containerRef = (0, import_react37.useRef)(null);
13121
- const previousFocusRef = (0, import_react37.useRef)(null);
13126
+ const containerRef = (0, import_react42.useRef)(null);
13127
+ const previousFocusRef = (0, import_react42.useRef)(null);
13122
13128
  const { returnFocus = true } = options ?? {};
13123
- const getFocusables = (0, import_react37.useCallback)((el) => {
13129
+ const getFocusables = (0, import_react42.useCallback)((el) => {
13124
13130
  const selector = [
13125
13131
  "a[href]",
13126
13132
  "button:not([disabled])",
@@ -13133,7 +13139,7 @@ function useFocusTrap(active, options) {
13133
13139
  (node) => node.offsetParent !== null
13134
13140
  );
13135
13141
  }, []);
13136
- (0, import_react37.useEffect)(() => {
13142
+ (0, import_react42.useEffect)(() => {
13137
13143
  if (!active || !containerRef.current) return;
13138
13144
  previousFocusRef.current = (typeof document !== "undefined" ? document.activeElement : null) ?? null;
13139
13145
  const container = containerRef.current;
@@ -13168,7 +13174,7 @@ function useFocusTrap(active, options) {
13168
13174
  }
13169
13175
 
13170
13176
  // components/Modal.tsx
13171
- var import_react38 = require("react");
13177
+ var import_react43 = require("react");
13172
13178
  var import_jsx_runtime21 = require("react/jsx-runtime");
13173
13179
  var modalVariants = cva(
13174
13180
  "relative z-10 max-h-[90vh] w-full max-w-[calc(100vw-2rem)] overflow-auto rounded-xl p-4 sm:p-6",
@@ -13185,7 +13191,7 @@ var modalVariants = cva(
13185
13191
  }
13186
13192
  }
13187
13193
  );
13188
- function Modal({
13194
+ var Modal = (0, import_react43.forwardRef)(function Modal2({
13189
13195
  open,
13190
13196
  onClose,
13191
13197
  title,
@@ -13194,18 +13200,19 @@ function Modal({
13194
13200
  style,
13195
13201
  children,
13196
13202
  theme: themeProp
13197
- }) {
13203
+ }, ref) {
13198
13204
  const { theme: contextTheme } = useTheme();
13199
13205
  const theme = themeProp ?? contextTheme;
13200
13206
  const themeClass = getThemeClass(theme, "modal", "default");
13201
13207
  const focusTrapRef = useFocusTrap(open, { returnFocus: true });
13202
- const handleEscape = (0, import_react38.useCallback)(
13208
+ const mergedRef = mergeRefs(ref, focusTrapRef);
13209
+ const handleEscape = (0, import_react43.useCallback)(
13203
13210
  (e) => {
13204
13211
  if (e.key === "Escape") onClose();
13205
13212
  },
13206
13213
  [onClose]
13207
13214
  );
13208
- (0, import_react38.useEffect)(() => {
13215
+ (0, import_react43.useEffect)(() => {
13209
13216
  if (!open) return;
13210
13217
  document.addEventListener("keydown", handleEscape);
13211
13218
  document.body.style.overflow = "hidden";
@@ -13235,7 +13242,7 @@ function Modal({
13235
13242
  /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
13236
13243
  "div",
13237
13244
  {
13238
- ref: focusTrapRef,
13245
+ ref: mergedRef,
13239
13246
  className: cn(modalVariants({ size }), themeClass, className),
13240
13247
  style,
13241
13248
  children: [
@@ -13268,42 +13275,43 @@ function Modal({
13268
13275
  ]
13269
13276
  }
13270
13277
  );
13271
- }
13278
+ });
13272
13279
 
13273
13280
  // components/Navbar.tsx
13274
- var import_react39 = require("react");
13281
+ var import_react44 = require("react");
13275
13282
  var import_jsx_runtime22 = require("react/jsx-runtime");
13276
- function Navbar({
13277
- children,
13278
- logo,
13279
- items,
13280
- right,
13281
- className,
13282
- style
13283
- }) {
13284
- const [mobileOpen, setMobileOpen] = (0, import_react39.useState)(false);
13285
- const navRef = (0, import_react39.useRef)(null);
13283
+ var DARK_PANEL_THEMES = ["night", "glass", "cyberpunk"];
13284
+ function mobilePanelOpaqueClasses(theme) {
13285
+ if (DARK_PANEL_THEMES.includes(theme)) {
13286
+ return "bg-zinc-900 text-zinc-100 border-zinc-700";
13287
+ }
13288
+ return "bg-white text-zinc-900 border-zinc-200";
13289
+ }
13290
+ var Navbar = (0, import_react44.forwardRef)(function Navbar2({ children, logo, items, right, mobileMenuExtra, className, style }, ref) {
13291
+ const [mobileOpen, setMobileOpen] = (0, import_react44.useState)(false);
13292
+ const navRef = (0, import_react44.useRef)(null);
13293
+ const wrapperRef = (0, import_react44.useRef)(null);
13294
+ const mergedNavRef = mergeRefs(ref, navRef);
13286
13295
  const { theme } = useTheme();
13287
13296
  const themeClass = getThemeClass(theme, "navbar", "default");
13288
- const mobilePanelBgOverride = theme === "glass" ? "bg-white/95 backdrop-blur-xl" : theme === "clay" ? "bg-white/95" : null;
13289
13297
  useClickOutside(
13290
- navRef,
13291
- (0, import_react39.useCallback)(() => setMobileOpen(false), []),
13298
+ wrapperRef,
13299
+ (0, import_react44.useCallback)(() => setMobileOpen(false), []),
13292
13300
  { enabled: mobileOpen }
13293
13301
  );
13294
13302
  const hasResponsiveNav = items != null && items.length > 0;
13295
13303
  if (hasResponsiveNav) {
13296
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
13304
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
13297
13305
  "nav",
13298
13306
  {
13299
- ref: navRef,
13307
+ ref: mergedNavRef,
13300
13308
  className: cn(
13301
13309
  "relative sticky top-0 z-50 flex h-14 w-full flex-col px-3 sm:px-4",
13302
13310
  themeClass,
13303
13311
  className
13304
13312
  ),
13305
13313
  style,
13306
- children: [
13314
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { ref: wrapperRef, className: "flex min-h-14 w-full flex-col", children: [
13307
13315
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex h-14 w-full min-w-0 shrink-0 items-center justify-between gap-2", children: [
13308
13316
  logo != null ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex min-w-0 shrink-0 items-center overflow-hidden", children: logo }) : null,
13309
13317
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "hidden flex-1 items-center justify-end gap-4 sm:flex", children: [
@@ -13333,35 +13341,46 @@ function Navbar({
13333
13341
  )
13334
13342
  ] })
13335
13343
  ] }),
13336
- mobileOpen && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
13344
+ mobileOpen && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
13337
13345
  "div",
13338
13346
  {
13339
13347
  className: cn(
13340
- "absolute left-0 right-0 top-14 z-10 flex flex-col gap-1 border-t border-inherit px-3 py-3 shadow-lg sm:hidden",
13341
- themeClass,
13342
- mobilePanelBgOverride
13348
+ "absolute left-0 right-0 top-14 z-10 flex flex-col gap-1 border-t px-3 py-3 shadow-lg sm:hidden",
13349
+ mobilePanelOpaqueClasses(theme)
13343
13350
  ),
13344
13351
  role: "dialog",
13345
13352
  "aria-label": "Navigation menu",
13346
- children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
13347
- "a",
13348
- {
13349
- href: item.href,
13350
- className: "block rounded-lg px-3 py-2.5 text-sm font-medium text-inherit opacity-90 transition-opacity hover:opacity-100",
13351
- onClick: () => setMobileOpen(false),
13352
- children: item.label
13353
- },
13354
- item.href
13355
- ))
13353
+ children: [
13354
+ items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
13355
+ "a",
13356
+ {
13357
+ href: item.href,
13358
+ className: "block rounded-lg px-3 py-2.5 text-sm font-medium text-inherit opacity-90 transition-opacity hover:opacity-100",
13359
+ onClick: () => setMobileOpen(false),
13360
+ children: item.label
13361
+ },
13362
+ item.href
13363
+ )),
13364
+ mobileMenuExtra != null ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
13365
+ "div",
13366
+ {
13367
+ className: "mt-2 border-t border-inherit pt-3",
13368
+ onClick: () => setMobileOpen(false),
13369
+ role: "presentation",
13370
+ children: mobileMenuExtra
13371
+ }
13372
+ ) : null
13373
+ ]
13356
13374
  }
13357
13375
  )
13358
- ]
13376
+ ] })
13359
13377
  }
13360
13378
  );
13361
13379
  }
13362
13380
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
13363
13381
  "nav",
13364
13382
  {
13383
+ ref: mergedNavRef,
13365
13384
  className: cn(
13366
13385
  "sticky top-0 z-50 flex h-14 w-full flex-wrap items-center gap-2 px-3 sm:px-4",
13367
13386
  themeClass,
@@ -13371,21 +13390,18 @@ function Navbar({
13371
13390
  children
13372
13391
  }
13373
13392
  );
13374
- }
13393
+ });
13375
13394
 
13376
13395
  // components/PricingCard.tsx
13396
+ var import_react45 = require("react");
13377
13397
  var import_jsx_runtime23 = require("react/jsx-runtime");
13378
- function PricingCard({
13379
- tier,
13380
- onSelect,
13381
- className,
13382
- style
13383
- }) {
13398
+ var PricingCard = (0, import_react45.forwardRef)(function PricingCard2({ tier, onSelect, className, style }, ref) {
13384
13399
  const { theme } = useTheme();
13385
13400
  const themeClass = getThemeClass(theme, "pricingCard", "default");
13386
13401
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
13387
13402
  "div",
13388
13403
  {
13404
+ ref,
13389
13405
  className: cn(
13390
13406
  "flex flex-col rounded-xl p-4 sm:p-6",
13391
13407
  themeClass,
@@ -13413,36 +13429,47 @@ function PricingCard({
13413
13429
  ]
13414
13430
  }
13415
13431
  );
13416
- }
13432
+ });
13417
13433
 
13418
13434
  // components/ProgressBar.tsx
13435
+ var import_react46 = require("react");
13419
13436
  var import_jsx_runtime24 = require("react/jsx-runtime");
13420
- function ProgressBar({
13437
+ var ProgressBar = (0, import_react46.forwardRef)(function ProgressBar2({
13421
13438
  value,
13422
13439
  max = 100,
13423
13440
  segmented = false,
13424
13441
  className,
13425
13442
  style,
13443
+ "aria-label": ariaLabel,
13426
13444
  trackColor,
13427
13445
  activeColor
13428
- }) {
13446
+ }, ref) {
13429
13447
  const { theme } = useTheme();
13430
13448
  const themeClass = getThemeClass(theme, "progress", "default");
13431
13449
  const pct = Math.min(100, Math.max(0, value / max * 100));
13432
13450
  const trackStyle = trackColor ? { backgroundColor: trackColor } : void 0;
13433
13451
  const fillStyle = activeColor ? { width: `${pct}%`, backgroundColor: activeColor } : { width: `${pct}%` };
13452
+ const progressRole = {
13453
+ role: "progressbar",
13454
+ "aria-valuenow": value,
13455
+ "aria-valuemin": 0,
13456
+ "aria-valuemax": max,
13457
+ ...ariaLabel && { "aria-label": ariaLabel }
13458
+ };
13434
13459
  if (segmented) {
13435
13460
  const segments = 10;
13436
13461
  const filled = Math.round(pct / 100 * segments);
13437
13462
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13438
13463
  "div",
13439
13464
  {
13465
+ ref,
13440
13466
  className: cn(
13441
13467
  "flex h-3 w-full gap-0.5 overflow-hidden rounded-full",
13442
13468
  themeClass,
13443
13469
  className
13444
13470
  ),
13445
13471
  style: { ...style, ...trackStyle },
13472
+ ...progressRole,
13446
13473
  children: Array.from({ length: segments }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13447
13474
  "div",
13448
13475
  {
@@ -13460,12 +13487,14 @@ function ProgressBar({
13460
13487
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13461
13488
  "div",
13462
13489
  {
13490
+ ref,
13463
13491
  className: cn(
13464
13492
  "relative h-3 w-full overflow-hidden rounded-full",
13465
13493
  themeClass,
13466
13494
  className
13467
13495
  ),
13468
13496
  style: { ...style, ...trackStyle },
13497
+ ...progressRole,
13469
13498
  children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13470
13499
  "span",
13471
13500
  {
@@ -13475,40 +13504,33 @@ function ProgressBar({
13475
13504
  )
13476
13505
  }
13477
13506
  );
13478
- }
13507
+ });
13479
13508
 
13480
13509
  // components/SectionHeader.tsx
13510
+ var import_react47 = require("react");
13481
13511
  var import_jsx_runtime25 = require("react/jsx-runtime");
13482
- function SectionHeader({
13483
- title,
13484
- subtitle,
13485
- className,
13486
- style
13487
- }) {
13512
+ var SectionHeader = (0, import_react47.forwardRef)(function SectionHeader2({ title, subtitle, className, style }, ref) {
13488
13513
  const { theme } = useTheme();
13489
13514
  const themeClass = getThemeClass(theme, "sectionHeader", "default");
13490
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("header", { className: cn("pb-4", themeClass, className), style, children: [
13515
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("header", { ref, className: cn("pb-4", themeClass, className), style, children: [
13491
13516
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: "text-lg font-semibold sm:text-xl", children: title }),
13492
13517
  subtitle ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "mt-1 text-sm opacity-80", children: subtitle }) : null,
13493
13518
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-3 border-b border-inherit" })
13494
13519
  ] });
13495
- }
13520
+ });
13496
13521
 
13497
13522
  // components/Sidebar.tsx
13498
- var import_react40 = require("react");
13523
+ var import_react48 = require("react");
13499
13524
  var import_jsx_runtime26 = require("react/jsx-runtime");
13500
- function Sidebar({
13501
- children,
13502
- className,
13503
- style
13504
- }) {
13505
- const [collapsed, setCollapsed] = (0, import_react40.useState)(false);
13525
+ var Sidebar = (0, import_react48.forwardRef)(function Sidebar2({ children, className, style }, ref) {
13526
+ const [collapsed, setCollapsed] = (0, import_react48.useState)(false);
13506
13527
  const { theme } = useTheme();
13507
13528
  const themeClass = getThemeClass(theme, "sidebar", "default");
13508
- const toggle = (0, import_react40.useCallback)(() => setCollapsed((c) => !c), []);
13529
+ const toggle = (0, import_react48.useCallback)(() => setCollapsed((c) => !c), []);
13509
13530
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
13510
13531
  "aside",
13511
13532
  {
13533
+ ref,
13512
13534
  className: cn(
13513
13535
  "flex h-full flex-col transition-[width] duration-200",
13514
13536
  collapsed ? "w-12 sm:w-14" : "w-48 max-w-[85vw] sm:w-56 sm:max-w-none",
@@ -13531,10 +13553,10 @@ function Sidebar({
13531
13553
  ]
13532
13554
  }
13533
13555
  );
13534
- }
13556
+ });
13535
13557
 
13536
13558
  // components/Skeleton.tsx
13537
- var import_react41 = require("react");
13559
+ var import_react49 = require("react");
13538
13560
  var import_jsx_runtime27 = require("react/jsx-runtime");
13539
13561
  var skeletonVariants = cva("", {
13540
13562
  variants: {
@@ -13548,7 +13570,7 @@ var skeletonVariants = cva("", {
13548
13570
  variant: "rectangle"
13549
13571
  }
13550
13572
  });
13551
- var Skeleton = (0, import_react41.forwardRef)(
13573
+ var Skeleton = (0, import_react49.forwardRef)(
13552
13574
  function Skeleton2({ variant = "rectangle", className, theme: themeProp, style, ...props }, ref) {
13553
13575
  const { theme: contextTheme } = useTheme();
13554
13576
  const theme = themeProp ?? contextTheme;
@@ -13574,7 +13596,7 @@ var Skeleton = (0, import_react41.forwardRef)(
13574
13596
  );
13575
13597
 
13576
13598
  // components/Slider.tsx
13577
- var import_react42 = require("react");
13599
+ var import_react50 = require("react");
13578
13600
  var import_jsx_runtime28 = require("react/jsx-runtime");
13579
13601
  var sliderVariants = cva(
13580
13602
  "relative flex w-full touch-none items-center overflow-visible py-1",
@@ -13595,7 +13617,7 @@ var trackVariants = cva(
13595
13617
  "relative h-3 w-full rounded-full overflow-visible",
13596
13618
  { variants: {}, defaultVariants: {} }
13597
13619
  );
13598
- var Slider = (0, import_react42.forwardRef)(function Slider2({
13620
+ var Slider = (0, import_react50.forwardRef)(function Slider2({
13599
13621
  min = 0,
13600
13622
  max = 100,
13601
13623
  step = 1,
@@ -13604,17 +13626,18 @@ var Slider = (0, import_react42.forwardRef)(function Slider2({
13604
13626
  onValueChange,
13605
13627
  size = "md",
13606
13628
  className,
13629
+ style,
13607
13630
  theme: themeProp,
13608
13631
  ...props
13609
13632
  }, ref) {
13610
- const [uncontrolled, setUncontrolled] = (0, import_react42.useState)(defaultValue);
13633
+ const [uncontrolled, setUncontrolled] = (0, import_react50.useState)(defaultValue);
13611
13634
  const isControlled = controlledValue !== void 0;
13612
13635
  const value = isControlled ? controlledValue : uncontrolled;
13613
13636
  const { theme: contextTheme } = useTheme();
13614
13637
  const theme = themeProp ?? contextTheme;
13615
13638
  const themeClass = getThemeClass(theme, "slider", "default");
13616
13639
  const pct = (value - min) / (max - min) * 100;
13617
- const handleChange = (0, import_react42.useCallback)(
13640
+ const handleChange = (0, import_react50.useCallback)(
13618
13641
  (e) => {
13619
13642
  const next = Number(e.target.value);
13620
13643
  if (!isControlled) setUncontrolled(next);
@@ -13622,7 +13645,7 @@ var Slider = (0, import_react42.forwardRef)(function Slider2({
13622
13645
  },
13623
13646
  [isControlled, onValueChange]
13624
13647
  );
13625
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(sliderVariants({ size }), className), children: [
13648
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(sliderVariants({ size }), className), style, children: [
13626
13649
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(trackVariants(), themeClass), children: [
13627
13650
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
13628
13651
  "span",
@@ -13660,20 +13683,15 @@ var Slider = (0, import_react42.forwardRef)(function Slider2({
13660
13683
  });
13661
13684
 
13662
13685
  // components/StatsCard.tsx
13686
+ var import_react51 = require("react");
13663
13687
  var import_jsx_runtime29 = require("react/jsx-runtime");
13664
- function StatsCard({
13665
- label,
13666
- value,
13667
- trend,
13668
- className,
13669
- style
13670
- }) {
13688
+ var StatsCard = (0, import_react51.forwardRef)(function StatsCard2({ label, value, trend, className, style }, ref) {
13671
13689
  const { theme } = useTheme();
13672
13690
  const themeClass = getThemeClass(theme, "statsCard", "default");
13673
13691
  const isDark = theme === "night" || theme === "cyberpunk";
13674
13692
  const trendUpClass = trend?.direction === "up" ? isDark ? "text-emerald-400" : "text-emerald-600" : null;
13675
13693
  const trendDownClass = trend?.direction === "down" ? isDark ? "text-rose-400" : "text-rose-600" : null;
13676
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cn("rounded-xl p-6", themeClass, className), style, children: [
13694
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { ref, className: cn("rounded-xl p-6", themeClass, className), style, children: [
13677
13695
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-sm font-medium opacity-80", children: label }),
13678
13696
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mt-2 text-2xl font-bold tracking-tight", children: value }),
13679
13697
  trend ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
@@ -13690,10 +13708,10 @@ function StatsCard({
13690
13708
  }
13691
13709
  ) : null
13692
13710
  ] });
13693
- }
13711
+ });
13694
13712
 
13695
13713
  // components/Tabs.tsx
13696
- var import_react43 = require("react");
13714
+ var import_react52 = require("react");
13697
13715
  var import_jsx_runtime30 = require("react/jsx-runtime");
13698
13716
  var tabsListVariants = cva(
13699
13717
  "flex min-w-0 overflow-x-auto scrollbar-thin -mx-1 px-1 sm:mx-0 sm:overflow-visible",
@@ -13716,7 +13734,7 @@ var tabTriggerVariants = cva(
13716
13734
  }
13717
13735
  }
13718
13736
  );
13719
- function Tabs({
13737
+ var Tabs = (0, import_react52.forwardRef)(function Tabs2({
13720
13738
  items,
13721
13739
  defaultValue,
13722
13740
  value: controlledValue,
@@ -13724,31 +13742,31 @@ function Tabs({
13724
13742
  className,
13725
13743
  style,
13726
13744
  theme: themeProp
13727
- }) {
13728
- const [uncontrolled, setUncontrolled] = (0, import_react43.useState)(
13745
+ }, ref) {
13746
+ const [uncontrolled, setUncontrolled] = (0, import_react52.useState)(
13729
13747
  () => defaultValue ?? items[0]?.value ?? ""
13730
13748
  );
13731
13749
  const isControlled = controlledValue !== void 0;
13732
13750
  const value = isControlled ? controlledValue : uncontrolled;
13733
13751
  const activeIndex = items.findIndex((i) => i.value === value);
13734
13752
  const safeIndex = activeIndex >= 0 ? activeIndex : 0;
13735
- const triggerRefs = (0, import_react43.useRef)([]);
13753
+ const triggerRefs = (0, import_react52.useRef)([]);
13736
13754
  const { theme: contextTheme } = useTheme();
13737
13755
  const theme = themeProp ?? contextTheme;
13738
13756
  const listThemeClass = getThemeClass(theme, "tabs", "default");
13739
13757
  const triggerActiveClass = getThemeClass(theme, "tabs", "triggerActive");
13740
13758
  const triggerInactiveClass = getThemeClass(theme, "tabs", "triggerInactive");
13741
- const setValue = (0, import_react43.useCallback)(
13759
+ const setValue = (0, import_react52.useCallback)(
13742
13760
  (v) => {
13743
13761
  if (!isControlled) setUncontrolled(v);
13744
13762
  onValueChange?.(v);
13745
13763
  },
13746
13764
  [isControlled, onValueChange]
13747
13765
  );
13748
- (0, import_react43.useEffect)(() => {
13766
+ (0, import_react52.useEffect)(() => {
13749
13767
  triggerRefs.current = triggerRefs.current.slice(0, items.length);
13750
13768
  }, [items.length]);
13751
- const handleKeyDown = (0, import_react43.useCallback)(
13769
+ const handleKeyDown = (0, import_react52.useCallback)(
13752
13770
  (e) => {
13753
13771
  if (e.key === "ArrowLeft") {
13754
13772
  e.preventDefault();
@@ -13766,7 +13784,7 @@ function Tabs({
13766
13784
  );
13767
13785
  const activeItem = items[safeIndex];
13768
13786
  const content = activeItem?.content ?? null;
13769
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cn("w-full min-w-0", className), style, children: [
13787
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { ref, className: cn("w-full min-w-0", className), style, children: [
13770
13788
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
13771
13789
  "div",
13772
13790
  {
@@ -13810,22 +13828,19 @@ function Tabs({
13810
13828
  }
13811
13829
  )
13812
13830
  ] });
13813
- }
13831
+ });
13814
13832
 
13815
13833
  // components/Terminal.tsx
13834
+ var import_react53 = require("react");
13816
13835
  var import_jsx_runtime31 = require("react/jsx-runtime");
13817
- function Terminal({
13818
- title = "terminal",
13819
- children,
13820
- className,
13821
- style
13822
- }) {
13836
+ var Terminal = (0, import_react53.forwardRef)(function Terminal2({ title = "terminal", children, className, style }, ref) {
13823
13837
  const { theme } = useTheme();
13824
13838
  const themeClass = getThemeClass(theme, "terminal", "default");
13825
13839
  const isCyberpunk = theme === "cyberpunk";
13826
13840
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
13827
13841
  "div",
13828
13842
  {
13843
+ ref,
13829
13844
  className: cn("overflow-hidden rounded-xl font-mono text-sm", themeClass, className),
13830
13845
  style,
13831
13846
  children: [
@@ -13851,22 +13866,21 @@ function Terminal({
13851
13866
  ]
13852
13867
  }
13853
13868
  );
13854
- }
13869
+ });
13855
13870
 
13856
13871
  // components/Timeline.tsx
13872
+ var import_react54 = require("react");
13857
13873
  var import_jsx_runtime32 = require("react/jsx-runtime");
13858
- function Timeline({
13859
- items,
13860
- className,
13861
- theme: themeProp
13862
- }) {
13874
+ var Timeline = (0, import_react54.forwardRef)(function Timeline2({ items, className, style, theme: themeProp }, ref) {
13863
13875
  const { theme: contextTheme } = useTheme();
13864
13876
  const theme = themeProp ?? contextTheme;
13865
13877
  const themeClass = getThemeClass(theme, "timeline", "default");
13866
13878
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13867
13879
  "div",
13868
13880
  {
13881
+ ref,
13869
13882
  className: cn("relative pl-4", themeClass, className),
13883
+ style,
13870
13884
  role: "list",
13871
13885
  "aria-label": "Timeline",
13872
13886
  children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
@@ -13893,21 +13907,25 @@ function Timeline({
13893
13907
  ))
13894
13908
  }
13895
13909
  );
13896
- }
13910
+ });
13897
13911
 
13898
13912
  // components/Toast.tsx
13913
+ var import_react55 = require("react");
13899
13914
  var import_jsx_runtime33 = require("react/jsx-runtime");
13900
- function Toast({
13901
- message,
13902
- onDismiss,
13903
- className,
13904
- style
13905
- }) {
13915
+ var Toast = (0, import_react55.forwardRef)(function Toast2({ message, onDismiss, className, style }, ref) {
13906
13916
  const { theme } = useTheme();
13907
13917
  const themeClass = getThemeClass(theme, "toast", "default");
13918
+ (0, import_react55.useEffect)(() => {
13919
+ const handler = (e) => {
13920
+ if (e.key === "Escape") onDismiss();
13921
+ };
13922
+ document.addEventListener("keydown", handler);
13923
+ return () => document.removeEventListener("keydown", handler);
13924
+ }, [onDismiss]);
13908
13925
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
13909
13926
  "div",
13910
13927
  {
13928
+ ref,
13911
13929
  role: "alert",
13912
13930
  className: cn(
13913
13931
  "flex items-center justify-between gap-4 rounded-lg px-4 py-3 shadow-lg",
@@ -13930,10 +13948,10 @@ function Toast({
13930
13948
  ]
13931
13949
  }
13932
13950
  );
13933
- }
13951
+ });
13934
13952
 
13935
13953
  // components/Toggle.tsx
13936
- var import_react44 = require("react");
13954
+ var import_react56 = require("react");
13937
13955
  var import_jsx_runtime34 = require("react/jsx-runtime");
13938
13956
  var toggleVariants = cva(
13939
13957
  "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",
@@ -13942,17 +13960,18 @@ var toggleVariants = cva(
13942
13960
  defaultVariants: {}
13943
13961
  }
13944
13962
  );
13945
- var Toggle = (0, import_react44.forwardRef)(function Toggle2({
13963
+ var Toggle = (0, import_react56.forwardRef)(function Toggle2({
13946
13964
  checked: controlledChecked,
13947
13965
  defaultChecked = false,
13948
13966
  onCheckedChange,
13949
13967
  className,
13968
+ style,
13950
13969
  "aria-label": ariaLabel = "Toggle",
13951
13970
  theme: themeProp,
13952
13971
  disabled,
13953
13972
  ...props
13954
13973
  }, ref) {
13955
- const [uncontrolled, setUncontrolled] = (0, import_react44.useState)(defaultChecked);
13974
+ const [uncontrolled, setUncontrolled] = (0, import_react56.useState)(defaultChecked);
13956
13975
  const isControlled = controlledChecked !== void 0;
13957
13976
  const checked = isControlled ? controlledChecked : uncontrolled;
13958
13977
  const { theme: contextTheme } = useTheme();
@@ -13960,8 +13979,8 @@ var Toggle = (0, import_react44.forwardRef)(function Toggle2({
13960
13979
  const themeClass = getThemeClass(theme, "toggle", "default");
13961
13980
  const thumbOnDark = theme === "night" && checked;
13962
13981
  const thumbClass = thumbOnDark ? "bg-zinc-900 shadow-inner" : "bg-white shadow";
13963
- const id3 = (0, import_react44.useId)();
13964
- const handleChange = (0, import_react44.useCallback)(
13982
+ const id3 = (0, import_react56.useId)();
13983
+ const handleChange = (0, import_react56.useCallback)(
13965
13984
  (e) => {
13966
13985
  const next = e.target.checked;
13967
13986
  if (!isControlled) setUncontrolled(next);
@@ -13974,6 +13993,7 @@ var Toggle = (0, import_react44.forwardRef)(function Toggle2({
13974
13993
  {
13975
13994
  htmlFor: id3,
13976
13995
  className: cn(toggleVariants(), themeClass, className),
13996
+ style,
13977
13997
  "data-state": checked ? "on" : "off",
13978
13998
  children: [
13979
13999
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
@@ -14007,7 +14027,7 @@ var Toggle = (0, import_react44.forwardRef)(function Toggle2({
14007
14027
  });
14008
14028
 
14009
14029
  // components/Tooltip.tsx
14010
- var import_react45 = require("react");
14030
+ var import_react57 = require("react");
14011
14031
  var import_jsx_runtime35 = require("react/jsx-runtime");
14012
14032
  var placementClasses = {
14013
14033
  top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
@@ -14019,34 +14039,31 @@ var tooltipVariants = cva(
14019
14039
  "absolute z-50 whitespace-nowrap rounded-lg px-2 py-1 text-xs shadow-lg",
14020
14040
  { variants: {}, defaultVariants: {} }
14021
14041
  );
14022
- function Tooltip({
14023
- content,
14024
- children,
14025
- placement = "top",
14026
- className,
14027
- style,
14028
- theme: themeProp
14029
- }) {
14030
- const [visible, setVisible] = (0, import_react45.useState)(false);
14042
+ var Tooltip = (0, import_react57.forwardRef)(function Tooltip2({ content, children, placement = "top", className, style, theme: themeProp }, ref) {
14043
+ const [visible, setVisible] = (0, import_react57.useState)(false);
14044
+ const tooltipId = (0, import_react57.useId)();
14031
14045
  const { theme: contextTheme } = useTheme();
14032
14046
  const theme = themeProp ?? contextTheme;
14033
14047
  const themeClass = getThemeClass(theme, "tooltip", "default");
14034
- const show = (0, import_react45.useCallback)(() => setVisible(true), []);
14035
- const hide = (0, import_react45.useCallback)(() => setVisible(false), []);
14048
+ const show = (0, import_react57.useCallback)(() => setVisible(true), []);
14049
+ const hide = (0, import_react57.useCallback)(() => setVisible(false), []);
14036
14050
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
14037
14051
  "span",
14038
14052
  {
14053
+ ref,
14039
14054
  className: cn("relative inline-block", className),
14040
14055
  style,
14041
14056
  onMouseEnter: show,
14042
14057
  onMouseLeave: hide,
14043
14058
  onFocus: show,
14044
14059
  onBlur: hide,
14060
+ "aria-describedby": visible ? tooltipId : void 0,
14045
14061
  children: [
14046
14062
  children,
14047
14063
  visible ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
14048
14064
  "span",
14049
14065
  {
14066
+ id: tooltipId,
14050
14067
  role: "tooltip",
14051
14068
  className: cn(
14052
14069
  tooltipVariants(),
@@ -14059,7 +14076,7 @@ function Tooltip({
14059
14076
  ]
14060
14077
  }
14061
14078
  );
14062
- }
14079
+ });
14063
14080
 
14064
14081
  // lib/theme-recommendations.ts
14065
14082
  var THEME_BACKGROUNDS = {
@@ -14191,6 +14208,7 @@ var THEME_RECOMMENDATIONS = {
14191
14208
  cn,
14192
14209
  getNextListIndex,
14193
14210
  getThemeClass,
14211
+ mergeRefs,
14194
14212
  useClickOutside,
14195
14213
  useFocusTrap,
14196
14214
  useKeyboardNavigation,