@olwiba/ui 0.1.12 → 0.1.14

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.d.ts CHANGED
@@ -3,7 +3,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import * as React from 'react';
4
4
  import React__default, { ReactNode } from 'react';
5
5
  import { ButtonProps as ButtonProps$1, CardProps as CardProps$1, BadgeProps as BadgeProps$1, InputProps as InputProps$1, TextareaProps as TextareaProps$1, CheckboxProps as CheckboxProps$1, SwitchProps as SwitchProps$1 } from '@olwiba/cn';
6
- export { CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@olwiba/cn';
6
+ export { CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Enchanted, EnchantedProps } from '@olwiba/cn';
7
7
  import { LucideIcon } from 'lucide-react';
8
8
  export { MdxContent, MdxContentProps } from './mdx/index.js';
9
9
 
@@ -210,6 +210,7 @@ interface AppShellUser {
210
210
  plan?: string;
211
211
  onSignOut?: () => void;
212
212
  onBilling?: () => void;
213
+ onNotifications?: () => void;
213
214
  }
214
215
  interface AppShellBrand {
215
216
  name: ReactNode;
@@ -302,6 +303,12 @@ interface EmptyStateProps extends React.HTMLAttributes<HTMLDivElement> {
302
303
  }
303
304
  declare function EmptyState({ icon: Icon, title, description, action, className, ...props }: EmptyStateProps): react_jsx_runtime.JSX.Element;
304
305
 
306
+ interface ErrorPageLink {
307
+ label: string;
308
+ href: string;
309
+ description?: string;
310
+ icon?: ReactNode;
311
+ }
305
312
  interface ErrorPageProps {
306
313
  statusCode?: string;
307
314
  title?: string;
@@ -315,9 +322,11 @@ interface ErrorPageProps {
315
322
  href?: string;
316
323
  onClick?: () => void;
317
324
  };
325
+ /** Optional "maybe you were looking for" links rendered below the actions. */
326
+ links?: ErrorPageLink[];
318
327
  renderLink?: AppShellRenderLink;
319
328
  }
320
- declare function ErrorPage({ statusCode, title, description, action, backAction, renderLink, }: ErrorPageProps): react_jsx_runtime.JSX.Element;
329
+ declare function ErrorPage({ statusCode, title, description, action, backAction, links, renderLink, }: ErrorPageProps): react_jsx_runtime.JSX.Element;
321
330
 
322
331
  interface UpgradeComparisonRow {
323
332
  key?: React.Key;
@@ -366,6 +375,12 @@ interface SectionTitleProps {
366
375
  }
367
376
  declare function SectionTitle({ title, description, badge, className }: SectionTitleProps): react_jsx_runtime.JSX.Element;
368
377
 
378
+ declare const marketingSectionSpacing: {
379
+ readonly standard: "px-6 py-14 sm:px-10 sm:py-20";
380
+ readonly hero: "px-6 pb-14 pt-10 sm:px-10 sm:py-20";
381
+ };
382
+ type MarketingSectionSpacing = keyof typeof marketingSectionSpacing;
383
+
369
384
  interface HeroSectionProps {
370
385
  heading: string;
371
386
  badge?: string;
@@ -1196,6 +1211,11 @@ interface RootErrorFallbackProps {
1196
1211
  }
1197
1212
  declare function RootErrorFallback({ error, reset }: RootErrorFallbackProps): react_jsx_runtime.JSX.Element;
1198
1213
 
1214
+ interface PostAuthor {
1215
+ name: string;
1216
+ role?: string;
1217
+ avatar?: string;
1218
+ }
1199
1219
  interface PostCardProps {
1200
1220
  title: string;
1201
1221
  description?: string;
@@ -1203,16 +1223,22 @@ interface PostCardProps {
1203
1223
  slug: string;
1204
1224
  image?: string;
1205
1225
  tags?: string[];
1226
+ author?: PostAuthor;
1227
+ hrefPrefix?: string;
1228
+ tagHrefPrefix?: string;
1206
1229
  renderLink?: AppShellRenderLink;
1207
1230
  }
1208
- declare function PostCard({ title, description, date, slug, image, tags, renderLink }: PostCardProps): react_jsx_runtime.JSX.Element;
1231
+ declare function PostCard({ title, description, date, slug, image, tags, author, hrefPrefix, tagHrefPrefix, renderLink, }: PostCardProps): react_jsx_runtime.JSX.Element;
1209
1232
 
1210
1233
  interface PostListProps {
1211
1234
  posts: PostCardProps[];
1212
1235
  renderLink?: AppShellRenderLink;
1213
1236
  emptyMessage?: string;
1237
+ /** Max columns at the widest breakpoint. */
1238
+ columns?: 2 | 3;
1239
+ className?: string;
1214
1240
  }
1215
- declare function PostList({ posts, renderLink, emptyMessage }: PostListProps): react_jsx_runtime.JSX.Element;
1241
+ declare function PostList({ posts, renderLink, emptyMessage, columns, className, }: PostListProps): react_jsx_runtime.JSX.Element;
1216
1242
 
1217
1243
  type ChangelogReleaseType = 'release' | 'fix' | 'enhancement';
1218
1244
  interface ChangelogHighlight {
@@ -1296,4 +1322,4 @@ interface UsePaginationReturn {
1296
1322
  }
1297
1323
  declare function usePagination(total: number, pageSize: number): UsePaginationReturn;
1298
1324
 
1299
- export { AnimatedPill, type AnimatedPillProps, AppContent, type AppContentProps, AppGrid, AppGridCell, type AppGridCellProps, type AppGridProps, type AppNavItem, AppScreen, AppShell, type AppShellAction, type AppShellBrand, type AppShellProps, type AppShellRenderLink, type AppShellUser, type AuthFormProps, AuthSection, type AuthSectionProps, Badge, type BadgeProps, BrandColorSwitchMinimal, Button, type ButtonProps, Card, type CardProps, CarouselSection, type CarouselSectionProps, ChangelogCard, type ChangelogCardProps, type ChangelogHighlight, ChangelogList, type ChangelogListProps, type ChangelogReleaseType, Checkbox, type CheckboxProps, type ComparisonColumn, ComparisonSection, type ComparisonSectionProps, ConfirmDialog, type ConfirmDialogProps, type ConfirmOptions, type ContactInfoItem, ContactSection, type ContactSectionProps, ContextMenu, type ContextMenuDef, type ContextMenuProps, CountUp, type CountUpProps, CountdownTimer, type CountdownTimerProps, CtaCardSection, type CtaCardSectionProps, CtaSection, type CtaSectionProps, DevBanner, type DevBannerProps, Dock, type DockItem, type DockProps, EmptyState, type EmptyStateProps, ErrorPage, type ErrorPageProps, FadeIn, type FadeInProps, FaqSection, type FaqSectionProps, FeatureCard, type FeatureCardProps, type FeatureMarqueeItem, type FeatureMarqueeRow, FeatureMarqueeSection, type FeatureMarqueeSectionProps, FeaturesSection, type FeaturesSectionProps, FlowBracket, type FlowBracketProps, FlowConnector, type FlowConnectorProps, Footer, type FooterProps, FullPageSpinner, GlassCard, type GlassCardProps, Grid, GridItem, type GridItemProps, type GridProps, type GroupedFeatureGroup, GroupedFeaturesSection, type GroupedFeaturesSectionProps, HeroSection, type HeroSectionProps, type Hotkey, ImageCard, type ImageCardProps, Input, type InputProps, LogoStrip, type LogoStripProps, ModeSwitchMinimal, Navbar, type NavbarProps, NewsletterSection, type NewsletterSectionProps, OlwibaUIProvider, type OlwibaUIProviderProps, Overlay, type OverlayProps, type OverlayVariant, PageHeader, type PageHeaderBackButton, type PageHeaderBreadcrumb, type PageHeaderProps, PageTransition, type PageTransitionProps, PhoneFrame, type PhoneFrameProps, PostCard, type PostCardProps, PostList, type PostListProps, PricingCard, type PricingCardProps, type PricingFeature, type PricingPlan, PricingSection, type PricingSectionProps, PublicPageFrame, type PublicPageFrameProps, type QualificationColumn, QualificationSection, type QualificationSectionProps, RegisterHotkeys, RootErrorFallback, Section, type SectionProps, SectionTitle, type SectionTitleProps, Spotlight, type SpotlightGroup, type SpotlightItem, type SpotlightProps, Stack, type StackProps, StaggerChildren, type StaggerChildrenProps, StatCard, type StatCardProps, StatsSection, type StatsSectionProps, type StepItem, StepsSection, type StepsSectionProps, Suspensed, Switch, type SwitchProps, type TeamMember, TeamSection, type TeamSectionProps, type TechStackItem, TechStackSection, type TechStackSectionProps, TestimonialCard, type TestimonialCardProps, TestimonialsSection, type TestimonialsSectionProps, Textarea, type TextareaProps, ThemeColorUpdater, ThemeSwitchMinimal, type UIMode, Underlay, type UnderlayProps, type UnderlayVariant, type UpgradeComparisonRow, UpgradePrompt, type UpgradePromptProps, type UseConfirmReturn, type UseControlledOpenReturn, type UsePaginationReturn, VersionBanner, cn, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode };
1325
+ export { AnimatedPill, type AnimatedPillProps, AppContent, type AppContentProps, AppGrid, AppGridCell, type AppGridCellProps, type AppGridProps, type AppNavItem, AppScreen, AppShell, type AppShellAction, type AppShellBrand, type AppShellProps, type AppShellRenderLink, type AppShellUser, type AuthFormProps, AuthSection, type AuthSectionProps, Badge, type BadgeProps, BrandColorSwitchMinimal, Button, type ButtonProps, Card, type CardProps, CarouselSection, type CarouselSectionProps, ChangelogCard, type ChangelogCardProps, type ChangelogHighlight, ChangelogList, type ChangelogListProps, type ChangelogReleaseType, Checkbox, type CheckboxProps, type ComparisonColumn, ComparisonSection, type ComparisonSectionProps, ConfirmDialog, type ConfirmDialogProps, type ConfirmOptions, type ContactInfoItem, ContactSection, type ContactSectionProps, ContextMenu, type ContextMenuDef, type ContextMenuProps, CountUp, type CountUpProps, CountdownTimer, type CountdownTimerProps, CtaCardSection, type CtaCardSectionProps, CtaSection, type CtaSectionProps, DevBanner, type DevBannerProps, Dock, type DockItem, type DockProps, EmptyState, type EmptyStateProps, ErrorPage, type ErrorPageProps, FadeIn, type FadeInProps, FaqSection, type FaqSectionProps, FeatureCard, type FeatureCardProps, type FeatureMarqueeItem, type FeatureMarqueeRow, FeatureMarqueeSection, type FeatureMarqueeSectionProps, FeaturesSection, type FeaturesSectionProps, FlowBracket, type FlowBracketProps, FlowConnector, type FlowConnectorProps, Footer, type FooterProps, FullPageSpinner, GlassCard, type GlassCardProps, Grid, GridItem, type GridItemProps, type GridProps, type GroupedFeatureGroup, GroupedFeaturesSection, type GroupedFeaturesSectionProps, HeroSection, type HeroSectionProps, type Hotkey, ImageCard, type ImageCardProps, Input, type InputProps, LogoStrip, type LogoStripProps, type MarketingSectionSpacing, ModeSwitchMinimal, Navbar, type NavbarProps, NewsletterSection, type NewsletterSectionProps, OlwibaUIProvider, type OlwibaUIProviderProps, Overlay, type OverlayProps, type OverlayVariant, PageHeader, type PageHeaderBackButton, type PageHeaderBreadcrumb, type PageHeaderProps, PageTransition, type PageTransitionProps, PhoneFrame, type PhoneFrameProps, type PostAuthor, PostCard, type PostCardProps, PostList, type PostListProps, PricingCard, type PricingCardProps, type PricingFeature, type PricingPlan, PricingSection, type PricingSectionProps, PublicPageFrame, type PublicPageFrameProps, type QualificationColumn, QualificationSection, type QualificationSectionProps, RegisterHotkeys, RootErrorFallback, Section, type SectionProps, SectionTitle, type SectionTitleProps, Spotlight, type SpotlightGroup, type SpotlightItem, type SpotlightProps, Stack, type StackProps, StaggerChildren, type StaggerChildrenProps, StatCard, type StatCardProps, StatsSection, type StatsSectionProps, type StepItem, StepsSection, type StepsSectionProps, Suspensed, Switch, type SwitchProps, type TeamMember, TeamSection, type TeamSectionProps, type TechStackItem, TechStackSection, type TechStackSectionProps, TestimonialCard, type TestimonialCardProps, TestimonialsSection, type TestimonialsSectionProps, Textarea, type TextareaProps, ThemeColorUpdater, ThemeSwitchMinimal, type UIMode, Underlay, type UnderlayProps, type UnderlayVariant, type UpgradeComparisonRow, UpgradePrompt, type UpgradePromptProps, type UseConfirmReturn, type UseControlledOpenReturn, type UsePaginationReturn, VersionBanner, cn, marketingSectionSpacing, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode };
package/dist/index.js CHANGED
@@ -3,9 +3,9 @@ export { MdxContent, cn } from './chunk-AMWLSHD6.js';
3
3
  import * as React29 from 'react';
4
4
  import { useRef, useEffect, useState } 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, 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, Spinner, Popover, PopoverTrigger, PopoverContent, SidebarProvider, SidebarInset, CardHeader, CardTitle, CardDescription, CardContent, ContextMenuSeparator, ContextMenuLabel, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent, ContextMenuItem, ContextMenuShortcut, Sidebar, SidebarHeader, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarFooter, SidebarTrigger, useSidebar, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup, DropdownMenuItem } from '@olwiba/cn';
6
- export { CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@olwiba/cn';
6
+ export { CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Enchanted } from '@olwiba/cn';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
- import { Compass, ArrowLeft, X, ArrowRight, ChevronLeft, ChevronRight, Sparkles, Rocket, Check, Minus, Quote, Star, Twitter, Github, Linkedin, Mail, MessageSquare, ChevronDown, Send, Menu, Search, TrendingUp, TrendingDown, Sun, Moon, Palette, AlertTriangle, Loader2, Layers, LayoutGrid, ShieldCheck, Building2, MoreVerticalIcon, CreditCardIcon, BellIcon, LogOutIcon } from 'lucide-react';
8
+ import { ArrowLeft, ArrowUpRight, X, ArrowRight, ChevronLeft, ChevronRight, Sparkles, Rocket, Check, Minus, Quote, Star, Twitter, Github, Linkedin, Mail, MessageSquare, ChevronDown, Send, Menu, Search, TrendingUp, TrendingDown, Sun, Moon, Palette, AlertTriangle, Loader2, Layers, LayoutGrid, ShieldCheck, Building2, MoreVerticalIcon, CreditCardIcon, BellIcon, LogOutIcon } from 'lucide-react';
9
9
 
10
10
  var OlwibaUIContext = React29.createContext({
11
11
  isMobile: false,
@@ -294,15 +294,17 @@ function NavUser({ user }) {
294
294
  /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-muted-foreground", children: user.email })
295
295
  ] })
296
296
  ] }) }),
297
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
298
- /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
299
- user.onBilling && /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: user.onBilling, children: [
300
- /* @__PURE__ */ jsx(CreditCardIcon, {}),
301
- "Billing"
302
- ] }),
303
- /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
304
- /* @__PURE__ */ jsx(BellIcon, {}),
305
- "Notifications"
297
+ (user.onBilling || user.onNotifications) && /* @__PURE__ */ jsxs(Fragment, { children: [
298
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
299
+ /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
300
+ user.onBilling && /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: user.onBilling, children: [
301
+ /* @__PURE__ */ jsx(CreditCardIcon, {}),
302
+ "Billing"
303
+ ] }),
304
+ user.onNotifications && /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: user.onNotifications, children: [
305
+ /* @__PURE__ */ jsx(BellIcon, {}),
306
+ "Notifications"
307
+ ] })
306
308
  ] })
