@olwiba/ui 0.2.19 → 0.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { cn } from './chunk-AMWLSHD6.js';
2
2
  export { MdxContent, cn } from './chunk-AMWLSHD6.js';
3
- import * as React20 from 'react';
3
+ import * as React21 from 'react';
4
4
  import { useRef, useEffect, useState, useCallback } from 'react';
5
5
  import { Button as Button$1, Card as Card$1, Input as Input$1, Textarea as Textarea$1, Checkbox as Checkbox$1, Switch as Switch$1, useIsMobile, UIVariantProvider, Badge as Badge$1, cn as cn$1, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Avatar, AvatarImage, AvatarFallback, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, Dialog, DialogTrigger, Progress, useUIVariant, Separator, Accordion, AccordionItem, AccordionTrigger, AccordionContent, Label, Sheet, SheetTrigger, SheetContent, StatusIndicator, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandSeparator, CommandGroup, CommandItem, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ContextMenu as ContextMenu$1, ContextMenuTrigger, ContextMenuContent, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, CommandShortcut, Popover, PopoverTrigger, PopoverContent, Spinner, SidebarProvider, SidebarInset, CardHeader, CardTitle, CardDescription, CardContent, InputOTP, InputOTPGroup, InputOTPSlot, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, ContextMenuSeparator, ContextMenuLabel, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent, ContextMenuItem, ContextMenuShortcut, useSidebar, Sidebar, SidebarHeader, SidebarMenu, SidebarMenuItem, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarMenuButton, SidebarFooter, SidebarTrigger, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup } from '@olwiba/cn';
6
6
  export { CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Enchanted } from '@olwiba/cn';
@@ -13,7 +13,7 @@ import { CSS } from '@dnd-kit/utilities';
13
13
  import { PieChart, Pie, Cell, BarChart, XAxis, YAxis, Bar, AreaChart, Area, LineChart, Line, ResponsiveContainer, Tooltip as Tooltip$1, CartesianGrid } from 'recharts';
14
14
  import { toast } from 'sonner';
15
15
 
