From 699f9e761b7eed7b44edc352e2257d3320cc3b55 Mon Sep 17 00:00:00 2001 From: Eric Chavez Date: Mon, 13 Apr 2026 19:54:25 -0700 Subject: [PATCH 01/15] chore(docs): scaffold Fumadocs app in docs/ Stage existing docs/*.md to docs-legacy/ (git-tracked rename) and scaffold a Next.js 15 + Fumadocs 15.8.5 + Tailwind v4 app into docs/. Adds docs to pnpm-workspace.yaml. Legacy files will be migrated into apps/docs/content/docs/*.mdx in a follow-up commit. Co-Authored-By: Claude Opus 4.6 (1M context) --- {docs => docs-legacy}/CONTRIBUTING.md | 0 {docs => docs-legacy}/api-reference.md | 0 .../assets/useui-explained.webp | Bin {docs => docs-legacy}/assets/zero-ui-logo.png | Bin {docs => docs-legacy}/demo.md | 0 {docs => docs-legacy}/experimental.md | 0 {docs => docs-legacy}/faq.md | 0 {docs => docs-legacy}/installation-next.md | 0 {docs => docs-legacy}/installation-vite.md | 0 {docs => docs-legacy}/internal.md | 0 {docs => docs-legacy}/migration-guide.md | 0 {docs => docs-legacy}/rules.md | 0 {docs => docs-legacy}/size.md | 0 {docs => docs-legacy}/usage-examples.md | 0 docs/.gitignore | 28 + docs/README.md | 45 + docs/app/(home)/layout.tsx | 6 + docs/app/(home)/page.tsx | 19 + docs/app/api/search/route.ts | 7 + docs/app/docs/[[...slug]]/page.tsx | 54 + docs/app/docs/layout.tsx | 11 + docs/app/global.css | 3 + docs/app/layout.tsx | 17 + docs/app/llms-full.txt/route.ts | 10 + docs/app/og/docs/[...slug]/route.tsx | 36 + docs/content/docs/index.mdx | 13 + docs/content/docs/test.mdx | 17 + docs/lib/layout.shared.tsx | 30 + docs/lib/source.ts | 27 + docs/mdx-components.tsx | 10 + docs/next.config.mjs | 10 + docs/package.json | 30 + docs/postcss.config.mjs | 5 + docs/source.config.ts | 26 + docs/tsconfig.json | 30 + pnpm-lock.yaml | 3203 ++++++++++++++++- pnpm-workspace.yaml | 1 + 37 files changed, 3511 insertions(+), 127 deletions(-) rename {docs => docs-legacy}/CONTRIBUTING.md (100%) rename {docs => docs-legacy}/api-reference.md (100%) rename {docs => docs-legacy}/assets/useui-explained.webp (100%) rename {docs => docs-legacy}/assets/zero-ui-logo.png (100%) rename {docs => docs-legacy}/demo.md (100%) rename {docs => docs-legacy}/experimental.md (100%) rename {docs => docs-legacy}/faq.md (100%) rename {docs => docs-legacy}/installation-next.md (100%) rename {docs => docs-legacy}/installation-vite.md (100%) rename {docs => docs-legacy}/internal.md (100%) rename {docs => docs-legacy}/migration-guide.md (100%) rename {docs => docs-legacy}/rules.md (100%) rename {docs => docs-legacy}/size.md (100%) rename {docs => docs-legacy}/usage-examples.md (100%) create mode 100644 docs/.gitignore create mode 100644 docs/README.md create mode 100644 docs/app/(home)/layout.tsx create mode 100644 docs/app/(home)/page.tsx create mode 100644 docs/app/api/search/route.ts create mode 100644 docs/app/docs/[[...slug]]/page.tsx create mode 100644 docs/app/docs/layout.tsx create mode 100644 docs/app/global.css create mode 100644 docs/app/layout.tsx create mode 100644 docs/app/llms-full.txt/route.ts create mode 100644 docs/app/og/docs/[...slug]/route.tsx create mode 100644 docs/content/docs/index.mdx create mode 100644 docs/content/docs/test.mdx create mode 100644 docs/lib/layout.shared.tsx create mode 100644 docs/lib/source.ts create mode 100644 docs/mdx-components.tsx create mode 100644 docs/next.config.mjs create mode 100644 docs/package.json create mode 100644 docs/postcss.config.mjs create mode 100644 docs/source.config.ts create mode 100644 docs/tsconfig.json diff --git a/docs/CONTRIBUTING.md b/docs-legacy/CONTRIBUTING.md similarity index 100% rename from docs/CONTRIBUTING.md rename to docs-legacy/CONTRIBUTING.md diff --git a/docs/api-reference.md b/docs-legacy/api-reference.md similarity index 100% rename from docs/api-reference.md rename to docs-legacy/api-reference.md diff --git a/docs/assets/useui-explained.webp b/docs-legacy/assets/useui-explained.webp similarity index 100% rename from docs/assets/useui-explained.webp rename to docs-legacy/assets/useui-explained.webp diff --git a/docs/assets/zero-ui-logo.png b/docs-legacy/assets/zero-ui-logo.png similarity index 100% rename from docs/assets/zero-ui-logo.png rename to docs-legacy/assets/zero-ui-logo.png diff --git a/docs/demo.md b/docs-legacy/demo.md similarity index 100% rename from docs/demo.md rename to docs-legacy/demo.md diff --git a/docs/experimental.md b/docs-legacy/experimental.md similarity index 100% rename from docs/experimental.md rename to docs-legacy/experimental.md diff --git a/docs/faq.md b/docs-legacy/faq.md similarity index 100% rename from docs/faq.md rename to docs-legacy/faq.md diff --git a/docs/installation-next.md b/docs-legacy/installation-next.md similarity index 100% rename from docs/installation-next.md rename to docs-legacy/installation-next.md diff --git a/docs/installation-vite.md b/docs-legacy/installation-vite.md similarity index 100% rename from docs/installation-vite.md rename to docs-legacy/installation-vite.md diff --git a/docs/internal.md b/docs-legacy/internal.md similarity index 100% rename from docs/internal.md rename to docs-legacy/internal.md diff --git a/docs/migration-guide.md b/docs-legacy/migration-guide.md similarity index 100% rename from docs/migration-guide.md rename to docs-legacy/migration-guide.md diff --git a/docs/rules.md b/docs-legacy/rules.md similarity index 100% rename from docs/rules.md rename to docs-legacy/rules.md diff --git a/docs/size.md b/docs-legacy/size.md similarity index 100% rename from docs/size.md rename to docs-legacy/size.md diff --git a/docs/usage-examples.md b/docs-legacy/usage-examples.md similarity index 100% rename from docs/usage-examples.md rename to docs-legacy/usage-examples.md diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..55a12ae --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,28 @@ +# deps +/node_modules + +# generated content +.contentlayer +.content-collections +.source + +# test & build +/coverage +/.next/ +/out/ +/build +*.tsbuildinfo + +# misc +.DS_Store +*.pem +/.pnp +.pnp.js +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# others +.env*.local +.vercel +next-env.d.ts \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..9b7bba9 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,45 @@ +# docs + +This is a Next.js application generated with +[Create Fumadocs](https://github.com/fuma-nama/fumadocs). + +Run development server: + +```bash +npm run dev +# or +pnpm dev +# or +yarn dev +``` + +Open http://localhost:3000 with your browser to see the result. + +## Explore + +In the project, you can see: + +- `lib/source.ts`: Code for content source adapter, [`loader()`](https://fumadocs.dev/docs/headless/source-api) provides the interface to access your content. +- `lib/layout.shared.tsx`: Shared options for layouts, optional but preferred to keep. + +| Route | Description | +| ------------------------- | ------------------------------------------------------ | +| `app/(home)` | The route group for your landing page and other pages. | +| `app/docs` | The documentation layout and pages. | +| `app/api/search/route.ts` | The Route Handler for search. | + +### Fumadocs MDX + +A `source.config.ts` config file has been included, you can customise different options like frontmatter schema. + +Read the [Introduction](https://fumadocs.dev/docs/mdx) for further details. + +## Learn More + +To learn more about Next.js and Fumadocs, take a look at the following +resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js + features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +- [Fumadocs](https://fumadocs.dev) - learn about Fumadocs diff --git a/docs/app/(home)/layout.tsx b/docs/app/(home)/layout.tsx new file mode 100644 index 0000000..77379fa --- /dev/null +++ b/docs/app/(home)/layout.tsx @@ -0,0 +1,6 @@ +import { HomeLayout } from 'fumadocs-ui/layouts/home'; +import { baseOptions } from '@/lib/layout.shared'; + +export default function Layout({ children }: LayoutProps<'/'>) { + return {children}; +} diff --git a/docs/app/(home)/page.tsx b/docs/app/(home)/page.tsx new file mode 100644 index 0000000..e5b59f4 --- /dev/null +++ b/docs/app/(home)/page.tsx @@ -0,0 +1,19 @@ +import Link from 'next/link'; + +export default function HomePage() { + return ( +
+

Hello World

+

+ You can open{' '} + + /docs + {' '} + and see the documentation. +

+
+ ); +} diff --git a/docs/app/api/search/route.ts b/docs/app/api/search/route.ts new file mode 100644 index 0000000..7ba7e82 --- /dev/null +++ b/docs/app/api/search/route.ts @@ -0,0 +1,7 @@ +import { source } from '@/lib/source'; +import { createFromSource } from 'fumadocs-core/search/server'; + +export const { GET } = createFromSource(source, { + // https://docs.orama.com/docs/orama-js/supported-languages + language: 'english', +}); diff --git a/docs/app/docs/[[...slug]]/page.tsx b/docs/app/docs/[[...slug]]/page.tsx new file mode 100644 index 0000000..9b6d208 --- /dev/null +++ b/docs/app/docs/[[...slug]]/page.tsx @@ -0,0 +1,54 @@ +import { getPageImage, source } from '@/lib/source'; +import { + DocsBody, + DocsDescription, + DocsPage, + DocsTitle, +} from 'fumadocs-ui/page'; +import { notFound } from 'next/navigation'; +import { getMDXComponents } from '@/mdx-components'; +import type { Metadata } from 'next'; +import { createRelativeLink } from 'fumadocs-ui/mdx'; + +export default async function Page(props: PageProps<'/docs/[[...slug]]'>) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + const MDX = page.data.body; + + return ( + + {page.data.title} + {page.data.description} + + + + + ); +} + +export async function generateStaticParams() { + return source.generateParams(); +} + +export async function generateMetadata( + props: PageProps<'/docs/[[...slug]]'>, +): Promise { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + return { + title: page.data.title, + description: page.data.description, + openGraph: { + images: getPageImage(page).url, + }, + }; +} diff --git a/docs/app/docs/layout.tsx b/docs/app/docs/layout.tsx new file mode 100644 index 0000000..8e9ec72 --- /dev/null +++ b/docs/app/docs/layout.tsx @@ -0,0 +1,11 @@ +import { DocsLayout } from 'fumadocs-ui/layouts/docs'; +import { baseOptions } from '@/lib/layout.shared'; +import { source } from '@/lib/source'; + +export default function Layout({ children }: LayoutProps<'/docs'>) { + return ( + + {children} + + ); +} diff --git a/docs/app/global.css b/docs/app/global.css new file mode 100644 index 0000000..50b3bc2 --- /dev/null +++ b/docs/app/global.css @@ -0,0 +1,3 @@ +@import 'tailwindcss'; +@import 'fumadocs-ui/css/neutral.css'; +@import 'fumadocs-ui/css/preset.css'; diff --git a/docs/app/layout.tsx b/docs/app/layout.tsx new file mode 100644 index 0000000..db55a54 --- /dev/null +++ b/docs/app/layout.tsx @@ -0,0 +1,17 @@ +import '@/app/global.css'; +import { RootProvider } from 'fumadocs-ui/provider/next'; +import { Inter } from 'next/font/google'; + +const inter = Inter({ + subsets: ['latin'], +}); + +export default function Layout({ children }: LayoutProps<'/'>) { + return ( + + + {children} + + + ); +} diff --git a/docs/app/llms-full.txt/route.ts b/docs/app/llms-full.txt/route.ts new file mode 100644 index 0000000..d494d2c --- /dev/null +++ b/docs/app/llms-full.txt/route.ts @@ -0,0 +1,10 @@ +import { getLLMText, source } from '@/lib/source'; + +export const revalidate = false; + +export async function GET() { + const scan = source.getPages().map(getLLMText); + const scanned = await Promise.all(scan); + + return new Response(scanned.join('\n\n')); +} diff --git a/docs/app/og/docs/[...slug]/route.tsx b/docs/app/og/docs/[...slug]/route.tsx new file mode 100644 index 0000000..f5df96d --- /dev/null +++ b/docs/app/og/docs/[...slug]/route.tsx @@ -0,0 +1,36 @@ +import { getPageImage, source } from '@/lib/source'; +import { notFound } from 'next/navigation'; +import { ImageResponse } from 'next/og'; +import { generate as DefaultImage } from 'fumadocs-ui/og'; + +export const revalidate = false; + +export async function GET( + _req: Request, + { params }: RouteContext<'/og/docs/[...slug]'>, +) { + const { slug } = await params; + const page = source.getPage(slug.slice(0, -1)); + if (!page) notFound(); + + return new ImageResponse( + ( + + ), + { + width: 1200, + height: 630, + }, + ); +} + +export function generateStaticParams() { + return source.getPages().map((page) => ({ + lang: page.locale, + slug: getPageImage(page).segments, + })); +} diff --git a/docs/content/docs/index.mdx b/docs/content/docs/index.mdx new file mode 100644 index 0000000..1ede18e --- /dev/null +++ b/docs/content/docs/index.mdx @@ -0,0 +1,13 @@ +--- +title: Hello World +description: Your first document +--- + +Welcome to the docs! You can start writing documents in `/content/docs`. + +## What is Next? + + + + + diff --git a/docs/content/docs/test.mdx b/docs/content/docs/test.mdx new file mode 100644 index 0000000..f475f4a --- /dev/null +++ b/docs/content/docs/test.mdx @@ -0,0 +1,17 @@ +--- +title: Components +description: Components +--- + +## Code Block + +```js +console.log('Hello World'); +``` + +## Cards + + + + + diff --git a/docs/lib/layout.shared.tsx b/docs/lib/layout.shared.tsx new file mode 100644 index 0000000..2bd1907 --- /dev/null +++ b/docs/lib/layout.shared.tsx @@ -0,0 +1,30 @@ +import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; + +/** + * Shared layout configurations + * + * you can customise layouts individually from: + * Home Layout: app/(home)/layout.tsx + * Docs Layout: app/docs/layout.tsx + */ +export function baseOptions(): BaseLayoutProps { + return { + nav: { + title: ( + <> + + + + My App + + ), + }, + // see https://fumadocs.dev/docs/ui/navigation/links + links: [], + }; +} diff --git a/docs/lib/source.ts b/docs/lib/source.ts new file mode 100644 index 0000000..5895211 --- /dev/null +++ b/docs/lib/source.ts @@ -0,0 +1,27 @@ +import { docs } from '@/.source'; +import { type InferPageType, loader } from 'fumadocs-core/source'; +import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons'; + +// See https://fumadocs.dev/docs/headless/source-api for more info +export const source = loader({ + baseUrl: '/docs', + source: docs.toFumadocsSource(), + plugins: [lucideIconsPlugin()], +}); + +export function getPageImage(page: InferPageType) { + const segments = [...page.slugs, 'image.png']; + + return { + segments, + url: `/og/docs/${segments.join('/')}`, + }; +} + +export async function getLLMText(page: InferPageType) { + const processed = await page.data.getText('processed'); + + return `# ${page.data.title} (${page.url}) + +${processed}`; +} diff --git a/docs/mdx-components.tsx b/docs/mdx-components.tsx new file mode 100644 index 0000000..d3fbb13 --- /dev/null +++ b/docs/mdx-components.tsx @@ -0,0 +1,10 @@ +import defaultMdxComponents from 'fumadocs-ui/mdx'; +import type { MDXComponents } from 'mdx/types'; + +// use this function to get MDX components, you will need it for rendering MDX +export function getMDXComponents(components?: MDXComponents): MDXComponents { + return { + ...defaultMdxComponents, + ...components, + }; +} diff --git a/docs/next.config.mjs b/docs/next.config.mjs new file mode 100644 index 0000000..457dcf2 --- /dev/null +++ b/docs/next.config.mjs @@ -0,0 +1,10 @@ +import { createMDX } from 'fumadocs-mdx/next'; + +const withMDX = createMDX(); + +/** @type {import('next').NextConfig} */ +const config = { + reactStrictMode: true, +}; + +export default withMDX(config); diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 0000000..6f0a1b2 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,30 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "next build", + "dev": "next dev --turbo", + "start": "next start", + "postinstall": "fumadocs-mdx" + }, + "dependencies": { + "next": "15.5.4", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "lucide-react": "^0.544.0", + "fumadocs-ui": "15.8.5", + "fumadocs-core": "15.8.5", + "fumadocs-mdx": "12.0.3" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "typescript": "^5", + "@types/mdx": "^2.0.13", + "@tailwindcss/postcss": "^4.1.10", + "tailwindcss": "^4.1.10", + "postcss": "^8.5.5" + } +} \ No newline at end of file diff --git a/docs/postcss.config.mjs b/docs/postcss.config.mjs new file mode 100644 index 0000000..a34a3d5 --- /dev/null +++ b/docs/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + }, +}; diff --git a/docs/source.config.ts b/docs/source.config.ts new file mode 100644 index 0000000..d2e968b --- /dev/null +++ b/docs/source.config.ts @@ -0,0 +1,26 @@ +import { + defineConfig, + defineDocs, + frontmatterSchema, + metaSchema, +} from 'fumadocs-mdx/config'; + +// You can customise Zod schemas for frontmatter and `meta.json` here +// see https://fumadocs.dev/docs/mdx/collections +export const docs = defineDocs({ + docs: { + schema: frontmatterSchema, + postprocess: { + includeProcessedMarkdown: true, + }, + }, + meta: { + schema: metaSchema, + }, +}); + +export default defineConfig({ + mdxOptions: { + // MDX options + }, +}); diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 0000000..4fd260f --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "target": "ESNext", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "paths": { + "@/.source": ["./.source/index.ts"], + "@/*": ["./*"] + }, + "plugins": [ + { + "name": "next" + } + ] + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 14a2efe..5087160 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,6 +39,55 @@ importers: specifier: ^5.9.2 version: 5.9.2 + docs: + dependencies: + fumadocs-core: + specifier: 15.8.5 + version: 15.8.5(@types/react@19.1.9)(lucide-react@0.544.0(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + fumadocs-mdx: + specifier: 12.0.3 + version: 12.0.3(fumadocs-core@15.8.5(@types/react@19.1.9)(lucide-react@0.544.0(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1) + fumadocs-ui: + specifier: 15.8.5 + version: 15.8.5(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(lucide-react@0.544.0(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.11) + lucide-react: + specifier: ^0.544.0 + version: 0.544.0(react@19.1.1) + next: + specifier: 15.5.4 + version: 15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: + specifier: ^19.0.0 + version: 19.1.1 + react-dom: + specifier: ^19.0.0 + version: 19.1.1(react@19.1.1) + devDependencies: + '@tailwindcss/postcss': + specifier: ^4.1.10 + version: 4.1.11 + '@types/mdx': + specifier: ^2.0.13 + version: 2.0.13 + '@types/node': + specifier: ^20 + version: 20.19.9 + '@types/react': + specifier: ^19 + version: 19.1.9 + '@types/react-dom': + specifier: ^19 + version: 19.1.7(@types/react@19.1.9) + postcss: + specifier: ^8.5.5 + version: 8.5.6 + tailwindcss: + specifier: ^4.1.10 + version: 4.1.11 + typescript: + specifier: ^5 + version: 5.9.2 + examples/demo: dependencies: '@codesandbox/sandpack-react': @@ -378,156 +427,312 @@ packages: '@emnapi/runtime@1.4.5': resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.25.8': resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.25.8': resolution: {integrity: sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.25.8': resolution: {integrity: sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.25.8': resolution: {integrity: sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.25.8': resolution: {integrity: sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.25.8': resolution: {integrity: sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.25.8': resolution: {integrity: sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.8': resolution: {integrity: sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.25.8': resolution: {integrity: sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.25.8': resolution: {integrity: sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.25.8': resolution: {integrity: sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.25.8': resolution: {integrity: sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.25.8': resolution: {integrity: sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.25.8': resolution: {integrity: sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.25.8': resolution: {integrity: sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.25.8': resolution: {integrity: sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.25.8': resolution: {integrity: sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-arm64@0.25.8': resolution: {integrity: sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.8': resolution: {integrity: sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-arm64@0.25.8': resolution: {integrity: sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.8': resolution: {integrity: sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/openharmony-arm64@0.25.8': resolution: {integrity: sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.25.8': resolution: {integrity: sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.25.8': resolution: {integrity: sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.25.8': resolution: {integrity: sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.25.8': resolution: {integrity: sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==} engines: {node: '>=18'} @@ -572,6 +777,24 @@ packages: resolution: {integrity: sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + + '@floating-ui/react-dom@2.1.8': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@formatjs/intl-localematcher@0.6.2': + resolution: {integrity: sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -755,57 +978,111 @@ packages: '@marijn/find-cluster-break@1.0.2': resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + '@next/env@15.3.8': resolution: {integrity: sha512-SAfHg0g91MQVMPioeFeDjE+8UPF3j3BvHjs8ZKJAUz1BG7eMPvfCKOAgNWJ6s1MLNeP6O2InKQRTNblxPWuq+Q==} + '@next/env@15.5.4': + resolution: {integrity: sha512-27SQhYp5QryzIT5uO8hq99C69eLQ7qkzkDPsk3N+GuS2XgOgoYEeOav7Pf8Tn4drECOVDsDg8oj+/DVy8qQL2A==} + '@next/swc-darwin-arm64@15.3.5': resolution: {integrity: sha512-lM/8tilIsqBq+2nq9kbTW19vfwFve0NR7MxfkuSUbRSgXlMQoJYg+31+++XwKVSXk4uT23G2eF/7BRIKdn8t8w==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] + '@next/swc-darwin-arm64@15.5.4': + resolution: {integrity: sha512-nopqz+Ov6uvorej8ndRX6HlxCYWCO3AHLfKK2TYvxoSB2scETOcfm/HSS3piPqc3A+MUgyHoqE6je4wnkjfrOA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + '@next/swc-darwin-x64@15.3.5': resolution: {integrity: sha512-WhwegPQJ5IfoUNZUVsI9TRAlKpjGVK0tpJTL6KeiC4cux9774NYE9Wu/iCfIkL/5J8rPAkqZpG7n+EfiAfidXA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] + '@next/swc-darwin-x64@15.5.4': + resolution: {integrity: sha512-QOTCFq8b09ghfjRJKfb68kU9k2K+2wsC4A67psOiMn849K9ZXgCSRQr0oVHfmKnoqCbEmQWG1f2h1T2vtJJ9mA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + '@next/swc-linux-arm64-gnu@15.3.5': resolution: {integrity: sha512-LVD6uMOZ7XePg3KWYdGuzuvVboxujGjbcuP2jsPAN3MnLdLoZUXKRc6ixxfs03RH7qBdEHCZjyLP/jBdCJVRJQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-gnu@15.5.4': + resolution: {integrity: sha512-eRD5zkts6jS3VfE/J0Kt1VxdFqTnMc3QgO5lFE5GKN3KDI/uUpSyK3CjQHmfEkYR4wCOl0R0XrsjpxfWEA++XA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-arm64-musl@15.3.5': resolution: {integrity: sha512-k8aVScYZ++BnS2P69ClK7v4nOu702jcF9AIHKu6llhHEtBSmM2zkPGl9yoqbSU/657IIIb0QHpdxEr0iW9z53A==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-musl@15.5.4': + resolution: {integrity: sha512-TOK7iTxmXFc45UrtKqWdZ1shfxuL4tnVAOuuJK4S88rX3oyVV4ZkLjtMT85wQkfBrOOvU55aLty+MV8xmcJR8A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-x64-gnu@15.3.5': resolution: {integrity: sha512-2xYU0DI9DGN/bAHzVwADid22ba5d/xrbrQlr2U+/Q5WkFUzeL0TDR963BdrtLS/4bMmKZGptLeg6282H/S2i8A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-gnu@15.5.4': + resolution: {integrity: sha512-7HKolaj+481FSW/5lL0BcTkA4Ueam9SPYWyN/ib/WGAFZf0DGAN8frNpNZYFHtM4ZstrHZS3LY3vrwlIQfsiMA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-linux-x64-musl@15.3.5': resolution: {integrity: sha512-TRYIqAGf1KCbuAB0gjhdn5Ytd8fV+wJSM2Nh2is/xEqR8PZHxfQuaiNhoF50XfY90sNpaRMaGhF6E+qjV1b9Tg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-musl@15.5.4': + resolution: {integrity: sha512-nlQQ6nfgN0nCO/KuyEUwwOdwQIGjOs4WNMjEUtpIQJPR2NUfmGpW2wkJln1d4nJ7oUzd1g4GivH5GoEPBgfsdw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-win32-arm64-msvc@15.3.5': resolution: {integrity: sha512-h04/7iMEUSMY6fDGCvdanKqlO1qYvzNxntZlCzfE8i5P0uqzVQWQquU1TIhlz0VqGQGXLrFDuTJVONpqGqjGKQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] + '@next/swc-win32-arm64-msvc@15.5.4': + resolution: {integrity: sha512-PcR2bN7FlM32XM6eumklmyWLLbu2vs+D7nJX8OAIoWy69Kef8mfiN4e8TUv2KohprwifdpFKPzIP1njuCjD0YA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + '@next/swc-win32-x64-msvc@15.3.5': resolution: {integrity: sha512-5fhH6fccXxnX2KhllnGhkYMndhOiLOLEiVGYjP2nizqeGWkN10sA9taATlXwake2E2XMvYZjjz0Uj7T0y+z1yw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] + '@next/swc-win32-x64-msvc@15.5.4': + resolution: {integrity: sha512-1ur2tSHZj8Px/KMAthmuI9FMp/YFusMMGoRNJaRZMOlSkgvLjzosSdQI0cJAKogdHl3qXUQKL9MGaYvKwA7DXg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -821,6 +1098,10 @@ packages: '@open-draft/deferred-promise@2.2.0': resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + '@orama/orama@3.1.18': + resolution: {integrity: sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA==} + engines: {node: '>= 20.0.0'} + '@pivanov/utils@0.0.2': resolution: {integrity: sha512-q9CN0bFWxWgMY5hVVYyBgez1jGiLBa6I+LkG37ycylPhFvEGOOeaADGtUSu46CaZasPnlY8fCdVJZmrgKb1EPA==} peerDependencies: @@ -840,56 +1121,421 @@ packages: peerDependencies: preact: 10.x - '@react-hook/intersection-observer@3.1.2': - resolution: {integrity: sha512-mWU3BMkmmzyYMSuhO9wu3eJVP21N8TcgYm9bZnTrMwuM818bEk+0NRM3hP+c/TqA9Ln5C7qE53p1H0QMtzYdvQ==} + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-accordion@1.2.12': + resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} peerDependencies: - react: '>=16.8' + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@react-hook/passive-layout-effect@1.2.1': - resolution: {integrity: sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==} + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} peerDependencies: - react: '>=16.8' + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@react-zero-ui/core@0.4.0': - resolution: {integrity: sha512-0ID068etBheJyT8QPJsDzgtAnoKTWNrZJV4HaLgyXrn1lYfJSV0ZS1S/KwNaaYtxlcYxZ3rzpURZ/9ZPZP8QAA==} - engines: {node: '>=22'} + '@radix-ui/react-collapsible@1.1.12': + resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} peerDependencies: - '@tailwindcss/postcss': ^4.1.10 - react: '>=16.8.0' + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@react-zero-ui/icon-sprite@0.1.4': - resolution: {integrity: sha512-5ud+LhiAp30zqntZdTen49Mc2rjBGgAoKBdSE6rmIunuUDco0Y2DWi9+N1jkVxxcGFwYVNwGjHf8Bd1YFPPPmg==} - hasBin: true + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} peerDependencies: - react: '>=17' + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@rollup/pluginutils@5.2.0': - resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} - engines: {node: '>=14.0.0'} + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - rollup: + '@types/react': optional: true - '@rollup/rollup-android-arm-eabi@4.46.2': - resolution: {integrity: sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==} - cpu: [arm] - os: [android] + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@rollup/rollup-android-arm64@4.46.2': - resolution: {integrity: sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==} - cpu: [arm64] - os: [android] + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@rollup/rollup-darwin-arm64@4.46.2': - resolution: {integrity: sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==} - cpu: [arm64] - os: [darwin] + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@rollup/rollup-darwin-x64@4.46.2': - resolution: {integrity: sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==} - cpu: [x64] + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-navigation-menu@1.2.14': + resolution: {integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popover@1.1.15': + resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-scroll-area@1.2.10': + resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-tabs@1.1.13': + resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + + '@react-hook/intersection-observer@3.1.2': + resolution: {integrity: sha512-mWU3BMkmmzyYMSuhO9wu3eJVP21N8TcgYm9bZnTrMwuM818bEk+0NRM3hP+c/TqA9Ln5C7qE53p1H0QMtzYdvQ==} + peerDependencies: + react: '>=16.8' + + '@react-hook/passive-layout-effect@1.2.1': + resolution: {integrity: sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==} + peerDependencies: + react: '>=16.8' + + '@react-zero-ui/core@0.4.0': + resolution: {integrity: sha512-0ID068etBheJyT8QPJsDzgtAnoKTWNrZJV4HaLgyXrn1lYfJSV0ZS1S/KwNaaYtxlcYxZ3rzpURZ/9ZPZP8QAA==} + engines: {node: '>=22'} + peerDependencies: + '@tailwindcss/postcss': ^4.1.10 + react: '>=16.8.0' + + '@react-zero-ui/icon-sprite@0.1.4': + resolution: {integrity: sha512-5ud+LhiAp30zqntZdTen49Mc2rjBGgAoKBdSE6rmIunuUDco0Y2DWi9+N1jkVxxcGFwYVNwGjHf8Bd1YFPPPmg==} + hasBin: true + peerDependencies: + react: '>=17' + + '@rollup/pluginutils@5.2.0': + resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.46.2': + resolution: {integrity: sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.46.2': + resolution: {integrity: sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.46.2': + resolution: {integrity: sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.46.2': + resolution: {integrity: sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==} + cpu: [x64] os: [darwin] '@rollup/rollup-freebsd-arm64@4.46.2': @@ -975,6 +1621,36 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@shikijs/core@3.23.0': + resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} + + '@shikijs/engine-javascript@3.23.0': + resolution: {integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==} + + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} + + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} + + '@shikijs/rehype@3.23.0': + resolution: {integrity: sha512-GepKJxXHbXFfAkiZZZ+4V7x71Lw3s0ALYmydUxJRdvpKjSx9FOMSaunv6WRLFBXR6qjYerUq1YZQno+2gLEPwA==} + + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} + + '@shikijs/transformers@3.23.0': + resolution: {integrity: sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==} + + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@stitches/core@1.2.8': resolution: {integrity: sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==} @@ -1087,15 +1763,33 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@20.19.9': resolution: {integrity: sha512-cuVNgarYWZqxRJDQHEB58GEONhOK79QVR/qYx4S7kcUObQvUwvFnYxJuuHUKm2aieN9X3yZB4LZsuYNU1Qphsw==} @@ -1115,6 +1809,12 @@ packages: '@types/react@19.1.9': resolution: {integrity: sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@typescript-eslint/parser@8.58.0': resolution: {integrity: sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1152,6 +1852,9 @@ packages: resolution: {integrity: sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@vercel/analytics@1.5.0': resolution: {integrity: sha512-MYsBzfPki4gthY5HnYN7jgInhAZ7Ac1cYDoRWFomwGHWEX7odTEzbtg9kf/QSo7XEsEAqlQugA6gJ2WS2DEa3g==} peerDependencies: @@ -1201,6 +1904,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + array-buffer-byte-length@1.0.2: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} @@ -1225,6 +1932,10 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} @@ -1233,6 +1944,9 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1293,10 +2007,25 @@ packages: caniuse-lite@1.0.30001731: resolution: {integrity: sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + cheerio-select@1.6.0: resolution: {integrity: sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==} @@ -1304,10 +2033,17 @@ packages: resolution: {integrity: sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==} engines: {node: '>= 6'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + chownr@3.0.0: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + clean-set@1.1.2: resolution: {integrity: sha512-cA8uCj0qSoG9e0kevyOWXwPaELRPVg5Pxp6WskLMwerx257Zfnh8Nl0JBH59d7wQzij2CK7qEfJQK3RjuKKIug==} @@ -1318,6 +2054,9 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1332,6 +2071,12 @@ packages: resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} engines: {node: '>=12.5.0'} + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + compute-scroll-into-view@3.1.1: + resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1352,6 +2097,11 @@ packages: resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -1397,6 +2147,9 @@ packages: supports-color: optional: true + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -1416,6 +2169,12 @@ packages: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -1490,6 +2249,17 @@ packages: resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} engines: {node: '>=0.12'} + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + esbuild@0.25.8: resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==} engines: {node: '>=18'} @@ -1506,6 +2276,10 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + eslint-compat-utils@0.5.1: resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} engines: {node: '>=12'} @@ -1604,6 +2378,27 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-value-to-estree@3.5.0: + resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -1620,6 +2415,9 @@ packages: ext@1.7.0: resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1671,26 +2469,99 @@ packages: framer-motion@12.23.12: resolution: {integrity: sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==} peerDependencies: - '@emotion/is-prop-valid': '*' - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fumadocs-core@15.8.5: + resolution: {integrity: sha512-hyJtKGuB2J/5y7tDfI1EnGMKlNbSXM5N5cpwvgCY0DcBJwFMDG/GpSpaVRzh3aWy67pAYDZFIwdtbKXBa/q5bg==} + peerDependencies: + '@mixedbread/sdk': ^0.19.0 + '@oramacloud/client': 1.x.x || 2.x.x + '@tanstack/react-router': 1.x.x + '@types/react': '*' + algoliasearch: 5.x.x + lucide-react: '*' + next: 14.x.x || 15.x.x + react: 18.x.x || 19.x.x + react-dom: 18.x.x || 19.x.x + react-router: 7.x.x + waku: ^0.26.0 + peerDependenciesMeta: + '@mixedbread/sdk': + optional: true + '@oramacloud/client': + optional: true + '@tanstack/react-router': + optional: true + '@types/react': + optional: true + algoliasearch: + optional: true + lucide-react: + optional: true + next: + optional: true + react: + optional: true + react-dom: + optional: true + react-router: + optional: true + waku: + optional: true + + fumadocs-mdx@12.0.3: + resolution: {integrity: sha512-OYqbHSmzkejG+iUMlZJJOitaVbCgBdo/REc/9Sq1WaZ1vq6bH9PCFU0cKJlRdHbQSGRfVg5EJJy5uKy5+iNFGQ==} + hasBin: true + peerDependencies: + '@fumadocs/mdx-remote': ^1.4.0 + fumadocs-core: ^14.0.0 || ^15.0.0 + next: ^15.3.0 + react: '*' + vite: 6.x.x || 7.x.x peerDependenciesMeta: - '@emotion/is-prop-valid': + '@fumadocs/mdx-remote': + optional: true + next: optional: true react: optional: true - react-dom: + vite: optional: true - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] + fumadocs-ui@15.8.5: + resolution: {integrity: sha512-9pyB+9rOOsrFnmmZ9xREp/OgVhyaSq2ocEpqTNbeQ7tlJ6JWbdFWfW0C9lRXprQEB6DJWUDtDxqKS5QXLH0EGA==} + peerDependencies: + '@types/react': '*' + next: 14.x.x || 15.x.x + react: 18.x.x || 19.x.x + react-dom: 18.x.x || 19.x.x + tailwindcss: ^3.4.14 || ^4.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + next: + optional: true + tailwindcss: + optional: true function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -1710,6 +2581,10 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} @@ -1721,6 +2596,9 @@ packages: get-tsconfig@4.10.1: resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1778,6 +2656,24 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + htmlparser2@6.1.0: resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} @@ -1788,6 +2684,11 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} + image-size@2.0.2: + resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==} + engines: {node: '>=16.x'} + hasBin: true + import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -1796,6 +2697,9 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -1804,6 +2708,12 @@ packages: resolution: {integrity: sha512-fn4bQ0Xq8FTej09YC/jqKZwtijpvARlRp6wxL5WTA6yPe2YWSJ5RJh7Nm79rK2qB0wr6iDQzH60XGq5V/7u8YQ==} deprecated: The Intersection Observer polyfill is no longer needed and can safely be removed. Intersection Observer has been Baseline since 2019. + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -1839,6 +2749,9 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1855,6 +2768,9 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -1871,6 +2787,10 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -2033,10 +2953,17 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + lru-cache@11.1.0: resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} engines: {node: 20 || >=22} + lru-cache@11.3.5: + resolution: {integrity: sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -2045,6 +2972,11 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + lucide-react@0.544.0: + resolution: {integrity: sha512-t5tS44bqd825zAW45UQxpG2CvcC4urOwn2TrwSH8u+MjeE+1NnWl6QqeQ/6NdjMqdOygyiT9p3Ev0p1NJykxjw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + lucide-static@0.525.0: resolution: {integrity: sha512-dPQiibOV/kRv/UnaNFbiTxdDFZ267rIjHVWLv6GoUXVD5YSW71cyF4tYJVD27zSb0OOWdeWrqZsuBtRaYc4FHw==} @@ -2055,14 +2987,174 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -2129,6 +3221,16 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + next-tick@1.1.0: resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} @@ -2153,9 +3255,35 @@ packages: sass: optional: true + next@15.5.4: + resolution: {integrity: sha512-xH4Yjhb82sFYQfY3vbkJfgSDgXvBB6a8xPs9i35k6oZJRoQRihZH+4s9Yo2qsWpzBmZ3lPXaJ2KPXLfkvW4LnA==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + deprecated: This version has a security vulnerability. Please upgrade to a patched version. See https://nextjs.org/blog/CVE-2025-66478 for more details. + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + npm-to-yarn@3.0.1: + resolution: {integrity: sha512-tt6PvKu4WyzPwWUzy/hvPFqn+uwXO0K1ZHka8az3NnrhWJDmSqI8ncWq0fkL0k/lmmi5tAC11FXwXuh0rFbt1A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -2183,6 +3311,12 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + + oniguruma-to-es@4.3.5: + resolution: {integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -2206,6 +3340,9 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse5-htmlparser2-tree-adapter@6.0.1: resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} @@ -2223,6 +3360,9 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2252,6 +3392,10 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + postcss@8.4.31: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} @@ -2272,6 +3416,9 @@ packages: engines: {node: '>=14'} hasBin: true + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2290,6 +3437,32 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-medium-image-zoom@5.4.3: + resolution: {integrity: sha512-cDIwdn35fRUPsGnnj/cG6Pacll+z+Mfv6EWU2wDO5ngbZjg5uLRb2ZhEnh92ufbXCJDFvXHekb8G3+oKqUcv5g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + react-scan@0.4.3: resolution: {integrity: sha512-jhAQuQ1nja6HUYrSpbmNFHqZPsRCXk8Yqu0lHoRIw9eb8N96uTfXCpVyQhTTnJ/nWqnwuvxbpKVG/oWZT8+iTQ==} hasBin: true @@ -2310,18 +3483,76 @@ packages: react-router-dom: optional: true + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + react@19.1.1: resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} engines: {node: '>=0.10.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + regexp.prototype.flags@1.5.4: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remark@15.0.1: + resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -2361,6 +3592,9 @@ packages: scheduler@0.26.0: resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2399,6 +3633,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shiki@3.23.0: + resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} + side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -2425,6 +3662,13 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + static-browser-server@1.0.3: resolution: {integrity: sha512-ZUyfgGDdFRbZGGJQ1YhiM930Yczz5VlbJObrQLlk24+qNHVQx4OlLcYswEUo3bIyNAbQUIUR9Yr5/Hqjzqb4zA==} @@ -2451,6 +3695,9 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -2462,6 +3709,12 @@ packages: style-mod@4.1.2: resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==} + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + styled-jsx@5.1.6: resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} engines: {node: '>= 12.0.0'} @@ -2487,6 +3740,9 @@ packages: resolution: {integrity: sha512-nL6WTxYnsVl3e0G/mwGEFSnPAWUrzIwHAPOwInD4QUuLDKxaKMnXduf0Ipw3m/g9AldPhp1Y8E/nkReFBukJrA==} engines: {node: '>= 12'} + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + tailwindcss@4.1.11: resolution: {integrity: sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==} @@ -2499,6 +3755,10 @@ packages: engines: {node: '>=18'} deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + tinyexec@1.1.1: + resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -2507,6 +3767,12 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + ts-api-utils@2.5.0: resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} @@ -2567,6 +3833,27 @@ packages: undici-types@7.10.0: resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + unplugin@2.1.0: resolution: {integrity: sha512-us4j03/499KhbGP8BU7Hrzrgseo+KdfJYWcbcajCOqsAyb8Gk0Yn2kiUIcZISYCb1JFaZfIuG3b42HmguVOKCQ==} engines: {node: '>=18.12.0'} @@ -2580,6 +3867,35 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -2622,6 +3938,12 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -2982,81 +4304,159 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.25.12': + optional: true + '@esbuild/aix-ppc64@0.25.8': optional: true + '@esbuild/android-arm64@0.25.12': + optional: true + '@esbuild/android-arm64@0.25.8': optional: true + '@esbuild/android-arm@0.25.12': + optional: true + '@esbuild/android-arm@0.25.8': optional: true + '@esbuild/android-x64@0.25.12': + optional: true + '@esbuild/android-x64@0.25.8': optional: true + '@esbuild/darwin-arm64@0.25.12': + optional: true + '@esbuild/darwin-arm64@0.25.8': optional: true + '@esbuild/darwin-x64@0.25.12': + optional: true + '@esbuild/darwin-x64@0.25.8': optional: true + '@esbuild/freebsd-arm64@0.25.12': + optional: true + '@esbuild/freebsd-arm64@0.25.8': optional: true + '@esbuild/freebsd-x64@0.25.12': + optional: true + '@esbuild/freebsd-x64@0.25.8': optional: true + '@esbuild/linux-arm64@0.25.12': + optional: true + '@esbuild/linux-arm64@0.25.8': optional: true + '@esbuild/linux-arm@0.25.12': + optional: true + '@esbuild/linux-arm@0.25.8': optional: true + '@esbuild/linux-ia32@0.25.12': + optional: true + '@esbuild/linux-ia32@0.25.8': optional: true + '@esbuild/linux-loong64@0.25.12': + optional: true + '@esbuild/linux-loong64@0.25.8': optional: true + '@esbuild/linux-mips64el@0.25.12': + optional: true + '@esbuild/linux-mips64el@0.25.8': optional: true + '@esbuild/linux-ppc64@0.25.12': + optional: true + '@esbuild/linux-ppc64@0.25.8': optional: true + '@esbuild/linux-riscv64@0.25.12': + optional: true + '@esbuild/linux-riscv64@0.25.8': optional: true + '@esbuild/linux-s390x@0.25.12': + optional: true + '@esbuild/linux-s390x@0.25.8': optional: true + '@esbuild/linux-x64@0.25.12': + optional: true + '@esbuild/linux-x64@0.25.8': optional: true + '@esbuild/netbsd-arm64@0.25.12': + optional: true + '@esbuild/netbsd-arm64@0.25.8': optional: true + '@esbuild/netbsd-x64@0.25.12': + optional: true + '@esbuild/netbsd-x64@0.25.8': optional: true + '@esbuild/openbsd-arm64@0.25.12': + optional: true + '@esbuild/openbsd-arm64@0.25.8': optional: true + '@esbuild/openbsd-x64@0.25.12': + optional: true + '@esbuild/openbsd-x64@0.25.8': optional: true + '@esbuild/openharmony-arm64@0.25.12': + optional: true + '@esbuild/openharmony-arm64@0.25.8': optional: true + '@esbuild/sunos-x64@0.25.12': + optional: true + '@esbuild/sunos-x64@0.25.8': optional: true + '@esbuild/win32-arm64@0.25.12': + optional: true + '@esbuild/win32-arm64@0.25.8': optional: true + '@esbuild/win32-ia32@0.25.12': + optional: true + '@esbuild/win32-ia32@0.25.8': optional: true + '@esbuild/win32-x64@0.25.12': + optional: true + '@esbuild/win32-x64@0.25.8': optional: true @@ -3104,6 +4504,27 @@ snapshots: '@eslint/core': 0.15.1 levn: 0.4.1 + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 + + '@floating-ui/dom@1.7.6': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + + '@floating-ui/react-dom@2.1.8(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/dom': 1.7.6 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + + '@floating-ui/utils@0.2.11': {} + + '@formatjs/intl-localematcher@0.6.2': + dependencies: + tslib: 2.8.1 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -3253,32 +4674,88 @@ snapshots: '@marijn/find-cluster-break@1.0.2': {} + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.15.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.15.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + '@next/env@15.3.8': {} + '@next/env@15.5.4': {} + '@next/swc-darwin-arm64@15.3.5': optional: true + '@next/swc-darwin-arm64@15.5.4': + optional: true + '@next/swc-darwin-x64@15.3.5': optional: true + '@next/swc-darwin-x64@15.5.4': + optional: true + '@next/swc-linux-arm64-gnu@15.3.5': optional: true + '@next/swc-linux-arm64-gnu@15.5.4': + optional: true + '@next/swc-linux-arm64-musl@15.3.5': optional: true + '@next/swc-linux-arm64-musl@15.5.4': + optional: true + '@next/swc-linux-x64-gnu@15.3.5': optional: true + '@next/swc-linux-x64-gnu@15.5.4': + optional: true + '@next/swc-linux-x64-musl@15.3.5': optional: true + '@next/swc-linux-x64-musl@15.5.4': + optional: true + '@next/swc-win32-arm64-msvc@15.3.5': optional: true + '@next/swc-win32-arm64-msvc@15.5.4': + optional: true + '@next/swc-win32-x64-msvc@15.3.5': optional: true + '@next/swc-win32-x64-msvc@15.5.4': + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3293,6 +4770,8 @@ snapshots: '@open-draft/deferred-promise@2.2.0': {} + '@orama/orama@3.1.18': {} + '@pivanov/utils@0.0.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: react: 19.1.1 @@ -3309,6 +4788,362 @@ snapshots: '@preact/signals-core': 1.11.0 preact: 10.27.0 + '@radix-ui/number@1.1.1': {} + + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.9)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-context@1.1.2(@types/react@19.1.9)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) + aria-hidden: 1.2.6 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-remove-scroll: 2.7.2(@types/react@19.1.9)(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-direction@1.1.1(@types/react@19.1.9)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.9)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-id@1.1.1(@types/react@19.1.9)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) + aria-hidden: 1.2.6 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-remove-scroll: 2.7.2(@types/react@19.1.9)(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/react-dom': 2.1.8(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/rect': 1.1.1 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-slot@1.2.3(@types/react@19.1.9)(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-slot@1.2.4(@types/react@19.1.9)(react@19.1.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.9)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.9)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.9)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.9)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.9)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.9)(react@19.1.1)': + dependencies: + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.9)(react@19.1.1)': + dependencies: + '@radix-ui/rect': 1.1.1 + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.9)(react@19.1.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + react: 19.1.1 + optionalDependencies: + '@types/react': 19.1.9 + + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + '@types/react-dom': 19.1.7(@types/react@19.1.9) + + '@radix-ui/rect@1.1.1': {} + '@react-hook/intersection-observer@3.1.2(react@19.1.1)': dependencies: '@react-hook/passive-layout-effect': 1.2.1(react@19.1.1) @@ -3418,6 +5253,55 @@ snapshots: '@rtsao/scc@1.1.0': {} + '@shikijs/core@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.5 + + '@shikijs/engine-oniguruma@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/rehype@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@types/hast': 3.0.4 + hast-util-to-string: 3.0.1 + shiki: 3.23.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + + '@shikijs/themes@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/transformers@3.23.0': + dependencies: + '@shikijs/core': 3.23.0 + '@shikijs/types': 3.23.0 + + '@shikijs/types@3.23.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@standard-schema/spec@1.1.0': {} + '@stitches/core@1.2.8': {} '@swc/counter@0.1.3': {} @@ -3521,12 +5405,32 @@ snapshots: dependencies: '@babel/types': 7.28.2 + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + '@types/estree@1.0.8': {} + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/ms@2.1.0': {} + '@types/node@20.19.9': dependencies: undici-types: 6.21.0 @@ -3547,6 +5451,10 @@ snapshots: dependencies: csstype: 3.1.3 + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + '@typescript-eslint/parser@8.58.0(eslint@9.32.0(jiti@2.6.1))(typescript@5.9.2)': dependencies: '@typescript-eslint/scope-manager': 8.58.0 @@ -3599,6 +5507,8 @@ snapshots: '@typescript-eslint/types': 8.58.0 eslint-visitor-keys: 5.0.1 + '@ungap/structured-clone@1.3.0': {} + '@vercel/analytics@1.5.0(next@15.3.8(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)': optionalDependencies: next: 15.3.8(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -3625,6 +5535,10 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + array-buffer-byte-length@1.0.2: dependencies: call-bound: 1.0.4 @@ -3675,12 +5589,16 @@ snapshots: get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 + astring@1.9.0: {} + async-function@1.0.0: {} available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 + bail@2.0.2: {} + balanced-match@1.0.2: {} balanced-match@4.0.4: {} @@ -3746,11 +5664,21 @@ snapshots: caniuse-lite@1.0.30001731: {} + ccount@2.0.1: {} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + cheerio-select@1.6.0: dependencies: css-select: 4.3.0 @@ -3769,14 +5697,24 @@ snapshots: parse5-htmlparser2-tree-adapter: 6.0.1 tslib: 2.8.1 + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + chownr@3.0.0: {} + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + clean-set@1.1.2: {} client-only@0.0.1: {} clsx@2.1.1: {} + collapse-white-space@2.1.0: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -3795,6 +5733,10 @@ snapshots: color-string: 1.9.1 optional: true + comma-separated-tokens@2.0.3: {} + + compute-scroll-into-view@3.1.1: {} + concat-map@0.0.1: {} convert-source-map@2.0.0: {} @@ -3817,6 +5759,8 @@ snapshots: css-what@6.2.2: {} + cssesc@3.0.0: {} + csstype@3.1.3: {} d@1.0.2: @@ -3854,6 +5798,10 @@ snapshots: dependencies: ms: 2.1.3 + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + deep-is@0.1.4: {} define-data-property@1.1.4: @@ -3872,6 +5820,12 @@ snapshots: detect-libc@2.0.4: {} + detect-node-es@1.1.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -4011,6 +5965,49 @@ snapshots: d: 1.0.2 ext: 1.7.0 + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.15.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + esbuild@0.25.8: optionalDependencies: '@esbuild/aix-ppc64': 0.25.8 @@ -4046,6 +6043,8 @@ snapshots: escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} + eslint-compat-utils@0.5.1(eslint@9.32.0(jiti@2.6.1)): dependencies: eslint: 9.32.0(jiti@2.6.1) @@ -4196,6 +6195,39 @@ snapshots: estraverse@5.3.0: {} + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-value-to-estree@3.5.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -4213,6 +6245,8 @@ snapshots: dependencies: type: 2.7.3 + extend@3.0.2: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -4274,6 +6308,97 @@ snapshots: fsevents@2.3.3: optional: true + fumadocs-core@15.8.5(@types/react@19.1.9)(lucide-react@0.544.0(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + dependencies: + '@formatjs/intl-localematcher': 0.6.2 + '@orama/orama': 3.1.18 + '@shikijs/rehype': 3.23.0 + '@shikijs/transformers': 3.23.0 + github-slugger: 2.0.0 + hast-util-to-estree: 3.1.3 + hast-util-to-jsx-runtime: 2.3.6 + image-size: 2.0.2 + negotiator: 1.0.0 + npm-to-yarn: 3.0.1 + path-to-regexp: 8.4.2 + react-remove-scroll: 2.7.2(@types/react@19.1.9)(react@19.1.1) + remark: 15.0.1 + remark-gfm: 4.0.1 + remark-rehype: 11.1.2 + scroll-into-view-if-needed: 3.1.0 + shiki: 3.23.0 + unist-util-visit: 5.1.0 + optionalDependencies: + '@types/react': 19.1.9 + lucide-react: 0.544.0(react@19.1.1) + next: 15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + transitivePeerDependencies: + - supports-color + + fumadocs-mdx@12.0.3(fumadocs-core@15.8.5(@types/react@19.1.9)(lucide-react@0.544.0(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1): + dependencies: + '@mdx-js/mdx': 3.1.1 + '@standard-schema/spec': 1.1.0 + chokidar: 4.0.3 + esbuild: 0.25.12 + estree-util-value-to-estree: 3.5.0 + fumadocs-core: 15.8.5(@types/react@19.1.9)(lucide-react@0.544.0(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + js-yaml: 4.1.0 + lru-cache: 11.3.5 + mdast-util-to-markdown: 2.1.2 + picocolors: 1.1.1 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + tinyexec: 1.1.1 + tinyglobby: 0.2.15 + unified: 11.0.5 + unist-util-visit: 5.1.0 + zod: 4.3.6 + optionalDependencies: + next: 15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.1.1 + transitivePeerDependencies: + - supports-color + + fumadocs-ui@15.8.5(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(lucide-react@0.544.0(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.11): + dependencies: + '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.4(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + class-variance-authority: 0.7.1 + fumadocs-core: 15.8.5(@types/react@19.1.9)(lucide-react@0.544.0(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + lodash.merge: 4.6.2 + next-themes: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + postcss-selector-parser: 7.1.1 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + react-medium-image-zoom: 5.4.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + scroll-into-view-if-needed: 3.1.0 + tailwind-merge: 3.5.0 + optionalDependencies: + '@types/react': 19.1.9 + next: 15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + tailwindcss: 4.1.11 + transitivePeerDependencies: + - '@mixedbread/sdk' + - '@oramacloud/client' + - '@tanstack/react-router' + - '@types/react-dom' + - algoliasearch + - lucide-react + - react-router + - supports-color + - waku + function-bind@1.1.2: {} function.prototype.name@1.1.8: @@ -4302,6 +6427,8 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 @@ -4317,6 +6444,8 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + github-slugger@2.0.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -4362,6 +6491,71 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + html-void-elements@3.0.0: {} + htmlparser2@6.1.0: dependencies: domelementtype: 2.3.0 @@ -4373,6 +6567,8 @@ snapshots: ignore@5.3.2: {} + image-size@2.0.2: {} + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -4380,6 +6576,8 @@ snapshots: imurmurhash@0.1.4: {} + inline-style-parser@0.2.7: {} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -4388,6 +6586,13 @@ snapshots: intersection-observer@0.10.0: {} + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -4431,6 +6636,8 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-decimal@2.0.1: {} + is-extglob@2.1.1: {} is-finalizationregistry@1.1.1: @@ -4448,6 +6655,8 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-hexadecimal@2.0.1: {} + is-map@2.0.3: {} is-negative-zero@2.0.3: {} @@ -4459,6 +6668,8 @@ snapshots: is-number@7.0.0: {} + is-plain-obj@4.1.0: {} + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -4489,127 +6700,566 @@ snapshots: is-weakmap@2.0.2: {} - is-weakref@1.1.1: + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + jiti@2.5.1: {} + + jiti@2.6.1: + optional: true + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@4.1.5: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-darwin-arm64@1.30.1: + optional: true + + lightningcss-darwin-x64@1.30.1: + optional: true + + lightningcss-freebsd-x64@1.30.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.1: + optional: true + + lightningcss-linux-arm64-gnu@1.30.1: + optional: true + + lightningcss-linux-arm64-musl@1.30.1: + optional: true + + lightningcss-linux-x64-gnu@1.30.1: + optional: true + + lightningcss-linux-x64-musl@1.30.1: + optional: true + + lightningcss-win32-arm64-msvc@1.30.1: + optional: true + + lightningcss-win32-x64-msvc@1.30.1: + optional: true + + lightningcss@1.30.1: + dependencies: + detect-libc: 2.0.4 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + longest-streak@3.1.0: {} + + lru-cache@11.1.0: {} + + lru-cache@11.3.5: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lucide-react@0.525.0(react@19.1.1): + dependencies: + react: 19.1.1 + + lucide-react@0.544.0(react@19.1.1): + dependencies: + react: 19.1.1 + + lucide-static@0.525.0: {} + + lz-string@1.5.0: {} + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.4 + + markdown-extensions@2.0.0: {} + + markdown-table@3.0.4: {} + + math-intrinsics@1.1.0: {} + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: dependencies: - call-bound: 1.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color - is-weakset@2.0.4: + mdast-util-mdxjs-esm@2.0.1: dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color - isarray@2.0.5: {} + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 - isexe@2.0.0: {} + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 - jiti@2.5.1: {} + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 - jiti@2.6.1: - optional: true + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 - js-tokens@4.0.0: {} + merge2@1.4.1: {} - js-yaml@4.1.0: + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: dependencies: - argparse: 2.0.1 + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - jsesc@3.1.0: {} + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 - json-buffer@3.0.1: {} + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 - json-schema-traverse@0.4.1: {} + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 - json-stable-stringify-without-jsonify@1.0.1: {} + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 - json5@1.0.2: + micromark-factory-destination@2.0.1: dependencies: - minimist: 1.2.8 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - json5@2.2.3: {} + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - keyv@4.5.4: + micromark-factory-mdx-expression@2.0.3: dependencies: - json-buffer: 3.0.1 + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 - kleur@4.1.5: {} + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 - levn@0.4.1: + micromark-factory-title@2.0.1: dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - lightningcss-darwin-arm64@1.30.1: - optional: true + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - lightningcss-darwin-x64@1.30.1: - optional: true + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - lightningcss-freebsd-x64@1.30.1: - optional: true + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 - lightningcss-linux-arm-gnueabihf@1.30.1: - optional: true + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - lightningcss-linux-arm64-gnu@1.30.1: - optional: true + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 - lightningcss-linux-arm64-musl@1.30.1: - optional: true + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 - lightningcss-linux-x64-gnu@1.30.1: - optional: true + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 - lightningcss-linux-x64-musl@1.30.1: - optional: true + micromark-util-encode@2.0.1: {} - lightningcss-win32-arm64-msvc@1.30.1: - optional: true + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 - lightningcss-win32-x64-msvc@1.30.1: - optional: true + micromark-util-html-tag-name@2.0.1: {} - lightningcss@1.30.1: + micromark-util-normalize-identifier@2.0.1: dependencies: - detect-libc: 2.0.4 - optionalDependencies: - lightningcss-darwin-arm64: 1.30.1 - lightningcss-darwin-x64: 1.30.1 - lightningcss-freebsd-x64: 1.30.1 - lightningcss-linux-arm-gnueabihf: 1.30.1 - lightningcss-linux-arm64-gnu: 1.30.1 - lightningcss-linux-arm64-musl: 1.30.1 - lightningcss-linux-x64-gnu: 1.30.1 - lightningcss-linux-x64-musl: 1.30.1 - lightningcss-win32-arm64-msvc: 1.30.1 - lightningcss-win32-x64-msvc: 1.30.1 + micromark-util-symbol: 2.0.1 - locate-path@6.0.0: + micromark-util-resolve-all@2.0.1: dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - - lru-cache@11.1.0: {} + micromark-util-types: 2.0.2 - lru-cache@5.1.1: + micromark-util-sanitize-uri@2.0.1: dependencies: - yallist: 3.1.1 + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 - lucide-react@0.525.0(react@19.1.1): + micromark-util-subtokenize@2.1.0: dependencies: - react: 19.1.1 + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - lucide-static@0.525.0: {} + micromark-util-symbol@2.0.1: {} - lz-string@1.5.0: {} + micromark-util-types@2.0.2: {} - magic-string@0.30.17: + micromark@4.0.2: dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - - math-intrinsics@1.1.0: {} - - merge2@1.4.1: {} + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color micromatch@4.0.8: dependencies: @@ -4658,6 +7308,13 @@ snapshots: natural-compare@1.4.0: {} + negotiator@1.0.0: {} + + next-themes@0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + dependencies: + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + next-tick@1.1.0: {} next@15.3.8(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): @@ -4686,8 +7343,34 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + dependencies: + '@next/env': 15.5.4 + '@swc/helpers': 0.5.15 + caniuse-lite: 1.0.30001731 + postcss: 8.4.31 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + styled-jsx: 5.1.6(@babel/core@7.28.0)(react@19.1.1) + optionalDependencies: + '@next/swc-darwin-arm64': 15.5.4 + '@next/swc-darwin-x64': 15.5.4 + '@next/swc-linux-arm64-gnu': 15.5.4 + '@next/swc-linux-arm64-musl': 15.5.4 + '@next/swc-linux-x64-gnu': 15.5.4 + '@next/swc-linux-x64-musl': 15.5.4 + '@next/swc-win32-arm64-msvc': 15.5.4 + '@next/swc-win32-x64-msvc': 15.5.4 + '@playwright/test': 1.54.2 + sharp: 0.34.3 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + node-releases@2.0.19: {} + npm-to-yarn@3.0.1: {} + nth-check@2.1.1: dependencies: boolbase: 1.0.0 @@ -4725,6 +7408,14 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + oniguruma-parser@0.12.1: {} + + oniguruma-to-es@4.3.5: + dependencies: + oniguruma-parser: 0.12.1 + regex: 6.1.0 + regex-recursion: 6.0.2 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -4754,6 +7445,16 @@ snapshots: dependencies: callsites: 3.1.0 + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + parse5-htmlparser2-tree-adapter@6.0.1: dependencies: parse5: 6.0.1 @@ -4766,6 +7467,8 @@ snapshots: path-parse@1.0.7: {} + path-to-regexp@8.4.2: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -4784,6 +7487,11 @@ snapshots: possible-typed-array-names@1.1.0: {} + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + postcss@8.4.31: dependencies: nanoid: 3.3.11 @@ -4802,6 +7510,8 @@ snapshots: prettier@3.6.2: {} + property-information@7.1.0: {} + punycode@2.3.1: {} queue-microtask@1.2.3: {} @@ -4817,6 +7527,30 @@ snapshots: react-is@17.0.2: {} + react-medium-image-zoom@5.4.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + dependencies: + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + + react-remove-scroll-bar@2.3.8(@types/react@19.1.9)(react@19.1.1): + dependencies: + react: 19.1.1 + react-style-singleton: 2.2.3(@types/react@19.1.9)(react@19.1.1) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.9 + + react-remove-scroll@2.7.2(@types/react@19.1.9)(react@19.1.1): + dependencies: + react: 19.1.1 + react-remove-scroll-bar: 2.3.8(@types/react@19.1.9)(react@19.1.1) + react-style-singleton: 2.2.3(@types/react@19.1.9)(react@19.1.1) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.1.9)(react@19.1.1) + use-sidecar: 1.1.3(@types/react@19.1.9)(react@19.1.1) + optionalDependencies: + '@types/react': 19.1.9 + react-scan@0.4.3(@types/react@19.1.9)(next@15.3.8(@babel/core@7.28.0)(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(rollup@4.46.2): dependencies: '@babel/core': 7.28.0 @@ -4846,8 +7580,47 @@ snapshots: - rollup - supports-color + react-style-singleton@2.2.3(@types/react@19.1.9)(react@19.1.1): + dependencies: + get-nonce: 1.0.1 + react: 19.1.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.9 + react@19.1.1: {} + readdirp@4.1.2: {} + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -4859,6 +7632,16 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + regexp.prototype.flags@1.5.4: dependencies: call-bind: 1.0.8 @@ -4868,6 +7651,64 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + remark@15.0.1: + dependencies: + '@types/mdast': 4.0.4 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + resolve-from@4.0.0: {} resolve-pkg-maps@1.0.0: {} @@ -4932,6 +7773,10 @@ snapshots: scheduler@0.26.0: {} + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + semver@6.3.1: {} semver@7.7.2: {} @@ -4964,7 +7809,7 @@ snapshots: dependencies: color: 4.2.3 detect-libc: 2.0.4 - semver: 7.7.2 + semver: 7.7.4 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.3 '@img/sharp-darwin-x64': 0.34.3 @@ -4996,6 +7841,17 @@ snapshots: shebang-regex@3.0.0: {} + shiki@3.23.0: + dependencies: + '@shikijs/core': 3.23.0 + '@shikijs/engine-javascript': 3.23.0 + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -5033,6 +7889,10 @@ snapshots: source-map-js@1.2.1: {} + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + static-browser-server@1.0.3: dependencies: '@open-draft/deferred-promise': 2.2.0 @@ -5072,12 +7932,25 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-bom@3.0.0: {} strip-json-comments@3.1.1: {} style-mod@4.1.2: {} + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + styled-jsx@5.1.6(@babel/core@7.28.0)(react@19.1.1): dependencies: client-only: 0.0.1 @@ -5095,6 +7968,8 @@ snapshots: dependencies: cheerio: 1.0.0-rc.10 + tailwind-merge@3.5.0: {} + tailwindcss@4.1.11: {} tapable@2.2.2: {} @@ -5108,6 +7983,8 @@ snapshots: mkdirp: 3.0.1 yallist: 5.0.0 + tinyexec@1.1.1: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.4) @@ -5117,6 +7994,10 @@ snapshots: dependencies: is-number: 7.0.0 + trim-lines@3.0.1: {} + + trough@2.2.0: {} + ts-api-utils@2.5.0(typescript@5.9.2): dependencies: typescript: 5.9.2 @@ -5194,6 +8075,43 @@ snapshots: undici-types@7.10.0: {} + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + unplugin@2.1.0: dependencies: acorn: 8.15.0 @@ -5210,6 +8128,33 @@ snapshots: dependencies: punycode: 2.3.1 + use-callback-ref@1.3.3(@types/react@19.1.9)(react@19.1.1): + dependencies: + react: 19.1.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.9 + + use-sidecar@1.1.3(@types/react@19.1.9)(react@19.1.1): + dependencies: + detect-node-es: 1.1.0 + react: 19.1.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.9 + + util-deprecate@1.0.2: {} + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + w3c-keyname@2.2.8: {} webpack-virtual-modules@0.6.2: @@ -5267,3 +8212,7 @@ snapshots: yallist@5.0.0: {} yocto-queue@0.1.0: {} + + zod@4.3.6: {} + + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 885e570..8308121 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,6 +1,7 @@ packages: - packages/* - examples/* + - docs onlyBuiltDependencies: - "@tailwindcss/oxide" From d79cff0a130040bf4ac82f5e67d23a7434422a69 Mon Sep 17 00:00:00 2001 From: Eric Chavez Date: Mon, 13 Apr 2026 20:09:50 -0700 Subject: [PATCH 02/15] docs: migrate legacy markdown to Fumadocs MDX Migrate 7 public docs from docs-legacy/*.md to docs/content/docs/*.mdx with frontmatter, updated internal links (/docs/*), and no manual TOCs (Fumadocs auto-generates). Split installation into getting-started/ {next,vite}.mdx. Replace Fumadocs starter index.mdx with a real docs home, delete starter test.mdx. Add meta.json for sidebar ordering with section separators (Getting Started, Core Concepts, Advanced). Delete legacy demo.md (duplicative) and rules.md (empty). docs-legacy still holds CONTRIBUTING.md, internal.md, size.md, assets/ pending Phase 5. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs-legacy/demo.md | 65 --- docs-legacy/rules.md | 0 docs/content/docs/api-reference.mdx | 379 ++++++++++++++++ docs/content/docs/experimental.mdx | 167 +++++++ docs/content/docs/faq.mdx | 328 ++++++++++++++ docs/content/docs/getting-started/meta.json | 4 + docs/content/docs/getting-started/next.mdx | 69 +++ docs/content/docs/getting-started/vite.mdx | 39 ++ docs/content/docs/index.mdx | 21 +- docs/content/docs/meta.json | 15 + docs/content/docs/migration-guide.mdx | 420 ++++++++++++++++++ docs/content/docs/test.mdx | 17 - docs/content/docs/usage-examples.mdx | 456 ++++++++++++++++++++ 13 files changed, 1892 insertions(+), 88 deletions(-) delete mode 100644 docs-legacy/demo.md delete mode 100644 docs-legacy/rules.md create mode 100644 docs/content/docs/api-reference.mdx create mode 100644 docs/content/docs/experimental.mdx create mode 100644 docs/content/docs/faq.mdx create mode 100644 docs/content/docs/getting-started/meta.json create mode 100644 docs/content/docs/getting-started/next.mdx create mode 100644 docs/content/docs/getting-started/vite.mdx create mode 100644 docs/content/docs/meta.json create mode 100644 docs/content/docs/migration-guide.mdx delete mode 100644 docs/content/docs/test.mdx create mode 100644 docs/content/docs/usage-examples.mdx diff --git a/docs-legacy/demo.md b/docs-legacy/demo.md deleted file mode 100644 index bdd0ffd..0000000 --- a/docs-legacy/demo.md +++ /dev/null @@ -1,65 +0,0 @@ -# Demo + Benchmarks - -
- -**See Zero-UI in action** with interactive demos and performance comparisons. - -Experience the difference between React re-renders and Zero-UI's instant updates. - -[**Live Demo**](https://zero-ui.dev/) | [**React Version**](https://zero-ui.dev/react) | [**Zero-UI Version**](https://zero-ui.dev/zero-ui) - -
- ---- - -## Interactive Examples - -| Demo | Description | Live Link | Source Code | -| --------------------- | ------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------- | -| **Interactive Menu** | Side-by-side comparison with render tracker | [Main Demo](https://zero-ui.dev/) | [GitHub](https://zero-ui.dev/react) | -| **React Benchmark** | Traditional React render path (10k nodes) | [React 10k](https://zero-ui.dev/react) | [GitHub](https://github.com/react-zero-ui/core/tree/main/examples/demo/src/app/react) | -| **Zero-UI Benchmark** | Identical DOM with `data-*` switching (10k nodes) | [Zero-UI 10k](https://zero-ui.dev/zero-ui) | [GitHub](https://github.com/react-zero-ui/core/tree/main/examples/demo/src/app/zero-ui) | - -> **Full Demo Source:** [Zero Rerender Demo](/examples/demo/) - ---- - -## Why Zero-UI? - -Every `setState` in React triggers the full **VDOM -> Diff -> Reconciliation -> Paint** pipeline. For _pure UI state_ (themes, menus, toggles) **that work is wasted**. - -### Zero-UI's "PRE-rendering" Approach: - -1. **Build-time:** Tailwind variants generated for every state -2. **Pre-render:** App renders once with all possible states -3. **Runtime:** State changes only flip a `data-*` attribute - -**Result:** **5-10× faster visual updates** with **ZERO additional bundle cost**. - ---- - -## Performance Benchmarks - -
- -_Tested on Apple M1 - Chrome DevTools Performance Tab_ - -
- -| **Nodes Updated** | **React State** | **Zero-UI** | **Speed Improvement** | -| :---------------: | :-------------: | :---------: | :-------------------: | -| 10,000 | ~50 ms | ~5 ms | **10× faster** | -| 25,000 | ~180 ms | ~15 ms | **12× faster** | -| 50,000 | ~300 ms | ~20 ms | **15× faster** | - -> **Try it yourself:** Re-run these benchmarks using the demo links above with Chrome DevTools. - ---- - -
- -### Ready to get started? - -[**Get Started**](https://github.com/react-zero-ui/core/#quick-start) and never re-render again. - -
diff --git a/docs-legacy/rules.md b/docs-legacy/rules.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/content/docs/api-reference.mdx b/docs/content/docs/api-reference.mdx new file mode 100644 index 0000000..92523cc --- /dev/null +++ b/docs/content/docs/api-reference.mdx @@ -0,0 +1,379 @@ +--- +title: API Reference +description: Complete API documentation for React Zero-UI +--- + +Detailed reference for all hooks, utilities, and configuration options. + +## Core Hooks + +### `useUI(key, initial, flag?)` + +Global UI state hook that updates `data-*` attributes on ``. + +```tsx +const [staleValue, setter] = useUI(key, initial, flag?); +``` + +#### Parameters + +| Parameter | Type | Description | +| --------- | --------------- | ------------------------------------------------------ | +| `key` | `string` | The state key (becomes `data-{key}` attribute) | +| `initial` | `T` | Initial/default value for SSR | +| `flag?` | `typeof CssVar` | Optional: Use CSS variables instead of data attributes | + +#### Returns + +| Return | Type | Description | +| ------------ | ------------------- | ------------------------------------------------ | +| `staleValue` | `T` | Initial value (doesn't update, use for SSR only) | +| `setter` | `GlobalSetterFn` | Function to update the global state | + +#### Examples + +```tsx +// Basic usage +const [theme, setTheme] = useUI("theme", "light"); +setTheme("dark"); // Sets data-theme="dark" on + +// With TypeScript generics +const [status, setStatus] = useUI<"loading" | "success" | "error">("status", "loading"); + +// With CSS variables +const [color, setColor] = useUI("primary", "#blue", CssVar); +setColor("#red"); // Sets --primary: #red on + +// Functional updates +setTheme((prev) => (prev === "light" ? "dark" : "light")); +``` + +### `useScopedUI(key, initial, flag?)` + +Scoped UI state hook that updates `data-*` attributes on a specific element. + +```tsx +const [staleValue, setter] = useScopedUI(key, initial, flag?); +``` + +#### Parameters + +Same as `useUI`, but affects only the element assigned to `setter.ref`. + +#### Returns + +| Return | Type | Description | +| ------------ | ------------------- | ------------------------------------------------ | +| `staleValue` | `T` | Initial value (doesn't update, use for SSR only) | +| `setter` | `ScopedSetterFn` | Function with attached `ref` property | + +#### Examples + +```tsx +// Basic scoped usage +const [modal, setModal] = useScopedUI("modal", "closed"); + +
+ Modal content +
; + +// With CSS variables +const [blur, setBlur] = useScopedUI("blur", "0px", CssVar); + +
+ Blurred content +
; +``` + +## Utilities + +### `CssVar` + +Flag to enable CSS variable mode instead of data attributes. + +```tsx +import { CssVar } from "@react-zero-ui/core"; + +// Global CSS variable +const [color, setColor] = useUI("primary", "#blue", CssVar); +// Result: + +// Scoped CSS variable +const [size, setSize] = useScopedUI("font-size", "16px", CssVar); +// Result:
+``` + +## Experimental APIs + +### `zeroSSR.onClick(key, values)` + +Creates click handlers for server components (experimental). + +```tsx +import { zeroSSR } from "@react-zero-ui/core/experimental"; + +const clickHandler = zeroSSR.onClick(key, values); +``` + +#### Parameters + +| Parameter | Type | Description | +| --------- | ---------- | -------------------------------- | +| `key` | `string` | State key (kebab-case required) | +| `values` | `string[]` | Array of values to cycle through | + +#### Returns + +Object with `data-ui` attribute for JSX spread. + +#### Examples + +```tsx +// Global state toggle + + +// Multi-value cycling + +``` + +### `scopedZeroSSR.onClick(key, values)` + +Creates scoped click handlers for server components. + +```tsx +import { scopedZeroSSR } from "@react-zero-ui/core/experimental"; + +const clickHandler = scopedZeroSSR.onClick(key, values); +``` + +#### Usage + +Same as `zeroSSR.onClick`, but affects the closest ancestor with `data-{key}` attribute. + +```tsx +
+ + +
Modal content
+
+``` + +### `activateZeroUiRuntime(variantMap)` + +Activates the SSR runtime for click handling (experimental). + +```tsx +import { activateZeroUiRuntime } from "@react-zero-ui/core/experimental/runtime"; +import { variantKeyMap } from "./.zero-ui/attributes"; + +activateZeroUiRuntime(variantKeyMap); +``` + +#### Parameters + +| Parameter | Type | Description | +| ------------ | -------------------------- | -------------------------------------------- | +| `variantMap` | `Record` | Generated variant mapping from build process | + +#### Setup + +```tsx +// src/components/InitZeroUI.tsx +"use client"; + +import { variantKeyMap } from "../.zero-ui/attributes"; +import { activateZeroUiRuntime } from "@react-zero-ui/core/experimental/runtime"; + +activateZeroUiRuntime(variantKeyMap); + +export const InitZeroUI = () => null; +``` + +```tsx +// app/layout.tsx +import { InitZeroUI } from "../components/InitZeroUI"; + +export default function RootLayout({ children }) { + return ( + + + + {children} + + + ); +} +``` + +## TypeScript Types + +### `UIAction` + +Union type for state update actions. + +```tsx +type UIAction = T | ((prev: T) => T); +``` + +### `GlobalSetterFn` + +Function type for global state setters. + +```tsx +type GlobalSetterFn = (action: UIAction) => void; +``` + +### `ScopedSetterFn` + +Function type for scoped state setters with attached ref. + +```tsx +interface ScopedSetterFn { + (action: UIAction): void; + ref?: RefObject | ((node: HTMLElement | null) => void); + cssVar?: typeof cssVar; +} +``` + +## Limitations & Constraints + +### State Key Requirements + +- **Do not use imported variables in the state key.** +- Must be valid HTML attribute names. +- Kebab-case required: `'sidebar-state'` not `'sidebarState'`. +- Avoid conflicts with existing data attributes. +- Must resolve to a non-spaced string: `'sidebar-state'` not `'sidebar State'`. +- Must be a local constant that resolves to a string. + +### Scoped UI Constraints + +- Each `useScopedUI` hook supports only one ref attachment. +- Multiple refs will throw development-time errors. +- Use separate hooks or components for multiple scoped elements. + +### CSS Variable Naming + +- Automatically prefixed with `--`. +- Must be valid CSS custom property names. +- Example: `'primary-color'` becomes `'--primary-color'`. + +### SSR Considerations + +- Initial values must be deterministic for SSR. +- Avoid dynamic initial values that differ between server/client. +- Use `useEffect` for client-only state initialization. + +## Generated Files + +### `.zero-ui/attributes.ts` + +Generated variant mapping for runtime activation. + +```ts +/* AUTO-GENERATED - DO NOT EDIT */ +export const bodyAttributes = { + "data-theme": "light", + "data-accent": "violet", + "data-scrolled": "up", + // ... +}; +``` + +### `.zero-ui/styles.css` (Vite) + +Generated CSS variants for Vite projects. + +```css +/* Auto-generated Tailwind variants */ +[data-theme="dark"] .theme-dark\:bg-gray-900 { + background-color: rgb(17 24 39); +} +/* ... */ +``` + +## Debugging + +### Enable debug mode + +```js +// postcss.config.js +module.exports = { + plugins: { + "@react-zero-ui/core/postcss": { + debug: true, // Enables verbose logging + }, + tailwindcss: {}, + }, +}; +``` + +### Check generated output + +```bash +# View generated variants +ls -la .zero-ui/ +cat .zero-ui/attributes.ts +``` + +### Browser DevTools + +1. **Elements tab** — check for `data-*` attributes on target elements. +2. **Computed styles** — verify CSS rules are applying correctly. +3. **Console** — look for Zero-UI runtime messages (in debug mode). + +## Best Practices + +### State key naming + +```tsx +// Good: Descriptive and clear +useUI("theme", "light"); +useUI("sidebar-state", "collapsed"); +useUI("modal-visibility", "hidden"); + +// Avoid: Generic or unclear +useUI("state", "on"); +useUI("x", "y"); +useUI("toggle", "true"); +``` + +### TypeScript usage + +```tsx +// Use specific union types +type Theme = "light" | "dark" | "auto"; +const [, setTheme] = useUI("theme", "light"); + +// For complex states, define types +type ModalState = "closed" | "opening" | "open" | "closing"; +const [, setModal] = useUI("modal", "closed"); +``` + +### Performance tips + +```tsx +// Use CSS for conditional rendering +
Modal content
; + +// Avoid reading stale values for logic — this won't work as expected: +const [modal, setModal] = useUI("modal", "closed"); +{ + modal === "open" && ; +} +``` + +## Need more help? + +- [Usage examples](/docs/usage-examples) +- [Migration guide](/docs/migration-guide) diff --git a/docs/content/docs/experimental.mdx b/docs/content/docs/experimental.mdx new file mode 100644 index 0000000..e3156ef --- /dev/null +++ b/docs/content/docs/experimental.mdx @@ -0,0 +1,167 @@ +--- +title: Experimental Runtime +description: SSR-safe click handling for React server components without "use client" +--- + +**SSR-safe runtime logic** for handling interactivity in React server components without using `"use client"`. + +Designed to be tiny (~300 bytes), deterministic, and fully compatible with React Zero-UI's pre-rendered data-attribute model. + +## Why this approach? + +**The problem:** a single `onClick` event forces your entire component tree to become client-rendered. In Next.js, this means shipping extra JavaScript, losing SSR benefits, and adding hydration overhead — all for basic interactivity. + +**The solution:** this design creates the perfect bridge between **static HTML** and **interactive UX**, while maintaining: + +- Server-rendered performance +- Zero JavaScript bundle overhead +- Instant visual feedback + +_Why sacrifice server-side rendering for a simple click handler when 300 bytes of runtime can handle all the clicks in your app?_ + +## Core Functionality + +### `activateZeroUiRuntime()` + +The core runtime entrypoint that enables client-side interactivity in server components. + +**How it works:** + +1. **Single global listener** — registers one click event listener on `document`. +2. **Smart detection** — listens for clicks on elements with `data-ui` attributes. +3. **Directive parsing** — interprets `data-ui` directives in this format: + + ``` + data-ui="global:key(val1,val2,...)" -> flips data-key on document.body + data-ui="scoped:key(val1,val2,...)" -> flips data-key on closest ancestor/self + ``` + +4. **Round-robin cycling** — cycles through values in sequence. +5. **Instant DOM updates** — updates DOM immediately for Tailwind responsiveness. + +> **Note:** guards against duplicate initialization using `window.__zero` flag. + +## Helper Functions + +### `zeroSSR.onClick()` & `scopedZeroSSR.onClick()` + +Utility functions that generate valid `data-ui` attributes for JSX/TSX. + +**Global example:** + +```tsx +zeroSSR.onClick("theme", ["dark", "light"]); +// Returns: { 'data-ui': 'global:theme(dark,light)' } +``` + +**Scoped example:** + +```tsx +scopedZeroSSR.onClick("modal", ["open", "closed"]); +// Returns: { 'data-ui': 'scoped:modal(open,closed)' } +``` + +**Development validation:** + +- Ensures keys are kebab-case +- Validates at least one value is provided + +## Installation & Setup + +### Step 1: Install the package + +```bash +npm install @react-zero-ui/core@0.3.1-beta.2 +``` + +### Step 2: Generate variants + +Run your development server to generate the required variant map: + +```bash +npm run dev +``` + +This creates `.zero-ui/attributes.ts` containing the variant map needed for runtime activation. + +### Step 3: Create `` component + +```tsx +"use client"; + +import { variantKeyMap } from "path/to/.zero-ui/attributes"; +import { activateZeroUiRuntime } from "@react-zero-ui/core/experimental/runtime"; + +activateZeroUiRuntime(variantKeyMap); + +export const InitZeroUI = () => null; +``` + +### Step 4: Add to root layout + +```tsx +import { InitZeroUI } from "path/to/InitZeroUI"; + +export default function RootLayout({ children }) { + return ( + + + + {children} + + + ); +} +``` + +## Usage Examples + +### Global theme toggle + +```tsx +import { zeroSSR } from "@react-zero-ui/core/experimental"; + +
Click me to cycle themes!
; +``` + +**Pair with Tailwind variants:** + +```html +
Interactive Server Component!
+``` + +### Scoped modal toggle + +```tsx +import { scopedZeroSSR } from "@react-zero-ui/core/experimental"; + +// Scopes based on matching data-* attribute (e.g. data-modal) +
+ +
; +``` + +## Design Philosophy + +### Core principles + +- **No React state** — zero re-renders involved +- **Pure DOM mutations** — works entirely via `data-*` attribute changes +- **Server component compatible** — full compatibility with all server components +- **Tailwind-first** — designed for conditional CSS classes + +## Summary + +| Feature | Description | +| ------------------------------- | --------------------------------------------------------- | +| **`activateZeroUiRuntime()`** | Enables click handling on static components via `data-ui` | +| **`zeroSSR` / `scopedZeroSSR`** | Generate valid click handlers as JSX props | +| **Runtime overhead** | ~300 bytes total | +| **React re-renders** | Zero | +| **Server component support** | Full compatibility | + +> **Source code:** see [experimental runtime source](https://github.com/react-zero-ui/core/tree/main/packages/core/src/experimental) for implementation details. + +--- + +_The bridge between static HTML and interactive UX — no state, no runtime overhead, works in server components, zero re-renders._ diff --git a/docs/content/docs/faq.mdx b/docs/content/docs/faq.mdx new file mode 100644 index 0000000..456cdcf --- /dev/null +++ b/docs/content/docs/faq.mdx @@ -0,0 +1,328 @@ +--- +title: FAQ +description: Frequently asked questions about React Zero-UI +--- + +Everything you need to know to get the most out of Zero-UI. + +## General Questions + +### What exactly is React Zero-UI? + +React Zero-UI is a state management library that eliminates React re-renders for UI state by using CSS and data attributes instead of component state. It "pre-renders" all possible UI states at **build time** and switches between them by flipping data attributes. + +### How is this different from regular React state? + +**Traditional React:** + +```tsx +const [theme, setTheme] = useState("light"); +// Every setState() triggers re-render of component tree +``` + +**React Zero-UI:** + +```tsx +const [, setTheme] = useUI("theme", "light"); +// No re-renders, just flips data-theme="dark" on +``` + +### Do I need to learn anything new? + +Not really! If you know React hooks and Tailwind CSS, you already know 95% of what you need: + +1. Replace `useState` with `useUI` +2. Replace conditional classes with Tailwind variants +3. Everything else works the same + +## Performance Questions + +### How much faster is it really? + +**Benchmarks** (10,000 DOM nodes): + +- React state changes: ~50ms +- Zero-UI state changes: ~5ms +- **Result: 10× faster updates** + +The more complex your UI, the bigger the performance gain. + +### Does it increase my bundle size? + +**Zero-UI core: ~350 bytes** in production (10x smaller than a single SVG icon). + +Compare that to: + +- Redux: ~5KB +- SVG icon: ~4KB + +### What about CSS file size? + +CSS variants are only generated for the states you actually use. If you use 3 theme values, you get CSS for 3 variants — not hundreds. + +## Technical Questions + +### Why can't I use imported variables in the state key? + +Zero-UI uses a custom Babel-based resolver that only analyzes **top-level `const` values in the same file**. Imported variables are **not supported**, even if re-assigned to a local `const`. + +Why? Because resolving cross-file imports requires a **full module graph**, accounting for: + +- ESM vs CJS interop +- TypeScript vs JavaScript +- Re-exports, namespace imports, aliased paths, dynamic values +- Recursive constant folding across files + +This problem is **deceptively deep** — even Facebook's [Prepack](https://prepack.io/) abandoned the attempt after years of effort. + +Until a future plugin system for **Turbopack** emerges, we've chosen the simpler, safer route: **only local `const` string literals are supported.** + +We may ship a resolver plugin for Turbopack once it's open to third-party hooks. + +### Can I use it with existing state management? + +Absolutely! Zero-UI is designed for **UI state only**. Use it alongside: + +- Redux/Zustand for business logic +- React Query for server state +- Regular `useState` for component-specific data + +```tsx +// Great combination +const [data, setData] = useState(null); // Component state +const { user } = useQuery("user"); // Server state +const [, setTheme] = useUI("theme", "light"); // UI state +``` + +### Does it work with SSR/Next.js? + +Yes! Zero-UI is designed with SSR in mind: + +- No hydration mismatches +- Perfect FOUC prevention +- Works with Next.js App Router +- Experimental server component support — see [experimental](/docs/experimental) + +### Can I persist state across page reloads? + +Zero-UI state is DOM-based, so it doesn't persist automatically. For persistence you handle it the same as you would with regular React state: + +```tsx +// Save to localStorage +const [, setTheme] = useUI("theme", "light"); + +const persistentSetTheme = (value) => { + setTheme(value); + localStorage.setItem("theme", value); +}; + +// Load on mount +useEffect(() => { + const saved = localStorage.getItem("theme"); + if (saved) setTheme(saved); +}, []); +``` + +## Styling Questions + +### Do I have to use Tailwind? + +**For the best experience, yes.** Zero-UI generates Tailwind variants automatically. + +```css +[data-theme="dark"] { + background: black; +} +``` + +### Can I use CSS variables? + +Yes! Pass the `CssVar` flag: + +```tsx +import { useUI, CssVar } from "@react-zero-ui/core"; + +const [, setColor] = useUI("primary", "#blue", CssVar); +// Result: +``` + +## Migration Questions + +### How hard is it to migrate from useState? + +**Very easy** for UI state: + +```tsx +// Before +const [theme, setTheme] = useState("light"); + +// After +const [, setTheme] = useUI("theme", "light"); +// Note: Don't use the first return value for logic +``` + +### What about Context API? + +If context is used for UI state, it's even easier! Just remove the provider: + +```tsx +// Before: Need provider, useContext, prop drilling + + +; + +// After: State works everywhere automatically +function App() { + const [, setTheme] = useUI("theme", "light"); + // Theme accessible anywhere via CSS classes +} +``` + +### Should I migrate everything at once? + +**No!** Migrate incrementally: + +1. Start with global UI state (theme, modals) +2. Move component-specific UI state +3. Leave business logic in existing solutions + +## Experimental Features + +### What's the experimental SSR runtime? + +It allows interactivity in **server components** without `'use client'` — see [experimental](/docs/experimental): + +```tsx +// This is a SERVER COMPONENT! +import { zeroSSR } from "@react-zero-ui/core/experimental"; + +function ServerThemeToggle() { + return ; +} +``` + +Only ~300 bytes of runtime for unlimited server component interactivity. + +### Is the experimental API stable? + +It's **experimental** but used in production by early adopters. The API may change in minor versions, but we'll provide migration guides. + +### Should I use it in production? + +I would not recommend using it in production until the API is stable. The API is still in development and may change in minor versions, but we'll provide migration guides. + +## Troubleshooting + +### My Tailwind variants aren't working + +**Check these in order:** + +1. **PostCSS plugin configured (Next.js)?** + + ```js + // postcss.config.js + module.exports = { + plugins: { + "@react-zero-ui/core/postcss": {}, // Before Tailwind! + tailwindcss: {}, + }, + }; + ``` + +2. **Tailwind v4 configured and imported?** + + ```css + @import "tailwindcss"; + ``` + +### I get "Multiple ref attachments" error + +Each `useScopedUI` can only attach to one element: + +```tsx +// Wrong +const [, setState] = useScopedUI('state', 'default'); +
+
// Error! + +// Right +const [, setState1] = useScopedUI('state-1', 'default'); +const [, setState2] = useScopedUI('state-2', 'default'); +
+
+``` + +## Best Practices + +### When should I use Zero-UI? + +**Perfect for:** + +- Theme switching +- Modal/drawer states +- Navigation states +- UI toggles and animations +- Any visual state that doesn't affect business logic + +**Not ideal for:** + +- Form data +- API responses +- Complex business logic +- State that needs to trigger side effects + +### Should I use global or scoped state? + +**Global (`useUI`)** for: + +- App-wide state (theme, language) +- State that affects multiple components +- State you want accessible everywhere + +**Scoped (`useScopedUI`)** for: + +- Component-specific state +- State that doesn't affect other components +- Better performance for isolated changes + +## Future & Roadmap + +### What's coming next? + +- Enhanced TypeScript support +- More framework integrations (Vue, Svelte) +- Better DevTools integration +- Performance monitoring tools + +### How can I influence the roadmap? + +- Vote on feature requests in GitHub Discussions +- Report bugs and use cases +- Share your usage patterns +- Contribute code or documentation + +## Getting Help + +### Where can I ask questions? + +1. **Documentation** — check the guides first +2. **Discussions** — [GitHub Discussions](https://github.com/react-zero-ui/core/discussions) for questions +3. **Issues** — [GitHub Issues](https://github.com/react-zero-ui/core/issues) for bugs + +### How do I report a bug? + +1. Check existing issues first +2. Create a minimal reproduction +3. Include your configuration (`postcss.config.js`, etc.) +4. Include browser and framework versions + +### Can I contribute? + +**Absolutely!** We welcome: + +- Documentation improvements +- Bug fixes +- Feature implementations +- Examples and demos + +See the [contributing guide](https://github.com/react-zero-ui/core/blob/main/CONTRIBUTING.md) to get started. diff --git a/docs/content/docs/getting-started/meta.json b/docs/content/docs/getting-started/meta.json new file mode 100644 index 0000000..0022fb7 --- /dev/null +++ b/docs/content/docs/getting-started/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Getting Started", + "pages": ["next", "vite"] +} diff --git a/docs/content/docs/getting-started/next.mdx b/docs/content/docs/getting-started/next.mdx new file mode 100644 index 0000000..4d69065 --- /dev/null +++ b/docs/content/docs/getting-started/next.mdx @@ -0,0 +1,69 @@ +--- +title: Next.js +description: Set up React Zero-UI in a Next.js App Router project +--- + +## 1. Install dependencies + +```bash +npm install @react-zero-ui/core +``` + +```bash +npm install @tailwindcss/postcss +``` + +## 2. Add the PostCSS plugin + +Zero-UI must come **before** Tailwind. + +```js +// postcss.config.* (ESM) +const config = { + plugins: ["@react-zero-ui/core/postcss", "@tailwindcss/postcss"], +}; +export default config; +``` + +```js +// postcss.config.* (CJS) +module.exports = { + plugins: { "@react-zero-ui/core/postcss": {}, tailwindcss: {} }, +}; +``` + +## 3. Import Tailwind + +```css +/* global.css */ +@import "tailwindcss"; +``` + +## 4. Start the app + +```bash +npm run dev +``` + +Zero-UI generates a `.zero-ui/` folder in your project root containing `attributes.ts` and type definitions. + +## 5. Prevent FOUC + +Spread `bodyAttributes` on `` in your root layout. + +```tsx +// app/layout.tsx +import { bodyAttributes } from "./.zero-ui/attributes"; + +export default function RootLayout({ children }) { + return ( + + {children} + + ); +} +``` + +That's it. Zero-UI now adds the data-`*` attributes to the body tag and Tailwind generates the matching variant classes. + +Next up: check out the [experimental SSR-safe click handler](/docs/experimental). diff --git a/docs/content/docs/getting-started/vite.mdx b/docs/content/docs/getting-started/vite.mdx new file mode 100644 index 0000000..39355df --- /dev/null +++ b/docs/content/docs/getting-started/vite.mdx @@ -0,0 +1,39 @@ +--- +title: Vite +description: Set up React Zero-UI in a Vite project +--- + +## 1. Install dependencies + +```bash +npm install @react-zero-ui/core +``` + +```bash +npm install @tailwindcss/postcss +``` + +## 2. Add the plugin to `vite.config.ts` + +```js +import zeroUI from "@react-zero-ui/core/vite"; +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import tailwindCss from "@tailwindcss/postcss"; + +export default defineConfig({ + // Remove the default `tailwindcss()` plugin — pass it into zeroUI instead + plugins: [zeroUI({ tailwind: tailwindCss }), react()], +}); +``` + +## 3. Import Tailwind + +```css +/* global.css */ +@import "tailwindcss"; +``` + +That's it. The plugin adds the data-`*` attributes to the body tag (no FOUC) and Tailwind generates the matching variant classes. + +See [Usage examples](/docs/usage-examples) for patterns you can drop into your app. diff --git a/docs/content/docs/index.mdx b/docs/content/docs/index.mdx index 1ede18e..b925500 100644 --- a/docs/content/docs/index.mdx +++ b/docs/content/docs/index.mdx @@ -1,13 +1,22 @@ --- -title: Hello World -description: Your first document +title: Introduction +description: Ultra-fast React UI state with zero runtime and zero re-renders --- -Welcome to the docs! You can start writing documents in `/content/docs`. +React Zero-UI is a state management library that eliminates React re-renders for UI state by using CSS and data attributes instead of component state. It pre-renders all possible UI states at build time and switches between them by flipping `data-*` attributes on `` (or on scoped elements). -## What is Next? +## Why Zero-UI? + +- **Zero re-renders** — state changes flip DOM attributes, not component trees. +- **~350 bytes** — smaller than a single SVG icon. +- **SSR-safe** — no hydration mismatches, no FOUC. +- **Tailwind-native** — use variants like `theme-dark:bg-gray-900` anywhere. + +## Get started - - + + + + diff --git a/docs/content/docs/meta.json b/docs/content/docs/meta.json new file mode 100644 index 0000000..71010e7 --- /dev/null +++ b/docs/content/docs/meta.json @@ -0,0 +1,15 @@ +{ + "title": "Docs", + "pages": [ + "index", + "---Getting Started---", + "getting-started", + "---Core Concepts---", + "usage-examples", + "api-reference", + "migration-guide", + "---Advanced---", + "experimental", + "faq" + ] +} diff --git a/docs/content/docs/migration-guide.mdx b/docs/content/docs/migration-guide.mdx new file mode 100644 index 0000000..dae0c17 --- /dev/null +++ b/docs/content/docs/migration-guide.mdx @@ -0,0 +1,420 @@ +--- +title: Migration Guide +description: Migrate to React Zero-UI from existing state management solutions +--- + +Step-by-step guides for common migration scenarios. + +## From React useState + +### Basic state migration + +**Before (React useState):** + +```tsx +import { useState } from "react"; + +function ThemeToggle() { + const [theme, setTheme] = useState("light"); + + return ( +
+ +
+ ); +} +``` + +**After (React Zero-UI):** + +```tsx +import { useUI } from "@react-zero-ui/core"; + +function ThemeToggle() { + const [, setTheme] = useUI("theme", "light"); + + return ( +
+ +
+ ); +} +``` + +**Key changes:** + +1. Replace `useState` with `useUI` +2. Replace conditional classNames with Tailwind variants +3. State key becomes a data attribute (`data-theme`) +4. Use functional updates for state transitions + +### Modal state migration + +**Before:** + +```tsx +function App() { + const [isModalOpen, setIsModalOpen] = useState(false); + + return ( + <> + + + {isModalOpen && ( +
+
+ +
+
+ )} + + ); +} +``` + +**After:** + +```tsx +function App() { + const [, setModal] = useUI("modal", "closed"); + + return ( + <> + + +
+
+ +
+
+ + ); +} +``` + +## From Context API + +### Global theme context + +**Before (Context API):** + +```tsx +const ThemeContext = createContext(); + +function ThemeProvider({ children }) { + const [theme, setTheme] = useState("light"); + + return ( + +
{children}
+
+ ); +} + +function ThemeToggle() { + const { theme, setTheme } = useContext(ThemeContext); + + return ; +} +``` + +**After (React Zero-UI):** + +```tsx +// No provider needed! + +function App({ children }) { + return
{children}
; +} + +function ThemeToggle() { + const [, setTheme] = useUI("theme", "light"); + + return ( + + ); +} +``` + +**Benefits:** + +- No more context providers +- No more prop drilling +- No re-renders when state changes +- State accessible anywhere via Tailwind classes + +## From Redux/Zustand + +### Redux theme slice + +**Before (Redux):** + +```tsx +// store/themeSlice.ts +const themeSlice = createSlice({ + name: "theme", + initialState: { value: "light" }, + reducers: { + toggleTheme: (state) => { + state.value = state.value === "light" ? "dark" : "light"; + }, + }, +}); + +// Component +function ThemeToggle() { + const theme = useSelector((state) => state.theme.value); + const dispatch = useDispatch(); + + return ( +
+ +
+ ); +} +``` + +**After (React Zero-UI):** + +```tsx +// No store setup needed! + +function ThemeToggle() { + const [, setTheme] = useUI("theme", "light"); + + return ( +
+ +
+ ); +} +``` + +### Zustand store + +**Before (Zustand):** + +```tsx +const useThemeStore = create((set) => ({ + theme: "light", + toggleTheme: () => set((state) => ({ theme: state.theme === "light" ? "dark" : "light" })), +})); + +function ThemeToggle() { + const { theme, toggleTheme } = useThemeStore(); + + return ( +
+ +
+ ); +} +``` + +**After (React Zero-UI):** + +```tsx +function ThemeToggle() { + const [, setTheme] = useUI("theme", "light"); + + return ( +
+ +
+ ); +} +``` + +## From CSS-in-JS Solutions + +### Styled Components with theme + +**Before (Styled Components):** + +```tsx +const ThemeProvider = styled.div` + background: ${(props) => props.theme.bg}; + color: ${(props) => props.theme.text}; +`; + +const theme = { light: { bg: "white", text: "black" }, dark: { bg: "black", text: "white" } }; + +function App() { + const [currentTheme, setCurrentTheme] = useState("light"); + + return ( + + + + ); +} +``` + +**After (React Zero-UI + Tailwind):** + +```tsx +function App() { + const [, setTheme] = useUI("theme", "light"); + + return ( +
+ +
+ ); +} +``` + +## From Component State to Global State + +### Converting local state to global + +**Before (local component state):** + +```tsx +function Sidebar() { + const [isOpen, setIsOpen] = useState(false); + + return ( +
+ +
+ ); +} + +function Header() { + // Can't access sidebar state! + return
Header content
; +} +``` + +**After (global state, accessible everywhere):** + +```tsx +function Sidebar() { + const [, setSidebar] = useUI("sidebar", "closed"); + + return ( +
+ +
+ ); +} + +function Header() { + // Can respond to sidebar state! + return
Header content
; +} +``` + +## Migration Checklist + +### Step 1: Identify UI state + +- List all `useState` hooks that control UI appearance +- Identify global state (Context, Redux, Zustand) +- Find conditional className logic +- Note prop drilling for UI state + +### Step 2: Install and configure + +```bash +npx create-zero-ui +``` + +Or manual setup: + +- Install `@react-zero-ui/core` +- Configure PostCSS plugin +- Update Tailwind config + +### Step 3: Convert state by state + +- Replace `useState` with `useUI` +- Convert conditional classes to Tailwind variants +- Remove context providers for UI state +- Update component dependencies + +### Step 4: Test and verify + +- Verify all state changes work +- Check for any missing CSS variants +- Test SSR/hydration (no FOUC) +- Validate performance improvements + +## Migration Gotchas + +### 1. State key naming + +```tsx +// Avoid conflicts with existing data attributes +const [, setState] = useUI("id", "default"); // conflicts with data-id + +// Use descriptive, unique keys +const [, setState] = useUI("modal-state", "closed"); +``` + +### 2. Initial value consistency + +```tsx +// Ensure initial values match what CSS expects +const [, setTheme] = useUI("theme", "lite"); // typo! + +// Match your Tailwind variants exactly +const [, setTheme] = useUI("theme", "light"); // matches theme-light: +``` + +### 3. No imported state keys (yet) + +Imported variables can't be resolved statically — even if reassigned locally. + +```ts +// This will fail at build time +import { THEME_KEY } from "./constants"; +const localKey = THEME_KEY; +const [, setTheme] = useUI(localKey, "dark"); +``` + +```ts +// Inline the string directly or re-declare as a top-level const +const THEME_KEY = "theme"; +const [, setTheme] = useUI(THEME_KEY, "dark"); +``` + +> We're working on support for imported bindings once Next.js exposes a plugin API for Turbopack. Until then, stick with top-level `const` literals. + +### 4. Don't read stale values + +```tsx +// Don't use returned value for logic +const [theme, setTheme] = useUI("theme", "light"); +if (theme === "dark") { + /* Won't work! */ +} + +// Use CSS classes for visual state +
Only visible in light mode
; +``` + +## Before / After comparison + +| Aspect | Before (Traditional) | After (React Zero-UI) | +| ----------------- | ----------------------------- | -------------------------- | +| **Bundle Size** | +5KB (Redux) / +2KB (Context) | +350 bytes | +| **Re-renders** | Every state change | Zero | +| **Performance** | Slower with scale | Constant fast | +| **Setup** | Complex (store, providers) | Simple (one hook) | +| **Global Access** | Prop drilling / Context | Tailwind variants anywhere | +| **SSR** | Hydration mismatches | Perfect SSR | + +## Migration complete + +Your app should now be faster, simpler, and more maintainable. + +- [Usage examples](/docs/usage-examples) +- [API reference](/docs/api-reference) diff --git a/docs/content/docs/test.mdx b/docs/content/docs/test.mdx deleted file mode 100644 index f475f4a..0000000 --- a/docs/content/docs/test.mdx +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Components -description: Components ---- - -## Code Block - -```js -console.log('Hello World'); -``` - -## Cards - - - - - diff --git a/docs/content/docs/usage-examples.mdx b/docs/content/docs/usage-examples.mdx new file mode 100644 index 0000000..4f7153b --- /dev/null +++ b/docs/content/docs/usage-examples.mdx @@ -0,0 +1,456 @@ +--- +title: Usage Examples +description: Comprehensive examples and patterns for React Zero-UI +--- + +Learn through practical, real-world use cases and best practices. + +## Basic Usage Patterns + +### 1. Theme toggle (global state) + +The most common pattern — global theme switching: + +```tsx +import { useUI } from "@react-zero-ui/core"; + +function ThemeToggle() { + const [theme, setTheme] = useUI("theme", "light"); + + return ( + + ); +} +``` + +**Tailwind usage anywhere in your app:** + +```html +
Content that responds to theme
+``` + +### 2. Modal state management + +```tsx +import { useUI } from "@react-zero-ui/core"; + +function App() { + const [, setModal] = useUI("modal", "closed"); + + return ( + <> + + + {/* Modal backdrop */} +
+
+

Modal Content

+ +
+
+ + ); +} +``` + +### 3. Multi-state navigation + +```tsx +import { useUI } from "@react-zero-ui/core"; + +type TabState = "home" | "about" | "contact"; + +function Navigation() { + const [activeTab, setActiveTab] = useUI("nav-tab", "home"); + + const tabs = [ + { id: "home", label: "Home" }, + { id: "about", label: "About" }, + { id: "contact", label: "Contact" }, + ] as const; + + return ( + + ); +} +``` + +## Scoped UI Patterns + +### 1. Component-level state + +```tsx +import { useScopedUI } from "@react-zero-ui/core"; + +function Card() { + const [state, setState] = useScopedUI("card-state", "collapsed"); + + return ( +
+ + +
+

This content only shows when expanded!

+
+
+ ); +} +``` + +### 2. Form field states + +```tsx +import { useScopedUI } from "@react-zero-ui/core"; + +function FormField({ label, ...props }) { + const [state, setState] = useScopedUI("field-state", "default"); + + return ( +
+ + setState("focused")} + onBlur={() => setState("default")} + onChange={(e) => { + const isValid = e.target.value.length > 0; + setState(isValid ? "success" : "error"); + }} + /> +
+ This field is required +
+
+ ); +} +``` + +## CSS Variable Patterns + +### 1. Dynamic styling with CSS variables + +```tsx +import { useUI, CssVar } from "@react-zero-ui/core"; + +function DynamicTheme() { + const [, setPrimaryColor] = useUI("primary-color", "#3b82f6", CssVar); + const [, setBlur] = useUI("blur-amount", "0px", CssVar); + + const colors = ["#3b82f6", "#ef4444", "#10b981", "#f59e0b"]; + + return ( +
+
+ {colors.map((color) => ( +
+ + + + {/* Uses CSS variables */} +
+ Dynamic styled content +
+
+ ); +} +``` + +### 2. Scoped CSS variables + +```tsx +import { useScopedUI, CssVar } from "@react-zero-ui/core"; + +function CustomSlider() { + const [value, setValue] = useScopedUI("slider-value", "50", CssVar); + + return ( +
+ setValue(e.target.value)} + className="w-full" + /> + + {/* Progress indicator using CSS variable */} +
+
+ ); +} +``` + +## SSR-Safe Patterns (Experimental) + +### 1. Server component interactivity + +```tsx +// This is a SERVER COMPONENT! No 'use client' needed +import { zeroSSR } from "@react-zero-ui/core/experimental"; + +function ServerThemeToggle() { + return ( + + ); +} +``` + +### 2. Scoped server component state + +```tsx +import { scopedZeroSSR } from "@react-zero-ui/core/experimental"; + +function ServerModal() { + return ( + // This data key sets the scope +
+ + +
+
+

Server-Rendered Modal

+ +
+
+
+ ); +} +``` + +## Advanced Patterns + +### 1. State composition + +```tsx +import { useUI } from "@react-zero-ui/core"; + +function Dashboard() { + const [, setSidebar] = useUI("sidebar", "collapsed"); + const [, setTheme] = useUI("theme", "light"); + const [, setNotifications] = useUI("notifications", "hidden"); + + return ( +
+ {/* Multiple states working together */} +
+ ); +} +``` + +### 2. Conditional logic with functional updates + +```tsx +import { useUI } from "@react-zero-ui/core"; + +function SmartToggle() { + const [, setMode] = useUI("app-mode", "normal"); + + const handleModeChange = (condition: boolean) => { + setMode((prev) => { + if (condition && prev === "normal") return "advanced"; + if (!condition && prev === "advanced") return "normal"; + return prev; + }); + }; + + return ; +} +``` + +### 3. Animation sequences + +```tsx +import { useUI } from "@react-zero-ui/core"; + +function AnimatedCard() { + const [, setAnimation] = useUI("card-anim", "idle"); + + const playAnimation = async () => { + setAnimation("preparing"); + await new Promise((resolve) => setTimeout(resolve, 100)); + + setAnimation("animating"); + await new Promise((resolve) => setTimeout(resolve, 500)); + + setAnimation("complete"); + await new Promise((resolve) => setTimeout(resolve, 200)); + + setAnimation("idle"); + }; + + return ( +
+ +
+ ); +} +``` + +## Styling Best Practices + +### 1. Semantic state names + +```tsx +// Good: Semantic and clear +const [, setModal] = useUI("modal", "closed"); +const [, setTheme] = useUI("theme", "light"); +const [, setNavigation] = useUI("nav-state", "collapsed"); + +// Avoid: Generic or unclear +const [, setState] = useUI("state", "on"); +const [, setThing] = useUI("x", "y"); +``` + +### 2. Consistent naming conventions + +```tsx +// Use kebab-case for multi-word keys +const [, setSidebarState] = useUI("sidebar-state", "collapsed"); +const [, setUserProfile] = useUI("user-profile", "hidden"); + +// Use clear value names +const [, setModal] = useUI("modal", "closed"); // closed/open +const [, setTheme] = useUI("theme", "light"); // light/dark/auto +``` + +### 3. Organize complex states + +```tsx +// For complex UIs, group related states +function App() { + // Layout states + const [, setSidebar] = useUI("sidebar", "collapsed"); + const [, setHeader] = useUI("header", "visible"); + + // Theme states + const [, setColorScheme] = useUI("color-scheme", "light"); + const [, setAccentColor] = useUI("accent-color", "blue"); + + // UI states + const [, setModal] = useUI("modal", "closed"); + const [, setToast] = useUI("toast", "hidden"); +} +``` + +## Common Pitfalls + +### 1. Don't use imported variables in the state key or initial value + +```tsx +// Wrong: Imported variables are not allowed +import { THEME_KEY } from "./constants"; +const [, setTheme] = useUI(THEME_KEY, "dark"); +``` + +### 2. Don't read state values for logic + +```tsx +// Wrong: staleValue doesn't update +const [theme, setTheme] = useUI("theme", "light"); +if (theme === "dark") { + /* This won't work as expected */ +} + +// Correct: Use CSS classes instead +
Light mode content
; +``` + +### 3. Avoid over-engineering simple toggles + +```tsx +// Overcomplicated for simple boolean +const [, setState] = useUI("feature", "disabled"); +setState((prev) => (prev === "disabled" ? "enabled" : "disabled")); + +// Better: Use descriptive boolean-like values +const [, setFeature] = useUI("feature", "off"); +setFeature((prev) => (prev === "off" ? "on" : "off")); +``` + +### 4. Don't attach multiple refs to scoped UI + +```tsx +// Wrong: Multiple refs not supported +const [, setState] = useScopedUI('state', 'default'); +return ( + <> +
{/* First ref */} +
{/* This will throw an error! */} + +); + +// Correct: Create separate components/hooks +function ComponentA() { + const [, setState] = useScopedUI("state-a", "default"); + return
; +} + +function ComponentB() { + const [, setState] = useScopedUI("state-b", "default"); + return
; +} +``` + +## Ready to build? + +These patterns cover 95% of real-world use cases. Mix and match them to create powerful, performant UIs. + +- [Live demo](https://zero-ui.dev) +- [API reference](/docs/api-reference) From 632fd7e54e86e228f605520269850cea2fd3ac92 Mon Sep 17 00:00:00 2001 From: Eric Chavez Date: Mon, 13 Apr 2026 20:25:48 -0700 Subject: [PATCH 03/15] docs: add landing page with inline Zero-UI demo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire @react-zero-ui/core into the docs workspace: PostCSS plugin ahead of Tailwind, bodyAttributes spread on in root layout, tsconfig path alias @zero-ui/attributes, .zero-ui/ gitignored. Replace default Fumadocs home page with a full landing: hero + install snippet + CTAs, useState-vs-useUI side-by-side, inline theme/accent demo (dog-foods Zero-UI itself — zero re-renders on click), why-it's-fast cards, and GitHub/npm/FAQ links. Update nav branding to "React Zero-UI" with Docs + GitHub links. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/.gitignore | 1 + docs/app/(home)/_components/LandingDemo.tsx | 82 ++++++++ docs/app/(home)/page.tsx | 205 +++++++++++++++++++- docs/app/layout.tsx | 3 +- docs/lib/layout.shared.tsx | 38 ++-- docs/package.json | 3 +- docs/postcss.config.mjs | 9 +- docs/tsconfig.json | 5 +- pnpm-lock.yaml | 3 + 9 files changed, 311 insertions(+), 38 deletions(-) create mode 100644 docs/app/(home)/_components/LandingDemo.tsx diff --git a/docs/.gitignore b/docs/.gitignore index 55a12ae..19b44eb 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -5,6 +5,7 @@ .contentlayer .content-collections .source +.zero-ui # test & build /coverage diff --git a/docs/app/(home)/_components/LandingDemo.tsx b/docs/app/(home)/_components/LandingDemo.tsx new file mode 100644 index 0000000..9a8dcd8 --- /dev/null +++ b/docs/app/(home)/_components/LandingDemo.tsx @@ -0,0 +1,82 @@ +'use client'; + +import { useUI } from '@react-zero-ui/core'; + +type Theme = 'light' | 'dark'; +type Accent = 'blue' | 'rose' | 'emerald' | 'amber'; + +const accents: { value: Accent; swatch: string; ring: string }[] = [ + { + value: 'blue', + swatch: 'bg-blue-500', + ring: 'demo-accent-blue:border-fd-foreground demo-accent-blue:scale-110', + }, + { + value: 'rose', + swatch: 'bg-rose-500', + ring: 'demo-accent-rose:border-fd-foreground demo-accent-rose:scale-110', + }, + { + value: 'emerald', + swatch: 'bg-emerald-500', + ring: 'demo-accent-emerald:border-fd-foreground demo-accent-emerald:scale-110', + }, + { + value: 'amber', + swatch: 'bg-amber-500', + ring: 'demo-accent-amber:border-fd-foreground demo-accent-amber:scale-110', + }, +]; + +export function LandingDemo() { + const [, setTheme] = useUI('demo-theme', 'light'); + const [, setAccent] = useUI('demo-accent', 'blue'); + + return ( +
+
+
+ Theme + +
+
+ Accent +
+ {accents.map((c) => ( +
+
+
+ +
+

+ Live preview +

+

Not a single React re-render.

+

+ Every click above flips data-demo-theme and{' '} + data-demo-accent on <body>. Tailwind + variants react instantly — no component state, no re-renders, no context provider. +

+ +
+
+ ); +} diff --git a/docs/app/(home)/page.tsx b/docs/app/(home)/page.tsx index e5b59f4..d8f2450 100644 --- a/docs/app/(home)/page.tsx +++ b/docs/app/(home)/page.tsx @@ -1,19 +1,204 @@ import Link from 'next/link'; +import { ArrowRight, Zap, Layers, Feather, Github } from 'lucide-react'; +import { LandingDemo } from './_components/LandingDemo'; export default function HomePage() { return ( -
-

Hello World

-

- You can open{' '} +

+ + + + + +
+ ); +} + +function Hero() { + return ( +
+
+ + Zero runtime · Zero re-renders · ~350 bytes +
+

+ Ultra-fast React UI state,
+ powered by CSS. +

+

+ React Zero-UI pre-renders every UI state at build time and flips data-* attributes on the + fly — giving you global state without providers, re-renders, or hydration headaches. +

+ +
+ $ + npm install @react-zero-ui/core +
+ +
- /docs - {' '} - and see the documentation. + className="bg-fd-primary text-fd-primary-foreground hover:bg-fd-primary/90 inline-flex items-center gap-2 rounded-md px-5 py-2.5 font-medium transition-colors"> + Read the Docs + + + Quick start + +
+
+ ); +} + +function MentalModel() { + return ( +
+
+

Presentation state is not data state.

+

+ Themes, modals, sidebars, accents — none of that needs to live in React. Zero-UI moves presentation state into the DOM where it + belongs, while you keep React for the things React is good at. +

+
+ +
+ + +
+);`} + /> + . +return ( +
+ +
+);`} + /> +
+ + ); +} + +function CodeCard({ label, tone, code }: { label: string; tone: 'muted' | 'primary'; code: string }) { + return ( +
+
{label}
+
+        {code}
+      
+
+ ); +} + +function Demo() { + return ( +
+
+

Try it right here.

+

+ The widget below is wired up with Zero-UI. Open React DevTools — you won't see a single render on click. +

+
+ +
+ ); +} + +function WhyFast() { + const cards = [ + { + icon: , + title: 'Zero re-renders', + body: 'State changes flip DOM attributes. React stays completely out of the loop — no reconciliation, no render cycles.', + }, + { + icon: , + title: '~350 bytes', + body: 'Smaller than a single SVG icon. An order of magnitude leaner than Redux or Zustand for UI state.', + }, + { + icon: , + title: 'Build-time CSS', + body: 'Tailwind variants are generated for every possible state at build time. Switching states is just changing a selector match.', + }, + ]; + + return ( +
+
+

Why it's fast.

+
+
+ {cards.map((c) => ( +
+
{c.icon}
+

{c.title}

+

{c.body}

+
+ ))} +
+
+ ); +} + +function SocialProof() { + return ( +
+

Open source. Tiny. Tested.

+

+ MIT licensed. Production-ready core, experimental SSR runtime, and a growing demo suite.

- + +
); } diff --git a/docs/app/layout.tsx b/docs/app/layout.tsx index db55a54..3076c7d 100644 --- a/docs/app/layout.tsx +++ b/docs/app/layout.tsx @@ -1,6 +1,7 @@ import '@/app/global.css'; import { RootProvider } from 'fumadocs-ui/provider/next'; import { Inter } from 'next/font/google'; +import { bodyAttributes } from '@zero-ui/attributes'; const inter = Inter({ subsets: ['latin'], @@ -9,7 +10,7 @@ const inter = Inter({ export default function Layout({ children }: LayoutProps<'/'>) { return ( - + {children} diff --git a/docs/lib/layout.shared.tsx b/docs/lib/layout.shared.tsx index 2bd1907..909fc2e 100644 --- a/docs/lib/layout.shared.tsx +++ b/docs/lib/layout.shared.tsx @@ -1,30 +1,28 @@ import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; +import { BookOpen, Github } from 'lucide-react'; -/** - * Shared layout configurations - * - * you can customise layouts individually from: - * Home Layout: app/(home)/layout.tsx - * Docs Layout: app/docs/layout.tsx - */ export function baseOptions(): BaseLayoutProps { return { nav: { title: ( - <> - - - - My App - + + React Zero-UI + ), }, - // see https://fumadocs.dev/docs/ui/navigation/links - links: [], + links: [ + { + icon: , + text: 'Docs', + url: '/docs', + }, + { + type: 'icon', + icon: , + text: 'GitHub', + url: 'https://github.com/react-zero-ui/core', + external: true, + }, + ], }; } diff --git a/docs/package.json b/docs/package.json index 6f0a1b2..a4750eb 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,7 +15,8 @@ "lucide-react": "^0.544.0", "fumadocs-ui": "15.8.5", "fumadocs-core": "15.8.5", - "fumadocs-mdx": "12.0.3" + "fumadocs-mdx": "12.0.3", + "@react-zero-ui/core": "^0.4.0" }, "devDependencies": { "@types/node": "^20", diff --git a/docs/postcss.config.mjs b/docs/postcss.config.mjs index a34a3d5..5758b6d 100644 --- a/docs/postcss.config.mjs +++ b/docs/postcss.config.mjs @@ -1,5 +1,6 @@ -export default { - plugins: { - '@tailwindcss/postcss': {}, - }, +// Zero-UI must come before Tailwind +const config = { + plugins: ['@react-zero-ui/core/postcss', '@tailwindcss/postcss'], }; + +export default config; diff --git a/docs/tsconfig.json b/docs/tsconfig.json index 4fd260f..4d8c21a 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -17,7 +17,8 @@ "incremental": true, "paths": { "@/.source": ["./.source/index.ts"], - "@/*": ["./*"] + "@/*": ["./*"], + "@zero-ui/attributes": ["./.zero-ui/attributes.js"] }, "plugins": [ { @@ -25,6 +26,6 @@ } ] }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".zero-ui/**/*.d.ts"], "exclude": ["node_modules"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5087160..ae95d67 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,9 @@ importers: docs: dependencies: + '@react-zero-ui/core': + specifier: ^0.4.0 + version: 0.4.0(@tailwindcss/postcss@4.1.11)(react@19.1.1) fumadocs-core: specifier: 15.8.5 version: 15.8.5(@types/react@19.1.9)(lucide-react@0.544.0(react@19.1.1))(next@15.5.4(@playwright/test@1.54.2)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) From 16dd037d1b063ea6c30f8df2ae89374920f4b65a Mon Sep 17 00:00:00 2001 From: Eric Chavez Date: Mon, 13 Apr 2026 20:44:33 -0700 Subject: [PATCH 04/15] docs: add real-world demo for hybrid useUI + useState pattern New /demo/real-world page puts a React-only pane and a Zero-UI hybrid pane side-by-side, both fetching the same mock data with a 650 ms simulated delay. React pane uses useState for loading; Zero-UI pane flips data-demo-search-status on via useUI so the skeleton appears via CSS, not reconciliation. Render counters in each pane make the difference visible during the loading transition. Cross-link from the landing page hero ("See it in action"), a Callout at the top of usage-examples, and a new FAQ entry on when to mix useUI with useState. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../(home)/demo/real-world/_components.tsx | 179 ++++++++++++++++++ docs/app/(home)/demo/real-world/_data.ts | 40 ++++ docs/app/(home)/demo/real-world/page.tsx | 61 ++++++ docs/app/(home)/page.tsx | 4 +- docs/content/docs/faq.mdx | 23 +++ docs/content/docs/usage-examples.mdx | 5 + 6 files changed, 310 insertions(+), 2 deletions(-) create mode 100644 docs/app/(home)/demo/real-world/_components.tsx create mode 100644 docs/app/(home)/demo/real-world/_data.ts create mode 100644 docs/app/(home)/demo/real-world/page.tsx diff --git a/docs/app/(home)/demo/real-world/_components.tsx b/docs/app/(home)/demo/real-world/_components.tsx new file mode 100644 index 0000000..f8793ee --- /dev/null +++ b/docs/app/(home)/demo/real-world/_components.tsx @@ -0,0 +1,179 @@ +'use client'; + +import { useEffect, useRef, useState } from 'react'; +import { useUI } from '@react-zero-ui/core'; +import { categories, fetchWithDelay, type Category, type Product } from './_data'; + +type CategoryFilter = Category | 'all'; + +export function RealWorldDemo() { + const [query, setQuery] = useState(''); + const [category, setCategory] = useState('all'); + + return ( +
+ +
+ + +
+

+ Type in the search or change the filter. Watch the render counters — both panes update on keystroke (the search input drives both), + but only the React pane re-renders during the loading transition. +

+
+ ); +} + +function SearchControls({ + query, + setQuery, + category, + setCategory, +}: { + query: string; + setQuery: (v: string) => void; + category: CategoryFilter; + setCategory: (v: CategoryFilter) => void; +}) { + return ( +
+ setQuery(e.target.value)} + className="border-fd-border bg-fd-background focus:border-fd-primary w-full rounded-md border px-3 py-2 text-sm outline-none sm:max-w-xs" + /> +
+ {categories.map((c) => { + const active = c.value === category; + return ( + + ); + })} +
+
+ ); +} + +function ReactPane({ query, category }: { query: string; category: CategoryFilter }) { + const [data, setData] = useState(() => []); + const [loading, setLoading] = useState(true); + const renderCount = useRef(0); + renderCount.current += 1; + + useEffect(() => { + let cancelled = false; + setLoading(true); + fetchWithDelay(query, category).then((results) => { + if (cancelled) return; + setData(results); + setLoading(false); + }); + return () => { + cancelled = true; + }; + }, [query, category]); + + return ( + + {loading ? : } + + ); +} + +function ZeroUiPane({ query, category }: { query: string; category: CategoryFilter }) { + const [data, setData] = useState(() => []); + const [, setStatus] = useUI<'idle' | 'loading' | 'success'>('demo-search-status', 'idle'); + const renderCount = useRef(0); + renderCount.current += 1; + + useEffect(() => { + let cancelled = false; + setStatus('loading'); + fetchWithDelay(query, category).then((results) => { + if (cancelled) return; + setData(results); + setStatus('success'); + }); + return () => { + cancelled = true; + }; + }, [query, category, setStatus]); + + return ( + +
+ +
+
+ +
+
+ ); +} + +function Pane({ title, subtitle, renderCount, children }: { title: string; subtitle: string; renderCount: number; children: React.ReactNode }) { + return ( +
+
+
+

{title}

+

{subtitle}

+
+
+ renders: {renderCount} +
+
+
{children}
+
+ ); +} + +function ProductList({ products }: { products: Product[] }) { + if (products.length === 0) { + return

No products match.

; + } + return ( +
    + {products.map((p) => ( +
  • +
    +
    {p.name}
    +
    {p.category}
    +
    +
    ${p.price}
    +
  • + ))} +
+ ); +} + +function SkeletonList() { + return ( +
    + {Array.from({ length: 5 }).map((_, i) => ( +
  • +
    +
    +
    +
    +
    +
  • + ))} +
+ ); +} diff --git a/docs/app/(home)/demo/real-world/_data.ts b/docs/app/(home)/demo/real-world/_data.ts new file mode 100644 index 0000000..9eb6f3f --- /dev/null +++ b/docs/app/(home)/demo/real-world/_data.ts @@ -0,0 +1,40 @@ +export type Category = 'electronics' | 'books' | 'clothing'; + +export type Product = { + id: number; + name: string; + category: Category; + price: number; +}; + +export const categories: { value: Category | 'all'; label: string }[] = [ + { value: 'all', label: 'All' }, + { value: 'electronics', label: 'Electronics' }, + { value: 'books', label: 'Books' }, + { value: 'clothing', label: 'Clothing' }, +]; + +export const products: Product[] = [ + { id: 1, name: 'Laptop Pro 14"', category: 'electronics', price: 1299 }, + { id: 2, name: 'Noise-cancelling Headphones', category: 'electronics', price: 299 }, + { id: 3, name: 'Wireless Mouse', category: 'electronics', price: 49 }, + { id: 4, name: '4K Monitor', category: 'electronics', price: 449 }, + { id: 5, name: 'Mechanical Keyboard', category: 'electronics', price: 129 }, + { id: 6, name: 'The Pragmatic Programmer', category: 'books', price: 32 }, + { id: 7, name: 'Designing Data-Intensive Apps', category: 'books', price: 45 }, + { id: 8, name: 'Refactoring', category: 'books', price: 38 }, + { id: 9, name: 'Clean Code', category: 'books', price: 29 }, + { id: 10, name: 'Merino Wool Sweater', category: 'clothing', price: 89 }, + { id: 11, name: 'Selvedge Denim Jeans', category: 'clothing', price: 145 }, + { id: 12, name: 'Leather Boots', category: 'clothing', price: 220 }, + { id: 13, name: 'Oxford Shirt', category: 'clothing', price: 68 }, + { id: 14, name: 'Wool Overcoat', category: 'clothing', price: 320 }, +]; + +export async function fetchWithDelay(query: string, category: Category | 'all'): Promise { + await new Promise((r) => setTimeout(r, 650)); + const q = query.trim().toLowerCase(); + return products.filter( + (p) => (category === 'all' || p.category === category) && (q === '' || p.name.toLowerCase().includes(q)) + ); +} diff --git a/docs/app/(home)/demo/real-world/page.tsx b/docs/app/(home)/demo/real-world/page.tsx new file mode 100644 index 0000000..2769379 --- /dev/null +++ b/docs/app/(home)/demo/real-world/page.tsx @@ -0,0 +1,61 @@ +import Link from 'next/link'; +import { ArrowLeft } from 'lucide-react'; +import { RealWorldDemo } from './_components'; + +export const metadata = { + title: 'Real-world demo · React Zero-UI', + description: 'Searchable list with skeleton loading — React useState vs the Zero-UI hybrid pattern.', +}; + +export default function RealWorldDemoPage() { + return ( +
+
+ + + Home + +

The hybrid pattern.

+

+ Use useState for what changes (the product data) and useUI{' '} + for how it looks (the loading skeleton). Both panes below fetch the same mock data with a 650 ms delay — only the React + version re-renders when the skeleton appears and disappears. +

+
+ + + +
+
+

The code that matters

+
+            {`const [data, setData] = useState([]);
+const [, setStatus] = useUI(
+  'search-status',
+  'idle',
+);
+
+useEffect(() => {
+  setStatus('loading');      // no re-render
+  fetchResults(query).then((r) => {
+    setData(r);              // 1 re-render
+    setStatus('success');    // no re-render
+  });
+}, [query]);`}
+          
+
+
+

When to reach for this

+
    +
  • — Presentation states (loading, expanded, focused) flip a data-attribute.
  • +
  • — Actual data (fetched items, form values) stays in React state.
  • +
  • — The expensive tree (the list) only re-renders when the data changes.
  • +
  • — The skeleton appears instantly via CSS, not via React reconciliation.
  • +
+
+
+
+ ); +} diff --git a/docs/app/(home)/page.tsx b/docs/app/(home)/page.tsx index d8f2450..0de4808 100644 --- a/docs/app/(home)/page.tsx +++ b/docs/app/(home)/page.tsx @@ -42,9 +42,9 @@ function Hero() { Read the Docs - Quick start + See it in action
diff --git a/docs/content/docs/faq.mdx b/docs/content/docs/faq.mdx index 456cdcf..1ee578e 100644 --- a/docs/content/docs/faq.mdx +++ b/docs/content/docs/faq.mdx @@ -79,6 +79,29 @@ Until a future plugin system for **Turbopack** emerges, we've chosen the simpler We may ship a resolver plugin for Turbopack once it's open to third-party hooks. +### When should I use Zero-UI vs useState? + +**Short answer:** `useUI` for how things look, `useState` for what things are. + +If the state only controls appearance (loading, open/closed, active tab, theme, focused), reach for `useUI` — it skips re-renders entirely. If the state _is_ the thing being rendered (fetched data, form values, counts), keep `useState`. + +Most real features are a mix of both. That's the **hybrid pattern**: + +```tsx +const [data, setData] = useState([]); // WHAT is shown +const [, setStatus] = useUI("search-status", "idle"); // HOW it looks + +useEffect(() => { + setStatus("loading"); // no re-render — skeleton appears via CSS + fetchResults(query).then((r) => { + setData(r); // one re-render — the list actually changed + setStatus("success"); // no re-render — skeleton hides via CSS + }); +}, [query]); +``` + +See this exact pattern running live with a side-by-side React-only comparison on the [real-world demo](/demo/real-world). + ### Can I use it with existing state management? Absolutely! Zero-UI is designed for **UI state only**. Use it alongside: diff --git a/docs/content/docs/usage-examples.mdx b/docs/content/docs/usage-examples.mdx index 4f7153b..fd002a9 100644 --- a/docs/content/docs/usage-examples.mdx +++ b/docs/content/docs/usage-examples.mdx @@ -5,6 +5,11 @@ description: Comprehensive examples and patterns for React Zero-UI Learn through practical, real-world use cases and best practices. + + See the patterns on this page wired into a live app: [the real-world demo](/demo/real-world) shows the hybrid pattern (useUI for + loading, useState for data) running side-by-side with a React-only version. + + ## Basic Usage Patterns ### 1. Theme toggle (global state) From afedd8afedf73202cd2e65f7f4e2389dbe805d69 Mon Sep 17 00:00:00 2001 From: Eric Chavez Date: Mon, 13 Apr 2026 20:57:11 -0700 Subject: [PATCH 05/15] docs: add perf comparison demo ported from examples/demo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scoped Phase 5: port the flagship tabbed Zero-UI vs React state comparison (examples/demo (test)/page.tsx) to /demo/perf on the docs site. State keys namespaced with perf-* prefix to avoid collision with other demos. Icon sprite dep replaced with lucide-react's Atom icon. Landing page Demo section now links to both /demo/perf and /demo/real-world. examples/demo left intact — deeper perf subpages (react/ssr/zero-ui) and the sprite demo are out of scope for this cut. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/app/(home)/demo/perf/_comparison.tsx | 39 +++++++ docs/app/(home)/demo/perf/_react-state.tsx | 116 +++++++++++++++++++ docs/app/(home)/demo/perf/_zero-state.tsx | 126 +++++++++++++++++++++ docs/app/(home)/demo/perf/page.tsx | 40 +++++++ docs/app/(home)/page.tsx | 21 ++++ 5 files changed, 342 insertions(+) create mode 100644 docs/app/(home)/demo/perf/_comparison.tsx create mode 100644 docs/app/(home)/demo/perf/_react-state.tsx create mode 100644 docs/app/(home)/demo/perf/_zero-state.tsx create mode 100644 docs/app/(home)/demo/perf/page.tsx diff --git a/docs/app/(home)/demo/perf/_comparison.tsx b/docs/app/(home)/demo/perf/_comparison.tsx new file mode 100644 index 0000000..b686be1 --- /dev/null +++ b/docs/app/(home)/demo/perf/_comparison.tsx @@ -0,0 +1,39 @@ +'use client'; + +import { Atom, Zap } from 'lucide-react'; +import { useUI } from '@react-zero-ui/core'; +import { ReactState } from './_react-state'; +import { ZeroState } from './_zero-state'; + +export function Comparison() { + const [, setActive] = useUI<'zero' | 'react'>('perf-active', 'zero'); + + return ( +
+
+
+ + +
+ +
+
+ + +
+
+
+ ); +} diff --git a/docs/app/(home)/demo/perf/_react-state.tsx b/docs/app/(home)/demo/perf/_react-state.tsx new file mode 100644 index 0000000..9675324 --- /dev/null +++ b/docs/app/(home)/demo/perf/_react-state.tsx @@ -0,0 +1,116 @@ +'use client'; + +import { useState } from 'react'; + +type Theme = 'light' | 'dark'; +type Accent = 'violet' | 'emerald' | 'amber'; + +export function ReactState() { + const [accent, setAccent] = useState('violet'); + const [theme, setTheme] = useState('light'); + const [menuOpen, setMenuOpen] = useState(false); + + return ( +
+
+ + + + +
+ ); +} + +function Header({ theme }: { theme: Theme }) { + return ( +
+

+ React State Management +

+

+ Reactive state management with React
+ Re-renders O(n) +

+
+ ); +} + +function ThemeSwitcher({ theme, setTheme }: { theme: Theme; setTheme: (t: Theme) => void }) { + return ( +
+ + +
+ ); +} + +function AccentPicker({ accent, setAccent, theme }: { accent: Accent; setAccent: (a: Accent) => void; theme: Theme }) { + return ( +
+

Choose Accent

+
+
+
+ ); +} + +function InteractiveCard({ theme, menuOpen, setMenuOpen, accent }: { theme: Theme; menuOpen: boolean; setMenuOpen: (o: boolean) => void; accent: Accent }) { + return ( +
+
+

Open Menu Demo

+ +
+
+
+

✨ This panel slides open and has to re-render!

+
+
+
+ ); +} + +function StateDisplay({ theme, accent, menuOpen }: { theme: Theme; accent: Accent; menuOpen: boolean }) { + return ( +
+
+
theme: {theme}
+
accent: {accent}
+
menu: {menuOpen ? 'Open' : 'Closed'}
+
+
+ ); +} diff --git a/docs/app/(home)/demo/perf/_zero-state.tsx b/docs/app/(home)/demo/perf/_zero-state.tsx new file mode 100644 index 0000000..e048a83 --- /dev/null +++ b/docs/app/(home)/demo/perf/_zero-state.tsx @@ -0,0 +1,126 @@ +'use client'; + +import { useUI } from '@react-zero-ui/core'; + +export function ZeroState() { + const [, setTheme] = useUI<'light' | 'dark'>('perf-theme', 'light'); + const [, setAccent] = useUI<'violet' | 'emerald' | 'amber'>('perf-accent', 'violet'); + const [, setMenuOpen] = useUI<'true' | 'false'>('perf-menu-open', 'false'); + + return ( +
+
+ + + setMenuOpen((prev) => (prev === 'true' ? 'false' : 'true'))} /> + +
+ ); +} + +function Header() { + return ( +
+

Zero UI

+

+ Reactive state without re-rendering. +
+ + Zero re-renders,{' '} + Reactive &{' '} + Global state. + +

+
+ ); +} + +function ThemeSwitcher({ setTheme }: { setTheme: (t: 'light' | 'dark') => void }) { + return ( +
+ + +
+ ); +} + +function AccentPicker({ setAccent }: { setAccent: (a: 'violet' | 'emerald' | 'amber') => void }) { + return ( +
+

Choose Accent

+
+
+
+ ); +} + +function InteractiveCard({ toggleMenu }: { toggleMenu: () => void }) { + return ( +
+
+

Open Menu Demo

+ +
+
+
+

✨ This panel slides open without re-rendering!

+
+
+
+ ); +} + +function StateDisplay() { + return ( +
+
+
+ theme: Light + Dark +
+
+ accent: + Violet + Emerald + Amber +
+
+ menu: + Open + Closed +
+
+
+ ); +} diff --git a/docs/app/(home)/demo/perf/page.tsx b/docs/app/(home)/demo/perf/page.tsx new file mode 100644 index 0000000..7e1dad4 --- /dev/null +++ b/docs/app/(home)/demo/perf/page.tsx @@ -0,0 +1,40 @@ +import Link from 'next/link'; +import { ArrowLeft } from 'lucide-react'; +import { Comparison } from './_comparison'; + +export const metadata = { + title: 'Zero-UI vs React state · React Zero-UI', + description: 'Side-by-side comparison: same UI built with React useState and with Zero-UI useUI. Flip between them and watch the re-render cost.', +}; + +export default function PerfDemoPage() { + return ( +
+
+ + + Home + +

Zero-UI vs React state.

+

+ Same UI, built twice. The Zero-UI version flips data-* attributes on{' '} + <body> and lets Tailwind variants do the work. The React version holds the + same state in useState and re-renders the component tree on every click. Open React + DevTools (or install the{' '} + + React Scan + {' '} + browser extension) to visualize the difference. +

+
+ + +
+ ); +} diff --git a/docs/app/(home)/page.tsx b/docs/app/(home)/page.tsx index 0de4808..654bcb9 100644 --- a/docs/app/(home)/page.tsx +++ b/docs/app/(home)/page.tsx @@ -129,6 +129,27 @@ function Demo() {

+ +
+ +
+
Zero-UI vs React state
+
Side-by-side tabbed comparison with the same UI built twice.
+
+ + + +
+
The hybrid pattern
+
Search + skeleton loading, useState for data, useUI for presentation.
+
+ + +
); } From d33e3f9e05bd136914c5f437f7f1b0a08d292ac2 Mon Sep 17 00:00:00 2001 From: Eric Chavez Date: Mon, 13 Apr 2026 21:05:12 -0700 Subject: [PATCH 06/15] chore: dissolve docs-legacy/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 2 migrated 7 public docs into docs/content/docs/*.mdx with Fumadocs. Those legacy sources can now go. Remaining maintainer-facing files relocated out of docs-legacy: - CONTRIBUTING.md → repo root (with Monorepo Structure updated to mention docs/ and examples/demo/, and a Bundle Size section merged in from the old size.md) - internal.md → packages/core/ARCHITECTURE.md (colocated with the variant extractor / PostCSS pipeline it describes) - assets/ → docs/public/assets/ (usable by the docs site going forward) docs-legacy/ is now empty and removed. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../CONTRIBUTING.md => CONTRIBUTING.md | 24 + docs-legacy/api-reference.md | 421 ---------------- docs-legacy/experimental.md | 197 -------- docs-legacy/faq.md | 374 -------------- docs-legacy/installation-next.md | 76 --- docs-legacy/installation-vite.md | 45 -- docs-legacy/migration-guide.md | 443 ---------------- docs-legacy/size.md | 29 -- docs-legacy/usage-examples.md | 477 ------------------ .../public}/assets/useui-explained.webp | Bin .../public}/assets/zero-ui-logo.png | Bin .../core/ARCHITECTURE.md | 0 12 files changed, 24 insertions(+), 2062 deletions(-) rename docs-legacy/CONTRIBUTING.md => CONTRIBUTING.md (73%) delete mode 100644 docs-legacy/api-reference.md delete mode 100644 docs-legacy/experimental.md delete mode 100644 docs-legacy/faq.md delete mode 100644 docs-legacy/installation-next.md delete mode 100644 docs-legacy/installation-vite.md delete mode 100644 docs-legacy/migration-guide.md delete mode 100644 docs-legacy/size.md delete mode 100644 docs-legacy/usage-examples.md rename {docs-legacy => docs/public}/assets/useui-explained.webp (100%) rename {docs-legacy => docs/public}/assets/zero-ui-logo.png (100%) rename docs-legacy/internal.md => packages/core/ARCHITECTURE.md (100%) diff --git a/docs-legacy/CONTRIBUTING.md b/CONTRIBUTING.md similarity index 73% rename from docs-legacy/CONTRIBUTING.md rename to CONTRIBUTING.md index b3f2638..f7fc3f6 100644 --- a/docs-legacy/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,8 +25,12 @@ Stay **pre-rendered, declarative, and brutally fast.** packages/ ├── core -> @react-zero-ui/core (library logic + postcss) └── cli -> create-zero-ui (npx installer) + docs/ -> Next.js + Fumadocs docs site (apps/docs replacement) + examples/demo/ -> Live performance + sprite showcase app ``` +For the variant extractor / PostCSS pipeline internals (AST parsing, literal resolution, token scanning), see [packages/core/ARCHITECTURE.md](packages/core/ARCHITECTURE.md). + --- ## Local Setup @@ -85,6 +89,26 @@ pnpm test # Runs all of the above --- +## Bundle Size + +This repo measures bundle size from the built `@react-zero-ui/core` entry. + +```bash +pnpm build +pnpm size # prints the gzipped byte count +pnpm size:badge # refreshes the README badge JSON +``` + +The `size` script runs: + +```bash +npx esbuild ./packages/core/dist/index.js --bundle --minify --format=esm --external:react --define:process.env.NODE_ENV='"production"' | gzip -c | wc -c +``` + +`size:badge` writes [`.github/badges/core-size.json`](.github/badges/core-size.json), which the README badge reads through a Shields endpoint. Run it after a build when you want to refresh the number. + +--- + ## Code of Conduct Keep it respectful and accessible. Push ideas hard, not people. diff --git a/docs-legacy/api-reference.md b/docs-legacy/api-reference.md deleted file mode 100644 index cf0c6a1..0000000 --- a/docs-legacy/api-reference.md +++ /dev/null @@ -1,421 +0,0 @@ -
- -# API Reference - -**Complete API documentation for React Zero-UI** - -Detailed reference for all hooks, utilities, and configuration options. - -
- ---- - -## Table of Contents - -- [Core Hooks](#core-hooks) -- [Utilities](#utilities) -- [Experimental APIs](#experimental-apis) -- [TypeScript Types](#typescript-types) -- [Limitations & Constraints](#limitations--constraints) -- [Generated Files](#generated-files) -- [Debugging](#debugging) - ---- - -## Core Hooks - -### `useUI(key, initial, flag?)` - -Global UI state hook that updates `data-*` attributes on ``. - -```tsx -const [staleValue, setter] = useUI(key, initial, flag?); -``` - -#### Parameters - -| Parameter | Type | Description | -| --------- | --------------- | ------------------------------------------------------ | -| `key` | `string` | The state key (becomes `data-{key}` attribute) | -| `initial` | `T` | Initial/default value for SSR | -| `flag?` | `typeof CssVar` | Optional: Use CSS variables instead of data attributes | - -#### Returns - -| Return | Type | Description | -| ------------ | ------------------- | ------------------------------------------------ | -| `staleValue` | `T` | Initial value (doesn't update, use for SSR only) | -| `setter` | `GlobalSetterFn` | Function to update the global state | - -#### Examples - -```tsx -// Basic usage -const [theme, setTheme] = useUI("theme", "light"); -setTheme("dark"); // Sets data-theme="dark" on - -// With TypeScript generics -const [status, setStatus] = useUI<"loading" | "success" | "error">("status", "loading"); - -// With CSS variables -const [color, setColor] = useUI("primary", "#blue", CssVar); -setColor("#red"); // Sets --primary: #red on - -// Functional updates -setTheme((prev) => (prev === "light" ? "dark" : "light")); -``` - ---- - -### `useScopedUI(key, initial, flag?)` - -Scoped UI state hook that updates `data-*` attributes on a specific element. - -```tsx -const [staleValue, setter] = useScopedUI(key, initial, flag?); -``` - -#### Parameters - -Same as `useUI`, but affects only the element assigned to `setter.ref`. - -#### Returns - -| Return | Type | Description | -| ------------ | ------------------- | ------------------------------------------------ | -| `staleValue` | `T` | Initial value (doesn't update, use for SSR only) | -| `setter` | `ScopedSetterFn` | Function with attached `ref` property | - -#### Examples - -```tsx -// Basic scoped usage -const [modal, setModal] = useScopedUI("modal", "closed"); - -
- Modal content -
; - -// With CSS variables -const [blur, setBlur] = useScopedUI("blur", "0px", CssVar); - -
- Blurred content -
; -``` - ---- - -## Utilities - -### `CssVar` - -Flag to enable CSS variable mode instead of data attributes. - -```tsx -import { CssVar } from "@react-zero-ui/core"; - -// Global CSS variable -const [color, setColor] = useUI("primary", "#blue", CssVar); -// Result: - -// Scoped CSS variable -const [size, setSize] = useScopedUI("font-size", "16px", CssVar); -// Result:
-``` - ---- - -## Experimental APIs - -### `zeroSSR.onClick(key, values)` - -Creates click handlers for server components (experimental). - -```tsx -import { zeroSSR } from "@react-zero-ui/core/experimental"; - -const clickHandler = zeroSSR.onClick(key, values); -``` - -#### Parameters - -| Parameter | Type | Description | -| --------- | ---------- | -------------------------------- | -| `key` | `string` | State key (kebab-case required) | -| `values` | `string[]` | Array of values to cycle through | - -#### Returns - -Object with `data-ui` attribute for JSX spread. - -#### Examples - -```tsx -// Global state toggle - - -// Multi-value cycling - -``` - ---- - -### `scopedZeroSSR.onClick(key, values)` - -Creates scoped click handlers for server components. - -```tsx -import { scopedZeroSSR } from "@react-zero-ui/core/experimental"; - -const clickHandler = scopedZeroSSR.onClick(key, values); -``` - -#### Usage - -Same as `zeroSSR.onClick`, but affects the closest ancestor with `data-{key}` attribute. - -```tsx -
- - -
Modal content
-
-``` - ---- - -### `activateZeroUiRuntime(variantMap)` - -Activates the SSR runtime for click handling (experimental). - -```tsx -import { activateZeroUiRuntime } from "@react-zero-ui/core/experimental/runtime"; -import { variantKeyMap } from "./.zero-ui/attributes"; - -activateZeroUiRuntime(variantKeyMap); -``` - -#### Parameters - -| Parameter | Type | Description | -| ------------ | -------------------------- | -------------------------------------------- | -| `variantMap` | `Record` | Generated variant mapping from build process | - -#### Setup - -```tsx -// src/components/InitZeroUI.tsx -"use client"; - -import { variantKeyMap } from "../.zero-ui/attributes"; -import { activateZeroUiRuntime } from "@react-zero-ui/core/experimental/runtime"; - -activateZeroUiRuntime(variantKeyMap); - -export const InitZeroUI = () => null; -``` - -```tsx -// app/layout.tsx -import { InitZeroUI } from "../components/InitZeroUI"; - -export default function RootLayout({ children }) { - return ( - - - - {children} - - - ); -} -``` - ---- - -## TypeScript Types - -### `UIAction` - -Union type for state update actions. - -```tsx -type UIAction = T | ((prev: T) => T); -``` - -### `GlobalSetterFn` - -Function type for global state setters. - -```tsx -type GlobalSetterFn = (action: UIAction) => void; -``` - -### `ScopedSetterFn` - -Function type for scoped state setters with attached ref. - -```tsx -interface ScopedSetterFn { - (action: UIAction): void; - ref?: RefObject | ((node: HTMLElement | null) => void); - cssVar?: typeof cssVar; -} -``` - ---- - -## Limitations & Constraints - -### State Key Requirements - -- DO NOT USE IMPORTED VARIABLES IN THE STATE KEY -- Must be valid HTML attribute names -- Kebab-case required: `'sidebar-state'` not `'sidebarState'` -- Avoid conflicts with existing data attributes -- Must resolve to a non-spaced string: `'sidebar-state'` not `'sidebar State'` -- Must be a local constant that resolves to a string: - -### Scoped UI Constraints - -- Each `useScopedUI` hook supports only one ref attachment -- Multiple refs will throw development-time errors -- Use separate hooks or components for multiple scoped elements - -### CSS Variable Naming - -- Automatically prefixed with `--` -- Must be valid CSS custom property names -- Example: `'primary-color'` becomes `'--primary-color'` - -### SSR Considerations - -- Initial values must be deterministic for SSR -- Avoid dynamic initial values that differ between server/client -- Use `useEffect` for client-only state initialization - ---- - -## Generated Files - -### `.zero-ui/attributes.ts` - -Generated variant mapping for runtime activation. - -```ts -/* AUTO-GENERATED - DO NOT EDIT */ -export const bodyAttributes = { - "data-theme": "light", - "data-accent": "violet", - "data-scrolled": "up", - // ... -}; -``` - -### `.zero-ui/styles.css` (Vite) - -Generated CSS variants for Vite projects. - -```css -/* Auto-generated Tailwind variants */ -[data-theme="dark"] .theme-dark\:bg-gray-900 { - background-color: rgb(17 24 39); -} -/* ... */ -``` - ---- - -## Debugging - -### Enable Debug Mode - -```js -// postcss.config.js -module.exports = { - plugins: { - "@react-zero-ui/core/postcss": { - debug: true, // Enables verbose logging - }, - tailwindcss: {}, - }, -}; -``` - -### Check Generated Output - -```bash -# View generated variants -ls -la .zero-ui/ -cat .zero-ui/attributes.ts -``` - -### Browser DevTools - -1. **Elements tab:** Check for `data-*` attributes on target elements -2. **Computed styles:** Verify CSS rules are applying correctly -3. **Console:** Look for Zero-UI runtime messages (in debug mode) - ---- - -## Best Practices - -### State Key Naming - -```tsx -// Good: Descriptive and clear -useUI("theme", "light"); -useUI("sidebar-state", "collapsed"); -useUI("modal-visibility", "hidden"); - -// Avoid: Generic or unclear -useUI("state", "on"); -useUI("x", "y"); -useUI("toggle", "true"); -``` - -### TypeScript Usage - -```tsx -// Use specific union types -type Theme = "light" | "dark" | "auto"; -const [, setTheme] = useUI("theme", "light"); - -// For complex states, define types -type ModalState = "closed" | "opening" | "open" | "closing"; -const [, setModal] = useUI("modal", "closed"); -``` - -### Performance Optimization - -```tsx -// Use CSS for conditional rendering -
Modal content
; - -// Avoid reading stale values for logic -const [modal, setModal] = useUI("modal", "closed"); -{ - modal === "open" && ; -} // Won't work as expected -``` - ---- - -
- -### Need More Help? - -[**Usage Examples**](./usage-examples.md) | [**Troubleshooting**](./troubleshooting.md) | [**Migration Guide**](./migration-guide.md) - -
diff --git a/docs-legacy/experimental.md b/docs-legacy/experimental.md deleted file mode 100644 index e720537..0000000 --- a/docs-legacy/experimental.md +++ /dev/null @@ -1,197 +0,0 @@ -
-

Experimental Runtime (Zero-UI)

- -**SSR-safe runtime logic** for handling interactivity in React server components without using - -```diff -- use client -``` - -
-
-Designed to be tiny(~300 bytes), deterministic, and fully compatible with - -React Zero-UI's pre-rendered data-attribute model. - -
- ---- - -### Why This Approach? - -**The Problem:** A single `onClick` event forces your entire component tree to become client-rendered. In Next.js, this means shipping extra JavaScript, losing SSR benefits, and adding hydration overhead, all for basic interactivity. - -**The Solution:** This design creates the perfect bridge between **static HTML** and **interactive UX**, while maintaining: - -- Server-rendered performance -- Zero JavaScript bundle overhead -- Instant visual feedback - -_Why sacrifice server-side rendering for a simple click handler when 300 bytes of runtime can handle all the clicks in your app?_ - ---- - -## Core Functionality - -### `activateZeroUiRuntime()` - -The core runtime entrypoint that enables client-side interactivity in server components: - -**How it works:** - -1. **Single Global Listener** - Registers one click event listener on `document` -2. **Smart Detection** - Listens for clicks on elements with `data-ui` attributes -3. **Directive Parsing** - Interprets `data-ui` directives in this format. - -```diff -+ data-ui="global:key(val1,val2,...)" -> flips data-key on document.body -+ data-ui="scoped:key(val1,val2,...)" -> flips data-key on closest ancestor/self -``` - -4. **Round-Robin Cycling** - Cycles through values in sequence -5. **Instant DOM Updates** - Updates DOM immediately for Tailwind responsiveness - -> **Note:** Guards against duplicate initialization using `window.__zero` flag. - ---- - -## Helper Functions - -### `zeroSSR.onClick()` & `scopedZeroSSR.onClick()` - -Utility functions that generate valid `data-ui` attributes for JSX/TSX: - -**Global Example:** - -```tsx -zeroSSR.onClick("theme", ["dark", "light"]); -// Returns: { 'data-ui': 'global:theme(dark,light)' } -``` - -**Scoped Example:** - -```tsx -scopedZeroSSR.onClick("modal", ["open", "closed"]); -// Returns: { 'data-ui': 'scoped:modal(open,closed)' } -``` - -**Development Validation:** - -- Ensures keys are kebab-case -- Validates at least one value is provided - ---- - -## Installation & Setup - -### Step 1: Install Package - -```bash -npm install @react-zero-ui/core@0.3.1-beta.2 -``` - -### Step 2: Generate Variants - -Run your development server to generate the required variant map: - -```bash -npm run dev -``` - -This creates `.zero-ui/attributes.ts` containing the variant map needed for runtime activation. - -### Step 3: Create `` Component - -```tsx -"use client"; - -import { variantKeyMap } from "path/to/.zero-ui/attributes"; -import { activateZeroUiRuntime } from "@react-zero-ui/core/experimental/runtime"; - -activateZeroUiRuntime(variantKeyMap); - -export const InitZeroUI = () => null; -``` - -### Step 4: Add to Root Layout - -```tsx -import { InitZeroUI } from "path/to/InitZeroUI"; - -export default function RootLayout({ children }) { - return ( - - - - {children} - - - ); -} -``` - ---- - -## Usage Examples - -### Global Theme Toggle - -```tsx -import { zeroSSR } from "@react-zero-ui/core/experimental"; - -
Click me to cycle themes!
; -``` - -**Pair with Tailwind variants:** - -```html -
Interactive Server Component!
-``` - -### Scoped Modal Toggle - -```tsx -import { scopedZeroSSR } from "@react-zero-ui/core/experimental"; - -// Scopes based on matching data-* attribute (e.g. data-modal) -
- -
; -``` - ---- - -## Design Philosophy - -### Core Principles - -- **No React State** - Zero re-renders involved -- **Pure DOM Mutations** - Works entirely via `data-*` attribute changes -- **Server Component Compatible** - Full compatibility with all server components -- **Tailwind-First** - Designed for conditional CSS classes - ---- - -## Summary - -| Feature | Description | -| ------------------------------- | --------------------------------------------------------- | -| **`activateZeroUiRuntime()`** | Enables click handling on static components via `data-ui` | -| **`zeroSSR` / `scopedZeroSSR`** | Generate valid click handlers as JSX props | -| **Runtime Overhead** | ~300 bytes total | -| **React Re-renders** | Zero | -| **Server Component Support** | Full compatibility | - -> **Source Code:** See [experimental](/packages/core/src/experimental) for implementation details. - ---- - -
- -**The bridge between static HTML and interactive UX** - -_No state. No runtime overhead. Works in server components. ZERO re-renders._ - -[**Get Started in less than 5 minutes**](/#quick-start) - -
diff --git a/docs-legacy/faq.md b/docs-legacy/faq.md deleted file mode 100644 index a87c703..0000000 --- a/docs-legacy/faq.md +++ /dev/null @@ -1,374 +0,0 @@ -
- -# Frequently Asked Questions - -**Common questions and answers about React Zero-UI** - -Everything you need to know to get the most out of Zero-UI. - -
- ---- - -## General Questions - -### What exactly is React Zero-UI? - -React Zero-UI is a state management library that eliminates React re-renders for UI state by using CSS and data attributes instead of component state. It "pre-renders" all possible UI states at **build time** and switches between them by flipping data attributes. - -### How is this different from regular React state? - -**Traditional React:** - -```tsx -const [theme, setTheme] = useState("light"); -// Every setState() triggers re-render of component tree -``` - -**React Zero-UI:** - -```tsx -const [, setTheme] = useUI("theme", "light"); -// No re-renders, just flips data-theme="dark" on -``` - -### Do I need to learn anything new? - -Not really! If you know React hooks and Tailwind CSS, you already know 95% of what you need: - -1. Replace `useState` with `useUI` -2. Replace conditional classes with Tailwind variants -3. Everything else works the same - ---- - -## Performance Questions - -### How much faster is it really? - -**Benchmarks** (10,000 DOM nodes): - -- React state changes: ~50ms -- Zero-UI state changes: ~5ms -- **Result: 10× faster updates** - -The more complex your UI, the bigger the performance gain. - -### Does it increase my bundle size? - -**Zero-UI core: ~350 bytes** in production (10x smaller than a single svg icon) - -Compare that to: - -- Redux: ~5KB -- SVG Icon: ~4KB - So about 10x smaller than a single SVG icon - -### What about CSS file size? - -CSS variants are only generated for the states you actually use. If you use 3 theme values, you get CSS for 3 variants—not hundreds. - ---- - -Here’s a tighter, sharper version with your key points, a nod to Prepack’s failure, and a forward-looking note about Turbopack: - ---- - -## Technical Questions - -### Why can't I use imported variables in the state key? - -Zero-UI uses a custom Babel-based resolver that only analyzes **top-level `const` values in the same file**. Imported variables are **not supported**, even if re-assigned to a local `const`. - -Why? Because resolving cross-file imports requires a **full module graph**, accounting for: - -- ESM vs CJS interop -- TypeScript vs JavaScript -- Re-exports, namespace imports, aliased paths, dynamic values -- Recursive constant folding across files - -This problem is **deceptively deep** — even Facebook's [Prepack](https://prepack.io/) abandoned the attempt after years of effort. - -Until a future plugin system for **Turbopack** emerges, we've chosen the simpler, safer route: -**Only local `const` string literals are supported.** - -We may ship a resolver plugin for Turbopack once it's open to third-party hooks. - ---- - -Want it even shorter or more opinionated? - -### Can I use it with existing state management? - -Absolutely! Zero-UI is designed for **UI state only**. Use it alongside: - -- Redux/Zustand for business logic -- React Query for server state -- Regular `useState` for component-specific data - -```tsx -// Great combination -const [data, setData] = useState(null); // Component state -const { user } = useQuery("user"); // Server state -const [, setTheme] = useUI("theme", "light"); // UI state -``` - -### Does it work with SSR/Next.js? - -Yes! Zero-UI is designed with SSR in mind: - -- No hydration mismatches -- Perfect FOUC prevention -- Works with Next.js App Router -- Experimental server component support see [experimental](./experimental.md) - -### Can I persist state across page reloads? - -Zero-UI state is DOM-based, so it doesn't persist automatically. For persistence you handle it the same as you would with regular React state: - -```tsx -// Save to localStorage -const [, setTheme] = useUI("theme", "light"); - -const persistentSetTheme = (value) => { - setTheme(value); - localStorage.setItem("theme", value); -}; - -// Load on mount -useEffect(() => { - const saved = localStorage.getItem("theme"); - if (saved) setTheme(saved); -}, []); -``` - ---- - -## Styling Questions - -### Do I have to use Tailwind? - -**For the best experience, yes.** Zero-UI generates Tailwind variants automatically. - -and tailwind variants are generated by tailwindCSS. - -```css -[data-theme="dark"] { - background: black; -} -``` - -### Can I use CSS variables? - -Yes! Pass the `CssVar` flag: - -```tsx -import { useUI, CssVar } from "@react-zero-ui/core"; - -const [, setColor] = useUI("primary", "#blue", CssVar); -// Result: -``` - ---- - -## Migration Questions - -### How hard is it to migrate from useState? - -**Very easy** for UI state: - -```tsx -// Before -const [theme, setTheme] = useState("light"); - -// After -const [, setTheme] = useUI("theme", "light"); -// Note: Don't use the first return value for logic -``` - -### What about Context API? - -If context is used for UI state, it's even easier! Just remove the provider: - -```tsx -// Before: Need provider, useContext, prop drilling - - -; - -// After: State works everywhere automatically -function App() { - const [, setTheme] = useUI("theme", "light"); - // Theme accessible anywhere via CSS classes -} -``` - -### Should I migrate everything at once? - -**No!** Migrate incrementally: - -1. Start with global UI state (theme, modals) -2. Move component-specific UI state -3. Leave business logic in existing solutions - ---- - -## Experimental Features - -### What's the experimental SSR runtime? - -It allows interactivity in **server components** without `'use client'` see [experimental](./experimental.md): - -```tsx -// This is a SERVER COMPONENT! -import { zeroSSR } from "@react-zero-ui/core/experimental"; - -function ServerThemeToggle() { - return ; -} -``` - -Only ~300 bytes of runtime for unlimited server component interactivity. - -### Is the experimental API stable? - -It's **experimental** but used in production by early adopters. The API may change in minor versions, but we'll provide migration guides. - -### Should I use it in production? - -I would not recommend using it in production until the API is stable. Because the API is still in development and the API may change in minor versions, but we'll provide migration guides. - ---- - -## Troubleshooting - -### My Tailwind variants aren't working - -**Check these in order:** - -1. **PostCSS plugin configured? (Next.js)** - - ```js - // postcss.config.js - module.exports = { - plugins: { - "@react-zero-ui/core/postcss": {}, // Before Tailwind! - tailwindcss: {}, - }, - }; - ``` - -2. **Tailwind V4 Configured and imported?** - ```css - @import "tailwindcss"; - ``` - -### I get "Multiple ref attachments" error - -Each `useScopedUI` can only attach to one element: - -```tsx -// Wrong -const [, setState] = useScopedUI('state', 'default'); -
-
// Error! - -// Right -const [, setState1] = useScopedUI('state-1', 'default'); -const [, setState2] = useScopedUI('state-2', 'default'); -
-
-``` - ---- - -## Best Practices - -### When should I use Zero-UI? - -**Perfect for:** - -- Theme switching -- Modal/drawer states -- Navigation states -- UI toggles and animations -- Any visual state that doesn't affect business logic - -**Not ideal for:** - -- Form data -- API responses -- Complex business logic -- State that needs to trigger side effects - -### Should I use global or scoped state? - -**Global (`useUI`)** for: - -- App-wide state (theme, language) -- State that affects multiple components -- State you want accessible everywhere - -**Scoped (`useScopedUI`)** for: - -- Component-specific state -- State that doesn't affect other components -- Better performance for isolated changes - ---- - -## Future & Roadmap - -### What's coming next? - -- Enhanced TypeScript support -- More framework integrations (Vue, Svelte) -- Better DevTools integration -- Performance monitoring tools - -### How can I influence the roadmap? - -- Vote on feature requests in GitHub Discussions -- Report bugs and use cases -- Share your usage patterns -- Contribute code or documentation - ---- - -## Getting Help - -### Where can I ask questions? - -1. **Documentation:** Check the guides first -2. **Discussions:** [GitHub Discussions](https://github.com/react-zero-ui/core/discussions) for questions -3. **Issues:** [GitHub Issues](https://github.com/react-zero-ui/core/issues) for bugs - -### How do I report a bug? - -1. Check existing issues first -2. Create a minimal reproduction -3. Include your configuration (postcss.config.js, etc.) -4. Include browser and framework versions - -### Can I contribute? - -**Absolutely!** We welcome: - -- Documentation improvements -- Bug fixes -- Feature implementations -- Examples and demos - -See our [Contributing Guide](./CONTRIBUTING.md) to get started. - ---- - -
- -### Still have questions? - -[**Ask in Discussions**](https://github.com/react-zero-ui/core/discussions) | [**Read the Docs**](../README.md) | [**Try the Demo**](https://zero-ui.dev) - -The community is here to help! - -
diff --git a/docs-legacy/installation-next.md b/docs-legacy/installation-next.md deleted file mode 100644 index 197a9b2..0000000 --- a/docs-legacy/installation-next.md +++ /dev/null @@ -1,76 +0,0 @@ -### Next.js (App Router) Setup - -1. **Install the dependencies** - -```bash -npm install @react-zero-ui/core -``` - -```bash -npm install @tailwindcss/postcss -``` - ---- - -2. **Add the PostCSS plugin (must come _before_ Tailwind).** - -```js -// postcss.config.* ESM Syntax -const config = { - // Zero-UI must come before Tailwind - plugins: ["@react-zero-ui/core/postcss", "@tailwindcss/postcss"], -}; -export default config; -``` - -```js -// postcss.config.* Common Module Syntax -module.exports = { - // Zero-UI must come before Tailwind - plugins: { "@react-zero-ui/core/postcss": {}, tailwindcss: {} }, -}; -``` - -3. **Import Tailwind CSS** - -```css -// global.css -@import "tailwindcss"; -``` - ---- - -4. **Start the App** - -```bash -npm run dev -``` - -> Zero-UI will generate a .zero-ui folder in your project root. and generate the attributes.ts and type definitions for it. - ---- - -5. **Preventing FOUC (Flash Of Unstyled Content)** - -Spread `bodyAttributes` on `` in your root layout. - -```tsx -// app/layout.tsx -import { bodyAttributes } from "./.zero-ui/attributes"; - -export default function RootLayout({ children }) { - return ( - - // Spread the bodyAttributes on the body tag - {children} - - ); -} -``` - -**Thats it.** -Zero-UI will now add used data-\* attributes to the body tag and the CSS will be injected and transformed by tailwind. - -**Checkout our Experimental SSR Safe OnClick Handler** - -[**Zero UI OnClick**](/docs/experimental.md) diff --git a/docs-legacy/installation-vite.md b/docs-legacy/installation-vite.md deleted file mode 100644 index dffedf6..0000000 --- a/docs-legacy/installation-vite.md +++ /dev/null @@ -1,45 +0,0 @@ -### Vite Setup - -1. **Install the dependencies** - -```bash -npm install @react-zero-ui/core -``` - -```bash -npm install @tailwindcss/postcss -``` - ---- - -## Setup - -### Vite - -2. **Add the plugin to your vite.config.ts** - -```js -// vite.config.* -import zeroUI from "@react-zero-ui/core/vite"; -import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; -import tailwindCss from "@tailwindcss/postcss"; - -export default defineConfig({ - // Remove the default `tailwindcss()` plugin - and pass it into the `zeroUI` plugin - plugins: [zeroUI({ tailwind: tailwindCss }), react()], -}); -``` - -3. **Import Tailwind CSS** - -```css -// global.css -@import "tailwindcss"; -``` - -**Thats it.** - -The plugin will add the data-\* attributes to the body tag (no FOUC) and the CSS will be injected and transformed by tailwind. - - diff --git a/docs-legacy/migration-guide.md b/docs-legacy/migration-guide.md deleted file mode 100644 index 5003459..0000000 --- a/docs-legacy/migration-guide.md +++ /dev/null @@ -1,443 +0,0 @@ -# Migration Guide - -
- -**Migrate to React Zero-UI from existing state management solutions** - -Step-by-step guides for common migration scenarios. - -
- ---- - -## From React useState - -### Basic State Migration - -**Before (React useState):** - -```tsx -import { useState } from "react"; - -function ThemeToggle() { - const [theme, setTheme] = useState("light"); - - return ( -
- -
- ); -} -``` - -**After (React Zero-UI):** - -```tsx -import { useUI } from "@react-zero-ui/core"; - -function ThemeToggle() { - const [, setTheme] = useUI("theme", "light"); - - return ( -
- -
- ); -} -``` - -**Key Changes:** - -1. Replace `useState` with `useUI` -2. Replace conditional classNames with Tailwind variants -3. State key becomes a data attribute (`data-theme`) -4. Use functional updates for state transitions - -### Modal State Migration - -**Before:** - -```tsx -function App() { - const [isModalOpen, setIsModalOpen] = useState(false); - - return ( - <> - - - {isModalOpen && ( -
-
- -
-
- )} - - ); -} -``` - -**After:** - -```tsx -function App() { - const [, setModal] = useUI("modal", "closed"); - - return ( - <> - - -
-
- -
-
- - ); -} -``` - ---- - -## From Context API - -### Global Theme Context - -**Before (Context API):** - -```tsx -const ThemeContext = createContext(); - -function ThemeProvider({ children }) { - const [theme, setTheme] = useState("light"); - - return ( - -
{children}
-
- ); -} - -function ThemeToggle() { - const { theme, setTheme } = useContext(ThemeContext); - - return ; -} -``` - -**After (React Zero-UI):** - -```tsx -// No provider needed! - -function App({ children }) { - return
{children}
; -} - -function ThemeToggle() { - const [, setTheme] = useUI("theme", "light"); - - return ( - - ); -} -``` - -**Benefits:** - -- No more context providers -- No more prop drilling -- No re-renders when state changes -- State accessible anywhere via Tailwind classes - ---- - -## From Redux/Zustand - -### Redux Theme Slice - -**Before (Redux):** - -```tsx -// store/themeSlice.ts -const themeSlice = createSlice({ - name: "theme", - initialState: { value: "light" }, - reducers: { - toggleTheme: (state) => { - state.value = state.value === "light" ? "dark" : "light"; - }, - }, -}); - -// Component -function ThemeToggle() { - const theme = useSelector((state) => state.theme.value); - const dispatch = useDispatch(); - - return ( -
- -
- ); -} -``` - -**After (React Zero-UI):** - -```tsx -// No store setup needed! - -function ThemeToggle() { - const [, setTheme] = useUI("theme", "light"); - - return ( -
- -
- ); -} -``` - -### Zustand Store - -**Before (Zustand):** - -```tsx -const useThemeStore = create((set) => ({ theme: "light", toggleTheme: () => set((state) => ({ theme: state.theme === "light" ? "dark" : "light" })) })); - -function ThemeToggle() { - const { theme, toggleTheme } = useThemeStore(); - - return ( -
- -
- ); -} -``` - -**After (React Zero-UI):** - -```tsx -function ThemeToggle() { - const [, setTheme] = useUI("theme", "light"); - - return ( -
- -
- ); -} -``` - ---- - -## From CSS-in-JS Solutions - -### Styled Components with Theme - -**Before (Styled Components):** - -```tsx -const ThemeProvider = styled.div` - background: ${(props) => props.theme.bg}; - color: ${(props) => props.theme.text}; -`; - -const theme = { light: { bg: "white", text: "black" }, dark: { bg: "black", text: "white" } }; - -function App() { - const [currentTheme, setCurrentTheme] = useState("light"); - - return ( - - - - ); -} -``` - -**After (React Zero-UI + Tailwind):** - -```tsx -function App() { - const [, setTheme] = useUI("theme", "light"); - - return ( -
- -
- ); -} -``` - ---- - -## From Component State to Global State - -### Converting Local State to Global - -**Before (Local component state):** - -```tsx -function Sidebar() { - const [isOpen, setIsOpen] = useState(false); - - return ( -
- -
- ); -} - -function Header() { - // Can't access sidebar state! - return
Header content
; -} -``` - -**After (Global state, accessible everywhere):** - -```tsx -function Sidebar() { - const [, setSidebar] = useUI("sidebar", "closed"); - - return ( -
- -
- ); -} - -function Header() { - // Can respond to sidebar state! - return
Header content
; -} -``` - ---- - -## Migration Checklist - -### Step 1: Identify UI State - -- [ ] List all `useState` hooks that control UI appearance -- [ ] Identify global state (Context, Redux, Zustand) -- [ ] Find conditional className logic -- [ ] Note prop drilling for UI state - -### Step 2: Install and Configure - -```bash -npx create-zero-ui -``` - -Or manual setup: - -- [ ] Install `@react-zero-ui/core` -- [ ] Configure PostCSS plugin -- [ ] Update Tailwind config - -### Step 3: Convert State by State - -- [ ] Replace `useState` with `useUI` -- [ ] Convert conditional classes to Tailwind variants -- [ ] Remove context providers for UI state -- [ ] Update component dependencies - -### Step 4: Test and Verify - -- [ ] Verify all state changes work -- [ ] Check for any missing CSS variants -- [ ] Test SSR/hydration (no FOUC) -- [ ] Validate performance improvements - ---- - -## Migration Gotchas - -### 1. State Key Naming - -```tsx -// Avoid conflicts with existing data attributes -const [, setState] = useUI("id", "default"); // conflicts with data-id - -// Use descriptive, unique keys -const [, setState] = useUI("modal-state", "closed"); -``` - -### 2. Initial Value Consistency - -```tsx -// Ensure initial values match what CSS expects -const [, setTheme] = useUI("theme", "lite"); // typo! - -// Match your Tailwind variants exactly -const [, setTheme] = useUI("theme", "light"); // matches theme-light: -``` - ---- - -### 3. **No Imported State Keys (Yet)** - -Imported variables can't be resolved statically — even if reassigned locally. - -```ts -// This will fail at build time -import { THEME_KEY } from "./constants"; -const localKey = THEME_KEY; -const [, setTheme] = useUI(localKey, "dark"); -``` - -```ts -// Inline the string directly or re-declare as a top-level const -const THEME_KEY = "theme"; -const [, setTheme] = useUI(THEME_KEY, "dark"); -``` - -> We're working on support for imported bindings once Next.js exposes a plugin API for Turbopack. Until then, stick with top-level `const` literals. - -### 4. Don't Read Stale Values - -```tsx -// Don't use returned value for logic -const [theme, setTheme] = useUI("theme", "light"); -if (theme === "dark") { - /* Won't work! */ -} - -// Use CSS classes for visual state -
Only visible in light mode
; -``` - ---- - -## Before/After Comparison - -| Aspect | Before (Traditional) | After (React Zero-UI) | -| ----------------- | ----------------------------- | -------------------------- | -| **Bundle Size** | +5KB (Redux) / +2KB (Context) | +350 bytes | -| **Re-renders** | Every state change | Zero | -| **Performance** | Slower with scale | Constant fast | -| **Setup** | Complex (store, providers) | Simple (one hook) | -| **Global Access** | Prop drilling / Context | Tailwind variants anywhere | -| **SSR** | Hydration mismatches | Perfect SSR | - ---- - -
- -### Migration Complete! - -Your app should now be faster, simpler, and more maintainable. - -[**Next: Usage Examples**](./usage-examples.md) | [**API Reference**](../README.md#api-reference) - -
diff --git a/docs-legacy/size.md b/docs-legacy/size.md deleted file mode 100644 index ce11131..0000000 --- a/docs-legacy/size.md +++ /dev/null @@ -1,29 +0,0 @@ -# Bundle Size Proof - -This repo measures bundle size from the built `@react-zero-ui/core` entry. - -## Command - -```bash -pnpm build -pnpm size -pnpm size:badge -``` - -The `size` script in [`package.json`](../package.json) runs: - -```bash -npx esbuild ./packages/core/dist/index.js --bundle --minify --format=esm --external:react --define:process.env.NODE_ENV='"production"' | gzip -c | wc -c -``` - -That produces the gzipped byte count used for the README badge. - -## Badge File - -Run `pnpm size:badge` after a build when you want to refresh the badge JSON. - -That writes: - -- [`core-size.json`](../.github/badges/core-size.json) - -The README badge reads from that committed file through a Shields endpoint. diff --git a/docs-legacy/usage-examples.md b/docs-legacy/usage-examples.md deleted file mode 100644 index 82b5341..0000000 --- a/docs-legacy/usage-examples.md +++ /dev/null @@ -1,477 +0,0 @@ -# Usage Examples & Patterns - -
- -**Comprehensive examples and patterns for React Zero-UI** - -Learn through practical, real-world use cases and best practices. - -
- ---- - -## Basic Usage Patterns - -### 1. Theme Toggle (Global State) - -The most common pattern - global theme switching: - -```tsx -import { useUI } from "@react-zero-ui/core"; - -function ThemeToggle() { - const [theme, setTheme] = useUI("theme", "light"); - - return ( - - ); -} -``` - -**Tailwind usage anywhere in your app:** - -```html -
Content that responds to theme
-``` - -### 2. Modal State Management - -```tsx -import { useUI } from "@react-zero-ui/core"; - -function App() { - const [, setModal] = useUI("modal", "closed"); - - return ( - <> - - - {/* Modal backdrop */} -
-
-

Modal Content

- -
-
- - ); -} -``` - -### 3. Multi-State Navigation - -```tsx -import { useUI } from "@react-zero-ui/core"; - -type TabState = "home" | "about" | "contact"; - -function Navigation() { - const [activeTab, setActiveTab] = useUI("nav-tab", "home"); - - const tabs = [ - { id: "home", label: "Home" }, - { id: "about", label: "About" }, - { id: "contact", label: "Contact" }, - ] as const; - - return ( - - ); -} -``` - ---- - -## Scoped UI Patterns - -### 1. Component-Level State - -```tsx -import { useScopedUI } from "@react-zero-ui/core"; - -function Card() { - const [state, setState] = useScopedUI("card-state", "collapsed"); - - return ( -
- - -
-

This content only shows when expanded!

-
-
- ); -} -``` - -### 2. Form Field States - -```tsx -import { useScopedUI } from "@react-zero-ui/core"; - -function FormField({ label, ...props }) { - const [state, setState] = useScopedUI("field-state", "default"); - - return ( -
- - setState("focused")} - onBlur={() => setState("default")} - onChange={(e) => { - // Validate and set state accordingly - const isValid = e.target.value.length > 0; - setState(isValid ? "success" : "error"); - }} - /> -
This field is required
-
- ); -} -``` - ---- - -## CSS Variables Patterns - -### 1. Dynamic Styling with CSS Variables - -```tsx -import { useUI, CssVar } from "@react-zero-ui/core"; - -function DynamicTheme() { - const [, setPrimaryColor] = useUI("primary-color", "#3b82f6", CssVar); - const [, setBlur] = useUI("blur-amount", "0px", CssVar); - - const colors = ["#3b82f6", "#ef4444", "#10b981", "#f59e0b"]; - - return ( -
-
- {colors.map((color) => ( -
- - - - {/* Uses CSS variables */} -
- Dynamic styled content -
-
- ); -} -``` - -### 2. Scoped CSS Variables - -```tsx -import { useScopedUI, CssVar } from "@react-zero-ui/core"; - -function CustomSlider() { - const [value, setValue] = useScopedUI("slider-value", "50", CssVar); - - return ( -
- setValue(e.target.value)} - className="w-full" - /> - - {/* Progress indicator using CSS variable */} -
-
- ); -} -``` - ---- - -## SSR-Safe Patterns (Experimental) - -### 1. Server Component Interactivity - -```tsx -// This is a SERVER COMPONENT! No 'use client' needed -import { zeroSSR } from "@react-zero-ui/core/experimental"; - -function ServerThemeToggle() { - return ( - - ); -} -``` - -### 2. Scoped Server Component State - -```tsx -import { scopedZeroSSR } from "@react-zero-ui/core/experimental"; - -function ServerModal() { - return ( - // This data key will set the scope -
- - -
-
-

Server-Rendered Modal

- -
-
-
- ); -} -``` - ---- - -## Advanced Patterns - -### 1. State Composition - -```tsx -import { useUI } from "@react-zero-ui/core"; - -function Dashboard() { - const [, setSidebar] = useUI("sidebar", "collapsed"); - const [, setTheme] = useUI("theme", "light"); - const [, setNotifications] = useUI("notifications", "hidden"); - - return ( -
- {/* Multiple states working together */} -
- ); -} -``` - -### 2. Conditional Logic with Functional Updates - -```tsx -import { useUI } from "@react-zero-ui/core"; - -function SmartToggle() { - const [, setMode] = useUI("app-mode", "normal"); - - const handleModeChange = (condition: boolean) => { - setMode((prev) => { - if (condition && prev === "normal") return "advanced"; - if (!condition && prev === "advanced") return "normal"; - return prev; // No change - }); - }; - - return ; -} -``` - -### 3. Animation Sequences - -```tsx -import { useUI } from "@react-zero-ui/core"; - -function AnimatedCard() { - const [, setAnimation] = useUI("card-anim", "idle"); - - const playAnimation = async () => { - setAnimation("preparing"); - await new Promise((resolve) => setTimeout(resolve, 100)); - - setAnimation("animating"); - await new Promise((resolve) => setTimeout(resolve, 500)); - - setAnimation("complete"); - await new Promise((resolve) => setTimeout(resolve, 200)); - - setAnimation("idle"); - }; - - return ( -
- -
- ); -} -``` - ---- - -## Styling Best Practices - -### 1. Semantic State Names - -```tsx -// Good: Semantic and clear -const [, setModal] = useUI("modal", "closed"); -const [, setTheme] = useUI("theme", "light"); -const [, setNavigation] = useUI("nav-state", "collapsed"); - -// Avoid: Generic or unclear -const [, setState] = useUI("state", "on"); -const [, setThing] = useUI("x", "y"); -``` - -### 2. Consistent Naming Conventions - -```tsx -// Use kebab-case for multi-word keys -const [, setSidebarState] = useUI("sidebar-state", "collapsed"); -const [, setUserProfile] = useUI("user-profile", "hidden"); - -// Use clear value names -const [, setModal] = useUI("modal", "closed"); // closed/open -const [, setTheme] = useUI("theme", "light"); // light/dark/auto -``` - -### 3. Organize Complex States - -```tsx -// For complex UIs, group related states -function App() { - // Layout states - const [, setSidebar] = useUI("sidebar", "collapsed"); - const [, setHeader] = useUI("header", "visible"); - - // Theme states - const [, setColorScheme] = useUI("color-scheme", "light"); - const [, setAccentColor] = useUI("accent-color", "blue"); - - // UI states - const [, setModal] = useUI("modal", "closed"); - const [, setToast] = useUI("toast", "hidden"); -} -``` - ---- - -## Common Pitfalls - -### 1. Don't use Imported Variables in the state key/initial value - -```tsx -// Wrong: Imported variables are not allowed -import { THEME_KEY } from "./constants"; -const [, setTheme] = useUI(THEME_KEY, "dark"); -``` - -### 1. Don't read state values for logic - -```tsx -// Wrong: staleValue doesn't update -const [theme, setTheme] = useUI("theme", "light"); -if (theme === "dark") { - /* This won't work as expected */ -} - -// Correct: Use CSS classes instead -
Light mode content
; -``` - -### 2. Avoid over-engineering simple toggles - -```tsx -// Overcomplicated for simple boolean -const [, setState] = useUI("feature", "disabled"); -setState((prev) => (prev === "disabled" ? "enabled" : "disabled")); - -// Better: Use descriptive boolean-like values -const [, setFeature] = useUI("feature", "off"); -setState((prev) => (prev === "off" ? "on" : "off")); -``` - -### 3. Don't attach multiple refs to scoped UI - -```tsx -// Wrong: Multiple refs not supported -const [, setState] = useScopedUI("state", "default"); -return ( - <> -
{/* First ref */} -
{/* This will throw an error! */} - -); - -// Correct: Create separate components/hooks -function ComponentA() { - const [, setState] = useScopedUI("state-a", "default"); - return
; -} - -function ComponentB() { - const [, setState] = useScopedUI("state-b", "default"); - return
; -} -``` - ---- - -
- -### Ready to build? - -These patterns cover 95% of real-world use cases. Mix and match them to create powerful, performant UIs. - -[**View Live Demo**](https://zero-ui.dev) | [**API Reference**](../README.md#api-reference) - -
diff --git a/docs-legacy/assets/useui-explained.webp b/docs/public/assets/useui-explained.webp similarity index 100% rename from docs-legacy/assets/useui-explained.webp rename to docs/public/assets/useui-explained.webp diff --git a/docs-legacy/assets/zero-ui-logo.png b/docs/public/assets/zero-ui-logo.png similarity index 100% rename from docs-legacy/assets/zero-ui-logo.png rename to docs/public/assets/zero-ui-logo.png diff --git a/docs-legacy/internal.md b/packages/core/ARCHITECTURE.md similarity index 100% rename from docs-legacy/internal.md rename to packages/core/ARCHITECTURE.md From b7550e2b451ea5bec38ac62f6f3510a28cf0b2b5 Mon Sep 17 00:00:00 2001 From: Eric Chavez Date: Mon, 13 Apr 2026 21:05:28 -0700 Subject: [PATCH 07/15] docs: add metadataBase, robots.txt, and sitemap.xml Clears the "metadataBase property is not set" build warning by defining it in the root layout. Site URL resolves from NEXT_PUBLIC_SITE_URL, falls back to VERCEL_URL (auto-set on preview deploys), and ultimately defaults to https://zero-ui.dev. robots.ts points crawlers at the sitemap; sitemap.ts emits entries for the static routes (/, /demo/perf, /demo/real-world) plus every docs page pulled from Fumadocs source.getPages(). Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/app/layout.tsx | 12 ++++++++++++ docs/app/robots.ts | 11 +++++++++++ docs/app/sitemap.ts | 27 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 docs/app/robots.ts create mode 100644 docs/app/sitemap.ts diff --git a/docs/app/layout.tsx b/docs/app/layout.tsx index 3076c7d..2a0242f 100644 --- a/docs/app/layout.tsx +++ b/docs/app/layout.tsx @@ -7,6 +7,18 @@ const inter = Inter({ subsets: ['latin'], }); +const siteUrl = + process.env.NEXT_PUBLIC_SITE_URL ?? (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : 'https://zero-ui.dev'); + +export const metadata = { + metadataBase: new URL(siteUrl), + title: { + default: 'React Zero-UI', + template: '%s · React Zero-UI', + }, + description: 'Ultra-fast React UI state with zero runtime and zero re-renders.', +}; + export default function Layout({ children }: LayoutProps<'/'>) { return ( diff --git a/docs/app/robots.ts b/docs/app/robots.ts new file mode 100644 index 0000000..c91e0dc --- /dev/null +++ b/docs/app/robots.ts @@ -0,0 +1,11 @@ +import type { MetadataRoute } from 'next'; + +const siteUrl = + process.env.NEXT_PUBLIC_SITE_URL ?? (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : 'https://zero-ui.dev'); + +export default function robots(): MetadataRoute.Robots { + return { + rules: [{ userAgent: '*', allow: '/' }], + sitemap: `${siteUrl}/sitemap.xml`, + }; +} diff --git a/docs/app/sitemap.ts b/docs/app/sitemap.ts new file mode 100644 index 0000000..2fb4e9f --- /dev/null +++ b/docs/app/sitemap.ts @@ -0,0 +1,27 @@ +import type { MetadataRoute } from 'next'; +import { source } from '@/lib/source'; + +const siteUrl = + process.env.NEXT_PUBLIC_SITE_URL ?? (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : 'https://zero-ui.dev'); + +const staticRoutes = ['/', '/demo/perf', '/demo/real-world']; + +export default function sitemap(): MetadataRoute.Sitemap { + const now = new Date().toISOString(); + + const staticEntries: MetadataRoute.Sitemap = staticRoutes.map((path) => ({ + url: `${siteUrl}${path}`, + lastModified: now, + changeFrequency: path === '/' ? 'weekly' : 'monthly', + priority: path === '/' ? 1 : 0.7, + })); + + const docEntries: MetadataRoute.Sitemap = source.getPages().map((page) => ({ + url: `${siteUrl}${page.url}`, + lastModified: now, + changeFrequency: 'weekly', + priority: 0.8, + })); + + return [...staticEntries, ...docEntries]; +} From 32e253b114431fc737ffac9067e83a57b7d8f4db Mon Sep 17 00:00:00 2001 From: Eric Chavez Date: Mon, 13 Apr 2026 21:05:38 -0700 Subject: [PATCH 08/15] docs: syntax-highlight landing + real-world code blocks Swap hand-styled
 blocks for Fumadocs'
. Same blocks that already render
correctly inside MDX now get the same Shiki-based highlighting on the
landing mental-model cards and the real-world demo's "code that
matters" section.

Cost: ~37 kB of Shiki runtime on first load for pages that use it.
Acceptable for marketing/demo pages; we're not using it on docs pages
where Fumadocs already highlights at build time.

Co-Authored-By: Claude Opus 4.6 (1M context) 
---
 docs/app/(home)/demo/real-world/page.tsx | 10 ++++++----
 docs/app/(home)/page.tsx                 |  9 ++++-----
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/docs/app/(home)/demo/real-world/page.tsx b/docs/app/(home)/demo/real-world/page.tsx
index 2769379..d53efea 100644
--- a/docs/app/(home)/demo/real-world/page.tsx
+++ b/docs/app/(home)/demo/real-world/page.tsx
@@ -1,5 +1,6 @@
 import Link from 'next/link';
 import { ArrowLeft } from 'lucide-react';
+import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
 import { RealWorldDemo } from './_components';
 
 export const metadata = {
@@ -30,8 +31,9 @@ export default function RealWorldDemoPage() {
       

The code that matters

-
-            {`const [data, setData] = useState([]);
+           {
     setData(r);              // 1 re-render
     setStatus('success');    // no re-render
   });