307
309
  ] }),
308
310
  user.onSignOut && /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -606,35 +608,90 @@ function ErrorPage({
606
608
  description = "The page you're looking for doesn't exist or has been moved. Check the URL or head back home.",
607
609
  action = { label: "Take me home", href: "/" },
608
610
  backAction = { label: "Go back" },
611
+ links,
609
612
  renderLink = defaultRenderLink3
610
613
  }) {
611
- return /* @__PURE__ */ jsx("section", { className: "overflow-hidden rounded-2xl border bg-card", children: /* @__PURE__ */ jsxs("div", { className: "relative flex min-h-[560px] flex-col items-center justify-center px-6 py-16 text-center", children: [
612
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_center,hsl(var(--muted)/0.8),transparent_70%)]" }),
613
- /* @__PURE__ */ jsxs("div", { className: "relative space-y-6", children: [
614
- /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl border bg-muted", children: /* @__PURE__ */ jsx(Compass, { className: "size-8 text-muted-foreground" }) }) }),
615
- /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
616
- /* @__PURE__ */ jsx("div", { className: "text-8xl font-bold tracking-tight text-muted-foreground/20", children: statusCode }),
617
- /* @__PURE__ */ jsx("h1", { className: "-mt-4 text-2xl font-semibold tracking-tight", children: title }),
618
- /* @__PURE__ */ jsx("p", { className: "mx-auto max-w-sm text-sm text-muted-foreground", children: description })
619
- ] }),
620
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-center gap-3", children: [
621
- backAction && (backAction.href ? renderLink({
622
- href: backAction.href,
623
- children: /* @__PURE__ */ jsxs(Button, { variant: "outline", children: [
624
- /* @__PURE__ */ jsx(ArrowLeft, { className: "mr-2 size-4" }),
625
- backAction.label
614
+ const hasLinks = links && links.length > 0;
615
+ return /* @__PURE__ */ jsxs("section", { className: "relative overflow-hidden rounded-2xl border bg-card", children: [
616
+ /* @__PURE__ */ jsx(
617
+ "div",
618
+ {
619
+ "aria-hidden": true,
620
+ className: "absolute inset-0 bg-[radial-gradient(hsl(var(--border))_1px,transparent_1px)] [background-size:24px_24px] [mask-image:radial-gradient(ellipse_at_center,black_30%,transparent_75%)]"
621
+ }
622
+ ),
623
+ /* @__PURE__ */ jsx(
624
+ "div",
625
+ {
626
+ "aria-hidden": true,
627
+ className: "absolute left-1/2 top-24 h-64 w-[36rem] max-w-full -translate-x-1/2 rounded-full bg-primary/10 blur-3xl"
628
+ }
629
+ ),
630
+ /* @__PURE__ */ jsxs(
631
+ "div",
632
+ {
633
+ className: cn$1(
634
+ "relative mx-auto flex max-w-3xl flex-col items-center px-6 pt-20 text-center sm:pt-24",
635
+ hasLinks ? "pb-16" : "pb-24 sm:pb-28"
636
+ ),
637
+ children: [
638
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2 rounded-full border bg-background/80 px-3 py-1 font-mono text-xs text-muted-foreground backdrop-blur", children: [
639
+ /* @__PURE__ */ jsxs("span", { className: "relative flex size-1.5", children: [
640
+ /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-primary opacity-60" }),
641
+ /* @__PURE__ */ jsx("span", { className: "relative inline-flex size-1.5 rounded-full bg-primary" })
642
+ ] }),
643
+ "HTTP ",
644
+ statusCode
645
+ ] }),
646
+ /* @__PURE__ */ jsx(
647
+ "div",
648
+ {
649
+ "aria-hidden": true,
650
+ className: "pointer-events-none -mb-8 mt-2 select-none bg-gradient-to-b from-foreground/15 via-foreground/[0.06] to-transparent bg-clip-text text-[9rem] font-black leading-none tracking-tighter text-transparent sm:-mb-12 sm:text-[13rem]",
651
+ children: statusCode
652
+ }
653
+ ),
654
+ /* @__PURE__ */ jsx("h1", { className: "text-balance text-2xl font-semibold tracking-tight sm:text-3xl", children: title }),
655
+ /* @__PURE__ */ jsx("p", { className: "mx-auto mt-3 max-w-md text-pretty text-sm leading-6 text-muted-foreground", children: description }),
656
+ /* @__PURE__ */ jsxs("div", { className: "mt-8 flex flex-wrap items-center justify-center gap-3", children: [
657
+ backAction && (backAction.href ? renderLink({
658
+ href: backAction.href,
659
+ children: /* @__PURE__ */ jsxs(Button, { variant: "outline", children: [
660
+ /* @__PURE__ */ jsx(ArrowLeft, { className: "mr-2 size-4" }),
661
+ backAction.label
662
+ ] })
663
+ }) : /* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: backAction.onClick, children: [
664
+ /* @__PURE__ */ jsx(ArrowLeft, { className: "mr-2 size-4" }),
665
+ backAction.label
666
+ ] })),
667
+ action && renderLink({
668
+ href: action.href,
669
+ children: /* @__PURE__ */ jsx(Button, { children: action.label })
670
+ })
671
+ ] }),
672
+ hasLinks && /* @__PURE__ */ jsxs("div", { className: "mt-14 w-full", children: [
673
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-wider text-muted-foreground", children: "Maybe you were looking for" }),
674
+ /* @__PURE__ */ jsx("div", { className: "mt-4 grid gap-3 text-left sm:grid-cols-2 lg:grid-cols-3", children: links.map(
675
+ (link) => renderLink({
676
+ href: link.href,
677
+ className: "group flex items-start gap-3 rounded-xl border bg-background/60 p-4 backdrop-blur transition-colors hover:border-primary/40 hover:bg-accent",
678
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [
679
+ link.icon && /* @__PURE__ */ jsx("span", { className: "mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-lg border bg-muted text-muted-foreground", children: link.icon }),
680
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 grow", children: [
681
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-sm font-medium", children: [
682
+ link.label,
683
+ /* @__PURE__ */ jsx(ArrowUpRight, { className: "size-3.5 text-muted-foreground transition-transform group-hover:-translate-y-0.5 group-hover:translate-x-0.5 group-hover:text-foreground" })
684
+ ] }),
685
+ link.description && /* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-xs leading-5 text-muted-foreground", children: link.description })
686
+ ] })
687
+ ] })
688
+ })
689
+ ) })
626
690
  ] })
627
- }) : /* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: backAction.onClick, children: [
628
- /* @__PURE__ */ jsx(ArrowLeft, { className: "mr-2 size-4" }),
629
- backAction.label
630
- ] })),
631
- action && renderLink({
632
- href: action.href,
633
- children: /* @__PURE__ */ jsx(Button, { children: action.label })
634
- })
635
- ] })
636
- ] })
637
- ] }) });
691
+ ]
692
+ }
693
+ )
694
+ ] });
638
695
  }