16
- var OlwibaUIContext = React20.createContext({
16
+ var OlwibaUIContext = React21.createContext({
17
17
  isMobile: false,
18
18
  mode: "default",
19
19
  setMode: () => {
@@ -22,17 +22,17 @@ var OlwibaUIContext = React20.createContext({
22
22
  function OlwibaUIProvider({ children, isMobile: isMobileProp, mode: initialMode = "default" }) {
23
23
  const detectedMobile = useIsMobile();
24
24
  const isMobile = isMobileProp ?? detectedMobile;
25
- const [mode, setMode] = React20.useState(initialMode);
25
+ const [mode, setMode] = React21.useState(initialMode);
26
26
  const variant = mode !== "default" ? mode : void 0;
27
27
  return /* @__PURE__ */ jsx(OlwibaUIContext.Provider, { value: { isMobile, mode, setMode }, children: /* @__PURE__ */ jsx(UIVariantProvider, { mode: variant, children }) });
28
28
  }
29
29
  function useOlwibaUI() {
30
- return React20.useContext(OlwibaUIContext);
30
+ return React21.useContext(OlwibaUIContext);
31
31
  }
32
32
  function useUIMode() {
33
- return React20.useContext(OlwibaUIContext).mode;
33
+ return React21.useContext(OlwibaUIContext).mode;
34
34
  }
35
- var Button = React20.forwardRef(
35
+ var Button = React21.forwardRef(
36
36
  ({ mode, ...props }, ref) => {
37
37
  const ctxMode = useUIMode();
38
38
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -40,7 +40,7 @@ var Button = React20.forwardRef(
40
40
  }
41
41
  );
42
42
  Button.displayName = "Button";
43
- var Card = React20.forwardRef(
43
+ var Card = React21.forwardRef(
44
44
  ({ mode, ...props }, ref) => {
45
45
  const ctxMode = useUIMode();
46
46
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -51,7 +51,7 @@ Card.displayName = "Card";
51
51
  function Badge(props) {
52
52
  return /* @__PURE__ */ jsx(Badge$1, { ...props });
53
53
  }
54
- var Input = React20.forwardRef(
54
+ var Input = React21.forwardRef(
55
55
  ({ mode, ...props }, ref) => {
56
56
  const ctxMode = useUIMode();
57
57
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -59,7 +59,7 @@ var Input = React20.forwardRef(
59
59
  }
60
60
  );
61
61
  Input.displayName = "Input";
62
- var Textarea = React20.forwardRef(
62
+ var Textarea = React21.forwardRef(
63
63
  ({ mode, ...props }, ref) => {
64
64
  const ctxMode = useUIMode();
65
65
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -67,13 +67,13 @@ var Textarea = React20.forwardRef(
67
67
  }
68
68
  );
69
69
  Textarea.displayName = "Textarea";
70
- var Checkbox = React20.forwardRef(({ mode, ...props }, ref) => {
70
+ var Checkbox = React21.forwardRef(({ mode, ...props }, ref) => {
71
71
  const ctxMode = useUIMode();
72
72
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
73
73
  return /* @__PURE__ */ jsx(Checkbox$1, { mode: resolvedMode, ...props, ref });
74
74
  });
75
75
  Checkbox.displayName = "Checkbox";
76
- var Switch = React20.forwardRef(({ mode: _mode, ...props }, ref) => {
76
+ var Switch = React21.forwardRef(({ mode: _mode, ...props }, ref) => {
77
77
  return /* @__PURE__ */ jsx(Switch$1, { ...props, ref });
78
78
  });
79
79
  Switch.displayName = "Switch";
@@ -626,7 +626,7 @@ function DefaultForm({
626
626
  const isForgotPassword = mode === "forgot-password";
627
627
  const isResetPassword = mode === "reset-password";
628
628
  const isVerify = mode === "verify";
629
- const [code, setCode] = React20.useState("");
629
+ const [code, setCode] = React21.useState("");
630
630
  const hasPrefill = !!(defaultEmail || defaultPassword);
631
631
  const prefillStyle = (active) => active ? { animation: "auth-prefill 1.6s ease-out 0.35s 1 both" } : void 0;
632
632
  const copy = authCopy[mode];
@@ -787,10 +787,10 @@ function DataTable({
787
787
  emptyMessage = "No results.",
788
788
  className
789
789
  }) {
790
- const [sorting, setSorting] = React20.useState([]);
791
- const [rowSelection, setRowSelection] = React20.useState({});
792
- const [globalFilter, setGlobalFilter] = React20.useState("");
793
- const allColumns = React20.useMemo(
790
+ const [sorting, setSorting] = React21.useState([]);
791
+ const [rowSelection, setRowSelection] = React21.useState({});
792
+ const [globalFilter, setGlobalFilter] = React21.useState("");
793
+ const allColumns = React21.useMemo(
794
794
  () => selectable ? [selectColumn, ...columns] : columns,
795
795
  [selectable, columns]
796
796
  );
@@ -812,7 +812,7 @@ function DataTable({
812
812
  initialState: pageSize > 0 ? { pagination: { pageSize } } : void 0,
813
813
  enableRowSelection: selectable
814
814
  });
815
- React20.useEffect(() => {
815
+ React21.useEffect(() => {
816
816
  if (!onSelectionChange) return;
817
817
  onSelectionChange(table.getSelectedRowModel().rows.map((r) => r.original));
818
818
  }, [rowSelection]);
@@ -892,8 +892,8 @@ function DataTable({
892
892
  ] });
893
893
  }
894
894
  function InviteDialog({ roles, onInvite, onClose }) {
895
- const [email, setEmail] = React20.useState("");
896
- const [role, setRole] = React20.useState(roles[roles.length - 1] ?? roles[0]);
895
+ const [email, setEmail] = React21.useState("");
896
+ const [role, setRole] = React21.useState(roles[roles.length - 1] ?? roles[0]);
897
897
  return /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs(
898
898
  "form",
899
899
  {
@@ -937,8 +937,8 @@ function TeamMembersPanel({
937
937
  title = "Team members",
938
938
  description = "Manage who has access to this workspace."
939
939
  }) {
940
- const [inviteOpen, setInviteOpen] = React20.useState(false);
941
- const columns = React20.useMemo(() => [
940
+ const [inviteOpen, setInviteOpen] = React21.useState(false);
941
+ const columns = React21.useMemo(() => [
942
942
  {
943
943
  accessorKey: "name",
944
944
  header: "Name",
@@ -1007,7 +1007,7 @@ function BillingPanel({
1007
1007
  onUpdatePaymentMethod,
1008
1008
  className
1009
1009
  }) {
1010
- const invoiceColumns = React20.useMemo(() => [
1010
+ const invoiceColumns = React21.useMemo(() => [
1011
1011
  { accessorKey: "date", header: "Date", enableSorting: false },
1012
1012
  { accessorKey: "amount", header: "Amount", enableSorting: false },
1013
1013
  {
@@ -1086,9 +1086,9 @@ function OnboardingWizard({
1086
1086
  completeLabel = "Finish",
1087
1087
  className
1088
1088
  }) {
1089
- const [internalStep, setInternalStep] = React20.useState(0);
1090
- const [error, setError] = React20.useState(null);
1091
- const [pending, setPending] = React20.useState(false);
1089
+ const [internalStep, setInternalStep] = React21.useState(0);
1090
+ const [error, setError] = React21.useState(null);
1091
+ const [pending, setPending] = React21.useState(false);
1092
1092
  const index = stepProp ?? internalStep;
1093
1093
  const current = steps[index];
1094
1094
  const isLast = index === steps.length - 1;
@@ -1418,10 +1418,10 @@ function UpdateBanner({
1418
1418
  buttonLabel = "Refresh now",
1419
1419
  className
1420
1420
  }) {
1421
- const [show, setShow] = React20.useState(forceShow);
1422
- const [entered, setEntered] = React20.useState(false);
1423
- const [refreshing, setRefreshing] = React20.useState(false);
1424
- React20.useEffect(() => {
1421
+ const [show, setShow] = React21.useState(forceShow);
1422
+ const [entered, setEntered] = React21.useState(false);
1423
+ const [refreshing, setRefreshing] = React21.useState(false);
1424
+ React21.useEffect(() => {
1425
1425
  if (forceShow) {
1426
1426
  setShow(true);
1427
1427
  return;
@@ -1444,7 +1444,7 @@ function UpdateBanner({
1444
1444
  clearInterval(id);
1445
1445
  };
1446
1446
  }, [currentVersion, fetchVersion, forceShow, intervalMs]);
1447
- React20.useEffect(() => {
1447
+ React21.useEffect(() => {
1448
1448
  if (!show) {
1449
1449
  setEntered(false);
1450
1450
  return;
@@ -1517,9 +1517,9 @@ function FadeIn({
1517
1517
  style,
1518
1518
  ...props
1519
1519
  }) {
1520
- const ref = React20.useRef(null);
1521
- const [visible, setVisible] = React20.useState(false);
1522
- React20.useEffect(() => {
1520
+ const ref = React21.useRef(null);
1521
+ const [visible, setVisible] = React21.useState(false);
1522
+ React21.useEffect(() => {
1523
1523
  const el = ref.current;
1524
1524
  if (!el) return;
1525
1525
  const observer = new IntersectionObserver(
@@ -1564,6 +1564,36 @@ var marketingSectionSpacing = {
1564
1564
  standard: "px-6 py-14 sm:px-10 sm:py-20",
1565
1565
  hero: "px-6 pb-14 pt-10 sm:px-10 sm:py-20"
1566
1566
  };
1567
+ var MarketingSurfaceContext = React21.createContext(void 0);
1568
+ function MarketingSurfaceProvider({
1569
+ surface,
1570
+ children
1571
+ }) {
1572
+ return /* @__PURE__ */ jsx(MarketingSurfaceContext.Provider, { value: surface, children });
1573
+ }
1574
+ function useMarketingSurface() {
1575
+ return React21.useContext(MarketingSurfaceContext);
1576
+ }
1577
+ function useSectionSurface(override) {
1578
+ const mode = useUIVariant();
1579
+ const contextSurface = useMarketingSurface();
1580
+ const surface = override ?? contextSurface ?? "card";
1581
+ if (surface === "plain") return "overflow-hidden";
1582
+ if (surface === "soft") {
1583
+ return cn$1(
1584
+ "overflow-hidden border backdrop-blur-md",
1585
+ mode === "smooth" && "rounded-[2rem] border-border/40 bg-card/40",
1586
+ mode === "playful" && "rounded-3xl border-primary/20 bg-card/50",
1587
+ !mode && "rounded-3xl border-border/50 bg-card/45"
1588
+ );
1589
+ }
1590
+ return cn$1(
1591
+ "overflow-hidden bg-card",
1592
+ mode === "smooth" && "rounded-3xl border",
1593
+ mode === "playful" && "rounded-2xl border-primary/25 border",
1594
+ !mode && "rounded-2xl border"
1595
+ );
1596
+ }
1567
1597
  var sizes = {
1568
1598
  sm: { outer: "w-44", height: "h-80", notch: "w-16 h-4", border: "rounded-[2rem]", screen: "rounded-[1.75rem]" },
1569
1599
  md: { outer: "w-56", height: "h-[26rem]", notch: "w-20 h-5", border: "rounded-[2.5rem]", screen: "rounded-[2.25rem]" },
@@ -1724,16 +1754,16 @@ function Carousel({
1724
1754
  className
1725
1755
  }) {
1726
1756
  const mode = useUIVariant();
1727
- const trackRef = React20.useRef(null);
1728
- const [canPrev, setCanPrev] = React20.useState(false);
1729
- const [canNext, setCanNext] = React20.useState(true);
1730
- const updateScrollState = React20.useCallback(() => {
1757
+ const trackRef = React21.useRef(null);
1758
+ const [canPrev, setCanPrev] = React21.useState(false);
1759
+ const [canNext, setCanNext] = React21.useState(true);
1760
+ const updateScrollState = React21.useCallback(() => {
1731
1761
  const track = trackRef.current;
1732
1762
  if (!track) return;
1733
1763
  setCanPrev(track.scrollLeft > 8);
1734
1764
  setCanNext(track.scrollLeft < track.scrollWidth - track.clientWidth - 8);
1735
1765
  }, []);
1736
- React20.useEffect(() => {
1766
+ React21.useEffect(() => {
1737
1767
  const track = trackRef.current;
1738
1768
  if (!track) return;
1739
1769
  updateScrollState();
@@ -1790,7 +1820,7 @@ function Carousel({
1790
1820
  role: "region",
1791
1821
  "aria-label": ariaLabel,
1792
1822
  className: "flex snap-x snap-mandatory gap-6 overflow-x-auto pb-4 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
1793
- children: React20.Children.map(
1823
+ children: React21.Children.map(
1794
1824
  children,
1795
1825
  (child) => child == null ? null : /* @__PURE__ */ jsx("div", { "data-carousel-item": true, className: cn$1("shrink-0 snap-start", itemClassName), children: child })
1796
1826
  )
@@ -1815,9 +1845,9 @@ function StaggerChildren({
1815
1845
  className,
1816
1846
  ...props
1817
1847
  }) {
1818
- const ref = React20.useRef(null);
1819
- const [visible, setVisible] = React20.useState(false);
1820
- React20.useEffect(() => {
1848
+ const ref = React21.useRef(null);
1849
+ const [visible, setVisible] = React21.useState(false);
1850
+ React21.useEffect(() => {
1821
1851
  const el = ref.current;
1822
1852
  if (!el) return;
1823
1853
  const observer = new IntersectionObserver(
@@ -1835,7 +1865,7 @@ function StaggerChildren({
1835
1865
  return () => observer.disconnect();
1836
1866
  }, [once]);
1837
1867
  const [tx, ty] = translateMap2[direction];
1838
- return /* @__PURE__ */ jsx("div", { ref, className: cn$1(className), ...props, children: React20.Children.map(children, (child, i) => /* @__PURE__ */ jsx(
1868
+ return /* @__PURE__ */ jsx("div", { ref, className: cn$1(className), ...props, children: React21.Children.map(children, (child, i) => /* @__PURE__ */ jsx(
1839
1869
  "div",
1840
1870
  {
1841
1871
  className: "h-full",
@@ -1854,15 +1884,10 @@ function FeaturesSection({
1854
1884
  description = "A complete system of components, blocks, and hooks designed to work together - and get out of your way.",
1855
1885
  badge = "Features",
1856
1886
  features,
1857
- layout = "grid"
1887
+ layout = "grid",
1888
+ surface
1858
1889
  }) {
1859
- const mode = useUIVariant();
1860
- const sectionClasses = cn$1(
1861
- "overflow-hidden bg-card",
1862
- mode === "smooth" && "rounded-3xl border",
1863
- mode === "playful" && "rounded-2xl border-primary/25 border",
1864
- !mode && "rounded-2xl border"
1865
- );
1890
+ const sectionClasses = useSectionSurface(surface);
1866
1891
  const cards = features.map((feature) => /* @__PURE__ */ jsx(
1867
1892
  FeatureCard,
1868
1893
  {
@@ -1882,15 +1907,10 @@ function GroupedFeaturesSection({
1882
1907
  badge = "Features",
1883
1908
  title = "Everything you need to ship",
1884
1909
  description,
1885
- groups
1910
+ groups,
1911
+ surface
1886
1912
  }) {
1887
- const mode = useUIVariant();
1888
- const sectionClasses = cn$1(
1889
- "overflow-hidden bg-card",
1890
- mode === "smooth" && "rounded-3xl border",
1891
- mode === "playful" && "rounded-2xl border-primary/25 border",
1892
- !mode && "rounded-2xl border"
1893
- );
1913
+ const sectionClasses = useSectionSurface(surface);
1894
1914
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsx("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-4xl", children: [
1895
1915
  /* @__PURE__ */ jsx(SectionTitle, { title, description, badge }),
1896
1916
  /* @__PURE__ */ jsx("div", { className: "mt-14 space-y-14", children: groups.map((group, i) => /* @__PURE__ */ jsxs("div", { children: [
@@ -1960,15 +1980,10 @@ function StepsSection({
1960
1980
  description,
1961
1981
  steps,
1962
1982
  variant = "default",
1963
- groups
1983
+ groups,
1984
+ surface
1964
1985
  }) {
1965
- const mode = useUIVariant();
1966
- const sectionClasses = cn$1(
1967
- "overflow-hidden bg-card",
1968
- mode === "smooth" && "rounded-3xl border",
1969
- mode === "playful" && "rounded-2xl border-primary/25 border",
1970
- !mode && "rounded-2xl border"
1971
- );
1986
+ const sectionClasses = useSectionSurface(surface);
1972
1987
  if (variant === "timeline") {
1973
1988
  const resolvedGroups = groups ?? (steps ? [{ steps }] : []);
1974
1989
  let nextNumber = 1;
@@ -1977,7 +1992,7 @@ function StepsSection({
1977
1992
  /* @__PURE__ */ jsx("div", { className: "mt-12", children: resolvedGroups.map((group, groupIndex) => {
1978
1993
  const startNumber = nextNumber;
1979
1994
  nextNumber += group.steps.length;
1980
- return /* @__PURE__ */ jsxs(React20.Fragment, { children: [
1995
+ return /* @__PURE__ */ jsxs(React21.Fragment, { children: [
1981
1996
  /* @__PURE__ */ jsx("div", { className: cn$1(groupIndex > 0 && "mt-10"), children: /* @__PURE__ */ jsx(TimelineGroup, { steps: group.steps, startNumber, fadeIn: groupIndex > 0 }) }),
1982
1997
  group.after && /* @__PURE__ */ jsx("div", { className: "mt-16", children: group.after })
1983
1998
  ] }, groupIndex);
@@ -2021,15 +2036,11 @@ function TechStackSection({
2021
2036
  badge = "Built on",
2022
2037
  title = "The stack",
2023
2038
  description,
2024
- items
2039
+ items,
2040
+ surface
2025
2041
  }) {
2026
2042
  const mode = useUIVariant();
2027
- const sectionClasses = cn$1(
2028
- "overflow-hidden bg-card",
2029
- mode === "smooth" && "rounded-3xl border",
2030
- mode === "playful" && "rounded-2xl border-primary/25 border",
2031
- !mode && "rounded-2xl border"
2032
- );
2043
+ const sectionClasses = useSectionSurface(surface);
2033
2044
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsx("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-4xl", children: [
2034
2045
  /* @__PURE__ */ jsx(SectionTitle, { badge, title, description }),
2035
2046
  /* @__PURE__ */ jsx(StaggerChildren, { className: "mt-12 grid gap-4 sm:grid-cols-2 lg:grid-cols-4", children: items.map((item) => {
@@ -2077,16 +2088,11 @@ function FeatureMarqueeSection({
2077
2088
  description,
2078
2089
  rows,
2079
2090
  speed = "normal",
2080
- pauseOnHover = true
2091
+ pauseOnHover = true,
2092
+ surface
2081
2093
  }) {
2082
- const mode = useUIVariant();
2083
2094
  const duration = speedDuration[speed];
2084
- const sectionClasses = cn$1(
2085
- "overflow-hidden bg-card",
2086
- mode === "smooth" && "rounded-3xl border",
2087
- mode === "playful" && "rounded-2xl border-primary/25 border",
2088
- !mode && "rounded-2xl border"
2089
- );
2095
+ const sectionClasses = useSectionSurface(surface);
2090
2096
  return /* @__PURE__ */ jsxs("section", { className: sectionClasses, children: [
2091
2097
  /* @__PURE__ */ jsxs("div", { className: "py-14 sm:py-20", children: [
2092
2098
  (title || badge || description) && /* @__PURE__ */ jsx(FadeIn, { direction: "up", children: /* @__PURE__ */ jsx("div", { className: "mx-auto mb-10 max-w-4xl px-6 sm:px-10", children: /* @__PURE__ */ jsx(SectionTitle, { title: title ?? "", description, badge }) }) }),
@@ -2147,9 +2153,9 @@ function FeatureMarqueeSection({
2147
2153
  ] });
2148
2154
  }
2149
2155
  function useIntersectionObserver(options) {
2150
- const ref = React20.useRef(null);
2151
- const [isIntersecting, setIsIntersecting] = React20.useState(false);
2152
- React20.useEffect(() => {
2156
+ const ref = React21.useRef(null);
2157
+ const [isIntersecting, setIsIntersecting] = React21.useState(false);
2158
+ React21.useEffect(() => {
2153
2159
  const el = ref.current;
2154
2160
  if (!el) return;
2155
2161
  const observer = new IntersectionObserver(([entry]) => {
@@ -2171,8 +2177,8 @@ function ShowcaseCta({
2171
2177
  sectionClasses
2172
2178
  }) {
2173
2179
  const [ref, intersecting] = useIntersectionObserver({ threshold: 0.15 });
2174
- const [visible, setVisible] = React20.useState(false);
2175
- React20.useEffect(() => {
2180
+ const [visible, setVisible] = React21.useState(false);
2181
+ React21.useEffect(() => {
2176
2182
  if (intersecting) setVisible(true);
2177
2183
  }, [intersecting]);
2178
2184
  return /* @__PURE__ */ jsxs(
@@ -2221,15 +2227,11 @@ function CtaSection(props) {
2221
2227
  secondaryCta,
2222
2228
  footnote,
2223
2229
  variant = "default",
2224
- renderLink = defaultRenderLink5
2230
+ renderLink = defaultRenderLink5,
2231
+ surface
2225
2232
  } = props;
2226
2233
  const mode = useUIVariant();
2227
- const sectionClasses = cn$1(
2228
- "overflow-hidden bg-card",
2229
- mode === "smooth" && "rounded-3xl border",
2230
- mode === "playful" && "rounded-2xl border-primary/25 border",
2231
- !mode && "rounded-2xl border"
2232
- );
2234
+ const sectionClasses = useSectionSurface(surface);
2233
2235
  if (variant === "showcase") {
2234
2236
  return /* @__PURE__ */ jsx(ShowcaseCta, { ...props, sectionClasses });
2235
2237
  }
@@ -2313,25 +2315,25 @@ function AnimatedSwap({
2313
2315
  const ms = duration ?? spec?.duration ?? 0;
2314
2316
  const reduced = usePrefersReducedMotion();
2315
2317
  const animated = spec !== null && !reduced;
2316
- const previous = React20.useRef(children);
2317
- const seenKey = React20.useRef(swapKey);
2318
- const [swap, setSwap] = React20.useState(null);
2318
+ const previous = React21.useRef(children);
2319
+ const seenKey = React21.useRef(swapKey);
2320
+ const [swap, setSwap] = React21.useState(null);
2319
2321
  if (seenKey.current !== swapKey) {
2320
2322
  const out = previous.current;
2321
2323
  seenKey.current = swapKey;
2322
2324
  if (animated) setSwap({ key: swapKey, out, running: false });
2323
2325
  }
2324
- React20.useEffect(() => {
2326
+ React21.useEffect(() => {
2325
2327
  previous.current = children;
2326
2328
  });
2327
- React20.useEffect(() => {
2329
+ React21.useEffect(() => {
2328
2330
  if (!swap || swap.running) return;
2329
2331
  const raf = requestAnimationFrame(() => {
2330
2332
  setSwap((s) => s && s.key === swap.key ? { ...s, running: true } : s);
2331
2333
  });
2332
2334
  return () => cancelAnimationFrame(raf);
2333
2335
  }, [swap]);
2334
- React20.useEffect(() => {
2336
+ React21.useEffect(() => {
2335
2337
  if (!swap?.running) return;
2336
2338
  const done = setTimeout(() => {
2337
2339
  setSwap((s) => s && s.key === swap.key ? null : s);
@@ -2361,8 +2363,8 @@ function AnimatedSwap({
2361
2363
  );
2362
2364
  }
2363
2365
  function usePrefersReducedMotion() {
2364
- const [reduced, setReduced] = React20.useState(false);
2365
- React20.useEffect(() => {
2366
+ const [reduced, setReduced] = React21.useState(false);
2367
+ React21.useEffect(() => {
2366
2368
  const query = window.matchMedia?.("(prefers-reduced-motion: reduce)");
2367
2369
  if (!query) return;
2368
2370
  setReduced(query.matches);
@@ -2474,8 +2476,8 @@ function CountdownTimer({
2474
2476
  className,
2475
2477
  compact = false
2476
2478
  }) {
2477
- const [timeLeft, setTimeLeft] = React20.useState(() => getTimeLeft(deadline));
2478
- React20.useEffect(() => {
2479
+ const [timeLeft, setTimeLeft] = React21.useState(() => getTimeLeft(deadline));
2480
+ React21.useEffect(() => {
2479
2481
  setTimeLeft(getTimeLeft(deadline));
2480
2482
  const id = setInterval(() => setTimeLeft(getTimeLeft(deadline)), 1e3);
2481
2483
  return () => clearInterval(id);
@@ -2501,7 +2503,7 @@ function CountdownTimer({
2501
2503
  ];
2502
2504
  return /* @__PURE__ */ jsxs("div", { className: cn$1("flex items-center justify-center gap-2 text-sm", className), children: [
2503
2505
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
2504
- /* @__PURE__ */ jsx("span", { className: "flex items-center gap-1 font-mono font-semibold tabular-nums", children: units.map(({ value, unit }, i) => /* @__PURE__ */ jsxs(React20.Fragment, { children: [
2506
+ /* @__PURE__ */ jsx("span", { className: "flex items-center gap-1 font-mono font-semibold tabular-nums", children: units.map(({ value, unit }, i) => /* @__PURE__ */ jsxs(React21.Fragment, { children: [
2505
2507
  /* @__PURE__ */ jsxs("span", { children: [
2506
2508
  String(value).padStart(2, "0"),
2507
2509
  /* @__PURE__ */ jsx("span", { className: "font-normal text-muted-foreground", children: unit })
@@ -2555,26 +2557,21 @@ function PricingSection({
2555
2557
  defaultCadence,
2556
2558
  onSelectPlan,
2557
2559
  pendingPlanName,
2558
- priceEffect
2560
+ priceEffect,
2561
+ surface
2559
2562
  }) {
2560
- const [annual, setAnnual] = React20.useState(false);
2563
+ const [annual, setAnnual] = React21.useState(false);
2561
2564
  const isOneTime = mode === "one-time";
2562
2565
  const useCadences = !!cadences?.length;
2563
2566
  const initialCadence = (defaultCadence && cadences?.some((c) => c.key === defaultCadence) ? defaultCadence : null) ?? cadences?.[0]?.key ?? "";
2564
- const [activeCadence, setActiveCadence] = React20.useState(initialCadence);
2567
+ const [activeCadence, setActiveCadence] = React21.useState(initialCadence);
2565
2568
  const cadence = cadences?.find((c) => c.key === activeCadence);
2566
- const saveBadges = React20.useMemo(
2569
+ const saveBadges = React21.useMemo(
2567
2570
  () => useCadences ? computeSaveBadges(plans, cadences, initialCadence) : {},
2568
2571
  [useCadences, plans, cadences, initialCadence]
2569
2572
  );
2570
2573
  const showToggle = useCadences ? cadences.length > 1 : !isOneTime;
2571
- const uiMode = useUIVariant();
2572
- const sectionClasses = cn$1(
2573
- "overflow-hidden bg-card",
2574
- uiMode === "smooth" && "rounded-3xl border",
2575
- uiMode === "playful" && "rounded-2xl border-primary/25 border",
2576
- !uiMode && "rounded-2xl border"
2577
- );
2574
+ const sectionClasses = useSectionSurface(surface);
2578
2575
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsx("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-5xl", children: [
2579
2576
  /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
2580
2577
  badge && (typeof badge === "string" ? /* @__PURE__ */ jsx(Badge$1, { variant: "secondary", className: "mb-4", children: badge }) : /* @__PURE__ */ jsx("div", { className: "mb-4", children: badge })),
@@ -2729,15 +2726,10 @@ function TestimonialsSection({
2729
2726
  title = "Trusted by teams shipping real products",
2730
2727
  description = "Here's what engineers and product teams say after using Olwiba in production.",
2731
2728
  badge = "Testimonials",
2732
- testimonials
2729
+ testimonials,
2730
+ surface
2733
2731
  }) {
2734
- const mode = useUIVariant();
2735
- const sectionClasses = cn$1(
2736
- "overflow-hidden bg-card",
2737
- mode === "smooth" && "rounded-3xl border",
2738
- mode === "playful" && "rounded-2xl border-primary/25 border",
2739
- !mode && "rounded-2xl border"
2740
- );
2732
+ const sectionClasses = useSectionSurface(surface);
2741
2733
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsx("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-5xl", children: [
2742
2734
  /* @__PURE__ */ jsx(SectionTitle, { title, description, badge }),
2743
2735
  /* @__PURE__ */ jsx(StaggerChildren, { className: "mt-12 columns-1 gap-4 sm:columns-2 lg:columns-3", children: testimonials.map((t) => /* @__PURE__ */ jsx(
@@ -2791,15 +2783,10 @@ function TeamSection({
2791
2783
  members = defaultTeam,
2792
2784
  badge = "Team",
2793
2785
  title = "The people behind Olwiba",
2794
- description = "A small team with deep experience in design systems, open source, and developer tooling."
2786
+ description = "A small team with deep experience in design systems, open source, and developer tooling.",
2787
+ surface
2795
2788
  }) {
2796
- const mode = useUIVariant();
2797
- const sectionClasses = cn$1(
2798
- "overflow-hidden bg-card",
2799
- mode === "smooth" && "rounded-3xl border",
2800
- mode === "playful" && "rounded-2xl border-primary/25 border",
2801
- !mode && "rounded-2xl border"
2802
- );
2789
+ const sectionClasses = useSectionSurface(surface);
2803
2790
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsx("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-5xl", children: [
2804
2791
  /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
2805
2792
  /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "mb-4", children: badge }),
@@ -2830,15 +2817,10 @@ function FaqSection({
2830
2817
  title = "Frequently asked questions",
2831
2818
  description = "Everything you need to know before getting started.",
2832
2819
  badge = "FAQ",
2833
- items
2820
+ items,
2821
+ surface
2834
2822
  }) {
2835
- const mode = useUIVariant();
2836
- const sectionClasses = cn$1(
2837
- "overflow-hidden bg-card",
2838
- mode === "smooth" && "rounded-3xl border",
2839
- mode === "playful" && "rounded-2xl border-primary/25 border",
2840
- !mode && "rounded-2xl border"
2841
- );
2823
+ const sectionClasses = useSectionSurface(surface);
2842
2824
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsx("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-3xl", children: [
2843
2825
  /* @__PURE__ */ jsx(SectionTitle, { title, description, badge }),
2844
2826
  /* @__PURE__ */ jsx(FadeIn, { direction: "up", children: /* @__PURE__ */ jsx(Accordion, { type: "single", collapsible: true, className: "mt-10 w-full", children: items.map((item, i) => /* @__PURE__ */ jsxs(AccordionItem, { value: `item-${i}`, children: [
@@ -2858,10 +2840,10 @@ function CountUp({
2858
2840
  className,
2859
2841
  ...props
2860
2842
  }) {
2861
- const ref = React20.useRef(null);
2862
- const [value, setValue] = React20.useState(from);
2863
- const hasStarted = React20.useRef(false);
2864
- React20.useEffect(() => {
2843
+ const ref = React21.useRef(null);
2844
+ const [value, setValue] = React21.useState(from);
2845
+ const hasStarted = React21.useRef(false);
2846
+ React21.useEffect(() => {
2865
2847
  const el = ref.current;
2866
2848
  if (!el) return;
2867
2849
  const observer = new IntersectionObserver(
@@ -2907,15 +2889,10 @@ function StatsSection({
2907
2889
  title = "Built for scale, used in production",
2908
2890
  description,
2909
2891
  badge = "By the numbers",
2910
- stats
2892
+ stats,
2893
+ surface
2911
2894
  }) {
2912
- const mode = useUIVariant();
2913
- const sectionClasses = cn$1(
2914
- "overflow-hidden bg-card",
2915
- mode === "smooth" && "rounded-3xl border",
2916
- mode === "playful" && "rounded-2xl border-primary/25 border",
2917
- !mode && "rounded-2xl border"
2918
- );
2895
+ const sectionClasses = useSectionSurface(surface);
2919
2896
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsxs("div", { className: "relative px-6 py-14 sm:px-10 sm:py-20", children: [
2920
2897
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-[radial-gradient(ellipse_at_bottom,hsl(var(--primary)/0.08),transparent_60%)]" }),
2921
2898
  /* @__PURE__ */ jsxs("div", { className: "relative mx-auto max-w-4xl", children: [
@@ -2952,17 +2929,12 @@ function NewsletterSection({
2952
2929
  privacyLabel = defaults.privacyLabel,
2953
2930
  successTitle = defaults.successTitle,
2954
2931
  successDescription = defaults.successDescription,
2955
- onSubscribe
2932
+ onSubscribe,
2933
+ surface
2956
2934
  } = {}) {
2957
- const [email, setEmail] = React20.useState("");
2958
- const [submitted, setSubmitted] = React20.useState(false);
2959
- const mode = useUIVariant();
2960
- const sectionClasses = cn$1(
2961
- "overflow-hidden bg-card",
2962
- mode === "smooth" && "rounded-3xl border",
2963
- mode === "playful" && "rounded-2xl border-primary/25 border",
2964
- !mode && "rounded-2xl border"
2965
- );
2935
+ const [email, setEmail] = React21.useState("");
2936
+ const [submitted, setSubmitted] = React21.useState(false);
2937
+ const sectionClasses = useSectionSurface(surface);
2966
2938
  async function handleSubmit(e) {
2967
2939
  e.preventDefault();
2968
2940
  if (!email) return;
@@ -3044,16 +3016,11 @@ function ContactSection({
3044
3016
  successTitle = defaults2.successTitle,
3045
3017
  successDescription = defaults2.successDescription,
3046
3018
  sendAnotherLabel = defaults2.sendAnotherLabel,
3047
- onSubmit
3019
+ onSubmit,
3020
+ surface
3048
3021
  } = {}) {
3049
- const [submitted, setSubmitted] = React20.useState(false);
3050
- const mode = useUIVariant();
3051
- const sectionClasses = cn$1(
3052
- "overflow-hidden bg-card",
3053
- mode === "smooth" && "rounded-3xl border",
3054
- mode === "playful" && "rounded-2xl border-primary/25 border",
3055
- !mode && "rounded-2xl border"
3056
- );
3022
+ const [submitted, setSubmitted] = React21.useState(false);
3023
+ const sectionClasses = useSectionSurface(surface);
3057
3024
  async function handleSubmit(e) {
3058
3025
  e.preventDefault();
3059
3026
  await onSubmit?.(e);
@@ -3237,15 +3204,10 @@ function ComparisonSection({
3237
3204
  badge = "The math",
3238
3205
  title = "The math is simple",
3239
3206
  description,
3240
- columns
3207
+ columns,
3208
+ surface
3241
3209
  }) {
3242
- const mode = useUIVariant();
3243
- const sectionClasses = cn$1(
3244
- "overflow-hidden bg-card",
3245
- mode === "smooth" && "rounded-3xl border",
3246
- mode === "playful" && "rounded-2xl border-primary/25 border",
3247
- !mode && "rounded-2xl border"
3248
- );
3210
+ const sectionClasses = useSectionSurface(surface);
3249
3211
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsx("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-4xl", children: [
3250
3212
  /* @__PURE__ */ jsx(SectionTitle, { badge, title, description }),
3251
3213
  /* @__PURE__ */ jsx(StaggerChildren, { className: "mt-12 grid gap-4 sm:grid-cols-3", children: columns.map((col) => /* @__PURE__ */ jsxs(
@@ -3293,15 +3255,10 @@ function QualificationSection({
3293
3255
  badge = "Who it is for",
3294
3256
  title = "Is this for you?",
3295
3257
  description,
3296
- columns
3258
+ columns,
3259
+ surface
3297
3260
  }) {
3298
- const mode = useUIVariant();
3299
- const sectionClasses = cn$1(
3300
- "overflow-hidden bg-card",
3301
- mode === "smooth" && "rounded-3xl border",
3302
- mode === "playful" && "rounded-2xl border-primary/25 border",
3303
- !mode && "rounded-2xl border"
3304
- );
3261
+ const sectionClasses = useSectionSurface(surface);
3305
3262
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsx("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-4xl", children: [
3306
3263
  /* @__PURE__ */ jsx(SectionTitle, { badge, title, description }),
3307
3264
  /* @__PURE__ */ jsx(FadeIn, { direction: "up", className: "mt-12 grid gap-6 sm:grid-cols-2", children: columns.map((col) => {
@@ -3344,10 +3301,10 @@ function Navbar({
3344
3301
  controls,
3345
3302
  renderLink = defaultRenderLink7
3346
3303
  }) {
3347
- const [open, setOpen] = React20.useState(false);
3304
+ const [open, setOpen] = React21.useState(false);
3348
3305
  const brandHref = brand.href ?? "/";
3349
3306
  const hasRightContent = controls?.length || cta?.primary || cta?.secondary;
3350
- const closeMobileMenu = React20.useCallback(() => setOpen(false), []);
3307
+ const closeMobileMenu = React21.useCallback(() => setOpen(false), []);
3351
3308
  return /* @__PURE__ */ jsx("section", { className: "overflow-hidden rounded-2xl border bg-card", children: /* @__PURE__ */ jsxs("nav", { className: "grid h-16 grid-cols-[1fr_auto_1fr] items-center px-6", children: [
3352
3309
  renderLink({
3353
3310
  href: brandHref,
@@ -3362,7 +3319,7 @@ function Navbar({
3362
3319
  children: link.label
3363
3320
  }) }, link.label)) }),
3364
3321
  hasRightContent && /* @__PURE__ */ jsxs("div", { className: "hidden items-center justify-end gap-2 md:flex", children: [
3365
- controls?.map((control, i) => /* @__PURE__ */ jsx(React20.Fragment, { children: control }, i)),
3322
+ controls?.map((control, i) => /* @__PURE__ */ jsx(React21.Fragment, { children: control }, i)),
3366
3323
  (cta?.secondary || cta?.primary) && controls?.length ? /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-border" }) : null,
3367
3324
  cta?.secondary && renderLink({
3368
3325
  href: cta.secondary.href,
@@ -3375,7 +3332,7 @@ function Navbar({
3375
3332
  ] }),
3376
3333
  /* @__PURE__ */ jsxs(Sheet, { open, onOpenChange: setOpen, children: [
3377
3334
  /* @__PURE__ */ jsxs("div", { className: "col-start-3 flex items-center justify-end gap-1 md:hidden", children: [
3378
- controls?.map((control, i) => /* @__PURE__ */ jsx(React20.Fragment, { children: control }, i)),
3335
+ controls?.map((control, i) => /* @__PURE__ */ jsx(React21.Fragment, { children: control }, i)),
3379
3336
  /* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button$1, { variant: "ghost", size: "icon", children: [
3380
3337
  /* @__PURE__ */ jsx(Menu, { className: "size-5" }),
3381
3338
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Open menu" })
@@ -3537,7 +3494,7 @@ function LogoStrip({
3537
3494
  ] });
3538
3495
  }
3539
3496
  function GridUnderlay({ variant, size = 24, className, ...props }) {
3540
- const id = React20.useId();
3497
+ const id = React21.useId();
3541
3498
  const pattern = variant === "dots" ? /* @__PURE__ */ jsx("circle", { cx: size / 2, cy: size / 2, r: 1, fill: "currentColor" }) : variant === "lines" ? /* @__PURE__ */ jsx("path", { d: `M ${size} 0 L 0 0 0 ${size}`, fill: "none", stroke: "currentColor", strokeWidth: 0.5 }) : /* @__PURE__ */ jsxs(Fragment, { children: [
3542
3499
  /* @__PURE__ */ jsx("line", { x1: size / 2, y1: 0, x2: size / 2, y2: size, stroke: "currentColor", strokeWidth: 0.5 }),
3543
3500
  /* @__PURE__ */ jsx("line", { x1: 0, y1: size / 2, x2: size, y2: size / 2, stroke: "currentColor", strokeWidth: 0.5 })
@@ -3565,9 +3522,9 @@ function GlowUnderlay({
3565
3522
  style,
3566
3523
  ...props
3567
3524
  }) {
3568
- const [pos, setPos] = React20.useState({ x: "50%", y: "50%" });
3569
- const containerRef = React20.useRef(null);
3570
- React20.useEffect(() => {
3525
+ const [pos, setPos] = React21.useState({ x: "50%", y: "50%" });
3526
+ const containerRef = React21.useRef(null);
3527
+ React21.useEffect(() => {
3571
3528
  if (!followCursor) return;
3572
3529
  const handleMouseMove = (e) => {
3573
3530
  const el = containerRef.current;
@@ -3706,8 +3663,8 @@ function PageTransition({
3706
3663
  style,
3707
3664
  ...props
3708
3665
  }) {
3709
- const [mounted, setMounted] = React20.useState(false);
3710
- React20.useEffect(() => {
3666
+ const [mounted, setMounted] = React21.useState(false);
3667
+ React21.useEffect(() => {
3711
3668
  const id = requestAnimationFrame(() => setMounted(true));
3712
3669
  return () => cancelAnimationFrame(id);
3713
3670
  }, []);
@@ -3782,7 +3739,7 @@ function Sortable({
3782
3739
  if (oldIndex === -1 || newIndex === -1) return;
3783
3740
  onReorder(arrayMove(items, oldIndex, newIndex));
3784
3741
  };
3785
- const childArray = React20.Children.toArray(children);
3742
+ const childArray = React21.Children.toArray(children);
3786
3743
  return /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsx(SortableContext, { items, strategy: strategies[direction], children: /* @__PURE__ */ jsx("div", { className: cn$1(containerClasses[direction], className), children: childArray.map(
3787
3744
  (child, i) => items[i] === void 0 ? null : /* @__PURE__ */ jsx(SortableItem, { id: items[i], disabled, className: itemClassName, children: child }, items[i])
3788
3745
  ) }) }) });
@@ -3794,8 +3751,8 @@ function Spotlight({
3794
3751
  triggerClassName,
3795
3752
  shortcut = "\u2318K"
3796
3753
  }) {
3797
- const [open, setOpen] = React20.useState(false);
3798
- React20.useEffect(() => {
3754
+ const [open, setOpen] = React21.useState(false);
3755
+ React21.useEffect(() => {
3799
3756
  const down = (e) => {
3800
3757
  if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
3801
3758
  e.preventDefault();
@@ -3825,7 +3782,7 @@ function Spotlight({
3825
3782
  /* @__PURE__ */ jsx(CommandInput, { placeholder }),
3826
3783
  /* @__PURE__ */ jsxs(CommandList, { children: [
3827
3784
  /* @__PURE__ */ jsx(CommandEmpty, { children: "No results found." }),
3828
- groups.map((group, i) => /* @__PURE__ */ jsxs(React20.Fragment, { children: [
3785
+ groups.map((group, i) => /* @__PURE__ */ jsxs(React21.Fragment, { children: [
3829
3786
  i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
3830
3787
  /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
3831
3788
  CommandItem,
@@ -3850,8 +3807,8 @@ function Spotlight({
3850
3807
  var BASE = 40;
3851
3808
  var MAGNIFY_RADIUS = 80;
3852
3809
  function Dock({ items, iconSize = BASE, magnification = 1.7, className, ...props }) {
3853
- const [mouseX, setMouseX] = React20.useState(null);
3854
- const containerRef = React20.useRef(null);
3810
+ const [mouseX, setMouseX] = React21.useState(null);
3811
+ const containerRef = React21.useRef(null);
3855
3812
  function getScale(index) {
3856
3813
  if (mouseX === null || !containerRef.current) return 1;
3857
3814
  const container = containerRef.current;
@@ -3950,7 +3907,7 @@ function ConfirmDialog({ isOpen, options, handleConfirm, handleCancel, destructi
3950
3907
  ] }) });
3951
3908
  }
3952
3909
  function RegisterHotkeys({ hotkeys }) {
3953
- React20.useEffect(() => {
3910
+ React21.useEffect(() => {
3954
3911
  const handleKeyDown = (event) => {
3955
3912
  for (const hotkey of hotkeys) {
3956
3913
  const matches = event.key.toLowerCase() === hotkey.key.toLowerCase() && !!event.ctrlKey === !!hotkey.ctrl && !!event.metaKey === !!hotkey.meta && !!event.shiftKey === !!hotkey.shift && !!event.altKey === !!hotkey.alt;
@@ -3967,10 +3924,10 @@ function RegisterHotkeys({ hotkeys }) {
3967
3924
  return null;
3968
3925
  }
3969
3926
  function useControlledOpen(defaultOpen = false) {
3970
- const [isOpen, setIsOpen] = React20.useState(defaultOpen);
3971
- const open = React20.useCallback(() => setIsOpen(true), []);
3972
- const close = React20.useCallback(() => setIsOpen(false), []);
3973
- const toggle = React20.useCallback(() => setIsOpen((prev) => !prev), []);
3927
+ const [isOpen, setIsOpen] = React21.useState(defaultOpen);
3928
+ const open = React21.useCallback(() => setIsOpen(true), []);
3929
+ const close = React21.useCallback(() => setIsOpen(false), []);
3930
+ const toggle = React21.useCallback(() => setIsOpen((prev) => !prev), []);
3974
3931
  return { isOpen, open, close, toggle, setIsOpen };
3975
3932
  }
3976
3933
  function CommandMenu({
@@ -3983,7 +3940,7 @@ function CommandMenu({
3983
3940
  }) {
3984
3941
  const internal = useControlledOpen(false);
3985
3942
  const isOpen = openProp ?? internal.isOpen;
3986
- const setOpen = React20.useCallback(
3943
+ const setOpen = React21.useCallback(
3987
3944
  (next) => {
3988
3945
  if (openProp === void 0) internal.setIsOpen(next);
3989
3946
  onOpenChange?.(next);
@@ -4008,7 +3965,7 @@ function CommandMenu({
4008
3965
  /* @__PURE__ */ jsx(CommandInput, { placeholder }),
4009
3966
  /* @__PURE__ */ jsxs(CommandList, { children: [
4010
3967
  /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
4011
- groups.map((group, i) => /* @__PURE__ */ jsxs(React20.Fragment, { children: [
3968
+ groups.map((group, i) => /* @__PURE__ */ jsxs(React21.Fragment, { children: [
4012
3969
  i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
4013
3970
  /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
4014
3971
  CommandItem,
@@ -4063,7 +4020,7 @@ function DataView({
4063
4020
  }
4064
4021
  );
4065
4022
  }
4066
- return /* @__PURE__ */ jsx(AppGrid, { columns: gridColumns, gap, className: cn$1(className), children: items.map((item) => /* @__PURE__ */ jsx(React20.Fragment, { children: renderCard(item) }, getRowId(item))) });
4023
+ return /* @__PURE__ */ jsx(AppGrid, { columns: gridColumns, gap, className: cn$1(className), children: items.map((item) => /* @__PURE__ */ jsx(React21.Fragment, { children: renderCard(item) }, getRowId(item))) });
4067
4024
  }
4068
4025
  var TOKEN_COLORS = ["var(--chart-1)", "var(--chart-2)", "var(--chart-3)", "var(--chart-4)", "var(--chart-5)"];
4069
4026
  var seriesColor = (s, i) => s.color ?? TOKEN_COLORS[i % TOKEN_COLORS.length];
@@ -4237,20 +4194,20 @@ function FileUpload({
4237
4194
  hint,
4238
4195
  className
4239
4196
  }) {
4240
- const [internalFiles, setInternalFiles] = React20.useState(defaultFiles ?? []);
4241
- const [isDragging, setIsDragging] = React20.useState(false);
4242
- const [validationError, setValidationError] = React20.useState(null);
4243
- const inputRef = React20.useRef(null);
4244
- const dragDepth = React20.useRef(0);
4197
+ const [internalFiles, setInternalFiles] = React21.useState(defaultFiles ?? []);
4198
+ const [isDragging, setIsDragging] = React21.useState(false);
4199
+ const [validationError, setValidationError] = React21.useState(null);
4200
+ const inputRef = React21.useRef(null);
4201
+ const dragDepth = React21.useRef(0);
4245
4202
  const files = filesProp ?? internalFiles;
4246
- const setFiles = React20.useCallback(
4203
+ const setFiles = React21.useCallback(
4247
4204
  (next) => {
4248
4205
  if (!filesProp) setInternalFiles(next);
4249
4206
  onFilesChange?.(next);
4250
4207
  },
4251
4208
  [filesProp, onFilesChange]
4252
4209
  );
4253
- const acceptList = React20.useMemo(
4210
+ const acceptList = React21.useMemo(
4254
4211
  () => accept?.split(",").map((a) => a.trim().toLowerCase()).filter(Boolean) ?? [],
4255
4212
  [accept]
4256
4213
  );
@@ -4974,7 +4931,7 @@ function PageHeader({
4974
4931
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1 pb-6", className), children: [
4975
4932
  breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-2 flex items-center gap-1 text-sm text-muted-foreground", children: breadcrumbs.map((crumb, i) => {
4976
4933
  const isLast = i === breadcrumbs.length - 1;
4977
- return /* @__PURE__ */ jsxs(React20.Fragment, { children: [
4934
+ return /* @__PURE__ */ jsxs(React21.Fragment, { children: [
4978
4935
  i > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "size-3.5 shrink-0" }),
4979
4936
  isLast || !crumb.href ? /* @__PURE__ */ jsx("span", { className: cn(isLast && "text-foreground font-medium"), children: crumb.label }) : renderLink({
4980
4937
  href: crumb.href,
@@ -5010,7 +4967,7 @@ function PageHeader({
5010
4967
  ] });
5011
4968
  }
5012
4969
  function Suspensed({ children, fallback }) {
5013
- return /* @__PURE__ */ jsx(React20.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
4970
+ return /* @__PURE__ */ jsx(React21.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
5014
4971
  }
5015
4972
  function getInitialTheme() {
5016
4973
  if (typeof document === "undefined") return "dark";
@@ -5018,7 +4975,7 @@ function getInitialTheme() {
5018
4975
  return stored ?? (document.documentElement.classList.contains("dark") ? "dark" : "light");
5019
4976
  }
5020
4977
  function ThemeSwitchMinimal() {
5021
- const [theme, setThemeState] = React20.useState(getInitialTheme);
4978
+ const [theme, setThemeState] = React21.useState(getInitialTheme);
5022
4979
  const toggle = () => {
5023
4980
  const next = theme === "dark" ? "light" : "dark";
5024
4981
  setThemeState(next);
@@ -5144,9 +5101,9 @@ function getInitialColorName() {
5144
5101
  return localStorage.getItem(STORAGE_KEY) ?? "emerald";
5145
5102
  }
5146
5103
  function BrandColorSwitchMinimal() {
5147
- const [active, setActive] = React20.useState(getInitialColorName);
5148
- const [open, setOpen] = React20.useState(false);
5149
- React20.useEffect(() => {
5104
+ const [active, setActive] = React21.useState(getInitialColorName);
5105
+ const [open, setOpen] = React21.useState(false);
5106
+ React21.useEffect(() => {
5150
5107
  const saved = localStorage.getItem(STORAGE_KEY) ?? "emerald";
5151
5108
  const color = BRAND_COLORS.find((c) => c.name === saved);
5152
5109
  if (color) applyColor(color);
@@ -5207,7 +5164,7 @@ function BrandColorSwitchMinimal() {
5207
5164
  ] });
5208
5165
  }
5209
5166
  function ThemeColorUpdater({ colorTheme }) {
5210
- React20.useEffect(() => {
5167
+ React21.useEffect(() => {
5211
5168
  if (colorTheme) {
5212
5169
  document.documentElement.setAttribute("data-theme", colorTheme);
5213
5170
  } else {
@@ -5217,7 +5174,7 @@ function ThemeColorUpdater({ colorTheme }) {
5217
5174
  return null;
5218
5175
  }
5219
5176
  function VersionBanner({ version, message, className, onDismiss }) {
5220
- const [dismissed, setDismissed] = React20.useState(false);
5177
+ const [dismissed, setDismissed] = React21.useState(false);
5221
5178
  if (dismissed) return null;
5222
5179
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-4 bg-primary/10 px-4 py-2 text-sm", className), children: [
5223
5180
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
@@ -5474,29 +5431,29 @@ function useMounted() {
5474
5431
  return mounted;
5475
5432
  }
5476
5433
  function useConfirm() {
5477
- const [isOpen, setIsOpen] = React20.useState(false);
5478
- const [options, setOptions] = React20.useState({});
5479
- const resolveRef = React20.useRef(null);
5480
- const confirm = React20.useCallback((opts = {}) => {
5434
+ const [isOpen, setIsOpen] = React21.useState(false);
5435
+ const [options, setOptions] = React21.useState({});
5436
+ const resolveRef = React21.useRef(null);
5437
+ const confirm = React21.useCallback((opts = {}) => {
5481
5438
  setOptions(opts);
5482
5439
  setIsOpen(true);
5483
5440
  return new Promise((resolve) => {
5484
5441
  resolveRef.current = resolve;
5485
5442
  });
5486
5443
  }, []);
5487
- const handleConfirm = React20.useCallback(() => {
5444
+ const handleConfirm = React21.useCallback(() => {
5488
5445
  resolveRef.current?.(true);
5489
5446
  setIsOpen(false);
5490
5447
  }, []);
5491
- const handleCancel = React20.useCallback(() => {
5448
+ const handleCancel = React21.useCallback(() => {
5492
5449
  resolveRef.current?.(false);
5493
5450
  setIsOpen(false);
5494
5451
  }, []);
5495
5452
  return { confirm, isOpen, options, handleConfirm, handleCancel };
5496
5453
  }
5497
5454
  function useScrolledPast(threshold) {
5498
- const [scrolledPast, setScrolledPast] = React20.useState(false);
5499
- React20.useEffect(() => {
5455
+ const [scrolledPast, setScrolledPast] = React21.useState(false);
5456
+ React21.useEffect(() => {
5500
5457
  const handleScroll = () => {
5501
5458
  setScrolledPast(window.scrollY > threshold);
5502
5459
  };
@@ -5507,28 +5464,28 @@ function useScrolledPast(threshold) {
5507
5464
  return scrolledPast;
5508
5465
  }
5509
5466
  function useCopyToClipboard() {
5510
- const [copied, setCopied] = React20.useState(false);
5511
- const timeoutRef = React20.useRef(void 0);
5512
- const copy = React20.useCallback((text) => {
5467
+ const [copied, setCopied] = React21.useState(false);
5468
+ const timeoutRef = React21.useRef(void 0);
5469
+ const copy = React21.useCallback((text) => {
5513
5470
  navigator.clipboard.writeText(text).then(() => {
5514
5471
  setCopied(true);
5515
5472
  clearTimeout(timeoutRef.current);
5516
5473
  timeoutRef.current = setTimeout(() => setCopied(false), 2e3);
5517
5474
  });
5518
5475
  }, []);
5519
- React20.useEffect(() => () => clearTimeout(timeoutRef.current), []);
5476
+ React21.useEffect(() => () => clearTimeout(timeoutRef.current), []);
5520
5477
  return [copied, copy];
5521
5478
  }
5522
5479
  function useDebounce(value, delay) {
5523
- const [debounced, setDebounced] = React20.useState(value);
5524
- React20.useEffect(() => {
5480
+ const [debounced, setDebounced] = React21.useState(value);
5481
+ React21.useEffect(() => {
5525
5482
  const timer = setTimeout(() => setDebounced(value), delay);
5526
5483
  return () => clearTimeout(timer);
5527
5484
  }, [value, delay]);
5528
5485
  return debounced;
5529
5486
  }
5530
5487
  function useLocalStorage(key, initialValue) {
5531
- const [storedValue, setStoredValue] = React20.useState(() => {
5488
+ const [storedValue, setStoredValue] = React21.useState(() => {
5532
5489
  if (typeof window === "undefined") return initialValue;
5533
5490
  try {
5534
5491
  const item = window.localStorage.getItem(key);
@@ -5537,7 +5494,7 @@ function useLocalStorage(key, initialValue) {
5537
5494
  return initialValue;
5538
5495
  }
5539
5496
  });
5540
- const setValue = React20.useCallback(
5497
+ const setValue = React21.useCallback(
5541
5498
  (value) => {
5542
5499
  try {
5543
5500
  setStoredValue(value);
@@ -5559,11 +5516,11 @@ function useViewMode(key = "view-mode", fallback = "cards") {
5559
5516
  return { view: mounted ? stored : fallback, setView: setStored, ready: mounted };
5560
5517
  }
5561
5518
  function useMediaQuery(query) {
5562
- const [matches, setMatches] = React20.useState(() => {
5519
+ const [matches, setMatches] = React21.useState(() => {
5563
5520
  if (typeof window === "undefined") return false;
5564
5521
  return window.matchMedia(query).matches;
5565
5522
  });
5566
- React20.useEffect(() => {
5523
+ React21.useEffect(() => {
5567
5524
  if (typeof window === "undefined") return;
5568
5525
  const mql = window.matchMedia(query);
5569
5526
  setMatches(mql.matches);
@@ -5574,18 +5531,18 @@ function useMediaQuery(query) {
5574
5531
  return matches;
5575
5532
  }
5576
5533
  function usePagination(total, pageSize) {
5577
- const [page, setPage] = React20.useState(1);
5534
+ const [page, setPage] = React21.useState(1);
5578
5535
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
5579
5536
  const offset = (page - 1) * pageSize;
5580
- const goTo = React20.useCallback(
5537
+ const goTo = React21.useCallback(
5581
5538
  (p) => setPage(Math.min(Math.max(1, p), totalPages)),
5582
5539
  [totalPages]
5583
5540
  );
5584
- const next = React20.useCallback(() => goTo(page + 1), [page, goTo]);
5585
- const prev = React20.useCallback(() => goTo(page - 1), [page, goTo]);
5541
+ const next = React21.useCallback(() => goTo(page + 1), [page, goTo]);
5542
+ const prev = React21.useCallback(() => goTo(page - 1), [page, goTo]);
5586
5543
  return { page, pageSize, totalPages, offset, hasPrev: page > 1, hasNext: page < totalPages, goTo, next, prev };
5587
5544
  }
5588
5545
 
5589
- export { ActivityFeed, AnimatedPill, AnimatedSwap, AppContent, AppGrid, AppGridCell, AppPageHero, AppScreen, AppShell, AuthSection, Badge, BillingPanel, BrandColorSwitchMinimal, Button, Card, Carousel, ChangelogCard, ChangelogList, Chart, Checkbox, CommandMenu, ComparisonSection, ConfirmDialog, ContactSection, ContextMenu, CountUp, CountdownTimer, CtaSection, DataTable, DataView, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeatureMarqueeSection, FeaturesSection, FileUpload, FlowBracket, FlowConnector, Footer, FullPageSpinner, GlassCard, Grid, GridItem, GroupedFeaturesSection, HeroSection, ImageCard, Input, LogoStrip, MediaCard, ModeSwitchMinimal, Navbar, NewsletterSection, NotificationToast, NotificationsPopover, OlwibaUIProvider, OnboardingWizard, Overlay, PageHeader, PageTransition, PhoneFrame, PostCard, PostList, PricingCard, PricingSection, PublicPageFrame, QualificationSection, RegisterHotkeys, RootErrorFallback, Section, SectionTitle, SettingsSection, Sortable, Spotlight, Stack, StaggerChildren, StatCard, StatsSection, StepsSection, Suspensed, Switch, TeamMembersPanel, TeamSection, TechStackSection, TestimonialCard, TestimonialsSection, Textarea, ThemeColorUpdater, ThemeSwitchMinimal, Underlay, UpdateBanner, UpgradePrompt, VersionBanner, ViewToggle, marketingSectionSpacing, notify, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode, useViewMode };
5546
+ export { ActivityFeed, AnimatedPill, AnimatedSwap, AppContent, AppGrid, AppGridCell, AppPageHero, AppScreen, AppShell, AuthSection, Badge, BillingPanel, BrandColorSwitchMinimal, Button, Card, Carousel, ChangelogCard, ChangelogList, Chart, Checkbox, CommandMenu, ComparisonSection, ConfirmDialog, ContactSection, ContextMenu, CountUp, CountdownTimer, CtaSection, DataTable, DataView, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeatureMarqueeSection, FeaturesSection, FileUpload, FlowBracket, FlowConnector, Footer, FullPageSpinner, GlassCard, Grid, GridItem, GroupedFeaturesSection, HeroSection, ImageCard, Input, LogoStrip, MarketingSurfaceProvider, MediaCard, ModeSwitchMinimal, Navbar, NewsletterSection, NotificationToast, NotificationsPopover, OlwibaUIProvider, OnboardingWizard, Overlay, PageHeader, PageTransition, PhoneFrame, PostCard, PostList, PricingCard, PricingSection, PublicPageFrame, QualificationSection, RegisterHotkeys, RootErrorFallback, Section, SectionTitle, SettingsSection, Sortable, Spotlight, Stack, StaggerChildren, StatCard, StatsSection, StepsSection, Suspensed, Switch, TeamMembersPanel, TeamSection, TechStackSection, TestimonialCard, TestimonialsSection, Textarea, ThemeColorUpdater, ThemeSwitchMinimal, Underlay, UpdateBanner, UpgradePrompt, VersionBanner, ViewToggle, marketingSectionSpacing, notify, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMarketingSurface, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useSectionSurface, useUIMode, useViewMode };
5590
5547
  //# sourceMappingURL=index.js.map
5591
5548
  //# sourceMappingURL=index.js.map