-}, [query]);`}
-          
+}, [query]);`} + />

When to reach for this

diff --git a/docs/app/(home)/page.tsx b/docs/app/(home)/page.tsx index 654bcb9..b97060e 100644 --- a/docs/app/(home)/page.tsx +++ b/docs/app/(home)/page.tsx @@ -1,5 +1,6 @@ import Link from 'next/link'; import { ArrowRight, Zap, Layers, Feather, Github } from 'lucide-react'; +import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock'; import { LandingDemo } from './_components/LandingDemo'; export default function HomePage() { @@ -108,13 +109,11 @@ function CodeCard({ label, tone, code }: { label: string; tone: 'muted' | 'prima return (
-
{label}
-
-        {code}
-      
+
{label}
+
); } From 5d5e5847ecaf4daabad12ad9d7dfcd3eac15e0cc Mon Sep 17 00:00:00 2001 From: Eric Chavez Date: Mon, 13 Apr 2026 21:06:35 -0700 Subject: [PATCH 09/15] docs: fix CssVar identifier (actual export is lowercase cssVar) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit packages/core/src/index.ts exports \`cssVar\` (a unique Symbol used as a typeof marker for the flag parameter of useUI/useScopedUI). The legacy markdown docs called it \`CssVar\` throughout — a doc bug that got migrated verbatim into the new MDX pages. Correct all 14 references across api-reference, usage-examples, and faq. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/content/docs/api-reference.mdx | 14 +++++++------- docs/content/docs/faq.mdx | 6 +++--- docs/content/docs/usage-examples.mdx | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/content/docs/api-reference.mdx b/docs/content/docs/api-reference.mdx index 92523cc..04ce4d1 100644 --- a/docs/content/docs/api-reference.mdx +++ b/docs/content/docs/api-reference.mdx @@ -21,7 +21,7 @@ const [staleValue, setter] = useUI(key, initial, flag?); | --------- | --------------- | ------------------------------------------------------ | | `key` | `string` | The state key (becomes `data-{key}` attribute) | | `initial` | `T` | Initial/default value for SSR | -| `flag?` | `typeof CssVar` | Optional: Use CSS variables instead of data attributes | +| `flag?` | `typeof cssVar` | Optional: Use CSS variables instead of data attributes | #### Returns @@ -41,7 +41,7 @@ setTheme("dark"); // Sets data-theme="dark" on const [status, setStatus] = useUI<"loading" | "success" | "error">("status", "loading"); // With CSS variables -const [color, setColor] = useUI("primary", "#blue", CssVar); +const [color, setColor] = useUI("primary", "#blue", cssVar); setColor("#red"); // Sets --primary: #red on // Functional updates @@ -81,7 +81,7 @@ const [modal, setModal] = useScopedUI("modal", "closed");
; // With CSS variables -const [blur, setBlur] = useScopedUI("blur", "0px", CssVar); +const [blur, setBlur] = useScopedUI("blur", "0px", cssVar);
// Scoped CSS variable -const [size, setSize] = useScopedUI("font-size", "16px", CssVar); +const [size, setSize] = useScopedUI("font-size", "16px", cssVar); // Result:
``` diff --git a/docs/content/docs/faq.mdx b/docs/content/docs/faq.mdx index 1ee578e..4dc222c 100644 --- a/docs/content/docs/faq.mdx +++ b/docs/content/docs/faq.mdx @@ -160,12 +160,12 @@ useEffect(() => { ### Can I use CSS variables? -Yes! Pass the `CssVar` flag: +Yes! Pass the `cssVar` flag: ```tsx -import { useUI, CssVar } from "@react-zero-ui/core"; +import { useUI, cssVar } from "@react-zero-ui/core"; -const [, setColor] = useUI("primary", "#blue", CssVar); +const [, setColor] = useUI("primary", "#blue", cssVar); // Result: ``` diff --git a/docs/content/docs/usage-examples.mdx b/docs/content/docs/usage-examples.mdx index fd002a9..542cb84 100644 --- a/docs/content/docs/usage-examples.mdx +++ b/docs/content/docs/usage-examples.mdx @@ -158,11 +158,11 @@ function FormField({ label, ...props }) { ### 1. Dynamic styling with CSS variables ```tsx -import { useUI, CssVar } from "@react-zero-ui/core"; +import { useUI, cssVar } from "@react-zero-ui/core"; function DynamicTheme() { - const [, setPrimaryColor] = useUI("primary-color", "#3b82f6", CssVar); - const [, setBlur] = useUI("blur-amount", "0px", CssVar); + const [, setPrimaryColor] = useUI("primary-color", "#3b82f6", cssVar); + const [, setBlur] = useUI("blur-amount", "0px", cssVar); const colors = ["#3b82f6", "#ef4444", "#10b981", "#f59e0b"]; @@ -195,10 +195,10 @@ function DynamicTheme() { ### 2. Scoped CSS variables ```tsx -import { useScopedUI, CssVar } from "@react-zero-ui/core"; +import { useScopedUI, cssVar } from "@react-zero-ui/core"; function CustomSlider() { - const [value, setValue] = useScopedUI("slider-value", "50", CssVar); + const [value, setValue] = useScopedUI("slider-value", "50", cssVar); return (
Date: Tue, 28 Apr 2026 08:26:21 -0700 Subject: [PATCH 10/15] chore: move Fumadocs app from docs/ into examples/demo/ Replaces the old Next.js demo app at examples/demo with the Fumadocs docs site previously living at docs/. Reuses the existing Vercel project pointed at examples/demo so each PR will get a preview deploy of the docs site for free, instead of needing a separate Vercel project. The valuable parts of the old demo (perf comparison, real-world hybrid example) were already ported into the docs app in afedd8a / 16dd037, so the deletion is safe. Also drops the now-unused 'docs' entry from pnpm-workspace.yaml; the existing 'examples/*' glob covers the new location. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/package.json | 31 - docs/postcss.config.mjs | 6 - docs/tsconfig.json | 31 - {docs => examples/demo}/.gitignore | 0 examples/demo/.zero-ui/attributes.d.ts | 15 - examples/demo/.zero-ui/attributes.js | 21 - {docs => examples/demo}/README.md | 0 .../app/(home)/_components/LandingDemo.tsx | 0 .../app/(home)/demo/perf/_comparison.tsx | 0 .../app/(home)/demo/perf/_react-state.tsx | 0 .../app/(home)/demo/perf/_zero-state.tsx | 0 .../demo}/app/(home)/demo/perf/page.tsx | 0 .../(home)/demo/real-world/_components.tsx | 0 .../demo}/app/(home)/demo/real-world/_data.ts | 0 .../demo}/app/(home)/demo/real-world/page.tsx | 0 {docs => examples/demo}/app/(home)/layout.tsx | 0 {docs => examples/demo}/app/(home)/page.tsx | 0 .../demo}/app/api/search/route.ts | 0 .../demo}/app/docs/[[...slug]]/page.tsx | 0 {docs => examples/demo}/app/docs/layout.tsx | 0 {docs => examples/demo}/app/global.css | 0 {docs => examples/demo}/app/layout.tsx | 0 .../demo}/app/llms-full.txt/route.ts | 0 .../demo}/app/og/docs/[...slug]/route.tsx | 0 {docs => examples/demo}/app/robots.ts | 0 {docs => examples/demo}/app/sitemap.ts | 0 .../demo}/content/docs/api-reference.mdx | 0 .../demo}/content/docs/experimental.mdx | 0 {docs => examples/demo}/content/docs/faq.mdx | 0 .../content/docs/getting-started/meta.json | 0 .../content/docs/getting-started/next.mdx | 0 .../content/docs/getting-started/vite.mdx | 0 .../demo}/content/docs/index.mdx | 0 .../demo}/content/docs/meta.json | 0 .../demo}/content/docs/migration-guide.mdx | 0 .../demo}/content/docs/usage-examples.mdx | 0 {docs => examples/demo}/lib/layout.shared.tsx | 0 {docs => examples/demo}/lib/source.ts | 0 {docs => examples/demo}/mdx-components.tsx | 0 examples/demo/next-env.d.ts | 1 + {docs => examples/demo}/next.config.mjs | 0 examples/demo/next.config.ts | 7 - examples/demo/package.json | 68 +- examples/demo/postcss.config.mjs | 7 +- .../demo}/public/assets/useui-explained.webp | Bin .../demo}/public/assets/zero-ui-logo.png | Bin examples/demo/public/icons-old.svg | 263 ---- examples/demo/public/icons.svg | 685 --------- examples/demo/public/zero-ui-favicon.png | Bin 32916 -> 0 bytes examples/demo/public/zero-ui-variant-4.webp | Bin 20886 -> 0 bytes {docs => examples/demo}/source.config.ts | 0 .../(sprite-demo)/components/HeaderBar.tsx | 16 - .../(sprite-demo)/components/HeaderTabs.tsx | 31 - .../(sprite-demo)/components/SectionGrid.tsx | 7 - .../(sprite-demo)/components/StatsCard.tsx | 26 - .../app/(sprite-demo)/icon-sprite/page.tsx | 367 ----- .../demo/src/app/(sprite-demo)/layout.tsx | 11 - .../app/(sprite-demo)/lucide-react/page.tsx | 353 ----- examples/demo/src/app/(test)/ReactState.tsx | 156 -- examples/demo/src/app/(test)/ZeroState.tsx | 133 -- examples/demo/src/app/(test)/layout.tsx | 78 - examples/demo/src/app/(test)/page.tsx | 47 - .../demo/src/app/(test)/react/Dashboard.tsx | 43 - .../demo/src/app/(test)/react/InnerDot.tsx | 19 - examples/demo/src/app/(test)/react/page.tsx | 19 - .../demo/src/app/(test)/ssr/Dashboard.tsx | 44 - examples/demo/src/app/(test)/ssr/InnerDot.tsx | 15 - .../demo/src/app/(test)/ssr/init-zero-ui.tsx | 8 - examples/demo/src/app/(test)/ssr/page.tsx | 22 - .../demo/src/app/(test)/zero-ui/Dashboard.tsx | 44 - .../demo/src/app/(test)/zero-ui/InnerDot.tsx | 15 - examples/demo/src/app/(test)/zero-ui/page.tsx | 20 - .../demo/src/app/components/DotMenuIcon.tsx | 9 - examples/demo/src/app/components/Icon.tsx | 11 - .../demo/src/app/components/MobileMenu.tsx | 41 - .../src/app/components/MobileMenuButton.tsx | 46 - .../demo/src/app/components/ReactScan.tsx | 14 - .../app/components/SandBox/CodeSandBox.tsx | 17 - examples/demo/src/app/components/TopBar.tsx | 75 - examples/demo/src/app/config/siteConfig.ts | 9 - examples/demo/src/app/favicon.ico | Bin 15086 -> 0 bytes examples/demo/src/app/globals.css | 155 -- examples/demo/src/app/layout.tsx | 18 - examples/demo/src/app/opengraph-image.png | Bin 91958 -> 0 bytes examples/demo/src/app/robots.ts | 5 - examples/demo/src/app/sitemap.ts | 16 - examples/demo/src/hooks/useIsMobile.ts | 22 - examples/demo/src/utils/getMediaQueryStore.ts | 41 - examples/demo/tsconfig.json | 59 +- pnpm-lock.yaml | 1339 +---------------- pnpm-workspace.yaml | 1 - 91 files changed, 93 insertions(+), 4394 deletions(-) delete mode 100644 docs/package.json delete mode 100644 docs/postcss.config.mjs delete mode 100644 docs/tsconfig.json rename {docs => examples/demo}/.gitignore (100%) delete mode 100644 examples/demo/.zero-ui/attributes.d.ts delete mode 100644 examples/demo/.zero-ui/attributes.js rename {docs => examples/demo}/README.md (100%) rename {docs => examples/demo}/app/(home)/_components/LandingDemo.tsx (100%) rename {docs => examples/demo}/app/(home)/demo/perf/_comparison.tsx (100%) rename {docs => examples/demo}/app/(home)/demo/perf/_react-state.tsx (100%) rename {docs => examples/demo}/app/(home)/demo/perf/_zero-state.tsx (100%) rename {docs => examples/demo}/app/(home)/demo/perf/page.tsx (100%) rename {docs => examples/demo}/app/(home)/demo/real-world/_components.tsx (100%) rename {docs => examples/demo}/app/(home)/demo/real-world/_data.ts (100%) rename {docs => examples/demo}/app/(home)/demo/real-world/page.tsx (100%) rename {docs => examples/demo}/app/(home)/layout.tsx (100%) rename {docs => examples/demo}/app/(home)/page.tsx (100%) rename {docs => examples/demo}/app/api/search/route.ts (100%) rename {docs => examples/demo}/app/docs/[[...slug]]/page.tsx (100%) rename {docs => examples/demo}/app/docs/layout.tsx (100%) rename {docs => examples/demo}/app/global.css (100%) rename {docs => examples/demo}/app/layout.tsx (100%) rename {docs => examples/demo}/app/llms-full.txt/route.ts (100%) rename {docs => examples/demo}/app/og/docs/[...slug]/route.tsx (100%) rename {docs => examples/demo}/app/robots.ts (100%) rename {docs => examples/demo}/app/sitemap.ts (100%) rename {docs => examples/demo}/content/docs/api-reference.mdx (100%) rename {docs => examples/demo}/content/docs/experimental.mdx (100%) rename {docs => examples/demo}/content/docs/faq.mdx (100%) rename {docs => examples/demo}/content/docs/getting-started/meta.json (100%) rename {docs => examples/demo}/content/docs/getting-started/next.mdx (100%) rename {docs => examples/demo}/content/docs/getting-started/vite.mdx (100%) rename {docs => examples/demo}/content/docs/index.mdx (100%) rename {docs => examples/demo}/content/docs/meta.json (100%) rename {docs => examples/demo}/content/docs/migration-guide.mdx (100%) rename {docs => examples/demo}/content/docs/usage-examples.mdx (100%) rename {docs => examples/demo}/lib/layout.shared.tsx (100%) rename {docs => examples/demo}/lib/source.ts (100%) rename {docs => examples/demo}/mdx-components.tsx (100%) rename {docs => examples/demo}/next.config.mjs (100%) delete mode 100644 examples/demo/next.config.ts rename {docs => examples/demo}/public/assets/useui-explained.webp (100%) rename {docs => examples/demo}/public/assets/zero-ui-logo.png (100%) delete mode 100644 examples/demo/public/icons-old.svg delete mode 100644 examples/demo/public/icons.svg delete mode 100644 examples/demo/public/zero-ui-favicon.png delete mode 100644 examples/demo/public/zero-ui-variant-4.webp rename {docs => examples/demo}/source.config.ts (100%) delete mode 100644 examples/demo/src/app/(sprite-demo)/components/HeaderBar.tsx delete mode 100644 examples/demo/src/app/(sprite-demo)/components/HeaderTabs.tsx delete mode 100644 examples/demo/src/app/(sprite-demo)/components/SectionGrid.tsx delete mode 100644 examples/demo/src/app/(sprite-demo)/components/StatsCard.tsx delete mode 100644 examples/demo/src/app/(sprite-demo)/icon-sprite/page.tsx delete mode 100644 examples/demo/src/app/(sprite-demo)/layout.tsx delete mode 100644 examples/demo/src/app/(sprite-demo)/lucide-react/page.tsx delete mode 100644 examples/demo/src/app/(test)/ReactState.tsx delete mode 100644 examples/demo/src/app/(test)/ZeroState.tsx delete mode 100644 examples/demo/src/app/(test)/layout.tsx delete mode 100644 examples/demo/src/app/(test)/page.tsx delete mode 100644 examples/demo/src/app/(test)/react/Dashboard.tsx delete mode 100644 examples/demo/src/app/(test)/react/InnerDot.tsx delete mode 100644 examples/demo/src/app/(test)/react/page.tsx delete mode 100644 examples/demo/src/app/(test)/ssr/Dashboard.tsx delete mode 100644 examples/demo/src/app/(test)/ssr/InnerDot.tsx delete mode 100644 examples/demo/src/app/(test)/ssr/init-zero-ui.tsx delete mode 100644 examples/demo/src/app/(test)/ssr/page.tsx delete mode 100644 examples/demo/src/app/(test)/zero-ui/Dashboard.tsx delete mode 100644 examples/demo/src/app/(test)/zero-ui/InnerDot.tsx delete mode 100644 examples/demo/src/app/(test)/zero-ui/page.tsx delete mode 100644 examples/demo/src/app/components/DotMenuIcon.tsx delete mode 100644 examples/demo/src/app/components/Icon.tsx delete mode 100644 examples/demo/src/app/components/MobileMenu.tsx delete mode 100644 examples/demo/src/app/components/MobileMenuButton.tsx delete mode 100644 examples/demo/src/app/components/ReactScan.tsx delete mode 100644 examples/demo/src/app/components/SandBox/CodeSandBox.tsx delete mode 100644 examples/demo/src/app/components/TopBar.tsx delete mode 100644 examples/demo/src/app/config/siteConfig.ts delete mode 100644 examples/demo/src/app/favicon.ico delete mode 100644 examples/demo/src/app/globals.css delete mode 100644 examples/demo/src/app/layout.tsx delete mode 100644 examples/demo/src/app/opengraph-image.png delete mode 100644 examples/demo/src/app/robots.ts delete mode 100644 examples/demo/src/app/sitemap.ts delete mode 100644 examples/demo/src/hooks/useIsMobile.ts delete mode 100644 examples/demo/src/utils/getMediaQueryStore.ts diff --git a/docs/package.json b/docs/package.json deleted file mode 100644 index a4750eb..0000000 --- a/docs/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "docs", - "version": "0.0.0", - "private": true, - "scripts": { - "build": "next build", - "dev": "next dev --turbo", - "start": "next start", - "postinstall": "fumadocs-mdx" - }, - "dependencies": { - "next": "15.5.4", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "lucide-react": "^0.544.0", - "fumadocs-ui": "15.8.5", - "fumadocs-core": "15.8.5", - "fumadocs-mdx": "12.0.3", - "@react-zero-ui/core": "^0.4.0" - }, - "devDependencies": { - "@types/node": "^20", - "@types/react": "^19", - "@types/react-dom": "^19", - "typescript": "^5", - "@types/mdx": "^2.0.13", - "@tailwindcss/postcss": "^4.1.10", - "tailwindcss": "^4.1.10", - "postcss": "^8.5.5" - } -} \ No newline at end of file diff --git a/docs/postcss.config.mjs b/docs/postcss.config.mjs deleted file mode 100644 index 5758b6d..0000000 --- a/docs/postcss.config.mjs +++ /dev/null @@ -1,6 +0,0 @@ -// Zero-UI must come before Tailwind -const config = { - plugins: ['@react-zero-ui/core/postcss', '@tailwindcss/postcss'], -}; - -export default config; diff --git a/docs/tsconfig.json b/docs/tsconfig.json deleted file mode 100644 index 4d8c21a..0000000 --- a/docs/tsconfig.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": ".", - "target": "ESNext", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "paths": { - "@/.source": ["./.source/index.ts"], - "@/*": ["./*"], - "@zero-ui/attributes": ["./.zero-ui/attributes.js"] - }, - "plugins": [ - { - "name": "next" - } - ] - }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".zero-ui/**/*.d.ts"], - "exclude": ["node_modules"] -} diff --git a/docs/.gitignore b/examples/demo/.gitignore similarity index 100% rename from docs/.gitignore rename to examples/demo/.gitignore diff --git a/examples/demo/.zero-ui/attributes.d.ts b/examples/demo/.zero-ui/attributes.d.ts deleted file mode 100644 index a2af8b3..0000000 --- a/examples/demo/.zero-ui/attributes.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* AUTO-GENERATED - DO NOT EDIT */ -export declare const bodyAttributes: { - "data-accent": "amber" | "emerald" | "violet"; - "data-active": "react" | "zero"; - "data-menu-open": "false" | "true"; - "data-mobile-menu": "closed" | "open"; - "data-scrolled": "down" | "up"; - "data-theme": "dark" | "light"; - "data-theme-test": "dark" | "light"; - "data-theme-test-ssr": "dark" | "light"; -}; - -export declare const variantKeyMap: { - [key: string]: true; -}; diff --git a/examples/demo/.zero-ui/attributes.js b/examples/demo/.zero-ui/attributes.js deleted file mode 100644 index cd87cdd..0000000 --- a/examples/demo/.zero-ui/attributes.js +++ /dev/null @@ -1,21 +0,0 @@ -/* AUTO-GENERATED - DO NOT EDIT */ -export const bodyAttributes = { - "data-accent": "violet", - "data-active": "zero", - "data-menu-open": "false", - "data-mobile-menu": "closed", - "data-scrolled": "up", - "data-theme": "light", - "data-theme-test": "light", - "data-theme-test-ssr": "dark" -}; -export const variantKeyMap = { - "data-accent": true, - "data-active": true, - "data-menu-open": true, - "data-mobile-menu": true, - "data-scrolled": true, - "data-theme": true, - "data-theme-test": true, - "data-theme-test-ssr": true -}; diff --git a/docs/README.md b/examples/demo/README.md similarity index 100% rename from docs/README.md rename to examples/demo/README.md diff --git a/docs/app/(home)/_components/LandingDemo.tsx b/examples/demo/app/(home)/_components/LandingDemo.tsx similarity index 100% rename from docs/app/(home)/_components/LandingDemo.tsx rename to examples/demo/app/(home)/_components/LandingDemo.tsx diff --git a/docs/app/(home)/demo/perf/_comparison.tsx b/examples/demo/app/(home)/demo/perf/_comparison.tsx similarity index 100% rename from docs/app/(home)/demo/perf/_comparison.tsx rename to examples/demo/app/(home)/demo/perf/_comparison.tsx diff --git a/docs/app/(home)/demo/perf/_react-state.tsx b/examples/demo/app/(home)/demo/perf/_react-state.tsx similarity index 100% rename from docs/app/(home)/demo/perf/_react-state.tsx rename to examples/demo/app/(home)/demo/perf/_react-state.tsx diff --git a/docs/app/(home)/demo/perf/_zero-state.tsx b/examples/demo/app/(home)/demo/perf/_zero-state.tsx similarity index 100% rename from docs/app/(home)/demo/perf/_zero-state.tsx rename to examples/demo/app/(home)/demo/perf/_zero-state.tsx diff --git a/docs/app/(home)/demo/perf/page.tsx b/examples/demo/app/(home)/demo/perf/page.tsx similarity index 100% rename from docs/app/(home)/demo/perf/page.tsx rename to examples/demo/app/(home)/demo/perf/page.tsx diff --git a/docs/app/(home)/demo/real-world/_components.tsx b/examples/demo/app/(home)/demo/real-world/_components.tsx similarity index 100% rename from docs/app/(home)/demo/real-world/_components.tsx rename to examples/demo/app/(home)/demo/real-world/_components.tsx diff --git a/docs/app/(home)/demo/real-world/_data.ts b/examples/demo/app/(home)/demo/real-world/_data.ts similarity index 100% rename from docs/app/(home)/demo/real-world/_data.ts rename to examples/demo/app/(home)/demo/real-world/_data.ts diff --git a/docs/app/(home)/demo/real-world/page.tsx b/examples/demo/app/(home)/demo/real-world/page.tsx similarity index 100% rename from docs/app/(home)/demo/real-world/page.tsx rename to examples/demo/app/(home)/demo/real-world/page.tsx diff --git a/docs/app/(home)/layout.tsx b/examples/demo/app/(home)/layout.tsx similarity index 100% rename from docs/app/(home)/layout.tsx rename to examples/demo/app/(home)/layout.tsx diff --git a/docs/app/(home)/page.tsx b/examples/demo/app/(home)/page.tsx similarity index 100% rename from docs/app/(home)/page.tsx rename to examples/demo/app/(home)/page.tsx diff --git a/docs/app/api/search/route.ts b/examples/demo/app/api/search/route.ts similarity index 100% rename from docs/app/api/search/route.ts rename to examples/demo/app/api/search/route.ts diff --git a/docs/app/docs/[[...slug]]/page.tsx b/examples/demo/app/docs/[[...slug]]/page.tsx similarity index 100% rename from docs/app/docs/[[...slug]]/page.tsx rename to examples/demo/app/docs/[[...slug]]/page.tsx diff --git a/docs/app/docs/layout.tsx b/examples/demo/app/docs/layout.tsx similarity index 100% rename from docs/app/docs/layout.tsx rename to examples/demo/app/docs/layout.tsx diff --git a/docs/app/global.css b/examples/demo/app/global.css similarity index 100% rename from docs/app/global.css rename to examples/demo/app/global.css diff --git a/docs/app/layout.tsx b/examples/demo/app/layout.tsx similarity index 100% rename from docs/app/layout.tsx rename to examples/demo/app/layout.tsx diff --git a/docs/app/llms-full.txt/route.ts b/examples/demo/app/llms-full.txt/route.ts similarity index 100% rename from docs/app/llms-full.txt/route.ts rename to examples/demo/app/llms-full.txt/route.ts diff --git a/docs/app/og/docs/[...slug]/route.tsx b/examples/demo/app/og/docs/[...slug]/route.tsx similarity index 100% rename from docs/app/og/docs/[...slug]/route.tsx rename to examples/demo/app/og/docs/[...slug]/route.tsx diff --git a/docs/app/robots.ts b/examples/demo/app/robots.ts similarity index 100% rename from docs/app/robots.ts rename to examples/demo/app/robots.ts diff --git a/docs/app/sitemap.ts b/examples/demo/app/sitemap.ts similarity index 100% rename from docs/app/sitemap.ts rename to examples/demo/app/sitemap.ts diff --git a/docs/content/docs/api-reference.mdx b/examples/demo/content/docs/api-reference.mdx similarity index 100% rename from docs/content/docs/api-reference.mdx rename to examples/demo/content/docs/api-reference.mdx diff --git a/docs/content/docs/experimental.mdx b/examples/demo/content/docs/experimental.mdx similarity index 100% rename from docs/content/docs/experimental.mdx rename to examples/demo/content/docs/experimental.mdx diff --git a/docs/content/docs/faq.mdx b/examples/demo/content/docs/faq.mdx similarity index 100% rename from docs/content/docs/faq.mdx rename to examples/demo/content/docs/faq.mdx diff --git a/docs/content/docs/getting-started/meta.json b/examples/demo/content/docs/getting-started/meta.json similarity index 100% rename from docs/content/docs/getting-started/meta.json rename to examples/demo/content/docs/getting-started/meta.json diff --git a/docs/content/docs/getting-started/next.mdx b/examples/demo/content/docs/getting-started/next.mdx similarity index 100% rename from docs/content/docs/getting-started/next.mdx rename to examples/demo/content/docs/getting-started/next.mdx diff --git a/docs/content/docs/getting-started/vite.mdx b/examples/demo/content/docs/getting-started/vite.mdx similarity index 100% rename from docs/content/docs/getting-started/vite.mdx rename to examples/demo/content/docs/getting-started/vite.mdx diff --git a/docs/content/docs/index.mdx b/examples/demo/content/docs/index.mdx similarity index 100% rename from docs/content/docs/index.mdx rename to examples/demo/content/docs/index.mdx diff --git a/docs/content/docs/meta.json b/examples/demo/content/docs/meta.json similarity index 100% rename from docs/content/docs/meta.json rename to examples/demo/content/docs/meta.json diff --git a/docs/content/docs/migration-guide.mdx b/examples/demo/content/docs/migration-guide.mdx similarity index 100% rename from docs/content/docs/migration-guide.mdx rename to examples/demo/content/docs/migration-guide.mdx diff --git a/docs/content/docs/usage-examples.mdx b/examples/demo/content/docs/usage-examples.mdx similarity index 100% rename from docs/content/docs/usage-examples.mdx rename to examples/demo/content/docs/usage-examples.mdx diff --git a/docs/lib/layout.shared.tsx b/examples/demo/lib/layout.shared.tsx similarity index 100% rename from docs/lib/layout.shared.tsx rename to examples/demo/lib/layout.shared.tsx diff --git a/docs/lib/source.ts b/examples/demo/lib/source.ts similarity index 100% rename from docs/lib/source.ts rename to examples/demo/lib/source.ts diff --git a/docs/mdx-components.tsx b/examples/demo/mdx-components.tsx similarity index 100% rename from docs/mdx-components.tsx rename to examples/demo/mdx-components.tsx diff --git a/examples/demo/next-env.d.ts b/examples/demo/next-env.d.ts index 1b3be08..830fb59 100644 --- a/examples/demo/next-env.d.ts +++ b/examples/demo/next-env.d.ts @@ -1,5 +1,6 @@ /// /// +/// // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/docs/next.config.mjs b/examples/demo/next.config.mjs similarity index 100% rename from docs/next.config.mjs rename to examples/demo/next.config.mjs diff --git a/examples/demo/next.config.ts b/examples/demo/next.config.ts deleted file mode 100644 index 7921f35..0000000 --- a/examples/demo/next.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { NextConfig } from "next"; - -const nextConfig: NextConfig = { - /* config options here */ -}; - -export default nextConfig; diff --git a/examples/demo/package.json b/examples/demo/package.json index 11015bb..a4750eb 100644 --- a/examples/demo/package.json +++ b/examples/demo/package.json @@ -1,39 +1,31 @@ { - "name": "react-zero", - "version": "0.1.0", - "private": true, - "type": "module", - "scripts": { - "dev": "next dev", - "prebuild": "zero-icons", - "build": "next build", - "start": "next start", - "lint": "next lint", - "lint:fix": "next lint --fix", - "format": "prettier --write .", - "format:check": "prettier --check .", - "type-check": "tsc --noEmit", - "clean": "rm -rf .next" - }, - "dependencies": { - "@codesandbox/sandpack-react": "^2.20.0", - "@react-zero-ui/core": "^0.4.0", - "@react-zero-ui/icon-sprite": "^0.1.4", - "@vercel/analytics": "^1.5.0", - "clsx": "^2.1.1", - "motion": "12.18.1", - "next": "15.3.8", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "react-scan": "^0.4.3" - }, - "devDependencies": { - "@tailwindcss/postcss": "^4.1.10", - "@types/node": "^20", - "@types/react": "^19", - "@types/react-dom": "^19", - "postcss": "^8.5.5", - "tailwindcss": "^4.1.10", - "typescript": "^5" - } -} + "name": "docs", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "next build", + "dev": "next dev --turbo", + "start": "next start", + "postinstall": "fumadocs-mdx" + }, + "dependencies": { + "next": "15.5.4", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "lucide-react": "^0.544.0", + "fumadocs-ui": "15.8.5", + "fumadocs-core": "15.8.5", + "fumadocs-mdx": "12.0.3", + "@react-zero-ui/core": "^0.4.0" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "typescript": "^5", + "@types/mdx": "^2.0.13", + "@tailwindcss/postcss": "^4.1.10", + "tailwindcss": "^4.1.10", + "postcss": "^8.5.5" + } +} \ No newline at end of file diff --git a/examples/demo/postcss.config.mjs b/examples/demo/postcss.config.mjs index 2e5af8c..5758b6d 100644 --- a/examples/demo/postcss.config.mjs +++ b/examples/demo/postcss.config.mjs @@ -1,5 +1,6 @@ -// postcss.config.mjs - -const config = { plugins: ["@react-zero-ui/core/postcss", "@tailwindcss/postcss"] }; +// Zero-UI must come before Tailwind +const config = { + plugins: ['@react-zero-ui/core/postcss', '@tailwindcss/postcss'], +}; export default config; diff --git a/docs/public/assets/useui-explained.webp b/examples/demo/public/assets/useui-explained.webp similarity index 100% rename from docs/public/assets/useui-explained.webp rename to examples/demo/public/assets/useui-explained.webp diff --git a/docs/public/assets/zero-ui-logo.png b/examples/demo/public/assets/zero-ui-logo.png similarity index 100% rename from docs/public/assets/zero-ui-logo.png rename to examples/demo/public/assets/zero-ui-logo.png diff --git a/examples/demo/public/icons-old.svg b/examples/demo/public/icons-old.svg deleted file mode 100644 index 35f9d92..0000000 --- a/examples/demo/public/icons-old.svg +++ /dev/null @@ -1,263 +0,0 @@ - \ No newline at end of file diff --git a/examples/demo/public/icons.svg b/examples/demo/public/icons.svg deleted file mode 100644 index 66ada77..0000000 --- a/examples/demo/public/icons.svg +++ /dev/null @@ -1,685 +0,0 @@ - \ No newline at end of file diff --git a/examples/demo/public/zero-ui-favicon.png b/examples/demo/public/zero-ui-favicon.png deleted file mode 100644 index bde7937d0a3d52b106e1534caca54b6ccae9f981..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32916 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 Pn0`V -
-

