@olwiba/ui 0.2.18 → 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]" },
@@ -1619,6 +1649,7 @@ function HeroSection({
1619
1649
  description,
1620
1650
  primaryCta,
1621
1651
  secondaryCta,
1652
+ primarySlot,
1622
1653
  heroImage,
1623
1654
  media = "image",
1624
1655
  phoneSize = "lg",
@@ -1633,19 +1664,28 @@ function HeroSection({
1633
1664
  badge && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: badge }) }),
1634
1665
  /* @__PURE__ */ jsx("h1", { className: "text-balance text-4xl font-semibold tracking-tight sm:text-5xl lg:text-6xl", children: heading }),
1635
1666
  /* @__PURE__ */ jsx("p", { className: "max-w-lg text-pretty text-lg text-muted-foreground", children: description }),
1636
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
1637
- renderLink({
1638
- href: primaryCta.href,
1639
- children: /* @__PURE__ */ jsxs(Button, { size: "lg", children: [
1640
- primaryCta.label,
1641
- /* @__PURE__ */ jsx(ArrowRight, { className: "ml-2 size-4" })
1642
- ] })
1643
- }),
1644
- secondaryCta && renderLink({
1645
- href: secondaryCta.href,
1646
- children: /* @__PURE__ */ jsx(Button, { size: "lg", variant: "outline", children: secondaryCta.label })
1647
- })
1648
- ] })
1667
+ /* @__PURE__ */ jsxs(
1668
+ "div",
1669
+ {
1670
+ className: cn$1(
1671
+ "flex gap-3",
1672
+ primarySlot ? "flex-col items-stretch sm:flex-row sm:items-center" : "flex-wrap items-center"
1673
+ ),
1674
+ children: [
1675
+ primarySlot ?? (primaryCta && renderLink({
1676
+ href: primaryCta.href,
1677
+ children: /* @__PURE__ */ jsxs(Button, { size: "lg", children: [
1678
+ primaryCta.label,
1679
+ /* @__PURE__ */ jsx(ArrowRight, { className: "ml-2 size-4" })
1680
+ ] })
1681
+ })),
1682
+ secondaryCta && renderLink({
1683
+ href: secondaryCta.href,
1684
+ children: /* @__PURE__ */ jsx(Button, { size: "lg", variant: "outline", children: secondaryCta.label })
1685
+ })
1686
+ ]
1687
+ }
1688
+ )
1649
1689
  ] }) }),
1650
1690
  media !== "none" && /* @__PURE__ */ jsx(FadeIn, { direction: "right", delay: 200, children: media === "phone" ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(PhoneFrame, { size: phoneSize, children: heroImage }) }) : /* @__PURE__ */ jsx("div", { className: cn$1("overflow-hidden", mode === "smooth" ? "rounded-3xl" : "rounded-2xl"), children: heroImage }) })
1651
1691
  ] }),
