ardo 3.4.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/dist/{DocPage-Dy7OrCP2.js → DocPage-EIVMae_6.js} +4 -4
  2. package/dist/DocPage-EIVMae_6.js.map +1 -0
  3. package/dist/assets/src/ui/components/{CodeBlock.css.ts.vanilla-BxDJ2gKc.css → CodeBlock.css.ts.vanilla-DYyQRTxk.css} +4 -4
  4. package/dist/assets/src/ui/components/{Container.css.ts.vanilla-CUhRUA9t.css → Container.css.ts.vanilla-B8_jKj0Q.css} +6 -0
  5. package/dist/assets/src/ui/components/{Features.css.ts.vanilla-ggYasCFy.css → Features.css.ts.vanilla-CcCxB5Q6.css} +1 -1
  6. package/dist/assets/src/ui/{content.css.ts.vanilla-CJnrOQNh.css → content.css.ts.vanilla-B5a1kmaY.css} +12 -2
  7. package/dist/assets/src/ui/theme/{dark.css.ts.vanilla-CQef5pk2.css → dark.css.ts.vanilla-CSJkJvIz.css} +1 -0
  8. package/dist/assets/src/ui/theme/{light.css.ts.vanilla-D8gxaS1c.css → light.css.ts.vanilla-CFz9jeJK.css} +1 -0
  9. package/dist/{contract.css-qPyk_asd.d.ts → contract.css-eFQbUr4z.d.ts} +2 -1
  10. package/dist/contract.css-eFQbUr4z.d.ts.map +1 -0
  11. package/dist/index.js +2 -2
  12. package/dist/mdx/provider.js +1 -1
  13. package/dist/theme/index.d.ts +3 -1
  14. package/dist/theme/index.d.ts.map +1 -1
  15. package/dist/theme/index.js +2 -0
  16. package/dist/theme/index.js.map +1 -1
  17. package/dist/ui/index.js +2 -2
  18. package/dist/ui/styles.css +25 -7
  19. package/dist/ui/styles.js +6 -6
  20. package/dist/{ui-AGPGBunC.js → ui-B6X8gAvz.js} +3 -3
  21. package/dist/{ui-AGPGBunC.js.map → ui-B6X8gAvz.js.map} +1 -1
  22. package/package.json +1 -1
  23. package/dist/DocPage-Dy7OrCP2.js.map +0 -1
  24. package/dist/contract.css-qPyk_asd.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ui-AGPGBunC.js","names":["styles.footerLink","styles.footerArdoLink","styles.footerOwl","styles.footerPrimary","styles.footerContainer","styles.searchPopover","styles.searchResults","styles.searchResult","styles.searchResultTitle","styles.searchNoResults","styles.searchNoResultsOwl","styles.searchFooter","styles.searchField","styles.searchInput","styles.searchKbd","styles.searchPopover","styles.search","styles.inline","styles.trigger","styles.themeToggle","styles.themeIcon","logo","styles.headerContainer","styles.headerLeft","styles.logoLink","styles.headerRight","styles.mobileBackdrop","styles.mobilePanel","styles.mobilePanelHeader","styles.mobilePanelClose","styles.mobilePanelSidebar","styles.sidebarRail","styles.sidebarRailList","styles.sidebarRailItem","styles.sidebarRailLink","styles.sidebarRailLabel","styles.sidebarPanel","styles.sidebarNav","styles.sidebarList","styles.sidebarList0","styles.sidebarText","styles.sidebarTextButton","styles.sidebarItemHeader","styles.sidebarItem","styles.sidebarList1","styles.sidebarLink","layoutStyles.layout","layoutStyles.home","styles.featureTitle","styles.featureDetails","styles.featuresContainer","styles.heroAction","styles.heroActionAlt","styles.heroActionBrand","styles.heroContainer","styles.heroAnimate","styles.root","styles.card","styles.owl","styles.status","styles.title","styles.description","styles.actions","styles.primaryAction","hero","heroActions","heroName","heroStyles.hero","heroStyles.heroContainer","layoutStyles.home","layoutStyles.homeMain","RouterNavLink"],"sources":["../src/ui/OwlMark.tsx","../src/ui/Footer.tsx","../src/ui/components/HeaderSearch.css.ts","../src/ui/components/search-hooks.ts","../src/ui/components/Search.css.ts","../src/ui/components/SearchPopover.tsx","../src/ui/components/Search.tsx","../src/ui/components/HeaderSearch.tsx","../src/ui/components/ThemeToggle.css.ts","../src/ui/components/ThemeToggle.tsx","../src/ui/Header.css.ts","../src/ui/Nav.css.ts","../src/ui/Header.tsx","../src/ui/Sidebar.css.ts","../src/ui/SidebarRail.tsx","../src/ui/Sidebar.tsx","../src/ui/ArdoRoot.tsx","../src/ui/components/Features.css.ts","../src/ui/components/Features.tsx","../src/ui/components/Hero.css.ts","../src/ui/components/Hero.tsx","../src/ui/ErrorBoundary.css.ts","../src/ui/ErrorBoundary.tsx","../src/ui/HomePage.tsx","../src/ui/Nav.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\"\n\nexport type ArdoOwlMarkProps = {\n size?: number | string\n title?: string\n} & Omit<ComponentProps<\"svg\">, \"children\">\n\n/**\n * Decorative line-art owl, drawn in `currentColor`. Used by the default\n * error and empty states. Set `color` on the parent (or `style.color`)\n * to recolor; set `title` to give it accessible meaning.\n */\nexport function ArdoOwlMark({ size = 96, title, ...props }: ArdoOwlMarkProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 600 600\"\n width={size}\n height={size}\n style={{ strokeLinecap: \"round\", strokeLinejoin: \"round\" }}\n role={title == null ? \"presentation\" : \"img\"}\n aria-hidden={title == null ? true : undefined}\n {...props}\n >\n {title == null ? null : <title>{title}</title>}\n <defs>\n <symbol id=\"ardo-owl-eye\" overflow=\"visible\">\n <path d=\"M300 300 151 128l2 178-41 94h93c-35 32-55 68-63 107m63-106 95 81m-32-96 28 88\" />\n <ellipse cx=\"222\" cy=\"327\" rx=\"20\" ry=\"33\" fill=\"currentColor\" opacity=\"0.6\" />\n <circle cx=\"227\" cy=\"324\" r=\"71\" />\n </symbol>\n </defs>\n <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"16\">\n <path d=\"M155 318c2-70 66-126 145-126s143 56 145 126\" />\n <circle cx=\"300\" cy=\"290\" r=\"270\" />\n <use href=\"#ardo-owl-eye\" />\n <use href=\"#ardo-owl-eye\" transform=\"matrix(-1 0 0 1 600 0)\" />\n </g>\n </svg>\n )\n}\n","import React, { type ReactNode } from \"react\"\n\nimport type { ProjectMeta, SponsorConfig } from \"../config/types\"\n\nimport { useArdoConfig } from \"../runtime/hooks\"\nimport * as styles from \"./Footer.css\"\nimport { ArdoOwlMark } from \"./OwlMark\"\n\n// =============================================================================\n// Footer Component\n// =============================================================================\n\nexport type ArdoFooterProps = {\n /** Footer message (supports HTML string) */\n message?: string\n /** Copyright text (supports HTML string) */\n copyright?: string\n /** Custom content (overrides all automatic rendering) */\n children?: ReactNode\n /** Additional CSS classes */\n className?: string\n /** Project metadata — renders linked \"name vX.Y.Z\" */\n project?: ProjectMeta\n /** Sponsor link — renders \"Sponsored by X\" */\n sponsor?: SponsorConfig\n /** Build timestamp (ISO string) — renders formatted date */\n buildTime?: string\n /** Git commit hash — rendered next to the build date */\n buildHash?: string\n /** Show \"Built with Ardo\" link (default: true) */\n ardoLink?: boolean\n}\n\nfunction formatBuildTime(iso: string): string {\n try {\n const date = new Date(iso)\n return date.toLocaleDateString(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })\n } catch {\n return iso\n }\n}\n\n/**\n * Footer component with structured layout for project info, sponsor, and build metadata.\n *\n * Automatically pulls data from Ardo context (`config.project`, `config.buildTime`,\n * `config.buildHash`). Props serve as overrides.\n *\n * When `children` is provided, all automatic rendering is skipped.\n *\n * @example Automatic (zero-config)\n * ```tsx\n * <Footer />\n * ```\n *\n * @example With overrides\n * ```tsx\n * <Footer\n * sponsor={{ text: \"Sebastian Software\", link: \"https://sebastian-software.com/oss\" }}\n * message=\"Released under the MIT License.\"\n * copyright=\"Copyright 2026 Sebastian Software GmbH\"\n * />\n * ```\n *\n * @example Custom content\n * ```tsx\n * <Footer>\n * <CustomFooterContent />\n * </Footer>\n * ```\n */\nfunction FooterProjectLink({\n project,\n config,\n}: {\n project: ArdoFooterProps[\"project\"]\n config: ReturnType<typeof useArdoConfig>\n}) {\n const resolved = project ?? config.project\n const name = resolved?.name ?? \"\"\n const version = resolved?.version ?? \"\"\n const homepage = resolved?.homepage ?? \"\"\n if (name === \"\") return null\n const label = version !== \"\" ? `${name} v${version}` : name\n return homepage !== \"\" ? (\n <a href={homepage} className={styles.footerLink}>\n {label}\n </a>\n ) : (\n <span>{label}</span>\n )\n}\n\nfunction FooterSponsorLink({ sponsor }: { sponsor: ArdoFooterProps[\"sponsor\"] }) {\n const text = sponsor?.text ?? \"\"\n const link = sponsor?.link ?? \"\"\n if (text === \"\" || link === \"\") return null\n return (\n <a href={link} className={styles.footerLink}>\n Sponsored by {text}\n </a>\n )\n}\n\nfunction FooterPrimaryLine({\n project,\n sponsor,\n ardoLink,\n config,\n}: {\n project: ArdoFooterProps[\"project\"]\n sponsor: ArdoFooterProps[\"sponsor\"]\n ardoLink: boolean\n config: ReturnType<typeof useArdoConfig>\n}) {\n const items: React.ReactNode[] = []\n const projectNode = <FooterProjectLink project={project} config={config} />\n const sponsorNode = <FooterSponsorLink sponsor={sponsor} />\n const hasProject =\n (project ?? config.project)?.name !== undefined && (project ?? config.project)?.name !== \"\"\n const hasSponsor = (sponsor?.text ?? \"\") !== \"\" && (sponsor?.link ?? \"\") !== \"\"\n\n if (hasProject) items.push(projectNode)\n if (ardoLink)\n items.push(\n <a href=\"https://ardo-docs.dev\" className={styles.footerArdoLink}>\n <ArdoOwlMark size={16} className={styles.footerOwl} title=\"\" />\n Built with Ardo\n </a>\n )\n if (hasSponsor) items.push(sponsorNode)\n if (items.length === 0) return null\n\n return (\n <p className={styles.footerPrimary}>\n {items.map((item, i) => (\n // eslint-disable-next-line react/no-array-index-key\n <React.Fragment key={i}>\n {i > 0 && <span className={styles.footerSeparator} aria-hidden=\"true\" />}\n {item}\n </React.Fragment>\n ))}\n </p>\n )\n}\n\nexport function ArdoFooter({\n children,\n className,\n ardoLink = true,\n message,\n copyright,\n project,\n sponsor,\n buildTime,\n buildHash,\n}: ArdoFooterProps) {\n const config = useArdoConfig()\n const resolvedBuildTime = buildTime ?? config.buildTime\n const resolvedBuildHash = buildHash ?? config.buildHash\n\n if (children != null) {\n return (\n <footer className={className ?? styles.footer}>\n <div className={styles.footerContainer}>{children}</div>\n </footer>\n )\n }\n\n return (\n <footer className={className ?? styles.footer}>\n <div className={styles.footerContainer}>\n <FooterPrimaryLine\n project={project}\n sponsor={sponsor}\n ardoLink={ardoLink}\n config={config}\n />\n {(message ?? \"\") !== \"\" && (\n <p className={styles.footerMessage} dangerouslySetInnerHTML={{ __html: message ?? \"\" }} />\n )}\n {(copyright ?? \"\") !== \"\" && (\n <p\n className={styles.footerCopyright}\n dangerouslySetInnerHTML={{ __html: copyright ?? \"\" }}\n />\n )}\n {(resolvedBuildTime ?? \"\") !== \"\" && (\n <p className={styles.footerBuildTime}>\n Built on {formatBuildTime(resolvedBuildTime ?? \"\")}\n {(resolvedBuildHash ?? \"\") !== \"\" && <> ({resolvedBuildHash})</>}\n </p>\n )}\n </div>\n </footer>\n )\n}\n\n// Type exports for compound pattern (kept for backwards compatibility)\nexport type ArdoFooterMessageProps = {\n children: ReactNode\n className?: string\n}\n\nexport type ArdoFooterCopyrightProps = {\n children: ReactNode\n className?: string\n}\n","import { style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"../theme/contract.css\"\n\nconst MOBILE = \"(max-width: 1024px)\"\n\n/** Inline search input — desktop only, hidden once the header collapses. */\nexport const inline = style({\n width: \"100%\",\n maxWidth: \"26rem\",\n \"@media\": {\n [MOBILE]: {\n display: \"none\",\n },\n },\n})\n\n/** Icon button that opens the search overlay — mobile only. */\nexport const trigger = style({\n display: \"none\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"2.25rem\",\n height: \"2.25rem\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n borderRadius: vars.radius.base,\n color: vars.color.text,\n transition: `background ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.bgSoft,\n },\n },\n \"@media\": {\n [MOBILE]: {\n display: \"flex\",\n },\n },\n})\n\nexport const overlay = style({\n position: \"fixed\",\n inset: 0,\n zIndex: 200,\n display: \"flex\",\n flexDirection: \"column\",\n background: `color-mix(in oklch, ${vars.color.bg} 88%, transparent)`,\n backdropFilter: \"blur(4px)\",\n WebkitBackdropFilter: \"blur(4px)\",\n})\n\nexport const overlayBar = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: vars.space.sm,\n padding: vars.space.md,\n borderBottom: `1px solid ${vars.color.border}`,\n background: vars.color.bg,\n})\n\nexport const overlaySearch = style({\n flex: 1,\n minWidth: 0,\n})\n\nexport const overlayClose = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"2.25rem\",\n height: \"2.25rem\",\n flexShrink: 0,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n borderRadius: vars.radius.base,\n color: vars.color.textLight,\n transition: `background ${vars.transition.fast}, color ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.bgSoft,\n color: vars.color.text,\n },\n },\n})\n","import { type RefObject, useEffect } from \"react\"\n\nexport function useGlobalSearchShortcut(\n inputRef: RefObject<HTMLInputElement | null>,\n setIsOpen: (open: boolean) => void\n) {\n useEffect(() => {\n const handleGlobalKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"k\") {\n e.preventDefault()\n inputRef.current?.focus()\n setIsOpen(true)\n }\n if (e.key === \"Escape\") {\n setIsOpen(false)\n }\n }\n document.addEventListener(\"keydown\", handleGlobalKeyDown)\n return () => {\n document.removeEventListener(\"keydown\", handleGlobalKeyDown)\n }\n }, [inputRef, setIsOpen])\n}\n\ntype OutsideClickOptions = {\n containerRef: RefObject<HTMLDivElement | null>\n popoverClass: string\n isOpen: boolean\n setIsOpen: (open: boolean) => void\n}\n\nexport function useOutsideClick({\n containerRef,\n popoverClass,\n isOpen,\n setIsOpen,\n}: OutsideClickOptions) {\n useEffect(() => {\n if (!isOpen) return\n const handleOutsideClick = (e: MouseEvent | TouchEvent) => {\n if (!(e.target instanceof Element)) {\n return\n }\n\n const target = e.target\n const inContainer = containerRef.current?.contains(target) === true\n const inPopover = target.closest(`.${popoverClass}`) != null\n if (!inContainer && !inPopover) {\n setIsOpen(false)\n }\n }\n document.addEventListener(\"mousedown\", handleOutsideClick)\n document.addEventListener(\"touchstart\", handleOutsideClick)\n return () => {\n document.removeEventListener(\"mousedown\", handleOutsideClick)\n document.removeEventListener(\"touchstart\", handleOutsideClick)\n }\n }, [containerRef, popoverClass, isOpen, setIsOpen])\n}\n","import { globalStyle, style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"../theme/contract.css\"\n\nexport const search = style({\n position: \"relative\",\n width: \"100%\",\n maxWidth: \"100%\",\n})\n\nexport const searchField = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: vars.space.sm,\n minHeight: \"2.5rem\",\n padding: `${vars.space.sm} 0.75rem`,\n background: vars.color.bg,\n border: `1px solid ${vars.color.border}`,\n borderRadius: vars.radius.base,\n color: vars.color.textLighter,\n cursor: \"text\",\n transition: `border-color ${vars.transition.fast}, box-shadow ${vars.transition.fast}, color ${vars.transition.fast}`,\n outline: \"none\",\n})\n\nglobalStyle(`${search}:focus-within ${searchField}`, {\n borderColor: vars.color.brand,\n color: vars.color.textLight,\n boxShadow: `0 0 0 3px color-mix(in oklch, ${vars.color.brand} 12%, transparent)`,\n})\n\nglobalStyle(`${searchField}:focus-within`, {\n outline: \"none\",\n})\n\nexport const searchInput = style({\n flex: 1,\n minWidth: 0,\n border: \"none\",\n outline: \"none\",\n fontSize: vars.fontSize.sm,\n background: \"none\",\n color: vars.color.text,\n \"::placeholder\": {\n color: vars.color.textLighter,\n },\n selectors: {\n \"&:focus-visible\": {\n outline: \"none\",\n },\n },\n})\n\nexport const searchPopover = style({\n position: \"fixed\",\n width: \"min(28rem, calc(100vw - 2rem))\",\n background: vars.color.bg,\n borderRadius: vars.radius.lg,\n border: `1px solid ${vars.color.border}`,\n boxShadow: vars.color.shadowLg,\n overflow: \"hidden\",\n zIndex: 210,\n})\n\nexport const searchResults = style({\n listStyle: \"none\",\n maxHeight: \"25rem\",\n overflowY: \"auto\",\n})\n\nexport const searchResult = style({\n display: \"block\",\n padding: `0.75rem ${vars.space.md}`,\n textDecoration: \"none\",\n color: vars.color.text,\n borderBottom: `1px solid ${vars.color.borderLight}`,\n transition: `background ${vars.transition.fast}`,\n selectors: {\n \"&:last-child\": {\n borderBottom: \"none\",\n },\n \"&:hover, &.selected\": {\n background: vars.color.brandSubtle,\n },\n },\n})\n\nexport const searchResultTitle = style({\n display: \"block\",\n fontWeight: 500,\n marginBottom: \"2px\",\n})\n\nexport const searchResultSection = style({\n display: \"block\",\n fontSize: vars.fontSize.xs,\n color: vars.color.textLighter,\n})\n\nexport const searchNoResults = style({\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: vars.space.sm,\n padding: `${vars.space.xl} ${vars.space.md}`,\n textAlign: \"center\",\n color: vars.color.textLighter,\n})\n\nexport const searchNoResultsOwl = style({\n color: vars.color.textLighter,\n opacity: 0.55,\n})\n\nexport const searchFooter = style({\n display: \"flex\",\n justifyContent: \"center\",\n gap: vars.space.lg,\n padding: `0.75rem ${vars.space.md}`,\n background: vars.color.bgSoft,\n borderTop: `1px solid ${vars.color.border}`,\n fontSize: vars.fontSize.xs,\n color: vars.color.textLighter,\n})\n\nglobalStyle(`${searchFooter} kbd`, {\n padding: \"2px 6px\",\n background: vars.color.bg,\n border: `1px solid ${vars.color.border}`,\n borderRadius: vars.radius.sm,\n marginRight: \"4px\",\n color: vars.color.accent,\n fontFamily: vars.font.mono,\n})\n\nexport const searchClear = style({\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"1.5rem\",\n height: \"1.5rem\",\n flexShrink: 0,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: vars.fontSize.lg,\n color: vars.color.textLighter,\n padding: vars.space.xs,\n borderRadius: vars.radius.sm,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.bgSoft,\n color: vars.color.text,\n },\n },\n})\n\nexport const searchKbd = style({\n display: \"flex\",\n gap: \"3px\",\n marginLeft: vars.space.xs,\n})\n\nglobalStyle(`${searchKbd} kbd`, {\n padding: \"2px 6px\",\n background: vars.color.bg,\n border: `1px solid ${vars.color.border}`,\n borderRadius: vars.radius.sm,\n fontSize: vars.fontSize.xs,\n fontFamily: vars.font.mono,\n color: vars.color.accent,\n})\n","import { useLayoutEffect, useState } from \"react\"\nimport { createPortal } from \"react-dom\"\n\nimport * as styles from \"./Search.css\"\n\n/**\n * Renders the search popover as a portal attached to document.body.\n * Uses getBoundingClientRect to position it below the anchor element.\n */\nexport function SearchPopover({\n anchorRef,\n children,\n}: {\n anchorRef: React.RefObject<HTMLElement | null>\n children: React.ReactNode\n}) {\n const [pos, setPos] = useState({ top: 0, left: 0, width: 0 })\n\n useLayoutEffect(() => {\n const el = anchorRef.current\n if (!el) return\n const rect = el.getBoundingClientRect()\n setPos({\n top: rect.bottom + 8,\n left: rect.left,\n width: Math.max(rect.width, 400),\n })\n }, [anchorRef])\n\n if (typeof document === \"undefined\") return null\n\n return createPortal(\n <div\n className={styles.searchPopover}\n style={{\n top: pos.top,\n left: pos.left,\n width: Math.min(pos.width, globalThis.innerWidth - 32),\n }}\n >\n {children}\n </div>,\n document.body\n )\n}\n","import MiniSearch from \"minisearch\"\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { Link, useNavigate } from \"react-router\"\nimport searchDocs from \"virtual:ardo/search-index\"\n\nimport { SearchIcon } from \"../icons\"\nimport { ArdoOwlMark } from \"../OwlMark\"\nimport { useGlobalSearchShortcut, useOutsideClick } from \"./search-hooks\"\nimport * as styles from \"./Search.css\"\nimport { SearchPopover } from \"./SearchPopover\"\n\ntype SearchDoc = {\n id: string\n title: string\n content: string\n path: string\n section?: string\n}\n\ntype SearchMatch = {\n id: string\n title: string\n path: string\n section?: string\n}\n\nexport type ArdoSearchProps = {\n /** Placeholder text for the search input (default: \"Search...\") */\n placeholder?: string\n /** Focus the input on mount (used by the mobile search overlay). */\n autoFocus?: boolean\n}\n\nfunction useSearchIndex() {\n return useMemo(() => {\n const index = new MiniSearch<SearchDoc>({\n fields: [\"title\", \"content\", \"section\"],\n storeFields: [\"title\", \"path\", \"section\"],\n searchOptions: { boost: { title: 2 }, fuzzy: 0.2, prefix: true },\n })\n index.addAll(searchDocs)\n return index\n }, [])\n}\n\nfunction normalizeResults(rawResults: Array<Record<string, unknown>>): SearchMatch[] {\n return rawResults.flatMap((result): SearchMatch[] => {\n const resultPath = typeof result.path === \"string\" ? result.path : undefined\n const title = typeof result.title === \"string\" ? result.title : undefined\n if (resultPath === undefined || title === undefined) return []\n return [\n {\n id: String(result.id),\n title,\n path: resultPath,\n section: typeof result.section === \"string\" ? result.section : undefined,\n },\n ]\n })\n}\n\nfunction SearchResults({\n results,\n selectedIndex,\n query,\n onClose,\n}: {\n results: SearchMatch[]\n selectedIndex: number\n query: string\n onClose: () => void\n}) {\n return (\n <>\n {results.length > 0 ? (\n <ul className={styles.searchResults}>\n {results.map((result, index) => (\n <li key={result.id}>\n <Link\n to={result.path}\n className={[styles.searchResult, index === selectedIndex && \"selected\"]\n .filter(Boolean)\n .join(\" \")}\n onClick={onClose}\n >\n <span className={styles.searchResultTitle}>{result.title}</span>\n {result.section !== undefined && (\n <span className={styles.searchResultSection}>{result.section}</span>\n )}\n </Link>\n </li>\n ))}\n </ul>\n ) : (\n <div className={styles.searchNoResults}>\n <ArdoOwlMark size={36} className={styles.searchNoResultsOwl} title=\"\" />\n <span>No results found for &quot;{query}&quot;</span>\n </div>\n )}\n <div className={styles.searchFooter}>\n <span>\n <kbd>↑</kbd> <kbd>↓</kbd> to navigate\n </span>\n <span>\n <kbd>↵</kbd> to select\n </span>\n <span>\n <kbd>esc</kbd> to close\n </span>\n </div>\n </>\n )\n}\n\nfunction useSearch(searchIndex: ReturnType<typeof useSearchIndex>) {\n const [isOpen, setIsOpen] = useState(false)\n const [query, setQuery] = useState(\"\")\n const [results, setResults] = useState<SearchMatch[]>([])\n const [selectedIndex, setSelectedIndex] = useState(0)\n\n const search = (searchQuery: string) => {\n setQuery(searchQuery)\n if (!searchQuery.trim()) {\n setResults([])\n setIsOpen(false)\n setSelectedIndex(0)\n return\n }\n const rawResults = searchIndex.search(searchQuery).slice(0, 10)\n setResults(normalizeResults(rawResults))\n setSelectedIndex(0)\n setIsOpen(true)\n }\n\n return { isOpen, setIsOpen, query, results, selectedIndex, setSelectedIndex, search }\n}\n\nfunction SearchInput({\n inputRef,\n placeholder,\n query,\n hasQuery,\n onSearch,\n onKeyDown,\n onFocus,\n}: {\n inputRef: React.RefObject<HTMLInputElement | null>\n placeholder: string\n query: string\n hasQuery: boolean\n onSearch: (q: string) => void\n onKeyDown: (e: React.KeyboardEvent) => void\n onFocus: () => void\n}) {\n return (\n <div className={styles.searchField}>\n <SearchIcon size={18} />\n <input\n ref={inputRef}\n type=\"text\"\n className={styles.searchInput}\n placeholder={placeholder}\n value={query}\n onChange={(e) => {\n onSearch(e.target.value)\n }}\n onKeyDown={onKeyDown}\n onFocus={onFocus}\n aria-label=\"Search\"\n />\n {hasQuery && (\n <button\n type=\"button\"\n className={styles.searchClear}\n onClick={(e) => {\n e.stopPropagation()\n onSearch(\"\")\n inputRef.current?.focus()\n }}\n aria-label=\"Clear search\"\n >\n ×\n </button>\n )}\n <span className={styles.searchKbd}>\n <kbd>⌘</kbd>\n <kbd>K</kbd>\n </span>\n </div>\n )\n}\n\nexport function ArdoSearch({ placeholder = \"Search...\", autoFocus = false }: ArdoSearchProps) {\n const navigate = useNavigate()\n const containerRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const searchIndex = useSearchIndex()\n const state = useSearch(searchIndex)\n const hasQuery = state.query.trim().length > 0\n\n useEffect(() => {\n if (autoFocus) inputRef.current?.focus()\n }, [autoFocus])\n\n useGlobalSearchShortcut(inputRef, state.setIsOpen)\n useOutsideClick({\n containerRef,\n popoverClass: styles.searchPopover,\n isOpen: state.isOpen,\n setIsOpen: state.setIsOpen,\n })\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case \"ArrowDown\":\n if (state.results.length > 0) {\n e.preventDefault()\n state.setSelectedIndex((p) => Math.min(p + 1, state.results.length - 1))\n }\n break\n case \"ArrowUp\":\n if (state.results.length > 0) {\n e.preventDefault()\n state.setSelectedIndex((p) => Math.max(p - 1, 0))\n }\n break\n case \"Enter\": {\n const p = state.results[state.selectedIndex]?.path\n if (typeof p === \"string\") {\n e.preventDefault()\n void navigate(p)\n state.setIsOpen(false)\n }\n break\n }\n case \"Escape\":\n state.setIsOpen(false)\n inputRef.current?.blur()\n break\n default:\n break\n }\n }\n\n return (\n <div\n className={styles.search}\n ref={containerRef}\n data-expanded={state.isOpen || hasQuery ? \"true\" : \"false\"}\n onMouseDown={() => inputRef.current?.focus()}\n >\n <SearchInput\n inputRef={inputRef}\n placeholder={placeholder}\n query={state.query}\n hasQuery={hasQuery}\n onSearch={state.search}\n onKeyDown={handleKeyDown}\n onFocus={() => {\n if (hasQuery) state.setIsOpen(true)\n }}\n />\n {state.isOpen && hasQuery && (\n <SearchPopover anchorRef={containerRef}>\n <SearchResults\n results={state.results}\n selectedIndex={state.selectedIndex}\n query={state.query}\n onClose={() => {\n state.setIsOpen(false)\n }}\n />\n </SearchPopover>\n )}\n </div>\n )\n}\n","import { useEffect, useState } from \"react\"\nimport { useLocation } from \"react-router\"\n\nimport { SearchIcon, XIcon } from \"../icons\"\nimport * as styles from \"./HeaderSearch.css\"\nimport { ArdoSearch, type ArdoSearchProps } from \"./Search\"\n\n/**\n * Header-hosted search. On desktop it renders the search input inline; on\n * narrow viewports it collapses to an icon button that opens a full-width\n * search overlay.\n */\nexport function ArdoHeaderSearch({ placeholder }: ArdoSearchProps) {\n const [overlayOpen, setOverlayOpen] = useState(false)\n const location = useLocation()\n\n // Close the overlay on navigation and on Escape.\n useEffect(() => {\n setOverlayOpen(false)\n }, [location.pathname])\n\n useEffect(() => {\n if (!overlayOpen) return\n const handleKey = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") setOverlayOpen(false)\n }\n document.addEventListener(\"keydown\", handleKey)\n return () => {\n document.removeEventListener(\"keydown\", handleKey)\n }\n }, [overlayOpen])\n\n return (\n <>\n <div className={styles.inline}>\n <ArdoSearch placeholder={placeholder} />\n </div>\n\n <button\n type=\"button\"\n className={styles.trigger}\n aria-label=\"Search\"\n onClick={() => {\n setOverlayOpen(true)\n }}\n >\n <SearchIcon size={20} />\n </button>\n\n {overlayOpen && (\n <div className={styles.overlay}>\n <div className={styles.overlayBar}>\n <div className={styles.overlaySearch}>\n <ArdoSearch placeholder={placeholder} autoFocus />\n </div>\n <button\n type=\"button\"\n className={styles.overlayClose}\n aria-label=\"Close search\"\n onClick={() => {\n setOverlayOpen(false)\n }}\n >\n <XIcon size={20} />\n </button>\n </div>\n </div>\n )}\n </>\n )\n}\n","import { style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"../theme/contract.css\"\n\nexport const themeIcon = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n})\n\nexport const themeToggle = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"40px\",\n height: \"40px\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n color: vars.color.textLight,\n borderRadius: vars.radius.base,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.bgSoft,\n color: vars.color.text,\n },\n },\n})\n","import { useEffect, useState, useSyncExternalStore } from \"react\"\n\nimport { MonitorIcon, MoonIcon, SunIcon } from \"../icons\"\nimport * as styles from \"./ThemeToggle.css\"\n\ntype Theme = \"dark\" | \"light\" | \"system\"\n\nconst isBrowser = typeof document !== \"undefined\"\n\nfunction getInitialTheme(): Theme {\n if (!isBrowser) return \"system\"\n const stored = localStorage.getItem(\"ardo-theme\")\n return isTheme(stored) ? stored : \"system\"\n}\n\nexport function ArdoThemeToggle() {\n const [theme, setTheme] = useState<Theme>(getInitialTheme)\n const mounted = useSyncExternalStore(subscribeMounted, getClientMounted, getServerMounted)\n\n useEffect(() => {\n if (!mounted) return\n applyTheme(theme)\n }, [mounted, theme])\n\n const toggleTheme = () => {\n const nextTheme: Theme = theme === \"light\" ? \"dark\" : theme === \"dark\" ? \"system\" : \"light\"\n setTheme(nextTheme)\n localStorage.setItem(\"ardo-theme\", nextTheme)\n applyTheme(nextTheme)\n }\n\n if (!mounted) {\n return (\n <button type=\"button\" className={styles.themeToggle} aria-label=\"Toggle theme\">\n <span className={styles.themeIcon}>\n <SunIcon size={20} />\n </span>\n </button>\n )\n }\n\n return (\n <button\n type=\"button\"\n className={styles.themeToggle}\n onClick={toggleTheme}\n aria-label={`Switch to ${theme === \"light\" ? \"dark\" : theme === \"dark\" ? \"system\" : \"light\"} theme`}\n >\n <span className={styles.themeIcon}>\n {theme === \"light\" && <SunIcon size={20} />}\n {theme === \"dark\" && <MoonIcon size={20} />}\n {theme === \"system\" && <MonitorIcon size={20} />}\n </span>\n </button>\n )\n}\n\nfunction applyTheme(theme: Theme) {\n const root = document.documentElement\n\n if (theme === \"system\") {\n const isDark = globalThis.matchMedia(\"(prefers-color-scheme: dark)\").matches\n root.classList.toggle(\"dark\", isDark)\n root.classList.toggle(\"light\", !isDark)\n } else {\n root.classList.toggle(\"dark\", theme === \"dark\")\n root.classList.toggle(\"light\", theme === \"light\")\n }\n}\n\nfunction subscribeMounted() {\n return noop\n}\n\nfunction getClientMounted() {\n return true\n}\n\nfunction getServerMounted() {\n return false\n}\n\nfunction noop() {\n return undefined\n}\n\nfunction isTheme(value: null | string): value is Theme {\n return value === \"dark\" || value === \"light\" || value === \"system\"\n}\n","import { globalStyle, style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"./theme/contract.css\"\n\nexport const header = style({\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n height: `calc(${vars.layout.headerHeight} + env(safe-area-inset-top))`,\n paddingTop: \"env(safe-area-inset-top)\",\n background: vars.color.bg,\n borderBottom: `1px solid ${vars.color.border}`,\n zIndex: 100,\n boxShadow: \"0 1px 0 oklch(0 0 0 / 0.02)\",\n})\n\nexport const headerContainer = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n height: vars.layout.headerHeight,\n padding: `0 ${vars.space.lg}`,\n \"@media\": {\n \"(max-width: 640px)\": {\n padding: `0 ${vars.space.md}`,\n },\n },\n})\n\nexport const headerLeft = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: vars.space.md,\n flexShrink: 0,\n})\n\nexport const headerCenter = style({\n display: \"flex\",\n flex: 1,\n justifyContent: \"center\",\n minWidth: 0,\n padding: `0 ${vars.space.lg}`,\n \"@media\": {\n \"(max-width: 1024px)\": {\n justifyContent: \"flex-end\",\n padding: `0 ${vars.space.sm}`,\n },\n },\n})\n\nexport const headerRight = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.75rem\",\n flexShrink: 0,\n})\n\nexport const logoLink = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: vars.space.sm,\n textDecoration: \"none\",\n color: vars.color.text,\n transition: `opacity ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n opacity: 0.8,\n },\n },\n})\n\nexport const logo = style({\n height: \"2rem\",\n})\n\nexport const siteTitle = style({\n fontSize: vars.fontSize.lg,\n fontWeight: 700,\n letterSpacing: \"-0.025em\",\n})\n\nexport const mobileMenuButton = style({\n display: \"none\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: vars.space.sm,\n borderRadius: vars.radius.sm,\n color: vars.color.text,\n selectors: {\n \"&:hover\": {\n background: vars.color.bgSoft,\n },\n },\n \"@media\": {\n \"(max-width: 1024px)\": {\n display: \"flex\",\n alignItems: \"center\",\n },\n },\n})\n\nexport const hamburger = style({\n display: \"flex\",\n flexDirection: \"column\",\n gap: vars.space.xs,\n})\n\nglobalStyle(`${hamburger} span`, {\n display: \"block\",\n width: \"1.25rem\",\n height: \"2px\",\n background: vars.color.text,\n borderRadius: \"1px\",\n transition: `all ${vars.transition.fast}`,\n})\n\nexport const desktopNav = style({\n display: \"flex\",\n alignItems: \"center\",\n \"@media\": {\n \"(max-width: 1024px)\": {\n display: \"none\",\n },\n },\n})\n\n// =============================================================================\n// Mobile slide-in panel\n// =============================================================================\n\nexport const mobileBackdrop = style({\n position: \"fixed\",\n inset: 0,\n zIndex: 150,\n background: \"oklch(0 0 0 / 0.3)\",\n transition: `opacity ${vars.transition.base}`,\n selectors: {\n '&[data-open=\"false\"]': {\n opacity: 0,\n pointerEvents: \"none\",\n },\n },\n})\n\nexport const mobilePanel = style({\n position: \"fixed\",\n top: 0,\n left: 0,\n bottom: 0,\n width: \"min(22rem, 88vw)\",\n zIndex: 151,\n background: vars.color.bg,\n overflowY: \"auto\",\n padding: `${vars.space.lg} ${vars.space.lg} ${vars.space.xl}`,\n borderRight: `1px solid ${vars.color.border}`,\n boxShadow: vars.color.shadowLg,\n transform: \"translateX(0)\",\n transition: `transform ${vars.transition.slow}`,\n selectors: {\n '&[data-open=\"false\"]': {\n transform: \"translateX(-100%)\",\n },\n },\n})\n\nexport const mobilePanelHeader = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n marginBottom: vars.space.lg,\n})\n\nexport const mobilePanelClose = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: vars.space.sm,\n borderRadius: vars.radius.base,\n color: vars.color.textLight,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n background: vars.color.bgMute,\n },\n },\n})\n\nexport const mobilePanelNav = style({\n marginBottom: vars.space.lg,\n paddingBottom: vars.space.md,\n borderBottom: `1px solid ${vars.color.border}`,\n})\n\nglobalStyle(`${mobilePanelNav} a`, {\n display: \"block\",\n padding: `${vars.space.sm} 0`,\n color: vars.color.textLight,\n textDecoration: \"none\",\n fontSize: vars.fontSize.sm,\n})\n\n// Force sidebar visible inside the mobile panel (overrides sidebar's display:none at 1024px)\nexport const mobilePanelSidebar = style({})\n\nglobalStyle(`${mobilePanelSidebar} > aside`, {\n display: \"block\",\n width: \"100%\",\n padding: 0,\n borderRight: \"none\",\n})\n\nglobalStyle(`${mobilePanelSidebar} nav[aria-label=\"Documentation sections\"]`, {\n display: \"none\",\n})\n\n// Legacy - keep for backwards compat but unused\nexport const mobileMenu = style({ display: \"none\" })\nexport const mobileTopNav = style({ display: \"none\" })\nexport const mobileMenuContent = style({})\nexport const mobileMenuSection = style({})\nexport const mobileNav = style({})\n","import { style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"./theme/contract.css\"\n\nexport const nav = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n})\n\nexport const navLink = style({\n position: \"relative\",\n color: vars.color.textLight,\n textDecoration: \"none\",\n fontSize: \"14px\",\n fontWeight: 500,\n padding: \"8px 14px\",\n borderRadius: vars.radius.sm,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&::after\": {\n content: '\"\"',\n position: \"absolute\",\n bottom: 0,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: 0,\n height: \"2px\",\n background: vars.color.brand,\n borderRadius: \"1px\",\n transition: `width ${vars.transition.base}`,\n },\n \"&:hover\": {\n color: vars.color.text,\n background: vars.color.bgSoft,\n },\n \"&.active\": {\n color: vars.color.brand,\n },\n \"&.active::after\": {\n width: \"calc(100% - 28px)\",\n },\n },\n})\n\nexport const socialLink = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"40px\",\n height: \"40px\",\n color: vars.color.textLight,\n borderRadius: vars.radius.base,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n background: vars.color.bgSoft,\n },\n },\n})\n","import { type ReactNode, useEffect, useState } from \"react\"\nimport { Link, useLocation } from \"react-router\"\n\nimport { useArdoConfig } from \"../runtime/hooks\"\nimport { ArdoHeaderSearch } from \"./components/HeaderSearch\"\nimport { ArdoThemeToggle } from \"./components/ThemeToggle\"\nimport * as styles from \"./Header.css\"\nimport {\n GithubIcon,\n LinkedinIcon,\n MessageCircleIcon,\n NpmIcon,\n TwitterIcon,\n XIcon,\n YoutubeIcon,\n} from \"./icons\"\nimport * as navStyles from \"./Nav.css\"\n\n// =============================================================================\n// Header Component\n// =============================================================================\n\nexport type ArdoHeaderProps = {\n /** Logo image URL or light/dark variants */\n logo?: { light: string; dark: string } | string\n /** Site title displayed next to logo */\n title?: string\n /** Navigation content (Nav component or custom) */\n nav?: ReactNode\n /** Actions/right side content (social links, custom buttons) */\n actions?: ReactNode\n /** Show search (default: true) */\n search?: boolean\n /** Placeholder text for the search input */\n searchPlaceholder?: string\n /** Show theme toggle (default: true) */\n themeToggle?: boolean\n /** Additional content rendered in the mobile menu (e.g. sidebar) */\n mobileMenuContent?: ReactNode\n /** Additional CSS classes */\n className?: string\n}\n\n/**\n * Mobile menu open state — resets on navigation and locks body scroll\n * while open.\n */\nfunction useMobileMenu(): [boolean, (open: boolean) => void] {\n const location = useLocation()\n const [open, setOpen] = useState(false)\n\n useEffect(() => {\n setOpen(false)\n }, [location.pathname])\n\n useEffect(() => {\n document.body.style.overflow = open ? \"hidden\" : \"\"\n return () => {\n document.body.style.overflow = \"\"\n }\n }, [open])\n\n return [open, setOpen]\n}\n\nexport function ArdoHeader({\n logo,\n title,\n nav,\n actions,\n search = true,\n searchPlaceholder,\n themeToggle = true,\n mobileMenuContent,\n className,\n}: ArdoHeaderProps) {\n const config = useArdoConfig()\n const [mobileMenuOpen, setMobileMenuOpen] = useMobileMenu()\n\n const resolvedLogo = logo\n const resolvedTitle = title ?? config.title\n const hasLogo = resolvedLogo !== undefined\n const hasTitle = resolvedTitle !== \"\"\n const hasMobileMenu = mobileMenuContent != null\n\n return (\n <>\n <header className={className ?? styles.header}>\n <div className={styles.headerContainer}>\n <div className={styles.headerLeft}>\n {hasMobileMenu && (\n <button\n type=\"button\"\n className={styles.mobileMenuButton}\n onClick={() => {\n setMobileMenuOpen(!mobileMenuOpen)\n }}\n aria-label=\"Toggle menu\"\n aria-expanded={mobileMenuOpen}\n >\n <span className={styles.hamburger}>\n <span />\n <span />\n <span />\n </span>\n </button>\n )}\n <Link to=\"/\" className={styles.logoLink}>\n {hasLogo && (\n <img\n src={typeof resolvedLogo === \"string\" ? resolvedLogo : resolvedLogo.light}\n alt={resolvedTitle}\n className={styles.logo}\n />\n )}\n {hasTitle && <span className={styles.siteTitle}>{resolvedTitle}</span>}\n </Link>\n </div>\n\n {search && (\n <div className={styles.headerCenter}>\n <ArdoHeaderSearch placeholder={searchPlaceholder} />\n </div>\n )}\n\n <div className={styles.headerRight}>\n {nav != null && <div className={styles.desktopNav}>{nav}</div>}\n {themeToggle && <ArdoThemeToggle />}\n {actions}\n </div>\n </div>\n </header>\n\n {hasMobileMenu && (\n <MobileSlidePanel\n isOpen={mobileMenuOpen}\n logo={resolvedLogo}\n title={resolvedTitle}\n nav={nav}\n themeToggle={themeToggle}\n onClose={() => {\n setMobileMenuOpen(false)\n }}\n >\n {mobileMenuContent}\n </MobileSlidePanel>\n )}\n </>\n )\n}\n\n// =============================================================================\n// Mobile Slide-in Panel\n// =============================================================================\n\nfunction MobileSlidePanel({\n isOpen,\n logo,\n title,\n nav,\n themeToggle,\n children,\n onClose,\n}: {\n isOpen: boolean\n logo?: { light: string; dark: string } | string\n title: string\n nav?: ReactNode\n themeToggle?: boolean\n children: ReactNode\n onClose: () => void\n}) {\n return (\n <>\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}\n <div className={styles.mobileBackdrop} data-open={isOpen} onClick={onClose} />\n\n {/* Panel */}\n <div className={styles.mobilePanel} data-open={isOpen} aria-hidden={!isOpen}>\n <div className={styles.mobilePanelHeader}>\n <Link to=\"/\" className={styles.logoLink} onClick={onClose}>\n {logo != null && (\n <img\n src={typeof logo === \"string\" ? logo : logo.light}\n alt={title}\n className={styles.logo}\n />\n )}\n </Link>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"0.5rem\" }}>\n {themeToggle && <ArdoThemeToggle />}\n <button\n type=\"button\"\n className={styles.mobilePanelClose}\n onClick={onClose}\n aria-label=\"Close menu\"\n >\n <XIcon size={20} />\n </button>\n </div>\n </div>\n\n {/* Nav links */}\n {nav != null && (\n <div className={styles.mobilePanelNav} onClickCapture={handleLinkClick(onClose)}>\n {nav}\n </div>\n )}\n\n {/* Sidebar content - wrapper overrides display:none from sidebar CSS */}\n <div className={styles.mobilePanelSidebar} onClickCapture={handleLinkClick(onClose)}>\n {children}\n </div>\n </div>\n </>\n )\n}\n\nfunction handleLinkClick(onClose: () => void) {\n return (event: React.MouseEvent<HTMLElement>) => {\n if (event.target instanceof HTMLElement && event.target.closest(\"a\") !== null) {\n onClose()\n }\n }\n}\n\n// =============================================================================\n// SocialLink Component\n// =============================================================================\n\nexport type ArdoSocialLinkProps = {\n /** URL to link to */\n href: string\n /** Social icon type */\n icon: \"discord\" | \"github\" | \"linkedin\" | \"npm\" | \"twitter\" | \"youtube\"\n /** Accessible label */\n ariaLabel?: string\n /** Additional CSS classes */\n className?: string\n}\n\nexport function ArdoSocialLink({ href, icon, ariaLabel, className }: ArdoSocialLinkProps) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={className ?? navStyles.socialLink}\n aria-label={ariaLabel ?? icon}\n >\n <SocialIcon icon={icon} />\n </a>\n )\n}\n\nconst socialIcons = {\n github: GithubIcon,\n twitter: TwitterIcon,\n discord: MessageCircleIcon,\n linkedin: LinkedinIcon,\n youtube: YoutubeIcon,\n npm: NpmIcon,\n} as const\n\nfunction SocialIcon({ icon }: { icon: keyof typeof socialIcons }) {\n const IconComponent = socialIcons[icon]\n return <IconComponent size={20} />\n}\n","import { style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"./theme/contract.css\"\n\nexport const sidebar = style({\n width: vars.layout.sidebarWidth,\n flexShrink: 0,\n display: \"flex\",\n minHeight: 0,\n borderRight: `1px solid ${vars.color.sidebarBorder}`,\n background: \"transparent\",\n \"@media\": {\n \"(max-width: 1024px)\": {\n display: \"none\",\n },\n },\n})\n\nexport const sidebarRail = style({\n width: \"4rem\",\n flexShrink: 0,\n padding: `${vars.space.md} 0`,\n borderRight: `1px solid ${vars.color.sidebarBorder}`,\n background: vars.color.bgSoft,\n})\n\nexport const sidebarRailItem = style({\n position: \"relative\",\n})\n\nexport const sidebarRailLabel = style({\n position: \"absolute\",\n left: \"calc(100% + 0.75rem)\",\n top: \"50%\",\n transform: \"translateY(-50%) translateX(-4px)\",\n padding: \"0.375rem 0.625rem\",\n background: vars.color.text,\n color: vars.color.bg,\n fontSize: vars.fontSize.xs,\n fontWeight: 500,\n borderRadius: vars.radius.sm,\n whiteSpace: \"nowrap\",\n pointerEvents: \"none\",\n opacity: 0,\n transition: `opacity ${vars.transition.fast}, transform ${vars.transition.fast}`,\n selectors: {\n [`${sidebarRailItem}:hover &`]: {\n opacity: 1,\n transform: \"translateY(-50%) translateX(0)\",\n transitionDelay: \"200ms\",\n },\n },\n zIndex: 50,\n})\n\nexport const sidebarRailList = style({\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: vars.space.xs,\n listStyle: \"none\",\n})\n\nexport const sidebarRailLink = style({\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"2.5rem\",\n height: \"2.5rem\",\n color: vars.color.textLight,\n borderRadius: vars.radius.base,\n textDecoration: \"none\",\n transition: `background ${vars.transition.fast}, color ${vars.transition.fast}, box-shadow ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n background: vars.color.bg,\n boxShadow: vars.color.shadowSm,\n },\n \"&.active\": {\n color: vars.color.brand,\n background: vars.color.brandSubtle,\n boxShadow: `inset 0 0 0 1px ${vars.color.borderLight}`,\n },\n \"&.active::before\": {\n content: '\"\"',\n position: \"absolute\",\n left: \"-0.75rem\",\n top: \"0.75rem\",\n bottom: \"0.75rem\",\n width: \"2px\",\n borderRadius: \"999px\",\n background: vars.color.brand,\n },\n },\n})\n\nexport const sidebarPanel = style({\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n flex: 1,\n padding: `${vars.space.md} ${vars.space.md} ${vars.space.md} 1.125rem`,\n})\n\nexport const sidebarHeader = style({\n flexShrink: 0,\n marginBottom: vars.space.lg,\n position: \"relative\",\n})\n\nexport const sidebarNav = style({\n flex: 1,\n overflowY: \"auto\",\n minHeight: 0,\n})\n\nexport const sidebarList = style({\n listStyle: \"none\",\n})\n\nexport const sidebarList0 = style({})\n\nexport const sidebarList1 = style({\n marginLeft: \"0.75rem\",\n marginTop: \"2px\",\n})\n\nexport const sidebarItem = style({})\n\n/**\n * Applied to `<li>` items that contain a collapsible group. Groups get\n * breathing room above them; plain links sit tight together (their own\n * padding provides the rhythm).\n */\nexport const sidebarItemGroup = style({\n selectors: {\n \"&:not(:first-child)\": {\n marginTop: vars.space.lg,\n },\n },\n})\n\nexport const sidebarItemHeader = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n})\n\nexport const sidebarLink = style({\n display: \"block\",\n padding: `0.375rem 0.75rem`,\n color: vars.color.textLight,\n textDecoration: \"none\",\n fontSize: vars.fontSize.sm,\n fontWeight: 400,\n borderLeft: \"2px solid transparent\",\n borderRadius: `0 ${vars.radius.base} ${vars.radius.base} 0`,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n background: vars.color.bgSoft,\n },\n \"&.active\": {\n color: vars.color.brand,\n background: vars.color.brandSubtle,\n borderLeftColor: vars.color.brand,\n fontWeight: 500,\n },\n },\n})\n\n// Section title (top-level group heading like \"Get started\", \"Organize\")\nexport const sidebarText = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: vars.space.sm,\n padding: `0.5rem 0.75rem 0.375rem`,\n color: vars.color.textLight,\n textDecoration: \"none\",\n fontWeight: 600,\n fontSize: vars.fontSize.sm,\n letterSpacing: \"-0.005em\",\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n },\n \"&.active\": {\n color: vars.color.brand,\n },\n \"&.child-active\": {\n color: vars.color.text,\n },\n },\n})\n\nexport const sidebarTextButton = style({\n width: \"100%\",\n background: \"none\",\n border: \"none\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n fontFamily: \"inherit\",\n lineHeight: \"inherit\",\n textAlign: \"left\",\n cursor: \"pointer\",\n})\n\nexport const sidebarCollapse = style({\n display: \"flex\",\n alignItems: \"center\",\n alignSelf: \"center\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: vars.space.xs,\n color: vars.color.textLighter,\n borderRadius: \"50%\",\n transition: `all ${vars.transition.base}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n },\n \"&.collapsed\": {\n transform: \"rotate(-90deg)\",\n },\n },\n})\n\nexport const sidebarCollapseWrapper = style({\n display: \"grid\",\n gridTemplateRows: \"1fr\",\n transition: `grid-template-rows ${vars.transition.slow}`,\n selectors: {\n '&[data-collapsed=\"true\"]': {\n gridTemplateRows: \"0fr\",\n },\n },\n})\n\nexport const sidebarCollapseInner = style({\n overflow: \"hidden\",\n minHeight: 0,\n})\n","import type { ComponentProps, ReactNode } from \"react\"\n\nimport { NavLink } from \"react-router\"\n\nimport type { ArdoContextItem, SidebarItem as SidebarItemType } from \"../config/types\"\n\nimport {\n BookOpenIcon,\n BoxIcon,\n CodeIcon,\n FileCodeIcon,\n FileTextIcon,\n PackageIcon,\n SettingsIcon,\n WrenchIcon,\n} from \"./icons\"\nimport * as styles from \"./Sidebar.css\"\n\ntype RoutePath = ComponentProps<typeof NavLink>[\"to\"]\n\nexport type SidebarRailItem = {\n key: string\n label: string\n to?: RoutePath\n icon?: ReactNode\n iconKey?: SidebarItemType[\"icon\"]\n active: boolean\n}\n\nexport function SidebarRail({ items }: { items: SidebarRailItem[] }) {\n if (items.length === 0) return null\n\n return (\n <nav aria-label=\"Documentation sections\" className={styles.sidebarRail}>\n <ul className={styles.sidebarRailList}>\n {items.map((item, index) => (\n <li key={item.key} className={styles.sidebarRailItem}>\n {item.to !== undefined ? (\n <NavLink\n to={item.to}\n aria-label={item.label}\n className={({ isActive }) =>\n [styles.sidebarRailLink, (item.active || isActive) && \"active\"]\n .filter(Boolean)\n .join(\" \")\n }\n >\n {resolveRailIcon(item, index)}\n </NavLink>\n ) : (\n <span className={styles.sidebarRailLink} aria-label={item.label}>\n {resolveRailIcon(item, index)}\n </span>\n )}\n <span className={styles.sidebarRailLabel} aria-hidden=\"true\">\n {item.label}\n </span>\n </li>\n ))}\n </ul>\n </nav>\n )\n}\n\nexport function getContextRailItems(\n contexts: ArdoContextItem[],\n activeId: string | undefined\n): SidebarRailItem[] {\n return contexts.map((ctx) => ({\n key: ctx.id,\n label: ctx.label,\n to: ctx.href,\n iconKey: inferContextIconKey(ctx),\n active: ctx.id === activeId,\n }))\n}\n\nfunction inferContextIconKey(ctx: ArdoContextItem): NonNullable<SidebarItemType[\"icon\"]> {\n const normalized = `${ctx.id} ${ctx.label}`.toLowerCase()\n if (normalized.includes(\"api\")) return \"api\"\n if (normalized.includes(\"component\")) return \"components\"\n if (normalized.includes(\"custom\") || normalized.includes(\"config\")) return \"settings\"\n if (normalized.includes(\"deploy\") || normalized.includes(\"trouble\")) return \"tools\"\n if (normalized.includes(\"guide\") || normalized.includes(\"intro\")) return \"guide\"\n if (normalized.includes(\"writing\") || normalized.includes(\"markdown\")) return \"docs\"\n return \"book\"\n}\n\nexport function getDataRailItems(items: SidebarItemType[], currentPath: string): SidebarRailItem[] {\n return items.map((item, index) => ({\n key: item.link ?? `${item.text}-${String(index)}`,\n label: item.text,\n to: item.link ?? findFirstItemLink(item.items ?? []),\n iconKey: item.icon,\n active: item.link === currentPath || hasActiveDataChild(item, currentPath),\n }))\n}\n\nexport function getTextLabel(children: ReactNode, fallback: string): string {\n if (typeof children === \"string\") return children\n if (typeof children === \"number\") return String(children)\n return fallback\n}\n\nfunction findFirstItemLink(items: SidebarItemType[]): string | undefined {\n for (const item of items) {\n if ((item.link ?? \"\") !== \"\") return item.link\n const nested = findFirstItemLink(item.items ?? [])\n if (nested !== undefined) return nested\n }\n return undefined\n}\n\nfunction hasActiveDataChild(item: SidebarItemType, currentPath: string): boolean {\n return (item.items ?? []).some(\n (child) => child.link === currentPath || hasActiveDataChild(child, currentPath)\n )\n}\n\nfunction resolveRailIcon(item: SidebarRailItem, index: number): ReactNode {\n if (item.icon !== undefined) return item.icon\n const iconKey = item.iconKey ?? inferIconKey(item.label, index)\n const Icon = iconByKey[iconKey]\n return <Icon size={18} strokeWidth={1.8} />\n}\n\nfunction inferIconKey(label: string, index: number): NonNullable<SidebarItemType[\"icon\"]> {\n const normalized = label.toLowerCase()\n if (normalized.includes(\"api\")) return \"api\"\n if (normalized.includes(\"component\")) return \"components\"\n if (normalized.includes(\"custom\") || normalized.includes(\"config\")) return \"settings\"\n if (normalized.includes(\"deploy\") || normalized.includes(\"trouble\")) return \"tools\"\n if (normalized.includes(\"writing\") || normalized.includes(\"markdown\")) return \"docs\"\n if (normalized.includes(\"intro\") || normalized.includes(\"guide\")) return \"guide\"\n return fallbackIconKeys[index % fallbackIconKeys.length]\n}\n\nconst iconByKey = {\n api: CodeIcon,\n book: BookOpenIcon,\n box: BoxIcon,\n code: FileCodeIcon,\n components: PackageIcon,\n docs: FileTextIcon,\n guide: BookOpenIcon,\n settings: SettingsIcon,\n tools: WrenchIcon,\n} satisfies Record<NonNullable<SidebarItemType[\"icon\"]>, typeof BookOpenIcon>\n\nconst fallbackIconKeys = [\n \"guide\",\n \"docs\",\n \"settings\",\n \"tools\",\n \"components\",\n \"box\",\n] satisfies Array<NonNullable<SidebarItemType[\"icon\"]>>\n","/* eslint-disable max-lines */\nimport {\n Children,\n type ComponentProps,\n createContext,\n isValidElement,\n type ReactElement,\n type ReactNode,\n use,\n useMemo,\n useState,\n} from \"react\"\nimport { NavLink, useLocation } from \"react-router\"\n\nimport type { SidebarItem as SidebarItemType } from \"../config/types\"\n\nimport { useArdoContexts, useArdoSidebar } from \"../runtime/hooks\"\nimport { ChevronDownIcon } from \"./icons\"\nimport * as styles from \"./Sidebar.css\"\nimport {\n getContextRailItems,\n getDataRailItems,\n getTextLabel,\n SidebarRail,\n type SidebarRailItem,\n} from \"./SidebarRail\"\n\n/** Route path type - uses React Router's NavLink 'to' prop type for type-safe routes */\ntype RoutePath = ComponentProps<typeof NavLink>[\"to\"]\n\n// =============================================================================\n// Sidebar Context\n// =============================================================================\n\ntype SidebarContextValue = {\n currentPath: string\n}\n\nconst SidebarContext = createContext<SidebarContextValue>({ currentPath: \"\" })\n\nfunction useSidebarContext() {\n return use(SidebarContext)\n}\n\n// =============================================================================\n// Sidebar Component Types\n// =============================================================================\n\nexport type ArdoSidebarProps = {\n /** Sidebar items (for data-driven approach) */\n items?: SidebarItemType[]\n /** Children for JSX composition (SidebarGroup, SidebarLink) */\n children?: ReactNode\n /** Content rendered above navigation (e.g. search) */\n header?: ReactNode\n /** Additional CSS classes */\n className?: string\n}\n\n// =============================================================================\n// Sidebar Main Component\n// =============================================================================\n\n/**\n * Sidebar component supporting data-driven, JSX composition, and zero-config patterns.\n *\n * When neither `items` nor `children` are provided, automatically renders from\n * the Ardo sidebar context (`virtual:ardo/sidebar`).\n *\n * @example Zero-config (from context)\n * ```tsx\n * <Sidebar />\n * ```\n *\n * @example Data-driven (items prop)\n * ```tsx\n * <Sidebar items={[\n * { text: 'Introduction', link: '/intro' },\n * { text: 'Guide', items: [\n * { text: 'Getting Started', link: '/guide/getting-started' }\n * ]}\n * ]} />\n * ```\n *\n * @example JSX composition\n * ```tsx\n * <Sidebar>\n * <SidebarLink to=\"/intro\">Introduction</SidebarLink>\n * <SidebarGroup title=\"Guide\">\n * <SidebarLink to=\"/guide/getting-started\">Getting Started</SidebarLink>\n * </SidebarGroup>\n * </Sidebar>\n * ```\n */\nexport function ArdoSidebar({ items, children, header, className }: ArdoSidebarProps) {\n const { pathname } = useLocation()\n const contextSidebar = useArdoSidebar()\n const { items: contexts, activeId } = useArdoContexts()\n const hasCustomChildren = children != null\n const resolvedItems = items ?? (hasCustomChildren ? undefined : contextSidebar)\n const hasResolvedItems = (resolvedItems?.length ?? 0) > 0\n // If contexts are configured, the rail is the world-switcher; otherwise\n // fall back to the legacy \"mirror sidebar sections as icons\" behaviour.\n const railItems =\n contexts.length > 0\n ? getContextRailItems(contexts, activeId)\n : hasCustomChildren\n ? getRailItemsFromChildren(children, pathname)\n : getDataRailItems(resolvedItems ?? [], pathname)\n const contextValue = useMemo(() => ({ currentPath: pathname }), [pathname])\n\n return (\n <SidebarContext value={contextValue}>\n <aside className={className ?? styles.sidebar}>\n <SidebarRail items={railItems} />\n <div className={styles.sidebarPanel}>\n {header != null && <div className={styles.sidebarHeader}>{header}</div>}\n <nav aria-label=\"Main navigation\" className={styles.sidebarNav}>\n {hasCustomChildren ? (\n <ul className={`${styles.sidebarList} ${styles.sidebarList0}`}>{children}</ul>\n ) : hasResolvedItems ? (\n <SidebarItems items={resolvedItems ?? []} depth={0} />\n ) : null}\n </nav>\n </div>\n </aside>\n </SidebarContext>\n )\n}\n\n// =============================================================================\n// SidebarGroup Component\n// =============================================================================\n\nexport type ArdoSidebarGroupProps = {\n /** Group title */\n title: string\n /** Optional icon shown in the desktop section rail */\n icon?: ReactNode\n /** Optional link for the group title */\n to?: string\n /** Initial collapsed state (default: false) */\n collapsed?: boolean\n /** Whether group is collapsible (default: true if has children) */\n collapsible?: boolean\n /** Children (SidebarLink, nested SidebarGroup) */\n children?: ReactNode\n /** Additional CSS classes */\n className?: string\n}\n\n/**\n * Group component for organizing sidebar links.\n *\n * @example\n * ```tsx\n * <SidebarGroup title=\"Guide\">\n * <SidebarLink to=\"/guide/intro\">Introduction</SidebarLink>\n * <SidebarLink to=\"/guide/setup\">Setup</SidebarLink>\n * </SidebarGroup>\n * ```\n *\n * @example With collapsible state\n * ```tsx\n * <SidebarGroup title=\"Advanced\" collapsed>\n * <SidebarLink to=\"/advanced/config\">Configuration</SidebarLink>\n * </SidebarGroup>\n * ```\n */\nexport function ArdoSidebarGroup({\n title,\n to,\n collapsed: initialCollapsed = false,\n collapsible = true,\n children,\n className,\n}: ArdoSidebarGroupProps) {\n const [collapsed, setCollapsed] = useState(initialCollapsed)\n const { currentPath } = useSidebarContext()\n\n // Check if any child is active\n const hasActiveChild = checkChildrenActive(children, currentPath)\n\n const textClassName = [styles.sidebarText, hasActiveChild && \"child-active\"]\n .filter(Boolean)\n .join(\" \")\n const textButtonClassName = [textClassName, styles.sidebarTextButton].join(\" \")\n\n const hasChildren = Children.count(children) > 0\n const hasTo = (to ?? \"\") !== \"\"\n const canToggle = collapsible && hasChildren\n\n const itemClassName =\n className ??\n [styles.sidebarItem, hasChildren && styles.sidebarItemGroup].filter(Boolean).join(\" \")\n\n return (\n <li className={itemClassName}>\n <div className={styles.sidebarItemHeader}>\n {hasTo ? (\n <NavLink\n to={to ?? \"/\"}\n end\n className={({ isActive }) =>\n [textClassName, isActive && \"active\"].filter(Boolean).join(\" \")\n }\n >\n {title}\n </NavLink>\n ) : (\n <button\n type=\"button\"\n className={textButtonClassName}\n onClick={() => {\n if (canToggle) {\n setCollapsed(!collapsed)\n }\n }}\n >\n {title}\n </button>\n )}\n\n {canToggle && (\n <button\n type=\"button\"\n className={[styles.sidebarCollapse, collapsed && \"collapsed\"].filter(Boolean).join(\" \")}\n onClick={() => {\n setCollapsed(!collapsed)\n }}\n aria-label={collapsed ? \"Expand\" : \"Collapse\"}\n >\n <ChevronDownIcon size={16} />\n </button>\n )}\n </div>\n\n {hasChildren && (\n <div className={styles.sidebarCollapseWrapper} data-collapsed={collapsed}>\n <div className={styles.sidebarCollapseInner}>\n <ul className={`${styles.sidebarList} ${styles.sidebarList1}`}>{children}</ul>\n </div>\n </div>\n )}\n </li>\n )\n}\n\n// =============================================================================\n// SidebarLink Component\n// =============================================================================\n\nexport type ArdoSidebarLinkProps = {\n /** Internal route path (type-safe with React Router's registered routes) */\n to: RoutePath\n /** Link text */\n children: ReactNode\n /** Additional CSS classes */\n className?: string\n}\n\n/**\n * Sidebar navigation link.\n *\n * @example\n * ```tsx\n * <SidebarLink to=\"/guide/getting-started\">Getting Started</SidebarLink>\n * ```\n */\nexport function ArdoSidebarLink({ to, children, className }: ArdoSidebarLinkProps) {\n const baseClassName = className ?? styles.sidebarLink\n return (\n <li className={styles.sidebarItem}>\n <NavLink\n to={to}\n className={({ isActive }) =>\n [baseClassName, isActive && \"active\"].filter(Boolean).join(\" \")\n }\n >\n {children}\n </NavLink>\n </li>\n )\n}\n\n// =============================================================================\n// Internal: Data-driven sidebar rendering\n// =============================================================================\n\ntype SidebarItemsProps = {\n items: SidebarItemType[]\n depth: number\n}\n\nfunction SidebarItems({ items, depth }: SidebarItemsProps) {\n return (\n <ul\n className={`${styles.sidebarList} ${depth === 0 ? styles.sidebarList0 : styles.sidebarList1}`}\n >\n {items.map((item) => (\n <SidebarItemComponent\n key={item.link ?? `${item.text}-${String(depth)}`}\n item={item}\n depth={depth}\n />\n ))}\n </ul>\n )\n}\n\ntype SidebarItemComponentProps = {\n item: SidebarItemType\n depth: number\n}\n\nfunction SidebarItemComponent({ item, depth }: SidebarItemComponentProps) {\n const { currentPath } = useSidebarContext()\n const [collapsed, setCollapsed] = useState(item.collapsed ?? false)\n const childItems = item.items ?? []\n\n const hasChildren = childItems.length > 0\n\n const hasActiveChild =\n hasChildren &&\n childItems.some(\n (child) =>\n child.link === currentPath ||\n child.items?.some((grandchild) => grandchild.link === currentPath)\n )\n const hasItemLink = (item.link ?? \"\") !== \"\"\n\n const linkClassName = [styles.sidebarLink, hasActiveChild && \"child-active\"]\n .filter(Boolean)\n .join(\" \")\n\n const textClassName = [styles.sidebarText, hasActiveChild && \"child-active\"]\n .filter(Boolean)\n .join(\" \")\n const textButtonClassName = [textClassName, styles.sidebarTextButton].join(\" \")\n\n const itemClassName = [styles.sidebarItem, hasChildren && styles.sidebarItemGroup]\n .filter(Boolean)\n .join(\" \")\n\n return (\n <li className={itemClassName}>\n <div className={styles.sidebarItemHeader}>\n {hasItemLink ? (\n <NavLink\n to={item.link ?? \"/\"}\n className={({ isActive }) =>\n [linkClassName, isActive && \"active\"].filter(Boolean).join(\" \")\n }\n >\n {item.text}\n </NavLink>\n ) : (\n <button\n type=\"button\"\n className={textButtonClassName}\n onClick={() => {\n if (hasChildren) {\n setCollapsed(!collapsed)\n }\n }}\n >\n {item.text}\n </button>\n )}\n\n {hasChildren && (\n <button\n type=\"button\"\n className={[styles.sidebarCollapse, collapsed && \"collapsed\"].filter(Boolean).join(\" \")}\n onClick={() => {\n setCollapsed(!collapsed)\n }}\n aria-label={collapsed ? \"Expand\" : \"Collapse\"}\n >\n <ChevronDownIcon size={16} />\n </button>\n )}\n </div>\n\n {hasChildren && (\n <div className={styles.sidebarCollapseWrapper} data-collapsed={collapsed}>\n <div className={styles.sidebarCollapseInner}>\n <SidebarItems items={childItems} depth={depth + 1} />\n </div>\n </div>\n )}\n </li>\n )\n}\n\n// =============================================================================\n// Sidebar Rail Data\n// =============================================================================\n\nfunction getRailItemsFromChildren(children: ReactNode, currentPath: string): SidebarRailItem[] {\n return Children.toArray(children)\n .filter(isValidElement)\n .map((child, index): SidebarRailItem | undefined => {\n if (isSidebarGroupElement(child)) {\n const { title, to, icon } = child.props\n return {\n key: to ?? title,\n label: title,\n to: to ?? findFirstChildLink(child.props.children),\n icon,\n active: to === currentPath || checkChildrenActive(child.props.children, currentPath),\n }\n }\n\n if (isSidebarLinkElement(child)) {\n const label = getTextLabel(child.props.children, `Section ${String(index + 1)}`)\n return {\n key: `${label}-${String(index)}`,\n label,\n to: child.props.to,\n active: child.props.to === currentPath,\n }\n }\n\n return undefined\n })\n .filter((item): item is SidebarRailItem => item !== undefined)\n}\n\nfunction findFirstChildLink(children: ReactNode): RoutePath | undefined {\n for (const child of Children.toArray(children)) {\n if (!isValidElement(child)) continue\n if (isSidebarLinkElement(child)) return child.props.to\n if (isSidebarGroupElement(child)) return findFirstGroupLink(child)\n }\n return undefined\n}\n\nfunction findFirstGroupLink(child: ReactElement<ArdoSidebarGroupProps>): RoutePath | undefined {\n if ((child.props.to ?? \"\") !== \"\") return child.props.to\n return findFirstChildLink(child.props.children)\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\nfunction isSidebarChildActive(child: ReactElement, currentPath: string): boolean {\n if (isSidebarLinkElement(child)) {\n return child.props.to === currentPath\n }\n if (isSidebarGroupElement(child)) {\n const groupProps = child.props\n return (\n groupProps.to === currentPath ||\n (groupProps.children != null && checkChildrenActive(groupProps.children, currentPath))\n )\n }\n return false\n}\n\nfunction checkChildrenActive(children: ReactNode, currentPath: string): boolean {\n return Children.toArray(children).some(\n (child) => isValidElement(child) && isSidebarChildActive(child, currentPath)\n )\n}\n\nfunction isSidebarLinkElement(child: ReactElement): child is ReactElement<ArdoSidebarLinkProps> {\n return child.type === ArdoSidebarLink\n}\n\nfunction isSidebarGroupElement(child: ReactElement): child is ReactElement<ArdoSidebarGroupProps> {\n return child.type === ArdoSidebarGroup\n}\n","import { cloneElement, isValidElement, type ReactNode, useMemo } from \"react\"\nimport { Outlet, useLocation, useMatches } from \"react-router\"\n\nimport type { ArdoConfig, ArdoContextItem, SidebarItem } from \"../config/types\"\n\nimport { ArdoProvider, type ArdoSiteConfig, ArdoSiteConfigProvider } from \"../runtime/hooks\"\nimport { ArdoFooter, type ArdoFooterProps } from \"./Footer\"\nimport { ArdoHeader, type ArdoHeaderProps } from \"./Header\"\nimport { ArdoLayout } from \"./Layout\"\nimport * as layoutStyles from \"./Layout.css\"\nimport { ArdoSidebar, type ArdoSidebarProps } from \"./Sidebar\"\n\n// =============================================================================\n// ArdoRoot Component\n// =============================================================================\n\nexport type ArdoRootProps = {\n /** Ardo config (from virtual:ardo/config) */\n config: ArdoConfig\n /**\n * Sidebar data.\n *\n * - `SidebarItem[]` — a single sidebar shown for every non-bare route\n * (from `virtual:ardo/sidebar`, back-compat).\n * - `Record<string, SidebarItem[]>` — a per-context sidebar map\n * (from `virtual:ardo/sidebars`). The active context's sidebar is\n * shown; the key matches the `id` of the matching `ArdoContextItem`.\n */\n sidebar: Record<string, SidebarItem[]> | SidebarItem[]\n /**\n * Top-level navigation contexts shown in the sidebar rail. When provided,\n * the rail renders these as world-switcher items and `sidebar` is treated\n * as a map keyed by context id.\n */\n contexts?: ArdoContextItem[]\n /** Custom header element (overrides auto-generated header) */\n header?: ReactNode\n /** Custom sidebar element (overrides auto-generated sidebar) */\n sidebarContent?: ReactNode\n /** Custom footer element (overrides auto-generated footer) */\n footer?: ReactNode\n /** Props passed to auto-generated ArdoHeader (ignored when header is provided) */\n headerProps?: ArdoHeaderProps\n /** Props passed to auto-generated ArdoSidebar (ignored when sidebarContent is provided) */\n sidebarProps?: ArdoSidebarProps\n /** Props passed to auto-generated ArdoFooter (ignored when footer is provided) */\n footerProps?: ArdoFooterProps\n /** Edit link configuration (applied site-wide via ArdoSiteConfig) */\n editLink?: { pattern: string; text?: string }\n /** Last updated configuration (applied site-wide via ArdoSiteConfig) */\n lastUpdated?: { enabled?: boolean; text?: string; formatOptions?: Intl.DateTimeFormatOptions }\n /** TOC label (applied site-wide via ArdoSiteConfig) */\n tocLabel?: string\n /** Additional CSS classes for the layout */\n className?: string\n /** Content to render (defaults to <Outlet />) */\n children?: ReactNode\n}\n\n/**\n * All-in-one root component that combines ArdoProvider, Layout, Header,\n * Sidebar, Footer, and homepage detection into a single component.\n *\n * @example Minimal usage\n * ```tsx\n * import config from \"virtual:ardo/config\"\n * import sidebar from \"virtual:ardo/sidebar\"\n *\n * export default function Root() {\n * return <ArdoRoot config={config} sidebar={sidebar} />\n * }\n * ```\n *\n * @example With custom nav and footer overrides\n * ```tsx\n * export default function Root() {\n * return (\n * <ArdoRoot\n * config={config}\n * sidebar={sidebar}\n * headerProps={{\n * nav: (\n * <Nav>\n * <NavLink to=\"/guide\">Guide</NavLink>\n * <NavLink to=\"/api\">API</NavLink>\n * </Nav>\n * ),\n * }}\n * footerProps={{\n * message: \"Released under the MIT License.\",\n * }}\n * editLink={{\n * pattern: \"https://github.com/user/repo/edit/main/docs/:path\",\n * text: \"Edit this page on GitHub\",\n * }}\n * lastUpdated={{ enabled: true }}\n * />\n * )\n * }\n * ```\n */\nfunction resolveRootHeader(\n header: ReactNode,\n headerProps: ArdoHeaderProps | undefined,\n mobileMenuContent: ReactNode\n): ReactNode {\n if (header != null) {\n return enhanceHeaderWithMobileMenuContent(header, mobileMenuContent)\n }\n return (\n <ArdoHeader\n {...headerProps}\n mobileMenuContent={headerProps?.mobileMenuContent ?? mobileMenuContent}\n />\n )\n}\n\nfunction resolveLayoutClassName(className: string | undefined, isBareLayout: boolean): string {\n if (className != null) return className\n return isBareLayout ? `${layoutStyles.layout} ${layoutStyles.home}` : layoutStyles.layout\n}\n\nfunction readLayoutHandle(handle: unknown): string | undefined {\n if (typeof handle !== \"object\" || handle === null) return undefined\n if (!(\"layout\" in handle)) return undefined\n const { layout } = handle\n return typeof layout === \"string\" ? layout : undefined\n}\n\n/**\n * Reads the React Router `handle` exports from every active route match and\n * returns the most specific `layout` value (the deepest match wins). MDX\n * routes get this export auto-generated from `frontmatter.layout`; .tsx\n * routes set it directly with `export const handle = { layout: \"bare\" }`.\n */\nfunction useRouteLayout(): string | undefined {\n const matches = useMatches()\n for (let i = matches.length - 1; i >= 0; i--) {\n const layout = readLayoutHandle(matches[i].handle)\n if (layout !== undefined) return layout\n }\n return undefined\n}\n\nfunction contextMatchesPath(ctx: ArdoContextItem, pathname: string): boolean {\n if (ctx.match != null) {\n return typeof ctx.match === \"string\" ? pathname.startsWith(ctx.match) : ctx.match.test(pathname)\n }\n const firstSegment = ctx.href.split(\"/\").find((segment) => segment !== \"\")\n if (firstSegment === undefined) return false\n const root = `/${firstSegment}`\n return pathname === root || pathname.startsWith(`${root}/`)\n}\n\nfunction findActiveContext(\n contexts: ArdoContextItem[] | undefined,\n pathname: string\n): ArdoContextItem | undefined {\n return contexts?.find((ctx) => contextMatchesPath(ctx, pathname))\n}\n\nfunction resolveContextSidebar(\n sidebar: Record<string, SidebarItem[]> | SidebarItem[],\n activeContext: ArdoContextItem | undefined\n): SidebarItem[] {\n if (Array.isArray(sidebar)) return sidebar\n if (activeContext == null) return []\n return sidebar[activeContext.id] ?? []\n}\n\nexport function ArdoRoot({\n config,\n sidebar,\n contexts,\n header,\n sidebarContent,\n footer,\n headerProps,\n sidebarProps,\n footerProps,\n editLink,\n lastUpdated,\n tocLabel,\n className,\n children,\n}: ArdoRootProps) {\n const location = useLocation()\n const layout = useRouteLayout()\n // Bare layout: no sidebar, no rail — used for the home page and any other\n // marketing-style routes (TSX or MDX). Falls back to the legacy hardcoded\n // home detection if a route hasn't opted in via `handle.layout`.\n const isBareLayout = layout === \"bare\" || location.pathname === \"/\" || location.pathname === \"\"\n const activeContext = useMemo(\n () => findActiveContext(contexts, location.pathname),\n [contexts, location.pathname]\n )\n const sidebarItems = useMemo(\n () => resolveContextSidebar(sidebar, activeContext),\n [sidebar, activeContext]\n )\n // Search lives in the header now. The sidebar no longer carries it.\n const resolvedSidebar = isBareLayout ? undefined : resolveSidebar(sidebarContent, sidebarProps)\n const resolvedHeader = resolveRootHeader(\n header,\n headerProps,\n isBareLayout ? undefined : resolvedSidebar\n )\n\n const siteConfig = useMemo<ArdoSiteConfig>(\n () => ({ editLink, lastUpdated, tocLabel }),\n [editLink, lastUpdated, tocLabel]\n )\n\n const content = (\n <ArdoProvider\n config={config}\n sidebar={sidebarItems}\n contexts={contexts}\n activeContextId={activeContext?.id}\n >\n <ArdoLayout\n className={resolveLayoutClassName(className, isBareLayout)}\n header={resolvedHeader}\n sidebar={resolvedSidebar}\n footer={footer ?? <ArdoFooter {...footerProps} />}\n >\n {children ?? <Outlet />}\n </ArdoLayout>\n </ArdoProvider>\n )\n\n const hasSiteConfig =\n editLink !== undefined || lastUpdated !== undefined || (tocLabel ?? \"\") !== \"\"\n return hasSiteConfig ? (\n <ArdoSiteConfigProvider value={siteConfig}>{content}</ArdoSiteConfigProvider>\n ) : (\n content\n )\n}\n\n/**\n * Resolves the sidebar element. Custom content is passed through as-is;\n * when none is given, a default data-driven <ArdoSidebar> is created.\n */\nfunction resolveSidebar(\n sidebarContent: ReactNode | undefined,\n sidebarProps: ArdoSidebarProps | undefined\n): ReactNode {\n if (sidebarContent == null) {\n return <ArdoSidebar {...sidebarProps} />\n }\n if (isValidElement(sidebarContent)) {\n return sidebarContent\n }\n return <ArdoSidebar>{sidebarContent}</ArdoSidebar>\n}\n\nfunction enhanceHeaderWithMobileMenuContent(\n header: ReactNode,\n mobileMenuContent: ReactNode\n): ReactNode {\n if (!isValidElement<ArdoHeaderProps>(header) || header.type !== ArdoHeader) {\n return header\n }\n\n const existingMobileMenuContent = header.props.mobileMenuContent\n if (existingMobileMenuContent !== undefined) {\n return header\n }\n\n return cloneElement(header, { mobileMenuContent })\n}\n","import { globalStyle, style } from \"@vanilla-extract/css\"\n\nimport { fadeInUp } from \"../theme/animations.css\"\nimport { vars } from \"../theme/contract.css\"\n\nconst brandBorder = `color-mix(in oklch, ${vars.color.brand} 38%, ${vars.color.border})`\nconst brandRing = `color-mix(in oklch, ${vars.color.brand} 12%, transparent)`\n\nexport const features = style({\n padding: \"80px 24px\",\n background: vars.color.bgSoft,\n borderTop: `1px solid ${vars.color.border}`,\n \"@media\": {\n \"(max-width: 768px)\": {\n padding: \"48px 16px\",\n },\n },\n})\n\nexport const featuresHeader = style({\n textAlign: \"center\",\n marginBottom: \"48px\",\n})\n\nexport const featuresTitle = style({\n fontSize: \"36px\",\n fontWeight: 700,\n letterSpacing: \"-0.02em\",\n marginBottom: \"12px\",\n textWrap: \"balance\",\n \"@media\": {\n \"(max-width: 768px)\": {\n fontSize: \"28px\",\n },\n },\n})\n\nexport const featuresSubtitle = style({\n fontSize: \"18px\",\n color: vars.color.textLight,\n maxWidth: \"560px\",\n margin: \"0 auto\",\n textWrap: \"pretty\",\n \"@media\": {\n \"(max-width: 768px)\": {\n fontSize: \"16px\",\n },\n },\n})\n\nexport const featuresContainer = style({\n display: \"grid\",\n gridTemplateColumns: \"repeat(auto-fit, minmax(260px, 1fr))\",\n gap: \"20px\",\n maxWidth: \"1100px\",\n margin: \"0 auto\",\n})\n\nexport const feature = style({\n padding: \"28px\",\n background: vars.color.bg,\n borderRadius: vars.radius.lg,\n border: `1px solid ${vars.color.border}`,\n boxShadow: vars.color.shadowSm,\n transition: `all ${vars.transition.base}`,\n animation: `${fadeInUp} 0.5s ease both`,\n selectors: {\n \"&:hover\": {\n borderColor: brandBorder,\n boxShadow: `${vars.color.shadowMd}, 0 0 0 1px ${brandRing}`,\n },\n },\n \"@media\": {\n \"(hover: hover)\": {\n selectors: {\n \"&:hover\": {\n transform: \"translateY(-3px)\",\n },\n },\n },\n \"(prefers-reduced-motion: reduce)\": {\n animation: \"none\",\n selectors: {\n \"&:hover\": {\n transform: \"none\",\n },\n },\n },\n },\n})\n\n// Stagger animation delays\nfor (let i = 1; i <= 6; i++) {\n globalStyle(`${featuresContainer} ${feature}:nth-child(${i})`, {\n animationDelay: `${(i - 1) * 80}ms`,\n })\n}\n\nexport const featureIcon = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"48px\",\n height: \"48px\",\n marginBottom: \"16px\",\n background: vars.color.brandSubtle,\n border: `1px solid color-mix(in oklch, ${vars.color.brand} 16%, ${vars.color.border})`,\n borderRadius: \"50%\",\n color: vars.color.brand,\n transition: `all ${vars.transition.base}`,\n})\n\nglobalStyle(`${feature}:hover ${featureIcon}`, {\n background: vars.color.brand,\n color: \"white\",\n borderColor: \"transparent\",\n})\n\nexport const featureTitle = style({\n fontSize: \"17px\",\n fontWeight: 600,\n marginBottom: \"10px\",\n letterSpacing: \"-0.01em\",\n textWrap: \"balance\",\n})\n\nexport const featureDetails = style({\n fontSize: \"14px\",\n color: vars.color.textLight,\n lineHeight: 1.6,\n marginBottom: \"12px\",\n textWrap: \"pretty\",\n})\n\nexport const featureLink = style({\n fontSize: \"14px\",\n fontWeight: 500,\n color: vars.color.brand,\n textDecoration: \"none\",\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n transition: `gap ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n gap: \"8px\",\n },\n \"&::after\": {\n content: '\"\\\\2192\"',\n },\n },\n})\n","import type { ReactNode } from \"react\"\n\nimport { Link } from \"react-router\"\n\nimport * as styles from \"./Features.css\"\n\nexport type ArdoFeaturesProps = {\n /** Feature cards as children */\n children: ReactNode\n /** Section title */\n title?: string\n /** Section subtitle */\n subtitle?: string\n /** Additional CSS class */\n className?: string\n}\n\nexport type ArdoFeatureCardProps = {\n /** Feature title */\n title: string\n /** Icon as ReactNode (emoji, Lucide icon component, or any JSX) */\n icon?: ReactNode\n /** Feature description as children */\n children: ReactNode\n /** Optional link */\n link?: string\n /** Link text (defaults to \"Learn more\") */\n linkText?: string\n /** Additional CSS class */\n className?: string\n}\n\n/**\n * Individual feature card component.\n *\n * @example\n * ```tsx\n * import { Zap } from \"lucide-react\"\n *\n * <ArdoFeatureCard title=\"Fast\" icon={<Zap size={28} />}>\n * Lightning fast builds with Vite\n * </ArdoFeatureCard>\n * ```\n */\nexport function ArdoFeatureCard({\n title,\n icon,\n children,\n link,\n linkText,\n className,\n}: ArdoFeatureCardProps) {\n const hasIcon = icon != null\n const hasLink = (link ?? \"\") !== \"\"\n const resolvedLinkText = linkText ?? \"Learn more\"\n\n return (\n <div className={className ?? styles.feature}>\n {hasIcon && <div className={styles.featureIcon}>{icon}</div>}\n <h3 className={styles.featureTitle}>{title}</h3>\n <p className={styles.featureDetails}>{children}</p>\n {hasLink && (\n <Link to={link ?? \"\"} className={styles.featureLink}>\n {resolvedLinkText}\n </Link>\n )}\n </div>\n )\n}\n\n/**\n * Features grid component for displaying multiple feature cards.\n *\n * @example\n * ```tsx\n * <ArdoFeatures title=\"Key Features\" subtitle=\"Everything you need\">\n * <ArdoFeatureCard title=\"React-First\" icon=\"⚛️\">Built on React.</ArdoFeatureCard>\n * <ArdoFeatureCard title=\"Fast\" icon=\"⚡\">Powered by Vite.</ArdoFeatureCard>\n * </ArdoFeatures>\n * ```\n */\nexport function ArdoFeatures({ children, title, subtitle, className }: ArdoFeaturesProps) {\n const hasTitle = (title ?? \"\") !== \"\"\n const hasSubtitle = (subtitle ?? \"\") !== \"\"\n const hasHeader = hasTitle || hasSubtitle\n\n return (\n <section className={className ?? styles.features}>\n {hasHeader && (\n <div className={styles.featuresHeader}>\n {hasTitle && <h2 className={styles.featuresTitle}>{title}</h2>}\n {hasSubtitle && <p className={styles.featuresSubtitle}>{subtitle}</p>}\n </div>\n )}\n <div className={styles.featuresContainer}>{children}</div>\n </section>\n )\n}\n","import { globalStyle, style } from \"@vanilla-extract/css\"\n\nimport { fadeInUp } from \"../theme/animations.css\"\nimport { vars } from \"../theme/contract.css\"\n\nconst brandHalo = `color-mix(in oklch, ${vars.color.brand} 26%, transparent)`\nconst brandHaloStrong = `color-mix(in oklch, ${vars.color.brand} 36%, transparent)`\nconst brandTint = `color-mix(in oklch, ${vars.color.brand} 10%, transparent)`\nconst brandTintSoft = `color-mix(in oklch, ${vars.color.brand} 6%, transparent)`\n\nexport const hero = style({\n padding: \"100px 24px 80px\",\n textAlign: \"center\",\n position: \"relative\",\n overflow: \"hidden\",\n selectors: {\n \"&::before\": {\n content: '\"\"',\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background: `radial-gradient(ellipse 60% 50% at 30% 0%, ${brandTintSoft} 0%, transparent 60%), radial-gradient(ellipse 80% 50% at 70% -10%, ${brandTint} 0%, transparent 70%), linear-gradient(180deg, ${vars.color.bg} 0%, ${vars.color.bgSoft} 100%)`,\n pointerEvents: \"none\",\n },\n \".dark &::before\": {\n background: `radial-gradient(ellipse 60% 50% at 30% 0%, color-mix(in oklch, ${vars.color.brand} 12%, transparent) 0%, transparent 60%), radial-gradient(ellipse 80% 50% at 70% -10%, color-mix(in oklch, ${vars.color.brand} 18%, transparent) 0%, transparent 70%), linear-gradient(180deg, ${vars.color.bg} 0%, ${vars.color.bgSoft} 100%)`,\n },\n },\n \"@media\": {\n \"(max-width: 768px)\": {\n padding: \"60px 20px\",\n },\n },\n})\n\nexport const heroContainer = style({\n maxWidth: \"800px\",\n margin: \"0 auto\",\n position: \"relative\",\n zIndex: 1,\n})\n\nexport const heroAnimate = style({\n animation: `${fadeInUp} 0.6s ease both`,\n \"@media\": {\n \"(prefers-reduced-motion: reduce)\": {\n animation: \"none\",\n },\n },\n})\n\nglobalStyle(`${hero} img`, {\n maxWidth: \"180px\",\n marginBottom: \"40px\",\n filter: \"drop-shadow(0 4px 18px oklch(0 0 0 / 0.12))\",\n})\n\nexport const heroVersion = style({\n display: \"inline-block\",\n padding: \"4px 14px\",\n fontSize: \"13px\",\n fontWeight: 600,\n color: vars.color.brand,\n background: vars.color.brandSubtle,\n border: `1px solid color-mix(in oklch, ${vars.color.brand} 20%, ${vars.color.border})`,\n borderRadius: \"999px\",\n marginBottom: \"16px\",\n letterSpacing: \"0.02em\",\n})\n\nexport const heroName = style({\n fontSize: \"64px\",\n fontWeight: 800,\n background: vars.color.brandGradient,\n WebkitBackgroundClip: \"text\",\n WebkitTextFillColor: \"transparent\",\n backgroundClip: \"text\",\n letterSpacing: \"-0.03em\",\n lineHeight: 1.1,\n textWrap: \"balance\",\n \"@media\": {\n \"(max-width: 768px)\": {\n fontSize: \"40px\",\n },\n },\n})\n\nexport const heroText = style({\n fontSize: \"48px\",\n fontWeight: 700,\n marginTop: \"8px\",\n letterSpacing: \"-0.02em\",\n lineHeight: 1.15,\n textWrap: \"balance\",\n \"@media\": {\n \"(max-width: 768px)\": {\n fontSize: \"28px\",\n },\n },\n})\n\nexport const heroTagline = style({\n fontSize: \"18px\",\n color: vars.color.textLight,\n marginTop: \"24px\",\n maxWidth: \"560px\",\n marginLeft: \"auto\",\n marginRight: \"auto\",\n lineHeight: 1.65,\n textWrap: \"pretty\",\n \"@media\": {\n \"(max-width: 768px)\": {\n fontSize: \"16px\",\n },\n },\n})\n\nexport const heroActions = style({\n display: \"flex\",\n justifyContent: \"center\",\n gap: \"16px\",\n marginTop: \"40px\",\n flexWrap: \"wrap\",\n})\n\nexport const heroAction = style({\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"14px 28px\",\n fontSize: \"15px\",\n fontWeight: 600,\n textDecoration: \"none\",\n borderRadius: vars.radius.base,\n transition: `all ${vars.transition.base}`,\n})\n\nexport const heroActionBrand = style({\n background: vars.color.brand,\n color: \"white\",\n boxShadow: `0 4px 14px ${brandHalo}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.brandDark,\n boxShadow: `0 6px 20px ${brandHaloStrong}`,\n },\n },\n \"@media\": {\n \"(hover: hover)\": {\n selectors: {\n \"&:hover\": {\n transform: \"translateY(-2px)\",\n },\n },\n },\n \"(prefers-reduced-motion: reduce)\": {\n selectors: {\n \"&:hover\": {\n transform: \"none\",\n },\n },\n },\n },\n})\n\nexport const heroActionAlt = style({\n background: vars.color.bg,\n color: vars.color.text,\n border: `1px solid ${vars.color.border}`,\n selectors: {\n \"&:hover\": {\n borderColor: vars.color.brand,\n color: vars.color.brand,\n },\n },\n})\n","import type { ComponentProps, ReactNode } from \"react\"\n\nimport { Link } from \"react-router\"\n\nimport * as styles from \"./Hero.css\"\n\n/** Internal route path from React Router */\ntype RoutePath = ComponentProps<typeof Link>[\"to\"]\n\nexport type ArdoHeroAction = {\n /** Button text */\n text: string\n /** Link destination - internal route path or external URL */\n link: RoutePath\n /** Visual theme: \"brand\" for primary, \"alt\" for secondary */\n theme?: \"alt\" | \"brand\"\n /** Optional icon as ReactNode (e.g. Lucide icon component) */\n icon?: ReactNode\n}\n\nexport type ArdoHeroImage = {\n /** Image for light mode */\n light: string\n /** Image for dark mode */\n dark?: string\n /** Alt text for the image */\n alt?: string\n}\n\nexport type ArdoHeroProps = {\n /** Large title displayed prominently */\n name?: string\n /** Secondary text below the name */\n text?: string\n /** Descriptive tagline */\n tagline?: string\n /** Hero image - can be a string URL or an object with light/dark variants */\n image?: ArdoHeroImage | string\n /** Call-to-action buttons */\n actions?: ArdoHeroAction[]\n /** Additional CSS class */\n className?: string\n /** Version string displayed as a pill badge above the name */\n version?: string\n}\n\n/**\n * Hero section component for landing pages.\n *\n * @example\n * ```tsx\n * import { ArrowRight, Github } from \"lucide-react\"\n *\n * <Hero\n * name=\"Ardo\"\n * text=\"React-first Documentation\"\n * tagline=\"Build beautiful documentation sites with React.\"\n * image=\"/logo.svg\"\n * actions={[\n * { text: \"Get Started\", link: \"/guide/getting-started\", theme: \"brand\", icon: <ArrowRight size={16} /> },\n * { text: \"GitHub\", link: \"https://github.com/...\", theme: \"alt\", icon: <Github size={16} /> }\n * ]}\n * />\n * ```\n */\nfunction HeroActionButton({ action }: { action: ArdoHeroAction }) {\n const link = action.link\n const isExternal =\n typeof link === \"string\" && (link.startsWith(\"http://\") || link.startsWith(\"https://\"))\n const cls = `${styles.heroAction} ${action.theme === \"alt\" ? styles.heroActionAlt : styles.heroActionBrand}`\n const content = (\n <>\n {action.icon}\n {action.text}\n </>\n )\n\n if (isExternal) {\n return (\n <a href={link} className={cls} target=\"_blank\" rel=\"noopener noreferrer\">\n {content}\n </a>\n )\n }\n return (\n <Link to={link} className={cls}>\n {content}\n </Link>\n )\n}\n\nfunction resolveHeroImage(image: ArdoHeroProps[\"image\"], name: string | undefined) {\n const url = typeof image === \"string\" ? image : (image?.light ?? \"\")\n const alt = typeof image === \"string\" ? (name ?? \"\") : (image?.alt ?? name ?? \"\")\n return { url, alt }\n}\n\nexport function ArdoHero({\n name,\n text,\n tagline,\n image,\n actions,\n className,\n version,\n}: ArdoHeroProps) {\n const img = resolveHeroImage(image, name)\n\n return (\n <section className={className ?? styles.hero}>\n <div className={`${styles.heroContainer} ${styles.heroAnimate}`}>\n {img.url !== \"\" && (\n <div>\n <img src={img.url} alt={img.alt} />\n </div>\n )}\n <div>\n {(version ?? \"\") !== \"\" && <span className={styles.heroVersion}>v{version}</span>}\n {(name ?? \"\") !== \"\" && <h1 className={styles.heroName}>{name}</h1>}\n {(text ?? \"\") !== \"\" && <p className={styles.heroText}>{text}</p>}\n {(tagline ?? \"\") !== \"\" && <p className={styles.heroTagline}>{tagline}</p>}\n {(actions?.length ?? 0) > 0 && (\n <div className={styles.heroActions}>\n {actions?.map((action) => {\n const key =\n typeof action.link === \"string\" ? `${action.link}-${action.text}` : action.text\n return <HeroActionButton key={key} action={action} />\n })}\n </div>\n )}\n </div>\n </div>\n </section>\n )\n}\n","import { style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"./theme/contract.css\"\n\nexport const root = style({\n minHeight: \"calc(100vh - 6rem)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: `${vars.space[\"3xl\"]} ${vars.space.lg}`,\n})\n\nexport const card = style({\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n textAlign: \"center\",\n maxWidth: \"32rem\",\n})\n\nexport const owl = style({\n color: vars.color.brand,\n opacity: 0.85,\n marginBottom: vars.space.lg,\n})\n\nexport const status = style({\n fontFamily: vars.font.mono,\n fontSize: vars.fontSize.xs,\n letterSpacing: \"0.08em\",\n textTransform: \"uppercase\",\n color: vars.color.textLighter,\n marginBottom: vars.space.sm,\n})\n\nexport const title = style({\n fontSize: \"clamp(1.5rem, 3vw, 2rem)\",\n fontFamily: vars.font.familyHeading,\n fontWeight: 700,\n lineHeight: 1.15,\n letterSpacing: \"-0.01em\",\n color: vars.color.text,\n marginBottom: vars.space.sm,\n textWrap: \"balance\",\n})\n\nexport const description = style({\n fontSize: vars.fontSize.base,\n lineHeight: 1.6,\n color: vars.color.textLight,\n marginBottom: vars.space.xl,\n textWrap: \"pretty\",\n})\n\nexport const actions = style({\n display: \"flex\",\n gap: vars.space.sm,\n flexWrap: \"wrap\",\n justifyContent: \"center\",\n})\n\nexport const primaryAction = style({\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: vars.space.xs,\n padding: `0.625rem ${vars.space.lg}`,\n background: vars.color.brand,\n color: vars.color.bg,\n fontSize: vars.fontSize.sm,\n fontWeight: 500,\n textDecoration: \"none\",\n borderRadius: vars.radius.base,\n transition: `background ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.brandDark,\n },\n },\n})\n\nexport const secondaryAction = style({\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: vars.space.xs,\n padding: `0.625rem ${vars.space.lg}`,\n background: \"transparent\",\n color: vars.color.text,\n fontSize: vars.fontSize.sm,\n fontWeight: 500,\n textDecoration: \"none\",\n borderRadius: vars.radius.base,\n border: `1px solid ${vars.color.border}`,\n transition: `border-color ${vars.transition.fast}, background ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n borderColor: vars.color.brand,\n background: vars.color.bgSoft,\n },\n },\n})\n\nexport const details = style({\n marginTop: vars.space.xl,\n width: \"100%\",\n textAlign: \"left\",\n fontSize: vars.fontSize.xs,\n color: vars.color.textLight,\n})\n\nexport const detailsSummary = style({\n cursor: \"pointer\",\n color: vars.color.textLighter,\n marginBottom: vars.space.sm,\n selectors: {\n \"&:hover\": { color: vars.color.text },\n },\n})\n\nexport const detailsPre = style({\n margin: 0,\n padding: vars.space.md,\n background: vars.color.codeBg,\n border: `1px solid ${vars.color.codeBorder}`,\n borderRadius: vars.radius.base,\n fontFamily: vars.font.mono,\n fontSize: vars.fontSize.xs,\n lineHeight: 1.5,\n overflowX: \"auto\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n})\n","import { isRouteErrorResponse, Link, useRouteError } from \"react-router\"\n\nimport * as styles from \"./ErrorBoundary.css\"\nimport { ArdoOwlMark } from \"./OwlMark\"\n\nexport type ArdoErrorBoundaryProps = {\n /** Override the heading/description shown for 404 responses. */\n notFound?: {\n title?: string\n description?: string\n homeLabel?: string\n homeHref?: string\n }\n /** Override the heading/description shown for non-404 errors. */\n error?: {\n title?: string\n description?: string\n homeLabel?: string\n homeHref?: string\n }\n}\n\nconst defaults = {\n notFound: {\n title: \"This page wandered off\",\n description:\n \"The page you were looking for has moved, been renamed, or never existed. The owl is on the case.\",\n homeLabel: \"Back to home\",\n homeHref: \"/\",\n },\n error: {\n title: \"Something went wrong\",\n description:\n \"An unexpected error happened while loading this page. Try again, or head back to safer ground.\",\n homeLabel: \"Back to home\",\n homeHref: \"/\",\n },\n} as const\n\n/**\n * Themed error/404 page. Drop into a React Router route as `ErrorBoundary`\n * to replace the default unstyled fallback with a layout-aware page.\n *\n * @example\n * ```tsx\n * // app/root.tsx\n * export { ArdoErrorBoundary as ErrorBoundary } from \"ardo/ui\"\n * ```\n */\nexport function ArdoErrorBoundary(props: ArdoErrorBoundaryProps = {}) {\n const error = useRouteError()\n const is404 = isRouteErrorResponse(error) && error.status === 404\n const isRouteError = isRouteErrorResponse(error)\n\n const copy = is404\n ? { ...defaults.notFound, ...props.notFound }\n : { ...defaults.error, ...props.error }\n\n const statusLabel = isRouteError ? `Error ${String(error.status)}` : \"Error\"\n const errorDetails = is404 ? undefined : formatErrorDetails(error)\n\n return (\n <main className={styles.root}>\n <section className={styles.card}>\n <ArdoOwlMark size={120} className={styles.owl} title=\"\" />\n <p className={styles.status}>{statusLabel}</p>\n <h1 className={styles.title}>{copy.title}</h1>\n <p className={styles.description}>{copy.description}</p>\n <div className={styles.actions}>\n <Link to={copy.homeHref} className={styles.primaryAction}>\n {copy.homeLabel}\n </Link>\n {!is404 && (\n <button\n type=\"button\"\n onClick={() => {\n globalThis.location.reload()\n }}\n className={styles.secondaryAction}\n >\n Reload\n </button>\n )}\n </div>\n {errorDetails != null && (\n <details className={styles.details}>\n <summary className={styles.detailsSummary}>Technical details</summary>\n <pre className={styles.detailsPre}>{errorDetails}</pre>\n </details>\n )}\n </section>\n </main>\n )\n}\n\nfunction formatErrorDetails(error: unknown): string | undefined {\n if (isRouteErrorResponse(error)) {\n if (typeof error.data === \"string\" && error.data.length > 0) return error.data\n return undefined\n }\n if (error instanceof Error) {\n return error.stack ?? error.message\n }\n return undefined\n}\n","import type { ReactNode } from \"react\"\n\nimport { Link } from \"react-router\"\n\nimport { useArdoConfig, useArdoPageData } from \"../runtime/hooks\"\nimport { ArdoFeatureCard, ArdoFeatures } from \"./components/Features\"\nimport * as heroStyles from \"./components/Hero.css\"\nimport { ArdoFooter, type ArdoFooterProps } from \"./Footer\"\nimport { ArdoHeader, type ArdoHeaderProps } from \"./Header\"\nimport * as layoutStyles from \"./Layout.css\"\n\nexport type ArdoHomePageProps = {\n /** Props passed to the Header component */\n headerProps?: ArdoHeaderProps\n /** Props passed to the Footer component */\n footerProps?: ArdoFooterProps\n /** Custom header element (overrides auto-generated header) */\n header?: ReactNode\n /** Custom footer element (overrides auto-generated footer) */\n footer?: ReactNode\n}\n\nfunction HomeHeroSection({\n hero,\n fallbackTitle,\n}: {\n hero: NonNullable<ReturnType<typeof useArdoPageData>>[\"frontmatter\"][\"hero\"]\n fallbackTitle: string\n}) {\n if (hero === undefined) return null\n const heroImage = hero.image\n const heroActions = hero.actions ?? []\n const heroName = hero.name ?? \"\"\n return (\n <section className={heroStyles.hero}>\n <div className={heroStyles.heroContainer}>\n {heroImage !== undefined && (\n <div>\n <img\n src={typeof heroImage === \"string\" ? heroImage : heroImage.light}\n alt={heroName !== \"\" ? heroName : fallbackTitle}\n />\n </div>\n )}\n <div>\n {heroName !== \"\" && <h1 className={heroStyles.heroName}>{heroName}</h1>}\n {(hero.text ?? \"\") !== \"\" && <p className={heroStyles.heroText}>{hero.text}</p>}\n {(hero.tagline ?? \"\") !== \"\" && <p className={heroStyles.heroTagline}>{hero.tagline}</p>}\n {heroActions.length > 0 && (\n <div className={heroStyles.heroActions}>\n {heroActions.map((action) => (\n <Link\n key={`${action.link}-${action.text}`}\n to={action.link}\n className={`${heroStyles.heroAction} ${action.theme === \"alt\" ? heroStyles.heroActionAlt : heroStyles.heroActionBrand}`}\n >\n {action.text}\n </Link>\n ))}\n </div>\n )}\n </div>\n </div>\n </section>\n )\n}\n\nfunction HomeFeaturesSection({\n features,\n}: {\n features: NonNullable<ReturnType<typeof useArdoPageData>>[\"frontmatter\"][\"features\"]\n}) {\n const safeFeatures = features ?? []\n if (safeFeatures.length === 0) return null\n return (\n <ArdoFeatures>\n {safeFeatures.map((feature) => (\n <ArdoFeatureCard\n key={feature.link ?? feature.title}\n title={feature.title}\n icon={feature.icon}\n link={feature.link}\n linkText={feature.linkText}\n >\n {feature.details}\n </ArdoFeatureCard>\n ))}\n </ArdoFeatures>\n )\n}\n\nexport function ArdoHomePage({ headerProps, footerProps, header, footer }: ArdoHomePageProps = {}) {\n const pageData = useArdoPageData()\n const config = useArdoConfig()\n\n return (\n <div className={layoutStyles.home}>\n {header ?? <ArdoHeader title={config.title} {...headerProps} />}\n <main className={layoutStyles.homeMain}>\n <HomeHeroSection hero={pageData?.frontmatter.hero} fallbackTitle={config.title} />\n <HomeFeaturesSection features={pageData?.frontmatter.features} />\n </main>\n {footer ?? <ArdoFooter {...footerProps} />}\n </div>\n )\n}\n","import { type ComponentProps, createContext, type ReactNode, use, useMemo, useState } from \"react\"\nimport { NavLink as RouterNavLink } from \"react-router\"\n\nimport * as styles from \"./Nav.css\"\n\n/** Route path type - uses React Router's NavLink 'to' prop type for type-safe routes */\ntype RoutePath = ComponentProps<typeof RouterNavLink>[\"to\"]\n\n// Nav context for shared state\ntype NavContextValue = {\n mobileMenuOpen: boolean\n setMobileMenuOpen: (open: boolean) => void\n}\n\nconst NavContext = createContext<NavContextValue | null>(null)\n\nfunction useNavContext() {\n return use(NavContext)\n}\n\n// =============================================================================\n// Nav Component\n// =============================================================================\n\nexport type ArdoNavProps = {\n children?: ReactNode\n className?: string\n}\n\n/**\n * Navigation container component for composing navigation links.\n *\n * @example\n * ```tsx\n * <Nav>\n * <NavLink to=\"/guide\">Guide</NavLink>\n * <NavLink to=\"/api\">API</NavLink>\n * <NavLink href=\"https://github.com/...\">GitHub</NavLink>\n * </Nav>\n * ```\n */\nexport function ArdoNav({ children, className }: ArdoNavProps) {\n return <nav className={className ?? styles.nav}>{children}</nav>\n}\n\n// =============================================================================\n// NavLink Component\n// =============================================================================\n\nexport type ArdoNavLinkProps = {\n /** Internal route path (type-safe with React Router's registered routes) */\n to?: RoutePath\n /** External URL (uses anchor tag) */\n href?: string\n /** Link text or children */\n children: ReactNode\n /** Additional CSS classes */\n className?: string\n /** Active state match pattern */\n activeMatch?: string\n}\n\n/**\n * Navigation link component supporting both internal routes and external URLs.\n *\n * @example\n * ```tsx\n * // Internal link\n * <NavLink to=\"/guide\">Guide</NavLink>\n *\n * // External link\n * <NavLink href=\"https://github.com/...\">GitHub</NavLink>\n * ```\n */\nexport function ArdoNavLink({\n to,\n href,\n children,\n className,\n activeMatch: _activeMatch,\n}: ArdoNavLinkProps) {\n const navContext = useNavContext()\n const baseClassName = className ?? styles.navLink\n const hasHref = (href ?? \"\") !== \"\"\n const hasTo = to !== undefined\n\n // Handle click for mobile menu\n const handleClick = () => {\n navContext?.setMobileMenuOpen(false)\n }\n\n // External link\n if (hasHref) {\n return (\n <a\n href={href ?? \"\"}\n className={baseClassName}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={handleClick}\n >\n {children}\n </a>\n )\n }\n\n // Internal link\n if (hasTo) {\n return (\n <RouterNavLink\n to={to}\n className={({ isActive }: { isActive: boolean }) =>\n [baseClassName, isActive && \"active\"].filter(Boolean).join(\" \")\n }\n onClick={handleClick}\n >\n {children}\n </RouterNavLink>\n )\n }\n\n // Text-only (no link)\n return <span className={baseClassName}>{children}</span>\n}\n\n// =============================================================================\n// NavProvider Component\n// =============================================================================\n\nexport type NavProviderProps = {\n children: ReactNode\n}\n\n/**\n * Provider for Nav context (mobile menu state).\n * Used internally by Header component.\n */\nexport function NavProvider({ children }: NavProviderProps) {\n const [mobileMenuOpen, setMobileMenuOpen] = useState(false)\n const contextValue = useMemo(() => ({ mobileMenuOpen, setMobileMenuOpen }), [mobileMenuOpen])\n\n return <NavContext value={contextValue}>{children}</NavContext>\n}\n\n// Export context hook for external use\nexport { useNavContext }\n"],"mappings":"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"}