{title}

-

{subtitle}

-
- -
- ); -} diff --git a/examples/demo/src/app/(sprite-demo)/components/HeaderTabs.tsx b/examples/demo/src/app/(sprite-demo)/components/HeaderTabs.tsx deleted file mode 100644 index cccddc3..0000000 --- a/examples/demo/src/app/(sprite-demo)/components/HeaderTabs.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import Link from "next/link"; -import React from "react"; - -type HeaderTabsProps = { active: "lucide" | "sprite"; className?: string }; - -export default function HeaderTabs({ active, className }: HeaderTabsProps) { - const baseLink = "px-3 py-2 text-sm font-medium transition-colors duration-150"; - const inactive = "text-slate-700 hover:bg-slate-50 dark:text-slate-300 dark:hover:bg-slate-800"; - const activeClasses = "bg-slate-900 text-white dark:bg-white dark:text-slate-900"; - - return ( -
- - Zero UI Sprite - - - Lucide React - -
- ); -} diff --git a/examples/demo/src/app/(sprite-demo)/components/SectionGrid.tsx b/examples/demo/src/app/(sprite-demo)/components/SectionGrid.tsx deleted file mode 100644 index 3e9cfaf..0000000 --- a/examples/demo/src/app/(sprite-demo)/components/SectionGrid.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export const SectionGrid: React.FC<{ children: React.ReactNode }> = ({ children }) => { - return ( -
- {children} -
- ); -}; diff --git a/examples/demo/src/app/(sprite-demo)/components/StatsCard.tsx b/examples/demo/src/app/(sprite-demo)/components/StatsCard.tsx deleted file mode 100644 index 403dedd..0000000 --- a/examples/demo/src/app/(sprite-demo)/components/StatsCard.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from "react"; - -type StatsCardProps = { title: string; value: string; badgeText?: string; badgeTone?: "positive" | "negative" | "neutral"; className?: string }; - -export default function StatsCard({ title, value, badgeText, badgeTone = "neutral", className }: StatsCardProps) { - const badgeClasses = - badgeTone === "positive" ? "bg-green-100 text-green-700" : badgeTone === "negative" ? "bg-red-100 text-red-700" : "bg-slate-100 text-slate-700"; - - return ( -
-
- {title} HTML size: -
-
-
{value}
- {badgeText ? ( - {badgeText} - ) : null} -
-
- ); -} diff --git a/examples/demo/src/app/(sprite-demo)/icon-sprite/page.tsx b/examples/demo/src/app/(sprite-demo)/icon-sprite/page.tsx deleted file mode 100644 index 0fe11d3..0000000 --- a/examples/demo/src/app/(sprite-demo)/icon-sprite/page.tsx +++ /dev/null @@ -1,367 +0,0 @@ -import { - AlarmSmoke, - Album, - AArrowDown, - AArrowUp, - Accessibility, - Activity, - Airplay, - AirVent, - ALargeSmall, - AlarmClock, - AlarmClockCheck, - AlarmClockMinus, - AlarmClockOff, - AlarmClockPlus, - AlignCenter, - AlignCenterHorizontal, - AlignCenterVertical, - AlignEndHorizontal, - AlignEndVertical, - AlignHorizontalDistributeCenter, - AlignHorizontalDistributeEnd, - AlignHorizontalDistributeStart, - AlignHorizontalJustifyCenter, - AlignHorizontalJustifyEnd, - AlignHorizontalJustifyStart, - AlignHorizontalSpaceAround, - AlignHorizontalSpaceBetween, - AlignJustify, - AlignLeft, - AlignRight, - AlignStartHorizontal, - AlignStartVertical, - AlignVerticalDistributeCenter, - AlignVerticalDistributeEnd, - AlignVerticalDistributeStart, - AlignVerticalJustifyCenter, - AlignVerticalJustifyEnd, - AlignVerticalJustifyStart, - AlignVerticalSpaceAround, - AlignVerticalSpaceBetween, - Ambulance, - Ampersand, - Ampersands, - Amphora, - Anchor, - Angry, - Annoyed, - Antenna, - Anvil, - Aperture, - Apple, - AppWindow, - AppWindowMac, - Archive, - ArchiveRestore, - ArchiveX, - Armchair, - ArrowBigDown, - ArrowBigDownDash, - ArrowBigLeft, - ArrowBigLeftDash, - ArrowBigRight, - ArrowBigRightDash, - ArrowBigUp, - ArrowBigUpDash, - ArrowDown, - ArrowDown01, - ArrowDown10, - ArrowDownAZ, - ArrowDownFromLine, - ArrowDownLeft, - ArrowDownNarrowWide, - ArrowDownRight, - ArrowDownToDot, - ArrowDownToLine, - ArrowDownUp, - ArrowDownWideNarrow, - ArrowDownZA, - ArrowLeft, - ArrowLeftFromLine, - ArrowLeftRight, - ArrowLeftToLine, - ArrowRight, - ArrowRightFromLine, - ArrowRightLeft, - ArrowRightToLine, - ArrowsUpFromLine, - ArrowUp, - ArrowUp01, - ArrowUp10, - ArrowUpAZ, - ArrowUpDown, - ArrowUpFromDot, - ArrowUpFromLine, - ArrowUpLeft, - ArrowUpNarrowWide, - ArrowUpRight, - ArrowUpToLine, - ArrowUpWideNarrow, - ArrowUpZA, - Asterisk, - Atom, - AtSign, - AudioLines, - AudioWaveform, - Award, - Axe, - Axis3d, - Baby, - Backpack, - Badge, - BadgeAlert, - BadgeCent, - BadgeCheck, - BadgeDollarSign, - BadgeEuro, - BadgeIndianRupee, - BadgeInfo, - BadgeJapaneseYen, - BadgeMinus, - BadgePercent, - BadgePlus, - BadgePoundSterling, - BadgeRussianRuble, - BadgeSwissFranc, - BadgeX, - BaggageClaim, - Ban, - Banana, - Bandage, - Banknote, - Barcode, - Baseline, - Bath, - Battery, - BluetoothSearching, - Facebook, - Instagram, - Linkedin, - InspectionPanel, - GitMerge, - GitPullRequest, - GitBranch, - PencilRuler, - GitGraph, - PencilLine, - Pen, - Pencil, - Pin, - GitCommitVertical, -} from "@react-zero-ui/icon-sprite"; -import Link from "next/link"; -import HeaderBar from "../components/HeaderBar"; -import StatsCard from "../components/StatsCard"; -import { SectionGrid } from "../components/SectionGrid"; - -export const metadata = { - title: "Zero UI Icon Sprite - The fastest way to do icons in React", - description: "Lucide to SVG sprite for React. w/custom icon support.", - alternates: { canonical: "https://zero-ui.dev/icon-sprite" }, -}; - -const page = () => { - return ( -
-
- - Lucide to SVG sprite solution for React. w/custom icon support.{" "} - - See Github - - - } - activeTab="sprite" - /> - -
- - -
- -

Open DevTools → Elements to compare document size and structure.

- -
-
-

150 Icons - loaded with Zero Icon Sprite

-
Sprite-based rendering
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- ); -}; - -export default page; diff --git a/examples/demo/src/app/(sprite-demo)/layout.tsx b/examples/demo/src/app/(sprite-demo)/layout.tsx deleted file mode 100644 index 1292243..0000000 --- a/examples/demo/src/app/(sprite-demo)/layout.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from "react"; - -const layout = ({ children }: { children: React.ReactNode }) => { - return ( -
- {children} -
- ); -}; - -export default layout; diff --git a/examples/demo/src/app/(sprite-demo)/lucide-react/page.tsx b/examples/demo/src/app/(sprite-demo)/lucide-react/page.tsx deleted file mode 100644 index 2dd3155..0000000 --- a/examples/demo/src/app/(sprite-demo)/lucide-react/page.tsx +++ /dev/null @@ -1,353 +0,0 @@ -import { - AlarmSmoke, - Album, - AArrowDown, - AArrowUp, - Accessibility, - Activity, - Airplay, - AirVent, - ALargeSmall, - AlarmClock, - AlarmClockCheck, - AlarmClockMinus, - AlarmClockOff, - AlarmClockPlus, - AlignCenter, - AlignCenterHorizontal, - AlignCenterVertical, - AlignEndHorizontal, - AlignEndVertical, - AlignHorizontalDistributeCenter, - AlignHorizontalDistributeEnd, - AlignHorizontalDistributeStart, - AlignHorizontalJustifyCenter, - AlignHorizontalJustifyEnd, - AlignHorizontalJustifyStart, - AlignHorizontalSpaceAround, - AlignHorizontalSpaceBetween, - AlignJustify, - AlignLeft, - AlignRight, - AlignStartHorizontal, - AlignStartVertical, - AlignVerticalDistributeCenter, - AlignVerticalDistributeEnd, - AlignVerticalDistributeStart, - AlignVerticalJustifyCenter, - AlignVerticalJustifyEnd, - AlignVerticalJustifyStart, - AlignVerticalSpaceAround, - AlignVerticalSpaceBetween, - Ambulance, - Ampersand, - Ampersands, - Amphora, - Anchor, - Angry, - Annoyed, - Antenna, - Anvil, - Aperture, - Apple, - AppWindow, - AppWindowMac, - Archive, - ArchiveRestore, - ArchiveX, - Armchair, - ArrowBigDown, - ArrowBigDownDash, - ArrowBigLeft, - ArrowBigLeftDash, - ArrowBigRight, - ArrowBigRightDash, - ArrowBigUp, - ArrowBigUpDash, - ArrowDown, - ArrowDown01, - ArrowDown10, - ArrowDownAZ, - ArrowDownFromLine, - ArrowDownLeft, - ArrowDownNarrowWide, - ArrowDownRight, - ArrowDownToDot, - ArrowDownToLine, - ArrowDownUp, - ArrowDownWideNarrow, - ArrowDownZA, - ArrowLeft, - ArrowLeftFromLine, - ArrowLeftRight, - ArrowLeftToLine, - ArrowRight, - ArrowRightFromLine, - ArrowRightLeft, - ArrowRightToLine, - ArrowsUpFromLine, - ArrowUp, - ArrowUp01, - ArrowUp10, - ArrowUpAZ, - ArrowUpDown, - ArrowUpFromDot, - ArrowUpFromLine, - ArrowUpLeft, - ArrowUpNarrowWide, - ArrowUpRight, - ArrowUpToLine, - ArrowUpWideNarrow, - ArrowUpZA, - Asterisk, - Atom, - AtSign, - AudioLines, - AudioWaveform, - Award, - Axe, - Axis3d, - Baby, - Backpack, - Badge, - BadgeAlert, - BadgeCent, - BadgeCheck, - BadgeDollarSign, - BadgeEuro, - BadgeIndianRupee, - BadgeInfo, - BadgeJapaneseYen, - BadgeMinus, - BadgePercent, - BadgePlus, - BadgePoundSterling, - BadgeRussianRuble, - BadgeSwissFranc, - BadgeX, - BaggageClaim, - Ban, - Banana, - Bandage, - Banknote, - Barcode, - Baseline, - Bath, - Battery, - BluetoothSearching, - Facebook, - Instagram, - Linkedin, - InspectionPanel, - Pin, - Pencil, - Pen, - PencilLine, - PencilRuler, - GitGraph, - GitBranch, - GitPullRequest, - GitMerge, - GitCommit, -} from "lucide-react"; -import HeaderBar from "../components/HeaderBar"; -import StatsCard from "../components/StatsCard"; -import { SectionGrid } from "../components/SectionGrid"; - -export const metadata = { - title: "Lucide React Icon Demo - Lucide to React solution", - description: "See the size difference between Lucide React and Zero UI Icon Sprite. Zero UI Icon Sprite is 300% smaller.", - alternates: { canonical: "https://zero-ui.dev/lucide-react" }, -}; - -const page = () => { - return ( -
-
- - -
- - -
- -

Open DevTools → Elements to compare document size and structure.

- -
-
-

150 Icons - loaded with Lucide React

-
Component-based rendering
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- ); -}; - -export default page; diff --git a/examples/demo/src/app/(test)/ReactState.tsx b/examples/demo/src/app/(test)/ReactState.tsx deleted file mode 100644 index bb6dac2..0000000 --- a/examples/demo/src/app/(test)/ReactState.tsx +++ /dev/null @@ -1,156 +0,0 @@ -"use client"; - -import { useState } from "react"; - -export function TestComponentWithState() { - const [accent, setAccent] = useState<"violet" | "emerald" | "amber">("violet"); - const [theme, setTheme] = useState<"light" | "dark">("light"); - const [menuOpen, setMenuOpen] = useState(false); - - return ( -
-
- - - - -
- ); -} - -// Header Component -function Header({ theme }: { theme: "light" | "dark" }) { - return ( -
-