@@ -1714,16 +1754,16 @@ function Carousel({
1714
1754
  className
1715
1755
  }) {
1716
1756
  const mode = useUIVariant();
1717
- const trackRef = React20.useRef(null);
1718
- const [canPrev, setCanPrev] = React20.useState(false);
1719
- const [canNext, setCanNext] = React20.useState(true);
1720
- 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(() => {
1721
1761
  const track = trackRef.current;
1722
1762
  if (!track) return;
1723
1763
  setCanPrev(track.scrollLeft > 8);
1724
1764
  setCanNext(track.scrollLeft < track.scrollWidth - track.clientWidth - 8);
1725
1765
  }, []);
1726
- React20.useEffect(() => {
1766
+ React21.useEffect(() => {
1727
1767
  const track = trackRef.current;
1728
1768
  if (!track) return;
1729
1769
  updateScrollState();
@@ -1780,7 +1820,7 @@ function Carousel({
1780
1820
  role: "region",
1781
1821
  "aria-label": ariaLabel,
1782
1822
  className: "flex snap-x snap-mandatory gap-6 overflow-x-auto pb-4 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
1783
- children: React20.Children.map(
1823
+ children: React21.Children.map(
1784
1824
  children,
1785
1825
  (child) => child == null ? null : /* @__PURE__ */ jsx("div", { "data-carousel-item": true, className: cn$1("shrink-0 snap-start", itemClassName), children: child })
1786
1826
  )
@@ -1805,9 +1845,9 @@ function StaggerChildren({
1805
1845
  className,
1806
1846
  ...props
1807
1847
  }) {
1808
- const ref = React20.useRef(null);
1809
- const [visible, setVisible] = React20.useState(false);
1810
- React20.useEffect(() => {
1848
+ const ref = React21.useRef(null);
1849
+ const [visible, setVisible] = React21.useState(false);
1850
+ React21.useEffect(() => {
1811
1851
  const el = ref.current;
1812
1852
  if (!el) return;
1813
1853
  const observer = new IntersectionObserver(
@@ -1825,7 +1865,7 @@ function StaggerChildren({
1825
1865
  return () => observer.disconnect();
1826
1866
  }, [once]);
1827
1867
  const [tx, ty] = translateMap2[direction];
1828
- 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(
1829
1869
  "div",
1830
1870
  {
1831
1871
  className: "h-full",
@@ -1844,15 +1884,10 @@ function FeaturesSection({
1844
1884
  description = "A complete system of components, blocks, and hooks designed to work together - and get out of your way.",
1845
1885
  badge = "Features",
1846
1886
  features,
1847
- layout = "grid"
1887
+ layout = "grid",
1888
+ surface
1848
1889
  }) {
1849
- const mode = useUIVariant();
1850
- const sectionClasses = cn$1(
1851
- "overflow-hidden bg-card",
1852
- mode === "smooth" && "rounded-3xl border",
1853
- mode === "playful" && "rounded-2xl border-primary/25 border",
1854
- !mode && "rounded-2xl border"
1855
- );
1890
+ const sectionClasses = useSectionSurface(surface);
1856
1891
  const cards = features.map((feature) => /* @__PURE__ */ jsx(
1857
1892
  FeatureCard,
1858
1893
  {
@@ -1872,15 +1907,10 @@ function GroupedFeaturesSection({
1872
1907
  badge = "Features",
1873
1908
  title = "Everything you need to ship",
1874
1909
  description,
1875
- groups
1910
+ groups,
1911
+ surface
1876
1912
  }) {
1877
- const mode = useUIVariant();
1878
- const sectionClasses = cn$1(
1879
- "overflow-hidden bg-card",
1880
- mode === "smooth" && "rounded-3xl border",
1881
- mode === "playful" && "rounded-2xl border-primary/25 border",
1882
- !mode && "rounded-2xl border"
1883
- );
1913
+ const sectionClasses = useSectionSurface(surface);
1884
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: [
1885
1915
  /* @__PURE__ */ jsx(SectionTitle, { title, description, badge }),
1886
1916
  /* @__PURE__ */ jsx("div", { className: "mt-14 space-y-14", children: groups.map((group, i) => /* @__PURE__ */ jsxs("div", { children: [
@@ -1950,15 +1980,10 @@ function StepsSection({
1950
1980
  description,
1951
1981
  steps,
1952
1982
  variant = "default",
1953
- groups
1983
+ groups,
1984
+ surface
1954
1985
  }) {
1955
- const mode = useUIVariant();
1956
- const sectionClasses = cn$1(
1957
- "overflow-hidden bg-card",
1958
- mode === "smooth" && "rounded-3xl border",
1959
- mode === "playful" && "rounded-2xl border-primary/25 border",
1960
- !mode && "rounded-2xl border"
1961
- );
1986
+ const sectionClasses = useSectionSurface(surface);
1962
1987
  if (variant === "timeline") {
1963
1988
  const resolvedGroups = groups ?? (steps ? [{ steps }] : []);
1964
1989
  let nextNumber = 1;
@@ -1967,7 +1992,7 @@ function StepsSection({
1967
1992
  /* @__PURE__ */ jsx("div", { className: "mt-12", children: resolvedGroups.map((group, groupIndex) => {
1968
1993
  const startNumber = nextNumber;
1969
1994
  nextNumber += group.steps.length;
1970
- return /* @__PURE__ */ jsxs(React20.Fragment, { children: [
1995
+ return /* @__PURE__ */ jsxs(React21.Fragment, { children: [
1971
1996
  /* @__PURE__ */ jsx("div", { className: cn$1(groupIndex > 0 && "mt-10"), children: /* @__PURE__ */ jsx(TimelineGroup, { steps: group.steps, startNumber, fadeIn: groupIndex > 0 }) }),
1972
1997
  group.after && /* @__PURE__ */ jsx("div", { className: "mt-16", children: group.after })
1973
1998
  ] }, groupIndex);
@@ -2011,15 +2036,11 @@ function TechStackSection({
2011
2036
  badge = "Built on",
2012
2037
  title = "The stack",
2013
2038
  description,
2014
- items
2039
+ items,
2040
+ surface
2015
2041
  }) {
2016
2042
  const mode = useUIVariant();
2017
- const sectionClasses = cn$1(
2018
- "overflow-hidden bg-card",
2019
- mode === "smooth" && "rounded-3xl border",
2020
- mode === "playful" && "rounded-2xl border-primary/25 border",
2021
- !mode && "rounded-2xl border"
2022
- );
2043
+ const sectionClasses = useSectionSurface(surface);
2023
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: [
2024
2045
  /* @__PURE__ */ jsx(SectionTitle, { badge, title, description }),
2025
2046
  /* @__PURE__ */ jsx(StaggerChildren, { className: "mt-12 grid gap-4 sm:grid-cols-2 lg:grid-cols-4", children: items.map((item) => {
@@ -2067,16 +2088,11 @@ function FeatureMarqueeSection({
2067
2088
  description,
2068
2089
  rows,
2069
2090
  speed = "normal",
2070
- pauseOnHover = true
2091
+ pauseOnHover = true,
2092
+ surface
2071
2093
  }) {
2072
- const mode = useUIVariant();
2073
2094
  const duration = speedDuration[speed];
2074
- const sectionClasses = cn$1(
2075
- "overflow-hidden bg-card",
2076
- mode === "smooth" && "rounded-3xl border",
2077
- mode === "playful" && "rounded-2xl border-primary/25 border",
2078
- !mode && "rounded-2xl border"
2079
- );
2095
+ const sectionClasses = useSectionSurface(surface);
2080
2096
  return /* @__PURE__ */ jsxs("section", { className: sectionClasses, children: [
2081
2097
  /* @__PURE__ */ jsxs("div", { className: "py-14 sm:py-20", children: [
2082
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 }) }) }),
@@ -2137,9 +2153,9 @@ function FeatureMarqueeSection({
2137
2153
  ] });
2138
2154
  }
2139
2155
  function useIntersectionObserver(options) {
2140
- const ref = React20.useRef(null);
2141
- const [isIntersecting, setIsIntersecting] = React20.useState(false);
2142
- React20.useEffect(() => {
2156
+ const ref = React21.useRef(null);
2157
+ const [isIntersecting, setIsIntersecting] = React21.useState(false);
2158
+ React21.useEffect(() => {
2143
2159
  const el = ref.current;
2144
2160
  if (!el) return;
2145
2161
  const observer = new IntersectionObserver(([entry]) => {
@@ -2161,8 +2177,8 @@ function ShowcaseCta({
2161
2177
  sectionClasses
2162
2178
  }) {
2163
2179
  const [ref, intersecting] = useIntersectionObserver({ threshold: 0.15 });
2164
- const [visible, setVisible] = React20.useState(false);
2165
- React20.useEffect(() => {
2180
+ const [visible, setVisible] = React21.useState(false);
2181
+ React21.useEffect(() => {
2166
2182
  if (intersecting) setVisible(true);
2167
2183
  }, [intersecting]);
2168
2184
  return /* @__PURE__ */ jsxs(
@@ -2211,15 +2227,11 @@ function CtaSection(props) {
2211
2227
  secondaryCta,
2212
2228
  footnote,
2213
2229
  variant = "default",
2214
- renderLink = defaultRenderLink5
2230
+ renderLink = defaultRenderLink5,
2231
+ surface
2215
2232
  } = props;
2216
2233
  const mode = useUIVariant();
2217
- const sectionClasses = cn$1(
2218
- "overflow-hidden bg-card",
2219
- mode === "smooth" && "rounded-3xl border",
2220
- mode === "playful" && "rounded-2xl border-primary/25 border",
2221
- !mode && "rounded-2xl border"
2222
- );
2234
+ const sectionClasses = useSectionSurface(surface);
2223
2235
  if (variant === "showcase") {
2224
2236
  return /* @__PURE__ */ jsx(ShowcaseCta, { ...props, sectionClasses });
2225
2237
  }
@@ -2303,25 +2315,25 @@ function AnimatedSwap({
2303
2315
  const ms = duration ?? spec?.duration ?? 0;
2304
2316
  const reduced = usePrefersReducedMotion();
2305
2317
  const animated = spec !== null && !reduced;
2306
- const previous = React20.useRef(children);
2307
- const seenKey = React20.useRef(swapKey);
2308
- 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);
2309
2321
  if (seenKey.current !== swapKey) {
2310
2322
  const out = previous.current;
2311
2323
  seenKey.current = swapKey;
2312
2324
  if (animated) setSwap({ key: swapKey, out, running: false });
2313
2325
  }
2314
- React20.useEffect(() => {
2326
+ React21.useEffect(() => {
2315
2327
  previous.current = children;
2316
2328
  });
2317
- React20.useEffect(() => {
2329
+ React21.useEffect(() => {
2318
2330
  if (!swap || swap.running) return;
2319
2331
  const raf = requestAnimationFrame(() => {
2320
2332
  setSwap((s) => s && s.key === swap.key ? { ...s, running: true } : s);
2321
2333
  });
2322
2334
  return () => cancelAnimationFrame(raf);
2323
2335
  }, [swap]);
2324
- React20.useEffect(() => {
2336
+ React21.useEffect(() => {
2325
2337
  if (!swap?.running) return;
2326
2338
  const done = setTimeout(() => {
2327
2339
  setSwap((s) => s && s.key === swap.key ? null : s);
@@ -2351,8 +2363,8 @@ function AnimatedSwap({
2351
2363
  );
2352
2364
  }
2353
2365
  function usePrefersReducedMotion() {
2354
- const [reduced, setReduced] = React20.useState(false);
2355
- React20.useEffect(() => {
2366
+ const [reduced, setReduced] = React21.useState(false);
2367
+ React21.useEffect(() => {
2356
2368
  const query = window.matchMedia?.("(prefers-reduced-motion: reduce)");
2357
2369
  if (!query) return;
2358
2370
  setReduced(query.matches);
@@ -2464,8 +2476,8 @@ function CountdownTimer({
2464
2476
  className,
2465
2477
  compact = false
2466
2478
  }) {
2467
- const [timeLeft, setTimeLeft] = React20.useState(() => getTimeLeft(deadline));
2468
- React20.useEffect(() => {
2479
+ const [timeLeft, setTimeLeft] = React21.useState(() => getTimeLeft(deadline));
2480
+ React21.useEffect(() => {
2469
2481
  setTimeLeft(getTimeLeft(deadline));
2470
2482
  const id = setInterval(() => setTimeLeft(getTimeLeft(deadline)), 1e3);
2471
2483
  return () => clearInterval(id);
@@ -2491,7 +2503,7 @@ function CountdownTimer({
2491
2503
  ];
2492
2504
  return /* @__PURE__ */ jsxs("div", { className: cn$1("flex items-center justify-center gap-2 text-sm", className), children: [
2493
2505
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
2494
- /* @__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: [
2495
2507
  /* @__PURE__ */ jsxs("span", { children: [
2496
2508
  String(value).padStart(2, "0"),
2497
2509
  /* @__PURE__ */ jsx("span", { className: "font-normal text-muted-foreground", children: unit })
@@ -2545,26 +2557,21 @@ function PricingSection({
2545
2557
  defaultCadence,
2546
2558
  onSelectPlan,
2547
2559
  pendingPlanName,
2548
- priceEffect
2560
+ priceEffect,
2561
+ surface
2549
2562
  }) {
2550
- const [annual, setAnnual] = React20.useState(false);
2563
+ const [annual, setAnnual] = React21.useState(false);
2551
2564
  const isOneTime = mode === "one-time";
2552
2565
  const useCadences = !!cadences?.length;
2553
2566
  const initialCadence = (defaultCadence && cadences?.some((c) => c.key === defaultCadence) ? defaultCadence : null) ?? cadences?.[0]?.key ?? "";
2554
- const [activeCadence, setActiveCadence] = React20.useState(initialCadence);
2567
+ const [activeCadence, setActiveCadence] = React21.useState(initialCadence);
2555
2568
  const cadence = cadences?.find((c) => c.key === activeCadence);
2556
- const saveBadges = React20.useMemo(
2569
+ const saveBadges = React21.useMemo(
2557
2570
  () => useCadences ? computeSaveBadges(plans, cadences, initialCadence) : {},
2558
2571
  [useCadences, plans, cadences, initialCadence]
2559
2572
  );
2560
2573
  const showToggle = useCadences ? cadences.length > 1 : !isOneTime;
2561
- const uiMode = useUIVariant();
2562
- const sectionClasses = cn$1(
2563
- "overflow-hidden bg-card",
2564
- uiMode === "smooth" && "rounded-3xl border",
2565
- uiMode === "playful" && "rounded-2xl border-primary/25 border",
2566
- !uiMode && "rounded-2xl border"
2567
- );
2574
+ const sectionClasses = useSectionSurface(surface);
2568
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: [
2569
2576
  /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
2570
2577
  badge && (typeof badge === "string" ? /* @__PURE__ */ jsx(Badge$1, { variant: "secondary", className: "mb-4", children: badge }) : /* @__PURE__ */ jsx("div", { className: "mb-4", children: badge })),
@@ -2719,15 +2726,10 @@ function TestimonialsSection({
2719
2726
  title = "Trusted by teams shipping real products",
2720
2727
  description = "Here's what engineers and product teams say after using Olwiba in production.",
2721
2728
  badge = "Testimonials",
2722
- testimonials
2729
+ testimonials,
2730
+ surface
2723
2731
  }) {
2724
- const mode = useUIVariant();
2725
- const sectionClasses = cn$1(
2726
- "overflow-hidden bg-card",
2727
- mode === "smooth" && "rounded-3xl border",
2728
- mode === "playful" && "rounded-2xl border-primary/25 border",
2729
- !mode && "rounded-2xl border"
2730
- );
2732
+ const sectionClasses = useSectionSurface(surface);
2731
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: [
2732
2734
  /* @__PURE__ */ jsx(SectionTitle, { title, description, badge }),
2733
2735
  /* @__PURE__ */ jsx(StaggerChildren, { className: "mt-12 columns-1 gap-4 sm:columns-2 lg:columns-3", children: testimonials.map((t) => /* @__PURE__ */ jsx(
@@ -2781,15 +2783,10 @@ function TeamSection({
2781
2783
  members = defaultTeam,
2782
2784
  badge = "Team",
2783
2785
  title = "The people behind Olwiba",
2784
- 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
2785
2788
  }) {
2786
- const mode = useUIVariant();
2787
- const sectionClasses = cn$1(
2788
- "overflow-hidden bg-card",
2789
- mode === "smooth" && "rounded-3xl border",
2790
- mode === "playful" && "rounded-2xl border-primary/25 border",
2791
- !mode && "rounded-2xl border"
2792
- );
2789
+ const sectionClasses = useSectionSurface(surface);
2793
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: [
2794
2791
  /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
2795
2792
  /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "mb-4", children: badge }),
@@ -2820,15 +2817,10 @@ function FaqSection({
2820
2817
  title = "Frequently asked questions",
2821
2818
  description = "Everything you need to know before getting started.",
2822
2819
  badge = "FAQ",
2823
- items
2820
+ items,
2821
+ surface
2824
2822
  }) {
2825
- const mode = useUIVariant();
2826
- const sectionClasses = cn$1(
2827
- "overflow-hidden bg-card",
2828
- mode === "smooth" && "rounded-3xl border",
2829
- mode === "playful" && "rounded-2xl border-primary/25 border",
2830
- !mode && "rounded-2xl border"
2831
- );
2823
+ const sectionClasses = useSectionSurface(surface);
2832
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: [
2833
2825
  /* @__PURE__ */ jsx(SectionTitle, { title, description, badge }),
2834
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: [
@@ -2848,10 +2840,10 @@ function CountUp({
2848
2840
  className,
2849
2841
  ...props
2850
2842
  }) {
2851
- const ref = React20.useRef(null);
2852
- const [value, setValue] = React20.useState(from);
2853
- const hasStarted = React20.useRef(false);
2854
- React20.useEffect(() => {
2843
+ const ref = React21.useRef(null);
2844
+ const [value, setValue] = React21.useState(from);
2845
+ const hasStarted = React21.useRef(false);
2846
+ React21.useEffect(() => {
2855
2847
  const el = ref.current;
2856
2848
  if (!el) return;
2857
2849
  const observer = new IntersectionObserver(
@@ -2897,15 +2889,10 @@ function StatsSection({
2897
2889
  title = "Built for scale, used in production",
2898
2890
  description,
2899
2891
  badge = "By the numbers",
2900
- stats
2892
+ stats,
2893
+ surface
2901
2894
  }) {
2902
- const mode = useUIVariant();
2903
- const sectionClasses = cn$1(
2904
- "overflow-hidden bg-card",
2905
- mode === "smooth" && "rounded-3xl border",
2906
- mode === "playful" && "rounded-2xl border-primary/25 border",
2907
- !mode && "rounded-2xl border"
2908
- );
2895
+ const sectionClasses = useSectionSurface(surface);
2909
2896
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsxs("div", { className: "relative px-6 py-14 sm:px-10 sm:py-20", children: [
2910
2897
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-[radial-gradient(ellipse_at_bottom,hsl(var(--primary)/0.08),transparent_60%)]" }),
2911
2898
  /* @__PURE__ */ jsxs("div", { className: "relative mx-auto max-w-4xl", children: [
@@ -2942,17 +2929,12 @@ function NewsletterSection({
2942
2929
  privacyLabel = defaults.privacyLabel,
2943
2930
  successTitle = defaults.successTitle,
2944
2931
  successDescription = defaults.successDescription,
2945
- onSubscribe
2932
+ onSubscribe,
2933
+ surface
2946
2934
  } = {}) {
2947
- const [email, setEmail] = React20.useState("");
2948
- const [submitted, setSubmitted] = React20.useState(false);
2949
- const mode = useUIVariant();
2950
- const sectionClasses = cn$1(
2951
- "overflow-hidden bg-card",
2952
- mode === "smooth" && "rounded-3xl border",
2953
- mode === "playful" && "rounded-2xl border-primary/25 border",
2954
- !mode && "rounded-2xl border"
2955
- );
2935
+ const [email, setEmail] = React21.useState("");
2936
+ const [submitted, setSubmitted] = React21.useState(false);
2937
+ const sectionClasses = useSectionSurface(surface);
2956
2938
  async function handleSubmit(e) {
2957
2939
  e.preventDefault();
2958
2940
  if (!email) return;
@@ -3034,16 +3016,11 @@ function ContactSection({
3034
3016
  successTitle = defaults2.successTitle,
3035
3017
  successDescription = defaults2.successDescription,
3036
3018
  sendAnotherLabel = defaults2.sendAnotherLabel,
3037
- onSubmit
3019
+ onSubmit,
3020
+ surface
3038
3021
  } = {}) {
3039
- const [submitted, setSubmitted] = React20.useState(false);
3040
- const mode = useUIVariant();
3041
- const sectionClasses = cn$1(
3042
- "overflow-hidden bg-card",
3043
- mode === "smooth" && "rounded-3xl border",
3044
- mode === "playful" && "rounded-2xl border-primary/25 border",
3045
- !mode && "rounded-2xl border"
3046
- );
3022
+ const [submitted, setSubmitted] = React21.useState(false);
3023
+ const sectionClasses = useSectionSurface(surface);
3047
3024
  async function handleSubmit(e) {
3048
3025
  e.preventDefault();
3049
3026
  await onSubmit?.(e);
@@ -3227,15 +3204,10 @@ function ComparisonSection({
3227
3204
  badge = "The math",
3228
3205
  title = "The math is simple",
3229
3206
  description,
3230
- columns
3207
+ columns,
3208
+ surface
3231
3209
  }) {
3232
- const mode = useUIVariant();
3233
- const sectionClasses = cn$1(
3234
- "overflow-hidden bg-card",
3235
- mode === "smooth" && "rounded-3xl border",
3236
- mode === "playful" && "rounded-2xl border-primary/25 border",
3237
- !mode && "rounded-2xl border"
3238
- );
3210
+ const sectionClasses = useSectionSurface(surface);
3239
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: [
3240
3212
  /* @__PURE__ */ jsx(SectionTitle, { badge, title, description }),
3241
3213
  /* @__PURE__ */ jsx(StaggerChildren, { className: "mt-12 grid gap-4 sm:grid-cols-3", children: columns.map((col) => /* @__PURE__ */ jsxs(
@@ -3283,15 +3255,10 @@ function QualificationSection({
3283
3255
  badge = "Who it is for",
3284
3256
  title = "Is this for you?",
3285
3257
  description,
3286
- columns
3258
+ columns,
3259
+ surface
3287
3260
  }) {
3288
- const mode = useUIVariant();
3289
- const sectionClasses = cn$1(
3290
- "overflow-hidden bg-card",
3291
- mode === "smooth" && "rounded-3xl border",
3292
- mode === "playful" && "rounded-2xl border-primary/25 border",
3293
- !mode && "rounded-2xl border"
3294
- );
3261
+ const sectionClasses = useSectionSurface(surface);
3295
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: [
3296
3263
  /* @__PURE__ */ jsx(SectionTitle, { badge, title, description }),
3297
3264
  /* @__PURE__ */ jsx(FadeIn, { direction: "up", className: "mt-12 grid gap-6 sm:grid-cols-2", children: columns.map((col) => {
@@ -3334,10 +3301,10 @@ function Navbar({
3334
3301
  controls,
3335
3302
  renderLink = defaultRenderLink7
3336
3303
  }) {
3337
- const [open, setOpen] = React20.useState(false);
3304
+ const [open, setOpen] = React21.useState(false);
3338
3305
  const brandHref = brand.href ?? "/";
3339
3306
  const hasRightContent = controls?.length || cta?.primary || cta?.secondary;
3340
- const closeMobileMenu = React20.useCallback(() => setOpen(false), []);
3307
+ const closeMobileMenu = React21.useCallback(() => setOpen(false), []);
3341
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: [
3342
3309
  renderLink({
3343
3310
  href: brandHref,
@@ -3352,7 +3319,7 @@ function Navbar({
3352
3319
  children: link.label
3353
3320
  }) }, link.label)) }),
3354
3321
  hasRightContent && /* @__PURE__ */ jsxs("div", { className: "hidden items-center justify-end gap-2 md:flex", children: [
3355
- controls?.map((control, i) => /* @__PURE__ */ jsx(React20.Fragment, { children: control }, i)),
3322
+ controls?.map((control, i) => /* @__PURE__ */ jsx(React21.Fragment, { children: control }, i)),
3356
3323
  (cta?.secondary || cta?.primary) && controls?.length ? /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-border" }) : null,
3357
3324
  cta?.secondary && renderLink({
3358
3325
  href: cta.secondary.href,
@@ -3365,7 +3332,7 @@ function Navbar({
3365
3332
  ] }),
3366
3333
  /* @__PURE__ */ jsxs(Sheet, { open, onOpenChange: setOpen, children: [
3367
3334
  /* @__PURE__ */ jsxs("div", { className: "col-start-3 flex items-center justify-end gap-1 md:hidden", children: [
3368
- controls?.map((control, i) => /* @__PURE__ */ jsx(React20.Fragment, { children: control }, i)),
3335
+ controls?.map((control, i) => /* @__PURE__ */ jsx(React21.Fragment, { children: control }, i)),
3369
3336
  /* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button$1, { variant: "ghost", size: "icon", children: [
3370
3337
  /* @__PURE__ */ jsx(Menu, { className: "size-5" }),
3371
3338
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Open menu" })
@@ -3527,7 +3494,7 @@ function LogoStrip({
3527
3494
  ] });
3528
3495
  }
3529
3496
  function GridUnderlay({ variant, size = 24, className, ...props }) {
3530
- const id = React20.useId();
3497
+ const id = React21.useId();
3531
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: [
3532
3499
  /* @__PURE__ */ jsx("line", { x1: size / 2, y1: 0, x2: size / 2, y2: size, stroke: "currentColor", strokeWidth: 0.5 }),
3533
3500
  /* @__PURE__ */ jsx("line", { x1: 0, y1: size / 2, x2: size, y2: size / 2, stroke: "currentColor", strokeWidth: 0.5 })
@@ -3555,9 +3522,9 @@ function GlowUnderlay({
3555
3522
  style,
3556
3523
  ...props
3557
3524
  }) {
3558
- const [pos, setPos] = React20.useState({ x: "50%", y: "50%" });
3559
- const containerRef = React20.useRef(null);
3560
- React20.useEffect(() => {
3525
+ const [pos, setPos] = React21.useState({ x: "50%", y: "50%" });
3526
+ const containerRef = React21.useRef(null);
3527
+ React21.useEffect(() => {
3561
3528
  if (!followCursor) return;
3562
3529
  const handleMouseMove = (e) => {
3563
3530
  const el = containerRef.current;
@@ -3696,8 +3663,8 @@ function PageTransition({
3696
3663
  style,
3697
3664
  ...props
3698
3665
  }) {
3699
- const [mounted, setMounted] = React20.useState(false);
3700
- React20.useEffect(() => {
3666
+ const [mounted, setMounted] = React21.useState(false);
3667
+ React21.useEffect(() => {
3701
3668
  const id = requestAnimationFrame(() => setMounted(true));
3702
3669
  return () => cancelAnimationFrame(id);
3703
3670
  }, []);
@@ -3772,7 +3739,7 @@ function Sortable({
3772
3739
  if (oldIndex === -1 || newIndex === -1) return;
3773
3740
  onReorder(arrayMove(items, oldIndex, newIndex));
3774
3741
  };
3775
- const childArray = React20.Children.toArray(children);
3742
+ const childArray = React21.Children.toArray(children);
3776
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(
3777
3744
  (child, i) => items[i] === void 0 ? null : /* @__PURE__ */ jsx(SortableItem, { id: items[i], disabled, className: itemClassName, children: child }, items[i])
3778
3745
  ) }) }) });
@@ -3784,8 +3751,8 @@ function Spotlight({
3784
3751
  triggerClassName,
3785
3752
  shortcut = "\u2318K"
3786
3753
  }) {
3787
- const [open, setOpen] = React20.useState(false);
3788
- React20.useEffect(() => {
3754
+ const [open, setOpen] = React21.useState(false);
3755
+ React21.useEffect(() => {
3789
3756
  const down = (e) => {
3790
3757
  if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
3791
3758
  e.preventDefault();
@@ -3815,7 +3782,7 @@ function Spotlight({
3815
3782
  /* @__PURE__ */ jsx(CommandInput, { placeholder }),
3816
3783
  /* @__PURE__ */ jsxs(CommandList, { children: [
3817
3784
  /* @__PURE__ */ jsx(CommandEmpty, { children: "No results found." }),
3818
- groups.map((group, i) => /* @__PURE__ */ jsxs(React20.Fragment, { children: [
3785
+ groups.map((group, i) => /* @__PURE__ */ jsxs(React21.Fragment, { children: [
3819
3786
  i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
3820
3787
  /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
3821
3788
  CommandItem,
@@ -3840,8 +3807,8 @@ function Spotlight({
3840
3807
  var BASE = 40;
3841
3808
  var MAGNIFY_RADIUS = 80;
3842
3809
  function Dock({ items, iconSize = BASE, magnification = 1.7, className, ...props }) {
3843
- const [mouseX, setMouseX] = React20.useState(null);
3844
- const containerRef = React20.useRef(null);
3810
+ const [mouseX, setMouseX] = React21.useState(null);
3811
+ const containerRef = React21.useRef(null);
3845
3812
  function getScale(index) {
3846
3813
  if (mouseX === null || !containerRef.current) return 1;
3847
3814
  const container = containerRef.current;
@@ -3940,7 +3907,7 @@ function ConfirmDialog({ isOpen, options, handleConfirm, handleCancel, destructi
3940
3907
  ] }) });
3941
3908
  }
3942
3909
  function RegisterHotkeys({ hotkeys }) {
3943
- React20.useEffect(() => {
3910
+ React21.useEffect(() => {
3944
3911
  const handleKeyDown = (event) => {
3945
3912
  for (const hotkey of hotkeys) {
3946
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;
@@ -3957,10 +3924,10 @@ function RegisterHotkeys({ hotkeys }) {
3957
3924
  return null;
3958
3925
  }
3959
3926
  function useControlledOpen(defaultOpen = false) {
3960
- const [isOpen, setIsOpen] = React20.useState(defaultOpen);
3961
- const open = React20.useCallback(() => setIsOpen(true), []);
3962
- const close = React20.useCallback(() => setIsOpen(false), []);
3963
- 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), []);
3964
3931
  return { isOpen, open, close, toggle, setIsOpen };
3965
3932
  }
3966
3933
  function CommandMenu({
@@ -3973,7 +3940,7 @@ function CommandMenu({
3973
3940
  }) {
3974
3941
  const internal = useControlledOpen(false);
3975
3942
  const isOpen = openProp ?? internal.isOpen;
3976
- const setOpen = React20.useCallback(
3943
+ const setOpen = React21.useCallback(
3977
3944
  (next) => {
3978
3945
  if (openProp === void 0) internal.setIsOpen(next);
3979
3946
  onOpenChange?.(next);
@@ -3998,7 +3965,7 @@ function CommandMenu({
3998
3965
  /* @__PURE__ */ jsx(CommandInput, { placeholder }),
3999
3966
  /* @__PURE__ */ jsxs(CommandList, { children: [
4000
3967
  /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
4001
- groups.map((group, i) => /* @__PURE__ */ jsxs(React20.Fragment, { children: [
3968
+ groups.map((group, i) => /* @__PURE__ */ jsxs(React21.Fragment, { children: [
4002
3969
  i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
4003
3970
  /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
4004
3971
  CommandItem,
@@ -4053,7 +4020,7 @@ function DataView({
4053
4020
  }
4054
4021
  );
4055
4022
  }
4056
- 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))) });
4057
4024
  }
4058
4025
  var TOKEN_COLORS = ["var(--chart-1)", "var(--chart-2)", "var(--chart-3)", "var(--chart-4)", "var(--chart-5)"];
4059
4026
  var seriesColor = (s, i) => s.color ?? TOKEN_COLORS[i % TOKEN_COLORS.length];
@@ -4227,20 +4194,20 @@ function FileUpload({
4227
4194
  hint,
4228
4195
  className
4229
4196
  }) {
4230
- const [internalFiles, setInternalFiles] = React20.useState(defaultFiles ?? []);
4231
- const [isDragging, setIsDragging] = React20.useState(false);
4232
- const [validationError, setValidationError] = React20.useState(null);
4233
- const inputRef = React20.useRef(null);
4234
- 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);
4235
4202
  const files = filesProp ?? internalFiles;
4236
- const setFiles = React20.useCallback(
4203
+ const setFiles = React21.useCallback(
4237
4204
  (next) => {
4238
4205
  if (!filesProp) setInternalFiles(next);
4239
4206
  onFilesChange?.(next);
4240
4207
  },
4241
4208
  [filesProp, onFilesChange]
4242
4209
  );
4243
- const acceptList = React20.useMemo(
4210
+ const acceptList = React21.useMemo(
4244
4211
  () => accept?.split(",").map((a) => a.trim().toLowerCase()).filter(Boolean) ?? [],
4245
4212
  [accept]
4246
4213
  );
@@ -4964,7 +4931,7 @@ function PageHeader({
4964
4931
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1 pb-6", className), children: [
4965
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) => {
4966
4933
  const isLast = i === breadcrumbs.length - 1;
4967
- return /* @__PURE__ */ jsxs(React20.Fragment, { children: [
4934
+ return /* @__PURE__ */ jsxs(React21.Fragment, { children: [
4968
4935
  i > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "size-3.5 shrink-0" }),
4969
4936
  isLast || !crumb.href ? /* @__PURE__ */ jsx("span", { className: cn(isLast && "text-foreground font-medium"), children: crumb.label }) : renderLink({
4970
4937
  href: crumb.href,
@@ -5000,7 +4967,7 @@ function PageHeader({
5000
4967
  ] });
5001
4968
  }
5002
4969
  function Suspensed({ children, fallback }) {
5003
- return /* @__PURE__ */ jsx(React20.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
4970
+ return /* @__PURE__ */ jsx(React21.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
5004
4971
  }
5005
4972
  function getInitialTheme() {
5006
4973
  if (typeof document === "undefined") return "dark";
@@ -5008,7 +4975,7 @@ function getInitialTheme() {
5008
4975
  return stored ?? (document.documentElement.classList.contains("dark") ? "dark" : "light");
5009
4976
  }
5010
4977
  function ThemeSwitchMinimal() {
5011
- const [theme, setThemeState] = React20.useState(getInitialTheme);
4978
+ const [theme, setThemeState] = React21.useState(getInitialTheme);
5012
4979
  const toggle = () => {
5013
4980
  const next = theme === "dark" ? "light" : "dark";
5014
4981
  setThemeState(next);
@@ -5134,9 +5101,9 @@ function getInitialColorName() {
5134
5101
  return localStorage.getItem(STORAGE_KEY) ?? "emerald";
5135
5102
  }
5136
5103
  function BrandColorSwitchMinimal() {
5137
- const [active, setActive] = React20.useState(getInitialColorName);
5138
- const [open, setOpen] = React20.useState(false);
5139
- React20.useEffect(() => {
5104
+ const [active, setActive] = React21.useState(getInitialColorName);
5105
+ const [open, setOpen] = React21.useState(false);
5106
+ React21.useEffect(() => {
5140
5107
  const saved = localStorage.getItem(STORAGE_KEY) ?? "emerald";
5141
5108
  const color = BRAND_COLORS.find((c) => c.name === saved);
5142
5109
  if (color) applyColor(color);
@@ -5197,7 +5164,7 @@ function BrandColorSwitchMinimal() {
5197
5164
  ] });
5198
5165
  }
5199
5166
  function ThemeColorUpdater({ colorTheme }) {
5200
- React20.useEffect(() => {
5167
+ React21.useEffect(() => {
5201
5168
  if (colorTheme) {
5202
5169
  document.documentElement.setAttribute("data-theme", colorTheme);
5203
5170
  } else {
@@ -5207,7 +5174,7 @@ function ThemeColorUpdater({ colorTheme }) {
5207
5174
  return null;
5208
5175
  }
5209
5176
  function VersionBanner({ version, message, className, onDismiss }) {
5210
- const [dismissed, setDismissed] = React20.useState(false);
5177
+ const [dismissed, setDismissed] = React21.useState(false);
5211
5178
  if (dismissed) return null;
5212
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: [
5213
5180
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
@@ -5464,29 +5431,29 @@ function useMounted() {
5464
5431
  return mounted;
5465
5432
  }
5466
5433
  function useConfirm() {
5467
- const [isOpen, setIsOpen] = React20.useState(false);
5468
- const [options, setOptions] = React20.useState({});
5469
- const resolveRef = React20.useRef(null);
5470
- 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 = {}) => {
5471
5438
  setOptions(opts);
5472
5439
  setIsOpen(true);
5473
5440
  return new Promise((resolve) => {
5474
5441
  resolveRef.current = resolve;
5475
5442
  });
5476
5443
  }, []);
5477
- const handleConfirm = React20.useCallback(() => {
5444
+ const handleConfirm = React21.useCallback(() => {
5478
5445
  resolveRef.current?.(true);
5479
5446
  setIsOpen(false);
5480
5447
  }, []);
5481
- const handleCancel = React20.useCallback(() => {
5448
+ const handleCancel = React21.useCallback(() => {
5482
5449
  resolveRef.current?.(false);
5483
5450
  setIsOpen(false);
5484
5451
  }, []);
5485
5452
  return { confirm, isOpen, options, handleConfirm, handleCancel };
5486
5453
  }
5487
5454
  function useScrolledPast(threshold) {
5488
- const [scrolledPast, setScrolledPast] = React20.useState(false);
5489
- React20.useEffect(() => {
5455
+ const [scrolledPast, setScrolledPast] = React21.useState(false);
5456
+ React21.useEffect(() => {
5490
5457
  const handleScroll = () => {
5491
5458
  setScrolledPast(window.scrollY > threshold);
5492
5459
  };
@@ -5497,28 +5464,28 @@ function useScrolledPast(threshold) {
5497
5464
  return scrolledPast;
5498
5465
  }
5499
5466
  function useCopyToClipboard() {
5500
- const [copied, setCopied] = React20.useState(false);
5501
- const timeoutRef = React20.useRef(void 0);
5502
- 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) => {
5503
5470
  navigator.clipboard.writeText(text).then(() => {
5504
5471
  setCopied(true);
5505
5472
  clearTimeout(timeoutRef.current);
5506
5473
  timeoutRef.current = setTimeout(() => setCopied(false), 2e3);
5507
5474
  });
5508
5475
  }, []);
5509
- React20.useEffect(() => () => clearTimeout(timeoutRef.current), []);
5476
+ React21.useEffect(() => () => clearTimeout(timeoutRef.current), []);
5510
5477
  return [copied, copy];
5511
5478
  }
5512
5479
  function useDebounce(value, delay) {
5513
- const [debounced, setDebounced] = React20.useState(value);
5514
- React20.useEffect(() => {
5480
+ const [debounced, setDebounced] = React21.useState(value);
5481
+ React21.useEffect(() => {
5515
5482
  const timer = setTimeout(() => setDebounced(value), delay);
5516
5483
  return () => clearTimeout(timer);
5517
5484
  }, [value, delay]);
5518
5485
  return debounced;
5519
5486
  }
5520
5487
  function useLocalStorage(key, initialValue) {
5521
- const [storedValue, setStoredValue] = React20.useState(() => {
5488
+ const [storedValue, setStoredValue] = React21.useState(() => {
5522
5489
  if (typeof window === "undefined") return initialValue;
5523
5490
  try {
5524
5491
  const item = window.localStorage.getItem(key);
@@ -5527,7 +5494,7 @@ function useLocalStorage(key, initialValue) {
5527
5494
  return initialValue;
5528
5495
  }
5529
5496
  });
5530
- const setValue = React20.useCallback(
5497
+ const setValue = React21.useCallback(
5531
5498
  (value) => {
5532
5499
  try {
5533
5500
  setStoredValue(value);
@@ -5549,11 +5516,11 @@ function useViewMode(key = "view-mode", fallback = "cards") {
5549
5516
  return { view: mounted ? stored : fallback, setView: setStored, ready: mounted };
5550
5517
  }
5551
5518
  function useMediaQuery(query) {
5552
- const [matches, setMatches] = React20.useState(() => {
5519
+ const [matches, setMatches] = React21.useState(() => {
5553
5520
  if (typeof window === "undefined") return false;
5554
5521
  return window.matchMedia(query).matches;
5555
5522
  });
5556
- React20.useEffect(() => {
5523
+ React21.useEffect(() => {
5557
5524
  if (typeof window === "undefined") return;
5558
5525
  const mql = window.matchMedia(query);
5559
5526
  setMatches(mql.matches);
@@ -5564,18 +5531,18 @@ function useMediaQuery(query) {
5564
5531
  return matches;
5565
5532
  }
5566
5533
  function usePagination(total, pageSize) {
5567
- const [page, setPage] = React20.useState(1);
5534
+ const [page, setPage] = React21.useState(1);
5568
5535
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
5569
5536
  const offset = (page - 1) * pageSize;
5570
- const goTo = React20.useCallback(
5537
+ const goTo = React21.useCallback(
5571
5538
  (p) => setPage(Math.min(Math.max(1, p), totalPages)),
5572
5539
  [totalPages]
5573
5540
  );
5574
- const next = React20.useCallback(() => goTo(page + 1), [page, goTo]);
5575
- 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]);
5576
5543
  return { page, pageSize, totalPages, offset, hasPrev: page > 1, hasNext: page < totalPages, goTo, next, prev };
5577
5544
  }
5578
5545
 
5579
- 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 };
5580
5547
  //# sourceMappingURL=index.js.map
5581
5548
  //# sourceMappingURL=index.js.map