Repository: colinhacks/zod
Pull request #4514 (2025-05-24 08:50:11)

fix typo in error-customization.mdx
<!--

Development of the next major version of Zod (`v4`) is currently underway. During this phase, only bugfixes and documentation improvements are being accepted into the `main` branch. All other PRs should target the `v4` branch. Thanks for contribting to OSS!

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Documentation**
  - Corrected a typographical error to clarify the explanation of the `error` parameter in the documentation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

coderabbitai[bot]: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: review in progress by coderabbit.ai -->

> [!NOTE]
> Currently processing new changes in this PR. This may take a few minutes, please wait...
> 
> <details>
> <summary>📥 Commits</summary>
> 
> Reviewing files that changed from the base of the PR and between 592de8de6e9c1f1d41aaa68e2c8ba57adced6507 and 3a99716a5480db0cb4e81248f5b1f4bcba25c3a1.
> 
> </details>
> 
> <details>
> <summary>📒 Files selected for processing (1)</summary>
> 
> * `packages/docs/content/error-customization.mdx` (1 hunks)
> 
> </details>
> 
> ```ascii
>  _________________________________________________________________________________________________
> < Question: How does a large software project get to be one year late? Answer: One day at a time! >
>  -------------------------------------------------------------------------------------------------
>   \
>    \   \
>         \ /\
>         ( )
>       .( o ).
> ```

<!-- end of auto-generated comment: review in progress by coderabbit.ai -->
<!-- usage_tips_start -->

> [!TIP]
> <details>
> <summary>CodeRabbit can enforce grammar and style rules using `languagetool`.</summary>
> 
> Configure `languagetool` in your project's settings in CodeRabbit enable/disable rules and categories. Refer to the [LanguageTool Community](https://community.languagetool.org/rule/list) to learn more.
> 
> </details>

<!-- usage_tips_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=colinhacks/zod&utm_content=4514):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Patch:
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
deleted file mode 100644
index 26476d0a..00000000
--- a/.github/pull_request_template.md
+++ /dev/null
@@ -1,5 +0,0 @@
-<!--
-
-Development of the next major version of Zod (`v4`) is currently underway. During this phase, only bugfixes and documentation improvements are being accepted into the `main` branch. All other PRs should target the `v4` branch. Thanks for contribting to OSS!
-
--->
diff --git a/.github/workflows/release-canary.yml b/.github/workflows/release-canary.yml
deleted file mode 100644
index 16e94a99..00000000
--- a/.github/workflows/release-canary.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-# .github/release.yml
-
-name: Release on npm (canary)
-on:
-  push:
-    branches:
-      - main
-    paths:
-      - "packages/zod/**"
-      - ".github/workflows/release-canary.yml"
-
-jobs:
-  build_and_publish:
-    runs-on: ubuntu-latest
-    permissions:
-      contents: write
-      pull-requests: read
-      id-token: write
-    steps:
-      - uses: actions/checkout@v4
-        with:
-          fetch-depth: 0
-
-      - name: Set up Node
-        uses: actions/setup-node@v4
-        with:
-          node-version: 20
-      
-      - name: Install pnpm
-        uses: pnpm/action-setup@v4
-
-      - name: Install dependencies
-        run: |
-          pnpm install
-
-      - name: Build and test
-        working-directory: ./packages/zod
-        run: |
-          pnpm run test
-          pnpm build
-
-      - name: Set version
-        working-directory: ./packages/zod
-        run: |
-          npm --no-git-tag-version version minor
-          npm --no-git-tag-version version $(npm pkg get version | sed 's/"//g')-canary.$(date +'%Y%m%dT%H%M%S')
-
-      - id: publish
-        name: Publish to NPM
-        uses: JS-DevTools/npm-publish@v3
-        with:
-          token: ${{ secrets.NPM_TOKEN }}
-          dry-run: false
-          provenance: true
-          tag: canary
-          package: ./packages/zod
-          
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 8af73fc9..82f2b1ef 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -7,6 +7,7 @@ on:
       - main
     paths:
       - "packages/zod/package.json"
+      - "packages/zod/src/**"
       - ".github/workflows/release.yml"
 
 jobs:
@@ -53,10 +54,27 @@ jobs:
         run: |
           echo "Published ${{ steps.publish.outputs.type }} version: ${{ steps.publish.outputs.version }}"
 
-      - name: Publish skipped
+      - name: Set canary version
+        if: ${{ !steps.publish.outputs.type }}
+        working-directory: ./packages/zod
+        run: |
+          npm --no-git-tag-version version minor
+          npm --no-git-tag-version version $(npm pkg get version | sed 's/"//g')-canary.$(date +'%Y%m%dT%H%M%S')
+
+      - name: Publish canary
+        if: ${{ !steps.publish.outputs.type }}
+        uses: JS-DevTools/npm-publish@v3
+        with:
+          token: ${{ secrets.NPM_TOKEN }}
+          dry-run: false
+          provenance: true
+          tag: canary
+          package: ./packages/zod
+      
+      - name: Done with canary
         if: ${{ !steps.publish.outputs.type }}
         run: |
-          echo "Version in package.json has not changed. Skipping."
+          echo "Canary published."
           exit 0
      
       - name: Configure changelog
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6d8cd365..5615c48e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -29,7 +29,8 @@ The following steps will get you setup to contribute changes to this repo:
 
 3. Run `pnpm i` to install dependencies.
 
-4. Start playing with the code! You can do some simple experimentation in [`playground.ts`](playground.ts) (see `pnpm play` below) or start implementing a feature right away.
+4. Start playing with the code! You can do some simple experimentation in [`play.ts`](play.ts) (see `pnpm play` below) or start implementing a feature right away.
+
 
 ## Alternative: VSCode Dev Container setup
 
@@ -64,9 +65,9 @@ In the OSS version of VSCode the extension may be not available.
 
 - runs all test files in `<ws>` that match `<file>` (e.g. `"enum"` will match `"enum.test.ts"`)
 
-**`pnpm play`**
+**`pnpm dev:play`**
 
-- executes [`playground.ts`](playground.ts), watches for changes. useful for experimentation
+- executes [`play.ts`](play.ts), watches for changes. useful for experimentation
 
 ### Tests
 
diff --git a/README.md b/README.md
index 2cbc27fa..a6e1e55e 100644
--- a/README.md
+++ b/README.md
@@ -105,7 +105,7 @@ npm install zod
 
 Before you can do anything else, you need to define a schema. For the purposes of this guide, we'll use a simple object schema.
 
