@raxrai/stylelab-ui 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -61,6 +61,7 @@ __export(index_exports, {
61
61
  cn: () => cn,
62
62
  getNextListIndex: () => getNextListIndex,
63
63
  getThemeClass: () => getThemeClass,
64
+ mergeRefs: () => mergeRefs,
64
65
  useClickOutside: () => useClickOutside,
65
66
  useFocusTrap: () => useFocusTrap,
66
67
  useKeyboardNavigation: () => useKeyboardNavigation,
@@ -74,13 +75,13 @@ var import_react = require("react");
74
75
  // lib/theme-resolver.ts
75
76
  var themeMap = {
76
77
  minimal: {
77
- button: { primary: "bg-zinc-900 text-white border border-zinc-200 transition-colors duration-200 hover:bg-zinc-800 hover:border-zinc-300 hover:shadow-md", secondary: "bg-transparent border border-zinc-200 text-zinc-900 hover:bg-zinc-100", ghost: "text-zinc-700 hover:bg-zinc-100" },
78
+ button: { primary: "bg-zinc-900 text-white border border-zinc-200 transition-colors duration-200 hover:bg-zinc-800 hover:border-zinc-300 hover:shadow-md", secondary: "bg-transparent border border-zinc-200 text-zinc-900 hover:bg-zinc-100", ghost: "text-inherit hover:bg-zinc-100" },
78
79
  input: { default: "border border-zinc-200 text-zinc-900 placeholder:text-zinc-400 focus:ring-1 focus:ring-zinc-400 focus:border-zinc-400" },
79
80
  toggle: { default: "bg-zinc-200 data-[state=on]:bg-zinc-900" },
80
81
  badge: { default: "bg-zinc-100 text-zinc-700 border border-zinc-200" },
81
82
  slider: { default: "bg-zinc-200 [&_.slider-thumb]:bg-zinc-900" },
82
83
  tabs: { default: "border-b border-zinc-200", triggerActive: "border-zinc-900 font-semibold", triggerInactive: "opacity-70" },
83
- card: { default: "bg-white text-zinc-900 border border-zinc-200 shadow-none" },
84
+ card: { default: "bg-white border border-zinc-200 shadow-none" },
84
85
  bento: { default: "gap-4" },
85
86
  navbar: { default: "bg-white text-zinc-900 border-b border-zinc-200" },
86
87
  sidebar: { default: "bg-white text-zinc-900 border-r border-zinc-200" },
@@ -103,13 +104,13 @@ var themeMap = {
103
104
  timeline: { default: "border-l-2 border-zinc-200 text-zinc-900" }
104
105
  },
105
106
  night: {
106
- button: { primary: "bg-white text-zinc-950 border border-white/10 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.1)] transition-colors duration-200 hover:bg-zinc-100 hover:shadow-md hover:border-white/20", secondary: "bg-zinc-900 border border-white/10 text-white hover:bg-zinc-800", ghost: "text-zinc-300 hover:bg-white/5" },
107
+ button: { primary: "bg-white text-zinc-950 border border-white/10 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.1)] transition-colors duration-200 hover:bg-zinc-100 hover:shadow-md hover:border-white/20", secondary: "bg-zinc-900 border border-white/10 text-white hover:bg-zinc-800", ghost: "text-inherit hover:bg-white/5" },
107
108
  input: { default: "bg-zinc-900 text-zinc-100 border border-white/10 placeholder:text-zinc-500 focus:ring-1 focus:ring-white/20 shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]" },
108
109
  toggle: { default: "bg-zinc-800 data-[state=on]:bg-white shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]" },
109
110
  badge: { default: "bg-zinc-800 text-zinc-300 border border-white/10" },
110
111
  slider: { default: "bg-zinc-800 [&_.slider-thumb]:bg-white shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]" },
111
112
  tabs: { default: "border-b border-white/10", triggerActive: "border-white font-semibold", triggerInactive: "opacity-70" },
112
- card: { default: "bg-zinc-950 text-zinc-100 border border-white/10 shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]" },
113
+ card: { default: "bg-zinc-950 border border-white/10 shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]" },
113
114
  bento: { default: "gap-4" },
114
115
  navbar: { default: "bg-zinc-950 text-zinc-100 border-b border-white/10" },
115
116
  sidebar: { default: "bg-zinc-950 text-zinc-100 border-r border-white/10" },
@@ -132,13 +133,13 @@ var themeMap = {
132
133
  timeline: { default: "border-l-2 border-white/20 text-zinc-100" }
133
134
  },
134
135
  glass: {
135
- button: { primary: "rounded-xl bg-white/70 backdrop-blur-2xl border border-white/60 text-slate-800 shadow-glass-soft transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/80 hover:border-white/80 hover:shadow-glass-button-hover active:translate-y-0 active:shadow-glass-soft", secondary: "rounded-xl bg-white/50 backdrop-blur-2xl border border-white/60 text-slate-800 shadow-glass-soft transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/60 hover:border-white/80 hover:shadow-glass-button-hover active:translate-y-0 active:shadow-glass-soft", ghost: "rounded-xl text-slate-700 backdrop-blur-xl transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/40 hover:shadow-glass-soft hover:border hover:border-white/60" },
136
+ button: { primary: "rounded-xl bg-white/70 backdrop-blur-2xl border border-white/60 text-slate-800 shadow-glass-soft transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/80 hover:border-white/80 hover:shadow-glass-button-hover active:translate-y-0 active:shadow-glass-soft", secondary: "rounded-xl bg-white/50 backdrop-blur-2xl border border-white/60 text-slate-800 shadow-glass-soft transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/60 hover:border-white/80 hover:shadow-glass-button-hover active:translate-y-0 active:shadow-glass-soft", ghost: "rounded-xl text-inherit backdrop-blur-xl transition-all duration-200 ease-in-out hover:-translate-y-0.5 hover:bg-white/40 hover:shadow-glass-soft hover:border hover:border-white/60" },
136
137
  input: { default: "rounded-xl bg-white/50 backdrop-blur-2xl border border-slate-200/80 text-slate-800 shadow-glass-soft placeholder:text-slate-500 focus:ring-2 focus:ring-slate-300/50 focus:border-slate-300" },
137
138
  toggle: { default: "rounded-full bg-white/50 data-[state=on]:bg-white/80 backdrop-blur-2xl border border-white/60 shadow-glass-soft" },
138
139
  badge: { default: "rounded-xl bg-white/60 backdrop-blur-2xl text-slate-700 border border-white/60 shadow-glass-soft" },
139
140
  slider: { default: "rounded-full bg-white/50 [&_.slider-thumb]:bg-white [&_.slider-thumb]:border-slate-200 [&_.slider-thumb]:shadow-glass-soft backdrop-blur-2xl border border-white/60 shadow-glass-soft" },
140
141
  tabs: { default: "border-b border-slate-200/60", triggerActive: "border-slate-700 font-semibold", triggerInactive: "opacity-70" },
141
- card: { default: "rounded-2xl bg-white/60 backdrop-blur-2xl border border-white/60 text-slate-800 shadow-glass-lift" },
142
+ card: { default: "rounded-2xl bg-white/60 backdrop-blur-2xl border border-white/60 shadow-glass-lift" },
142
143
  bento: { default: "gap-4" },
143
144
  navbar: { default: "rounded-none bg-white/50 backdrop-blur-2xl border-b border-white/60 text-slate-800 shadow-glass-soft" },
144
145
  sidebar: { default: "rounded-none bg-white/50 backdrop-blur-2xl border-r border-white/60 text-slate-800 shadow-glass-soft" },
@@ -161,13 +162,13 @@ var themeMap = {
161
162
  timeline: { default: "border-l-2 border-slate-200/60 text-slate-800" }
162
163
  },
163
164
  neubrutal: {
164
- button: { primary: "rounded-none bg-[#FFD600] text-black border-4 border-black shadow-neubrutal hover:translate-x-1 hover:translate-y-1 hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)]", secondary: "rounded-none bg-[#FF5733] text-black border-4 border-black shadow-neubrutal hover:translate-x-1 hover:translate-y-1", ghost: "rounded-none border-4 border-transparent hover:border-black hover:bg-zinc-100 text-black" },
165
+ button: { primary: "rounded-none bg-[#FFD600] text-black border-4 border-black shadow-neubrutal hover:translate-x-1 hover:translate-y-1 hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)]", secondary: "rounded-none bg-[#FF5733] text-black border-4 border-black shadow-neubrutal hover:translate-x-1 hover:translate-y-1", ghost: "rounded-none text-inherit border-4 border-transparent hover:border-black hover:bg-zinc-100" },
165
166
  input: { default: "rounded-none border-4 border-black text-black placeholder:text-zinc-600 focus:ring-4 focus:ring-black/20 bg-white" },
166
167
  toggle: { default: "rounded-none border-4 border-black bg-white data-[state=on]:bg-[#FFD600] shadow-neubrutal" },
167
168
  badge: { default: "rounded-none bg-[#FFD600] text-black border-4 border-black" },
168
169
  slider: { default: "rounded-none border-4 border-black bg-white [&_.slider-thumb]:bg-[#FF5733] [&_.slider-thumb]:border-4 [&_.slider-thumb]:border-black" },
169
170
  tabs: { default: "border-b-4 border-black", triggerActive: "bg-[#FFD600] border-b-4 border-black font-bold -mb-[3px] pb-[5px] shadow-neubrutal", triggerInactive: "opacity-80" },
170
- card: { default: "rounded-none bg-white text-black border-4 border-black shadow-neubrutal" },
171
+ card: { default: "rounded-none bg-white border-4 border-black shadow-neubrutal" },
171
172
  bento: { default: "gap-4" },
172
173
  navbar: { default: "rounded-none bg-[#FFD600] text-black border-b-4 border-black shadow-neubrutal" },
173
174
  sidebar: { default: "rounded-none bg-[#FFD600]/30 border-r-4 border-black shadow-neubrutal text-black" },
@@ -190,13 +191,13 @@ var themeMap = {
190
191
  timeline: { default: "border-l-4 border-black text-black" }
191
192
  },
192
193
  clay: {
193
- button: { primary: "rounded-[40px] bg-rose-200 text-rose-900 border border-rose-300 shadow-clay-outer hover:shadow-[10px_10px_20px_rgba(0,0,0,0.08),inset_-8px_-8px_15px_rgba(0,0,0,0.2),inset_8px_8px_15px_rgba(255,255,255,0.4)]", secondary: "rounded-[40px] bg-sky-100 text-sky-900 shadow-clay-outer", ghost: "rounded-[40px] hover:bg-zinc-100 text-zinc-800" },
194
+ button: { primary: "rounded-[40px] bg-rose-200 text-rose-900 border border-rose-300 shadow-clay-outer hover:shadow-[10px_10px_20px_rgba(0,0,0,0.08),inset_-8px_-8px_15px_rgba(0,0,0,0.2),inset_8px_8px_15px_rgba(255,255,255,0.4)]", secondary: "rounded-[40px] bg-sky-100 text-sky-900 shadow-clay-outer", ghost: "rounded-[40px] text-inherit hover:bg-zinc-100" },
194
195
  input: { default: "rounded-[40px] border border-zinc-200 bg-zinc-50 text-zinc-900 placeholder:text-zinc-500 focus:ring-2 focus:ring-sky-300" },
195
196
  toggle: { default: "rounded-full bg-sky-100 data-[state=on]:bg-sky-300 data-[state=on]:shadow-clay-outer" },
196
197
  badge: { default: "rounded-[40px] bg-amber-100 text-amber-900" },
197
198
  slider: { default: "rounded-full bg-sky-100 [&_.slider-thumb]:rounded-full [&_.slider-thumb]:bg-rose-300" },
198
199
  tabs: { default: "border-b-2 border-zinc-200/80", triggerActive: "border-rose-600 font-semibold", triggerInactive: "opacity-70" },
199
- card: { default: "rounded-[40px] bg-rose-50 text-zinc-900 shadow-clay-outer border border-rose-100" },
200
+ card: { default: "rounded-[40px] bg-rose-50 shadow-clay-outer border border-rose-100" },
200
201
  bento: { default: "gap-4" },
201
202
  navbar: { default: "rounded-b-3xl bg-white/80 text-zinc-900 backdrop-blur-md shadow-clay-outer border-b border-zinc-200" },
202
203
  sidebar: { default: "rounded-r-3xl bg-sky-50 text-zinc-900 shadow-clay-outer border-r border-sky-100" },
@@ -219,13 +220,13 @@ var themeMap = {
219
220
  timeline: { default: "border-l-2 border-rose-200 text-zinc-900" }
220
221
  },
221
222
  cyberpunk: {
222
- button: { primary: "bg-transparent border-2 border-[#22d3ee] text-[#22d3ee] font-mono shadow-neon-glow hover:animate-glitch-anim", secondary: "bg-transparent border-2 border-[#ec4899] text-[#ec4899] font-mono hover:animate-glitch-anim", ghost: "text-[#22d3ee] font-mono hover:bg-[#22d3ee]/10" },
223
+ button: { primary: "bg-transparent border-2 border-[#22d3ee] text-[#22d3ee] font-mono shadow-neon-glow hover:animate-glitch-anim", secondary: "bg-transparent border-2 border-[#ec4899] text-[#ec4899] font-mono hover:animate-glitch-anim", ghost: "text-inherit font-mono hover:bg-[#22d3ee]/10" },
223
224
  input: { default: "bg-black border-2 border-[#22d3ee] text-[#22d3ee] placeholder:text-[#22d3ee]/50 font-mono focus:shadow-neon-glow" },
224
225
  toggle: { default: "bg-zinc-900 border-2 border-[#22d3ee] data-[state=on]:bg-[#22d3ee] data-[state=on]:shadow-neon-glow" },
225
226
  badge: { default: "bg-black border-2 border-[#ec4899] text-[#ec4899] font-mono" },
226
227
  slider: { default: "bg-zinc-900 [&_.slider-thumb]:border-2 [&_.slider-thumb]:border-[#22d3ee] [&_.slider-thumb]:bg-[#22d3ee] [&_.slider-thumb]:shadow-neon-glow" },
227
228
  tabs: { default: "border-b-2 border-[#22d3ee]", triggerActive: "text-[#22d3ee] border-[#22d3ee] font-bold shadow-neon-glow", triggerInactive: "opacity-50 text-[#22d3ee]/70" },
228
- card: { default: "bg-black text-[#22d3ee] border-2 border-[#22d3ee] shadow-neon-glow font-mono" },
229
+ card: { default: "bg-black border-2 border-[#22d3ee] shadow-neon-glow font-mono" },
229
230
  bento: { default: "gap-4" },
230
231
  navbar: { default: "bg-black text-[#22d3ee] border-b-2 border-[#22d3ee] font-mono" },
231
232
  sidebar: { default: "bg-black text-[#22d3ee] border-r-2 border-[#22d3ee] font-mono" },
@@ -248,13 +249,13 @@ var themeMap = {
248
249
  timeline: { default: "border-l-2 border-[#22d3ee] text-[#22d3ee] font-mono" }
249
250
  },
250
251
  retro: {
251
- button: { primary: "rounded-none bg-lime-500 text-black border-2 border-black font-mono shadow-[4px_4px_0_0_rgba(0,0,0,1)] hover:bg-lime-400 active:shadow-[2px_2px_0_0_rgba(0,0,0,1)]", secondary: "rounded-none bg-white text-black border-2 border-black font-mono shadow-[4px_4px_0_0_rgba(0,0,0,1)] hover:bg-zinc-100 active:shadow-[2px_2px_0_0_rgba(0,0,0,1)]", ghost: "rounded-none font-mono text-black border-2 border-transparent hover:border-black hover:bg-zinc-100" },
252
+ button: { primary: "rounded-none bg-lime-500 text-black border-2 border-black font-mono shadow-[4px_4px_0_0_rgba(0,0,0,1)] hover:bg-lime-400 active:shadow-[2px_2px_0_0_rgba(0,0,0,1)]", secondary: "rounded-none bg-white text-black border-2 border-black font-mono shadow-[4px_4px_0_0_rgba(0,0,0,1)] hover:bg-zinc-100 active:shadow-[2px_2px_0_0_rgba(0,0,0,1)]", ghost: "rounded-none font-mono text-inherit border-2 border-transparent hover:border-black hover:bg-zinc-100" },
252
253
  input: { default: "rounded-none border-2 border-black text-black placeholder:text-zinc-500 font-mono focus:ring-2 focus:ring-black focus:ring-offset-0 bg-white" },
253
254
  toggle: { default: "rounded-none border-2 border-black bg-zinc-200 data-[state=on]:bg-lime-500 shadow-[3px_3px_0_0_rgba(0,0,0,1)]" },
254
255
  badge: { default: "rounded-none bg-lime-500 text-black border-2 border-black font-mono" },
255
256
  slider: { default: "rounded-none border-2 border-black bg-zinc-200 [&_.slider-thumb]:rounded-none [&_.slider-thumb]:border-2 [&_.slider-thumb]:border-black [&_.slider-thumb]:bg-lime-500 [&_.slider-thumb]:shadow-[2px_2px_0_0_rgba(0,0,0,1)]" },
256
257
  tabs: { default: "border-b-2 border-black font-mono", triggerActive: "border-b-2 border-black font-bold bg-lime-500/20 text-black -mb-[2px] pb-[6px]", triggerInactive: "opacity-70 text-black" },
257
- card: { default: "rounded-none bg-white text-black border-2 border-black shadow-[6px_6px_0_0_rgba(0,0,0,1)] font-mono" },
258
+ card: { default: "rounded-none bg-white border-2 border-black shadow-[6px_6px_0_0_rgba(0,0,0,1)] font-mono" },
258
259
  bento: { default: "gap-4" },
259
260
  navbar: { default: "rounded-none bg-zinc-100 text-black border-b-2 border-black font-mono shadow-[0_4px_0_0_rgba(0,0,0,1)]" },
260
261
  sidebar: { default: "rounded-none bg-zinc-100 text-black border-r-2 border-black font-mono" },
@@ -277,13 +278,13 @@ var themeMap = {
277
278
  timeline: { default: "border-l-2 border-black text-black font-mono" }
278
279
  },
279
280
  motion: {
280
- button: { primary: "rounded-xl bg-indigo-500 text-white border-0 shadow-lg transition-all duration-300 ease-out hover:scale-105 hover:-translate-y-0.5 hover:shadow-xl hover:bg-indigo-600 active:scale-100 active:translate-y-0 focus:ring-2 focus:ring-indigo-400 focus:ring-offset-2", secondary: "rounded-xl bg-white text-indigo-600 border-2 border-indigo-200 shadow-md transition-all duration-300 ease-out hover:scale-105 hover:-translate-y-0.5 hover:border-indigo-300 hover:shadow-lg active:scale-100 active:translate-y-0 focus:ring-2 focus:ring-indigo-300 focus:ring-offset-2", ghost: "rounded-xl text-indigo-600 transition-all duration-300 ease-out hover:scale-105 hover:bg-indigo-50 hover:-translate-y-0.5 active:scale-100 active:translate-y-0" },
281
+ button: { primary: "rounded-xl bg-indigo-500 text-white border-0 shadow-lg transition-all duration-300 ease-out hover:scale-105 hover:-translate-y-0.5 hover:shadow-xl hover:bg-indigo-600 active:scale-100 active:translate-y-0 focus:ring-2 focus:ring-indigo-400 focus:ring-offset-2", secondary: "rounded-xl bg-white text-indigo-600 border-2 border-indigo-200 shadow-md transition-all duration-300 ease-out hover:scale-105 hover:-translate-y-0.5 hover:border-indigo-300 hover:shadow-lg active:scale-100 active:translate-y-0 focus:ring-2 focus:ring-indigo-300 focus:ring-offset-2", ghost: "rounded-xl text-inherit transition-all duration-300 ease-out hover:scale-105 hover:bg-indigo-50 hover:-translate-y-0.5 active:scale-100 active:translate-y-0" },
281
282
  input: { default: "rounded-xl border-2 border-indigo-200 bg-white text-zinc-900 transition-all duration-300 ease-out placeholder:text-zinc-400 focus:scale-[1.01] focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 focus:ring-offset-0" },
282
283
  toggle: { default: "rounded-full bg-zinc-200 transition-all duration-300 ease-out data-[state=on]:bg-indigo-500 [&_.slider-thumb]:transition-transform [&_.slider-thumb]:duration-300 [&_.slider-thumb]:data-[state=on]:scale-110" },
283
284
  badge: { default: "rounded-full bg-indigo-100 text-indigo-700 border border-indigo-200 transition-all duration-300 ease-out hover:scale-110 hover:bg-indigo-200" },
284
285
  slider: { default: "rounded-full bg-zinc-200 transition-all duration-300 [&_.slider-thumb]:rounded-full [&_.slider-thumb]:bg-indigo-500 [&_.slider-thumb]:transition-transform [&_.slider-thumb]:duration-300 [&_.slider-thumb]:hover:scale-125 [&_.slider-thumb]:active:scale-110" },
285
286
  tabs: { default: "border-b-2 border-indigo-200 transition-colors duration-300", triggerActive: "border-indigo-500 font-semibold text-indigo-600 transition-all duration-300", triggerInactive: "opacity-70 transition-opacity duration-300 hover:opacity-100" },
286
- card: { default: "rounded-2xl bg-white text-zinc-900 border-2 border-indigo-100 shadow-lg transition-all duration-300 ease-out hover:scale-[1.02] hover:shadow-xl hover:border-indigo-200 hover:-translate-y-1" },
287
+ card: { default: "rounded-2xl bg-white border-2 border-indigo-100 shadow-lg transition-all duration-300 ease-out hover:scale-[1.02] hover:shadow-xl hover:border-indigo-200 hover:-translate-y-1" },
287
288
  bento: { default: "gap-4" },
288
289
  navbar: { default: "rounded-none bg-white/95 backdrop-blur-md text-zinc-900 border-b-2 border-indigo-100 shadow-sm transition-all duration-300" },
289
290
  sidebar: { default: "rounded-none bg-white/95 backdrop-blur-md text-zinc-900 border-r-2 border-indigo-100 transition-all duration-300" },
@@ -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,181 +4762,75 @@ 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(
4611
4769
  "mt-3 border-t pt-3 text-xs",
4612
4770
  isDarkHeader ? "border-zinc-700 text-zinc-400" : "border-zinc-200 text-zinc-500"
4613
- ),
4614
- children: userEmail
4615
- }
4616
- ),
4617
- onLogout && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4618
- "button",
4619
- {
4620
- type: "button",
4621
- onClick: onLogout,
4622
- className: cn(
4623
- "mt-2 w-full rounded-lg px-4 py-2.5 text-left text-sm font-medium transition-colors",
4624
- mobileNavLinkStateClasses(theme, false)
4625
- ),
4626
- children: "Logout"
4627
- }
4628
- )
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
- ]
4771
+ ),
4772
+ children: userEmail
4773
+ }
4774
+ ),
4775
+ onLogout && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4776
+ "button",
4777
+ {
4778
+ type: "button",
4779
+ onClick: onLogout,
4780
+ className: cn(
4781
+ "mt-2 w-full rounded-lg px-4 py-2.5 text-left text-sm font-medium transition-colors",
4782
+ mobileNavLinkStateClasses(theme, false)
4783
+ ),
4784
+ children: "Logout"
4773
4785
  }
4774
4786
  )
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,27 +13275,21 @@ 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 Navbar = (0, import_react44.forwardRef)(function Navbar2({ children, logo, items, right, className, style }, ref) {
13284
+ const [mobileOpen, setMobileOpen] = (0, import_react44.useState)(false);
13285
+ const navRef = (0, import_react44.useRef)(null);
13286
+ const mergedNavRef = mergeRefs(ref, navRef);
13286
13287
  const { theme } = useTheme();
13287
13288
  const themeClass = getThemeClass(theme, "navbar", "default");
13288
13289
  const mobilePanelBgOverride = theme === "glass" ? "bg-white/95 backdrop-blur-xl" : theme === "clay" ? "bg-white/95" : null;
13289
13290
  useClickOutside(
13290
13291
  navRef,
13291
- (0, import_react39.useCallback)(() => setMobileOpen(false), []),
13292
+ (0, import_react44.useCallback)(() => setMobileOpen(false), []),
13292
13293
  { enabled: mobileOpen }
13293
13294
  );
13294
13295
  const hasResponsiveNav = items != null && items.length > 0;
@@ -13296,7 +13297,7 @@ function Navbar({
13296
13297
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
13297
13298
  "nav",
13298
13299
  {
13299
- ref: navRef,
13300
+ ref: mergedNavRef,
13300
13301
  className: cn(
13301
13302
  "relative sticky top-0 z-50 flex h-14 w-full flex-col px-3 sm:px-4",
13302
13303
  themeClass,
@@ -13362,6 +13363,7 @@ function Navbar({
13362
13363
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
13363
13364
  "nav",
13364
13365
  {
13366
+ ref: mergedNavRef,
13365
13367
  className: cn(
13366
13368
  "sticky top-0 z-50 flex h-14 w-full flex-wrap items-center gap-2 px-3 sm:px-4",
13367
13369
  themeClass,
@@ -13371,21 +13373,18 @@ function Navbar({
13371
13373
  children
13372
13374
  }
13373
13375
  );
13374
- }
13376
+ });
13375
13377
 
13376
13378
  // components/PricingCard.tsx
13379
+ var import_react45 = require("react");
13377
13380
  var import_jsx_runtime23 = require("react/jsx-runtime");
13378
- function PricingCard({
13379
- tier,
13380
- onSelect,
13381
- className,
13382
- style
13383
- }) {
13381
+ var PricingCard = (0, import_react45.forwardRef)(function PricingCard2({ tier, onSelect, className, style }, ref) {
13384
13382
  const { theme } = useTheme();
13385
13383
  const themeClass = getThemeClass(theme, "pricingCard", "default");
13386
13384
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
13387
13385
  "div",
13388
13386
  {
13387
+ ref,
13389
13388
  className: cn(
13390
13389
  "flex flex-col rounded-xl p-4 sm:p-6",
13391
13390
  themeClass,
@@ -13413,36 +13412,47 @@ function PricingCard({
13413
13412
  ]
13414
13413
  }
13415
13414
  );
13416
- }
13415
+ });
13417
13416
 
13418
13417
  // components/ProgressBar.tsx
13418
+ var import_react46 = require("react");
13419
13419
  var import_jsx_runtime24 = require("react/jsx-runtime");
13420
- function ProgressBar({
13420
+ var ProgressBar = (0, import_react46.forwardRef)(function ProgressBar2({
13421
13421
  value,
13422
13422
  max = 100,
13423
13423
  segmented = false,
13424
13424
  className,
13425
13425
  style,
13426
+ "aria-label": ariaLabel,
13426
13427
  trackColor,
13427
13428
  activeColor
13428
- }) {
13429
+ }, ref) {
13429
13430
  const { theme } = useTheme();
13430
13431
  const themeClass = getThemeClass(theme, "progress", "default");
13431
13432
  const pct = Math.min(100, Math.max(0, value / max * 100));
13432
13433
  const trackStyle = trackColor ? { backgroundColor: trackColor } : void 0;
13433
13434
  const fillStyle = activeColor ? { width: `${pct}%`, backgroundColor: activeColor } : { width: `${pct}%` };
13435
+ const progressRole = {
13436
+ role: "progressbar",
13437
+ "aria-valuenow": value,
13438
+ "aria-valuemin": 0,
13439
+ "aria-valuemax": max,
13440
+ ...ariaLabel && { "aria-label": ariaLabel }
13441
+ };
13434
13442
  if (segmented) {
13435
13443
  const segments = 10;
13436
13444
  const filled = Math.round(pct / 100 * segments);
13437
13445
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13438
13446
  "div",
13439
13447
  {
13448
+ ref,
13440
13449
  className: cn(
13441
13450
  "flex h-3 w-full gap-0.5 overflow-hidden rounded-full",
13442
13451
  themeClass,
13443
13452
  className
13444
13453
  ),
13445
13454
  style: { ...style, ...trackStyle },
13455
+ ...progressRole,
13446
13456
  children: Array.from({ length: segments }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13447
13457
  "div",
13448
13458
  {
@@ -13460,12 +13470,14 @@ function ProgressBar({
13460
13470
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13461
13471
  "div",
13462
13472
  {
13473
+ ref,
13463
13474
  className: cn(
13464
13475
  "relative h-3 w-full overflow-hidden rounded-full",
13465
13476
  themeClass,
13466
13477
  className
13467
13478
  ),
13468
13479
  style: { ...style, ...trackStyle },
13480
+ ...progressRole,
13469
13481
  children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
13470
13482
  "span",
13471
13483
  {
@@ -13475,40 +13487,33 @@ function ProgressBar({
13475
13487
  )
13476
13488
  }
13477
13489
  );
13478
- }
13490
+ });
13479
13491
 
13480
13492
  // components/SectionHeader.tsx
13493
+ var import_react47 = require("react");
13481
13494
  var import_jsx_runtime25 = require("react/jsx-runtime");
13482
- function SectionHeader({
13483
- title,
13484
- subtitle,
13485
- className,
13486
- style
13487
- }) {
13495
+ var SectionHeader = (0, import_react47.forwardRef)(function SectionHeader2({ title, subtitle, className, style }, ref) {
13488
13496
  const { theme } = useTheme();
13489
13497
  const themeClass = getThemeClass(theme, "sectionHeader", "default");
13490
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("header", { className: cn("pb-4", themeClass, className), style, children: [
13498
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("header", { ref, className: cn("pb-4", themeClass, className), style, children: [
13491
13499
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: "text-lg font-semibold sm:text-xl", children: title }),
13492
13500
  subtitle ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "mt-1 text-sm opacity-80", children: subtitle }) : null,
13493
13501
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-3 border-b border-inherit" })
13494
13502
  ] });
13495
- }
13503
+ });
13496
13504
 
13497
13505
  // components/Sidebar.tsx
13498
- var import_react40 = require("react");
13506
+ var import_react48 = require("react");
13499
13507
  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);
13508
+ var Sidebar = (0, import_react48.forwardRef)(function Sidebar2({ children, className, style }, ref) {
13509
+ const [collapsed, setCollapsed] = (0, import_react48.useState)(false);
13506
13510
  const { theme } = useTheme();
13507
13511
  const themeClass = getThemeClass(theme, "sidebar", "default");
13508
- const toggle = (0, import_react40.useCallback)(() => setCollapsed((c) => !c), []);
13512
+ const toggle = (0, import_react48.useCallback)(() => setCollapsed((c) => !c), []);
13509
13513
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
13510
13514
  "aside",
13511
13515
  {
13516
+ ref,
13512
13517
  className: cn(
13513
13518
  "flex h-full flex-col transition-[width] duration-200",
13514
13519
  collapsed ? "w-12 sm:w-14" : "w-48 max-w-[85vw] sm:w-56 sm:max-w-none",
@@ -13531,10 +13536,10 @@ function Sidebar({
13531
13536
  ]
13532
13537
  }
13533
13538
  );
13534
- }
13539
+ });
13535
13540
 
13536
13541
  // components/Skeleton.tsx
13537
- var import_react41 = require("react");
13542
+ var import_react49 = require("react");
13538
13543
  var import_jsx_runtime27 = require("react/jsx-runtime");
13539
13544
  var skeletonVariants = cva("", {
13540
13545
  variants: {
@@ -13548,7 +13553,7 @@ var skeletonVariants = cva("", {
13548
13553
  variant: "rectangle"
13549
13554
  }
13550
13555
  });
13551
- var Skeleton = (0, import_react41.forwardRef)(
13556
+ var Skeleton = (0, import_react49.forwardRef)(
13552
13557
  function Skeleton2({ variant = "rectangle", className, theme: themeProp, style, ...props }, ref) {
13553
13558
  const { theme: contextTheme } = useTheme();
13554
13559
  const theme = themeProp ?? contextTheme;
@@ -13574,7 +13579,7 @@ var Skeleton = (0, import_react41.forwardRef)(
13574
13579
  );
13575
13580
 
13576
13581
  // components/Slider.tsx
13577
- var import_react42 = require("react");
13582
+ var import_react50 = require("react");
13578
13583
  var import_jsx_runtime28 = require("react/jsx-runtime");
13579
13584
  var sliderVariants = cva(
13580
13585
  "relative flex w-full touch-none items-center overflow-visible py-1",
@@ -13595,7 +13600,7 @@ var trackVariants = cva(
13595
13600
  "relative h-3 w-full rounded-full overflow-visible",
13596
13601
  { variants: {}, defaultVariants: {} }
13597
13602
  );
13598
- var Slider = (0, import_react42.forwardRef)(function Slider2({
13603
+ var Slider = (0, import_react50.forwardRef)(function Slider2({
13599
13604
  min = 0,
13600
13605
  max = 100,
13601
13606
  step = 1,
@@ -13604,17 +13609,18 @@ var Slider = (0, import_react42.forwardRef)(function Slider2({
13604
13609
  onValueChange,
13605
13610
  size = "md",
13606
13611
  className,
13612
+ style,
13607
13613
  theme: themeProp,
13608
13614
  ...props
13609
13615
  }, ref) {
13610
- const [uncontrolled, setUncontrolled] = (0, import_react42.useState)(defaultValue);
13616
+ const [uncontrolled, setUncontrolled] = (0, import_react50.useState)(defaultValue);
13611
13617
  const isControlled = controlledValue !== void 0;
13612
13618
  const value = isControlled ? controlledValue : uncontrolled;
13613
13619
  const { theme: contextTheme } = useTheme();
13614
13620
  const theme = themeProp ?? contextTheme;
13615
13621
  const themeClass = getThemeClass(theme, "slider", "default");
13616
13622
  const pct = (value - min) / (max - min) * 100;
13617
- const handleChange = (0, import_react42.useCallback)(
13623
+ const handleChange = (0, import_react50.useCallback)(
13618
13624
  (e) => {
13619
13625
  const next = Number(e.target.value);
13620
13626
  if (!isControlled) setUncontrolled(next);
@@ -13622,7 +13628,7 @@ var Slider = (0, import_react42.forwardRef)(function Slider2({
13622
13628
  },
13623
13629
  [isControlled, onValueChange]
13624
13630
  );
13625
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(sliderVariants({ size }), className), children: [
13631
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(sliderVariants({ size }), className), style, children: [
13626
13632
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(trackVariants(), themeClass), children: [
13627
13633
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
13628
13634
  "span",
@@ -13660,20 +13666,15 @@ var Slider = (0, import_react42.forwardRef)(function Slider2({
13660
13666
  });
13661
13667
 
13662
13668
  // components/StatsCard.tsx
13669
+ var import_react51 = require("react");
13663
13670
  var import_jsx_runtime29 = require("react/jsx-runtime");
13664
- function StatsCard({
13665
- label,
13666
- value,
13667
- trend,
13668
- className,
13669
- style
13670
- }) {
13671
+ var StatsCard = (0, import_react51.forwardRef)(function StatsCard2({ label, value, trend, className, style }, ref) {
13671
13672
  const { theme } = useTheme();
13672
13673
  const themeClass = getThemeClass(theme, "statsCard", "default");
13673
13674
  const isDark = theme === "night" || theme === "cyberpunk";
13674
13675
  const trendUpClass = trend?.direction === "up" ? isDark ? "text-emerald-400" : "text-emerald-600" : null;
13675
13676
  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: [
13677
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { ref, className: cn("rounded-xl p-6", themeClass, className), style, children: [
13677
13678
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-sm font-medium opacity-80", children: label }),
13678
13679
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mt-2 text-2xl font-bold tracking-tight", children: value }),
13679
13680
  trend ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
@@ -13690,10 +13691,10 @@ function StatsCard({
13690
13691
  }
13691
13692
  ) : null
13692
13693
  ] });
13693
- }
13694
+ });
13694
13695
 
13695
13696
  // components/Tabs.tsx
13696
- var import_react43 = require("react");
13697
+ var import_react52 = require("react");
13697
13698
  var import_jsx_runtime30 = require("react/jsx-runtime");
13698
13699
  var tabsListVariants = cva(
13699
13700
  "flex min-w-0 overflow-x-auto scrollbar-thin -mx-1 px-1 sm:mx-0 sm:overflow-visible",
@@ -13716,7 +13717,7 @@ var tabTriggerVariants = cva(
13716
13717
  }
13717
13718
  }
13718
13719
  );
13719
- function Tabs({
13720
+ var Tabs = (0, import_react52.forwardRef)(function Tabs2({
13720
13721
  items,
13721
13722
  defaultValue,
13722
13723
  value: controlledValue,
@@ -13724,31 +13725,31 @@ function Tabs({
13724
13725
  className,
13725
13726
  style,
13726
13727
  theme: themeProp
13727
- }) {
13728
- const [uncontrolled, setUncontrolled] = (0, import_react43.useState)(
13728
+ }, ref) {
13729
+ const [uncontrolled, setUncontrolled] = (0, import_react52.useState)(
13729
13730
  () => defaultValue ?? items[0]?.value ?? ""
13730
13731
  );
13731
13732
  const isControlled = controlledValue !== void 0;
13732
13733
  const value = isControlled ? controlledValue : uncontrolled;
13733
13734
  const activeIndex = items.findIndex((i) => i.value === value);
13734
13735
  const safeIndex = activeIndex >= 0 ? activeIndex : 0;
13735
- const triggerRefs = (0, import_react43.useRef)([]);
13736
+ const triggerRefs = (0, import_react52.useRef)([]);
13736
13737
  const { theme: contextTheme } = useTheme();
13737
13738
  const theme = themeProp ?? contextTheme;
13738
13739
  const listThemeClass = getThemeClass(theme, "tabs", "default");
13739
13740
  const triggerActiveClass = getThemeClass(theme, "tabs", "triggerActive");
13740
13741
  const triggerInactiveClass = getThemeClass(theme, "tabs", "triggerInactive");
13741
- const setValue = (0, import_react43.useCallback)(
13742
+ const setValue = (0, import_react52.useCallback)(
13742
13743
  (v) => {
13743
13744
  if (!isControlled) setUncontrolled(v);
13744
13745
  onValueChange?.(v);
13745
13746
  },
13746
13747
  [isControlled, onValueChange]
13747
13748
  );
13748
- (0, import_react43.useEffect)(() => {
13749
+ (0, import_react52.useEffect)(() => {
13749
13750
  triggerRefs.current = triggerRefs.current.slice(0, items.length);
13750
13751
  }, [items.length]);
13751
- const handleKeyDown = (0, import_react43.useCallback)(
13752
+ const handleKeyDown = (0, import_react52.useCallback)(
13752
13753
  (e) => {
13753
13754
  if (e.key === "ArrowLeft") {
13754
13755
  e.preventDefault();
@@ -13766,7 +13767,7 @@ function Tabs({
13766
13767
  );
13767
13768
  const activeItem = items[safeIndex];
13768
13769
  const content = activeItem?.content ?? null;
13769
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cn("w-full min-w-0", className), style, children: [
13770
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { ref, className: cn("w-full min-w-0", className), style, children: [
13770
13771
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
13771
13772
  "div",
13772
13773
  {
@@ -13810,22 +13811,19 @@ function Tabs({
13810
13811
  }
13811
13812
  )
13812
13813
  ] });
13813
- }
13814
+ });
13814
13815
 
13815
13816
  // components/Terminal.tsx
13817
+ var import_react53 = require("react");
13816
13818
  var import_jsx_runtime31 = require("react/jsx-runtime");
13817
- function Terminal({
13818
- title = "terminal",
13819
- children,
13820
- className,
13821
- style
13822
- }) {
13819
+ var Terminal = (0, import_react53.forwardRef)(function Terminal2({ title = "terminal", children, className, style }, ref) {
13823
13820
  const { theme } = useTheme();
13824
13821
  const themeClass = getThemeClass(theme, "terminal", "default");
13825
13822
  const isCyberpunk = theme === "cyberpunk";
13826
13823
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
13827
13824
  "div",
13828
13825
  {
13826
+ ref,
13829
13827
  className: cn("overflow-hidden rounded-xl font-mono text-sm", themeClass, className),
13830
13828
  style,
13831
13829
  children: [
@@ -13851,22 +13849,21 @@ function Terminal({
13851
13849
  ]
13852
13850
  }
13853
13851
  );
13854
- }
13852
+ });
13855
13853
 
13856
13854
  // components/Timeline.tsx
13855
+ var import_react54 = require("react");
13857
13856
  var import_jsx_runtime32 = require("react/jsx-runtime");
13858
- function Timeline({
13859
- items,
13860
- className,
13861
- theme: themeProp
13862
- }) {
13857
+ var Timeline = (0, import_react54.forwardRef)(function Timeline2({ items, className, style, theme: themeProp }, ref) {
13863
13858
  const { theme: contextTheme } = useTheme();
13864
13859
  const theme = themeProp ?? contextTheme;
13865
13860
  const themeClass = getThemeClass(theme, "timeline", "default");
13866
13861
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13867
13862
  "div",
13868
13863
  {
13864
+ ref,
13869
13865
  className: cn("relative pl-4", themeClass, className),
13866
+ style,
13870
13867
  role: "list",
13871
13868
  "aria-label": "Timeline",
13872
13869
  children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
@@ -13893,21 +13890,25 @@ function Timeline({
13893
13890
  ))
13894
13891
  }
13895
13892
  );
13896
- }
13893
+ });
13897
13894
 
13898
13895
  // components/Toast.tsx
13896
+ var import_react55 = require("react");
13899
13897
  var import_jsx_runtime33 = require("react/jsx-runtime");
13900
- function Toast({
13901
- message,
13902
- onDismiss,
13903
- className,
13904
- style
13905
- }) {
13898
+ var Toast = (0, import_react55.forwardRef)(function Toast2({ message, onDismiss, className, style }, ref) {
13906
13899
  const { theme } = useTheme();
13907
13900
  const themeClass = getThemeClass(theme, "toast", "default");
13901
+ (0, import_react55.useEffect)(() => {
13902
+ const handler = (e) => {
13903
+ if (e.key === "Escape") onDismiss();
13904
+ };
13905
+ document.addEventListener("keydown", handler);
13906
+ return () => document.removeEventListener("keydown", handler);
13907
+ }, [onDismiss]);
13908
13908
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
13909
13909
  "div",
13910
13910
  {
13911
+ ref,
13911
13912
  role: "alert",
13912
13913
  className: cn(
13913
13914
  "flex items-center justify-between gap-4 rounded-lg px-4 py-3 shadow-lg",
@@ -13930,10 +13931,10 @@ function Toast({
13930
13931
  ]
13931
13932
  }
13932
13933
  );
13933
- }
13934
+ });
13934
13935
 
13935
13936
  // components/Toggle.tsx
13936
- var import_react44 = require("react");
13937
+ var import_react56 = require("react");
13937
13938
  var import_jsx_runtime34 = require("react/jsx-runtime");
13938
13939
  var toggleVariants = cva(
13939
13940
  "relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full px-0.5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 data-[state=off]:justify-start data-[state=on]:justify-end [&:has(input:disabled)]:cursor-not-allowed [&:has(input:disabled)]:opacity-50",
@@ -13942,17 +13943,18 @@ var toggleVariants = cva(
13942
13943
  defaultVariants: {}
13943
13944
  }
13944
13945
  );
13945
- var Toggle = (0, import_react44.forwardRef)(function Toggle2({
13946
+ var Toggle = (0, import_react56.forwardRef)(function Toggle2({
13946
13947
  checked: controlledChecked,
13947
13948
  defaultChecked = false,
13948
13949
  onCheckedChange,
13949
13950
  className,
13951
+ style,
13950
13952
  "aria-label": ariaLabel = "Toggle",
13951
13953
  theme: themeProp,
13952
13954
  disabled,
13953
13955
  ...props
13954
13956
  }, ref) {
13955
- const [uncontrolled, setUncontrolled] = (0, import_react44.useState)(defaultChecked);
13957
+ const [uncontrolled, setUncontrolled] = (0, import_react56.useState)(defaultChecked);
13956
13958
  const isControlled = controlledChecked !== void 0;
13957
13959
  const checked = isControlled ? controlledChecked : uncontrolled;
13958
13960
  const { theme: contextTheme } = useTheme();
@@ -13960,8 +13962,8 @@ var Toggle = (0, import_react44.forwardRef)(function Toggle2({
13960
13962
  const themeClass = getThemeClass(theme, "toggle", "default");
13961
13963
  const thumbOnDark = theme === "night" && checked;
13962
13964
  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)(
13965
+ const id3 = (0, import_react56.useId)();
13966
+ const handleChange = (0, import_react56.useCallback)(
13965
13967
  (e) => {
13966
13968
  const next = e.target.checked;
13967
13969
  if (!isControlled) setUncontrolled(next);
@@ -13974,6 +13976,7 @@ var Toggle = (0, import_react44.forwardRef)(function Toggle2({
13974
13976
  {
13975
13977
  htmlFor: id3,
13976
13978
  className: cn(toggleVariants(), themeClass, className),
13979
+ style,
13977
13980
  "data-state": checked ? "on" : "off",
13978
13981
  children: [
13979
13982
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
@@ -14007,7 +14010,7 @@ var Toggle = (0, import_react44.forwardRef)(function Toggle2({
14007
14010
  });
14008
14011
 
14009
14012
  // components/Tooltip.tsx
14010
- var import_react45 = require("react");
14013
+ var import_react57 = require("react");
14011
14014
  var import_jsx_runtime35 = require("react/jsx-runtime");
14012
14015
  var placementClasses = {
14013
14016
  top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
@@ -14019,34 +14022,31 @@ var tooltipVariants = cva(
14019
14022
  "absolute z-50 whitespace-nowrap rounded-lg px-2 py-1 text-xs shadow-lg",
14020
14023
  { variants: {}, defaultVariants: {} }
14021
14024
  );
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);
14025
+ var Tooltip = (0, import_react57.forwardRef)(function Tooltip2({ content, children, placement = "top", className, style, theme: themeProp }, ref) {
14026
+ const [visible, setVisible] = (0, import_react57.useState)(false);
14027
+ const tooltipId = (0, import_react57.useId)();
14031
14028
  const { theme: contextTheme } = useTheme();
14032
14029
  const theme = themeProp ?? contextTheme;
14033
14030
  const themeClass = getThemeClass(theme, "tooltip", "default");
14034
- const show = (0, import_react45.useCallback)(() => setVisible(true), []);
14035
- const hide = (0, import_react45.useCallback)(() => setVisible(false), []);
14031
+ const show = (0, import_react57.useCallback)(() => setVisible(true), []);
14032
+ const hide = (0, import_react57.useCallback)(() => setVisible(false), []);
14036
14033
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
14037
14034
  "span",
14038
14035
  {
14036
+ ref,
14039
14037
  className: cn("relative inline-block", className),
14040
14038
  style,
14041
14039
  onMouseEnter: show,
14042
14040
  onMouseLeave: hide,
14043
14041
  onFocus: show,
14044
14042
  onBlur: hide,
14043
+ "aria-describedby": visible ? tooltipId : void 0,
14045
14044
  children: [
14046
14045
  children,
14047
14046
  visible ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
14048
14047
  "span",
14049
14048
  {
14049
+ id: tooltipId,
14050
14050
  role: "tooltip",
14051
14051
  className: cn(
14052
14052
  tooltipVariants(),
@@ -14059,7 +14059,7 @@ function Tooltip({
14059
14059
  ]
14060
14060
  }
14061
14061
  );
14062
- }
14062
+ });
14063
14063
 
14064
14064
  // lib/theme-recommendations.ts
14065
14065
  var THEME_BACKGROUNDS = {
@@ -14191,6 +14191,7 @@ var THEME_RECOMMENDATIONS = {
14191
14191
  cn,
14192
14192
  getNextListIndex,
14193
14193
  getThemeClass,
14194
+ mergeRefs,
14194
14195
  useClickOutside,
14195
14196
  useFocusTrap,
14196
14197
  useKeyboardNavigation,