- React State Management -

- -

- Reactive state management with React
- Re-renders O(n) -

-
- ); -} - -// Theme Switcher Component -function ThemeSwitcher({ theme, setTheme }: { theme: "light" | "dark"; setTheme: (t: "light" | "dark") => void }) { - return ( -
- - -
- ); -} - -// Accent Picker Component -function AccentPicker({ - accent, - setAccent, - theme, -}: { - accent: "violet" | "emerald" | "amber"; - setAccent: (a: "violet" | "emerald" | "amber") => void; - theme: "light" | "dark"; -}) { - return ( -
-

Choose Accent

-
-
-
- ); -} - -// Interactive Card Component -function InteractiveCard({ - theme, - menuOpen, - setMenuOpen, - accent, -}: { - theme: "light" | "dark"; - menuOpen: boolean; - setMenuOpen: (open: boolean) => void; - accent: "violet" | "emerald" | "amber"; -}) { - return ( -
-
-

Open Menu Demo

- - -
- - {/* Sliding Menu */} -
-
-

✨ This panel slides open and has to re-render!

-
-
-
- ); -} - -// State Display Component -function StateDisplay({ theme, accent, menuOpen }: { theme: "light" | "dark"; accent: "violet" | "emerald" | "amber"; menuOpen: boolean }) { - return ( -
-
-
theme: {theme}
-
accent: {accent}
-
menu: {menuOpen ? "Open" : "Closed"}
-
-
- ); -} diff --git a/examples/demo/src/app/(test)/ZeroState.tsx b/examples/demo/src/app/(test)/ZeroState.tsx deleted file mode 100644 index 1305557..0000000 --- a/examples/demo/src/app/(test)/ZeroState.tsx +++ /dev/null @@ -1,133 +0,0 @@ -"use client"; - -import { useUI } from "@react-zero-ui/core"; - -export function TestComponentZero() { - const [, setTheme] = useUI<"light" | "dark">("theme", "light"); - const [, setAccent] = useUI<"violet" | "emerald" | "amber">("accent", "violet"); - const [, setMenuOpen] = useUI<"true" | "false">("menu-open", "false"); - - return ( -
-
- - - setMenuOpen((prev) => (prev === "true" ? "false" : "true"))} /> - -
- ); -} - -// Header Component - Never re-renders! -function Header() { - return ( -
-