1
+ {"version":3,"file":"ui-B6X8gAvz.js","names":["styles.footerLink","styles.footerArdoLink","styles.footerOwl","styles.footerPrimary","styles.footerContainer","styles.searchPopover","styles.searchResults","styles.searchResult","styles.searchResultTitle","styles.searchNoResults","styles.searchNoResultsOwl","styles.searchFooter","styles.searchField","styles.searchInput","styles.searchKbd","styles.searchPopover","styles.search","styles.inline","styles.trigger","styles.themeToggle","styles.themeIcon","logo","styles.headerContainer","styles.headerLeft","styles.logoLink","styles.headerRight","styles.mobileBackdrop","styles.mobilePanel","styles.mobilePanelHeader","styles.mobilePanelClose","styles.mobilePanelSidebar","styles.sidebarRail","styles.sidebarRailList","styles.sidebarRailItem","styles.sidebarRailLink","styles.sidebarRailLabel","styles.sidebarPanel","styles.sidebarNav","styles.sidebarList","styles.sidebarList0","styles.sidebarText","styles.sidebarTextButton","styles.sidebarItemHeader","styles.sidebarItem","styles.sidebarList1","styles.sidebarLink","layoutStyles.layout","layoutStyles.home","styles.featureTitle","styles.featureDetails","styles.featuresContainer","styles.heroAction","styles.heroActionAlt","styles.heroActionBrand","styles.heroContainer","styles.heroAnimate","styles.root","styles.card","styles.owl","styles.status","styles.title","styles.description","styles.actions","styles.primaryAction","hero","heroActions","heroName","heroStyles.hero","heroStyles.heroContainer","layoutStyles.home","layoutStyles.homeMain","RouterNavLink"],"sources":["../src/ui/OwlMark.tsx","../src/ui/Footer.tsx","../src/ui/components/HeaderSearch.css.ts","../src/ui/components/search-hooks.ts","../src/ui/components/Search.css.ts","../src/ui/components/SearchPopover.tsx","../src/ui/components/Search.tsx","../src/ui/components/HeaderSearch.tsx","../src/ui/components/ThemeToggle.css.ts","../src/ui/components/ThemeToggle.tsx","../src/ui/Header.css.ts","../src/ui/Nav.css.ts","../src/ui/Header.tsx","../src/ui/Sidebar.css.ts","../src/ui/SidebarRail.tsx","../src/ui/Sidebar.tsx","../src/ui/ArdoRoot.tsx","../src/ui/components/Features.css.ts","../src/ui/components/Features.tsx","../src/ui/components/Hero.css.ts","../src/ui/components/Hero.tsx","../src/ui/ErrorBoundary.css.ts","../src/ui/ErrorBoundary.tsx","../src/ui/HomePage.tsx","../src/ui/Nav.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\"\n\nexport type ArdoOwlMarkProps = {\n size?: number | string\n title?: string\n} & Omit<ComponentProps<\"svg\">, \"children\">\n\n/**\n * Decorative line-art owl, drawn in `currentColor`. Used by the default\n * error and empty states. Set `color` on the parent (or `style.color`)\n * to recolor; set `title` to give it accessible meaning.\n */\nexport function ArdoOwlMark({ size = 96, title, ...props }: ArdoOwlMarkProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 600 600\"\n width={size}\n height={size}\n style={{ strokeLinecap: \"round\", strokeLinejoin: \"round\" }}\n role={title == null ? \"presentation\" : \"img\"}\n aria-hidden={title == null ? true : undefined}\n {...props}\n >\n {title == null ? null : <title>{title}</title>}\n <defs>\n <symbol id=\"ardo-owl-eye\" overflow=\"visible\">\n <path d=\"M300 300 151 128l2 178-41 94h93c-35 32-55 68-63 107m63-106 95 81m-32-96 28 88\" />\n <ellipse cx=\"222\" cy=\"327\" rx=\"20\" ry=\"33\" fill=\"currentColor\" opacity=\"0.6\" />\n <circle cx=\"227\" cy=\"324\" r=\"71\" />\n </symbol>\n </defs>\n <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"16\">\n <path d=\"M155 318c2-70 66-126 145-126s143 56 145 126\" />\n <circle cx=\"300\" cy=\"290\" r=\"270\" />\n <use href=\"#ardo-owl-eye\" />\n <use href=\"#ardo-owl-eye\" transform=\"matrix(-1 0 0 1 600 0)\" />\n </g>\n </svg>\n )\n}\n","import React, { type ReactNode } from \"react\"\n\nimport type { ProjectMeta, SponsorConfig } from \"../config/types\"\n\nimport { useArdoConfig } from \"../runtime/hooks\"\nimport * as styles from \"./Footer.css\"\nimport { ArdoOwlMark } from \"./OwlMark\"\n\n// =============================================================================\n// Footer Component\n// =============================================================================\n\nexport type ArdoFooterProps = {\n /** Footer message (supports HTML string) */\n message?: string\n /** Copyright text (supports HTML string) */\n copyright?: string\n /** Custom content (overrides all automatic rendering) */\n children?: ReactNode\n /** Additional CSS classes */\n className?: string\n /** Project metadata — renders linked \"name vX.Y.Z\" */\n project?: ProjectMeta\n /** Sponsor link — renders \"Sponsored by X\" */\n sponsor?: SponsorConfig\n /** Build timestamp (ISO string) — renders formatted date */\n buildTime?: string\n /** Git commit hash — rendered next to the build date */\n buildHash?: string\n /** Show \"Built with Ardo\" link (default: true) */\n ardoLink?: boolean\n}\n\nfunction formatBuildTime(iso: string): string {\n try {\n const date = new Date(iso)\n return date.toLocaleDateString(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n })\n } catch {\n return iso\n }\n}\n\n/**\n * Footer component with structured layout for project info, sponsor, and build metadata.\n *\n * Automatically pulls data from Ardo context (`config.project`, `config.buildTime`,\n * `config.buildHash`). Props serve as overrides.\n *\n * When `children` is provided, all automatic rendering is skipped.\n *\n * @example Automatic (zero-config)\n * ```tsx\n * <Footer />\n * ```\n *\n * @example With overrides\n * ```tsx\n * <Footer\n * sponsor={{ text: \"Sebastian Software\", link: \"https://sebastian-software.com/oss\" }}\n * message=\"Released under the MIT License.\"\n * copyright=\"Copyright 2026 Sebastian Software GmbH\"\n * />\n * ```\n *\n * @example Custom content\n * ```tsx\n * <Footer>\n * <CustomFooterContent />\n * </Footer>\n * ```\n */\nfunction FooterProjectLink({\n project,\n config,\n}: {\n project: ArdoFooterProps[\"project\"]\n config: ReturnType<typeof useArdoConfig>\n}) {\n const resolved = project ?? config.project\n const name = resolved?.name ?? \"\"\n const version = resolved?.version ?? \"\"\n const homepage = resolved?.homepage ?? \"\"\n if (name === \"\") return null\n const label = version !== \"\" ? `${name} v${version}` : name\n return homepage !== \"\" ? (\n <a href={homepage} className={styles.footerLink}>\n {label}\n </a>\n ) : (\n <span>{label}</span>\n )\n}\n\nfunction FooterSponsorLink({ sponsor }: { sponsor: ArdoFooterProps[\"sponsor\"] }) {\n const text = sponsor?.text ?? \"\"\n const link = sponsor?.link ?? \"\"\n if (text === \"\" || link === \"\") return null\n return (\n <a href={link} className={styles.footerLink}>\n Sponsored by {text}\n </a>\n )\n}\n\nfunction FooterPrimaryLine({\n project,\n sponsor,\n ardoLink,\n config,\n}: {\n project: ArdoFooterProps[\"project\"]\n sponsor: ArdoFooterProps[\"sponsor\"]\n ardoLink: boolean\n config: ReturnType<typeof useArdoConfig>\n}) {\n const items: React.ReactNode[] = []\n const projectNode = <FooterProjectLink project={project} config={config} />\n const sponsorNode = <FooterSponsorLink sponsor={sponsor} />\n const hasProject =\n (project ?? config.project)?.name !== undefined && (project ?? config.project)?.name !== \"\"\n const hasSponsor = (sponsor?.text ?? \"\") !== \"\" && (sponsor?.link ?? \"\") !== \"\"\n\n if (hasProject) items.push(projectNode)\n if (ardoLink)\n items.push(\n <a href=\"https://ardo-docs.dev\" className={styles.footerArdoLink}>\n <ArdoOwlMark size={16} className={styles.footerOwl} title=\"\" />\n Built with Ardo\n </a>\n )\n if (hasSponsor) items.push(sponsorNode)\n if (items.length === 0) return null\n\n return (\n <p className={styles.footerPrimary}>\n {items.map((item, i) => (\n // eslint-disable-next-line react/no-array-index-key\n <React.Fragment key={i}>\n {i > 0 && <span className={styles.footerSeparator} aria-hidden=\"true\" />}\n {item}\n </React.Fragment>\n ))}\n </p>\n )\n}\n\nexport function ArdoFooter({\n children,\n className,\n ardoLink = true,\n message,\n copyright,\n project,\n sponsor,\n buildTime,\n buildHash,\n}: ArdoFooterProps) {\n const config = useArdoConfig()\n const resolvedBuildTime = buildTime ?? config.buildTime\n const resolvedBuildHash = buildHash ?? config.buildHash\n\n if (children != null) {\n return (\n <footer className={className ?? styles.footer}>\n <div className={styles.footerContainer}>{children}</div>\n </footer>\n )\n }\n\n return (\n <footer className={className ?? styles.footer}>\n <div className={styles.footerContainer}>\n <FooterPrimaryLine\n project={project}\n sponsor={sponsor}\n ardoLink={ardoLink}\n config={config}\n />\n {(message ?? \"\") !== \"\" && (\n <p className={styles.footerMessage} dangerouslySetInnerHTML={{ __html: message ?? \"\" }} />\n )}\n {(copyright ?? \"\") !== \"\" && (\n <p\n className={styles.footerCopyright}\n dangerouslySetInnerHTML={{ __html: copyright ?? \"\" }}\n />\n )}\n {(resolvedBuildTime ?? \"\") !== \"\" && (\n <p className={styles.footerBuildTime}>\n Built on {formatBuildTime(resolvedBuildTime ?? \"\")}\n {(resolvedBuildHash ?? \"\") !== \"\" && <> ({resolvedBuildHash})</>}\n </p>\n )}\n </div>\n </footer>\n )\n}\n\n// Type exports for compound pattern (kept for backwards compatibility)\nexport type ArdoFooterMessageProps = {\n children: ReactNode\n className?: string\n}\n\nexport type ArdoFooterCopyrightProps = {\n children: ReactNode\n className?: string\n}\n","import { style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"../theme/contract.css\"\n\nconst MOBILE = \"(max-width: 1024px)\"\n\n/** Inline search input — desktop only, hidden once the header collapses. */\nexport const inline = style({\n width: \"100%\",\n maxWidth: \"26rem\",\n \"@media\": {\n [MOBILE]: {\n display: \"none\",\n },\n },\n})\n\n/** Icon button that opens the search overlay — mobile only. */\nexport const trigger = style({\n display: \"none\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"2.25rem\",\n height: \"2.25rem\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n borderRadius: vars.radius.base,\n color: vars.color.text,\n transition: `background ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.bgSoft,\n },\n },\n \"@media\": {\n [MOBILE]: {\n display: \"flex\",\n },\n },\n})\n\nexport const overlay = style({\n position: \"fixed\",\n inset: 0,\n zIndex: 200,\n display: \"flex\",\n flexDirection: \"column\",\n background: `color-mix(in oklch, ${vars.color.bg} 88%, transparent)`,\n backdropFilter: \"blur(4px)\",\n WebkitBackdropFilter: \"blur(4px)\",\n})\n\nexport const overlayBar = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: vars.space.sm,\n padding: vars.space.md,\n borderBottom: `1px solid ${vars.color.border}`,\n background: vars.color.bg,\n})\n\nexport const overlaySearch = style({\n flex: 1,\n minWidth: 0,\n})\n\nexport const overlayClose = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"2.25rem\",\n height: \"2.25rem\",\n flexShrink: 0,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n borderRadius: vars.radius.base,\n color: vars.color.textLight,\n transition: `background ${vars.transition.fast}, color ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.bgSoft,\n color: vars.color.text,\n },\n },\n})\n","import { type RefObject, useEffect } from \"react\"\n\nexport function useGlobalSearchShortcut(\n inputRef: RefObject<HTMLInputElement | null>,\n setIsOpen: (open: boolean) => void\n) {\n useEffect(() => {\n const handleGlobalKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"k\") {\n e.preventDefault()\n inputRef.current?.focus()\n setIsOpen(true)\n }\n if (e.key === \"Escape\") {\n setIsOpen(false)\n }\n }\n document.addEventListener(\"keydown\", handleGlobalKeyDown)\n return () => {\n document.removeEventListener(\"keydown\", handleGlobalKeyDown)\n }\n }, [inputRef, setIsOpen])\n}\n\ntype OutsideClickOptions = {\n containerRef: RefObject<HTMLDivElement | null>\n popoverClass: string\n isOpen: boolean\n setIsOpen: (open: boolean) => void\n}\n\nexport function useOutsideClick({\n containerRef,\n popoverClass,\n isOpen,\n setIsOpen,\n}: OutsideClickOptions) {\n useEffect(() => {\n if (!isOpen) return\n const handleOutsideClick = (e: MouseEvent | TouchEvent) => {\n if (!(e.target instanceof Element)) {\n return\n }\n\n const target = e.target\n const inContainer = containerRef.current?.contains(target) === true\n const inPopover = target.closest(`.${popoverClass}`) != null\n if (!inContainer && !inPopover) {\n setIsOpen(false)\n }\n }\n document.addEventListener(\"mousedown\", handleOutsideClick)\n document.addEventListener(\"touchstart\", handleOutsideClick)\n return () => {\n document.removeEventListener(\"mousedown\", handleOutsideClick)\n document.removeEventListener(\"touchstart\", handleOutsideClick)\n }\n }, [containerRef, popoverClass, isOpen, setIsOpen])\n}\n","import { globalStyle, style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"../theme/contract.css\"\n\nexport const search = style({\n position: \"relative\",\n width: \"100%\",\n maxWidth: \"100%\",\n})\n\nexport const searchField = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: vars.space.sm,\n minHeight: \"2.5rem\",\n padding: `${vars.space.sm} 0.75rem`,\n background: vars.color.bg,\n border: `1px solid ${vars.color.border}`,\n borderRadius: vars.radius.base,\n color: vars.color.textLighter,\n cursor: \"text\",\n transition: `border-color ${vars.transition.fast}, box-shadow ${vars.transition.fast}, color ${vars.transition.fast}`,\n outline: \"none\",\n})\n\nglobalStyle(`${search}:focus-within ${searchField}`, {\n borderColor: vars.color.brand,\n color: vars.color.textLight,\n boxShadow: `0 0 0 3px color-mix(in oklch, ${vars.color.brand} 12%, transparent)`,\n})\n\nglobalStyle(`${searchField}:focus-within`, {\n outline: \"none\",\n})\n\nexport const searchInput = style({\n flex: 1,\n minWidth: 0,\n border: \"none\",\n outline: \"none\",\n fontSize: vars.fontSize.sm,\n background: \"none\",\n color: vars.color.text,\n \"::placeholder\": {\n color: vars.color.textLighter,\n },\n selectors: {\n \"&:focus-visible\": {\n outline: \"none\",\n },\n },\n})\n\nexport const searchPopover = style({\n position: \"fixed\",\n width: \"min(28rem, calc(100vw - 2rem))\",\n background: vars.color.bg,\n borderRadius: vars.radius.lg,\n border: `1px solid ${vars.color.border}`,\n boxShadow: vars.color.shadowLg,\n overflow: \"hidden\",\n zIndex: 210,\n})\n\nexport const searchResults = style({\n listStyle: \"none\",\n maxHeight: \"25rem\",\n overflowY: \"auto\",\n})\n\nexport const searchResult = style({\n display: \"block\",\n padding: `0.75rem ${vars.space.md}`,\n textDecoration: \"none\",\n color: vars.color.text,\n borderBottom: `1px solid ${vars.color.borderLight}`,\n transition: `background ${vars.transition.fast}`,\n selectors: {\n \"&:last-child\": {\n borderBottom: \"none\",\n },\n \"&:hover, &.selected\": {\n background: vars.color.brandSubtle,\n },\n },\n})\n\nexport const searchResultTitle = style({\n display: \"block\",\n fontWeight: 500,\n marginBottom: \"2px\",\n})\n\nexport const searchResultSection = style({\n display: \"block\",\n fontSize: vars.fontSize.xs,\n color: vars.color.textLighter,\n})\n\nexport const searchNoResults = style({\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: vars.space.sm,\n padding: `${vars.space.xl} ${vars.space.md}`,\n textAlign: \"center\",\n color: vars.color.textLighter,\n})\n\nexport const searchNoResultsOwl = style({\n color: vars.color.textLighter,\n opacity: 0.55,\n})\n\nexport const searchFooter = style({\n display: \"flex\",\n justifyContent: \"center\",\n gap: vars.space.lg,\n padding: `0.75rem ${vars.space.md}`,\n background: vars.color.bgSoft,\n borderTop: `1px solid ${vars.color.border}`,\n fontSize: vars.fontSize.xs,\n color: vars.color.textLighter,\n})\n\nglobalStyle(`${searchFooter} kbd`, {\n padding: \"2px 6px\",\n background: vars.color.bg,\n border: `1px solid ${vars.color.border}`,\n borderRadius: vars.radius.sm,\n marginRight: \"4px\",\n color: vars.color.accent,\n fontFamily: vars.font.mono,\n})\n\nexport const searchClear = style({\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"1.5rem\",\n height: \"1.5rem\",\n flexShrink: 0,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: vars.fontSize.lg,\n color: vars.color.textLighter,\n padding: vars.space.xs,\n borderRadius: vars.radius.sm,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.bgSoft,\n color: vars.color.text,\n },\n },\n})\n\nexport const searchKbd = style({\n display: \"flex\",\n gap: \"3px\",\n marginLeft: vars.space.xs,\n})\n\nglobalStyle(`${searchKbd} kbd`, {\n padding: \"2px 6px\",\n background: vars.color.bg,\n border: `1px solid ${vars.color.border}`,\n borderRadius: vars.radius.sm,\n fontSize: vars.fontSize.xs,\n fontFamily: vars.font.mono,\n color: vars.color.accent,\n})\n","import { useLayoutEffect, useState } from \"react\"\nimport { createPortal } from \"react-dom\"\n\nimport * as styles from \"./Search.css\"\n\n/**\n * Renders the search popover as a portal attached to document.body.\n * Uses getBoundingClientRect to position it below the anchor element.\n */\nexport function SearchPopover({\n anchorRef,\n children,\n}: {\n anchorRef: React.RefObject<HTMLElement | null>\n children: React.ReactNode\n}) {\n const [pos, setPos] = useState({ top: 0, left: 0, width: 0 })\n\n useLayoutEffect(() => {\n const el = anchorRef.current\n if (!el) return\n const rect = el.getBoundingClientRect()\n setPos({\n top: rect.bottom + 8,\n left: rect.left,\n width: Math.max(rect.width, 400),\n })\n }, [anchorRef])\n\n if (typeof document === \"undefined\") return null\n\n return createPortal(\n <div\n className={styles.searchPopover}\n style={{\n top: pos.top,\n left: pos.left,\n width: Math.min(pos.width, globalThis.innerWidth - 32),\n }}\n >\n {children}\n </div>,\n document.body\n )\n}\n","import MiniSearch from \"minisearch\"\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { Link, useNavigate } from \"react-router\"\nimport searchDocs from \"virtual:ardo/search-index\"\n\nimport { SearchIcon } from \"../icons\"\nimport { ArdoOwlMark } from \"../OwlMark\"\nimport { useGlobalSearchShortcut, useOutsideClick } from \"./search-hooks\"\nimport * as styles from \"./Search.css\"\nimport { SearchPopover } from \"./SearchPopover\"\n\ntype SearchDoc = {\n id: string\n title: string\n content: string\n path: string\n section?: string\n}\n\ntype SearchMatch = {\n id: string\n title: string\n path: string\n section?: string\n}\n\nexport type ArdoSearchProps = {\n /** Placeholder text for the search input (default: \"Search...\") */\n placeholder?: string\n /** Focus the input on mount (used by the mobile search overlay). */\n autoFocus?: boolean\n}\n\nfunction useSearchIndex() {\n return useMemo(() => {\n const index = new MiniSearch<SearchDoc>({\n fields: [\"title\", \"content\", \"section\"],\n storeFields: [\"title\", \"path\", \"section\"],\n searchOptions: { boost: { title: 2 }, fuzzy: 0.2, prefix: true },\n })\n index.addAll(searchDocs)\n return index\n }, [])\n}\n\nfunction normalizeResults(rawResults: Array<Record<string, unknown>>): SearchMatch[] {\n return rawResults.flatMap((result): SearchMatch[] => {\n const resultPath = typeof result.path === \"string\" ? result.path : undefined\n const title = typeof result.title === \"string\" ? result.title : undefined\n if (resultPath === undefined || title === undefined) return []\n return [\n {\n id: String(result.id),\n title,\n path: resultPath,\n section: typeof result.section === \"string\" ? result.section : undefined,\n },\n ]\n })\n}\n\nfunction SearchResults({\n results,\n selectedIndex,\n query,\n onClose,\n}: {\n results: SearchMatch[]\n selectedIndex: number\n query: string\n onClose: () => void\n}) {\n return (\n <>\n {results.length > 0 ? (\n <ul className={styles.searchResults}>\n {results.map((result, index) => (\n <li key={result.id}>\n <Link\n to={result.path}\n className={[styles.searchResult, index === selectedIndex && \"selected\"]\n .filter(Boolean)\n .join(\" \")}\n onClick={onClose}\n >\n <span className={styles.searchResultTitle}>{result.title}</span>\n {result.section !== undefined && (\n <span className={styles.searchResultSection}>{result.section}</span>\n )}\n </Link>\n </li>\n ))}\n </ul>\n ) : (\n <div className={styles.searchNoResults}>\n <ArdoOwlMark size={36} className={styles.searchNoResultsOwl} title=\"\" />\n <span>No results found for &quot;{query}&quot;</span>\n </div>\n )}\n <div className={styles.searchFooter}>\n <span>\n <kbd>↑</kbd> <kbd>↓</kbd> to navigate\n </span>\n <span>\n <kbd>↵</kbd> to select\n </span>\n <span>\n <kbd>esc</kbd> to close\n </span>\n </div>\n </>\n )\n}\n\nfunction useSearch(searchIndex: ReturnType<typeof useSearchIndex>) {\n const [isOpen, setIsOpen] = useState(false)\n const [query, setQuery] = useState(\"\")\n const [results, setResults] = useState<SearchMatch[]>([])\n const [selectedIndex, setSelectedIndex] = useState(0)\n\n const search = (searchQuery: string) => {\n setQuery(searchQuery)\n if (!searchQuery.trim()) {\n setResults([])\n setIsOpen(false)\n setSelectedIndex(0)\n return\n }\n const rawResults = searchIndex.search(searchQuery).slice(0, 10)\n setResults(normalizeResults(rawResults))\n setSelectedIndex(0)\n setIsOpen(true)\n }\n\n return { isOpen, setIsOpen, query, results, selectedIndex, setSelectedIndex, search }\n}\n\nfunction SearchInput({\n inputRef,\n placeholder,\n query,\n hasQuery,\n onSearch,\n onKeyDown,\n onFocus,\n}: {\n inputRef: React.RefObject<HTMLInputElement | null>\n placeholder: string\n query: string\n hasQuery: boolean\n onSearch: (q: string) => void\n onKeyDown: (e: React.KeyboardEvent) => void\n onFocus: () => void\n}) {\n return (\n <div className={styles.searchField}>\n <SearchIcon size={18} />\n <input\n ref={inputRef}\n type=\"text\"\n className={styles.searchInput}\n placeholder={placeholder}\n value={query}\n onChange={(e) => {\n onSearch(e.target.value)\n }}\n onKeyDown={onKeyDown}\n onFocus={onFocus}\n aria-label=\"Search\"\n />\n {hasQuery && (\n <button\n type=\"button\"\n className={styles.searchClear}\n onClick={(e) => {\n e.stopPropagation()\n onSearch(\"\")\n inputRef.current?.focus()\n }}\n aria-label=\"Clear search\"\n >\n ×\n </button>\n )}\n <span className={styles.searchKbd}>\n <kbd>⌘</kbd>\n <kbd>K</kbd>\n </span>\n </div>\n )\n}\n\nexport function ArdoSearch({ placeholder = \"Search...\", autoFocus = false }: ArdoSearchProps) {\n const navigate = useNavigate()\n const containerRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const searchIndex = useSearchIndex()\n const state = useSearch(searchIndex)\n const hasQuery = state.query.trim().length > 0\n\n useEffect(() => {\n if (autoFocus) inputRef.current?.focus()\n }, [autoFocus])\n\n useGlobalSearchShortcut(inputRef, state.setIsOpen)\n useOutsideClick({\n containerRef,\n popoverClass: styles.searchPopover,\n isOpen: state.isOpen,\n setIsOpen: state.setIsOpen,\n })\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case \"ArrowDown\":\n if (state.results.length > 0) {\n e.preventDefault()\n state.setSelectedIndex((p) => Math.min(p + 1, state.results.length - 1))\n }\n break\n case \"ArrowUp\":\n if (state.results.length > 0) {\n e.preventDefault()\n state.setSelectedIndex((p) => Math.max(p - 1, 0))\n }\n break\n case \"Enter\": {\n const p = state.results[state.selectedIndex]?.path\n if (typeof p === \"string\") {\n e.preventDefault()\n void navigate(p)\n state.setIsOpen(false)\n }\n break\n }\n case \"Escape\":\n state.setIsOpen(false)\n inputRef.current?.blur()\n break\n default:\n break\n }\n }\n\n return (\n <div\n className={styles.search}\n ref={containerRef}\n data-expanded={state.isOpen || hasQuery ? \"true\" : \"false\"}\n onMouseDown={() => inputRef.current?.focus()}\n >\n <SearchInput\n inputRef={inputRef}\n placeholder={placeholder}\n query={state.query}\n hasQuery={hasQuery}\n onSearch={state.search}\n onKeyDown={handleKeyDown}\n onFocus={() => {\n if (hasQuery) state.setIsOpen(true)\n }}\n />\n {state.isOpen && hasQuery && (\n <SearchPopover anchorRef={containerRef}>\n <SearchResults\n results={state.results}\n selectedIndex={state.selectedIndex}\n query={state.query}\n onClose={() => {\n state.setIsOpen(false)\n }}\n />\n </SearchPopover>\n )}\n </div>\n )\n}\n","import { useEffect, useState } from \"react\"\nimport { useLocation } from \"react-router\"\n\nimport { SearchIcon, XIcon } from \"../icons\"\nimport * as styles from \"./HeaderSearch.css\"\nimport { ArdoSearch, type ArdoSearchProps } from \"./Search\"\n\n/**\n * Header-hosted search. On desktop it renders the search input inline; on\n * narrow viewports it collapses to an icon button that opens a full-width\n * search overlay.\n */\nexport function ArdoHeaderSearch({ placeholder }: ArdoSearchProps) {\n const [overlayOpen, setOverlayOpen] = useState(false)\n const location = useLocation()\n\n // Close the overlay on navigation and on Escape.\n useEffect(() => {\n setOverlayOpen(false)\n }, [location.pathname])\n\n useEffect(() => {\n if (!overlayOpen) return\n const handleKey = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") setOverlayOpen(false)\n }\n document.addEventListener(\"keydown\", handleKey)\n return () => {\n document.removeEventListener(\"keydown\", handleKey)\n }\n }, [overlayOpen])\n\n return (\n <>\n <div className={styles.inline}>\n <ArdoSearch placeholder={placeholder} />\n </div>\n\n <button\n type=\"button\"\n className={styles.trigger}\n aria-label=\"Search\"\n onClick={() => {\n setOverlayOpen(true)\n }}\n >\n <SearchIcon size={20} />\n </button>\n\n {overlayOpen && (\n <div className={styles.overlay}>\n <div className={styles.overlayBar}>\n <div className={styles.overlaySearch}>\n <ArdoSearch placeholder={placeholder} autoFocus />\n </div>\n <button\n type=\"button\"\n className={styles.overlayClose}\n aria-label=\"Close search\"\n onClick={() => {\n setOverlayOpen(false)\n }}\n >\n <XIcon size={20} />\n </button>\n </div>\n </div>\n )}\n </>\n )\n}\n","import { style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"../theme/contract.css\"\n\nexport const themeIcon = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n})\n\nexport const themeToggle = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"40px\",\n height: \"40px\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n color: vars.color.textLight,\n borderRadius: vars.radius.base,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.bgSoft,\n color: vars.color.text,\n },\n },\n})\n","import { useEffect, useState, useSyncExternalStore } from \"react\"\n\nimport { MonitorIcon, MoonIcon, SunIcon } from \"../icons\"\nimport * as styles from \"./ThemeToggle.css\"\n\ntype Theme = \"dark\" | \"light\" | \"system\"\n\nconst isBrowser = typeof document !== \"undefined\"\n\nfunction getInitialTheme(): Theme {\n if (!isBrowser) return \"system\"\n const stored = localStorage.getItem(\"ardo-theme\")\n return isTheme(stored) ? stored : \"system\"\n}\n\nexport function ArdoThemeToggle() {\n const [theme, setTheme] = useState<Theme>(getInitialTheme)\n const mounted = useSyncExternalStore(subscribeMounted, getClientMounted, getServerMounted)\n\n useEffect(() => {\n if (!mounted) return\n applyTheme(theme)\n }, [mounted, theme])\n\n const toggleTheme = () => {\n const nextTheme: Theme = theme === \"light\" ? \"dark\" : theme === \"dark\" ? \"system\" : \"light\"\n setTheme(nextTheme)\n localStorage.setItem(\"ardo-theme\", nextTheme)\n applyTheme(nextTheme)\n }\n\n if (!mounted) {\n return (\n <button type=\"button\" className={styles.themeToggle} aria-label=\"Toggle theme\">\n <span className={styles.themeIcon}>\n <SunIcon size={20} />\n </span>\n </button>\n )\n }\n\n return (\n <button\n type=\"button\"\n className={styles.themeToggle}\n onClick={toggleTheme}\n aria-label={`Switch to ${theme === \"light\" ? \"dark\" : theme === \"dark\" ? \"system\" : \"light\"} theme`}\n >\n <span className={styles.themeIcon}>\n {theme === \"light\" && <SunIcon size={20} />}\n {theme === \"dark\" && <MoonIcon size={20} />}\n {theme === \"system\" && <MonitorIcon size={20} />}\n </span>\n </button>\n )\n}\n\nfunction applyTheme(theme: Theme) {\n const root = document.documentElement\n\n if (theme === \"system\") {\n const isDark = globalThis.matchMedia(\"(prefers-color-scheme: dark)\").matches\n root.classList.toggle(\"dark\", isDark)\n root.classList.toggle(\"light\", !isDark)\n } else {\n root.classList.toggle(\"dark\", theme === \"dark\")\n root.classList.toggle(\"light\", theme === \"light\")\n }\n}\n\nfunction subscribeMounted() {\n return noop\n}\n\nfunction getClientMounted() {\n return true\n}\n\nfunction getServerMounted() {\n return false\n}\n\nfunction noop() {\n return undefined\n}\n\nfunction isTheme(value: null | string): value is Theme {\n return value === \"dark\" || value === \"light\" || value === \"system\"\n}\n","import { globalStyle, style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"./theme/contract.css\"\n\nexport const header = style({\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n height: `calc(${vars.layout.headerHeight} + env(safe-area-inset-top))`,\n paddingTop: \"env(safe-area-inset-top)\",\n background: vars.color.bg,\n borderBottom: `1px solid ${vars.color.border}`,\n zIndex: 100,\n boxShadow: \"0 1px 0 oklch(0 0 0 / 0.02)\",\n})\n\nexport const headerContainer = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n height: vars.layout.headerHeight,\n padding: `0 ${vars.space.lg}`,\n \"@media\": {\n \"(max-width: 640px)\": {\n padding: `0 ${vars.space.md}`,\n },\n },\n})\n\nexport const headerLeft = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: vars.space.md,\n flexShrink: 0,\n})\n\nexport const headerCenter = style({\n display: \"flex\",\n flex: 1,\n justifyContent: \"center\",\n minWidth: 0,\n padding: `0 ${vars.space.lg}`,\n \"@media\": {\n \"(max-width: 1024px)\": {\n justifyContent: \"flex-end\",\n padding: `0 ${vars.space.sm}`,\n },\n },\n})\n\nexport const headerRight = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.75rem\",\n flexShrink: 0,\n})\n\nexport const logoLink = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: vars.space.sm,\n textDecoration: \"none\",\n color: vars.color.text,\n transition: `opacity ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n opacity: 0.8,\n },\n },\n})\n\nexport const logo = style({\n height: \"2rem\",\n})\n\nexport const siteTitle = style({\n fontSize: vars.fontSize.lg,\n fontWeight: 700,\n letterSpacing: \"-0.025em\",\n})\n\nexport const mobileMenuButton = style({\n display: \"none\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: vars.space.sm,\n borderRadius: vars.radius.sm,\n color: vars.color.text,\n selectors: {\n \"&:hover\": {\n background: vars.color.bgSoft,\n },\n },\n \"@media\": {\n \"(max-width: 1024px)\": {\n display: \"flex\",\n alignItems: \"center\",\n },\n },\n})\n\nexport const hamburger = style({\n display: \"flex\",\n flexDirection: \"column\",\n gap: vars.space.xs,\n})\n\nglobalStyle(`${hamburger} span`, {\n display: \"block\",\n width: \"1.25rem\",\n height: \"2px\",\n background: vars.color.text,\n borderRadius: \"1px\",\n transition: `all ${vars.transition.fast}`,\n})\n\nexport const desktopNav = style({\n display: \"flex\",\n alignItems: \"center\",\n \"@media\": {\n \"(max-width: 1024px)\": {\n display: \"none\",\n },\n },\n})\n\n// =============================================================================\n// Mobile slide-in panel\n// =============================================================================\n\nexport const mobileBackdrop = style({\n position: \"fixed\",\n inset: 0,\n zIndex: 150,\n background: \"oklch(0 0 0 / 0.3)\",\n transition: `opacity ${vars.transition.base}`,\n selectors: {\n '&[data-open=\"false\"]': {\n opacity: 0,\n pointerEvents: \"none\",\n },\n },\n})\n\nexport const mobilePanel = style({\n position: \"fixed\",\n top: 0,\n left: 0,\n bottom: 0,\n width: \"min(22rem, 88vw)\",\n zIndex: 151,\n background: vars.color.bg,\n overflowY: \"auto\",\n padding: `${vars.space.lg} ${vars.space.lg} ${vars.space.xl}`,\n borderRight: `1px solid ${vars.color.border}`,\n boxShadow: vars.color.shadowLg,\n transform: \"translateX(0)\",\n transition: `transform ${vars.transition.slow}`,\n selectors: {\n '&[data-open=\"false\"]': {\n transform: \"translateX(-100%)\",\n },\n },\n})\n\nexport const mobilePanelHeader = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n marginBottom: vars.space.lg,\n})\n\nexport const mobilePanelClose = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: vars.space.sm,\n borderRadius: vars.radius.base,\n color: vars.color.textLight,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n background: vars.color.bgMute,\n },\n },\n})\n\nexport const mobilePanelNav = style({\n marginBottom: vars.space.lg,\n paddingBottom: vars.space.md,\n borderBottom: `1px solid ${vars.color.border}`,\n})\n\nglobalStyle(`${mobilePanelNav} a`, {\n display: \"block\",\n padding: `${vars.space.sm} 0`,\n color: vars.color.textLight,\n textDecoration: \"none\",\n fontSize: vars.fontSize.sm,\n})\n\n// Force sidebar visible inside the mobile panel (overrides sidebar's display:none at 1024px)\nexport const mobilePanelSidebar = style({})\n\nglobalStyle(`${mobilePanelSidebar} > aside`, {\n display: \"block\",\n width: \"100%\",\n padding: 0,\n borderRight: \"none\",\n})\n\nglobalStyle(`${mobilePanelSidebar} nav[aria-label=\"Documentation sections\"]`, {\n display: \"none\",\n})\n\n// Legacy - keep for backwards compat but unused\nexport const mobileMenu = style({ display: \"none\" })\nexport const mobileTopNav = style({ display: \"none\" })\nexport const mobileMenuContent = style({})\nexport const mobileMenuSection = style({})\nexport const mobileNav = style({})\n","import { style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"./theme/contract.css\"\n\nexport const nav = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n})\n\nexport const navLink = style({\n position: \"relative\",\n color: vars.color.textLight,\n textDecoration: \"none\",\n fontSize: \"14px\",\n fontWeight: 500,\n padding: \"8px 14px\",\n borderRadius: vars.radius.sm,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&::after\": {\n content: '\"\"',\n position: \"absolute\",\n bottom: 0,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n width: 0,\n height: \"2px\",\n background: vars.color.brand,\n borderRadius: \"1px\",\n transition: `width ${vars.transition.base}`,\n },\n \"&:hover\": {\n color: vars.color.text,\n background: vars.color.bgSoft,\n },\n \"&.active\": {\n color: vars.color.brand,\n },\n \"&.active::after\": {\n width: \"calc(100% - 28px)\",\n },\n },\n})\n\nexport const socialLink = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"40px\",\n height: \"40px\",\n color: vars.color.textLight,\n borderRadius: vars.radius.base,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n background: vars.color.bgSoft,\n },\n },\n})\n","import { type ReactNode, useEffect, useState } from \"react\"\nimport { Link, useLocation } from \"react-router\"\n\nimport { useArdoConfig } from \"../runtime/hooks\"\nimport { ArdoHeaderSearch } from \"./components/HeaderSearch\"\nimport { ArdoThemeToggle } from \"./components/ThemeToggle\"\nimport * as styles from \"./Header.css\"\nimport {\n GithubIcon,\n LinkedinIcon,\n MessageCircleIcon,\n NpmIcon,\n TwitterIcon,\n XIcon,\n YoutubeIcon,\n} from \"./icons\"\nimport * as navStyles from \"./Nav.css\"\n\n// =============================================================================\n// Header Component\n// =============================================================================\n\nexport type ArdoHeaderProps = {\n /** Logo image URL or light/dark variants */\n logo?: { light: string; dark: string } | string\n /** Site title displayed next to logo */\n title?: string\n /** Navigation content (Nav component or custom) */\n nav?: ReactNode\n /** Actions/right side content (social links, custom buttons) */\n actions?: ReactNode\n /** Show search (default: true) */\n search?: boolean\n /** Placeholder text for the search input */\n searchPlaceholder?: string\n /** Show theme toggle (default: true) */\n themeToggle?: boolean\n /** Additional content rendered in the mobile menu (e.g. sidebar) */\n mobileMenuContent?: ReactNode\n /** Additional CSS classes */\n className?: string\n}\n\n/**\n * Mobile menu open state — resets on navigation and locks body scroll\n * while open.\n */\nfunction useMobileMenu(): [boolean, (open: boolean) => void] {\n const location = useLocation()\n const [open, setOpen] = useState(false)\n\n useEffect(() => {\n setOpen(false)\n }, [location.pathname])\n\n useEffect(() => {\n document.body.style.overflow = open ? \"hidden\" : \"\"\n return () => {\n document.body.style.overflow = \"\"\n }\n }, [open])\n\n return [open, setOpen]\n}\n\nexport function ArdoHeader({\n logo,\n title,\n nav,\n actions,\n search = true,\n searchPlaceholder,\n themeToggle = true,\n mobileMenuContent,\n className,\n}: ArdoHeaderProps) {\n const config = useArdoConfig()\n const [mobileMenuOpen, setMobileMenuOpen] = useMobileMenu()\n\n const resolvedLogo = logo\n const resolvedTitle = title ?? config.title\n const hasLogo = resolvedLogo !== undefined\n const hasTitle = resolvedTitle !== \"\"\n const hasMobileMenu = mobileMenuContent != null\n\n return (\n <>\n <header className={className ?? styles.header}>\n <div className={styles.headerContainer}>\n <div className={styles.headerLeft}>\n {hasMobileMenu && (\n <button\n type=\"button\"\n className={styles.mobileMenuButton}\n onClick={() => {\n setMobileMenuOpen(!mobileMenuOpen)\n }}\n aria-label=\"Toggle menu\"\n aria-expanded={mobileMenuOpen}\n >\n <span className={styles.hamburger}>\n <span />\n <span />\n <span />\n </span>\n </button>\n )}\n <Link to=\"/\" className={styles.logoLink}>\n {hasLogo && (\n <img\n src={typeof resolvedLogo === \"string\" ? resolvedLogo : resolvedLogo.light}\n alt={resolvedTitle}\n className={styles.logo}\n />\n )}\n {hasTitle && <span className={styles.siteTitle}>{resolvedTitle}</span>}\n </Link>\n </div>\n\n {search && (\n <div className={styles.headerCenter}>\n <ArdoHeaderSearch placeholder={searchPlaceholder} />\n </div>\n )}\n\n <div className={styles.headerRight}>\n {nav != null && <div className={styles.desktopNav}>{nav}</div>}\n {themeToggle && <ArdoThemeToggle />}\n {actions}\n </div>\n </div>\n </header>\n\n {hasMobileMenu && (\n <MobileSlidePanel\n isOpen={mobileMenuOpen}\n logo={resolvedLogo}\n title={resolvedTitle}\n nav={nav}\n themeToggle={themeToggle}\n onClose={() => {\n setMobileMenuOpen(false)\n }}\n >\n {mobileMenuContent}\n </MobileSlidePanel>\n )}\n </>\n )\n}\n\n// =============================================================================\n// Mobile Slide-in Panel\n// =============================================================================\n\nfunction MobileSlidePanel({\n isOpen,\n logo,\n title,\n nav,\n themeToggle,\n children,\n onClose,\n}: {\n isOpen: boolean\n logo?: { light: string; dark: string } | string\n title: string\n nav?: ReactNode\n themeToggle?: boolean\n children: ReactNode\n onClose: () => void\n}) {\n return (\n <>\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}\n <div className={styles.mobileBackdrop} data-open={isOpen} onClick={onClose} />\n\n {/* Panel */}\n <div className={styles.mobilePanel} data-open={isOpen} aria-hidden={!isOpen}>\n <div className={styles.mobilePanelHeader}>\n <Link to=\"/\" className={styles.logoLink} onClick={onClose}>\n {logo != null && (\n <img\n src={typeof logo === \"string\" ? logo : logo.light}\n alt={title}\n className={styles.logo}\n />\n )}\n </Link>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"0.5rem\" }}>\n {themeToggle && <ArdoThemeToggle />}\n <button\n type=\"button\"\n className={styles.mobilePanelClose}\n onClick={onClose}\n aria-label=\"Close menu\"\n >\n <XIcon size={20} />\n </button>\n </div>\n </div>\n\n {/* Nav links */}\n {nav != null && (\n <div className={styles.mobilePanelNav} onClickCapture={handleLinkClick(onClose)}>\n {nav}\n </div>\n )}\n\n {/* Sidebar content - wrapper overrides display:none from sidebar CSS */}\n <div className={styles.mobilePanelSidebar} onClickCapture={handleLinkClick(onClose)}>\n {children}\n </div>\n </div>\n </>\n )\n}\n\nfunction handleLinkClick(onClose: () => void) {\n return (event: React.MouseEvent<HTMLElement>) => {\n if (event.target instanceof HTMLElement && event.target.closest(\"a\") !== null) {\n onClose()\n }\n }\n}\n\n// =============================================================================\n// SocialLink Component\n// =============================================================================\n\nexport type ArdoSocialLinkProps = {\n /** URL to link to */\n href: string\n /** Social icon type */\n icon: \"discord\" | \"github\" | \"linkedin\" | \"npm\" | \"twitter\" | \"youtube\"\n /** Accessible label */\n ariaLabel?: string\n /** Additional CSS classes */\n className?: string\n}\n\nexport function ArdoSocialLink({ href, icon, ariaLabel, className }: ArdoSocialLinkProps) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={className ?? navStyles.socialLink}\n aria-label={ariaLabel ?? icon}\n >\n <SocialIcon icon={icon} />\n </a>\n )\n}\n\nconst socialIcons = {\n github: GithubIcon,\n twitter: TwitterIcon,\n discord: MessageCircleIcon,\n linkedin: LinkedinIcon,\n youtube: YoutubeIcon,\n npm: NpmIcon,\n} as const\n\nfunction SocialIcon({ icon }: { icon: keyof typeof socialIcons }) {\n const IconComponent = socialIcons[icon]\n return <IconComponent size={20} />\n}\n","import { style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"./theme/contract.css\"\n\nexport const sidebar = style({\n width: vars.layout.sidebarWidth,\n flexShrink: 0,\n display: \"flex\",\n minHeight: 0,\n borderRight: `1px solid ${vars.color.sidebarBorder}`,\n background: \"transparent\",\n \"@media\": {\n \"(max-width: 1024px)\": {\n display: \"none\",\n },\n },\n})\n\nexport const sidebarRail = style({\n width: \"4rem\",\n flexShrink: 0,\n padding: `${vars.space.md} 0`,\n borderRight: `1px solid ${vars.color.sidebarBorder}`,\n background: vars.color.bgSoft,\n})\n\nexport const sidebarRailItem = style({\n position: \"relative\",\n})\n\nexport const sidebarRailLabel = style({\n position: \"absolute\",\n left: \"calc(100% + 0.75rem)\",\n top: \"50%\",\n transform: \"translateY(-50%) translateX(-4px)\",\n padding: \"0.375rem 0.625rem\",\n background: vars.color.text,\n color: vars.color.bg,\n fontSize: vars.fontSize.xs,\n fontWeight: 500,\n borderRadius: vars.radius.sm,\n whiteSpace: \"nowrap\",\n pointerEvents: \"none\",\n opacity: 0,\n transition: `opacity ${vars.transition.fast}, transform ${vars.transition.fast}`,\n selectors: {\n [`${sidebarRailItem}:hover &`]: {\n opacity: 1,\n transform: \"translateY(-50%) translateX(0)\",\n transitionDelay: \"200ms\",\n },\n },\n zIndex: 50,\n})\n\nexport const sidebarRailList = style({\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: vars.space.xs,\n listStyle: \"none\",\n})\n\nexport const sidebarRailLink = style({\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"2.5rem\",\n height: \"2.5rem\",\n color: vars.color.textLight,\n borderRadius: vars.radius.base,\n textDecoration: \"none\",\n transition: `background ${vars.transition.fast}, color ${vars.transition.fast}, box-shadow ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n background: vars.color.bg,\n boxShadow: vars.color.shadowSm,\n },\n \"&.active\": {\n color: vars.color.brand,\n background: vars.color.brandSubtle,\n boxShadow: `inset 0 0 0 1px ${vars.color.borderLight}`,\n },\n \"&.active::before\": {\n content: '\"\"',\n position: \"absolute\",\n left: \"-0.75rem\",\n top: \"0.75rem\",\n bottom: \"0.75rem\",\n width: \"2px\",\n borderRadius: \"999px\",\n background: vars.color.brand,\n },\n },\n})\n\nexport const sidebarPanel = style({\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n flex: 1,\n padding: `${vars.space.md} ${vars.space.md} ${vars.space.md} 1.125rem`,\n})\n\nexport const sidebarHeader = style({\n flexShrink: 0,\n marginBottom: vars.space.lg,\n position: \"relative\",\n})\n\nexport const sidebarNav = style({\n flex: 1,\n overflowY: \"auto\",\n minHeight: 0,\n})\n\nexport const sidebarList = style({\n listStyle: \"none\",\n})\n\nexport const sidebarList0 = style({})\n\nexport const sidebarList1 = style({\n marginLeft: \"0.75rem\",\n marginTop: \"2px\",\n})\n\nexport const sidebarItem = style({})\n\n/**\n * Applied to `<li>` items that contain a collapsible group. Groups get\n * breathing room above them; plain links sit tight together (their own\n * padding provides the rhythm).\n */\nexport const sidebarItemGroup = style({\n selectors: {\n \"&:not(:first-child)\": {\n marginTop: vars.space.lg,\n },\n },\n})\n\nexport const sidebarItemHeader = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n})\n\nexport const sidebarLink = style({\n display: \"block\",\n padding: `0.375rem 0.75rem`,\n color: vars.color.textLight,\n textDecoration: \"none\",\n fontSize: vars.fontSize.sm,\n fontWeight: 400,\n borderLeft: \"2px solid transparent\",\n borderRadius: `0 ${vars.radius.base} ${vars.radius.base} 0`,\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n background: vars.color.bgSoft,\n },\n \"&.active\": {\n color: vars.color.brand,\n background: vars.color.brandSubtle,\n borderLeftColor: vars.color.brand,\n fontWeight: 500,\n },\n },\n})\n\n// Section title (top-level group heading like \"Get started\", \"Organize\")\nexport const sidebarText = style({\n display: \"flex\",\n alignItems: \"center\",\n gap: vars.space.sm,\n padding: `0.5rem 0.75rem 0.375rem`,\n color: vars.color.textLight,\n textDecoration: \"none\",\n fontWeight: 600,\n fontSize: vars.fontSize.sm,\n letterSpacing: \"-0.005em\",\n transition: `all ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n },\n \"&.active\": {\n color: vars.color.brand,\n },\n \"&.child-active\": {\n color: vars.color.text,\n },\n },\n})\n\nexport const sidebarTextButton = style({\n width: \"100%\",\n background: \"none\",\n border: \"none\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n fontFamily: \"inherit\",\n lineHeight: \"inherit\",\n textAlign: \"left\",\n cursor: \"pointer\",\n})\n\nexport const sidebarCollapse = style({\n display: \"flex\",\n alignItems: \"center\",\n alignSelf: \"center\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: vars.space.xs,\n color: vars.color.textLighter,\n borderRadius: \"50%\",\n transition: `all ${vars.transition.base}`,\n selectors: {\n \"&:hover\": {\n color: vars.color.text,\n },\n \"&.collapsed\": {\n transform: \"rotate(-90deg)\",\n },\n },\n})\n\nexport const sidebarCollapseWrapper = style({\n display: \"grid\",\n gridTemplateRows: \"1fr\",\n transition: `grid-template-rows ${vars.transition.slow}`,\n selectors: {\n '&[data-collapsed=\"true\"]': {\n gridTemplateRows: \"0fr\",\n },\n },\n})\n\nexport const sidebarCollapseInner = style({\n overflow: \"hidden\",\n minHeight: 0,\n})\n","import type { ComponentProps, ReactNode } from \"react\"\n\nimport { NavLink } from \"react-router\"\n\nimport type { ArdoContextItem, SidebarItem as SidebarItemType } from \"../config/types\"\n\nimport {\n BookOpenIcon,\n BoxIcon,\n CodeIcon,\n FileCodeIcon,\n FileTextIcon,\n PackageIcon,\n SettingsIcon,\n WrenchIcon,\n} from \"./icons\"\nimport * as styles from \"./Sidebar.css\"\n\ntype RoutePath = ComponentProps<typeof NavLink>[\"to\"]\n\nexport type SidebarRailItem = {\n key: string\n label: string\n to?: RoutePath\n icon?: ReactNode\n iconKey?: SidebarItemType[\"icon\"]\n active: boolean\n}\n\nexport function SidebarRail({ items }: { items: SidebarRailItem[] }) {\n if (items.length === 0) return null\n\n return (\n <nav aria-label=\"Documentation sections\" className={styles.sidebarRail}>\n <ul className={styles.sidebarRailList}>\n {items.map((item, index) => (\n <li key={item.key} className={styles.sidebarRailItem}>\n {item.to !== undefined ? (\n <NavLink\n to={item.to}\n aria-label={item.label}\n className={({ isActive }) =>\n [styles.sidebarRailLink, (item.active || isActive) && \"active\"]\n .filter(Boolean)\n .join(\" \")\n }\n >\n {resolveRailIcon(item, index)}\n </NavLink>\n ) : (\n <span className={styles.sidebarRailLink} aria-label={item.label}>\n {resolveRailIcon(item, index)}\n </span>\n )}\n <span className={styles.sidebarRailLabel} aria-hidden=\"true\">\n {item.label}\n </span>\n </li>\n ))}\n </ul>\n </nav>\n )\n}\n\nexport function getContextRailItems(\n contexts: ArdoContextItem[],\n activeId: string | undefined\n): SidebarRailItem[] {\n return contexts.map((ctx) => ({\n key: ctx.id,\n label: ctx.label,\n to: ctx.href,\n iconKey: inferContextIconKey(ctx),\n active: ctx.id === activeId,\n }))\n}\n\nfunction inferContextIconKey(ctx: ArdoContextItem): NonNullable<SidebarItemType[\"icon\"]> {\n const normalized = `${ctx.id} ${ctx.label}`.toLowerCase()\n if (normalized.includes(\"api\")) return \"api\"\n if (normalized.includes(\"component\")) return \"components\"\n if (normalized.includes(\"custom\") || normalized.includes(\"config\")) return \"settings\"\n if (normalized.includes(\"deploy\") || normalized.includes(\"trouble\")) return \"tools\"\n if (normalized.includes(\"guide\") || normalized.includes(\"intro\")) return \"guide\"\n if (normalized.includes(\"writing\") || normalized.includes(\"markdown\")) return \"docs\"\n return \"book\"\n}\n\nexport function getDataRailItems(items: SidebarItemType[], currentPath: string): SidebarRailItem[] {\n return items.map((item, index) => ({\n key: item.link ?? `${item.text}-${String(index)}`,\n label: item.text,\n to: item.link ?? findFirstItemLink(item.items ?? []),\n iconKey: item.icon,\n active: item.link === currentPath || hasActiveDataChild(item, currentPath),\n }))\n}\n\nexport function getTextLabel(children: ReactNode, fallback: string): string {\n if (typeof children === \"string\") return children\n if (typeof children === \"number\") return String(children)\n return fallback\n}\n\nfunction findFirstItemLink(items: SidebarItemType[]): string | undefined {\n for (const item of items) {\n if ((item.link ?? \"\") !== \"\") return item.link\n const nested = findFirstItemLink(item.items ?? [])\n if (nested !== undefined) return nested\n }\n return undefined\n}\n\nfunction hasActiveDataChild(item: SidebarItemType, currentPath: string): boolean {\n return (item.items ?? []).some(\n (child) => child.link === currentPath || hasActiveDataChild(child, currentPath)\n )\n}\n\nfunction resolveRailIcon(item: SidebarRailItem, index: number): ReactNode {\n if (item.icon !== undefined) return item.icon\n const iconKey = item.iconKey ?? inferIconKey(item.label, index)\n const Icon = iconByKey[iconKey]\n return <Icon size={18} strokeWidth={1.8} />\n}\n\nfunction inferIconKey(label: string, index: number): NonNullable<SidebarItemType[\"icon\"]> {\n const normalized = label.toLowerCase()\n if (normalized.includes(\"api\")) return \"api\"\n if (normalized.includes(\"component\")) return \"components\"\n if (normalized.includes(\"custom\") || normalized.includes(\"config\")) return \"settings\"\n if (normalized.includes(\"deploy\") || normalized.includes(\"trouble\")) return \"tools\"\n if (normalized.includes(\"writing\") || normalized.includes(\"markdown\")) return \"docs\"\n if (normalized.includes(\"intro\") || normalized.includes(\"guide\")) return \"guide\"\n return fallbackIconKeys[index % fallbackIconKeys.length]\n}\n\nconst iconByKey = {\n api: CodeIcon,\n book: BookOpenIcon,\n box: BoxIcon,\n code: FileCodeIcon,\n components: PackageIcon,\n docs: FileTextIcon,\n guide: BookOpenIcon,\n settings: SettingsIcon,\n tools: WrenchIcon,\n} satisfies Record<NonNullable<SidebarItemType[\"icon\"]>, typeof BookOpenIcon>\n\nconst fallbackIconKeys = [\n \"guide\",\n \"docs\",\n \"settings\",\n \"tools\",\n \"components\",\n \"box\",\n] satisfies Array<NonNullable<SidebarItemType[\"icon\"]>>\n","/* eslint-disable max-lines */\nimport {\n Children,\n type ComponentProps,\n createContext,\n isValidElement,\n type ReactElement,\n type ReactNode,\n use,\n useMemo,\n useState,\n} from \"react\"\nimport { NavLink, useLocation } from \"react-router\"\n\nimport type { SidebarItem as SidebarItemType } from \"../config/types\"\n\nimport { useArdoContexts, useArdoSidebar } from \"../runtime/hooks\"\nimport { ChevronDownIcon } from \"./icons\"\nimport * as styles from \"./Sidebar.css\"\nimport {\n getContextRailItems,\n getDataRailItems,\n getTextLabel,\n SidebarRail,\n type SidebarRailItem,\n} from \"./SidebarRail\"\n\n/** Route path type - uses React Router's NavLink 'to' prop type for type-safe routes */\ntype RoutePath = ComponentProps<typeof NavLink>[\"to\"]\n\n// =============================================================================\n// Sidebar Context\n// =============================================================================\n\ntype SidebarContextValue = {\n currentPath: string\n}\n\nconst SidebarContext = createContext<SidebarContextValue>({ currentPath: \"\" })\n\nfunction useSidebarContext() {\n return use(SidebarContext)\n}\n\n// =============================================================================\n// Sidebar Component Types\n// =============================================================================\n\nexport type ArdoSidebarProps = {\n /** Sidebar items (for data-driven approach) */\n items?: SidebarItemType[]\n /** Children for JSX composition (SidebarGroup, SidebarLink) */\n children?: ReactNode\n /** Content rendered above navigation (e.g. search) */\n header?: ReactNode\n /** Additional CSS classes */\n className?: string\n}\n\n// =============================================================================\n// Sidebar Main Component\n// =============================================================================\n\n/**\n * Sidebar component supporting data-driven, JSX composition, and zero-config patterns.\n *\n * When neither `items` nor `children` are provided, automatically renders from\n * the Ardo sidebar context (`virtual:ardo/sidebar`).\n *\n * @example Zero-config (from context)\n * ```tsx\n * <Sidebar />\n * ```\n *\n * @example Data-driven (items prop)\n * ```tsx\n * <Sidebar items={[\n * { text: 'Introduction', link: '/intro' },\n * { text: 'Guide', items: [\n * { text: 'Getting Started', link: '/guide/getting-started' }\n * ]}\n * ]} />\n * ```\n *\n * @example JSX composition\n * ```tsx\n * <Sidebar>\n * <SidebarLink to=\"/intro\">Introduction</SidebarLink>\n * <SidebarGroup title=\"Guide\">\n * <SidebarLink to=\"/guide/getting-started\">Getting Started</SidebarLink>\n * </SidebarGroup>\n * </Sidebar>\n * ```\n */\nexport function ArdoSidebar({ items, children, header, className }: ArdoSidebarProps) {\n const { pathname } = useLocation()\n const contextSidebar = useArdoSidebar()\n const { items: contexts, activeId } = useArdoContexts()\n const hasCustomChildren = children != null\n const resolvedItems = items ?? (hasCustomChildren ? undefined : contextSidebar)\n const hasResolvedItems = (resolvedItems?.length ?? 0) > 0\n // If contexts are configured, the rail is the world-switcher; otherwise\n // fall back to the legacy \"mirror sidebar sections as icons\" behaviour.\n const railItems =\n contexts.length > 0\n ? getContextRailItems(contexts, activeId)\n : hasCustomChildren\n ? getRailItemsFromChildren(children, pathname)\n : getDataRailItems(resolvedItems ?? [], pathname)\n const contextValue = useMemo(() => ({ currentPath: pathname }), [pathname])\n\n return (\n <SidebarContext value={contextValue}>\n <aside className={className ?? styles.sidebar}>\n <SidebarRail items={railItems} />\n <div className={styles.sidebarPanel}>\n {header != null && <div className={styles.sidebarHeader}>{header}</div>}\n <nav aria-label=\"Main navigation\" className={styles.sidebarNav}>\n {hasCustomChildren ? (\n <ul className={`${styles.sidebarList} ${styles.sidebarList0}`}>{children}</ul>\n ) : hasResolvedItems ? (\n <SidebarItems items={resolvedItems ?? []} depth={0} />\n ) : null}\n </nav>\n </div>\n </aside>\n </SidebarContext>\n )\n}\n\n// =============================================================================\n// SidebarGroup Component\n// =============================================================================\n\nexport type ArdoSidebarGroupProps = {\n /** Group title */\n title: string\n /** Optional icon shown in the desktop section rail */\n icon?: ReactNode\n /** Optional link for the group title */\n to?: string\n /** Initial collapsed state (default: false) */\n collapsed?: boolean\n /** Whether group is collapsible (default: true if has children) */\n collapsible?: boolean\n /** Children (SidebarLink, nested SidebarGroup) */\n children?: ReactNode\n /** Additional CSS classes */\n className?: string\n}\n\n/**\n * Group component for organizing sidebar links.\n *\n * @example\n * ```tsx\n * <SidebarGroup title=\"Guide\">\n * <SidebarLink to=\"/guide/intro\">Introduction</SidebarLink>\n * <SidebarLink to=\"/guide/setup\">Setup</SidebarLink>\n * </SidebarGroup>\n * ```\n *\n * @example With collapsible state\n * ```tsx\n * <SidebarGroup title=\"Advanced\" collapsed>\n * <SidebarLink to=\"/advanced/config\">Configuration</SidebarLink>\n * </SidebarGroup>\n * ```\n */\nexport function ArdoSidebarGroup({\n title,\n to,\n collapsed: initialCollapsed = false,\n collapsible = true,\n children,\n className,\n}: ArdoSidebarGroupProps) {\n const [collapsed, setCollapsed] = useState(initialCollapsed)\n const { currentPath } = useSidebarContext()\n\n // Check if any child is active\n const hasActiveChild = checkChildrenActive(children, currentPath)\n\n const textClassName = [styles.sidebarText, hasActiveChild && \"child-active\"]\n .filter(Boolean)\n .join(\" \")\n const textButtonClassName = [textClassName, styles.sidebarTextButton].join(\" \")\n\n const hasChildren = Children.count(children) > 0\n const hasTo = (to ?? \"\") !== \"\"\n const canToggle = collapsible && hasChildren\n\n const itemClassName =\n className ??\n [styles.sidebarItem, hasChildren && styles.sidebarItemGroup].filter(Boolean).join(\" \")\n\n return (\n <li className={itemClassName}>\n <div className={styles.sidebarItemHeader}>\n {hasTo ? (\n <NavLink\n to={to ?? \"/\"}\n end\n className={({ isActive }) =>\n [textClassName, isActive && \"active\"].filter(Boolean).join(\" \")\n }\n >\n {title}\n </NavLink>\n ) : (\n <button\n type=\"button\"\n className={textButtonClassName}\n onClick={() => {\n if (canToggle) {\n setCollapsed(!collapsed)\n }\n }}\n >\n {title}\n </button>\n )}\n\n {canToggle && (\n <button\n type=\"button\"\n className={[styles.sidebarCollapse, collapsed && \"collapsed\"].filter(Boolean).join(\" \")}\n onClick={() => {\n setCollapsed(!collapsed)\n }}\n aria-label={collapsed ? \"Expand\" : \"Collapse\"}\n >\n <ChevronDownIcon size={16} />\n </button>\n )}\n </div>\n\n {hasChildren && (\n <div className={styles.sidebarCollapseWrapper} data-collapsed={collapsed}>\n <div className={styles.sidebarCollapseInner}>\n <ul className={`${styles.sidebarList} ${styles.sidebarList1}`}>{children}</ul>\n </div>\n </div>\n )}\n </li>\n )\n}\n\n// =============================================================================\n// SidebarLink Component\n// =============================================================================\n\nexport type ArdoSidebarLinkProps = {\n /** Internal route path (type-safe with React Router's registered routes) */\n to: RoutePath\n /** Link text */\n children: ReactNode\n /** Additional CSS classes */\n className?: string\n}\n\n/**\n * Sidebar navigation link.\n *\n * @example\n * ```tsx\n * <SidebarLink to=\"/guide/getting-started\">Getting Started</SidebarLink>\n * ```\n */\nexport function ArdoSidebarLink({ to, children, className }: ArdoSidebarLinkProps) {\n const baseClassName = className ?? styles.sidebarLink\n return (\n <li className={styles.sidebarItem}>\n <NavLink\n to={to}\n className={({ isActive }) =>\n [baseClassName, isActive && \"active\"].filter(Boolean).join(\" \")\n }\n >\n {children}\n </NavLink>\n </li>\n )\n}\n\n// =============================================================================\n// Internal: Data-driven sidebar rendering\n// =============================================================================\n\ntype SidebarItemsProps = {\n items: SidebarItemType[]\n depth: number\n}\n\nfunction SidebarItems({ items, depth }: SidebarItemsProps) {\n return (\n <ul\n className={`${styles.sidebarList} ${depth === 0 ? styles.sidebarList0 : styles.sidebarList1}`}\n >\n {items.map((item) => (\n <SidebarItemComponent\n key={item.link ?? `${item.text}-${String(depth)}`}\n item={item}\n depth={depth}\n />\n ))}\n </ul>\n )\n}\n\ntype SidebarItemComponentProps = {\n item: SidebarItemType\n depth: number\n}\n\nfunction SidebarItemComponent({ item, depth }: SidebarItemComponentProps) {\n const { currentPath } = useSidebarContext()\n const [collapsed, setCollapsed] = useState(item.collapsed ?? false)\n const childItems = item.items ?? []\n\n const hasChildren = childItems.length > 0\n\n const hasActiveChild =\n hasChildren &&\n childItems.some(\n (child) =>\n child.link === currentPath ||\n child.items?.some((grandchild) => grandchild.link === currentPath)\n )\n const hasItemLink = (item.link ?? \"\") !== \"\"\n\n const linkClassName = [styles.sidebarLink, hasActiveChild && \"child-active\"]\n .filter(Boolean)\n .join(\" \")\n\n const textClassName = [styles.sidebarText, hasActiveChild && \"child-active\"]\n .filter(Boolean)\n .join(\" \")\n const textButtonClassName = [textClassName, styles.sidebarTextButton].join(\" \")\n\n const itemClassName = [styles.sidebarItem, hasChildren && styles.sidebarItemGroup]\n .filter(Boolean)\n .join(\" \")\n\n return (\n <li className={itemClassName}>\n <div className={styles.sidebarItemHeader}>\n {hasItemLink ? (\n <NavLink\n to={item.link ?? \"/\"}\n className={({ isActive }) =>\n [linkClassName, isActive && \"active\"].filter(Boolean).join(\" \")\n }\n >\n {item.text}\n </NavLink>\n ) : (\n <button\n type=\"button\"\n className={textButtonClassName}\n onClick={() => {\n if (hasChildren) {\n setCollapsed(!collapsed)\n }\n }}\n >\n {item.text}\n </button>\n )}\n\n {hasChildren && (\n <button\n type=\"button\"\n className={[styles.sidebarCollapse, collapsed && \"collapsed\"].filter(Boolean).join(\" \")}\n onClick={() => {\n setCollapsed(!collapsed)\n }}\n aria-label={collapsed ? \"Expand\" : \"Collapse\"}\n >\n <ChevronDownIcon size={16} />\n </button>\n )}\n </div>\n\n {hasChildren && (\n <div className={styles.sidebarCollapseWrapper} data-collapsed={collapsed}>\n <div className={styles.sidebarCollapseInner}>\n <SidebarItems items={childItems} depth={depth + 1} />\n </div>\n </div>\n )}\n </li>\n )\n}\n\n// =============================================================================\n// Sidebar Rail Data\n// =============================================================================\n\nfunction getRailItemsFromChildren(children: ReactNode, currentPath: string): SidebarRailItem[] {\n return Children.toArray(children)\n .filter(isValidElement)\n .map((child, index): SidebarRailItem | undefined => {\n if (isSidebarGroupElement(child)) {\n const { title, to, icon } = child.props\n return {\n key: to ?? title,\n label: title,\n to: to ?? findFirstChildLink(child.props.children),\n icon,\n active: to === currentPath || checkChildrenActive(child.props.children, currentPath),\n }\n }\n\n if (isSidebarLinkElement(child)) {\n const label = getTextLabel(child.props.children, `Section ${String(index + 1)}`)\n return {\n key: `${label}-${String(index)}`,\n label,\n to: child.props.to,\n active: child.props.to === currentPath,\n }\n }\n\n return undefined\n })\n .filter((item): item is SidebarRailItem => item !== undefined)\n}\n\nfunction findFirstChildLink(children: ReactNode): RoutePath | undefined {\n for (const child of Children.toArray(children)) {\n if (!isValidElement(child)) continue\n if (isSidebarLinkElement(child)) return child.props.to\n if (isSidebarGroupElement(child)) return findFirstGroupLink(child)\n }\n return undefined\n}\n\nfunction findFirstGroupLink(child: ReactElement<ArdoSidebarGroupProps>): RoutePath | undefined {\n if ((child.props.to ?? \"\") !== \"\") return child.props.to\n return findFirstChildLink(child.props.children)\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\nfunction isSidebarChildActive(child: ReactElement, currentPath: string): boolean {\n if (isSidebarLinkElement(child)) {\n return child.props.to === currentPath\n }\n if (isSidebarGroupElement(child)) {\n const groupProps = child.props\n return (\n groupProps.to === currentPath ||\n (groupProps.children != null && checkChildrenActive(groupProps.children, currentPath))\n )\n }\n return false\n}\n\nfunction checkChildrenActive(children: ReactNode, currentPath: string): boolean {\n return Children.toArray(children).some(\n (child) => isValidElement(child) && isSidebarChildActive(child, currentPath)\n )\n}\n\nfunction isSidebarLinkElement(child: ReactElement): child is ReactElement<ArdoSidebarLinkProps> {\n return child.type === ArdoSidebarLink\n}\n\nfunction isSidebarGroupElement(child: ReactElement): child is ReactElement<ArdoSidebarGroupProps> {\n return child.type === ArdoSidebarGroup\n}\n","import { cloneElement, isValidElement, type ReactNode, useMemo } from \"react\"\nimport { Outlet, useLocation, useMatches } from \"react-router\"\n\nimport type { ArdoConfig, ArdoContextItem, SidebarItem } from \"../config/types\"\n\nimport { ArdoProvider, type ArdoSiteConfig, ArdoSiteConfigProvider } from \"../runtime/hooks\"\nimport { ArdoFooter, type ArdoFooterProps } from \"./Footer\"\nimport { ArdoHeader, type ArdoHeaderProps } from \"./Header\"\nimport { ArdoLayout } from \"./Layout\"\nimport * as layoutStyles from \"./Layout.css\"\nimport { ArdoSidebar, type ArdoSidebarProps } from \"./Sidebar\"\n\n// =============================================================================\n// ArdoRoot Component\n// =============================================================================\n\nexport type ArdoRootProps = {\n /** Ardo config (from virtual:ardo/config) */\n config: ArdoConfig\n /**\n * Sidebar data.\n *\n * - `SidebarItem[]` — a single sidebar shown for every non-bare route\n * (from `virtual:ardo/sidebar`, back-compat).\n * - `Record<string, SidebarItem[]>` — a per-context sidebar map\n * (from `virtual:ardo/sidebars`). The active context's sidebar is\n * shown; the key matches the `id` of the matching `ArdoContextItem`.\n */\n sidebar: Record<string, SidebarItem[]> | SidebarItem[]\n /**\n * Top-level navigation contexts shown in the sidebar rail. When provided,\n * the rail renders these as world-switcher items and `sidebar` is treated\n * as a map keyed by context id.\n */\n contexts?: ArdoContextItem[]\n /** Custom header element (overrides auto-generated header) */\n header?: ReactNode\n /** Custom sidebar element (overrides auto-generated sidebar) */\n sidebarContent?: ReactNode\n /** Custom footer element (overrides auto-generated footer) */\n footer?: ReactNode\n /** Props passed to auto-generated ArdoHeader (ignored when header is provided) */\n headerProps?: ArdoHeaderProps\n /** Props passed to auto-generated ArdoSidebar (ignored when sidebarContent is provided) */\n sidebarProps?: ArdoSidebarProps\n /** Props passed to auto-generated ArdoFooter (ignored when footer is provided) */\n footerProps?: ArdoFooterProps\n /** Edit link configuration (applied site-wide via ArdoSiteConfig) */\n editLink?: { pattern: string; text?: string }\n /** Last updated configuration (applied site-wide via ArdoSiteConfig) */\n lastUpdated?: { enabled?: boolean; text?: string; formatOptions?: Intl.DateTimeFormatOptions }\n /** TOC label (applied site-wide via ArdoSiteConfig) */\n tocLabel?: string\n /** Additional CSS classes for the layout */\n className?: string\n /** Content to render (defaults to <Outlet />) */\n children?: ReactNode\n}\n\n/**\n * All-in-one root component that combines ArdoProvider, Layout, Header,\n * Sidebar, Footer, and homepage detection into a single component.\n *\n * @example Minimal usage\n * ```tsx\n * import config from \"virtual:ardo/config\"\n * import sidebar from \"virtual:ardo/sidebar\"\n *\n * export default function Root() {\n * return <ArdoRoot config={config} sidebar={sidebar} />\n * }\n * ```\n *\n * @example With custom nav and footer overrides\n * ```tsx\n * export default function Root() {\n * return (\n * <ArdoRoot\n * config={config}\n * sidebar={sidebar}\n * headerProps={{\n * nav: (\n * <Nav>\n * <NavLink to=\"/guide\">Guide</NavLink>\n * <NavLink to=\"/api\">API</NavLink>\n * </Nav>\n * ),\n * }}\n * footerProps={{\n * message: \"Released under the MIT License.\",\n * }}\n * editLink={{\n * pattern: \"https://github.com/user/repo/edit/main/docs/:path\",\n * text: \"Edit this page on GitHub\",\n * }}\n * lastUpdated={{ enabled: true }}\n * />\n * )\n * }\n * ```\n */\nfunction resolveRootHeader(\n header: ReactNode,\n headerProps: ArdoHeaderProps | undefined,\n mobileMenuContent: ReactNode\n): ReactNode {\n if (header != null) {\n return enhanceHeaderWithMobileMenuContent(header, mobileMenuContent)\n }\n return (\n <ArdoHeader\n {...headerProps}\n mobileMenuContent={headerProps?.mobileMenuContent ?? mobileMenuContent}\n />\n )\n}\n\nfunction resolveLayoutClassName(className: string | undefined, isBareLayout: boolean): string {\n if (className != null) return className\n return isBareLayout ? `${layoutStyles.layout} ${layoutStyles.home}` : layoutStyles.layout\n}\n\nfunction readLayoutHandle(handle: unknown): string | undefined {\n if (typeof handle !== \"object\" || handle === null) return undefined\n if (!(\"layout\" in handle)) return undefined\n const { layout } = handle\n return typeof layout === \"string\" ? layout : undefined\n}\n\n/**\n * Reads the React Router `handle` exports from every active route match and\n * returns the most specific `layout` value (the deepest match wins). MDX\n * routes get this export auto-generated from `frontmatter.layout`; .tsx\n * routes set it directly with `export const handle = { layout: \"bare\" }`.\n */\nfunction useRouteLayout(): string | undefined {\n const matches = useMatches()\n for (let i = matches.length - 1; i >= 0; i--) {\n const layout = readLayoutHandle(matches[i].handle)\n if (layout !== undefined) return layout\n }\n return undefined\n}\n\nfunction contextMatchesPath(ctx: ArdoContextItem, pathname: string): boolean {\n if (ctx.match != null) {\n return typeof ctx.match === \"string\" ? pathname.startsWith(ctx.match) : ctx.match.test(pathname)\n }\n const firstSegment = ctx.href.split(\"/\").find((segment) => segment !== \"\")\n if (firstSegment === undefined) return false\n const root = `/${firstSegment}`\n return pathname === root || pathname.startsWith(`${root}/`)\n}\n\nfunction findActiveContext(\n contexts: ArdoContextItem[] | undefined,\n pathname: string\n): ArdoContextItem | undefined {\n return contexts?.find((ctx) => contextMatchesPath(ctx, pathname))\n}\n\nfunction resolveContextSidebar(\n sidebar: Record<string, SidebarItem[]> | SidebarItem[],\n activeContext: ArdoContextItem | undefined\n): SidebarItem[] {\n if (Array.isArray(sidebar)) return sidebar\n if (activeContext == null) return []\n return sidebar[activeContext.id] ?? []\n}\n\nexport function ArdoRoot({\n config,\n sidebar,\n contexts,\n header,\n sidebarContent,\n footer,\n headerProps,\n sidebarProps,\n footerProps,\n editLink,\n lastUpdated,\n tocLabel,\n className,\n children,\n}: ArdoRootProps) {\n const location = useLocation()\n const layout = useRouteLayout()\n // Bare layout: no sidebar, no rail — used for the home page and any other\n // marketing-style routes (TSX or MDX). Falls back to the legacy hardcoded\n // home detection if a route hasn't opted in via `handle.layout`.\n const isBareLayout = layout === \"bare\" || location.pathname === \"/\" || location.pathname === \"\"\n const activeContext = useMemo(\n () => findActiveContext(contexts, location.pathname),\n [contexts, location.pathname]\n )\n const sidebarItems = useMemo(\n () => resolveContextSidebar(sidebar, activeContext),\n [sidebar, activeContext]\n )\n // Search lives in the header now. The sidebar no longer carries it.\n const resolvedSidebar = isBareLayout ? undefined : resolveSidebar(sidebarContent, sidebarProps)\n const resolvedHeader = resolveRootHeader(\n header,\n headerProps,\n isBareLayout ? undefined : resolvedSidebar\n )\n\n const siteConfig = useMemo<ArdoSiteConfig>(\n () => ({ editLink, lastUpdated, tocLabel }),\n [editLink, lastUpdated, tocLabel]\n )\n\n const content = (\n <ArdoProvider\n config={config}\n sidebar={sidebarItems}\n contexts={contexts}\n activeContextId={activeContext?.id}\n >\n <ArdoLayout\n className={resolveLayoutClassName(className, isBareLayout)}\n header={resolvedHeader}\n sidebar={resolvedSidebar}\n footer={footer ?? <ArdoFooter {...footerProps} />}\n >\n {children ?? <Outlet />}\n </ArdoLayout>\n </ArdoProvider>\n )\n\n const hasSiteConfig =\n editLink !== undefined || lastUpdated !== undefined || (tocLabel ?? \"\") !== \"\"\n return hasSiteConfig ? (\n <ArdoSiteConfigProvider value={siteConfig}>{content}</ArdoSiteConfigProvider>\n ) : (\n content\n )\n}\n\n/**\n * Resolves the sidebar element. Custom content is passed through as-is;\n * when none is given, a default data-driven <ArdoSidebar> is created.\n */\nfunction resolveSidebar(\n sidebarContent: ReactNode | undefined,\n sidebarProps: ArdoSidebarProps | undefined\n): ReactNode {\n if (sidebarContent == null) {\n return <ArdoSidebar {...sidebarProps} />\n }\n if (isValidElement(sidebarContent)) {\n return sidebarContent\n }\n return <ArdoSidebar>{sidebarContent}</ArdoSidebar>\n}\n\nfunction enhanceHeaderWithMobileMenuContent(\n header: ReactNode,\n mobileMenuContent: ReactNode\n): ReactNode {\n if (!isValidElement<ArdoHeaderProps>(header) || header.type !== ArdoHeader) {\n return header\n }\n\n const existingMobileMenuContent = header.props.mobileMenuContent\n if (existingMobileMenuContent !== undefined) {\n return header\n }\n\n return cloneElement(header, { mobileMenuContent })\n}\n","import { globalStyle, style } from \"@vanilla-extract/css\"\n\nimport { fadeInUp } from \"../theme/animations.css\"\nimport { vars } from \"../theme/contract.css\"\n\nconst brandBorder = `color-mix(in oklch, ${vars.color.brand} 38%, ${vars.color.border})`\nconst brandRing = `color-mix(in oklch, ${vars.color.brand} 12%, transparent)`\n\nexport const features = style({\n padding: \"80px 24px\",\n background: vars.color.bgSoft,\n borderTop: `1px solid ${vars.color.border}`,\n \"@media\": {\n \"(max-width: 768px)\": {\n padding: \"48px 16px\",\n },\n },\n})\n\nexport const featuresHeader = style({\n textAlign: \"center\",\n marginBottom: \"48px\",\n})\n\nexport const featuresTitle = style({\n fontSize: \"36px\",\n fontWeight: 700,\n letterSpacing: \"-0.02em\",\n marginBottom: \"12px\",\n textWrap: \"balance\",\n \"@media\": {\n \"(max-width: 768px)\": {\n fontSize: \"28px\",\n },\n },\n})\n\nexport const featuresSubtitle = style({\n fontSize: \"18px\",\n color: vars.color.textLight,\n maxWidth: \"560px\",\n margin: \"0 auto\",\n textWrap: \"pretty\",\n \"@media\": {\n \"(max-width: 768px)\": {\n fontSize: \"16px\",\n },\n },\n})\n\nexport const featuresContainer = style({\n display: \"grid\",\n gridTemplateColumns: \"repeat(auto-fit, minmax(260px, 1fr))\",\n gap: \"20px\",\n maxWidth: \"1100px\",\n margin: \"0 auto\",\n})\n\nexport const feature = style({\n padding: vars.space.lg,\n background: vars.color.bg,\n borderRadius: vars.radius.lg,\n border: `1px solid ${vars.color.border}`,\n boxShadow: vars.color.shadowSm,\n transition: `all ${vars.transition.base}`,\n animation: `${fadeInUp} 0.5s ease both`,\n selectors: {\n \"&:hover\": {\n borderColor: brandBorder,\n boxShadow: `${vars.color.shadowMd}, 0 0 0 1px ${brandRing}`,\n },\n },\n \"@media\": {\n \"(hover: hover)\": {\n selectors: {\n \"&:hover\": {\n transform: \"translateY(-3px)\",\n },\n },\n },\n \"(prefers-reduced-motion: reduce)\": {\n animation: \"none\",\n selectors: {\n \"&:hover\": {\n transform: \"none\",\n },\n },\n },\n },\n})\n\n// Stagger animation delays\nfor (let i = 1; i <= 6; i++) {\n globalStyle(`${featuresContainer} ${feature}:nth-child(${i})`, {\n animationDelay: `${(i - 1) * 80}ms`,\n })\n}\n\nexport const featureIcon = style({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"48px\",\n height: \"48px\",\n marginBottom: \"16px\",\n background: vars.color.brandSubtle,\n border: `1px solid color-mix(in oklch, ${vars.color.brand} 16%, ${vars.color.border})`,\n borderRadius: \"50%\",\n color: vars.color.brand,\n transition: `all ${vars.transition.base}`,\n})\n\nglobalStyle(`${feature}:hover ${featureIcon}`, {\n background: vars.color.brand,\n color: \"white\",\n borderColor: \"transparent\",\n})\n\nexport const featureTitle = style({\n fontSize: \"17px\",\n fontWeight: 600,\n marginBottom: \"10px\",\n letterSpacing: \"-0.01em\",\n textWrap: \"balance\",\n})\n\nexport const featureDetails = style({\n fontSize: \"14px\",\n color: vars.color.textLight,\n lineHeight: 1.6,\n marginBottom: \"12px\",\n textWrap: \"pretty\",\n})\n\nexport const featureLink = style({\n fontSize: \"14px\",\n fontWeight: 500,\n color: vars.color.brand,\n textDecoration: \"none\",\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n transition: `gap ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n gap: \"8px\",\n },\n \"&::after\": {\n content: '\"\\\\2192\"',\n },\n },\n})\n","import type { ReactNode } from \"react\"\n\nimport { Link } from \"react-router\"\n\nimport * as styles from \"./Features.css\"\n\nexport type ArdoFeaturesProps = {\n /** Feature cards as children */\n children: ReactNode\n /** Section title */\n title?: string\n /** Section subtitle */\n subtitle?: string\n /** Additional CSS class */\n className?: string\n}\n\nexport type ArdoFeatureCardProps = {\n /** Feature title */\n title: string\n /** Icon as ReactNode (emoji, Lucide icon component, or any JSX) */\n icon?: ReactNode\n /** Feature description as children */\n children: ReactNode\n /** Optional link */\n link?: string\n /** Link text (defaults to \"Learn more\") */\n linkText?: string\n /** Additional CSS class */\n className?: string\n}\n\n/**\n * Individual feature card component.\n *\n * @example\n * ```tsx\n * import { Zap } from \"lucide-react\"\n *\n * <ArdoFeatureCard title=\"Fast\" icon={<Zap size={28} />}>\n * Lightning fast builds with Vite\n * </ArdoFeatureCard>\n * ```\n */\nexport function ArdoFeatureCard({\n title,\n icon,\n children,\n link,\n linkText,\n className,\n}: ArdoFeatureCardProps) {\n const hasIcon = icon != null\n const hasLink = (link ?? \"\") !== \"\"\n const resolvedLinkText = linkText ?? \"Learn more\"\n\n return (\n <div className={className ?? styles.feature}>\n {hasIcon && <div className={styles.featureIcon}>{icon}</div>}\n <h3 className={styles.featureTitle}>{title}</h3>\n <p className={styles.featureDetails}>{children}</p>\n {hasLink && (\n <Link to={link ?? \"\"} className={styles.featureLink}>\n {resolvedLinkText}\n </Link>\n )}\n </div>\n )\n}\n\n/**\n * Features grid component for displaying multiple feature cards.\n *\n * @example\n * ```tsx\n * <ArdoFeatures title=\"Key Features\" subtitle=\"Everything you need\">\n * <ArdoFeatureCard title=\"React-First\" icon=\"⚛️\">Built on React.</ArdoFeatureCard>\n * <ArdoFeatureCard title=\"Fast\" icon=\"⚡\">Powered by Vite.</ArdoFeatureCard>\n * </ArdoFeatures>\n * ```\n */\nexport function ArdoFeatures({ children, title, subtitle, className }: ArdoFeaturesProps) {\n const hasTitle = (title ?? \"\") !== \"\"\n const hasSubtitle = (subtitle ?? \"\") !== \"\"\n const hasHeader = hasTitle || hasSubtitle\n\n return (\n <section className={className ?? styles.features}>\n {hasHeader && (\n <div className={styles.featuresHeader}>\n {hasTitle && <h2 className={styles.featuresTitle}>{title}</h2>}\n {hasSubtitle && <p className={styles.featuresSubtitle}>{subtitle}</p>}\n </div>\n )}\n <div className={styles.featuresContainer}>{children}</div>\n </section>\n )\n}\n","import { globalStyle, style } from \"@vanilla-extract/css\"\n\nimport { fadeInUp } from \"../theme/animations.css\"\nimport { vars } from \"../theme/contract.css\"\n\nconst brandHalo = `color-mix(in oklch, ${vars.color.brand} 26%, transparent)`\nconst brandHaloStrong = `color-mix(in oklch, ${vars.color.brand} 36%, transparent)`\nconst brandTint = `color-mix(in oklch, ${vars.color.brand} 10%, transparent)`\nconst brandTintSoft = `color-mix(in oklch, ${vars.color.brand} 6%, transparent)`\n\nexport const hero = style({\n padding: \"100px 24px 80px\",\n textAlign: \"center\",\n position: \"relative\",\n overflow: \"hidden\",\n selectors: {\n \"&::before\": {\n content: '\"\"',\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background: `radial-gradient(ellipse 60% 50% at 30% 0%, ${brandTintSoft} 0%, transparent 60%), radial-gradient(ellipse 80% 50% at 70% -10%, ${brandTint} 0%, transparent 70%), linear-gradient(180deg, ${vars.color.bg} 0%, ${vars.color.bgSoft} 100%)`,\n pointerEvents: \"none\",\n },\n \".dark &::before\": {\n background: `radial-gradient(ellipse 60% 50% at 30% 0%, color-mix(in oklch, ${vars.color.brand} 12%, transparent) 0%, transparent 60%), radial-gradient(ellipse 80% 50% at 70% -10%, color-mix(in oklch, ${vars.color.brand} 18%, transparent) 0%, transparent 70%), linear-gradient(180deg, ${vars.color.bg} 0%, ${vars.color.bgSoft} 100%)`,\n },\n },\n \"@media\": {\n \"(max-width: 768px)\": {\n padding: \"60px 20px\",\n },\n },\n})\n\nexport const heroContainer = style({\n maxWidth: \"800px\",\n margin: \"0 auto\",\n position: \"relative\",\n zIndex: 1,\n})\n\nexport const heroAnimate = style({\n animation: `${fadeInUp} 0.6s ease both`,\n \"@media\": {\n \"(prefers-reduced-motion: reduce)\": {\n animation: \"none\",\n },\n },\n})\n\nglobalStyle(`${hero} img`, {\n maxWidth: \"180px\",\n marginBottom: \"40px\",\n filter: \"drop-shadow(0 4px 18px oklch(0 0 0 / 0.12))\",\n})\n\nexport const heroVersion = style({\n display: \"inline-block\",\n padding: \"4px 14px\",\n fontSize: \"13px\",\n fontWeight: 600,\n color: vars.color.brand,\n background: vars.color.brandSubtle,\n border: `1px solid color-mix(in oklch, ${vars.color.brand} 20%, ${vars.color.border})`,\n borderRadius: \"999px\",\n marginBottom: \"16px\",\n letterSpacing: \"0.02em\",\n})\n\nexport const heroName = style({\n fontSize: \"64px\",\n fontWeight: 800,\n background: vars.color.brandGradient,\n WebkitBackgroundClip: \"text\",\n WebkitTextFillColor: \"transparent\",\n backgroundClip: \"text\",\n letterSpacing: \"-0.03em\",\n lineHeight: 1.1,\n textWrap: \"balance\",\n \"@media\": {\n \"(max-width: 768px)\": {\n fontSize: \"40px\",\n },\n },\n})\n\nexport const heroText = style({\n fontSize: \"48px\",\n fontWeight: 700,\n marginTop: \"8px\",\n letterSpacing: \"-0.02em\",\n lineHeight: 1.15,\n textWrap: \"balance\",\n \"@media\": {\n \"(max-width: 768px)\": {\n fontSize: \"28px\",\n },\n },\n})\n\nexport const heroTagline = style({\n fontSize: \"18px\",\n color: vars.color.textLight,\n marginTop: \"24px\",\n maxWidth: \"560px\",\n marginLeft: \"auto\",\n marginRight: \"auto\",\n lineHeight: 1.65,\n textWrap: \"pretty\",\n \"@media\": {\n \"(max-width: 768px)\": {\n fontSize: \"16px\",\n },\n },\n})\n\nexport const heroActions = style({\n display: \"flex\",\n justifyContent: \"center\",\n gap: \"16px\",\n marginTop: \"40px\",\n flexWrap: \"wrap\",\n})\n\nexport const heroAction = style({\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"14px 28px\",\n fontSize: \"15px\",\n fontWeight: 600,\n textDecoration: \"none\",\n borderRadius: vars.radius.base,\n transition: `all ${vars.transition.base}`,\n})\n\nexport const heroActionBrand = style({\n background: vars.color.brand,\n color: \"white\",\n boxShadow: `0 4px 14px ${brandHalo}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.brandDark,\n boxShadow: `0 6px 20px ${brandHaloStrong}`,\n },\n },\n \"@media\": {\n \"(hover: hover)\": {\n selectors: {\n \"&:hover\": {\n transform: \"translateY(-2px)\",\n },\n },\n },\n \"(prefers-reduced-motion: reduce)\": {\n selectors: {\n \"&:hover\": {\n transform: \"none\",\n },\n },\n },\n },\n})\n\nexport const heroActionAlt = style({\n background: vars.color.bg,\n color: vars.color.text,\n border: `1px solid ${vars.color.border}`,\n selectors: {\n \"&:hover\": {\n borderColor: vars.color.brand,\n color: vars.color.brand,\n },\n },\n})\n","import type { ComponentProps, ReactNode } from \"react\"\n\nimport { Link } from \"react-router\"\n\nimport * as styles from \"./Hero.css\"\n\n/** Internal route path from React Router */\ntype RoutePath = ComponentProps<typeof Link>[\"to\"]\n\nexport type ArdoHeroAction = {\n /** Button text */\n text: string\n /** Link destination - internal route path or external URL */\n link: RoutePath\n /** Visual theme: \"brand\" for primary, \"alt\" for secondary */\n theme?: \"alt\" | \"brand\"\n /** Optional icon as ReactNode (e.g. Lucide icon component) */\n icon?: ReactNode\n}\n\nexport type ArdoHeroImage = {\n /** Image for light mode */\n light: string\n /** Image for dark mode */\n dark?: string\n /** Alt text for the image */\n alt?: string\n}\n\nexport type ArdoHeroProps = {\n /** Large title displayed prominently */\n name?: string\n /** Secondary text below the name */\n text?: string\n /** Descriptive tagline */\n tagline?: string\n /** Hero image - can be a string URL or an object with light/dark variants */\n image?: ArdoHeroImage | string\n /** Call-to-action buttons */\n actions?: ArdoHeroAction[]\n /** Additional CSS class */\n className?: string\n /** Version string displayed as a pill badge above the name */\n version?: string\n}\n\n/**\n * Hero section component for landing pages.\n *\n * @example\n * ```tsx\n * import { ArrowRight, Github } from \"lucide-react\"\n *\n * <Hero\n * name=\"Ardo\"\n * text=\"React-first Documentation\"\n * tagline=\"Build beautiful documentation sites with React.\"\n * image=\"/logo.svg\"\n * actions={[\n * { text: \"Get Started\", link: \"/guide/getting-started\", theme: \"brand\", icon: <ArrowRight size={16} /> },\n * { text: \"GitHub\", link: \"https://github.com/...\", theme: \"alt\", icon: <Github size={16} /> }\n * ]}\n * />\n * ```\n */\nfunction HeroActionButton({ action }: { action: ArdoHeroAction }) {\n const link = action.link\n const isExternal =\n typeof link === \"string\" && (link.startsWith(\"http://\") || link.startsWith(\"https://\"))\n const cls = `${styles.heroAction} ${action.theme === \"alt\" ? styles.heroActionAlt : styles.heroActionBrand}`\n const content = (\n <>\n {action.icon}\n {action.text}\n </>\n )\n\n if (isExternal) {\n return (\n <a href={link} className={cls} target=\"_blank\" rel=\"noopener noreferrer\">\n {content}\n </a>\n )\n }\n return (\n <Link to={link} className={cls}>\n {content}\n </Link>\n )\n}\n\nfunction resolveHeroImage(image: ArdoHeroProps[\"image\"], name: string | undefined) {\n const url = typeof image === \"string\" ? image : (image?.light ?? \"\")\n const alt = typeof image === \"string\" ? (name ?? \"\") : (image?.alt ?? name ?? \"\")\n return { url, alt }\n}\n\nexport function ArdoHero({\n name,\n text,\n tagline,\n image,\n actions,\n className,\n version,\n}: ArdoHeroProps) {\n const img = resolveHeroImage(image, name)\n\n return (\n <section className={className ?? styles.hero}>\n <div className={`${styles.heroContainer} ${styles.heroAnimate}`}>\n {img.url !== \"\" && (\n <div>\n <img src={img.url} alt={img.alt} />\n </div>\n )}\n <div>\n {(version ?? \"\") !== \"\" && <span className={styles.heroVersion}>v{version}</span>}\n {(name ?? \"\") !== \"\" && <h1 className={styles.heroName}>{name}</h1>}\n {(text ?? \"\") !== \"\" && <p className={styles.heroText}>{text}</p>}\n {(tagline ?? \"\") !== \"\" && <p className={styles.heroTagline}>{tagline}</p>}\n {(actions?.length ?? 0) > 0 && (\n <div className={styles.heroActions}>\n {actions?.map((action) => {\n const key =\n typeof action.link === \"string\" ? `${action.link}-${action.text}` : action.text\n return <HeroActionButton key={key} action={action} />\n })}\n </div>\n )}\n </div>\n </div>\n </section>\n )\n}\n","import { style } from \"@vanilla-extract/css\"\n\nimport { vars } from \"./theme/contract.css\"\n\nexport const root = style({\n minHeight: \"calc(100vh - 6rem)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: `${vars.space[\"3xl\"]} ${vars.space.lg}`,\n})\n\nexport const card = style({\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n textAlign: \"center\",\n maxWidth: \"32rem\",\n})\n\nexport const owl = style({\n color: vars.color.brand,\n opacity: 0.85,\n marginBottom: vars.space.lg,\n})\n\nexport const status = style({\n fontFamily: vars.font.mono,\n fontSize: vars.fontSize.xs,\n letterSpacing: \"0.08em\",\n textTransform: \"uppercase\",\n color: vars.color.textLighter,\n marginBottom: vars.space.sm,\n})\n\nexport const title = style({\n fontSize: \"clamp(1.5rem, 3vw, 2rem)\",\n fontFamily: vars.font.familyHeading,\n fontWeight: 700,\n lineHeight: 1.15,\n letterSpacing: \"-0.01em\",\n color: vars.color.text,\n marginBottom: vars.space.sm,\n textWrap: \"balance\",\n})\n\nexport const description = style({\n fontSize: vars.fontSize.base,\n lineHeight: 1.6,\n color: vars.color.textLight,\n marginBottom: vars.space.xl,\n textWrap: \"pretty\",\n})\n\nexport const actions = style({\n display: \"flex\",\n gap: vars.space.sm,\n flexWrap: \"wrap\",\n justifyContent: \"center\",\n})\n\nexport const primaryAction = style({\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: vars.space.xs,\n padding: `0.625rem ${vars.space.lg}`,\n background: vars.color.brand,\n color: vars.color.bg,\n fontSize: vars.fontSize.sm,\n fontWeight: 500,\n textDecoration: \"none\",\n borderRadius: vars.radius.base,\n transition: `background ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n background: vars.color.brandDark,\n },\n },\n})\n\nexport const secondaryAction = style({\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: vars.space.xs,\n padding: `0.625rem ${vars.space.lg}`,\n background: \"transparent\",\n color: vars.color.text,\n fontSize: vars.fontSize.sm,\n fontWeight: 500,\n textDecoration: \"none\",\n borderRadius: vars.radius.base,\n border: `1px solid ${vars.color.border}`,\n transition: `border-color ${vars.transition.fast}, background ${vars.transition.fast}`,\n selectors: {\n \"&:hover\": {\n borderColor: vars.color.brand,\n background: vars.color.bgSoft,\n },\n },\n})\n\nexport const details = style({\n marginTop: vars.space.xl,\n width: \"100%\",\n textAlign: \"left\",\n fontSize: vars.fontSize.xs,\n color: vars.color.textLight,\n})\n\nexport const detailsSummary = style({\n cursor: \"pointer\",\n color: vars.color.textLighter,\n marginBottom: vars.space.sm,\n selectors: {\n \"&:hover\": { color: vars.color.text },\n },\n})\n\nexport const detailsPre = style({\n margin: 0,\n padding: vars.space.md,\n background: vars.color.codeBg,\n border: `1px solid ${vars.color.codeBorder}`,\n borderRadius: vars.radius.base,\n fontFamily: vars.font.mono,\n fontSize: vars.fontSize.xs,\n lineHeight: 1.5,\n overflowX: \"auto\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n})\n","import { isRouteErrorResponse, Link, useRouteError } from \"react-router\"\n\nimport * as styles from \"./ErrorBoundary.css\"\nimport { ArdoOwlMark } from \"./OwlMark\"\n\nexport type ArdoErrorBoundaryProps = {\n /** Override the heading/description shown for 404 responses. */\n notFound?: {\n title?: string\n description?: string\n homeLabel?: string\n homeHref?: string\n }\n /** Override the heading/description shown for non-404 errors. */\n error?: {\n title?: string\n description?: string\n homeLabel?: string\n homeHref?: string\n }\n}\n\nconst defaults = {\n notFound: {\n title: \"This page wandered off\",\n description:\n \"The page you were looking for has moved, been renamed, or never existed. The owl is on the case.\",\n homeLabel: \"Back to home\",\n homeHref: \"/\",\n },\n error: {\n title: \"Something went wrong\",\n description:\n \"An unexpected error happened while loading this page. Try again, or head back to safer ground.\",\n homeLabel: \"Back to home\",\n homeHref: \"/\",\n },\n} as const\n\n/**\n * Themed error/404 page. Drop into a React Router route as `ErrorBoundary`\n * to replace the default unstyled fallback with a layout-aware page.\n *\n * @example\n * ```tsx\n * // app/root.tsx\n * export { ArdoErrorBoundary as ErrorBoundary } from \"ardo/ui\"\n * ```\n */\nexport function ArdoErrorBoundary(props: ArdoErrorBoundaryProps = {}) {\n const error = useRouteError()\n const is404 = isRouteErrorResponse(error) && error.status === 404\n const isRouteError = isRouteErrorResponse(error)\n\n const copy = is404\n ? { ...defaults.notFound, ...props.notFound }\n : { ...defaults.error, ...props.error }\n\n const statusLabel = isRouteError ? `Error ${String(error.status)}` : \"Error\"\n const errorDetails = is404 ? undefined : formatErrorDetails(error)\n\n return (\n <main className={styles.root}>\n <section className={styles.card}>\n <ArdoOwlMark size={120} className={styles.owl} title=\"\" />\n <p className={styles.status}>{statusLabel}</p>\n <h1 className={styles.title}>{copy.title}</h1>\n <p className={styles.description}>{copy.description}</p>\n <div className={styles.actions}>\n <Link to={copy.homeHref} className={styles.primaryAction}>\n {copy.homeLabel}\n </Link>\n {!is404 && (\n <button\n type=\"button\"\n onClick={() => {\n globalThis.location.reload()\n }}\n className={styles.secondaryAction}\n >\n Reload\n </button>\n )}\n </div>\n {errorDetails != null && (\n <details className={styles.details}>\n <summary className={styles.detailsSummary}>Technical details</summary>\n <pre className={styles.detailsPre}>{errorDetails}</pre>\n </details>\n )}\n </section>\n </main>\n )\n}\n\nfunction formatErrorDetails(error: unknown): string | undefined {\n if (isRouteErrorResponse(error)) {\n if (typeof error.data === \"string\" && error.data.length > 0) return error.data\n return undefined\n }\n if (error instanceof Error) {\n return error.stack ?? error.message\n }\n return undefined\n}\n","import type { ReactNode } from \"react\"\n\nimport { Link } from \"react-router\"\n\nimport { useArdoConfig, useArdoPageData } from \"../runtime/hooks\"\nimport { ArdoFeatureCard, ArdoFeatures } from \"./components/Features\"\nimport * as heroStyles from \"./components/Hero.css\"\nimport { ArdoFooter, type ArdoFooterProps } from \"./Footer\"\nimport { ArdoHeader, type ArdoHeaderProps } from \"./Header\"\nimport * as layoutStyles from \"./Layout.css\"\n\nexport type ArdoHomePageProps = {\n /** Props passed to the Header component */\n headerProps?: ArdoHeaderProps\n /** Props passed to the Footer component */\n footerProps?: ArdoFooterProps\n /** Custom header element (overrides auto-generated header) */\n header?: ReactNode\n /** Custom footer element (overrides auto-generated footer) */\n footer?: ReactNode\n}\n\nfunction HomeHeroSection({\n hero,\n fallbackTitle,\n}: {\n hero: NonNullable<ReturnType<typeof useArdoPageData>>[\"frontmatter\"][\"hero\"]\n fallbackTitle: string\n}) {\n if (hero === undefined) return null\n const heroImage = hero.image\n const heroActions = hero.actions ?? []\n const heroName = hero.name ?? \"\"\n return (\n <section className={heroStyles.hero}>\n <div className={heroStyles.heroContainer}>\n {heroImage !== undefined && (\n <div>\n <img\n src={typeof heroImage === \"string\" ? heroImage : heroImage.light}\n alt={heroName !== \"\" ? heroName : fallbackTitle}\n />\n </div>\n )}\n <div>\n {heroName !== \"\" && <h1 className={heroStyles.heroName}>{heroName}</h1>}\n {(hero.text ?? \"\") !== \"\" && <p className={heroStyles.heroText}>{hero.text}</p>}\n {(hero.tagline ?? \"\") !== \"\" && <p className={heroStyles.heroTagline}>{hero.tagline}</p>}\n {heroActions.length > 0 && (\n <div className={heroStyles.heroActions}>\n {heroActions.map((action) => (\n <Link\n key={`${action.link}-${action.text}`}\n to={action.link}\n className={`${heroStyles.heroAction} ${action.theme === \"alt\" ? heroStyles.heroActionAlt : heroStyles.heroActionBrand}`}\n >\n {action.text}\n </Link>\n ))}\n </div>\n )}\n </div>\n </div>\n </section>\n )\n}\n\nfunction HomeFeaturesSection({\n features,\n}: {\n features: NonNullable<ReturnType<typeof useArdoPageData>>[\"frontmatter\"][\"features\"]\n}) {\n const safeFeatures = features ?? []\n if (safeFeatures.length === 0) return null\n return (\n <ArdoFeatures>\n {safeFeatures.map((feature) => (\n <ArdoFeatureCard\n key={feature.link ?? feature.title}\n title={feature.title}\n icon={feature.icon}\n link={feature.link}\n linkText={feature.linkText}\n >\n {feature.details}\n </ArdoFeatureCard>\n ))}\n </ArdoFeatures>\n )\n}\n\nexport function ArdoHomePage({ headerProps, footerProps, header, footer }: ArdoHomePageProps = {}) {\n const pageData = useArdoPageData()\n const config = useArdoConfig()\n\n return (\n <div className={layoutStyles.home}>\n {header ?? <ArdoHeader title={config.title} {...headerProps} />}\n <main className={layoutStyles.homeMain}>\n <HomeHeroSection hero={pageData?.frontmatter.hero} fallbackTitle={config.title} />\n <HomeFeaturesSection features={pageData?.frontmatter.features} />\n </main>\n {footer ?? <ArdoFooter {...footerProps} />}\n </div>\n )\n}\n","import { type ComponentProps, createContext, type ReactNode, use, useMemo, useState } from \"react\"\nimport { NavLink as RouterNavLink } from \"react-router\"\n\nimport * as styles from \"./Nav.css\"\n\n/** Route path type - uses React Router's NavLink 'to' prop type for type-safe routes */\ntype RoutePath = ComponentProps<typeof RouterNavLink>[\"to\"]\n\n// Nav context for shared state\ntype NavContextValue = {\n mobileMenuOpen: boolean\n setMobileMenuOpen: (open: boolean) => void\n}\n\nconst NavContext = createContext<NavContextValue | null>(null)\n\nfunction useNavContext() {\n return use(NavContext)\n}\n\n// =============================================================================\n// Nav Component\n// =============================================================================\n\nexport type ArdoNavProps = {\n children?: ReactNode\n className?: string\n}\n\n/**\n * Navigation container component for composing navigation links.\n *\n * @example\n * ```tsx\n * <Nav>\n * <NavLink to=\"/guide\">Guide</NavLink>\n * <NavLink to=\"/api\">API</NavLink>\n * <NavLink href=\"https://github.com/...\">GitHub</NavLink>\n * </Nav>\n * ```\n */\nexport function ArdoNav({ children, className }: ArdoNavProps) {\n return <nav className={className ?? styles.nav}>{children}</nav>\n}\n\n// =============================================================================\n// NavLink Component\n// =============================================================================\n\nexport type ArdoNavLinkProps = {\n /** Internal route path (type-safe with React Router's registered routes) */\n to?: RoutePath\n /** External URL (uses anchor tag) */\n href?: string\n /** Link text or children */\n children: ReactNode\n /** Additional CSS classes */\n className?: string\n /** Active state match pattern */\n activeMatch?: string\n}\n\n/**\n * Navigation link component supporting both internal routes and external URLs.\n *\n * @example\n * ```tsx\n * // Internal link\n * <NavLink to=\"/guide\">Guide</NavLink>\n *\n * // External link\n * <NavLink href=\"https://github.com/...\">GitHub</NavLink>\n * ```\n */\nexport function ArdoNavLink({\n to,\n href,\n children,\n className,\n activeMatch: _activeMatch,\n}: ArdoNavLinkProps) {\n const navContext = useNavContext()\n const baseClassName = className ?? styles.navLink\n const hasHref = (href ?? \"\") !== \"\"\n const hasTo = to !== undefined\n\n // Handle click for mobile menu\n const handleClick = () => {\n navContext?.setMobileMenuOpen(false)\n }\n\n // External link\n if (hasHref) {\n return (\n <a\n href={href ?? \"\"}\n className={baseClassName}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={handleClick}\n >\n {children}\n </a>\n )\n }\n\n // Internal link\n if (hasTo) {\n return (\n <RouterNavLink\n to={to}\n className={({ isActive }: { isActive: boolean }) =>\n [baseClassName, isActive && \"active\"].filter(Boolean).join(\" \")\n }\n onClick={handleClick}\n >\n {children}\n </RouterNavLink>\n )\n }\n\n // Text-only (no link)\n return <span className={baseClassName}>{children}</span>\n}\n\n// =============================================================================\n// NavProvider Component\n// =============================================================================\n\nexport type NavProviderProps = {\n children: ReactNode\n}\n\n/**\n * Provider for Nav context (mobile menu state).\n * Used internally by Header component.\n */\nexport function NavProvider({ children }: NavProviderProps) {\n const [mobileMenuOpen, setMobileMenuOpen] = useState(false)\n const contextValue = useMemo(() => ({ mobileMenuOpen, setMobileMenuOpen }), [mobileMenuOpen])\n\n return <NavContext value={contextValue}>{children}</NavContext>\n}\n\n// Export context hook for external use\nexport { useNavContext }\n"],"mappings":"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"}