-```
+```ts
 import { z } from "zod/v4"; 
 
 const Player = z.object({ 
diff --git a/packages/docs/app/og.png/route.tsx b/packages/docs/app/og.png/route.tsx
index 58c3ed22..b1c52e38 100644
--- a/packages/docs/app/og.png/route.tsx
+++ b/packages/docs/app/og.png/route.tsx
@@ -15,7 +15,7 @@ export const config = {
 export async function GET(request: Request) {
   try {
     const { searchParams } = new URL(request.url);
-    const imagePrefix = process.env.VERCEL_URL ? `https://v4.zod.dev` : "http://localhost:3000";
+    const imagePrefix = process.env.VERCEL_URL ? `https://zod.dev` : "http://localhost:3000";
 
     // Get dynamic params
     const title = searchParams.get("title") || "Zod Documentation";
diff --git a/packages/docs/components/bronze.tsx b/packages/docs/components/bronze.tsx
index e593c395..f382ce6f 100644
--- a/packages/docs/components/bronze.tsx
+++ b/packages/docs/components/bronze.tsx
@@ -60,6 +60,12 @@ export const Bronze = () => {
       url: "github.com/jasonLaster",
       href: "https://github.com/jasonLaster",
     },
+    {
+      name: "Clipboard",
+      logoSrc: "https://avatars.githubusercontent.com/u/28880063?s=200&v=4",
+      url: "clipboardhealth.com/engineering",
+      href: "https://www.clipboardhealth.com/engineering",
+    },
   ];
 
   return (
diff --git a/packages/docs/components/ecosystem.tsx b/packages/docs/components/ecosystem.tsx
index 4dcead68..1741392f 100644
--- a/packages/docs/components/ecosystem.tsx
+++ b/packages/docs/components/ecosystem.tsx
@@ -47,6 +47,13 @@ const formIntegrations: ZodResource[] = [
     description: "Headless form validation library for Vue.js.",
     slug: "victorgarciaesgi/regle",
   },
+  {
+    name: "conform",
+    url: "https://conform.guide/api/zod/parseWithZod",
+    description:
+      "A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix and Next.js.",
+    slug: "edmundhung/conform",
+  },
 ];
 
 const zodToXConverters: ZodResource[] = [];
diff --git a/packages/docs/components/inkeep-bubble.tsx b/packages/docs/components/inkeep-bubble.tsx
index b30d35f5..33492907 100644
--- a/packages/docs/components/inkeep-bubble.tsx
+++ b/packages/docs/components/inkeep-bubble.tsx
@@ -45,7 +45,7 @@ export function InkeepBubble() {
     aiChatSettings: {
       // optional settings
 
-      aiAssistantAvatar: "https://v4.zod.dev/logo/logo.png", // use your own ai assistant avatar
+      aiAssistantAvatar: "https://zod.dev/logo/logo.png", // use your own ai assistant avatar
       exampleQuestions: [
         "How do I convert a Zod schema to a JSON Schema?",
         "How do I define a cyclical object type?",
diff --git a/packages/docs/content/api.mdx b/packages/docs/content/api.mdx
index 3a88d5c2..678ba0a4 100644
--- a/packages/docs/content/api.mdx
+++ b/packages/docs/content/api.mdx
@@ -297,19 +297,18 @@ z.guid();
 
 ### URLs
 
-To validate any WHATWG-compatible URL.
+To validate any WHATWG-compatible URL:
 
 ```ts
 const schema = z.url();
 
 schema.parse("https://example.com"); // ✅
 schema.parse("http://localhost"); // ✅
-
-schema.parse("mailto:noreply@zod.dev"); // ❌
-schema.parse("sup"); // ❌
+schema.parse("mailto:noreply@zod.dev"); // ✅
+schema.parse("sup"); // ✅
 ```
 
-> Internally this uses the `new URL()` constructor to perform validation. This may behave differently across platforms and runtimes but is generally the most rigorous way to validate URIs/URLs. 
+As you can see this is quite permissive. Internally this uses the `new URL()` constructor to valid inputs; this behavior may differ across platforms and runtimes but it's the mostly rigorous way to validate URIs/URLs on any given JS runtime/engine. 
 
 To validate the hostname against a specific regex:
 
@@ -329,6 +328,22 @@ schema.parse("https://example.com"); // ✅
 schema.parse("http://example.com"); // ❌
 ```
 
+<Callout>
+  **Web URLs** — In many cases, you'll want to validate Web URLs specifically. Here's the recommended schema for doing so:
+
+  ```ts
+  const httpUrl = z.url({
+    protocol: /^https?$/,
+    hostname: z.regexes.domain
+  });
+  ```
+
+  This restricts the protocol to `http`/`https` and ensures the hostname is a valid domain name with the `z.regexes.domain` regular expression:
+
+  ```ts
+  /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/
+  ```
+</Callout>
 
 ### ISO datetimes
 
@@ -932,7 +947,7 @@ Dog.parse({ name: "Yeller", extraKey: true });
 
 ### `.catchall()`
 
-To defina a *catchall schema* that will be used to validate any unrecognized keys:
+To define a *catchall schema* that will be used to validate any unrecognized keys:
 
 ```
 const DogWithStrings = z.object({
@@ -1019,11 +1034,11 @@ Starting from this initial schema:
 
 ```ts z.object
 const Recipe = z.object({
-  name: z.string(),
+  title: z.string(),
   description: z.string().optional(),
   ingredients: z.array(z.string()),
 });
-// { id: string; name: string; ingredients: string[] }
+// { title: string; description?: string | undefined; ingredients: string[] }
 ```
 To pick certain keys:
 
@@ -2480,8 +2495,8 @@ const computeTrimmedLength = MyFunction.implement((input) => {
   return input.trim().length;
 });
 
-trimmedLength("sandwich"); // => 8
-trimmedLength(" asdf "); // => 4
+computeTrimmedLength("sandwich"); // => 8
+computeTrimmedLength(" asdf "); // => 4
 ```
 
 This function will throw a `ZodError` if the input is invalid:
diff --git a/packages/docs/content/error-customization.mdx b/packages/docs/content/error-customization.mdx
index 3c3ecf23..451625ae 100644
--- a/packages/docs/content/error-customization.mdx
+++ b/packages/docs/content/error-customization.mdx
@@ -134,7 +134,7 @@ z.set(z.string(), { error: "Bad set!" });
 </Tabs>
 
 
-The `error` param optionally accepts a function. An error customization function is known as an **error map** in Zod terminology. The error map will can at parse time if a valiation error occurs.
+The `error` param optionally accepts a function. An error customization function is known as an **error map** in Zod terminology. The error map will run at parse time if a valiation error occurs.
 
 ```ts
 z.string({ error: ()=>`[${Date.now()}]: Validation failure.` });
@@ -346,6 +346,7 @@ The following locales are available:
 - `id` — Indonesian  
 - `it` — Italian  
 - `ja` — Japanese  
+- `kh` — Khmer
 - `ko` — Korean  
 - `mk` — Macedonian  
 - `ms` — Malay  
@@ -355,7 +356,8 @@ The following locales are available:
 - `pt` — Portuguese  
 - `ru` — Russian  
 - `sl` — Slovenian  
-- `ta` — Tamil  
+- `sv` — Swedish
+- `ta` — Tamil
 - `th` — Thai  
 - `tr` — Türkçe  
 - `ua` — Ukrainian  
diff --git a/packages/docs/content/v4/changelog.mdx b/packages/docs/content/v4/changelog.mdx
index 0cef0445..b0fab595 100644
--- a/packages/docs/content/v4/changelog.mdx
+++ b/packages/docs/content/v4/changelog.mdx
@@ -79,7 +79,7 @@ Error maps can also now return a plain `string` (instead of `{message: string}`)
 <Tabs groupId="error-map" items={["Zod 4", "Zod 3"]} persist>
 <Tab value="Zod 4">
 ```ts
-z.string({
+z.string().min(5, {
   error: (issue) => {
     if (issue.code === "too_small") {
       return `Value must be >${issue.minimum}`
diff --git a/packages/docs/content/v4/index.mdx b/packages/docs/content/v4/index.mdx
index 65d91819..e5491bfb 100644
--- a/packages/docs/content/v4/index.mdx
+++ b/packages/docs/content/v4/index.mdx
@@ -14,7 +14,7 @@ Huge thanks to [Clerk](https://go.clerk.com/zod-clerk), who supported my work on
 
 ## Versioning 
 
-To simplify the migration process both for users and Zod's ecosystem of associated libraries, Zod 4 will initially published alongside Zod 3 as part of the `zod@3.25` release. Despite the version number, it it considered stable and ready for production use.
+To simplify the migration process both for users and Zod's ecosystem of associated libraries, Zod 4 will initially published alongside Zod 3 as part of the `zod@3.25` release. Despite the version number, it is considered stable and ready for production use.
 
 To upgrade: 
 
diff --git a/packages/docs/package.json b/packages/docs/package.json
index 40b7f978..bc131361 100644
--- a/packages/docs/package.json
+++ b/packages/docs/package.json
@@ -9,7 +9,7 @@
     "postinstall": "fumadocs-mdx"
   },
   "dependencies": {
-    "@inkeep/cxkit-react": "^0.5.52",
+    "@inkeep/cxkit-react": "^0.5.80",
     "@radix-ui/react-accordion": "^1.2.4",
     "@vercel/analytics": "^1.5.0",
     "@vercel/og": "^0.6.8",
diff --git a/packages/docs/pages/api/_og.tsx b/packages/docs/pages/api/_og.tsx
index 9c660f77..8ff1a1e0 100644
--- a/packages/docs/pages/api/_og.tsx
+++ b/packages/docs/pages/api/_og.tsx
@@ -15,7 +15,7 @@ export const config = {
 export default async function (request: NextRequest) {
   try {
     const { searchParams } = new URL(request.url);
-    const imagePrefix = process.env.VERCEL_URL ? `https://v4.zod.dev` : "http://localhost:3000";
+    const imagePrefix = process.env.VERCEL_URL ? `https://zod.dev` : "http://localhost:3000";
 
     // Get dynamic params
     const title = searchParams.get("title") || "Zod Documentation";
diff --git a/packages/zod/package.json b/packages/zod/package.json
index be0db740..bada2cf4 100644
--- a/packages/zod/package.json
+++ b/packages/zod/package.json
@@ -1,6 +1,6 @@
 {
   "name": "zod",
-  "version": "3.25.28",
+  "version": "3.25.32",
   "type": "module",
   "author": "Colin McDonnell <zod@colinhacks.com>",
   "description": "TypeScript-first schema declaration and validation library with static type inference",
@@ -14,7 +14,6 @@
   "types": "./dist/types/index.d.ts",
   "module": "./dist/esm/index.js",
   "exports": {
-    "./package.json": "./package.json",
     ".": {
       "import": {
         "@zod/source": "./src/index.ts",
@@ -57,6 +56,12 @@
       "import": "./dist/esm/v4/mini/index.js",
       "require": "./dist/cjs/v4/mini/index.js"
     },
+    "./v4/mini": {
+      "@zod/source": "./src/v4/mini/index.ts",
+      "types": "./dist/types/v4/mini/index.d.ts",
+      "import": "./dist/esm/v4/mini/index.js",
+      "require": "./dist/cjs/v4/mini/index.js"
+    },
     "./v4/core": {
       "@zod/source": "./src/v4/core/index.ts",
       "types": "./dist/types/v4/core/index.d.ts",
@@ -74,7 +79,8 @@
       "types": "./dist/types/v4/locales/*",
       "import": "./dist/esm/v4/locales/*",
       "require": "./dist/cjs/v4/locales/*"
-    }
+    },
+    "./package.json": "./package.json"
   },
   "tshy": {
     "exports": {
diff --git a/packages/zod/src/v4/classic/schemas.ts b/packages/zod/src/v4/classic/schemas.ts
index 191412d1..19a0452d 100644
--- a/packages/zod/src/v4/classic/schemas.ts
+++ b/packages/zod/src/v4/classic/schemas.ts
@@ -238,8 +238,8 @@ export const _ZodString: core.$constructor<_ZodString> = /*@__PURE__*/ core.$con
   // validations
   inst.regex = (...args) => inst.check(checks.regex(...args));
   inst.includes = (...args) => inst.check(checks.includes(...args));
-  inst.startsWith = (params) => inst.check(checks.startsWith(params));
-  inst.endsWith = (params) => inst.check(checks.endsWith(params));
+  inst.startsWith = (...args) => inst.check(checks.startsWith(...args));
+  inst.endsWith = (...args) => inst.check(checks.endsWith(...args));
   inst.min = (...args) => inst.check(checks.minLength(...args));
   inst.max = (...args) => inst.check(checks.maxLength(...args));
   inst.length = (...args) => inst.check(checks.length(...args));
@@ -1015,6 +1015,8 @@ export interface ZodArray<T extends core.$ZodType = core.$ZodType> extends ZodTy
   nonempty(params?: string | core.$ZodCheckMinLengthParams): this;
   max(maxLength: number, params?: string | core.$ZodCheckMaxLengthParams): this;
   length(len: number, params?: string | core.$ZodCheckLengthEqualsParams): this;
+
+  unwrap(): T;
 }
 export const ZodArray: core.$constructor<ZodArray> = /*@__PURE__*/ core.$constructor("ZodArray", (inst, def) => {
   core.$ZodArray.init(inst, def);
@@ -1025,6 +1027,8 @@ export const ZodArray: core.$constructor<ZodArray> = /*@__PURE__*/ core.$constru
   inst.nonempty = (params) => inst.check(checks.minLength(1, params));
   inst.max = (maxLength, params) => inst.check(checks.maxLength(maxLength, params));
   inst.length = (len, params) => inst.check(checks.length(len, params));
+
+  inst.unwrap = () => inst.element;
 });
 
 export function array<T extends core.$ZodType>(element: T, params?: string | core.$ZodArrayParams): ZodArray<T> {
@@ -1067,10 +1071,13 @@ export interface ZodObject<
   ): ZodObject<util.Extend<Shape, U>, Config>;
 
   /**
-   * @deprecated Use destructuring to merge the shapes:
+   * @deprecated Use spread syntax and the `.shape` property to combine two object schemas:
    *
    * ```ts
-   * z.object({
+   * const A = z.object({ a: z.string() });
+   * const B = z.object({ b: z.number() });
+   *
+   * const C = z.object({
    *    ...A.shape,
    *    ...B.shape
    * });
@@ -1149,12 +1156,10 @@ export function object<T extends core.$ZodLooseShape = Partial<Record<never, cor
 ): ZodObject<util.Writeable<T> & {}, core.$strip> {
   const def: core.$ZodObjectDef = {
     type: "object",
-
     get shape() {
       util.assignProp(this, "shape", { ...shape });
       return this.shape;
     },
-
     ...util.normalizeParams(params),
   };
   return new ZodObject(def) as any;
@@ -1998,7 +2003,7 @@ function _instanceof<T extends typeof util.Class>(
   params: ZodInstanceOfParams = {
     error: `Input not instance of ${cls.name}`,
   }
-): ZodCustom<InstanceType<T>> {
+): ZodCustom<InstanceType<T>, InstanceType<T>> {
   const inst = new ZodCustom({
     type: "custom",
     check: "custom",
diff --git a/packages/zod/src/v4/core/api.ts b/packages/zod/src/v4/core/api.ts
index cafe9d44..f6787333 100644
--- a/packages/zod/src/v4/core/api.ts
+++ b/packages/zod/src/v4/core/api.ts
@@ -1476,9 +1476,10 @@ export function _stringbool(
   },
   _params?: string | $ZodStringBoolParams
 ): schemas.$ZodPipe<schemas.$ZodUnknown, schemas.$ZodBoolean<boolean>> {
-  const params = util.normalizeParams(_params);
-  const trueValues = new Set(params?.truthy ?? ["true", "1", "yes", "on", "y", "enabled"]);
-  const falseValues = new Set(params?.falsy ?? ["false", "0", "no", "off", "n", "disabled"]);
+  const { case: _case, error, truthy, falsy } = util.normalizeParams(_params);
+
+  const trueValues = new Set(truthy ?? ["true", "1", "yes", "on", "y", "enabled"]);
+  const falseValues = new Set(falsy ?? ["false", "0", "no", "off", "n", "disabled"]);
 
   const _Pipe = Classes.Pipe ?? schemas.$ZodPipe;
   const _Boolean = Classes.Boolean ?? schemas.$ZodBoolean;
@@ -1492,7 +1493,7 @@ export function _stringbool(
           check: (ctx: any) => {
             if (typeof ctx.value === "string") {
               let data: string = ctx.value;
-              if (params?.case !== "sensitive") data = data.toLowerCase();
+              if (_case !== "sensitive") data = data.toLowerCase();
               if (trueValues.has(data)) {
                 ctx.value = true;
               } else if (falseValues.has(data)) {
@@ -1521,6 +1522,7 @@ export function _stringbool(
         },
       },
     ],
+    error,
   });
 
   return new _Pipe({
@@ -1528,6 +1530,8 @@ export function _stringbool(
     in: inst,
     out: new _Boolean({
       type: "boolean",
+      error,
     }),
+    error,
   }) as any;
 }
diff --git a/packages/zod/src/v4/core/checks.ts b/packages/zod/src/v4/core/checks.ts
index a19026e5..867bdfad 100644
--- a/packages/zod/src/v4/core/checks.ts
+++ b/packages/zod/src/v4/core/checks.ts
@@ -286,6 +286,14 @@ export const $ZodCheckNumberFormat: core.$constructor<$ZodCheckNumberFormat> = /
 
       if (isInt) {
         if (!Number.isInteger(input)) {
+          // invalid_format issue
+          // payload.issues.push({
+          //   expected: def.format,
+          //   format: def.format,
+          //   code: "invalid_format",
+          //   input,
+          //   inst,
+          // });
           // invalid_type issue
           payload.issues.push({
             expected: origin,
@@ -779,8 +787,12 @@ export const $ZodCheckStringFormat: core.$constructor<$ZodCheckStringFormat> = /
     $ZodCheck.init(inst, def);
 
     inst._zod.onattach.push((inst) => {
-      inst._zod.bag.format = def.format;
-      if (def.pattern) inst._zod.bag.pattern = def.pattern;
+      const bag = inst._zod.bag as schemas.$ZodStringInternals<unknown>["bag"];
+      bag.format = def.format;
+      if (def.pattern) {
+        bag.patterns ??= new Set();
+        bag.patterns.add(def.pattern);
+      }
     });
 
     inst._zod.check ??= (payload) => {
@@ -943,7 +955,9 @@ export const $ZodCheckIncludes: core.$constructor<$ZodCheckIncludes> = /*@__PURE
     const pattern = new RegExp(util.escapeRegex(def.includes));
     def.pattern = pattern;
     inst._zod.onattach.push((inst) => {
-      inst._zod.bag.pattern = pattern;
+      const bag = inst._zod.bag as schemas.$ZodStringInternals<unknown>["bag"];
+      bag.patterns ??= new Set();
+      bag.patterns.add(pattern);
     });
 
     inst._zod.check = (payload) => {
@@ -985,7 +999,9 @@ export const $ZodCheckStartsWith: core.$constructor<$ZodCheckStartsWith> = /*@__
     const pattern = new RegExp(`^${util.escapeRegex(def.prefix)}.*`);
     def.pattern ??= pattern;
     inst._zod.onattach.push((inst) => {
-      inst._zod.bag.pattern = pattern;
+      const bag = inst._zod.bag as schemas.$ZodStringInternals<unknown>["bag"];
+      bag.patterns ??= new Set();
+      bag.patterns.add(pattern);
     });
 
     inst._zod.check = (payload) => {
@@ -1027,7 +1043,9 @@ export const $ZodCheckEndsWith: core.$constructor<$ZodCheckEndsWith> = /*@__PURE
     const pattern = new RegExp(`.*${util.escapeRegex(def.suffix)}$`);
     def.pattern ??= pattern;
     inst._zod.onattach.push((inst) => {
-      inst._zod.bag.pattern = new RegExp(`.*${util.escapeRegex(def.suffix)}$`);
+      const bag = inst._zod.bag as schemas.$ZodStringInternals<unknown>["bag"];
+      bag.patterns ??= new Set();
+      bag.patterns.add(pattern);
     });
 
     inst._zod.check = (payload) => {
diff --git a/packages/zod/src/v4/core/regexes.ts b/packages/zod/src/v4/core/regexes.ts
index 62490d7f..7ecfed8a 100644
--- a/packages/zod/src/v4/core/regexes.ts
+++ b/packages/zod/src/v4/core/regexes.ts
@@ -74,6 +74,7 @@ export const base64url: RegExp = /^[A-Za-z0-9_-]*$/;
 // export const hostname: RegExp =
 //   /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
 export const hostname: RegExp = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+$/;
+export const domain: RegExp = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
 
 // https://blog.stevenlevithan.com/archives/validate-phone-number#r4-3 (regex sans spaces)
 export const e164: RegExp = /^\+(?:[0-9]){6,14}[0-9]$/;
diff --git a/packages/zod/src/v4/core/schemas.ts b/packages/zod/src/v4/core/schemas.ts
index a9ff9668..0f4172d7 100644
--- a/packages/zod/src/v4/core/schemas.ts
+++ b/packages/zod/src/v4/core/schemas.ts
@@ -51,7 +51,6 @@ export interface $ZodTypeDef {
     | "unknown"
     | "date"
     | "object"
-    | "interface"
     | "record"
     | "file"
     | "array"
@@ -290,8 +289,9 @@ export interface $ZodStringInternals<Input> extends $ZodTypeInternals<string, In
   bag: util.LoosePartial<{
     minimum: number;
     maximum: number;
-    pattern: RegExp;
+    patterns: Set<RegExp>;
     format: string;
+    contentEncoding: string;
   }>;
 }
 
@@ -301,7 +301,7 @@ export interface $ZodString<Input = unknown> extends $ZodType {
 
 export const $ZodString: core.$constructor<$ZodString> = /*@__PURE__*/ core.$constructor("$ZodString", (inst, def) => {
   $ZodType.init(inst, def);
-  inst._zod.pattern = inst?._zod.bag?.pattern ?? regexes.string(inst._zod.bag);
+  inst._zod.pattern = [...(inst?._zod.bag?.patterns ?? [])].pop() ?? regexes.string(inst._zod.bag);
   inst._zod.parse = (payload, _) => {
     if (def.coerce)
       try {
@@ -426,18 +426,6 @@ export const $ZodURL: core.$constructor<$ZodURL> = /*@__PURE__*/ core.$construct
     try {
       const url = new URL(payload.value);
 
-      regexes.hostname.lastIndex = 0;
-      if (!regexes.hostname.test(url.hostname)) {
-        payload.issues.push({
-          code: "invalid_format",
-          format: "url",
-          note: "Invalid hostname",
-          pattern: regexes.hostname.source,
-          input: payload.value,
-          inst,
-        });
-      }
-
       if (def.hostname) {
         def.hostname.lastIndex = 0;
         if (!def.hostname.test(url.hostname)) {
@@ -445,7 +433,7 @@ export const $ZodURL: core.$constructor<$ZodURL> = /*@__PURE__*/ core.$construct
             code: "invalid_format",
             format: "url",
             note: "Invalid hostname",
-            pattern: def.hostname.source,
+            pattern: regexes.hostname.source,
             input: payload.value,
             inst,
           });
@@ -688,7 +676,8 @@ export const $ZodIPv4: core.$constructor<$ZodIPv4> = /*@__PURE__*/ core.$constru
   def.pattern ??= regexes.ipv4;
   $ZodStringFormat.init(inst, def);
   inst._zod.onattach.push((inst) => {
-    inst._zod.bag.format = `ipv4`;
+    const bag = inst._zod.bag as $ZodStringInternals<unknown>["bag"];
+    bag.format = `ipv4`;
   });
 });
 
@@ -711,7 +700,8 @@ export const $ZodIPv6: core.$constructor<$ZodIPv6> = /*@__PURE__*/ core.$constru
   $ZodStringFormat.init(inst, def);
 
   inst._zod.onattach.push((inst) => {
-    inst._zod.bag.format = `ipv6`;
+    const bag = inst._zod.bag as $ZodStringInternals<unknown>["bag"];
+    bag.format = `ipv6`;
   });
 
   inst._zod.check = (payload) => {
@@ -1539,7 +1529,6 @@ export interface $ZodObjectInternals<
   config: Config;
   isst: errors.$ZodIssueInvalidType | errors.$ZodIssueUnrecognizedKeys;
   disc: util.DiscriminatorMap;
-
   // special keys only used for objects
   // not defined on $ZodTypeInternals (base interface) because it breaks cyclical inference
   // the z.infer<> util checks for these first when extracting inferred type
@@ -1637,6 +1626,11 @@ export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$con
 
   const _normalized = util.cached(() => {
     const keys = Object.keys(def.shape);
+    for (const k of keys) {
+      if (!(def.shape[k] instanceof $ZodType)) {
+        throw new Error(`Invalid element at key "${k}": expected a Zod schema`);
+      }
+    }
     const okeys = util.optionalKeys(def.shape);
 
     return {
@@ -1782,7 +1776,7 @@ export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$con
         // }
 
         const r = el._zod.run({ value: input[key], issues: [] }, ctx);
-        const isOptional = el._zod.optin === "optional";
+        const isOptional = el._zod.optin === "optional" && el._zod.optout === "optional";
 
         if (r instanceof Promise) {
           proms.push(
diff --git a/packages/zod/src/v4/core/to-json-schema.ts b/packages/zod/src/v4/core/to-json-schema.ts
index 060298ac..0d25ca04 100644
--- a/packages/zod/src/v4/core/to-json-schema.ts
+++ b/packages/zod/src/v4/core/to-json-schema.ts
@@ -48,11 +48,12 @@ interface EmitParams {
     | undefined;
 }
 
-const formatMap: Partial<Record<checks.$ZodStringFormats, string>> = {
+const formatMap: Partial<Record<checks.$ZodStringFormats, string | undefined>> = {
   guid: "uuid",
   url: "uri",
   datetime: "date-time",
   json_string: "json-string",
+  regex: "", // do not set
 };
 
 interface Seen {
@@ -149,23 +150,28 @@ export class JSONSchemaGenerator {
         case "string": {
           const json: JSONSchema.StringSchema = _json as any;
           json.type = "string";
-          const { minimum, maximum, format, pattern, contentEncoding } = schema._zod.bag as {
-            minimum?: number;
-            maximum?: number;
-            format?: checks.$ZodStringFormats;
-            pattern?: RegExp;
-            contentEncoding?: string;
-          };
+          const { minimum, maximum, format, patterns, contentEncoding } = schema._zod
+            .bag as schemas.$ZodStringInternals<unknown>["bag"];
           if (typeof minimum === "number") json.minLength = minimum;
           if (typeof maximum === "number") json.maxLength = maximum;
           // custom pattern overrides format
           if (format) {
-            json.format = formatMap[format] ?? format;
-          }
-          if (pattern) {
-            json.pattern = pattern.source;
+            json.format = formatMap[format as checks.$ZodStringFormats] ?? format;
+            if (json.format === "") delete json.format; // empty format is not valid
           }
           if (contentEncoding) json.contentEncoding = contentEncoding;
+          if (patterns && patterns.size > 0) {
+            const regexes = [...patterns];
+            if (regexes.length === 1) json.pattern = regexes[0].source;
+            else if (regexes.length > 1) {
+              result.schema.allOf = [
+                ...regexes.map((regex) => ({
+                  ...(this.target === "draft-7" ? { type: "string" } : {}),
+                  pattern: regex.source,
+                })),
+              ];
+            }
+          }
 
           break;
         }
@@ -703,7 +709,16 @@ export class JSONSchemaGenerator {
       flattenRef(entry[0], { target: this.target });
     }
 
-    const result = { ...root.def };
+    const result: JSONSchema.BaseSchema = {};
+    if (this.target === "draft-2020-12") {
+      result.$schema = "https://json-schema.org/draft/2020-12/schema";
+    } else if (this.target === "draft-7") {
+      result.$schema = "http://json-schema.org/draft-07/schema#";
+    } else {
+      console.warn(`Invalid target: ${this.target}`);
+    }
+
+    Object.assign(result, root.def);
 
     const defs: JSONSchema.BaseSchema["$defs"] = params.external?.defs ?? {};
     for (const entry of this.seen.entries()) {
@@ -722,14 +737,6 @@ export class JSONSchemaGenerator {
       }
     }
 
-    if (this.target === "draft-2020-12") {
-      result.$schema = "https://json-schema.org/draft/2020-12/schema";
-    } else if (this.target === "draft-7") {
-      result.$schema = "http://json-schema.org/draft-07/schema#";
-    } else {
-      console.warn(`Invalid target: ${this.target}`);
-    }
-
     try {
       // this "finalizes" this schema and ensures all cycles are removed
       // each call to .emit() is functionally independent
diff --git a/packages/zod/src/v4/core/util.ts b/packages/zod/src/v4/core/util.ts
index 0537bfc4..9431471e 100644
--- a/packages/zod/src/v4/core/util.ts
+++ b/packages/zod/src/v4/core/util.ts
@@ -318,7 +318,7 @@ export function esc(str: string): string {
 }
 
 export function isObject(data: any): data is Record<PropertyKey, unknown> {
-  return typeof data === "object" && data !== null;
+  return typeof data === "object" && data !== null && !Array.isArray(data);
 }
 
 export const allowsEval: { value: boolean } = cached(() => {
@@ -489,7 +489,7 @@ export function stringifyPrimitive(value: any): string {
 
 export function optionalKeys(shape: schemas.$ZodShape): string[] {
   return Object.keys(shape).filter((k) => {
-    return shape[k]._zod.optin === "optional";
+    return shape[k]._zod.optin === "optional" && shape[k]._zod.optout === "optional";
   });
 }
 
diff --git a/packages/zod/src/v4/locales/index.ts b/packages/zod/src/v4/locales/index.ts
index 798e7d04..878df5af 100644
--- a/packages/zod/src/v4/locales/index.ts
+++ b/packages/zod/src/v4/locales/index.ts
@@ -15,6 +15,7 @@ export { default as hu } from "./hu.js";
 export { default as id } from "./id.js";
 export { default as it } from "./it.js";
 export { default as ja } from "./ja.js";
+export { default as kh } from "./kh.js";
 export { default as ko } from "./ko.js";
 export { default as mk } from "./mk.js";
 export { default as ms } from "./ms.js";
@@ -24,6 +25,7 @@ export { default as pl } from "./pl.js";
 export { default as pt } from "./pt.js";
 export { default as ru } from "./ru.js";
 export { default as sl } from "./sl.js";
+export { default as sv } from "./sv.js";
 export { default as ta } from "./ta.js";
 export { default as th } from "./th.js";
 export { default as tr } from "./tr.js";
diff --git a/packages/zod/src/v4/locales/kh.ts b/packages/zod/src/v4/locales/kh.ts
new file mode 100644
index 00000000..5d586153
--- /dev/null
+++ b/packages/zod/src/v4/locales/kh.ts
@@ -0,0 +1,126 @@
+import type { $ZodStringFormats } from "../core/checks.js";
+import type * as errors from "../core/errors.js";
+import * as util from "../core/util.js";
+
+const Sizable: Record<string, { unit: string; verb: string }> = {
+  string: { unit: "តួអក្សរ", verb: "គួរមាន" },
+  file: { unit: "បៃ", verb: "គួរមាន" },
+  array: { unit: "ធាតុ", verb: "គួរមាន" },
+  set: { unit: "ធាតុ", verb: "គួរមាន" },
+};
+
+function getSizing(origin: string): { unit: string; verb: string } | null {
+  return Sizable[origin] ?? null;
+}
+
+export const parsedType = (data: any): string => {
+  const t = typeof data;
+
+  switch (t) {
+    case "number": {
+      return Number.isNaN(data) ? "មិនមែនជាលេខ (NaN)" : "លេខ";
+    }
+    case "object": {
+      if (Array.isArray(data)) {
+        return "អារេ (Array)";
+      }
+      if (data === null) {
+        return "គ្មានតម្លៃ (null)";
+      }
+
+      if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) {
+        return data.constructor.name;
+      }
+    }
+  }
+  return t;
+};
+
+const Nouns: {
+  [k in $ZodStringFormats | (string & {})]?: string;
+} = {
+  regex: "ទិន្នន័យបញ្ចូល",
+  email: "អាសយដ្ឋានអ៊ីមែល",
+  url: "URL",
+  emoji: "សញ្ញាអារម្មណ៍",
+  uuid: "UUID",
+  uuidv4: "UUIDv4",
+  uuidv6: "UUIDv6",
+  nanoid: "nanoid",
+  guid: "GUID",
+  cuid: "cuid",
+  cuid2: "cuid2",
+  ulid: "ULID",
+  xid: "XID",
+  ksuid: "KSUID",
+  datetime: "កាលបរិច្ឆេទ និងម៉ោង ISO",
+  date: "កាលបរិច្ឆេទ ISO",
+  time: "ម៉ោង ISO",
+  duration: "រយៈពេល ISO",
+  ipv4: "អាសយដ្ឋាន IPv4",
+  ipv6: "អាសយដ្ឋាន IPv6",
+  cidrv4: "ដែនអាសយដ្ឋាន IPv4",
+  cidrv6: "ដែនអាសយដ្ឋាន IPv6",
+  base64: "ខ្សែអក្សរអ៊ិកូដ base64",
+  base64url: "ខ្សែអក្សរអ៊ិកូដ base64url",
+  json_string: "ខ្សែអក្សរ JSON",
+  e164: "លេខ E.164",
+  jwt: "JWT",
+  template_literal: "ទិន្នន័យបញ្ចូល",
+};
+
+const error: errors.$ZodErrorMap = (issue) => {
+  switch (issue.code) {
+    case "invalid_type":
+      return `ទិន្នន័យបញ្ចូលមិនត្រឹមត្រូវ៖ ត្រូវការ ${issue.expected} ប៉ុន្តែទទួលបាន ${parsedType(issue.input)}`;
+    case "invalid_value":
+      if (issue.values.length === 1) return `ទិន្នន័យបញ្ចូលមិនត្រឹមត្រូវ៖ ត្រូវការ ${util.stringifyPrimitive(issue.values[0])}`;
+      return `ជម្រើសមិនត្រឹមត្រូវ៖ ត្រូវជាមួយក្នុងចំណោម ${util.joinValues(issue.values, "|")}`;
+    case "too_big": {
+      const adj = issue.inclusive ? "<=" : "<";
+      const sizing = getSizing(issue.origin);
+      if (sizing)
+        return `ធំពេក៖ ត្រូវការ ${issue.origin ?? "តម្លៃ"} ${adj} ${issue.maximum.toString()} ${sizing.unit ?? "ធាតុ"}`;
+      return `ធំពេក៖ ត្រូវការ ${issue.origin ?? "តម្លៃ"} ${adj} ${issue.maximum.toString()}`;
+    }
+    case "too_small": {
+      const adj = issue.inclusive ? ">=" : ">";
+      const sizing = getSizing(issue.origin);
+      if (sizing) {
+        return `តូចពេក៖ ត្រូវការ ${issue.origin} ${adj} ${issue.minimum.toString()} ${sizing.unit}`;
+      }
+
+      return `តូចពេក៖ ត្រូវការ ${issue.origin} ${adj} ${issue.minimum.toString()}`;
+    }
+    case "invalid_format": {
+      const _issue = issue as errors.$ZodStringFormatIssues;
+      if (_issue.format === "starts_with") {
+        return `ខ្សែអក្សរមិនត្រឹមត្រូវ៖ ត្រូវចាប់ផ្តើមដោយ "${_issue.prefix}"`;
+      }
+      if (_issue.format === "ends_with") return `ខ្សែអក្សរមិនត្រឹមត្រូវ៖ ត្រូវបញ្ចប់ដោយ "${_issue.suffix}"`;
+      if (_issue.format === "includes") return `ខ្សែអក្សរមិនត្រឹមត្រូវ៖ ត្រូវមាន "${_issue.includes}"`;
+      if (_issue.format === "regex") return `ខ្សែអក្សរមិនត្រឹមត្រូវ៖ ត្រូវតែផ្គូផ្គងនឹងទម្រង់ដែលបានកំណត់ ${_issue.pattern}`;
+      return `មិនត្រឹមត្រូវ៖ ${Nouns[_issue.format] ?? issue.format}`;
+    }
+    case "not_multiple_of":
+      return `លេខមិនត្រឹមត្រូវ៖ ត្រូវតែជាពហុគុណនៃ ${issue.divisor}`;
+    case "unrecognized_keys":
+      return `រកឃើញសោមិនស្គាល់៖ ${util.joinValues(issue.keys, ", ")}`;
+    case "invalid_key":
+      return `សោមិនត្រឹមត្រូវនៅក្នុង ${issue.origin}`;
+    case "invalid_union":
+      return `ទិន្នន័យមិនត្រឹមត្រូវ`;
+    case "invalid_element":
+      return `ទិន្នន័យមិនត្រឹមត្រូវនៅក្នុង ${issue.origin}`;
+    default:
+      return `ទិន្នន័យមិនត្រឹមត្រូវ`;
+  }
+};
+
+export { error };
+
+export default function (): { localeError: errors.$ZodErrorMap } {
+  return {
+    localeError: error,
+  };
+}
diff --git a/packages/zod/src/v4/locales/sv.ts b/packages/zod/src/v4/locales/sv.ts
new file mode 100644
index 00000000..588e5708
--- /dev/null
+++ b/packages/zod/src/v4/locales/sv.ts
@@ -0,0 +1,126 @@
+import type { $ZodStringFormats } from "../core/checks.js";
+import type * as errors from "../core/errors.js";
+import * as util from "../core/util.js";
+
+const Sizable: Record<string, { unit: string; verb: string }> = {
+  string: { unit: "tecken", verb: "att ha" },
+  file: { unit: "bytes", verb: "att ha" },
+  array: { unit: "objekt", verb: "att innehålla" },
+  set: { unit: "objekt", verb: "att innehålla" },
+};
+
+function getSizing(origin: string): { unit: string; verb: string } | null {
+  return Sizable[origin] ?? null;
+}
+
+export const parsedType = (data: any): string => {
+  const t = typeof data;
+
+  switch (t) {
+    case "number": {
+      return Number.isNaN(data) ? "NaN" : "antal";
+    }
+    case "object": {
+      if (Array.isArray(data)) {
+        return "lista";
+      }
+      if (data === null) {
+        return "null";
+      }
+
+      if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) {
+        return data.constructor.name;
+      }
+    }
+  }
+  return t;
+};
+
+const Nouns: {
+  [k in $ZodStringFormats | (string & {})]?: string;
+} = {
+  regex: "reguljärt uttryck",
+  email: "e-postadress",
+  url: "URL",
+  emoji: "emoji",
+  uuid: "UUID",
+  uuidv4: "UUIDv4",
+  uuidv6: "UUIDv6",
+  nanoid: "nanoid",
+  guid: "GUID",
+  cuid: "cuid",
+  cuid2: "cuid2",
+  ulid: "ULID",
+  xid: "XID",
+  ksuid: "KSUID",
+  datetime: "ISO-datum och tid",
+  date: "ISO-datum",
+  time: "ISO-tid",
+  duration: "ISO-varaktighet",
+  ipv4: "IPv4-intervall",
+  ipv6: "IPv6-intervall",
+  cidrv4: "IPv4-spektrum",
+  cidrv6: "IPv6-spektrum",
+  base64: "base64-kodad sträng",
+  base64url: "base64url-kodad sträng",
+  json_string: "JSON-sträng",
+  e164: "E.164-nummer",
+  jwt: "JWT",
+  template_literal: "mall-literal",
+};
+
+const error: errors.$ZodErrorMap = (issue) => {
+  switch (issue.code) {
+    case "invalid_type":
+      return `Ogiltig inmatning: förväntat ${issue.expected}, fick ${parsedType(issue.input)}`;
+    case "invalid_value":
+      if (issue.values.length === 1) return `Ogiltig inmatning: förväntat ${util.stringifyPrimitive(issue.values[0])}`;
+      return `Ogiltigt val: förväntade en av ${util.joinValues(issue.values, "|")}`;
+    case "too_big": {
+      const adj = issue.inclusive ? "<=" : "<";
+      const sizing = getSizing(issue.origin);
+      if (sizing) {
+        return `För stor(t): förväntade ${issue.origin ?? "värdet"} att ha ${adj}${issue.maximum.toString()} ${sizing.unit ?? "element"}`;
+      }
+      return `För stor(t): förväntat ${issue.origin ?? "värdet"} att ha ${adj}${issue.maximum.toString()}`;
+    }
+    case "too_small": {
+      const adj = issue.inclusive ? ">=" : ">";
+      const sizing = getSizing(issue.origin);
+      if (sizing) {
+        return `För lite(t): förväntade ${issue.origin ?? "värdet"} att ha ${adj}${issue.minimum.toString()} ${sizing.unit}`;
+      }
+      return `För lite(t): förväntade ${issue.origin ?? "värdet"} att ha ${adj}${issue.minimum.toString()}`;
+    }
+    case "invalid_format": {
+      const _issue = issue as errors.$ZodStringFormatIssues;
+      if (_issue.format === "starts_with") {
+        return `Ogiltig sträng: måste börja med "${_issue.prefix}"`;
+      }
+      if (_issue.format === "ends_with") return `Ogiltig sträng: måste sluta med "${_issue.suffix}"`;
+      if (_issue.format === "includes") return `Ogiltig sträng: måste innehålla "${_issue.includes}"`;
+      if (_issue.format === "regex") return `Ogiltig sträng: måste matcha mönstret "${_issue.pattern}"`;
+      return `Ogiltig(t) ${Nouns[_issue.format] ?? issue.format}`;
+    }
+    case "not_multiple_of":
+      return `Ogiltigt tal: måste vara en multipel av ${issue.divisor}`;
+    case "unrecognized_keys":
+      return `${issue.keys.length > 1 ? "Okända nycklar" : "Okänd nyckel"}: ${util.joinValues(issue.keys, ", ")}`;
+    case "invalid_key":
+      return `Ogiltig nyckel i ${issue.origin ?? "värdet"}`;
+    case "invalid_union":
+      return "Ogiltig input";
+    case "invalid_element":
+      return `Ogiltigt värde i ${issue.origin ?? "värdet"}`;
+    default:
+      return `Ogiltig input`;
+  }
+};
+
+export { error };
+
+export default function (): { localeError: errors.$ZodErrorMap } {
+  return {
+    localeError: error,
+  };
+}
diff --git a/packages/zod/src/v4/mini/schemas.ts b/packages/zod/src/v4/mini/schemas.ts
index 7d1cec37..71f439f9 100644
--- a/packages/zod/src/v4/mini/schemas.ts
+++ b/packages/zod/src/v4/mini/schemas.ts
@@ -1500,7 +1500,7 @@ function _instanceof<T extends typeof Class>(
   params: core.$ZodCustomParams = {
     error: `Input not instance of ${cls.name}`,
   }
-): ZodMiniCustom<InstanceType<T>> {
+): ZodMiniCustom<InstanceType<T>, InstanceType<T>> {
   const inst = custom((data) => data instanceof cls, params);
   inst._zod.bag.Class = cls;
   return inst as any;
diff --git a/play.ts b/play.ts
index fcc1a10b..a565b160 100644
--- a/play.ts
+++ b/play.ts
@@ -1,13 +1,3 @@
-import * as z from "zod/v4";
+import { z } from "zod/v4";
 
-export const a = z.object({
-  asdf: z.iso.datetime(),
-});
-
-const fn = z.function({
-  // input: z.tuple([z.string()], z.number()),
-  output: z.string(),
-});
-
-fn.def.output;
-fn.def.input;
+console.dir(z.string(), { depth: null });
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a8632891..50199364 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -114,8 +114,8 @@ importers:
   packages/docs:
     dependencies:
       '@inkeep/cxkit-react':
-        specifier: ^0.5.52
-        version: 0.5.52(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@3.24.3)
+        specifier: ^0.5.80
+        version: 0.5.80(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@packages+zod)
       '@radix-ui/react-accordion':
         specifier: ^1.2.4
         version: 1.2.4(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -323,6 +323,10 @@ packages:
     resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==}
     engines: {node: '>=6.9.0'}
 
+  '@babel/runtime@7.27.1':
+    resolution: {integrity: sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==}
+    engines: {node: '>=6.9.0'}
+
   '@babel/types@7.27.1':
     resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==}
     engines: {node: '>=6.9.0'}
@@ -963,26 +967,26 @@ packages:
     cpu: [x64]
     os: [win32]
 
-  '@inkeep/cxkit-color-mode@0.5.52':
-    resolution: {integrity: sha512-Mm9ax+2yP+T4F9ICP2eQqqpnm1BaiVUbmuhOF3oNOEQVR8X9sENeSU6X6JIJnFKtVSXYb/AMRe1U4/c5wJzvww==}
+  '@inkeep/cxkit-color-mode@0.5.80':
+    resolution: {integrity: sha512-sT1F0/wWL4I3SqpAMoYVe/9TiMKejPbmBuzXOkMDOsfYuFfaTRlMT3BZu646sguVmwAS5OC7S1FddanwLD60jg==}
 
-  '@inkeep/cxkit-primitives@0.5.52':
-    resolution: {integrity: sha512-xq5ZGC8RX9qhelIbAvRM3EN7cFuwjYUERsoH6cwgyjtk5PnN3HoChlxuA18x1v9mqp8Bv3/lu4Bz0TDNUdiSxQ==}
+  '@inkeep/cxkit-primitives@0.5.80':
+    resolution: {integrity: sha512-ivzGbXUrycTwbQzcYlFUdFACexbt4HgkPPEQl8KJHpWCUQ5xZIhnyGDDSZmdFIlmKMlLFLEP00q7zUbQseqUqw==}
     peerDependencies:
       react: '>=17.0.0'
       react-dom: '>=17.0.0'
 
-  '@inkeep/cxkit-react@0.5.52':
-    resolution: {integrity: sha512-kNa+cvjH/JrWHVTh9DcYTgX/J6J4h2tyOh7FvK41zvbdKuAOarzQGWJMLvmAsDm4Z4tmPe104Yvm3nrmsrfTOA==}
+  '@inkeep/cxkit-react@0.5.80':
+    resolution: {integrity: sha512-fVYBv0OjUg94/70+HTZSyWotUnM/WDJt32fbZ5/7BxB6ZN0O2JlN3D9TKo1S8CFOMHg5flp0+W4VeeWXDk9d4w==}
 
-  '@inkeep/cxkit-styled@0.5.52':
-    resolution: {integrity: sha512-QLtJJ+/ufNG3PqrSMfwHSKWwOhnB4i0qOhsrNiAyNcOtQ5fMZdaAlShAjHDH2ye68sfw2tsyEBxXgZuxHji9dw==}
+  '@inkeep/cxkit-styled@0.5.80':
+    resolution: {integrity: sha512-ZlJwEegL8MCIx3pVapj32AOV2AWROWC+uBKjM/vvnGWhg5fNnQx40p90RnDCWF5H5fgmlP7PS8r1CmN0lVtwug==}
 
-  '@inkeep/cxkit-theme@0.5.52':
-    resolution: {integrity: sha512-2MWJc+J2n1d4gWkB3A+g4ZSmWxvi/nqxAgEOquiDDWWTrTWCEI8uk8MsWubtCBa73aEOa/tMTKiGYGjbdSCpgw==}
+  '@inkeep/cxkit-theme@0.5.80':
+    resolution: {integrity: sha512-7wwjczUz7deEP8V3uY1+YnUaVIhwBs8om9/N10jP2Vh9kkpEIZELSCwPS7QeKeY0FpIB0WgUNwDUcN4yrZ3EnA==}
 
-  '@inkeep/cxkit-types@0.5.52':
-    resolution: {integrity: sha512-2AwsCpeB37wU8I+uhMsP2wFu/8goodgTvqL/V/QIaTGDBw62E1qsA6kjt+5V7rzkLzR658aSUOtL9D1G9zc31Q==}
+  '@inkeep/cxkit-types@0.5.80':
+    resolution: {integrity: sha512-Vpr/yTritQ0Fyy7GvxWTYpAHMn3Iee7xyZykR0Bv0aMNaB4XKq8eVXsueVxz4pgJao+inOU6GzrSflK8QBGJYw==}
 
   '@isaacs/cliui@8.0.2':
     resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
@@ -1244,6 +1248,9 @@ packages:
   '@radix-ui/number@1.1.0':
     resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==}
 
+  '@radix-ui/number@1.1.1':
+    resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==}
+
   '@radix-ui/primitive@1.1.1':
     resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==}
 
@@ -1289,6 +1296,19 @@ packages:
       '@types/react-dom':
         optional: true
 
+  '@radix-ui/react-arrow@1.1.7':
+    resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==}
+    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-avatar@1.1.2':
     resolution: {integrity: sha512-GaC7bXQZ5VgZvVvsJ5mu/AEbjYLnhhkoidOboC50Z6FFlLA03wG2ianUoH+zgDQ31/9gCF59bE4+2bBgTyMiig==}
     peerDependencies:
@@ -1341,8 +1361,8 @@ packages:
       '@types/react-dom':
         optional: true
 
-  '@radix-ui/react-collection@1.1.1':
-    resolution: {integrity: sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==}
+  '@radix-ui/react-collection@1.1.2':
+    resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==}
     peerDependencies:
       '@types/react': '*'
       '@types/react-dom': '*'
@@ -1354,8 +1374,8 @@ packages:
       '@types/react-dom':
         optional: true
 
-  '@radix-ui/react-collection@1.1.2':
-    resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==}
+  '@radix-ui/react-collection@1.1.3':
+    resolution: {integrity: sha512-mM2pxoQw5HJ49rkzwOs7Y6J4oYH22wS8BfK2/bBxROlI4xuR0c4jEenQP63LlTlDkO6Buj2Vt+QYAYcOgqtrXA==}
     peerDependencies:
       '@types/react': '*'
       '@types/react-dom': '*'
@@ -1367,8 +1387,8 @@ packages:
       '@types/react-dom':
         optional: true
 
-  '@radix-ui/react-collection@1.1.3':
-    resolution: {integrity: sha512-mM2pxoQw5HJ49rkzwOs7Y6J4oYH22wS8BfK2/bBxROlI4xuR0c4jEenQP63LlTlDkO6Buj2Vt+QYAYcOgqtrXA==}
+  '@radix-ui/react-collection@1.1.7':
+    resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==}
     peerDependencies:
       '@types/react': '*'
       '@types/react-dom': '*'
@@ -1447,6 +1467,19 @@ packages:
       '@types/react':
         optional: true
 
+  '@radix-ui/react-dismissable-layer@1.1.10':
+    resolution: {integrity: sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==}
+    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-dismissable-layer@1.1.3':
     resolution: {integrity: sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==}
     peerDependencies:
@@ -1482,6 +1515,15 @@ packages:
       '@types/react':
         optional: true
 
+  '@radix-ui/react-focus-guards@1.1.2':
+    resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==}
+    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.2':
     resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==}
     peerDependencies:
@@ -1495,8 +1537,21 @@ packages:
       '@types/react-dom':
         optional: true
 
-  '@radix-ui/react-hover-card@1.1.6':
-    resolution: {integrity: sha512-E4ozl35jq0VRlrdc4dhHrNSV0JqBb4Jy73WAhBEK7JoYnQ83ED5r0Rb/XdVKw89ReAJN38N492BAPBZQ57VmqQ==}
+  '@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-hover-card@1.1.14':
+    resolution: {integrity: sha512-CPYZ24Mhirm+g6D8jArmLzjYu4Eyg3TTUHswR26QgzXBHBe64BO/RHOJKzmF/Dxb4y4f9PKyJdwm/O/AhNkb+Q==}
     peerDependencies:
       '@types/react': '*'
       '@types/react-dom': '*'
@@ -1578,6 +1633,19 @@ packages:
       '@types/react-dom':
         optional: true
 
+  '@radix-ui/react-popper@1.2.7':
+    resolution: {integrity: sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==}
+    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.3':
     resolution: {integrity: sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==}
     peerDependencies:
@@ -1604,6 +1672,19 @@ packages:
       '@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.2':
     resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==}
     peerDependencies:
@@ -1630,6 +1711,19 @@ packages:
       '@types/react-dom':
         optional: true
 
+  '@radix-ui/react-presence@1.1.4':
+    resolution: {integrity: sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==}
+    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.0.1':
     resolution: {integrity: sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==}
     peerDependencies:
@@ -1669,8 +1763,21 @@ packages:
       '@types/react-dom':
         optional: true
 
-  '@radix-ui/react-roving-focus@1.1.1':
-    resolution: {integrity: sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==}
+  '@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.10':
+    resolution: {integrity: sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==}
     peerDependencies:
       '@types/react': '*'
       '@types/react-dom': '*'
@@ -1721,8 +1828,8 @@ packages:
       '@types/react-dom':
         optional: true
 
-  '@radix-ui/react-select@2.1.6':
-    resolution: {integrity: sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==}
+  '@radix-ui/react-select@2.2.5':
+    resolution: {integrity: sha512-HnMTdXEVuuyzx63ME0ut4+sEMYW6oouHWNGUZc7ddvUWIcfCva/AMoqEW/3wnEllriMWBa0RHspCYnfCWJQYmA==}
     peerDependencies:
       '@types/react': '*'
       '@types/react-dom': '*'
@@ -1761,8 +1868,17 @@ packages:
       '@types/react':
         optional: true
 
-  '@radix-ui/react-tabs@1.1.2':
-    resolution: {integrity: sha512-9u/tQJMcC2aGq7KXpGivMm1mgq7oRJKXphDwdypPd/j21j/2znamPU8WkXgnhUaTrSFNIt8XhOyCAupg8/GbwQ==}
+  '@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-tabs@1.1.12':
+    resolution: {integrity: sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==}
     peerDependencies:
       '@types/react': '*'
       '@types/react-dom': '*'
@@ -1836,6 +1952,24 @@ packages:
       '@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.0':
     resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==}
     peerDependencies:
@@ -1845,6 +1979,15 @@ packages:
       '@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.0':
     resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
     peerDependencies:
@@ -1872,6 +2015,15 @@ packages:
       '@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.0':
     resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==}
     peerDependencies:
@@ -1881,6 +2033,15 @@ packages:
       '@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.0':
     resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==}
     peerDependencies:
@@ -1890,6 +2051,15 @@ packages:
       '@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.1.1':
     resolution: {integrity: sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==}
     peerDependencies:
@@ -1916,9 +2086,25 @@ packages:
       '@types/react-dom':
         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.0':
     resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==}
 
+  '@radix-ui/rect@1.1.1':
+    resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
+
   '@resvg/resvg-wasm@2.4.0':
     resolution: {integrity: sha512-C7c51Nn4yTxXFKvgh2txJFNweaVcfUPQxwEUFw4aWsCmfiBDJsTSwviIF8EcwjQ6k8bPyMWCl1vw4BdxE569Cg==}
     engines: {node: '>= 10'}
@@ -2447,8 +2633,8 @@ packages:
   '@types/node-fetch@2.6.12':
     resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==}
 
-  '@types/node@18.19.86':
-    resolution: {integrity: sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ==}
+  '@types/node@18.19.103':
+    resolution: {integrity: sha512-hHTHp+sEz6SxFsp+SA+Tqrua3AbmlAw+Y//aEwdHrdZkYVRWdvWD3y5uPZ0flYOkgskaFWqZ/YGFm3FaFQ0pRw==}
 
   '@types/node@20.17.30':
     resolution: {integrity: sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==}
@@ -2560,14 +2746,14 @@ packages:
   '@web-std/stream@1.0.0':
     resolution: {integrity: sha512-jyIbdVl+0ZJyKGTV0Ohb9E6UnxP+t7ZzX4Do3AHjZKxUXKMs9EmqnBDQgHF7bEw0EzbQygOjtt/7gvtmi//iCQ==}
 
-  '@zag-js/dom-query@1.8.2':
-    resolution: {integrity: sha512-bn6Pxga19PJzpDb+Oh326kn1sgVfO97mxRzRFqzrKz9NuANGlCblmv2NTYmhfppqE1nt9QyLLhyQ2BLbzwouLg==}
+  '@zag-js/dom-query@1.13.0':
+    resolution: {integrity: sha512-NMYNufLpfZwDWFipxgbkB0+N8UGH5KqLmhf2sC9pMqASE30E7LrOJTPtdbbwmxqZdpZNfxlVmNiZsXFFEP1Dzg==}
 
-  '@zag-js/focus-trap@1.8.2':
-    resolution: {integrity: sha512-GzKdicdiVjlOOsNzmmRAZVccs902PXnoyO+qkzXlIsr8+RPRgtPlZthIp6wtr4CJ2vLOMByvrEt7wCNSIoDzxA==}
+  '@zag-js/focus-trap@1.13.0':
+    resolution: {integrity: sha512-lPMruEcNx5VqUXhZiqsZjtTOzV1ZPRtnCmRTsqsfo3nhxysN3qVkxEhOmb9DigdWYzcZYy3xMjHvMdzg3s+4hA==}
 
-  '@zag-js/types@1.8.2':
-    resolution: {integrity: sha512-J+94HhFAPOBchNdGcmvqjB8nbQFgKHcqGoPl5vNTKlcoibN0yFjn4XFZoQU6uCf8sPhNg6NUNTkluR5YjybyJA==}
+  '@zag-js/types@1.13.0':
+    resolution: {integrity: sha512-l7zcdIAXTdtS9x8866HgZ4/T2s30Tawpw/y5J4usQnCPgUBLMDnAbtVNL/kHrMNNlj9//lLYzXtu8sN2tUrrOA==}
 
   '@zod/core@0.8.1':
     resolution: {integrity: sha512-djj8hPhxIHcG8ptxITaw/Bout5HJZ9NyRbKr95Eilqwt9R0kvITwUQGDU+n+MVdsBIka5KwztmZSLti22F+P0A==}
@@ -2687,6 +2873,10 @@ packages:
     resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
     engines: {node: '>=10'}
 
+  aria-hidden@1.2.6:
+    resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
+    engines: {node: '>=10'}
+
   arktype@2.1.19:
     resolution: {integrity: sha512-notORSuTSpfLV7rq0kYC4mTgIVlVR0xQuvtFxOaE9aKiXyON/kgoIBwZZcKeSSb4BebNcfJoGlxJicAUl/HMdw==}
 
@@ -2773,10 +2963,6 @@ packages:
     resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==}
     engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 
-  call-bind-apply-helpers@1.0.1:
-    resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==}
-    engines: {node: '>= 0.4'}
-
   call-bind-apply-helpers@1.0.2:
     resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
     engines: {node: '>= 0.4'}
@@ -3115,8 +3301,8 @@ packages:
     resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==}
     engines: {node: '>=8.6'}
 
-  entities@4.5.0:
-    resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+  entities@6.0.0:
+    resolution: {integrity: sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==}
     engines: {node: '>=0.12'}
 
   env-paths@2.2.1:
@@ -3385,10 +3571,6 @@ packages:
     resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
     engines: {node: 6.* || 8.* || >= 10.*}
 
-  get-intrinsic@1.2.7:
-    resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==}
-    engines: {node: '>= 0.4'}
-
   get-intrinsic@1.3.0:
     resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
     engines: {node: '>= 0.4'}
@@ -3955,6 +4137,11 @@ packages:
     peerDependencies:
       react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
 
+  lucide-react@0.503.0:
+    resolution: {integrity: sha512-HGGkdlPWQ0vTF8jJ5TdIqhQXZi6uh3LnNgfZ8MHiuxFfX3RZeA79r2MW2tHAZKlAVfoNE8esm3p+O6VkIvpj6w==}
+    peerDependencies:
+      react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
   magic-string@0.30.17:
     resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
 
@@ -3979,6 +4166,11 @@ packages:
     peerDependencies:
       marked: '>=1 <16'
 
+  marked@15.0.12:
+    resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==}
+    engines: {node: '>= 18'}
+    hasBin: true
+
   marked@9.1.6:
     resolution: {integrity: sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==}
     engines: {node: '>= 16'}
@@ -4446,8 +4638,8 @@ packages:
   parse5@6.0.1:
     resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==}
 
-  parse5@7.2.1:
-    resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==}
+  parse5@7.3.0:
+    resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
 
   path-browserify@1.0.1:
     resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
@@ -4574,6 +4766,9 @@ packages:
   property-information@7.0.0:
     resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
 
+  property-information@7.1.0:
+    resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
+
   quansync@0.2.10:
     resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==}
 
@@ -4588,17 +4783,17 @@ packages:
     peerDependencies:
       react: ^19.0.0
 
+  react-error-boundary@6.0.0:
+    resolution: {integrity: sha512-gdlJjD7NWr0IfkPlaREN2d9uUZUlksrfOx7SX62VRerwXbMY6ftGCIZua1VG1aXFNOimhISsTq+Owp725b9SiA==}
+    peerDependencies:
+      react: '>=16.13.1'
+
   react-hook-form@7.54.2:
     resolution: {integrity: sha512-eHpAUgUjWbZocoQYUHposymRb4ZP6d0uwUnooL2uOybA9/3tPUvoAKqEWK1WaSiTxxOfTpffNZP7QwlnM3/gEg==}
     engines: {node: '>=18.0.0'}
     peerDependencies:
       react: ^16.8.0 || ^17 || ^18 || ^19
 
-  react-icons@5.4.0:
-    resolution: {integrity: sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==}
-    peerDependencies:
-      react: '*'
-
   react-is@16.13.1:
     resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
 
@@ -4723,6 +4918,9 @@ packages:
   remark-rehype@11.1.1:
     resolution: {integrity: sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==}
 
+  remark-rehype@11.1.2:
+    resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
+
   remark-stringify@11.0.0:
     resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
 
@@ -5323,8 +5521,8 @@ packages:
       '@types/react':
         optional: true
 
-  use-isomorphic-layout-effect@1.2.0:
-    resolution: {integrity: sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==}
+  use-isomorphic-layout-effect@1.2.1:
+    resolution: {integrity: sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==}
     peerDependencies:
       '@types/react': '*'
       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
@@ -5643,6 +5841,8 @@ snapshots:
     dependencies:
       regenerator-runtime: 0.14.1
 
+  '@babel/runtime@7.27.1': {}
+
   '@babel/types@7.27.1':
     dependencies:
       '@babel/helper-string-parser': 7.27.1
@@ -6026,46 +6226,48 @@ snapshots:
   '@img/sharp-win32-x64@0.33.5':
     optional: true
 
-  '@inkeep/cxkit-color-mode@0.5.52': {}
+  '@inkeep/cxkit-color-mode@0.5.80': {}
 
-  '@inkeep/cxkit-primitives@0.5.52(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@3.24.3)':
+  '@inkeep/cxkit-primitives@0.5.80(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@packages+zod)':
     dependencies:
-      '@inkeep/cxkit-color-mode': 0.5.52
-      '@inkeep/cxkit-theme': 0.5.52
-      '@inkeep/cxkit-types': 0.5.52
-      '@radix-ui/primitive': 1.1.1
+      '@inkeep/cxkit-color-mode': 0.5.80
+      '@inkeep/cxkit-theme': 0.5.80
+      '@inkeep/cxkit-types': 0.5.80
+      '@radix-ui/primitive': 1.1.2
       '@radix-ui/react-avatar': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
       '@radix-ui/react-checkbox': 1.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-context': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-hover-card': 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-id': 1.1.0(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-context': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-hover-card': 1.1.14(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-id': 1.1.1(@types/react@19.0.11)(react@19.0.0)
       '@radix-ui/react-popover': 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
       '@radix-ui/react-scroll-area': 1.2.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-select': 2.1.6(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-slot': 1.1.2(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-tabs': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-select': 2.2.5(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-slot': 1.2.3(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-tabs': 1.1.12(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
       '@radix-ui/react-tooltip': 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.11)(react@19.0.0)
       '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@zag-js/focus-trap': 1.8.2
+      '@zag-js/focus-trap': 1.13.0
       altcha-lib: 1.2.0
-      aria-hidden: 1.2.4
+      aria-hidden: 1.2.6
       dequal: 2.0.3
       humps: 2.0.1
+      lucide-react: 0.503.0(react@19.0.0)
+      marked: 15.0.12
       merge-anything: 5.1.7
-      openai: 4.78.1(encoding@0.1.13)(zod@3.24.3)
+      openai: 4.78.1(encoding@0.1.13)(zod@packages+zod)
       prism-react-renderer: 2.4.1(react@19.0.0)
       react: 19.0.0
       react-dom: 19.0.0(react@19.0.0)
+      react-error-boundary: 6.0.0(react@19.0.0)
       react-hook-form: 7.54.2(react@19.0.0)
-      react-icons: 5.4.0(react@19.0.0)
       react-markdown: 9.0.3(@types/react@19.0.11)(react@19.0.0)
       react-remove-scroll: 2.6.3(@types/react@19.0.11)(react@19.0.0)
       react-svg: 16.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -6081,10 +6283,11 @@ snapshots:
       - supports-color
       - zod
 
-  '@inkeep/cxkit-react@0.5.52(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@3.24.3)':
+  '@inkeep/cxkit-react@0.5.80(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@packages+zod)':
     dependencies:
-      '@inkeep/cxkit-styled': 0.5.52(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@3.24.3)
+      '@inkeep/cxkit-styled': 0.5.80(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@packages+zod)
       '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.11)(react@19.0.0)
+      lucide-react: 0.503.0(react@19.0.0)
     transitivePeerDependencies:
       - '@types/react'
       - '@types/react-dom'
@@ -6094,9 +6297,9 @@ snapshots:
       - supports-color
       - zod
 
-  '@inkeep/cxkit-styled@0.5.52(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@3.24.3)':
+  '@inkeep/cxkit-styled@0.5.80(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@packages+zod)':
     dependencies:
-      '@inkeep/cxkit-primitives': 0.5.52(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@3.24.3)
+      '@inkeep/cxkit-primitives': 0.5.80(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(encoding@0.1.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(zod@packages+zod)
       class-variance-authority: 0.7.1
       clsx: 2.1.1
       merge-anything: 5.1.7
@@ -6110,11 +6313,11 @@ snapshots:
       - supports-color
       - zod
 
-  '@inkeep/cxkit-theme@0.5.52':
+  '@inkeep/cxkit-theme@0.5.80':
     dependencies:
       colorjs.io: 0.5.2
 
-  '@inkeep/cxkit-types@0.5.52': {}
+  '@inkeep/cxkit-types@0.5.80': {}
 
   '@isaacs/cliui@8.0.2':
     dependencies:
@@ -6437,6 +6640,8 @@ snapshots:
 
   '@radix-ui/number@1.1.0': {}
 
+  '@radix-ui/number@1.1.1': {}
+
   '@radix-ui/primitive@1.1.1': {}
 
   '@radix-ui/primitive@1.1.2': {}
@@ -6476,6 +6681,15 @@ snapshots:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
+  '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+    dependencies:
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      react: 19.0.0
+      react-dom: 19.0.0(react@19.0.0)
+    optionalDependencies:
+      '@types/react': 19.0.11
+      '@types/react-dom': 19.0.4(@types/react@19.0.11)
+
   '@radix-ui/react-avatar@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
       '@radix-ui/react-context': 1.1.1(@types/react@19.0.11)(react@19.0.0)
@@ -6536,36 +6750,36 @@ snapshots:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
-  '@radix-ui/react-collection@1.1.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+  '@radix-ui/react-collection@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
       '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
       '@radix-ui/react-context': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-slot': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-slot': 1.1.2(@types/react@19.0.11)(react@19.0.0)
       react: 19.0.0
       react-dom: 19.0.0(react@19.0.0)
     optionalDependencies:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
-  '@radix-ui/react-collection@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+  '@radix-ui/react-collection@1.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
-      '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-context': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-slot': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-context': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-slot': 1.2.0(@types/react@19.0.11)(react@19.0.0)
       react: 19.0.0
       react-dom: 19.0.0(react@19.0.0)
     optionalDependencies:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
-  '@radix-ui/react-collection@1.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+  '@radix-ui/react-collection@1.1.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
       '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
       '@radix-ui/react-context': 1.1.2(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-slot': 1.2.0(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-slot': 1.2.3(@types/react@19.0.11)(react@19.0.0)
       react: 19.0.0
       react-dom: 19.0.0(react@19.0.0)
     optionalDependencies:
@@ -6630,6 +6844,19 @@ snapshots:
     optionalDependencies:
       '@types/react': 19.0.11
 
+  '@radix-ui/react-dismissable-layer@1.1.10(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+    dependencies:
+      '@radix-ui/primitive': 1.1.2
+      '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      react: 19.0.0
+      react-dom: 19.0.0(react@19.0.0)
+    optionalDependencies:
+      '@types/react': 19.0.11
+      '@types/react-dom': 19.0.4(@types/react@19.0.11)
+
   '@radix-ui/react-dismissable-layer@1.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
       '@radix-ui/primitive': 1.1.1
@@ -6662,6 +6889,12 @@ snapshots:
     optionalDependencies:
       '@types/react': 19.0.11
 
+  '@radix-ui/react-focus-guards@1.1.2(@types/react@19.0.11)(react@19.0.0)':
+    dependencies:
+      react: 19.0.0
+    optionalDependencies:
+      '@types/react': 19.0.11
+
   '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
       '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
@@ -6673,17 +6906,28 @@ snapshots:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
-  '@radix-ui/react-hover-card@1.1.6(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+  '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
-      '@radix-ui/primitive': 1.1.1
-      '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-context': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      react: 19.0.0
+      react-dom: 19.0.0(react@19.0.0)
+    optionalDependencies:
+      '@types/react': 19.0.11
+      '@types/react-dom': 19.0.4(@types/react@19.0.11)
+
+  '@radix-ui/react-hover-card@1.1.14(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+    dependencies:
+      '@radix-ui/primitive': 1.1.2
+      '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-context': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-popper': 1.2.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.0.11)(react@19.0.0)
       react: 19.0.0
       react-dom: 19.0.0(react@19.0.0)
     optionalDependencies:
@@ -6785,6 +7029,24 @@ snapshots:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
+  '@radix-ui/react-popper@1.2.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+    dependencies:
+      '@floating-ui/react-dom': 2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-context': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-rect': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-size': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/rect': 1.1.1
+      react: 19.0.0
+      react-dom: 19.0.0(react@19.0.0)
+    optionalDependencies:
+      '@types/react': 19.0.11
+      '@types/react-dom': 19.0.4(@types/react@19.0.11)
+
   '@radix-ui/react-portal@1.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
       '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -6805,6 +7067,16 @@ snapshots:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
+  '@radix-ui/react-portal@1.1.9(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+    dependencies:
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      react: 19.0.0
+      react-dom: 19.0.0(react@19.0.0)
+    optionalDependencies:
+      '@types/react': 19.0.11
+      '@types/react-dom': 19.0.4(@types/react@19.0.11)
+
   '@radix-ui/react-presence@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
       '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
@@ -6825,6 +7097,16 @@ snapshots:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
+  '@radix-ui/react-presence@1.1.4(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+    dependencies:
+      '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      react: 19.0.0
+      react-dom: 19.0.0(react@19.0.0)
+    optionalDependencies:
+      '@types/react': 19.0.11
+      '@types/react-dom': 19.0.4(@types/react@19.0.11)
+
   '@radix-ui/react-primitive@2.0.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
       '@radix-ui/react-slot': 1.1.1(@types/react@19.0.11)(react@19.0.0)
@@ -6852,17 +7134,26 @@ snapshots:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
-  '@radix-ui/react-roving-focus@1.1.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+  '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
-      '@radix-ui/primitive': 1.1.1
-      '@radix-ui/react-collection': 1.1.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-context': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-direction': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-id': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-slot': 1.2.3(@types/react@19.0.11)(react@19.0.0)
+      react: 19.0.0
+      react-dom: 19.0.0(react@19.0.0)
+    optionalDependencies:
+      '@types/react': 19.0.11
+      '@types/react-dom': 19.0.4(@types/react@19.0.11)
+
+  '@radix-ui/react-roving-focus@1.1.10(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+    dependencies:
+      '@radix-ui/primitive': 1.1.2
+      '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-context': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-direction': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-id': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.0.11)(react@19.0.0)
       react: 19.0.0
       react-dom: 19.0.0(react@19.0.0)
     optionalDependencies:
@@ -6920,28 +7211,28 @@ snapshots:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
-  '@radix-ui/react-select@2.1.6(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+  '@radix-ui/react-select@2.2.5(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
-      '@radix-ui/number': 1.1.0
-      '@radix-ui/primitive': 1.1.1
-      '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-context': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-direction': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-id': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-slot': 1.1.2(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-use-previous': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      aria-hidden: 1.2.4
+      '@radix-ui/number': 1.1.1
+      '@radix-ui/primitive': 1.1.2
+      '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-context': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-direction': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-id': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-popper': 1.2.7(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-slot': 1.2.3(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-previous': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      aria-hidden: 1.2.6
       react: 19.0.0
       react-dom: 19.0.0(react@19.0.0)
       react-remove-scroll: 2.6.3(@types/react@19.0.11)(react@19.0.0)
@@ -6970,16 +7261,23 @@ snapshots:
     optionalDependencies:
       '@types/react': 19.0.11
 
-  '@radix-ui/react-tabs@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+  '@radix-ui/react-slot@1.2.3(@types/react@19.0.11)(react@19.0.0)':
     dependencies:
-      '@radix-ui/primitive': 1.1.1
-      '@radix-ui/react-context': 1.1.1(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-direction': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-id': 1.1.0(@types/react@19.0.11)(react@19.0.0)
-      '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-roving-focus': 1.1.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
-      '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      react: 19.0.0
+    optionalDependencies:
+      '@types/react': 19.0.11
+
+  '@radix-ui/react-tabs@1.1.12(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+    dependencies:
+      '@radix-ui/primitive': 1.1.2
+      '@radix-ui/react-context': 1.1.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-direction': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-id': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.0.11)(react@19.0.0)
       react: 19.0.0
       react-dom: 19.0.0(react@19.0.0)
     optionalDependencies:
@@ -7048,6 +7346,21 @@ snapshots:
     optionalDependencies:
       '@types/react': 19.0.11
 
+  '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.0.11)(react@19.0.0)':
+    dependencies:
+      '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.0.11)(react@19.0.0)
+      '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      react: 19.0.0
+    optionalDependencies:
+      '@types/react': 19.0.11
+
+  '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.0.11)(react@19.0.0)':
+    dependencies:
+      '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      react: 19.0.0
+    optionalDependencies:
+      '@types/react': 19.0.11
+
   '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@19.0.11)(react@19.0.0)':
     dependencies:
       '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.11)(react@19.0.0)
@@ -7055,6 +7368,13 @@ snapshots:
     optionalDependencies:
       '@types/react': 19.0.11
 
+  '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.0.11)(react@19.0.0)':
+    dependencies:
+      '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      react: 19.0.0
+    optionalDependencies:
+      '@types/react': 19.0.11
+
   '@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.11)(react@19.0.0)':
     dependencies:
       react: 19.0.0
@@ -7073,6 +7393,12 @@ snapshots:
     optionalDependencies:
       '@types/react': 19.0.11
 
+  '@radix-ui/react-use-previous@1.1.1(@types/react@19.0.11)(react@19.0.0)':
+    dependencies:
+      react: 19.0.0
+    optionalDependencies:
+      '@types/react': 19.0.11
+
   '@radix-ui/react-use-rect@1.1.0(@types/react@19.0.11)(react@19.0.0)':
     dependencies:
       '@radix-ui/rect': 1.1.0
@@ -7080,6 +7406,13 @@ snapshots:
     optionalDependencies:
       '@types/react': 19.0.11
 
+  '@radix-ui/react-use-rect@1.1.1(@types/react@19.0.11)(react@19.0.0)':
+    dependencies:
+      '@radix-ui/rect': 1.1.1
+      react: 19.0.0
+    optionalDependencies:
+      '@types/react': 19.0.11
+
   '@radix-ui/react-use-size@1.1.0(@types/react@19.0.11)(react@19.0.0)':
     dependencies:
       '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.11)(react@19.0.0)
@@ -7087,6 +7420,13 @@ snapshots:
     optionalDependencies:
       '@types/react': 19.0.11
 
+  '@radix-ui/react-use-size@1.1.1(@types/react@19.0.11)(react@19.0.0)':
+    dependencies:
+      '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.0.11)(react@19.0.0)
+      react: 19.0.0
+    optionalDependencies:
+      '@types/react': 19.0.11
+
   '@radix-ui/react-visually-hidden@1.1.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
       '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -7105,8 +7445,19 @@ snapshots:
       '@types/react': 19.0.11
       '@types/react-dom': 19.0.4(@types/react@19.0.11)
 
+  '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+    dependencies:
+      '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+      react: 19.0.0
+      react-dom: 19.0.0(react@19.0.0)
+    optionalDependencies:
+      '@types/react': 19.0.11
+      '@types/react-dom': 19.0.4(@types/react@19.0.11)
+
   '@radix-ui/rect@1.1.0': {}
 
+  '@radix-ui/rect@1.1.1': {}
+
   '@resvg/resvg-wasm@2.4.0': {}
 
   '@rolldown/binding-darwin-arm64@1.0.0-beta.8-commit.d95f99e':
@@ -7469,7 +7820,7 @@ snapshots:
 
   '@tanem/svg-injector@10.1.68':
     dependencies:
-      '@babel/runtime': 7.27.0
+      '@babel/runtime': 7.27.1
       content-type: 1.0.5
       tslib: 2.8.1
 
@@ -7537,7 +7888,7 @@ snapshots:
       '@types/node': 22.13.10
       form-data: 4.0.2
 
-  '@types/node@18.19.86':
+  '@types/node@18.19.103':
     dependencies:
       undici-types: 5.26.5
 
@@ -7652,15 +8003,15 @@ snapshots:
     dependencies:
       web-streams-polyfill: 3.3.3
 
-  '@zag-js/dom-query@1.8.2':
+  '@zag-js/dom-query@1.13.0':
     dependencies:
-      '@zag-js/types': 1.8.2
+      '@zag-js/types': 1.13.0
 
-  '@zag-js/focus-trap@1.8.2':
+  '@zag-js/focus-trap@1.13.0':
     dependencies:
-      '@zag-js/dom-query': 1.8.2
+      '@zag-js/dom-query': 1.13.0
 
-  '@zag-js/types@1.8.2':
+  '@zag-js/types@1.13.0':
     dependencies:
       csstype: 3.1.3
 
@@ -7765,6 +8116,10 @@ snapshots:
     dependencies:
       tslib: 2.8.1
 
+  aria-hidden@1.2.6:
+    dependencies:
+      tslib: 2.8.1
+
   arktype@2.1.19:
     dependencies:
       '@ark/schema': 0.45.9
@@ -7878,11 +8233,6 @@ snapshots:
       tar: 6.2.1
       unique-filename: 3.0.0
 
-  call-bind-apply-helpers@1.0.1:
-    dependencies:
-      es-errors: 1.3.0
-      function-bind: 1.1.2
-
   call-bind-apply-helpers@1.0.2:
     dependencies:
       es-errors: 1.3.0
@@ -8179,7 +8529,7 @@ snapshots:
       strip-ansi: 6.0.1
     optional: true
 
-  entities@4.5.0: {}
+  entities@6.0.0: {}
 
   env-paths@2.2.1: {}
 
@@ -8200,7 +8550,7 @@ snapshots:
   es-set-tostringtag@2.1.0:
     dependencies:
       es-errors: 1.3.0
-      get-intrinsic: 1.2.7
+      get-intrinsic: 1.3.0
       has-tostringtag: 1.0.2
       hasown: 2.0.2
 
@@ -8553,19 +8903,6 @@ snapshots:
 
   get-caller-file@2.0.5: {}
 
-  get-intrinsic@1.2.7:
-    dependencies:
-      call-bind-apply-helpers: 1.0.1
-      es-define-property: 1.0.1
-      es-errors: 1.3.0
-      es-object-atoms: 1.1.1
-      function-bind: 1.1.2
-      get-proto: 1.0.1
-      gopd: 1.2.0
-      has-symbols: 1.1.0
-      hasown: 2.0.2
-      math-intrinsics: 1.1.0
-
   get-intrinsic@1.3.0:
     dependencies:
       call-bind-apply-helpers: 1.0.2
@@ -8694,7 +9031,7 @@ snapshots:
       '@types/unist': 3.0.3
       devlop: 1.1.0
       hastscript: 9.0.1
-      property-information: 7.0.0
+      property-information: 7.1.0
       vfile: 6.0.3
       vfile-location: 5.0.3
       web-namespaces: 2.0.1
@@ -8712,7 +9049,7 @@ snapshots:
       hast-util-to-parse5: 8.0.0
       html-void-elements: 3.0.0
       mdast-util-to-hast: 13.2.0
-      parse5: 7.2.1
+      parse5: 7.3.0
       unist-util-position: 5.0.0
       unist-util-visit: 5.0.0
       vfile: 6.0.3
@@ -8797,7 +9134,7 @@ snapshots:
       '@types/hast': 3.0.4
       comma-separated-tokens: 2.0.3
       hast-util-parse-selector: 4.0.0
-      property-information: 7.0.0
+      property-information: 7.1.0
       space-separated-tokens: 2.0.2
 
   hex-rgb@4.3.0: {}
@@ -9170,6 +9507,10 @@ snapshots:
     dependencies:
       react: 19.0.0
 
+  lucide-react@0.503.0(react@19.0.0):
+    dependencies:
+      react: 19.0.0
+
   magic-string@0.30.17:
     dependencies:
       '@jridgewell/sourcemap-codec': 1.5.0
@@ -9231,6 +9572,8 @@ snapshots:
       node-emoji: 2.2.0
       supports-hyperlinks: 3.2.0
 
+  marked@15.0.12: {}
+
   marked@9.1.6: {}
 
   math-intrinsics@1.1.0: {}
@@ -9948,9 +10291,9 @@ snapshots:
       regex: 6.0.1
       regex-recursion: 6.0.2
 
-  openai@4.78.1(encoding@0.1.13)(zod@3.24.3):
+  openai@4.78.1(encoding@0.1.13)(zod@packages+zod):
     dependencies:
-      '@types/node': 18.19.86
+      '@types/node': 18.19.103
       '@types/node-fetch': 2.6.12
       abort-controller: 3.0.0
       agentkeepalive: 4.6.0
@@ -9958,7 +10301,7 @@ snapshots:
       formdata-node: 4.4.1
       node-fetch: 2.7.0(encoding@0.1.13)
     optionalDependencies:
-      zod: 3.24.3
+      zod: link:packages/zod
     transitivePeerDependencies:
       - encoding
 
@@ -10023,9 +10366,9 @@ snapshots:
 
   parse5@6.0.1: {}
 
-  parse5@7.2.1:
+  parse5@7.3.0:
     dependencies:
-      entities: 4.5.0
+      entities: 6.0.0
 
   path-browserify@1.0.1: {}
 
@@ -10123,6 +10466,8 @@ snapshots:
 
   property-information@7.0.0: {}
 
+  property-information@7.1.0: {}
+
   quansync@0.2.10: {}
 
   queue-microtask@1.2.3: {}
@@ -10136,11 +10481,12 @@ snapshots:
       react: 19.0.0
       scheduler: 0.25.0
 
-  react-hook-form@7.54.2(react@19.0.0):
+  react-error-boundary@6.0.0(react@19.0.0):
     dependencies:
+      '@babel/runtime': 7.27.1
       react: 19.0.0
 
-  react-icons@5.4.0(react@19.0.0):
+  react-hook-form@7.54.2(react@19.0.0):
     dependencies:
       react: 19.0.0
 
@@ -10156,7 +10502,7 @@ snapshots:
       mdast-util-to-hast: 13.2.0
       react: 19.0.0
       remark-parse: 11.0.0
-      remark-rehype: 11.1.1
+      remark-rehype: 11.1.2
       unified: 11.0.5
       unist-util-visit: 5.0.0
       vfile: 6.0.3
@@ -10197,7 +10543,7 @@ snapshots:
 
   react-svg@16.3.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
     dependencies:
-      '@babel/runtime': 7.27.0
+      '@babel/runtime': 7.27.1
       '@tanem/svg-injector': 10.1.68
       '@types/prop-types': 15.7.14
       prop-types: 15.8.1
@@ -10206,7 +10552,7 @@ snapshots:
 
   react-textarea-autosize@8.5.7(@types/react@19.0.11)(react@19.0.0):
     dependencies:
-      '@babel/runtime': 7.27.0
+      '@babel/runtime': 7.27.1
       react: 19.0.0
       use-composed-ref: 1.4.0(@types/react@19.0.11)(react@19.0.0)
       use-latest: 1.3.0(@types/react@19.0.11)(react@19.0.0)
@@ -10330,6 +10676,14 @@ snapshots:
       unified: 11.0.5
       vfile: 6.0.3
 
+  remark-rehype@11.1.2:
+    dependencies:
+      '@types/hast': 3.0.4
+      '@types/mdast': 4.0.4
+      mdast-util-to-hast: 13.2.0
+      unified: 11.0.5
+      vfile: 6.0.3
+
   remark-stringify@11.0.0:
     dependencies:
       '@types/mdast': 4.0.4
@@ -11040,7 +11394,7 @@ snapshots:
     optionalDependencies:
       '@types/react': 19.0.11
 
-  use-isomorphic-layout-effect@1.2.0(@types/react@19.0.11)(react@19.0.0):
+  use-isomorphic-layout-effect@1.2.1(@types/react@19.0.11)(react@19.0.0):
     dependencies:
       react: 19.0.0
     optionalDependencies:
@@ -11049,7 +11403,7 @@ snapshots:
   use-latest@1.3.0(@types/react@19.0.11)(react@19.0.0):
     dependencies:
       react: 19.0.0
-      use-isomorphic-layout-effect: 1.2.0(@types/react@19.0.11)(react@19.0.0)
+      use-isomorphic-layout-effect: 1.2.1(@types/react@19.0.11)(react@19.0.0)
     optionalDependencies:
       '@types/react': 19.0.11
 


Test patch:
diff --git a/packages/zod/src/v4/classic/tests/custom.test.ts b/packages/zod/src/v4/classic/tests/custom.test.ts
index b3ffe715..c360a216 100644
--- a/packages/zod/src/v4/classic/tests/custom.test.ts
+++ b/packages/zod/src/v4/classic/tests/custom.test.ts
@@ -14,3 +14,10 @@ test("string params", () => {
   expect(result.success).toEqual(false);
   expect(JSON.stringify(result.error).includes("customerr")).toEqual(true);
 });
+
+test("instanceof", () => {
+  const fn = (value: string) => Uint8Array.from(Buffer.from(value, "base64"));
+
+  // Argument of type 'ZodCustom<Uint8Array<ArrayBuffer>, unknown>' is not assignable to parameter of type '$ZodType<any, Uint8Array<ArrayBuffer>>'.
+  z.string().transform(fn).pipe(z.instanceof(Uint8Array));
+});
diff --git a/packages/zod/src/v4/classic/tests/default.test.ts b/packages/zod/src/v4/classic/tests/default.test.ts
index 56b85f55..28015711 100644
--- a/packages/zod/src/v4/classic/tests/default.test.ts
+++ b/packages/zod/src/v4/classic/tests/default.test.ts
@@ -112,3 +112,183 @@ test("object optionality", () => {
     hi: "hi",
   });
 });
+
+test("nested prefault/default", () => {
+  const a = z
+    .string()
+    .default("a")
+    .refine((val) => val.startsWith("a"));
+  const b = z
+    .string()
+    .refine((val) => val.startsWith("b"))
+    .default("b");
+  const c = z
+    .string()
+    .prefault("c")
+    .refine((val) => val.startsWith("c"));
+  const d = z
+    .string()
+    .refine((val) => val.startsWith("d"))
+    .prefault("d");
+
+  const obj = z.object({
+    a,
+    b,
+    c,
+    d,
+  });
+
+  expect(obj.safeParse({ a: "a1", b: "b1", c: "c1", d: "d1" })).toMatchInlineSnapshot(`
+    {
+      "data": {
+        "a": "a1",
+        "b": "b1",
+        "c": "c1",
+        "d": "d1",
+      },
+      "success": true,
+    }
+  `);
+
+  expect(obj.safeParse({ a: "f", b: "f", c: "f", d: "f" })).toMatchInlineSnapshot(`
+    {
+      "error": [ZodError: [
+      {
+        "code": "custom",
+        "path": [
+          "a"
+        ],
+        "message": "Invalid input"
+      },
+      {
+        "code": "custom",
+        "path": [
+          "b"
+        ],
+        "message": "Invalid input"
+      },
+      {
+        "code": "custom",
+        "path": [
+          "c"
+        ],
+        "message": "Invalid input"
+      },
+      {
+        "code": "custom",
+        "path": [
+          "d"
+        ],
+        "message": "Invalid input"
+      }
+    ]],
+      "success": false,
+    }
+  `);
+
+  expect(obj.safeParse({})).toMatchInlineSnapshot(`
+    {
+      "data": {
+        "a": "a",
+        "b": "b",
+        "c": "c",
+        "d": "d",
+      },
+      "success": true,
+    }
+  `);
+
+  expect(obj.safeParse({ a: undefined, b: undefined, c: undefined, d: undefined })).toMatchInlineSnapshot(`
+    {
+      "data": {
+        "a": "a",
+        "b": "b",
+        "c": "c",
+        "d": "d",
+      },
+      "success": true,
+    }
+  `);
+
+  const obj2 = z.object({
+    a: a.optional(),
+    b: b.optional(),
+    c: c.optional(),
+    d: d.optional(),
+  });
+  expect(obj2.safeParse({ a: undefined, b: undefined, c: undefined, d: undefined })).toMatchInlineSnapshot(`
+    {
+      "data": {
+        "a": undefined,
+        "b": undefined,
+        "c": undefined,
+        "d": undefined,
+      },
+      "success": true,
+    }
+  `);
+
+  expect(a.parse(undefined)).toBe("a");
+  expect(b.parse(undefined)).toBe("b");
+  expect(c.parse(undefined)).toBe("c");
+  expect(d.parse(undefined)).toBe("d");
+});
+
+test("failing default", () => {
+  const a = z
+    .string()
+    .default("z")
+    .refine((val) => val.startsWith("a"));
+  const b = z
+    .string()
+    .refine((val) => val.startsWith("b"))
+    .default("z");
+  const c = z
+    .string()
+    .prefault("z")
+    .refine((val) => val.startsWith("c"));
+  const d = z
+    .string()
+    .refine((val) => val.startsWith("d"))
+    .prefault("z");
+
+  const obj = z.object({
+    a,
+    b,
+    c,
+    d,
+  });
+
+  expect(
+    obj.safeParse({
+      a: undefined,
+      b: undefined,
+      c: undefined,
+      d: undefined,
+    }).error!.issues
+  ).toMatchInlineSnapshot(`
+    [
+      {
+        "code": "custom",
+        "message": "Invalid input",
+        "path": [
+          "a",
+        ],
+      },
+      {
+        "code": "custom",
+        "message": "Invalid input",
+        "path": [
+          "c",
+        ],
+      },
+      {
+        "code": "custom",
+        "message": "Invalid input",
+        "path": [
+          "d",
+        ],
+      },
+    ]
+  `);
+});
diff --git a/packages/zod/src/v4/classic/tests/firstparty.test.ts b/packages/zod/src/v4/classic/tests/firstparty.test.ts
index ac689930..de394fe0 100644
--- a/packages/zod/src/v4/classic/tests/firstparty.test.ts
+++ b/packages/zod/src/v4/classic/tests/firstparty.test.ts
@@ -120,8 +120,6 @@ test("$ZodSchemaTypes", () => {
       break;
     case "object":
       break;
-    case "interface":
-      break;
     case "union":
       break;
     case "intersection":
diff --git a/packages/zod/src/v4/classic/tests/index.test.ts b/packages/zod/src/v4/classic/tests/index.test.ts
index 559a2d2b..5ded8c49 100644
--- a/packages/zod/src/v4/classic/tests/index.test.ts
+++ b/packages/zod/src/v4/classic/tests/index.test.ts
@@ -835,48 +835,6 @@ test("z.json", () => {
   expect(() => z.parse(a, { a: undefined })).toThrow();
 });
 
-test("z.stringbool", () => {
-  const a = z.stringbool();
-
-  expect(z.parse(a, "true")).toEqual(true);
-  expect(z.parse(a, "yes")).toEqual(true);
-  expect(z.parse(a, "1")).toEqual(true);
-  expect(z.parse(a, "on")).toEqual(true);
-  expect(z.parse(a, "y")).toEqual(true);
-  expect(z.parse(a, "enabled")).toEqual(true);
-  expect(z.parse(a, "TRUE")).toEqual(true);
-
-  expect(z.parse(a, "false")).toEqual(false);
-  expect(z.parse(a, "no")).toEqual(false);
-  expect(z.parse(a, "0")).toEqual(false);
-  expect(z.parse(a, "off")).toEqual(false);
-  expect(z.parse(a, "n")).toEqual(false);
-  expect(z.parse(a, "disabled")).toEqual(false);
-  expect(z.parse(a, "FALSE")).toEqual(false);
-
-  expect(z.safeParse(a, "other")).toMatchObject({ success: false });
-  expect(z.safeParse(a, "")).toMatchObject({ success: false });
-  expect(z.safeParse(a, undefined)).toMatchObject({ success: false });
-  expect(z.safeParse(a, {})).toMatchObject({ success: false });
-  expect(z.safeParse(a, true)).toMatchObject({ success: false });
-  expect(z.safeParse(a, false)).toMatchObject({ success: false });
-
-  const b = z.stringbool({
-    truthy: ["y"],
-    falsy: ["n"],
-  });
-  expect(z.parse(b, "y")).toEqual(true);
-  expect(z.parse(b, "n")).toEqual(false);
-  expect(z.safeParse(b, "true")).toMatchObject({ success: false });
-  expect(z.safeParse(b, "false")).toMatchObject({ success: false });
-
-  const c = z.stringbool({
-    case: "sensitive",
-  });
-  expect(z.parse(c, "true")).toEqual(true);
-  expect(z.safeParse(c, "TRUE")).toMatchObject({ success: false });
-});
-
 // promise
 test("z.promise", async () => {
   const a = z.promise(z.string());
diff --git a/packages/zod/src/v4/classic/tests/json-schema.test.ts b/packages/zod/src/v4/classic/tests/json-schema.test.ts
index a6efe894..d014ddf2 100644
--- a/packages/zod/src/v4/classic/tests/json-schema.test.ts
+++ b/packages/zod/src/v4/classic/tests/json-schema.test.ts
@@ -361,13 +361,66 @@ describe("toJSONSchema", () => {
     expect(z.toJSONSchema(z.string().regex(/asdf/))).toMatchInlineSnapshot(`
       {
         "$schema": "https://json-schema.org/draft/2020-12/schema",
-        "format": "regex",
         "pattern": "asdf",
         "type": "string",
       }
     `);
   });
 
+  test("string patterns", () => {
+    expect(
+      z.toJSONSchema(z.string().startsWith("hello").includes("cruel").endsWith("world").regex(/stuff/))
+    ).toMatchInlineSnapshot(`
+      {
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
+        "allOf": [
+          {
+            "pattern": "^hello.*",
+          },
+          {
+            "pattern": "cruel",
+          },
+          {
+            "pattern": ".*world$",
+          },
+          {
+            "pattern": "stuff",
+          },
+        ],
+        "type": "string",
+      }
+    `);
+
+    expect(
+      z.toJSONSchema(z.string().startsWith("hello").includes("cruel").endsWith("world").regex(/stuff/), {
+        target: "draft-7",
+      })
+    ).toMatchInlineSnapshot(`
+      {
+        "$schema": "http://json-schema.org/draft-07/schema#",
+        "allOf": [
+          {
+            "pattern": "^hello.*",
+            "type": "string",
+          },
+          {
+            "pattern": "cruel",
+            "type": "string",
+          },
+          {
+            "pattern": ".*world$",
+            "type": "string",
+          },
+          {
+            "pattern": "stuff",
+            "type": "string",
+          },
+        ],
+        "type": "string",
+      }
+    `);
+  });
+
   test("number constraints", () => {
     expect(z.toJSONSchema(z.number().min(5).max(10))).toMatchInlineSnapshot(
       `
@@ -984,6 +1037,7 @@ describe("toJSONSchema", () => {
     expect(JSON.stringify(result, null, 2)).toMatchInlineSnapshot(
       `
       "{
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "object",
         "properties": {
           "id": {
@@ -997,8 +1051,7 @@ describe("toJSONSchema", () => {
           "id",
           "children"
         ],
-        "additionalProperties": false,
-        "$schema": "https://json-schema.org/draft/2020-12/schema"
+        "additionalProperties": false
       }"
     `
     );
@@ -1025,6 +1078,7 @@ describe("toJSONSchema", () => {
     expect(JSON.stringify(result, null, 2)).toMatchInlineSnapshot(
       `
       "{
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "object",
         "properties": {
           "name": {
@@ -1054,8 +1108,7 @@ describe("toJSONSchema", () => {
           "name",
           "files"
         ],
-        "additionalProperties": false,
-        "$schema": "https://json-schema.org/draft/2020-12/schema"
+        "additionalProperties": false
       }"
     `
     );
diff --git a/packages/zod/src/v4/classic/tests/object.test.ts b/packages/zod/src/v4/classic/tests/object.test.ts
index 56d2699b..29c39806 100644
--- a/packages/zod/src/v4/classic/tests/object.test.ts
+++ b/packages/zod/src/v4/classic/tests/object.test.ts
@@ -491,3 +491,15 @@ test("preserve key order", () => {
   `);
   expect(Object.keys(r1.data!)).toEqual(Object.keys(r2.data!));
 });
+
+test("empty shape", () => {
+  const a = z.object({});
+
+  a.parse({});
+  a.parse({}, { jitless: true });
+  a.parse(Object.create(null));
+  a.parse(Object.create(null), { jitless: true });
+
+  expect(() => a.parse([])).toThrow();
+  expect(() => a.parse([], { jitless: true })).toThrow();
+});
diff --git a/packages/zod/src/v4/classic/tests/string.test.ts b/packages/zod/src/v4/classic/tests/string.test.ts
index 125b5ad4..154a9187 100644
--- a/packages/zod/src/v4/classic/tests/string.test.ts
+++ b/packages/zod/src/v4/classic/tests/string.test.ts
@@ -339,12 +339,52 @@ test("url validations", () => {
   url.parse("http://aslkfjdalsdfkjaf");
   url.parse("http://localhost");
 
+  url.parse("c:");
+
   expect(() => url.parse("asdf")).toThrow();
-  expect(() => url.parse("http:.......///broken.com")).toThrow();
-  expect(() => url.parse("c:")).toThrow();
-  expect(() => url.parse("WWW:WWW.COM")).toThrow();
   expect(() => url.parse("https:/")).toThrow();
   expect(() => url.parse("asdfj@lkjsdf.com")).toThrow();
+  expect(() => url.parse("https://")).toThrow();
+});
+
+test("httpurl", () => {
+  const httpUrl = z.url({
+    protocol: /^https?$/,
+    hostname: z.regexes.domain,
+    // /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/
+  });
+
+  httpUrl.parse("https://example.com");
+  httpUrl.parse("http://example.com");
+  // ports
+  httpUrl.parse("https://example.com:8080");
+  httpUrl.parse("http://example.com:8080");
+  // subdomains
+  httpUrl.parse("https://sub.example.com");
+  httpUrl.parse("http://sub.example.com");
+  // paths
+  httpUrl.parse("https://example.com/path/to/resource");
+  httpUrl.parse("http://example.com/path/to/resource");
+  // query parameters
+  httpUrl.parse("https://example.com/path?query=param");
+  httpUrl.parse("http://example.com/path?query=param");
+  // fragment identifiers
+  httpUrl.parse("https://example.com/path#fragment");
+  httpUrl.parse("http://example.com/path#fragment");
+  // fails
+  expect(() => httpUrl.parse("ftp://example.com")).toThrow();
+  expect(() => httpUrl.parse("shttp://example.com")).toThrow();
+  expect(() => httpUrl.parse("httpz://example.com")).toThrow();
+  expect(() => httpUrl.parse("http://")).toThrow();
+  expect(() => httpUrl.parse("http://localhost")).toThrow();
+  expect(() => httpUrl.parse("http://-asdf.com")).toThrow();
+  expect(() =>
+    httpUrl.parse(
+      "http://asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf.com"
+    )
+  ).toThrow();
+  expect(() => httpUrl.parse("http://asdf.c")).toThrow();
+  expect(() => httpUrl.parse("mailto:asdf@lckj.com")).toThrow();
 });
 
 test("url error overrides", () => {
diff --git a/packages/zod/src/v4/classic/tests/stringbool.test.ts b/packages/zod/src/v4/classic/tests/stringbool.test.ts
new file mode 100644
index 00000000..f0cd31ea
--- /dev/null
+++ b/packages/zod/src/v4/classic/tests/stringbool.test.ts
@@ -0,0 +1,53 @@
+import { expect, expectTypeOf, test } from "vitest";
+import * as z from "zod/v4";
+
+test("z.stringbool", () => {
+  const a = z.stringbool();
+  type a = z.infer<typeof a>;
+  expectTypeOf<a>().toEqualTypeOf<boolean>();
+
+  expect(z.parse(a, "true")).toEqual(true);
+  expect(z.parse(a, "yes")).toEqual(true);
+  expect(z.parse(a, "1")).toEqual(true);
+  expect(z.parse(a, "on")).toEqual(true);
+  expect(z.parse(a, "y")).toEqual(true);
+  expect(z.parse(a, "enabled")).toEqual(true);
+  expect(z.parse(a, "TRUE")).toEqual(true);
+
+  expect(z.parse(a, "false")).toEqual(false);
+  expect(z.parse(a, "no")).toEqual(false);
+  expect(z.parse(a, "0")).toEqual(false);
+  expect(z.parse(a, "off")).toEqual(false);
+  expect(z.parse(a, "n")).toEqual(false);
+  expect(z.parse(a, "disabled")).toEqual(false);
+  expect(z.parse(a, "FALSE")).toEqual(false);
+
+  expect(z.safeParse(a, "other")).toMatchObject({ success: false });
+  expect(z.safeParse(a, "")).toMatchObject({ success: false });
+  expect(z.safeParse(a, undefined)).toMatchObject({ success: false });
+  expect(z.safeParse(a, {})).toMatchObject({ success: false });
+  expect(z.safeParse(a, true)).toMatchObject({ success: false });
+  expect(z.safeParse(a, false)).toMatchObject({ success: false });
+
+  const b = z.stringbool({
+    truthy: ["y"],
+    falsy: ["n"],
+  });
+  expect(z.parse(b, "y")).toEqual(true);
+  expect(z.parse(b, "n")).toEqual(false);
+  expect(z.safeParse(b, "true")).toMatchObject({ success: false });
+  expect(z.safeParse(b, "false")).toMatchObject({ success: false });
+
+  const c = z.stringbool({
+    case: "sensitive",
+  });
+  expect(z.parse(c, "true")).toEqual(true);
+  expect(z.safeParse(c, "TRUE")).toMatchObject({ success: false });
+});
+
+// test custom error messages
+test("z.stringbool with custom error messages", () => {
+  const a = z.stringbool("wrong!");
+
+  expect(() => a.parse("")).toThrowError("wrong!");
+});
diff --git a/packages/zod/src/v4/mini/tests/string.test.ts b/packages/zod/src/v4/mini/tests/string.test.ts
index 2bbf77c8..7e034670 100644
--- a/packages/zod/src/v4/mini/tests/string.test.ts
+++ b/packages/zod/src/v4/mini/tests/string.test.ts
@@ -121,6 +121,15 @@ test("z.url with optional hostname regex", () => {
   expect(() => a.parse("asdf")).toThrow();
 });
 
+test("z.url - file urls", () => {
+  // file URLs
+  const a = z.url({ hostname: /.*/ }); // allow any hostname
+  expect(a.parse("file:///path/to/file.txt")).toEqual("file:///path/to/file.txt");
+  expect(a.parse("file:///C:/path/to/file.txt")).toEqual("file:///C:/path/to/file.txt");
+  expect(a.parse("file:///C:/path/to/file.txt?query=123#fragment")).toEqual(
+    "file:///C:/path/to/file.txt?query=123#fragment"
+  );
+});
 test("z.url with optional protocol regex", () => {
   const a = z.url({ protocol: /^https?$/ });
   expect(a.parse("http://example.com")).toEqual("http://example.com");