Zero UI

- -

- Reactive state without re-rendering .
- - Zero re-renders,{" "} - Reactive &{" "} - Global state. - -

-
- ); -} - -// Theme Switcher - Never re-renders! -function ThemeSwitcher({ setTheme }: { setTheme: (t: "light" | "dark") => void }) { - return ( -
- - -
- ); -} - -// Accent Picker - Never re-renders! -function AccentPicker({ setAccent }: { setAccent: (a: "violet" | "emerald" | "amber") => void }) { - return ( -
-

Choose Accent

-
-
-
- ); -} - -// Interactive Card - Never re-renders! -function InteractiveCard({ toggleMenu }: { toggleMenu: () => void }) { - return ( -
-
-

Open Menu Demo

- -
- - {/* Sliding Panel */} -
-
-

✨ This panel slides open without re-rendering!

-
-
-
- ); -} - -// State Display - Never re-renders! -function StateDisplay() { - return ( -
-
-
- theme: Light - Dark -
-
- accent: - Violet - Emerald - Amber -
-
- menu: - Open - Closed -
-
-
- ); -} diff --git a/examples/demo/src/app/(test)/layout.tsx b/examples/demo/src/app/(test)/layout.tsx deleted file mode 100644 index 9484d2f..0000000 --- a/examples/demo/src/app/(test)/layout.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { ReactScan } from "../components/ReactScan"; - -export const metadata = { - title: "React Zero UI Demo - Zero Re-Render State Management for React", - description: "Compare the difference in re-renders between React and Zero UI.", - alternates: { canonical: "https://zero-ui.dev/" }, -}; - -const layout: React.FC<{ children: React.ReactNode }> = ({ children }) => { - return ( -
-