639
696
  function UpgradePrompt({
640
697
  variant,
@@ -817,6 +874,12 @@ function SectionTitle({ title, description, badge, className }) {
817
874
  description && /* @__PURE__ */ jsx("p", { className: "mx-auto mt-4 max-w-2xl text-pretty text-muted-foreground", children: description })
818
875
  ] }) });
819
876
  }
877
+
878
+ // src/marketing/section-spacing.ts
879
+ var marketingSectionSpacing = {
880
+ standard: "px-6 py-14 sm:px-10 sm:py-20",
881
+ hero: "px-6 pb-14 pt-10 sm:px-10 sm:py-20"
882
+ };
820
883
  var sizes = {
821
884
  sm: { outer: "w-44", height: "h-80", notch: "w-16 h-4", border: "rounded-[2rem]", screen: "rounded-[1.75rem]" },
822
885
  md: { outer: "w-56", height: "h-[26rem]", notch: "w-20 h-5", border: "rounded-[2.5rem]", screen: "rounded-[2.25rem]" },
@@ -879,7 +942,7 @@ function HeroSection({
879
942
  socialProofText,
880
943
  renderLink = defaultRenderLink4
881
944
  }) {
882
- return /* @__PURE__ */ jsx("section", { className: "overflow-hidden", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: [
945
+ return /* @__PURE__ */ jsx("section", { className: "overflow-hidden", children: /* @__PURE__ */ jsxs("div", { className: marketingSectionSpacing.hero, children: [
883
946
  /* @__PURE__ */ jsxs("div", { className: "mx-auto grid max-w-6xl items-center gap-10 lg:grid-cols-2 lg:gap-16", children: [
884
947
  /* @__PURE__ */ jsx(FadeIn, { direction: "left", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
885
948
  badge && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Badge$1, { variant: "secondary", children: badge }) }),
@@ -3573,35 +3636,111 @@ function RootErrorFallback({ error, reset }) {
3573
3636
  function formatDate(dateStr) {
3574
3637
  return new Date(dateStr).toLocaleDateString("en-US", {
3575
3638
  year: "numeric",
3576
- month: "long",
3639
+ month: "short",
3577
3640
  day: "numeric"
3578
3641
  });
3579
3642
  }
3580
- function PostCard({ title, description, date, slug, image, tags, renderLink }) {
3581
- const href = `/blog/${slug}`;
3582
- const LinkWrapper = ({ children, className }) => renderLink ? renderLink({ href, children, className }) : /* @__PURE__ */ jsx("a", { href, className, children });
3583
- return /* @__PURE__ */ jsxs("article", { className: "group flex flex-col gap-3", children: [
3584
- image && /* @__PURE__ */ jsx(LinkWrapper, { className: "block overflow-hidden rounded-xl", children: /* @__PURE__ */ jsx(
3585
- "img",
3586
- {
3587
- src: image,
3588
- alt: title,
3589
- className: "aspect-video w-full object-cover transition-transform duration-300 group-hover:scale-105"
3590
- }
3591
- ) }),
3592
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
3593
- tags && tags.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: tags.map((tag) => /* @__PURE__ */ jsx(Badge$1, { variant: "secondary", className: "text-xs", children: tag }, tag)) }),
3594
- /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold leading-snug tracking-tight", children: /* @__PURE__ */ jsx(LinkWrapper, { className: "hover:text-primary transition-colors", children: title }) }),
3595
- description && /* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-sm text-muted-foreground", children: description }),
3596
- /* @__PURE__ */ jsx("time", { dateTime: date, className: "text-xs text-muted-foreground", children: formatDate(date) })
3643
+ function PostCard({
3644
+ title,
3645
+ description,
3646
+ date,
3647
+ slug,
3648
+ image,
3649
+ tags,
3650
+ author,
3651
+ hrefPrefix = "/blog",
3652
+ tagHrefPrefix = "/blog/tag",
3653
+ renderLink
3654
+ }) {
3655
+ const href = `${hrefPrefix}/${slug}`;
3656
+ const LinkWrapper = ({
3657
+ href: linkHref,
3658
+ children,
3659
+ className
3660
+ }) => renderLink ? renderLink({ href: linkHref, children, className }) : /* @__PURE__ */ jsx("a", { href: linkHref, className, children });
3661
+ return /* @__PURE__ */ jsxs("article", { className: "group relative flex flex-col items-start", children: [
3662
+ /* @__PURE__ */ jsxs("div", { className: "relative w-full overflow-hidden rounded-2xl bg-muted", children: [
3663
+ image ? /* @__PURE__ */ jsx(
3664
+ "img",
3665
+ {
3666
+ src: image,
3667
+ alt: title,
3668
+ className: "aspect-video w-full object-cover transition-transform duration-500 group-hover:scale-[1.03]"
3669
+ }
3670
+ ) : /* @__PURE__ */ jsx(
3671
+ "div",
3672
+ {
3673
+ "aria-hidden": true,
3674
+ className: "aspect-video w-full bg-gradient-to-br from-primary/15 via-muted to-muted"
3675
+ }
3676
+ ),
3677
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 rounded-2xl ring-1 ring-inset ring-foreground/10" })
3678
+ ] }),
3679
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full grow flex-col", children: [
3680
+ /* @__PURE__ */ jsxs("div", { className: "mt-6 flex flex-wrap items-center gap-x-3 gap-y-2 text-xs", children: [
3681
+ /* @__PURE__ */ jsx("time", { dateTime: date, className: "text-muted-foreground", children: formatDate(date) }),
3682
+ tags?.map((tag) => /* @__PURE__ */ jsx(
3683
+ LinkWrapper,
3684
+ {
3685
+ href: `${tagHrefPrefix}/${encodeURIComponent(tag)}`,
3686
+ className: "relative z-10 rounded-full bg-muted px-3 py-1.5 font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
3687
+ children: tag
3688
+ },
3689
+ tag
3690
+ ))
3691
+ ] }),
3692
+ /* @__PURE__ */ jsxs("div", { className: "grow", children: [
3693
+ /* @__PURE__ */ jsx("h2", { className: "mt-3 text-lg font-semibold leading-snug tracking-tight transition-colors group-hover:text-primary", children: /* @__PURE__ */ jsxs(LinkWrapper, { href, children: [
3694
+ /* @__PURE__ */ jsx("span", { className: "absolute inset-0", "aria-hidden": true }),
3695
+ title
3696
+ ] }) }),
3697
+ description && /* @__PURE__ */ jsx("p", { className: "mt-3 line-clamp-3 text-sm leading-6 text-muted-foreground", children: description })
3698
+ ] }),
3699
+ author && /* @__PURE__ */ jsxs("div", { className: "mt-6 flex items-center gap-x-3", children: [
3700
+ author.avatar ? /* @__PURE__ */ jsx(
3701
+ "img",
3702
+ {
3703
+ src: author.avatar,
3704
+ alt: author.name,
3705
+ className: "size-9 rounded-full bg-muted object-cover"
3706
+ }
3707
+ ) : /* @__PURE__ */ jsx(
3708
+ "span",
3709
+ {
3710
+ "aria-hidden": true,
3711
+ className: "flex size-9 items-center justify-center rounded-full bg-muted text-sm font-semibold text-muted-foreground",
3712
+ children: author.name.charAt(0).toUpperCase()
3713
+ }
3714
+ ),
3715
+ /* @__PURE__ */ jsxs("div", { className: "text-sm leading-tight", children: [
3716
+ /* @__PURE__ */ jsx("p", { className: "font-semibold", children: author.name }),
3717
+ author.role && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: author.role })
3718
+ ] })
3719
+ ] })
3597
3720
  ] })
3598
3721
  ] });
3599
3722
  }
3600
- function PostList({ posts, renderLink, emptyMessage = "No posts published yet." }) {
3723
+ function PostList({
3724
+ posts,
3725
+ renderLink,
3726
+ emptyMessage = "No posts published yet.",
3727
+ columns = 3,
3728
+ className
3729
+ }) {
3601
3730
  if (posts.length === 0) {
3602
3731
  return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground italic", children: emptyMessage });
3603
3732
  }
3604
- return /* @__PURE__ */ jsx("div", { className: "grid gap-8 sm:grid-cols-2", children: posts.map((post) => /* @__PURE__ */ jsx(PostCard, { ...post, renderLink }, post.slug)) });
3733
+ return /* @__PURE__ */ jsx(
3734
+ "div",
3735
+ {
3736
+ className: cn$1(
3737
+ "grid grid-cols-1 gap-x-8 gap-y-14 sm:grid-cols-2",
3738
+ columns === 3 && "lg:grid-cols-3",
3739
+ className
3740
+ ),
3741
+ children: posts.map((post) => /* @__PURE__ */ jsx(PostCard, { ...post, renderLink }, post.slug))
3742
+ }
3743
+ );
3605
3744
  }
3606
3745
  var releaseTypeLabel = {
3607
3746
  release: "Major Release",
@@ -3828,6 +3967,6 @@ function usePagination(total, pageSize) {
3828
3967
  return { page, pageSize, totalPages, offset, hasPrev: page > 1, hasNext: page < totalPages, goTo, next, prev };
3829
3968
  }
3830
3969
 
3831
- export { AnimatedPill, AppContent, AppGrid, AppGridCell, AppScreen, AppShell, AuthSection, Badge, BrandColorSwitchMinimal, Button, Card, CarouselSection, ChangelogCard, ChangelogList, Checkbox, ComparisonSection, ConfirmDialog, ContactSection, ContextMenu, CountUp, CountdownTimer, CtaCardSection, CtaSection, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeatureMarqueeSection, FeaturesSection, FlowBracket, FlowConnector, Footer, FullPageSpinner, GlassCard, Grid, GridItem, GroupedFeaturesSection, HeroSection, ImageCard, Input, LogoStrip, ModeSwitchMinimal, Navbar, NewsletterSection, OlwibaUIProvider, Overlay, PageHeader, PageTransition, PhoneFrame, PostCard, PostList, PricingCard, PricingSection, PublicPageFrame, QualificationSection, RegisterHotkeys, RootErrorFallback, Section, SectionTitle, Spotlight, Stack, StaggerChildren, StatCard, StatsSection, StepsSection, Suspensed, Switch, TeamSection, TechStackSection, TestimonialCard, TestimonialsSection, Textarea, ThemeColorUpdater, ThemeSwitchMinimal, Underlay, UpgradePrompt, VersionBanner, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode };
3970
+ export { AnimatedPill, AppContent, AppGrid, AppGridCell, AppScreen, AppShell, AuthSection, Badge, BrandColorSwitchMinimal, Button, Card, CarouselSection, ChangelogCard, ChangelogList, Checkbox, ComparisonSection, ConfirmDialog, ContactSection, ContextMenu, CountUp, CountdownTimer, CtaCardSection, CtaSection, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeatureMarqueeSection, FeaturesSection, FlowBracket, FlowConnector, Footer, FullPageSpinner, GlassCard, Grid, GridItem, GroupedFeaturesSection, HeroSection, ImageCard, Input, LogoStrip, ModeSwitchMinimal, Navbar, NewsletterSection, OlwibaUIProvider, Overlay, PageHeader, PageTransition, PhoneFrame, PostCard, PostList, PricingCard, PricingSection, PublicPageFrame, QualificationSection, RegisterHotkeys, RootErrorFallback, Section, SectionTitle, Spotlight, Stack, StaggerChildren, StatCard, StatsSection, StepsSection, Suspensed, Switch, TeamSection, TechStackSection, TestimonialCard, TestimonialsSection, Textarea, ThemeColorUpdater, ThemeSwitchMinimal, Underlay, UpgradePrompt, VersionBanner, marketingSectionSpacing, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode };
3832
3971
  //# sourceMappingURL=index.js.map
3833
3972
  //# sourceMappingURL=index.js.map