Repository: colinhacks/zod
Pull request #4451 (2025-05-21 05:58:59)

add Swedish locale
Add Swedish locale for Swedish translation for error messages

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

- **New Features**
  - Added support for Swedish-language error messages in validation error outputs.
  - Updated documentation to include Swedish as an available locale option.
<!-- 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 c2cec4e3cf293bd8e6a47a90d4d9c7cb2ea1f65a and e6ab4fc1938c33f661ee4adc6b47def35c64dff9.
> 
> </details>
> 
> <details>
> <summary>📒 Files selected for processing (2)</summary>
> 
> * `packages/zod/src/v4/locales/index.ts` (1 hunks)
> * `packages/zod/src/v4/locales/sv.ts` (1 hunks)
> 
> </details>
> 
> ```ascii
>  ____________________________
> < Bunny-grade bug detection. >
>  ----------------------------
>   \
>    \   \
>         \ /\
>         ( )
>       .( o ).
> ```

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

> [!TIP]
> <details>
> <summary>CodeRabbit can use Shopify Theme Check to improve the quality of Shopify theme reviews.</summary>
> 
> Add a [configuration file](https://shopify.dev/docs/themes/tools/theme-check) to your project to customize how CodeRabbit runs Shopify Theme Check.
> 
> </details>

<!-- usage_tips_end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings
<details open="true">
<summary>🧪 Generate Unit Tests</summary>

- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Create PR with Unit Tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Commit Unit Tests in branch `add-locale-sv`
- [ ] <!-- {"checkboxId": "07f1e7d6-8a8e-4e23-9900-8731c2c87f58", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Post Copyable Unit Tests in Comment

</details>

</details>

<!-- finishing_touch_checkbox_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=4451):

- 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 auto-generate unit tests` to generate unit tests for 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 339084f7..00000000
--- a/.github/workflows/release-canary.yml
+++ /dev/null
@@ -1,49 +0,0 @@
-# .github/release.yml
-
-name: Release on npm (canary)
-on:
-  push:
-    branches:
-      - main
-    paths:
-      - "src/**"
-      - ".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 dependencies
-      #   run: |
-      #     yarn install
-
-      # - name: Build
-      #   run: |
-      #     yarn clean
-      #     yarn build
-
-      # - name: Set version
-      #   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
-      #     tag: canary
-      #     provenance: true
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 2206890e..82f2b1ef 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -6,7 +6,9 @@ on:
     branches:
       - main
     paths:
-      - packages/zod/package.json
+      - "packages/zod/package.json"
+      - "packages/zod/src/**"
+      - ".github/workflows/release.yml"
 
 jobs:
   build_and_publish:
@@ -24,18 +26,20 @@ jobs:
         uses: actions/setup-node@v4
         with:
           node-version: 20
+      
       - name: Install pnpm
         uses: pnpm/action-setup@v4
+        
       - name: Install dependencies
         run: |
           pnpm install
 
-      - name: Install dependencies
+      - name: Build and test
         working-directory: ./packages/zod
         run: |
           pnpm run test
           pnpm build
-
+          
       - id: publish
         name: Publish to NPM
         uses: JS-DevTools/npm-publish@v3
@@ -46,18 +50,35 @@ jobs:
           package: ./packages/zod
 
       - name: Post-publish
-        if: steps.publish.outputs.type != 'none'
+        if: ${{ steps.publish.outputs.type }}
         run: |
           echo "Published ${{ steps.publish.outputs.type }} version: ${{ steps.publish.outputs.version }}"
 
-      - name: Publish skipped
-        if: steps.publish.outputs.type == 'none'
+      - 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
-        if: steps.publish.outputs.type != 'none'
+        if: ${{ steps.publish.outputs.type }}
         run: |
           echo '{"categories": [], "template": "## Commits:\n\n${{ '${{UNCATEGORIZED}}' }}", "pr_template": ${{ '"- ${{MERGE_SHA}} ${{TITLE}}"' }} }' > changelog_config.json
           cat changelog_config.json
@@ -65,7 +86,7 @@ jobs:
           echo "curr_commit=$(git rev-parse HEAD)" >> $GITHUB_ENV
 
       - name: Generate changelog
-        if: steps.publish.outputs.type != 'none'
+        if: ${{ steps.publish.outputs.type }}
         id: github_release
         uses: mikepenz/release-changelog-builder-action@v2.9.0
         env:
@@ -77,7 +98,7 @@ jobs:
           configuration: changelog_config.json
 
       - name: Create release
-        if: steps.publish.outputs.type != 'none'
+        if: ${{ steps.publish.outputs.type }}
         id: create_release
         uses: actions/create-release@v1
         env:
diff --git a/.husky/pre-commit b/.husky/pre-commit
index ba85fbee..ccd710b5 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,4 +1,7 @@
 #!/bin/sh
 . "$(dirname "$0")/_/husky.sh"
 
+pnpm semver-check
 npx lint-staged --verbose
+
+
diff --git a/.husky/pre-push b/.husky/pre-push
index 8ef6b5f1..3b20f4e1 100755
--- a/.husky/pre-push
+++ b/.husky/pre-push
@@ -2,3 +2,5 @@
 . "$(dirname "$0")/_/husky.sh"
 
 pnpm test
+
+pnpm semver-check
diff --git a/README.md b/README.md
index 8c66df94..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({ 
@@ -164,7 +164,7 @@ try {
 To avoid a `try/catch` block, you can use the `.safeParse()` method to get back a plain result object containing either the successfully parsed data or a `ZodError`. The result type is a [discriminated union](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions), so you can handle both cases conveniently.
 
 ```ts
-const result = Player.parse({ username: 42, xp: "100" });
+const result = Player.safeParse({ username: 42, xp: "100" });
 if (!result.success) {
   result.error;   // ZodError instance
 } else {
diff --git a/package.json b/package.json
index 557f6349..0f9179c6 100644
--- a/package.json
+++ b/package.json
@@ -26,11 +26,13 @@
     "chalk": "^5.4.1",
     "console-table-printer": "^2.12.1",
     "execa": "^9.5.2",
+    "globby": "^14.1.0",
     "husky": "^7.0.4",
     "jsr": "^0.12.4",
     "lint-staged": "^12.5.0",
     "mitata": "^0.1.14",
     "prettier": "^3.5.3",
+    "semver": "^7.7.2",
     "supershy": "^1.0.0",
     "tinybench": "^2.9.0",
     "ts-morph": "^14.0.0",
@@ -63,7 +65,7 @@
     "build": "pnpm run -r --filter '!@zod/docs' build",
     "test:watch": "vitest",
     "test": "vitest run",
-    "prepublishOnly": "pnpm run test && pnpm run build && tsx scripts/prepublish.ts",
+    "prepublishOnly": "pnpm run test && pnpm run build",
     "dev": "tsx --conditions @zod/source",
     "dev:watch": "tsx --conditions @zod/source --watch",
     "dev:play": "pnpm dev play.ts",
@@ -74,6 +76,7 @@
     "publish:jsr": "jsr publish --dry-run",
     "bundle:rollup": "rollup -c",
     "bundle:esbuild": "esbuild --bundle ./scratch/input.ts --outfile=./scratch/out_esbuild.js --bundle --format=esm",
-    "pub:beta": "pnpm run -r pub:beta"
+    "pub:beta": "pnpm run -r pub:beta",
+    "semver-check": "tsx scripts/semver-check.ts"
   }
 }
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/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 6679dd0f..678ba0a4 100644
--- a/packages/docs/content/api.mdx
+++ b/packages/docs/content/api.mdx
@@ -174,8 +174,8 @@ z.string().lowercase();
 </Tab>
 <Tab value="Zod Mini">
 ```ts zod/v4-mini
-z.string().check(z.max(5));
-z.string().check(z.min(5));
+z.string().check(z.maximum(5)); // or z.lte()
+z.string().check(z.minimum(5)); // or z.gte()
 z.string().check(z.length(5));
 z.string().check(z.regex(/^[a-z]+$/));
 z.string().check(z.startsWith("aaa"));
@@ -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/basics.mdx b/packages/docs/content/basics.mdx
index bdaae173..fd6d5b3f 100644
--- a/packages/docs/content/basics.mdx
+++ b/packages/docs/content/basics.mdx
@@ -133,7 +133,7 @@ try {
 To avoid a `try/catch` block, you can use the `.safeParse()` method to get back a plain result object containing either the successfully parsed data or a `ZodError`. The result type is a [discriminated union](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions), so you can handle both cases conveniently.
 
 ```ts
-const result = Player.parse({ username: 42, xp: "100" });
+const result = Player.safeParse({ username: 42, xp: "100" });
 if (!result.success) {
   result.error;   // ZodError instance
 } else {
diff --git a/packages/docs/content/error-customization.mdx b/packages/docs/content/error-customization.mdx
index 3ac421bc..45a8e9d4 100644
--- a/packages/docs/content/error-customization.mdx
+++ b/packages/docs/content/error-customization.mdx
@@ -56,7 +56,7 @@ Every issue contains a `message` property with a human-readable error message. E
 
 ## The `error` param
 
-Virtually every Zod API accepts an optional error message parameter.
+Virtually every Zod API accepts an optional error message.
 
 ```ts
 z.string("Not a string!");
@@ -87,7 +87,7 @@ z.string("Bad!");
 z.string().min(5, "Too short!");
 z.uuid("Bad UUID!");
 z.iso.date("Bad date!");
-z.array(z.string(), "Bad array!");
+z.array(z.string(), "Not an array!");
 z.array(z.string()).min(5, "Too few items!");
 z.set(z.string(), "Bad set!");
 ```
@@ -133,7 +133,8 @@ z.set(z.string(), { error: "Bad set!" });
 </Tab>
 </Tabs>
 
-The `error` param optionally accepts a function. This function will be called 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 can at parse time if a valiation error occurs.
 
 ```ts
 z.string({ error: ()=>`[${Date.now()}]: Validation failure.` });
@@ -143,47 +144,19 @@ z.string({ error: ()=>`[${Date.now()}]: Validation failure.` });
 **Note** — In Zod v3, there were separate params for `message` (a string) and `errorMap` (a function). These have been unified in Zod 4 as `error`.
 </Callout>
 
+The error map receives a context object you can use to customize the error message based on the validation issue.
 
-The `error` function received a context object you can use to customize the error message based on the `input` or other validation information.
-
-<Tabs groupId="lib" items={["Zod", "Zod Mini"]}>
-<Tab value="Zod">
 ```ts
 z.string({
-  error: (iss) => iss.input===undefined ? "Field is required." : "Invalid input."
+  error: (iss) => iss.input === undefined ? "Field is required." : "Invalid input."
 });
 ```
-</Tab>
-<Tab value="Zod Mini">
-```ts
-z.string({
-  error: (iss) => iss.input===undefined ? "Field is required." : "Invalid input."
-});
-```
-</Tab>
-</Tabs>
 
 For advanced cases, the `iss` object provides additional information you can use to customize the error.
 
-
-<Tabs groupId="lib" items={["Zod", "Zod Mini"]}>
-<Tab value="Zod">
-```ts
-z.string({
-  error: (iss) => {
-    iss.code; // the issue code
-    iss.input; // the input data
-    iss.inst; // the schema/check that originated this issue
-    iss.path; // the path of the error
-  },
-});
-```
-</Tab>
-<Tab value="Zod Mini">
 ```ts
 z.string({
   error: (iss) => {
-    iss.inst;
     iss.code; // the issue code
     iss.input; // the input data
     iss.inst; // the schema/check that originated this issue
@@ -191,8 +164,6 @@ z.string({
   },
 });
 ```
-</Tab>
-</Tabs>
 
 Depending on the API you are using, there may be additional properties available. Use TypeScript's autocomplete to explore the available properties.
 
@@ -207,6 +178,22 @@ z.string().min(5, {
 });
 ```
 
+Return `undefined` to avoid setting an error message. This is useful for customizing certain error messages but not others. Zod will yield control to the next error map in the [precedence chain](#error-precedence).
+
+```ts
+z.int64({
+  error: (issue) => {
+    // override too_big error message
+    if (issue.code === "too_big") {
+      return { message: `Value must be <${issue.maximum}` };
+    }
+
+    //  defer to default
+    return undefined;
+  },
+});
+```
+
 ## Per-parse error customization
 
 To customize errors on a *per-parse* basis, pass an error map into the parse method:
@@ -291,7 +278,7 @@ To support internationalization of error message, Zod provides several built-in
 <Tab value="Zod">
 ```ts
 import { z } from "zod/v4";
-import en from "zod/v4/locales/en"
+import en from "zod/v4/locales/en.js"
 
 z.config(en());
 ```
@@ -299,7 +286,7 @@ z.config(en());
 <Tab value="Zod Mini">
 ```ts
 import { z } from "zod/v4-mini"
-import en from "zod/v4/locales/en"
+import en from "zod/v4/locales/en.js"
 
 z.config(en());
 ```
@@ -312,7 +299,7 @@ To lazily load a locale, consider dynamic imports:
 import { z } from "zod/v4";
 
 async function loadLocale(locale: string) {
-  const { default: locale } = await import(`zod/v4/locales/${locale}`);
+  const { default: locale } = await import(`zod/v4/locales/${locale}.js`);
   z.config(locale());
 };
 
@@ -359,6 +346,7 @@ The following locales are available:
 - `id` — Indonesian  
 - `it` — Italian  
 - `ja` — Japanese  
+- `kh` — Khmer
 - `ko` — Korean  
 - `mk` — Macedonian  
 - `ms` — Malay  
@@ -368,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/json-schema.mdx b/packages/docs/content/json-schema.mdx
index 94298d72..7039b2d5 100644
--- a/packages/docs/content/json-schema.mdx
+++ b/packages/docs/content/json-schema.mdx
@@ -142,7 +142,7 @@ Below is a quick reference for each supported parameter. Each one is explained i
 interface ToJSONSchemaParams {
   /** The JSON Schema version to target.
    * - `"draft-2020-12"` — Default. JSON Schema Draft 2020-12
-   * - `"draft-7"` — Default. JSON Schema Draft 7 */
+   * - `"draft-7"` — JSON Schema Draft 7 */
   target?: "draft-7" | "draft-2020-12";
 
   /** A registry used to look up metadata for each schema. 
@@ -398,7 +398,7 @@ z.toJSONSchema(User, { reused: "ref" });
 
 ### `override`
 
-To define some custom override logic, use `override`. The provided callback has access to the original Zod schema and the default JSON Schema. *This function should dircectly modify `ctx.jsonSchema`.*
+To define some custom override logic, use `override`. The provided callback has access to the original Zod schema and the default JSON Schema. *This function should directly modify `ctx.jsonSchema`.*
 
 
 ```ts
@@ -414,6 +414,21 @@ z.toJSONSchema(mySchema, {
 });
 ```
 
+Note that unrepresentable types will throw an `Error` before this functions is called. If you are trying to define custom behavior for an unrepresentable type, you'll need to use set the `unrepresentable: "any"` alongside `override`.
+
+```ts
+// support z.date() as ISO datetime strings
+const result = z.toJSONSchema(z.date(), {
+  unrepresentable: "any",
+  override: (ctx) => {
+    const def = ctx.zodSchema._zod.def;
+    if(def.type ==="date"){
+      ctx.jsonSchema.type = "string";
+      ctx.jsonSchema.format = "date-time";
+    }
+  },
+});
+```
 
 ### `io`
 
diff --git a/packages/docs/content/packages/core.mdx b/packages/docs/content/packages/core.mdx
index 7164f7a1..65b9ed10 100644
--- a/packages/docs/content/packages/core.mdx
+++ b/packages/docs/content/packages/core.mdx
@@ -88,9 +88,10 @@ export type $ZodTypes =
   | $ZodFile;
 ```
 
-All `zod/v4/core` subclasses only contain a single property: `_zod`. This property is an object containing the schemas *internals*. The goal is to make `zod/v4/core` as extensible and unopinionated as possible. Other libraries can "build their own Zod" on top of these classes without `zod/v4/core` cluttering up the interface. 
 
-Refer to the implementations of `zod/v4` and `zod/v4-mini` for examples of how to extend these classes. 
+## Internals
+
+All `zod/v4/core` subclasses only contain a single property: `_zod`. This property is an object containing the schemas *internals*. The goal is to make `zod/v4/core` as extensible and unopinionated as possible. Other libraries can "build their own Zod" on top of these classes without `zod/v4/core` cluttering up the interface. Refer to the implementations of `zod/v4` and `zod/v4-mini` for examples of how to extend these classes. 
 
 The `_zod` internals property contains some notable properties:
 
@@ -122,7 +123,6 @@ export function walk(_schema: z.$ZodType) {
 
 There are a number of subclasses of `$ZodString` that implement various *string formats*. These are exported as `z.$ZodStringFormatTypes`.
 
-
 ```ts
 export type $ZodStringFormatTypes =
   | $ZodGUID
@@ -151,6 +151,21 @@ export type $ZodStringFormatTypes =
 ```
 
 
+## Parsing 
+
+As the Zod Core schema classes have no methods, there are top-level functions for parsing data.
+
+```ts
+import * as z from "zod/v4/core";
+
+const schema = new z.$ZodString({ type: "string" });
+z.parse(schema, "hello");
+z.safeParse(schema, "hello");
+await z.parseAsync(schema, "hello");
+await z.safeParseAsync(schema, "hello");
+```
+
+
 ## Checks
 
 Every Zod schema contains an array of *checks*. These perform post-parsing refinements (and occasionally mutations) that *do not affect* the inferred type.
diff --git a/packages/docs/content/v4/changelog.mdx b/packages/docs/content/v4/changelog.mdx
index 1c6be066..0cef0445 100644
--- a/packages/docs/content/v4/changelog.mdx
+++ b/packages/docs/content/v4/changelog.mdx
@@ -363,7 +363,7 @@ type schemaInput = z.input<typeof schema>;
 
 ## `.default()` updates
 
-The application of `.default()` has changed in a subtle way. If the input is `undefined`, `ZodDefault` short-circuits the parsing process and returns the default value. The the default value must be assignable to the *output type*.
+The application of `.default()` has changed in a subtle way. If the input is `undefined`, `ZodDefault` short-circuits the parsing process and returns the default value. The default value must be assignable to the *output type*.
 
 ```ts
 const schema = z.string()
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/build.mts b/packages/zod/build.mts
new file mode 100644
index 00000000..06ee6643
--- /dev/null
+++ b/packages/zod/build.mts
@@ -0,0 +1,123 @@
+// import * as fs from "node:fs";
+// import * as path from "node:path";
+import * as fs from "node:fs";
+import * as path from "node:path";
+import { execaSync } from "execa";
+// import { globbySync } from "globby";
+
+const $ = execaSync({ stdio: "inherit" });
+
+$`rm -rf ./dist`;
+
+function writePackageJson(dir: string, fields: Record<string, any>) {
+  const packageJsonPath = path.join(path.resolve(dir), "package.json");
+  fs.mkdirSync(dir, {
+    recursive: true,
+  });
+  console.log(`writing package.json to ${packageJsonPath}...`);
+  fs.writeFileSync(packageJsonPath, JSON.stringify(fields, null, 2));
+  return packageJsonPath;
+}
+
+console.log("building ESM...");
+const esmPkg = writePackageJson("./src", { type: "module" });
+$`pnpm tsc -p tsconfig.esm.json`;
+fs.rmSync(esmPkg, { force: true });
+
+// const esmDistDir = path.resolve("./dist/esm");
+// const esmPackageJsonPath = path.join(esmDistDir, "package.json");
+// fs.mkdirSync(esmDistDir, { recursive: true });
+// fs.writeFileSync(esmPackageJsonPath, JSON.stringify({ type: "module" }, null, 2));
+writePackageJson("./dist/esm", { type: "module" });
+
+console.log("building CJS...");
+const cjsPkg = writePackageJson("./src", { type: "commonjs" });
+$`pnpm tsc -p tsconfig.cjs.json`;
+fs.rmSync(cjsPkg, { force: true });
+// const cjsPath = "./dist/cjs";
+// const cjsDistDir = path.resolve(cjsPath);
+// const cjsPackageJsonPath = path.join(path.resolve(cjsPath), "package.json");
+// fs.mkdirSync(cjsDistDir, { recursive: true });
+// fs.writeFileSync(cjsPackageJsonPath, JSON.stringify({ type: "commonjs" }, null, 2));
+writePackageJson("./dist/cjs", { type: "commonjs" });
+
+console.log("building types...");
+$`pnpm tsc -p tsconfig.types.json`;
+// const typesPath = "./dist/types";
+// const typesDistDir = path.resolve(typesPath);
+// const typesPackageJsonPath = path.join(path.resolve(typesPath), "package.json");
+// fs.mkdirSync(typesDistDir, { recursive: true });
+// fs.writeFileSync(typesPackageJsonPath, JSON.stringify({ type: "module" }, null, 2));
+writePackageJson("./dist/types", { type: "commonjs" });
+
+console.log("DONE.");
+
+// /**
+//  * Synchronously builds TypeScript projects (ESM and CommonJS)
+//  * and recursively renames all .js files in the dist directory to .mjs.
+//  * Uses execa's $.sync for shell commands and globbySync for file finding.
+//  * Pipes subprocess logs (stdout/stderr) to the main process.
+//  */
+// // Resolve the absolute path to the 'dist' directory
+// const distDir = path.resolve("./dist");
+
+// // Check if the 'dist' directory exists and remove it if it does
+// // The 'recursive' and 'force' options ensure it works for non-empty directories
+// // and doesn't throw an error if the directory doesn't exist.
+// console.log("Cleaning up old dist directory..."); // Added log for clarity
+// if (fs.existsSync(distDir)) {
+//   // Use rmdirSync instead of rmSync for compatibility
+//   fs.rmSync(distDir, { recursive: true });
+//   console.log("Dist directory cleaned."); // Added log for clarity
+// } else {
+//   console.log("Dist directory does not exist, skipping clean-up."); // Added log for clarity
+// }
+
+// console.log("Compiling ES modules..."); // Added log for clarity
+// // Compile ES modules using pnpm tsc with the specified tsconfig
+// // $.sync executes the command synchronously and waits for it to complete.
+// // stdio: 'inherit' pipes the subprocess's stdout and stderr to the main process's console.
+// $`pnpm tsc -p tsconfig.esm.json`;
+// console.log("ES modules compiled."); // Added log for clarity
+
+// {
+//   console.log("Renaming .js files to .mjs in dist directory..."); // Added log for clarity
+//   const tsFiles = globbySync(`${distDir}/**/*.js`, {
+//     onlyFiles: true,
+//   });
+
+//   // Iterate over each found .js file and rename it to .mjs
+//   for (const file of tsFiles) {
+//     if (file.endsWith(".mjs")) continue; // skip if already .mjs
+//     // Create the new path by replacing the .js extension with .mjs
+//     const newPath = file.replace(/\.js$/, ".mjs");
+//     // Execute the 'mv' command synchronously to rename the file
+//     // Using $.sync for this shell command as well, with stdio inherited.
+//     fs.renameSync(file, newPath);
+//   }
+//   console.log("Files renamed to .mjs."); // Added log for clarity
+// }
+// console.log("Compiling CommonJS modules..."); // Added log for clarity
+// // Compile CommonJS modules using pnpm tsc with the specified tsconfig
+// // stdio: 'inherit' pipes the subprocess's stdout and stderr to the main process's console.
+// $`pnpm tsc -p tsconfig.cjs.json`;
+// console.log("CommonJS modules compiled."); // Added log for clarity
+
+// console.log("Build process completed successfully!"); // Added log for clarity
+// {
+//   console.log("Renaming .js files to .mjs in dist directory..."); // Added log for clarity
+//   const tsFiles = globbySync(`${distDir}/**/*.js`, {
+//     onlyFiles: true,
+//   });
+
+//   // Iterate over each found .js file and rename it to .mjs
+//   for (const file of tsFiles) {
+//     if (file.endsWith(".cjs")) continue; // skip if already .mjs
+//     // Create the new path by replacing the .js extension with .mjs
+//     const newPath = file.replace(/\.js$/, ".cjs");
+//     // Execute the 'mv' command synchronously to rename the file
+//     // Using $.sync for this shell command as well, with stdio inherited.
+//     fs.renameSync(file, newPath);
+//   }
+//   console.log("Files renamed to .cjs."); // Added log for clarity
+// }
diff --git a/packages/zod/package.json b/packages/zod/package.json
index 930ef5d7..bada2cf4 100644
--- a/packages/zod/package.json
+++ b/packages/zod/package.json
@@ -1,20 +1,19 @@
 {
   "name": "zod",
-  "version": "3.25.13",
+  "version": "3.25.32",
   "type": "module",
   "author": "Colin McDonnell <zod@colinhacks.com>",
   "description": "TypeScript-first schema declaration and validation library with static type inference",
-  "files": ["src", "dist"],
+  "files": ["dist", "v3", "v4", "v4-mini"],
   "funding": "https://github.com/sponsors/colinhacks",
   "homepage": "https://zod.dev",
   "keywords": ["typescript", "schema", "validation", "type", "inference"],
   "license": "MIT",
   "sideEffects": false,
-  "main": "./dist/commonjs/index.js",
+  "main": "./dist/cjs/index.js",
   "types": "./dist/types/index.d.ts",
   "module": "./dist/esm/index.js",
   "exports": {
-    "./package.json": "./package.json",
     ".": {
       "import": {
         "@zod/source": "./src/index.ts",
@@ -24,19 +23,19 @@
       "require": {
         "@zod/source": "./src/index.ts",
         "types": "./dist/types/index.d.ts",
-        "default": "./dist/commonjs/index.js"
+        "default": "./dist/cjs/index.js"
       }
     },
     "./v3": {
       "import": {
-        "@zod/source": "./src/v3/index.ts",
-        "types": "./dist/types/v3/index.d.ts",
-        "default": "./dist/esm/v3/index.js"
+        "@zod/source": "./src/index.ts",
+        "types": "./dist/types/index.d.ts",
+        "default": "./dist/esm/index.js"
       },
       "require": {
-        "@zod/source": "./src/v3/index.ts",
-        "types": "./dist/types/v3/index.d.ts",
-        "default": "./dist/commonjs/v3/index.js"
+        "@zod/source": "./src/index.ts",
+        "types": "./dist/types/index.d.ts",
+        "default": "./dist/cjs/index.js"
       }
     },
     "./v4": {
@@ -48,57 +47,40 @@
       "require": {
         "@zod/source": "./src/v4/index.ts",
         "types": "./dist/types/v4/index.d.ts",
-        "default": "./dist/commonjs/v4/index.js"
+        "default": "./dist/cjs/v4/index.js"
       }
     },
     "./v4-mini": {
-      "import": {
-        "@zod/source": "./src/v4/mini/index.ts",
-        "types": "./dist/types/v4/mini/index.d.ts",
-        "default": "./dist/esm/v4/mini/index.js"
-      },
-      "require": {
-        "@zod/source": "./src/v4/mini/index.ts",
-        "types": "./dist/types/v4/mini/index.d.ts",
-        "default": "./dist/commonjs/v4/mini/index.js"
-      }
+      "@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/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": {
-      "import": {
-        "@zod/source": "./src/v4/core/index.ts",
-        "types": "./dist/types/v4/core/index.d.ts",
-        "default": "./dist/esm/v4/core/index.js"
-      },
-      "require": {
-        "@zod/source": "./src/v4/core/index.ts",
-        "types": "./dist/types/v4/core/index.d.ts",
-        "default": "./dist/commonjs/v4/core/index.js"
-      }
+      "@zod/source": "./src/v4/core/index.ts",
+      "types": "./dist/types/v4/core/index.d.ts",
+      "import": "./dist/esm/v4/core/index.js",
+      "require": "./dist/cjs/v4/core/index.js"
     },
     "./v4/locales": {
-      "import": {
-        "@zod/source": "./src/v4/locales/index.ts",
-        "types": "./dist/types/v4/locales/index.d.ts",
-        "default": "./dist/esm/v4/locales/index.js"
-      },
-      "require": {
-        "@zod/source": "./src/v4/locales/index.ts",
-        "types": "./dist/types/v4/locales/index.d.ts",
-        "default": "./dist/commonjs/v4/locales/index.js"
-      }
+      "@zod/source": "./src/v4/locales/index.ts",
+      "types": "./dist/types/v4/locales/index.d.ts",
+      "import": "./dist/esm/v4/locales/index.js",
+      "require": "./dist/cjs/v4/locales/index.js"
     },
     "./v4/locales/*": {
-      "import": {
-        "@zod/source": "./src/v4/locales/*",
-        "types": "./dist/types/v4/locales/*",
-        "default": "./dist/esm/v4/locales/*"
-      },
-      "require": {
-        "@zod/source": "./src/v4/locales/*",
-        "types": "./dist/types/v4/locales/*",
-        "default": "./dist/commonjs/v4/locales/*"
-      }
-    }
+      "@zod/source": "./src/v4/locales/*",
+      "types": "./dist/types/v4/locales/*",
+      "import": "./dist/esm/v4/locales/*",
+      "require": "./dist/cjs/v4/locales/*"
+    },
+    "./package.json": "./package.json"
   },
   "tshy": {
     "exports": {
@@ -128,8 +110,8 @@
   },
   "scripts": {
     "clean": "rm -rf dist",
-    "build": "supershy",
-    "postbuild": "pnpm biome check --write . && tsx postbuild.ts",
+    "build": "tsx ./build.mts",
+    "postbuild": "pnpm biome check --write .",
     "test:watch": "pnpm vitest",
     "test": "pnpm vitest run",
     "bump:beta": "pnpm version \"v$(pnpm pkg get version | jq -r)-beta.$(date +%Y%m%dT%H%M%S)\"",
diff --git a/packages/zod/src/v4/classic/schemas.ts b/packages/zod/src/v4/classic/schemas.ts
index b8ca8970..19a0452d 100644
--- a/packages/zod/src/v4/classic/schemas.ts
+++ b/packages/zod/src/v4/classic/schemas.ts
@@ -35,8 +35,8 @@ export interface ZodType<out Output = unknown, out Input = unknown> extends core
     registry: R,
     ...meta: this extends R["_schema"]
       ? undefined extends R["_meta"]
-        ? [core.$ZodRegistry<R["_meta"], this>["_meta"]?]
-        : [core.$ZodRegistry<R["_meta"], this>["_meta"]]
+        ? [core.$replace<R["_meta"], this>?]
+        : [core.$replace<R["_meta"], this>]
       : ["Incompatible schema"]
   ): this;
 
@@ -116,7 +116,7 @@ export interface ZodType<out Output = unknown, out Input = unknown> extends core
 export const ZodType: core.$constructor<ZodType> = /*@__PURE__*/ core.$constructor("ZodType", (inst, def) => {
   core.$ZodType.init(inst, def);
   inst.def = def;
-  inst._def = def;
+  Object.defineProperty(inst, "_def", { value: def });
 
   // base methods
   inst.check = (...checks) => {
@@ -140,30 +140,6 @@ export const ZodType: core.$constructor<ZodType> = /*@__PURE__*/ core.$construct
     return inst;
   }) as any;
 
-  //  const parse: <T extends core.$ZodType>(
-  //   schema: T,
-  //   value: unknown,
-  //   _ctx?: core.ParseContext<core.$ZodIssue>
-  // ) => core.output<T> = /* @__PURE__ */ core._parse(ZodError, parse) as any;
-
-  //  const safeParse: <T extends core.$ZodType>(
-  //   schema: T,
-  //   value: unknown,
-  //   _ctx?: core.ParseContext<core.$ZodIssue>
-  // ) => ZodSafeParseResult<core.output<T>> = /* @__PURE__ */ core._safeParse(ZodError) as any;
-
-  //  const parseAsync: <T extends core.$ZodType>(
-  //   schema: T,
-  //   value: unknown,
-  //   _ctx?: core.ParseContext<core.$ZodIssue>
-  // ) => Promise<core.output<T>> = /* @__PURE__ */ core._parseAsync(ZodError) as any;
-
-  //  const safeParseAsync: <T extends core.$ZodType>(
-  //   schema: T,
-  //   value: unknown,
-  //   _ctx?: core.ParseContext<core.$ZodIssue>
-  // ) => Promise<ZodSafeParseResult<core.output<T>>> = /* @__PURE__ */ core._safeParseAsync(ZodError) as any;
-
   // parsing
   inst.parse = (data, params) => parse.parse(inst, data, params, { callee: inst.parse });
   inst.safeParse = (data, params) => parse.safeParse(inst, data, params);
@@ -262,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));
@@ -1039,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);
@@ -1049,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> {
@@ -1064,7 +1044,7 @@ export function keyof<T extends ZodObject>(schema: T): ZodLiteral<keyof T["_zod"
 // ZodObject
 
 export interface ZodObject<
-  // @ts-ignore cast variance
+  /** @ts-ignore Cast variance */
   out Shape extends core.$ZodShape = core.$ZodLooseShape,
   out Config extends core.$ZodObjectConfig = core.$ZodObjectConfig,
 > extends ZodType {
@@ -1091,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
    * });
@@ -1173,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;
@@ -1540,11 +1521,21 @@ export function nativeEnum<T extends util.EnumLike>(entries: T, params?: string
 export interface ZodLiteral<T extends util.Primitive = util.Primitive> extends ZodType {
   _zod: core.$ZodLiteralInternals<T>;
   values: Set<T>;
+  /** @legacy Use `.values` instead. Accessing this property will throw an error if the literal accepts multiple values. */
+  value: T;
 }
 export const ZodLiteral: core.$constructor<ZodLiteral> = /*@__PURE__*/ core.$constructor("ZodLiteral", (inst, def) => {
   core.$ZodLiteral.init(inst, def);
   ZodType.init(inst, def);
   inst.values = new Set(def.values);
+  Object.defineProperty(inst, "value", {
+    get() {
+      if (def.values.length > 1) {
+        throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");
+      }
+      return def.values[0];
+    },
+  });
 });
 
 export function literal<const T extends Array<util.Literal>>(
@@ -1962,10 +1953,10 @@ export function check<O = unknown>(fn: core.CheckFn<O>, params?: string | core.$
   return ch;
 }
 
-export function custom<O = unknown, I = O>(
-  fn?: (data: O) => unknown,
+export function custom<O>(
+  fn?: (data: unknown) => unknown,
   _params?: string | core.$ZodCustomParams | undefined
-): ZodCustom<O, I> {
+): ZodCustom<O, O> {
   return core._custom(ZodCustom, fn ?? (() => true), _params) as any;
 }
 
@@ -2012,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 5202d58e..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,
@@ -313,7 +321,7 @@ export const $ZodCheckNumberFormat: core.$constructor<$ZodCheckNumberFormat> = /
               input,
               code: "too_big",
               maximum: Number.MAX_SAFE_INTEGER,
-              note: "Integers must be within the the safe integer range.",
+              note: "Integers must be within the safe integer range.",
               inst,
               origin,
               continue: !def.abort,
@@ -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/core.ts b/packages/zod/src/v4/core/core.ts
index 707c5a05..fc7f86c6 100644
--- a/packages/zod/src/v4/core/core.ts
+++ b/packages/zod/src/v4/core/core.ts
@@ -14,42 +14,46 @@ export /*@__NO_SIDE_EFFECTS__*/ function $constructor<T extends ZodTrait, D = T[
   initializer: (inst: T, def: D) => void,
   params?: { Parent?: typeof Class }
 ): $constructor<T, D> {
-  const Parent = params?.Parent ?? Object;
+  function init(inst: T, def: D) {
+    Object.defineProperty(inst, "_zod", {
+      value: inst._zod ?? {},
+      enumerable: false,
+    });
+
+    inst._zod.traits ??= new Set();
 
-  class _ extends Parent {
-    constructor(def: D) {
-      super();
-      const th = this as any;
-      _.init(th, def);
-      th._zod.deferred ??= [];
-      for (const fn of th._zod.deferred) {
-        fn();
-      }
+    inst._zod.traits.add(name);
+    initializer(inst, def);
+    // support prototype modifications
+    for (const k in _.prototype) {
+      Object.defineProperty(inst, k, { value: (_.prototype as any)[k].bind(inst) });
     }
-    static init(inst: T, def: D) {
-      Object.defineProperty(inst, "_zod", {
-        value: inst._zod ?? {},
-        enumerable: false,
-      });
-      // inst._zod ??= {} as any;
-      inst._zod.traits ??= new Set();
-      // const seen = inst._zod.traits.has(name);
-
-      inst._zod.traits.add(name);
-      initializer(inst, def);
-      // support prototype modifications
-      for (const k in _.prototype) {
-        Object.defineProperty(inst, k, { value: (_.prototype as any)[k].bind(inst) });
-      }
-      inst._zod.constr = _;
-      inst._zod.def = def;
+    inst._zod.constr = _;
+    inst._zod.def = def;
+  }
+
+  // doesn't work if Parent has a constructor with arguments
+  const Parent = params?.Parent ?? Object;
+  class Definition extends Parent {}
+  Object.defineProperty(Definition, "name", { value: name });
+
+  function _(this: any, def: D) {
+    const inst = params?.Parent ? new Definition() : this;
+    init(inst, def);
+    inst._zod.deferred ??= [];
+    for (const fn of inst._zod.deferred) {
+      fn();
     }
+    return inst;
+  }
 
-    static override [Symbol.hasInstance](inst: any) {
+  Object.defineProperty(_, "init", { value: init });
+  Object.defineProperty(_, Symbol.hasInstance, {
+    value: (inst: any) => {
       if (params?.Parent && inst instanceof params.Parent) return true;
       return inst?._zod?.traits?.has(name);
-    }
-  }
+    },
+  });
   Object.defineProperty(_, "name", { value: name });
   return _ as any;
 }
diff --git a/packages/zod/src/v4/core/errors.ts b/packages/zod/src/v4/core/errors.ts
index 59fb738b..fff075e5 100644
--- a/packages/zod/src/v4/core/errors.ts
+++ b/packages/zod/src/v4/core/errors.ts
@@ -86,7 +86,7 @@ export interface $ZodIssueInvalidValue<Input = unknown> extends $ZodIssueBase {
 }
 
 export interface $ZodIssueCustom extends $ZodIssueBase {
-  readonly code?: "custom";
+  readonly code: "custom";
   readonly params?: Record<string, any> | undefined;
   readonly input: unknown;
 }
@@ -149,6 +149,8 @@ export type $ZodIssue =
   | $ZodIssueInvalidValue
   | $ZodIssueCustom;
 
+export type $ZodIssueCode = $ZodIssue["code"];
+
 export type $ZodRawIssue<T extends $ZodIssueBase = $ZodIssue> = T extends any ? RawIssue<T> : never;
 type RawIssue<T extends $ZodIssueBase> = util.Flatten<
   util.MakePartial<T, "message" | "path"> & {
@@ -190,7 +192,6 @@ const initializer = (inst: $ZodError, def: $ZodIssue[]): void => {
     value: def,
     enumerable: false,
   });
-  // inst.message = JSON.stringify(def, util.jsonStringifyReplacer, 2);
   Object.defineProperty(inst, "message", {
     get() {
       return JSON.stringify(def, util.jsonStringifyReplacer, 2);
@@ -198,22 +199,6 @@ const initializer = (inst: $ZodError, def: $ZodIssue[]): void => {
     enumerable: true,
     // configurable: false,
   });
-  // inst.toString = () => inst.message;
-
-  // inst.message = `Invalid input`;
-  // Object.defineProperty(inst, "message", {
-  //   get() {
-  //     return (
-  //       "\n" +
-  //       inst.issues
-  //         .map((iss) => {
-  //           return `✖ ${iss.message}${iss.path.length ? ` [${iss.path.join(".")}]` : ""}`;
-  //         })
-  //         .join("\n")
-  //     );
-  //   },
-  //   enumerable: false,
-  // });
 };
 
 export const $ZodError: $constructor<$ZodError> = $constructor("$ZodError", initializer);
diff --git a/packages/zod/src/v4/core/function.ts b/packages/zod/src/v4/core/function.ts
index a8057cb5..a3bae95e 100644
--- a/packages/zod/src/v4/core/function.ts
+++ b/packages/zod/src/v4/core/function.ts
@@ -12,40 +12,55 @@ import type * as util from "./util.js";
 //////////                      //////////
 //////////////////////////////////////////
 //////////////////////////////////////////
-export interface $ZodFunctionDef /* extends schemas.$ZodTypeDef */ {
+export interface $ZodFunctionDef<
+  In extends $ZodFunctionIn = $ZodFunctionIn,
+  Out extends $ZodFunctionOut = $ZodFunctionOut,
+> {
   type: "function";
-  input: $ZodFunctionArgs | null;
-  output: schemas.$ZodType | null;
+  input: In;
+  output: Out;
 }
 
 export type $ZodFunctionArgs = schemas.$ZodType<unknown[], unknown[]>;
+export type $ZodFunctionIn = $ZodFunctionArgs | null;
+export type $ZodFunctionOut = schemas.$ZodType | null;
 
-export type $InferInnerFunctionType<Args extends $ZodFunctionArgs, Returns extends schemas.$ZodType> = (
-  ...args: Args["_zod"]["output"]
-) => Returns["_zod"]["input"];
+export type $InferInnerFunctionType<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
+  ...args: null extends Args ? never[] : NonNullable<Args>["_zod"]["output"]
+) => null extends Returns ? unknown : NonNullable<Returns>["_zod"]["input"];
 
-export type $InferInnerFunctionTypeAsync<Args extends $ZodFunctionArgs, Returns extends schemas.$ZodType> = (
-  ...args: Args["_zod"]["output"]
-) => util.MaybeAsync<Returns["_zod"]["input"]>;
+export type $InferInnerFunctionTypeAsync<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
+  ...args: null extends Args ? never[] : NonNullable<Args>["_zod"]["output"]
+) => null extends Returns ? unknown : util.MaybeAsync<NonNullable<Returns>["_zod"]["input"]>;
 
-export type $InferOuterFunctionType<Args extends $ZodFunctionArgs, Returns extends schemas.$ZodType> = (
-  ...args: Args["_zod"]["input"]
-) => Returns["_zod"]["output"];
+export type $InferOuterFunctionType<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
+  ...args: null extends Args ? never[] : NonNullable<Args>["_zod"]["input"]
+) => null extends Returns ? unknown : NonNullable<Returns>["_zod"]["output"];
 
-export type $InferOuterFunctionTypeAsync<Args extends $ZodFunctionArgs, Returns extends schemas.$ZodType> = (
-  ...args: Args["_zod"]["input"]
-) => util.MaybeAsync<Returns["_zod"]["output"]>;
+export type $InferOuterFunctionTypeAsync<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
+  ...args: null extends Args ? never[] : NonNullable<Args>["_zod"]["input"]
+) => null extends Returns ? unknown : util.MaybeAsync<NonNullable<Returns>["_zod"]["output"]>;
 
 export class $ZodFunction<
-  Args extends $ZodFunctionArgs = $ZodFunctionArgs,
-  Returns extends schemas.$ZodType = schemas.$ZodType,
+  Args extends $ZodFunctionIn = $ZodFunctionIn,
+  Returns extends $ZodFunctionOut = $ZodFunctionOut,
 > {
-  _def: $ZodFunctionDef;
+  // _zod!: {
+  //   def: $ZodFunctionDef<Args, Returns>;
+  //   input: $InferInnerFunctionType<Args, Returns>;
+  //   output: $InferOuterFunctionType<Args, Returns>;
+  // };
+
+  def: $ZodFunctionDef<Args, Returns>;
+
+  /** @deprecated */
+  _def!: $ZodFunctionDef<Args, Returns>;
   _input!: $InferInnerFunctionType<Args, Returns>;
   _output!: $InferOuterFunctionType<Args, Returns>;
 
-  constructor(def: $ZodFunctionDef) {
+  constructor(def: $ZodFunctionDef<Args, Returns>) {
     this._def = def;
+    this.def = def;
   }
 
   implement<F extends $InferInnerFunctionType<Args, Returns>>(
@@ -59,7 +74,7 @@ export class $ZodFunction<
       if (!Array.isArray(parsedArgs)) {
         throw new Error("Invalid arguments schema: not an array or tuple schema.");
       }
-      const output = func(...parsedArgs);
+      const output = func(...(parsedArgs as any));
       return this._def.output ? parse(this._def.output, output, undefined, { callee: impl }) : output;
     }) as any;
     return impl;
@@ -77,17 +92,17 @@ export class $ZodFunction<
       if (!Array.isArray(parsedArgs)) {
         throw new Error("Invalid arguments schema: not an array or tuple schema.");
       }
-      const output = await func(...parsedArgs);
+      const output = await func(...(parsedArgs as any));
       return this._def.output ? parseAsync(this._def.output, output, undefined, { callee: impl }) : output;
     }) as any;
     return impl;
   }
 
-  input<const Items extends util.TupleItems, const Rest extends schemas.$ZodType | null = null>(
+  input<const Items extends util.TupleItems, const Rest extends $ZodFunctionOut = null>(
     args: Items,
     rest?: Rest
   ): $ZodFunction<schemas.$ZodTuple<Items, Rest>, Returns>;
-  input<NewArgs extends $ZodFunctionArgs>(args: NewArgs): $ZodFunction<NewArgs, Returns>;
+  input<NewArgs extends $ZodFunctionIn>(args: NewArgs): $ZodFunction<NewArgs, Returns>;
   input(...args: any[]): $ZodFunction<any, Returns> {
     if (Array.isArray(args[0])) {
       return new $ZodFunction({
@@ -116,19 +131,28 @@ export class $ZodFunction<
   }
 }
 
-export interface $ZodFunctionParams<I extends $ZodFunctionArgs, O extends schemas.$ZodType> {
+export interface $ZodFunctionParams<I extends $ZodFunctionIn, O extends schemas.$ZodType> {
   input?: I;
   output?: O;
 }
 
 function _function(): $ZodFunction;
+function _function<const In extends Array<schemas.$ZodType> = Array<schemas.$ZodType>>(params: {
+  input: In;
+}): $ZodFunction<$ZodTuple<In, null>, null>;
+function _function<const In extends $ZodFunctionIn = $ZodFunctionIn>(params: {
+  input: In;
+}): $ZodFunction<In, null>;
+function _function<const Out extends $ZodFunctionOut = $ZodFunctionOut>(params: {
+  output: Out;
+}): $ZodFunction<null, Out>;
 function _function<
-  const In extends Array<schemas.$ZodType> = Array<schemas.$ZodType>,
+  In extends $ZodFunctionIn = $ZodFunctionIn,
   Out extends schemas.$ZodType = schemas.$ZodType,
->(params?: { input?: In; output?: Out }): $ZodFunction<$ZodTuple<In, null>, Out>;
-function _function<In extends $ZodFunctionArgs = $ZodFunctionArgs, Out extends schemas.$ZodType = schemas.$ZodType>(
-  params?: $ZodFunctionParams<In, Out>
-): $ZodFunction<In, Out>;
+>(params?: {
+  input: In;
+  output: Out;
+}): $ZodFunction<In, Out>;
 function _function(params?: {
   output?: schemas.$ZodType;
   input?: $ZodFunctionArgs | Array<schemas.$ZodType>;
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 d1e976eb..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"
@@ -81,7 +80,6 @@ export interface $ZodTypeDef {
   checks?: checks.$ZodCheck<never>[];
 }
 
-// @ts-ignore
 /** @internal */
 export interface $ZodTypeInternals<out O = unknown, out I = unknown> {
   /** The `@zod/core` version of this schema */
@@ -291,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;
   }>;
 }
 
@@ -302,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 {
@@ -427,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)) {
@@ -446,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,
           });
@@ -689,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`;
   });
 });
 
@@ -712,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) => {
@@ -792,28 +781,6 @@ export const $ZodCIDRv6: core.$constructor<$ZodCIDRv6> = /*@__PURE__*/ core.$con
   }
 );
 
-//////////////////////////////   ZodIP   //////////////////////////////
-
-// export interface $ZodIPDef extends $ZodStringFormatDef<"ip"> {
-//   version?: "v4" | "v6";
-// }
-
-// export interface $ZodIPInternals extends $ZodStringFormatInternals<"ip"> {
-//   def: $ZodIPDef;
-// }
-
-// export interface $ZodIP extends $ZodType {
-//   _zod: $ZodIPInternals;
-// }
-
-// export const $ZodIP: core.$constructor<$ZodIP> = /*@__PURE__*/ core.$constructor("$ZodIP", (inst, def): void => {
-//   if (def.version === "v4") def.pattern ??= regexes.ipv4;
-//   else if (def.version === "v6") def.pattern ??= regexes.ipv6;
-//   else def.pattern ??= regexes.ip;
-//   $ZodStringFormat.init(inst, def);
-
-// });
-
 //////////////////////////////   ZodBase64   //////////////////////////////
 export function isValidBase64(data: string): boolean {
   if (data === "") return true;
@@ -894,34 +861,6 @@ export const $ZodBase64URL: core.$constructor<$ZodBase64URL> = /*@__PURE__*/ cor
   }
 );
 
-//////////////////////////////   ZodJSONString   //////////////////////////////
-
-// export interface $ZodJSONStringDef extends $ZodStringFormatDef<"json_string"> {}
-// export Def $ZodJSONStringDef extends $ZodStringFormatInternals {
-// export interface $ZodJSONStringInternals extends $ZodStringFormatInternals {
-//   _def: $ZodJSONStringDef;
-// }
-
-// export const $ZodJSONString: core.$constructor<{_zod: $ZodJSONStringInternals}> = /*@__PURE__*/ core.$constructor(
-//   "$ZodJSONString",
-//   (inst, def): void => {
-//     $ZodStringFormat.init(inst, def);
-//     inst._zod.check = (payload) => {
-//       try {
-//         JSON.parse(payload.value);
-//         return;
-//       } catch {
-//         payload.issues.push({
-//           code: "invalid_format",
-//           format: "json_string",
-//           input: payload.value,
-//           inst,
-//         });
-//       }
-//     };
-//   }
-// );
-
 //////////////////////////////   ZodE164   //////////////////////////////
 
 export interface $ZodE164Def extends $ZodStringFormatDef<"e164"> {}
@@ -1582,7 +1521,7 @@ export interface $ZodObjectDef<Shape extends $ZodShape = $ZodShape> extends $Zod
 }
 
 export interface $ZodObjectInternals<
-  // @ts-ignore Cast variance
+  /** @ts-ignore Cast variance */
   out Shape extends Readonly<$ZodShape> = Readonly<$ZodShape>,
   out Config extends $ZodObjectConfig = $ZodObjectConfig,
 > extends $ZodTypeInternals<any, any> {
@@ -1590,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
@@ -1676,7 +1614,7 @@ export type $catchall<T extends $ZodType> = {
   in: { [k: string]: core.input<T> };
 };
 export interface $ZodObject<
-  // @ts-ignore Cast variance
+  /** @ts-ignore Cast variance */
   out Shape extends Readonly<$ZodShape> = Readonly<$ZodShape>,
   out Params extends $ZodObjectConfig = $ZodObjectConfig,
 > extends $ZodType {
@@ -1688,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 {
@@ -1833,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(
@@ -2714,7 +2657,7 @@ export interface $ZodEnumDef<T extends util.EnumLike = util.EnumLike> extends $Z
 }
 
 export interface $ZodEnumInternals<
-  // @ts-ignore Cast variance
+  /** @ts-ignore Cast variance */
   out T extends util.EnumLike = util.EnumLike,
 > extends $ZodTypeInternals<$InferEnumOutput<T>, $InferEnumInput<T>> {
   // enum: T;
@@ -2778,7 +2721,7 @@ export interface $ZodLiteralDef extends $ZodTypeDef {
 
 export interface $ZodLiteralInternals<T extends util.Primitive = util.Primitive> extends $ZodTypeInternals<T, T> {
   def: $ZodLiteralDef;
-  values: util.PrimitiveSet;
+  values: Set<T>;
   pattern: RegExp;
   isst: errors.$ZodIssueInvalidValue;
 }
@@ -2866,7 +2809,10 @@ export const $ZodLiteral: core.$constructor<$ZodLiteral> = /*@__PURE__*/ core.$c
 //////////////////////////////////////////
 
 // provide a fallback in case the File interface isn't provided in the environment
-interface File {}
+declare global {
+  interface File {}
+}
+
 export interface $ZodFileDef extends $ZodTypeDef {
   type: "file";
 }
diff --git a/packages/zod/src/v4/core/to-json-schema.ts b/packages/zod/src/v4/core/to-json-schema.ts
index 7d8a0aab..0d25ca04 100644
--- a/packages/zod/src/v4/core/to-json-schema.ts
+++ b/packages/zod/src/v4/core/to-json-schema.ts
@@ -16,7 +16,7 @@ interface JSONSchemaGeneratorParams {
    * - `"any"` — Unrepresentable types become `{}` */
   unrepresentable?: "throw" | "any";
   /** Arbitrary custom logic that can be used to modify the generated JSON Schema. */
-  override?: (ctx: { zodSchema: schemas.$ZodType; jsonSchema: JSONSchema.BaseSchema }) => void;
+  override?: (ctx: { zodSchema: schemas.$ZodTypes; jsonSchema: JSONSchema.BaseSchema }) => void;
   /** Whether to extract the `"input"` or `"output"` type. Relevant to transforms, Error converting schema to JSONz, defaults, coerced primitives, etc.
    * - `"output" — Default. Convert the output schema.
    * - `"input"` — Convert the input schema. */
@@ -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 {
@@ -73,7 +74,7 @@ export class JSONSchemaGenerator {
   metadataRegistry: $ZodRegistry<Record<string, any>>;
   target: "draft-7" | "draft-2020-12";
   unrepresentable: "throw" | "any";
-  override: (ctx: { zodSchema: schemas.$ZodType; jsonSchema: JSONSchema.BaseSchema }) => void;
+  override: (ctx: { zodSchema: schemas.$ZodTypes; jsonSchema: JSONSchema.BaseSchema }) => void;
   io: "input" | "output";
 
   counter = 0;
@@ -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;
         }
@@ -285,7 +291,11 @@ export class JSONSchemaGenerator {
 
           // catchall
           if (def.catchall?._zod.def.type === "never") {
+            // strict
             json.additionalProperties = false;
+          } else if (!def.catchall) {
+            // regular
+            if (this.io === "output") json.additionalProperties = false;
           } else if (def.catchall) {
             json.additionalProperties = this.process(def.catchall, {
               ...params,
@@ -604,7 +614,6 @@ export class JSONSchemaGenerator {
       // wipe away all properties except $ref
       const schema = seen.schema;
       for (const key in schema) {
-        // @ts-ignore
         delete schema[key];
         schema.$ref = ref;
       }
@@ -691,7 +700,7 @@ export class JSONSchemaGenerator {
 
       if (!seen.isParent)
         this.override({
-          zodSchema,
+          zodSchema: zodSchema as schemas.$ZodTypes,
           jsonSchema: schema,
         });
     };
@@ -700,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()) {
@@ -719,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 = "https://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 d4b9b9a4..71f439f9 100644
--- a/packages/zod/src/v4/mini/schemas.ts
+++ b/packages/zod/src/v4/mini/schemas.ts
@@ -14,8 +14,8 @@ export interface ZodMiniType<out Output = unknown, out Input = unknown> extends
     registry: R,
     ...meta: this extends R["_schema"]
       ? undefined extends R["_meta"]
-        ? [core.$ZodRegistry<R["_meta"], this>["_meta"]?]
-        : [core.$ZodRegistry<R["_meta"], this>["_meta"]]
+        ? [core.$replace<R["_meta"], this>?]
+        : [core.$replace<R["_meta"], this>]
       : ["Incompatible schema"]
   ): this;
   brand<T extends PropertyKey = PropertyKey>(
@@ -282,19 +282,6 @@ export function ksuid(params?: string | core.$ZodKSUIDParams): ZodMiniKSUID {
   return core._ksuid(ZodMiniKSUID, params);
 }
 
-// ZodMiniIP
-// export interface ZodMiniIP extends ZodMiniStringFormat<"ip"> {
-//   _zod: core.$ZodIPInternals;
-// }
-// export const ZodMiniIP: core.$constructor<ZodMiniIP> = /*@__PURE__*/ core.$constructor("ZodMiniIP", (inst, def) => {
-//   core.$ZodIP.init(inst, def);
-//   ZodMiniStringFormat.init(inst, def);
-// });
-
-// export function ip(params?: string | core.$ZodIPParams): ZodMiniIP {
-//   return core._ip(ZodMiniIP, params);
-// }
-
 // ZodMiniIPv4
 export interface ZodMiniIPv4 extends ZodMiniStringFormat<"ipv4"> {
   _zod: core.$ZodIPv4Internals;
@@ -695,7 +682,7 @@ export function keyof<T extends ZodMiniObject>(schema: T): ZodMiniLiteral<keyof
 
 // ZodMiniObject
 export interface ZodMiniObject<
-  // @ts-ignore Cast variance
+  /** @ts-ignore Cast variance */
   out Shape extends core.$ZodShape = core.$ZodShape,
   out Config extends core.$ZodObjectConfig = core.$ZodObjectConfig,
 > extends ZodMiniType {
@@ -1513,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/packages/zod/tsconfig.cjs.json b/packages/zod/tsconfig.cjs.json
new file mode 100644
index 00000000..87658db7
--- /dev/null
+++ b/packages/zod/tsconfig.cjs.json
@@ -0,0 +1,12 @@
+{
+  "extends": "../../.configs/tsconfig.base.json",
+  "compilerOptions": {
+    "rootDir": "./src",
+    "module": "Node16",
+    "moduleResolution": "node16",
+    "customConditions": ["@zod/source"],
+    "outDir": "./dist/cjs"
+  },
+  "include": ["src"],
+  "exclude": ["**/tests/**"]
+}
diff --git a/packages/zod/tsconfig.esm.json b/packages/zod/tsconfig.esm.json
new file mode 100644
index 00000000..dc020bde
--- /dev/null
+++ b/packages/zod/tsconfig.esm.json
@@ -0,0 +1,12 @@
+{
+  "extends": "../../.configs/tsconfig.base.json",
+  "compilerOptions": {
+    "rootDir": "./src",
+    "module": "esnext",
+    "moduleResolution": "bundler",
+    "customConditions": ["@zod/source"],
+    "outDir": "./dist/esm"
+  },
+  "include": ["src"],
+  "exclude": ["**/tests/**"]
+}
diff --git a/packages/zod/tsconfig.json b/packages/zod/tsconfig.json
index d71e7512..36fb9c8d 100644
--- a/packages/zod/tsconfig.json
+++ b/packages/zod/tsconfig.json
@@ -1,9 +1,6 @@
 {
   "extends": "../../.configs/tsconfig.base.json",
   "compilerOptions": {
-    "isolatedDeclarations": false,
-    "composite": true,
-    "exactOptionalPropertyTypes": true,
     "module": "NodeNext",
     "moduleResolution": "nodenext",
     "customConditions": ["@zod/source"]
diff --git a/packages/zod/tsconfig.types.json b/packages/zod/tsconfig.types.json
new file mode 100644
index 00000000..cd30daa5
--- /dev/null
+++ b/packages/zod/tsconfig.types.json
@@ -0,0 +1,15 @@
+{
+  "extends": "../../.configs/tsconfig.base.json",
+  "compilerOptions": {
+    "rootDir": "./src",
+    "module": "Node16",
+    "moduleResolution": "node16",
+    "customConditions": ["@zod/source"],
+    "declaration": true,
+    "emitDeclarationOnly": true,
+    "outDir": "./dist/types",
+    "removeComments": false
+  },
+  "include": ["src"],
+  "exclude": ["**/tests/**"]
+}
diff --git a/packages/zod/v3/index.d.ts b/packages/zod/v3/index.d.ts
new file mode 100644
index 00000000..5e93f214
--- /dev/null
+++ b/packages/zod/v3/index.d.ts
@@ -0,0 +1,1 @@
+export * from "../dist/types/v3/index.d.ts";
diff --git a/packages/zod/v3/index.js b/packages/zod/v3/index.js
new file mode 100644
index 00000000..ee04209d
--- /dev/null
+++ b/packages/zod/v3/index.js
@@ -0,0 +1,1 @@
+export * from "../dist/esm/v3/index.js";
diff --git a/packages/zod/v4-mini/index.d.ts b/packages/zod/v4-mini/index.d.ts
new file mode 100644
index 00000000..63288d8c
--- /dev/null
+++ b/packages/zod/v4-mini/index.d.ts
@@ -0,0 +1,1 @@
+export * from "../dist/types/v4/mini/index.d.ts";
diff --git a/packages/zod/v4-mini/index.js b/packages/zod/v4-mini/index.js
new file mode 100644
index 00000000..509f8a8d
--- /dev/null
+++ b/packages/zod/v4-mini/index.js
@@ -0,0 +1,1 @@
+export * from "../dist/esm/v4/mini/index.js";
diff --git a/packages/zod/v4/core/index.d.ts b/packages/zod/v4/core/index.d.ts
new file mode 100644
index 00000000..dd890b7f
--- /dev/null
+++ b/packages/zod/v4/core/index.d.ts
@@ -0,0 +1,1 @@
+export * from "../../dist/types/v4/core/index.d.ts";
diff --git a/packages/zod/v4/core/index.js b/packages/zod/v4/core/index.js
new file mode 100644
index 00000000..6e6c051c
--- /dev/null
+++ b/packages/zod/v4/core/index.js
@@ -0,0 +1,1 @@
+export * from "../../dist/esm/v4/core/index.js";
diff --git a/packages/zod/v4/index.d.ts b/packages/zod/v4/index.d.ts
new file mode 100644
index 00000000..aa34be52
--- /dev/null
+++ b/packages/zod/v4/index.d.ts
@@ -0,0 +1,1 @@
+export * from "../dist/types/v4/index.d.ts";
diff --git a/packages/zod/v4/index.js b/packages/zod/v4/index.js
new file mode 100644
index 00000000..ad08461b
--- /dev/null
+++ b/packages/zod/v4/index.js
@@ -0,0 +1,1 @@
+export * from "../dist/esm/v4/index.js";
diff --git a/packages/zod/v4/locales/en.d.ts b/packages/zod/v4/locales/en.d.ts
new file mode 100644
index 00000000..41378370
--- /dev/null
+++ b/packages/zod/v4/locales/en.d.ts
@@ -0,0 +1,2 @@
+export * from "../../dist/types/v4/locales/en.d.ts";
+export { default } from "../../dist/types/v4/locales/en.d.ts";
diff --git a/packages/zod/v4/locales/en.js b/packages/zod/v4/locales/en.js
new file mode 100644
index 00000000..9d4b4794
--- /dev/null
+++ b/packages/zod/v4/locales/en.js
@@ -0,0 +1,2 @@
+export * from "../../dist/esm/v4/locales/en.js";
+export { default } from "../../dist/esm/v4/locales/en.js";
diff --git a/packages/zod/v4/locales/index.d.ts b/packages/zod/v4/locales/index.d.ts
new file mode 100644
index 00000000..2f123947
--- /dev/null
+++ b/packages/zod/v4/locales/index.d.ts
@@ -0,0 +1,1 @@
+export * from "../../dist/types/v4/locales/index.d.ts";
diff --git a/packages/zod/v4/locales/index.js b/packages/zod/v4/locales/index.js
new file mode 100644
index 00000000..5e244534
--- /dev/null
+++ b/packages/zod/v4/locales/index.js
@@ -0,0 +1,1 @@
+export * from "../../dist/esm/v4/locales/index.js";
diff --git a/play.ts b/play.ts
index 92940a52..a565b160 100644
--- a/play.ts
+++ b/play.ts
@@ -1,3 +1,3 @@
-import { z } from "zod";
+import { z } from "zod/v4";
 
-z;
+console.dir(z.string(), { depth: null });
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4ab2934e..50199364 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -41,6 +41,9 @@ importers:
       execa:
         specifier: ^9.5.2
         version: 9.5.2
+      globby:
+        specifier: ^14.1.0
+        version: 14.1.0
       husky:
         specifier: ^7.0.4
         version: 7.0.4
@@ -56,6 +59,9 @@ importers:
       prettier:
         specifier: ^3.5.3
         version: 3.5.3
+      semver:
+        specifier: ^7.7.2
+        version: 7.7.2
       supershy:
         specifier: ^1.0.0
         version: 1.0.0
@@ -108,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@packages+zod)
+        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)
@@ -317,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'}
@@ -957,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==}
@@ -1238,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==}
 
@@ -1283,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:
@@ -1335,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': '*'
@@ -1348,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': '*'
@@ -1361,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': '*'
@@ -1441,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:
@@ -1476,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:
@@ -1489,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': '*'
@@ -1572,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:
@@ -1598,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:
@@ -1624,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:
@@ -1663,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': '*'
@@ -1715,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': '*'
@@ -1755,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': '*'
@@ -1830,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:
@@ -1839,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:
@@ -1866,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:
@@ -1875,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:
@@ -1884,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:
@@ -1910,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'}
@@ -2284,6 +2476,10 @@ packages:
     resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
     engines: {node: '>=10'}
 
+  '@sindresorhus/merge-streams@2.3.0':
+    resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==}
+    engines: {node: '>=18'}
+
   '@sindresorhus/merge-streams@4.0.0':
     resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
     engines: {node: '>=18'}
@@ -2437,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==}
@@ -2550,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==}
@@ -2677,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==}
 
@@ -2763,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'}
@@ -3105,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:
@@ -3375,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'}
@@ -3427,6 +3619,10 @@ packages:
     engines: {node: '>=12'}
     deprecated: Glob versions prior to v9 are no longer supported
 
+  globby@14.1.0:
+    resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==}
+    engines: {node: '>=18'}
+
   gopd@1.2.0:
     resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
     engines: {node: '>= 0.4'}
@@ -3560,6 +3756,10 @@ packages:
     resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==}
     engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 
+  ignore@7.0.4:
+    resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==}
+    engines: {node: '>= 4'}
+
   image-size@2.0.1:
     resolution: {integrity: sha512-NI6NK/2zchlZopsQrcVIS7jxA0/rtIy74B+/rx5s7rKQyFebmQjZVhzxXgRZJROk+WhhOq+S6sUaODxp0L5hfg==}
     engines: {node: '>=16.x'}
@@ -3937,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==}
 
@@ -3961,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'}
@@ -4428,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==}
@@ -4457,6 +4667,10 @@ packages:
     resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
     engines: {node: 20 || >=22}
 
+  path-type@6.0.0:
+    resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==}
+    engines: {node: '>=18'}
+
   pathe@1.1.2:
     resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
 
@@ -4552,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==}
 
@@ -4566,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==}
 
@@ -4701,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==}
 
@@ -4824,16 +5044,6 @@ packages:
     resolution: {integrity: sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==}
     engines: {node: '>=6'}
 
-  semver@7.6.3:
-    resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
-    engines: {node: '>=10'}
-    hasBin: true
-
-  semver@7.7.1:
-    resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==}
-    engines: {node: '>=10'}
-    hasBin: true
-
   semver@7.7.2:
     resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
     engines: {node: '>=10'}
@@ -4889,6 +5099,10 @@ packages:
     resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==}
     engines: {node: '>=8'}
 
+  slash@5.1.0:
+    resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
+    engines: {node: '>=14.16'}
+
   slice-ansi@3.0.0:
     resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==}
     engines: {node: '>=8'}
@@ -5307,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
@@ -5588,7 +5802,7 @@ snapshots:
       commander: 10.0.1
       marked: 9.1.6
       marked-terminal: 7.3.0(marked@9.1.6)
-      semver: 7.7.1
+      semver: 7.7.2
 
   '@arethetypeswrong/core@0.17.4':
     dependencies:
@@ -5597,7 +5811,7 @@ snapshots:
       cjs-module-lexer: 1.4.3
       fflate: 0.8.2
       lru-cache: 10.4.3
-      semver: 7.7.1
+      semver: 7.7.2
       typescript: 5.6.1-rc
       validate-npm-package-name: 5.0.1
 
@@ -5627,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
@@ -6010,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@packages+zod)':
+  '@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@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)
@@ -6065,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@packages+zod)':
+  '@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@packages+zod)
+      '@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'
@@ -6078,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@packages+zod)':
+  '@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@packages+zod)
+      '@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
@@ -6094,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:
@@ -6213,11 +6432,11 @@ snapshots:
   '@npmcli/fs@2.1.2':
     dependencies:
       '@gar/promisify': 1.1.3
-      semver: 7.7.1
+      semver: 7.7.2
 
   '@npmcli/fs@3.1.1':
     dependencies:
-      semver: 7.7.1
+      semver: 7.7.2
 
   '@npmcli/git@4.1.0':
     dependencies:
@@ -6227,7 +6446,7 @@ snapshots:
       proc-log: 3.0.0
       promise-inflight: 1.0.1
       promise-retry: 2.0.1
-      semver: 7.7.1
+      semver: 7.7.2
       which: 3.0.1
     transitivePeerDependencies:
       - bluebird
@@ -6421,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': {}
@@ -6460,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)
@@ -6520,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:
@@ -6614,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
@@ -6646,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)
@@ -6657,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:
@@ -6769,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)
@@ -6789,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)
@@ -6809,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)
@@ -6836,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:
@@ -6904,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)
@@ -6954,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:
@@ -7032,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)
@@ -7039,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
@@ -7057,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
@@ -7064,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)
@@ -7071,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)
@@ -7089,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':
@@ -7377,6 +7744,8 @@ snapshots:
 
   '@sindresorhus/is@4.6.0': {}
 
+  '@sindresorhus/merge-streams@2.3.0': {}
+
   '@sindresorhus/merge-streams@4.0.0': {}
 
   '@standard-schema/spec@1.0.0': {}
@@ -7451,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
 
@@ -7519,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
 
@@ -7634,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
 
@@ -7747,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
@@ -7860,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
@@ -8161,7 +8529,7 @@ snapshots:
       strip-ansi: 6.0.1
     optional: true
 
-  entities@4.5.0: {}
+  entities@6.0.0: {}
 
   env-paths@2.2.1: {}
 
@@ -8182,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
 
@@ -8535,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
@@ -8620,6 +8975,15 @@ snapshots:
       minimatch: 5.1.6
       once: 1.4.0
 
+  globby@14.1.0:
+    dependencies:
+      '@sindresorhus/merge-streams': 2.3.0
+      fast-glob: 3.3.3
+      ignore: 7.0.4
+      path-type: 6.0.0
+      slash: 5.1.0
+      unicorn-magic: 0.3.0
+
   gopd@1.2.0: {}
 
   graceful-fs@4.2.11: {}
@@ -8667,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
@@ -8685,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
@@ -8770,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: {}
@@ -8825,6 +9189,8 @@ snapshots:
     dependencies:
       minimatch: 9.0.5
 
+  ignore@7.0.4: {}
+
   image-size@2.0.1: {}
 
   imurmurhash@0.1.4: {}
@@ -9141,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
@@ -9202,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: {}
@@ -9805,7 +10177,7 @@ snapshots:
       nopt: 6.0.0
       npmlog: 6.0.2
       rimraf: 3.0.2
-      semver: 7.7.1
+      semver: 7.7.2
       tar: 6.2.1
       which: 2.0.2
     transitivePeerDependencies:
@@ -9822,7 +10194,7 @@ snapshots:
     dependencies:
       hosted-git-info: 6.1.3
       is-core-module: 2.16.1
-      semver: 7.7.1
+      semver: 7.7.2
       validate-npm-package-license: 3.0.4
 
   normalize-path@3.0.0: {}
@@ -9833,7 +10205,7 @@ snapshots:
 
   npm-install-checks@6.3.0:
     dependencies:
-      semver: 7.7.1
+      semver: 7.7.2
 
   npm-normalize-package-bin@3.0.1: {}
 
@@ -9841,7 +10213,7 @@ snapshots:
     dependencies:
       hosted-git-info: 6.1.3
       proc-log: 3.0.0
-      semver: 7.7.1
+      semver: 7.7.2
       validate-npm-package-name: 5.0.1
 
   npm-packlist@7.0.4:
@@ -9853,7 +10225,7 @@ snapshots:
       npm-install-checks: 6.3.0
       npm-normalize-package-bin: 3.0.1
       npm-package-arg: 10.1.0
-      semver: 7.7.1
+      semver: 7.7.2
 
   npm-registry-fetch@14.0.5:
     dependencies:
@@ -9921,7 +10293,7 @@ snapshots:
 
   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
@@ -9994,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: {}
 
@@ -10018,6 +10390,8 @@ snapshots:
       lru-cache: 11.1.0
       minipass: 7.1.2
 
+  path-type@6.0.0: {}
+
   pathe@1.1.2: {}
 
   pathe@2.0.3: {}
@@ -10092,6 +10466,8 @@ snapshots:
 
   property-information@7.0.0: {}
 
+  property-information@7.1.0: {}
+
   quansync@0.2.10: {}
 
   queue-microtask@1.2.3: {}
@@ -10105,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
 
@@ -10125,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
@@ -10166,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
@@ -10175,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)
@@ -10299,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
@@ -10503,11 +10888,6 @@ snapshots:
 
   semiver@1.1.0: {}
 
-  semver@7.6.3:
-    optional: true
-
-  semver@7.7.1: {}
-
   semver@7.7.2: {}
 
   serialize-javascript@6.0.2:
@@ -10529,7 +10909,7 @@ snapshots:
     dependencies:
       color: 4.2.3
       detect-libc: 2.0.3
-      semver: 7.6.3
+      semver: 7.7.2
     optionalDependencies:
       '@img/sharp-darwin-arm64': 0.33.5
       '@img/sharp-darwin-x64': 0.33.5
@@ -10596,6 +10976,8 @@ snapshots:
     dependencies:
       unicode-emoji-modifier-base: 1.0.0
 
+  slash@5.1.0: {}
+
   slice-ansi@3.0.0:
     dependencies:
       ansi-styles: 4.3.0
@@ -11012,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:
@@ -11021,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
 
diff --git a/scripts/prepublish.ts b/scripts/prepublish.ts
deleted file mode 100644
index a3e6c82f..00000000
--- a/scripts/prepublish.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { readFileSync } from "node:fs";
-
-// read package.json for zod and @zod/mini
-const zodPackageJson = JSON.parse(readFileSync("packages/zod/package.json", "utf-8"));
-const zodMiniPackageJson = JSON.parse(readFileSync("packages/mini/package.json", "utf-8"));
-
-// check that versions are the same
-if (zodPackageJson.version !== zodMiniPackageJson.version) {
-  throw new Error(
-    `zod and @zod/mini versions do not match: ${zodPackageJson.version} !== ${zodMiniPackageJson.version}`
-  );
-}
diff --git a/scripts/semver-check.ts b/scripts/semver-check.ts
new file mode 100644
index 00000000..bb3398b8
--- /dev/null
+++ b/scripts/semver-check.ts
@@ -0,0 +1,31 @@
+import { readFileSync } from "node:fs";
+import { join } from "node:path";
+import { fileURLToPath } from "node:url";
+import semver from "semver";
+
+const __dirname = fileURLToPath(new URL(".", import.meta.url));
+const packageJsonPath = join(__dirname, "../packages/zod/package.json");
+
+try {
+  const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
+  const version = packageJson.version;
+
+  if (!version) {
+    throw new Error("Version field is missing in package.json");
+  }
+
+  if (!semver.valid(version)) {
+    throw new Error(`Invalid semver version: ${version}`);
+  }
+
+  // check x.y.z format with regex
+  const semverRegex = /^\d+\.\d+\.\d+$/;
+  if (!semverRegex.test(version)) {
+    throw new Error(`Version ${version} does not match x.y.z format`);
+  }
+
+  console.log(`Valid semver version: ${version}`);
+} catch (error) {
+  console.error(`Error: ${error.message}`);
+  process.exit(1);
+}
diff --git a/tsconfig.json b/tsconfig.json
index 8f00c107..67e572c6 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,7 +2,7 @@
   "extends": "./.configs/tsconfig.base.json",
   "compilerOptions": {
     "rootDir": ".",
-    "noEmit": true
+    "declaration": true
   },
   "exclude": ["packages/docs"]
 }


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/error-utils.test.ts b/packages/zod/src/v4/classic/tests/error-utils.test.ts
index d45e748b..c1e79a16 100644
--- a/packages/zod/src/v4/classic/tests/error-utils.test.ts
+++ b/packages/zod/src/v4/classic/tests/error-utils.test.ts
@@ -1,6 +1,8 @@
 import { expect, expectTypeOf, test } from "vitest";
 import * as z from "zod/v4";
 
+declare const iss: z.core.$ZodIssueCode;
+
 const Test = z.object({
   f1: z.number(),
   f2: z.string().optional(),
diff --git a/packages/zod/src/v4/classic/tests/error.test.ts b/packages/zod/src/v4/classic/tests/error.test.ts
index aa14b194..19e25abf 100644
--- a/packages/zod/src/v4/classic/tests/error.test.ts
+++ b/packages/zod/src/v4/classic/tests/error.test.ts
@@ -1,3 +1,4 @@
+import { inspect } from "node:util";
 import { expect, test } from "vitest";
 import * as z from "zod/v4";
 
@@ -683,7 +684,6 @@ test("error serialization", () => {
   try {
     z.string().parse(123);
   } catch (e) {
-    console.dir(e, { depth: null });
     expect(e).toMatchInlineSnapshot(`
       [ZodError: [
         {
@@ -694,5 +694,15 @@ test("error serialization", () => {
         }
       ]]
     `);
+    expect(inspect(e).split("\n").slice(0, 8).join("\n")).toMatchInlineSnapshot(`
+      "ZodError: [
+        {
+          "expected": "string",
+          "code": "invalid_type",
+          "path": [],
+          "message": "Invalid input: expected string, received number"
+        }
+      ]"
+    `);
   }
 });
diff --git a/packages/zod/src/v4/classic/tests/file.test.ts b/packages/zod/src/v4/classic/tests/file.test.ts
index 2fc48009..10424b2d 100644
--- a/packages/zod/src/v4/classic/tests/file.test.ts
+++ b/packages/zod/src/v4/classic/tests/file.test.ts
@@ -1,3 +1,4 @@
+// @ts-ignore
 import { File as WebFile } from "@web-std/file";
 
 import { afterEach, beforeEach, expect, test } from "vitest";
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/function.test.ts b/packages/zod/src/v4/classic/tests/function.test.ts
index 93056da0..3fb9a7b4 100644
--- a/packages/zod/src/v4/classic/tests/function.test.ts
+++ b/packages/zod/src/v4/classic/tests/function.test.ts
@@ -68,7 +68,8 @@ test("function inference 1", () => {
 test("args method", () => {
   const t1 = z.function();
   type t1 = (typeof t1)["_input"];
-  expectTypeOf<t1>().toEqualTypeOf<(...args_1: unknown[]) => unknown>();
+  expectTypeOf<t1>().toEqualTypeOf<(...args_1: never[]) => unknown>();
+  t1._input;
 
   const t2args = z.tuple([z.string()], z.unknown());
 
@@ -81,6 +82,14 @@ test("args method", () => {
   expectTypeOf<t3>().toEqualTypeOf<(arg: string, ...args_1: unknown[]) => boolean>();
 });
 
+test("contravariance", () => {
+  const fn = z.function().implement((_a: string, _b: number) => {
+    return new Date();
+  });
+
+  expectTypeOf(fn).toEqualTypeOf<(a: string, b: number) => Date>();
+});
+
 const args2 = z.tuple([
   z.object({
     f1: z.number(),
diff --git a/packages/zod/src/v4/classic/tests/index.test.ts b/packages/zod/src/v4/classic/tests/index.test.ts
index ad0132cc..5ded8c49 100644
--- a/packages/zod/src/v4/classic/tests/index.test.ts
+++ b/packages/zod/src/v4/classic/tests/index.test.ts
@@ -706,17 +706,17 @@ test("z.templateLiteral", () => {
 });
 
 // this returns both a schema and a check
-test("z.custom", () => {
+test("z.custom schema", () => {
   const a = z.custom((val) => {
     return typeof val === "string";
   });
   expect(z.parse(a, "hello")).toEqual("hello");
   expect(() => z.parse(a, 123)).toThrow();
+});
 
-  const b = z.string().check(z.custom((val) => val.length > 3));
-
-  expect(z.parse(b, "hello")).toEqual("hello");
-  expect(() => z.parse(b, "hi")).toThrow();
+test("z.custom check", () => {
+  // @ts-expect-error Inference not possible, use z.refine()
+  z.date().check(z.custom((val) => val.getTime() > 0));
 });
 
 test("z.check", () => {
@@ -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 80b6a0e3..d014ddf2 100644
--- a/packages/zod/src/v4/classic/tests/json-schema.test.ts
+++ b/packages/zod/src/v4/classic/tests/json-schema.test.ts
@@ -1,226 +1,226 @@
 import { describe, expect, test } from "vitest";
 import * as z from "zod/v4";
-import { toJSONSchema } from "zod/v4/core";
+// import * as zCore from "zod/v4/core";
 
 describe("toJSONSchema", () => {
   test("primitive types", () => {
-    expect(toJSONSchema(z.string())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.string())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.number())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "number",
       }
     `);
-    expect(toJSONSchema(z.boolean())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.boolean())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "boolean",
       }
     `);
-    expect(toJSONSchema(z.null())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.null())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "null",
       }
     `);
-    expect(toJSONSchema(z.undefined())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.undefined())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "null",
       }
     `);
-    expect(toJSONSchema(z.any())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.any())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
       }
     `);
-    expect(toJSONSchema(z.unknown())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.unknown())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
       }
     `);
-    expect(toJSONSchema(z.never())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.never())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "not": {},
       }
     `);
-    expect(toJSONSchema(z.email())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.email())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "email",
         "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.iso.datetime())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.iso.datetime())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "date-time",
         "pattern": "^((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d+)?(Z)$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.iso.date())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.iso.date())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "date",
         "pattern": "^((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.iso.time())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.iso.time())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "time",
         "pattern": "^([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d+)?$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.iso.duration())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.iso.duration())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "duration",
         "pattern": "^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.ipv4())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.ipv4())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "ipv4",
         "pattern": "^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.ipv6())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.ipv6())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "ipv6",
         "pattern": "^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.uuid())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.uuid())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "uuid",
         "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.guid())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.guid())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "uuid",
         "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.url())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.url())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "uri",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.base64())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.base64())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "contentEncoding": "base64",
         "format": "base64",
         "pattern": "^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.cuid())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.cuid())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "cuid",
         "pattern": "^[cC][^\\s-]{8,}$",
         "type": "string",
       }
     `);
-    // expect(toJSONSchema(z.regex(/asdf/))).toMatchInlineSnapshot();
-    expect(toJSONSchema(z.emoji())).toMatchInlineSnapshot(`
+    // expect(z.toJSONSchema(z.regex(/asdf/))).toMatchInlineSnapshot();
+    expect(z.toJSONSchema(z.emoji())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "emoji",
         "pattern": "^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.nanoid())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.nanoid())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "nanoid",
         "pattern": "^[a-zA-Z0-9_-]{21}$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.cuid2())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.cuid2())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "cuid2",
         "pattern": "^[0-9a-z]+$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.ulid())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.ulid())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "ulid",
         "pattern": "^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$",
         "type": "string",
       }
     `);
-    // expect(toJSONSchema(z.cidr())).toMatchInlineSnapshot();
-    expect(toJSONSchema(z.number())).toMatchInlineSnapshot(`
+    // expect(z.toJSONSchema(z.cidr())).toMatchInlineSnapshot();
+    expect(z.toJSONSchema(z.number())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "number",
       }
     `);
-    expect(toJSONSchema(z.int())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.int())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "maximum": 9007199254740991,
         "minimum": -9007199254740991,
         "type": "integer",
       }
     `);
-    expect(toJSONSchema(z.int32())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.int32())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "maximum": 2147483647,
         "minimum": -2147483648,
         "type": "integer",
       }
     `);
-    expect(toJSONSchema(z.float32())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.float32())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "maximum": 3.4028234663852886e+38,
         "minimum": -3.4028234663852886e+38,
         "type": "number",
       }
     `);
-    expect(toJSONSchema(z.float64())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.float64())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "maximum": 1.7976931348623157e+308,
         "minimum": -1.7976931348623157e+308,
         "type": "number",
       }
     `);
-    expect(toJSONSchema(z.jwt())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.jwt())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "jwt",
         "type": "string",
       }
@@ -228,28 +228,28 @@ describe("toJSONSchema", () => {
   });
 
   test("unsupported schema types", () => {
-    expect(() => toJSONSchema(z.bigint())).toThrow("BigInt cannot be represented in JSON Schema");
-    expect(() => toJSONSchema(z.int64())).toThrow("BigInt cannot be represented in JSON Schema");
-    expect(() => toJSONSchema(z.symbol())).toThrow("Symbols cannot be represented in JSON Schema");
-    expect(() => toJSONSchema(z.void())).toThrow("Void cannot be represented in JSON Schema");
-    expect(() => toJSONSchema(z.date())).toThrow("Date cannot be represented in JSON Schema");
-    expect(() => toJSONSchema(z.map(z.string(), z.number()))).toThrow("Map cannot be represented in JSON Schema");
-    expect(() => toJSONSchema(z.set(z.string()))).toThrow("Set cannot be represented in JSON Schema");
-    expect(() => toJSONSchema(z.custom(() => true))).toThrow("Custom types cannot be represented in JSON Schema");
+    expect(() => z.toJSONSchema(z.bigint())).toThrow("BigInt cannot be represented in JSON Schema");
+    expect(() => z.toJSONSchema(z.int64())).toThrow("BigInt cannot be represented in JSON Schema");
+    expect(() => z.toJSONSchema(z.symbol())).toThrow("Symbols cannot be represented in JSON Schema");
+    expect(() => z.toJSONSchema(z.void())).toThrow("Void cannot be represented in JSON Schema");
+    expect(() => z.toJSONSchema(z.date())).toThrow("Date cannot be represented in JSON Schema");
+    expect(() => z.toJSONSchema(z.map(z.string(), z.number()))).toThrow("Map cannot be represented in JSON Schema");
+    expect(() => z.toJSONSchema(z.set(z.string()))).toThrow("Set cannot be represented in JSON Schema");
+    expect(() => z.toJSONSchema(z.custom(() => true))).toThrow("Custom types cannot be represented in JSON Schema");
 
     // File type
     const fileSchema = z.file();
-    expect(() => toJSONSchema(fileSchema)).toThrow("File cannot be represented in JSON Schema");
+    expect(() => z.toJSONSchema(fileSchema)).toThrow("File cannot be represented in JSON Schema");
 
     // Transform
     const transformSchema = z.string().transform((val) => Number.parseInt(val));
-    expect(() => toJSONSchema(transformSchema)).toThrow("Transforms cannot be represented in JSON Schema");
+    expect(() => z.toJSONSchema(transformSchema)).toThrow("Transforms cannot be represented in JSON Schema");
 
     // Static catch values
     const staticCatchSchema = z.string().catch(() => "sup");
-    expect(toJSONSchema(staticCatchSchema)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(staticCatchSchema)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "default": "sup",
         "type": "string",
       }
@@ -257,122 +257,175 @@ describe("toJSONSchema", () => {
 
     // Dynamic catch values
     const dynamicCatchSchema = z.string().catch((ctx) => `${ctx.issues.length}`);
-    expect(() => toJSONSchema(dynamicCatchSchema)).toThrow("Dynamic catch values are not supported in JSON Schema");
+    expect(() => z.toJSONSchema(dynamicCatchSchema)).toThrow("Dynamic catch values are not supported in JSON Schema");
   });
 
   test("string formats", () => {
-    expect(toJSONSchema(z.string().email())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.string().email())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "email",
         "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.string().uuid())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.string().uuid())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "uuid",
         "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.iso.datetime())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.iso.datetime())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "date-time",
         "pattern": "^((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d+)?(Z)$",
         "type": "string",
       }
     `);
 
-    expect(toJSONSchema(z.iso.date())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.iso.date())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "date",
         "pattern": "^((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.iso.time())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.iso.time())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "time",
         "pattern": "^([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d+)?$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.iso.duration())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.iso.duration())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "duration",
         "pattern": "^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$",
         "type": "string",
       }
     `);
-    // expect(toJSONSchema(z.string().ip())).toMatchInlineSnapshot(`
+    // expect(z.toJSONSchema(z.string().ip())).toMatchInlineSnapshot(`
     //   {
     //     "pattern": /\\(\\^\\(\\?:\\(\\?:25\\[0-5\\]\\|2\\[0-4\\]\\[0-9\\]\\|1\\[0-9\\]\\[0-9\\]\\|\\[1-9\\]\\[0-9\\]\\|\\[0-9\\]\\)\\\\\\.\\)\\{3\\}\\(\\?:25\\[0-5\\]\\|2\\[0-4\\]\\[0-9\\]\\|1\\[0-9\\]\\[0-9\\]\\|\\[1-9\\]\\[0-9\\]\\|\\[0-9\\]\\)\\$\\)\\|\\(\\^\\(\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{7\\}\\|::\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,6\\}\\|\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{1\\}:\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,5\\}\\|\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{2\\}:\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,4\\}\\|\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{3\\}:\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,3\\}\\|\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{4\\}:\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,2\\}\\|\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{5\\}:\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,1\\}\\)\\(\\[a-fA-F0-9\\]\\{1,4\\}\\|\\(\\(\\(25\\[0-5\\]\\)\\|\\(2\\[0-4\\]\\[0-9\\]\\)\\|\\(1\\[0-9\\]\\{2\\}\\)\\|\\(\\[0-9\\]\\{1,2\\}\\)\\)\\\\\\.\\)\\{3\\}\\(\\(25\\[0-5\\]\\)\\|\\(2\\[0-4\\]\\[0-9\\]\\)\\|\\(1\\[0-9\\]\\{2\\}\\)\\|\\(\\[0-9\\]\\{1,2\\}\\)\\)\\)\\$\\)/,
     //     "type": "string",
     //   }
     // `);
-    expect(toJSONSchema(z.ipv4())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.ipv4())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "ipv4",
         "pattern": "^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$",
         "type": "string",
       }
     `);
 
-    expect(toJSONSchema(z.ipv6())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.ipv6())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "ipv6",
         "pattern": "^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})$",
         "type": "string",
       }
     `);
 
-    expect(toJSONSchema(z.base64())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.base64())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "contentEncoding": "base64",
         "format": "base64",
         "pattern": "^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.url())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.url())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "uri",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.guid())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.guid())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "format": "uuid",
         "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
         "type": "string",
       }
     `);
-    expect(toJSONSchema(z.string().regex(/asdf/))).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.string().regex(/asdf/))).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
-        "format": "regex",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "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(toJSONSchema(z.number().min(5).max(10))).toMatchInlineSnapshot(
+    expect(z.toJSONSchema(z.number().min(5).max(10))).toMatchInlineSnapshot(
       `
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "maximum": 10,
         "minimum": 5,
         "type": "number",
@@ -380,86 +433,86 @@ describe("toJSONSchema", () => {
     `
     );
 
-    expect(toJSONSchema(z.number().gt(5).gt(10))).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().gt(5).gt(10))).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "exclusiveMinimum": 10,
         "type": "number",
       }
     `);
 
-    expect(toJSONSchema(z.number().gt(5).gte(10))).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().gt(5).gte(10))).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "minimum": 10,
         "type": "number",
       }
     `);
 
-    expect(toJSONSchema(z.number().lt(5).lt(3))).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().lt(5).lt(3))).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "exclusiveMaximum": 3,
         "type": "number",
       }
     `);
 
-    expect(toJSONSchema(z.number().lt(5).lt(3).lte(2))).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().lt(5).lt(3).lte(2))).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "maximum": 2,
         "type": "number",
       }
     `);
 
-    expect(toJSONSchema(z.number().lt(5).lte(3))).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().lt(5).lte(3))).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "maximum": 3,
         "type": "number",
       }
     `);
 
-    expect(toJSONSchema(z.number().gt(5).lt(10))).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().gt(5).lt(10))).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "exclusiveMaximum": 10,
         "exclusiveMinimum": 5,
         "type": "number",
       }
     `);
-    expect(toJSONSchema(z.number().gte(5).lte(10))).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().gte(5).lte(10))).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "maximum": 10,
         "minimum": 5,
         "type": "number",
       }
     `);
-    expect(toJSONSchema(z.number().positive())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().positive())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "exclusiveMinimum": 0,
         "type": "number",
       }
     `);
-    expect(toJSONSchema(z.number().negative())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().negative())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "exclusiveMaximum": 0,
         "type": "number",
       }
     `);
-    expect(toJSONSchema(z.number().nonpositive())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().nonpositive())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "maximum": 0,
         "type": "number",
       }
     `);
-    expect(toJSONSchema(z.number().nonnegative())).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.number().nonnegative())).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "minimum": 0,
         "type": "number",
       }
@@ -467,9 +520,9 @@ describe("toJSONSchema", () => {
   });
 
   test("arrays", () => {
-    expect(toJSONSchema(z.array(z.string()))).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(z.array(z.string()))).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "items": {
           "type": "string",
         },
@@ -480,9 +533,9 @@ describe("toJSONSchema", () => {
 
   test("unions", () => {
     const schema = z.union([z.string(), z.number()]);
-    expect(toJSONSchema(schema)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "anyOf": [
           {
             "type": "string",
@@ -498,11 +551,12 @@ describe("toJSONSchema", () => {
   test("intersections", () => {
     const schema = z.intersection(z.object({ name: z.string() }), z.object({ age: z.number() }));
 
-    expect(toJSONSchema(schema)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "allOf": [
           {
+            "additionalProperties": false,
             "properties": {
               "name": {
                 "type": "string",
@@ -514,6 +568,7 @@ describe("toJSONSchema", () => {
             "type": "object",
           },
           {
+            "additionalProperties": false,
             "properties": {
               "age": {
                 "type": "number",
@@ -531,9 +586,9 @@ describe("toJSONSchema", () => {
 
   test("record", () => {
     const schema = z.record(z.string(), z.boolean());
-    expect(toJSONSchema(schema)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "additionalProperties": {
           "type": "boolean",
         },
@@ -547,9 +602,9 @@ describe("toJSONSchema", () => {
 
   test("tuple", () => {
     const schema = z.tuple([z.string(), z.number()]).rest(z.boolean());
-    expect(toJSONSchema(schema)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "items": {
           "type": "boolean",
         },
@@ -568,9 +623,9 @@ describe("toJSONSchema", () => {
 
   test("promise", () => {
     const schema = z.promise(z.string());
-    expect(toJSONSchema(schema)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "string",
       }
     `);
@@ -578,9 +633,9 @@ describe("toJSONSchema", () => {
 
   test("lazy", () => {
     const schema = z.lazy(() => z.string());
-    expect(toJSONSchema(schema)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "string",
       }
     `);
@@ -589,9 +644,9 @@ describe("toJSONSchema", () => {
   // enum
   test("enum", () => {
     const schema = z.enum(["a", "b", "c"]);
-    expect(toJSONSchema(schema)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "enum": [
           "a",
           "b",
@@ -604,20 +659,20 @@ describe("toJSONSchema", () => {
   // literal
   test("literal", () => {
     const a = z.literal("hello");
-    expect(toJSONSchema(a)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "const": "hello",
       }
     `);
 
     const b = z.literal(["hello", undefined, null, 5, BigInt(1324)]);
-    expect(() => toJSONSchema(b)).toThrow();
+    expect(() => z.toJSONSchema(b)).toThrow();
 
     const c = z.literal(["hello", null, 5]);
-    expect(toJSONSchema(c)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(c)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "enum": [
           "hello",
           null,
@@ -633,9 +688,9 @@ describe("toJSONSchema", () => {
       .string()
       .transform((val) => Number.parseInt(val))
       .pipe(z.number());
-    expect(toJSONSchema(schema)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "number",
       }
     `);
@@ -647,10 +702,11 @@ describe("toJSONSchema", () => {
       age: z.number(),
     });
 
-    expect(toJSONSchema(schema)).toMatchInlineSnapshot(
+    expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(
       `
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
+        "additionalProperties": false,
         "properties": {
           "age": {
             "type": "number",
@@ -669,15 +725,75 @@ describe("toJSONSchema", () => {
     );
   });
 
+  test("additionalproperties in z.object", () => {
+    const a = z.object({
+      name: z.string(),
+    });
+    expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
+      {
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
+        "additionalProperties": false,
+        "properties": {
+          "name": {
+            "type": "string",
+          },
+        },
+        "required": [
+          "name",
+        ],
+        "type": "object",
+      }
+    `);
+    expect(z.toJSONSchema(a, { io: "input" })).toMatchInlineSnapshot(`
+      {
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
+        "properties": {
+          "name": {
+            "type": "string",
+          },
+        },
+        "required": [
+          "name",
+        ],
+        "type": "object",
+      }
+    `);
+    expect(
+      z.toJSONSchema(a, {
+        io: "input",
+        override(ctx) {
+          const def = (ctx.zodSchema as z.core.$ZodTypes)._zod.def;
+          if (def.type === "object" && !def.catchall) {
+            (ctx.jsonSchema as z.core.JSONSchema.ObjectSchema).additionalProperties = false;
+          }
+        },
+      })
+    ).toMatchInlineSnapshot(`
+      {
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
+        "additionalProperties": false,
+        "properties": {
+          "name": {
+            "type": "string",
+          },
+        },
+        "required": [
+          "name",
+        ],
+        "type": "object",
+      }
+    `);
+  });
+
   test("catchall objects", () => {
     const a = z.strictObject({
       name: z.string(),
       age: z.number(),
     });
 
-    expect(toJSONSchema(a)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "additionalProperties": false,
         "properties": {
           "age": {
@@ -701,9 +817,9 @@ describe("toJSONSchema", () => {
       })
       .catchall(z.string());
 
-    expect(toJSONSchema(b)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(b)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "additionalProperties": {
           "type": "string",
         },
@@ -723,9 +839,9 @@ describe("toJSONSchema", () => {
       name: z.string(),
     });
 
-    expect(toJSONSchema(c)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(c)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "additionalProperties": {},
         "properties": {
           "name": {
@@ -747,11 +863,12 @@ describe("toJSONSchema", () => {
       nonoptional: z.string().optional().nonoptional(),
     });
 
-    const result = toJSONSchema(schema);
+    const result = z.toJSONSchema(schema);
 
     expect(result).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
+        "additionalProperties": false,
         "properties": {
           "nonoptional": {
             "type": "string",
@@ -783,10 +900,11 @@ describe("toJSONSchema", () => {
       subcategories: z.array(z.lazy(() => categorySchema)),
     });
 
-    const result = toJSONSchema(categorySchema);
+    const result = z.toJSONSchema(categorySchema);
     expect(result).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
+        "additionalProperties": false,
         "properties": {
           "name": {
             "type": "string",
@@ -813,10 +931,11 @@ describe("toJSONSchema", () => {
       age: z.number().optional(),
     });
 
-    const result = toJSONSchema(userSchema);
+    const result = z.toJSONSchema(userSchema);
     expect(result).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
+        "additionalProperties": false,
         "properties": {
           "age": {
             "type": "number",
@@ -839,9 +958,9 @@ describe("toJSONSchema", () => {
       age: z.number(),
     });
 
-    expect(toJSONSchema(a)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "additionalProperties": false,
         "properties": {
           "age": {
@@ -865,9 +984,9 @@ describe("toJSONSchema", () => {
       })
       .catchall(z.string());
 
-    expect(toJSONSchema(b)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(b)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "additionalProperties": {
           "type": "string",
         },
@@ -887,9 +1006,9 @@ describe("toJSONSchema", () => {
       name: z.string(),
     });
 
-    expect(toJSONSchema(c)).toMatchInlineSnapshot(`
+    expect(z.toJSONSchema(c)).toMatchInlineSnapshot(`
       {
-        "$schema": "https://json-schema.org/draft-2020-12/schema",
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "additionalProperties": {},
         "properties": {
           "name": {
@@ -912,12 +1031,13 @@ describe("toJSONSchema", () => {
       },
     });
 
-    const result = toJSONSchema(TreeNodeSchema);
+    const result = z.toJSONSchema(TreeNodeSchema);
 
     // Should have definitions for recursive schema
     expect(JSON.stringify(result, null, 2)).toMatchInlineSnapshot(
       `
       "{
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "object",
         "properties": {
           "id": {
@@ -931,7 +1051,7 @@ describe("toJSONSchema", () => {
           "id",
           "children"
         ],
-        "$schema": "https://json-schema.org/draft-2020-12/schema"
+        "additionalProperties": false
       }"
     `
     );
@@ -952,12 +1072,13 @@ describe("toJSONSchema", () => {
       },
     });
 
-    const result = toJSONSchema(FolderSchema);
+    const result = z.toJSONSchema(FolderSchema);
 
     // Should have definitions for both schemas
     expect(JSON.stringify(result, null, 2)).toMatchInlineSnapshot(
       `
       "{
+        "$schema": "https://json-schema.org/draft/2020-12/schema",
         "type": "object",
         "properties": {
           "name": {
@@ -978,7 +1099,8 @@ describe("toJSONSchema", () => {
               "required": [
                 "name",
                 "parent"
-              ]
+              ],
+              "additionalProperties": false
             }
           }
         },
@@ -986,7 +1108,7 @@ describe("toJSONSchema", () => {
           "name",
           "files"
         ],
-        "$schema": "https://json-schema.org/draft-2020-12/schema"
+        "additionalProperties": false
       }"
     `
     );
@@ -994,7 +1116,7 @@ describe("toJSONSchema", () => {
 });
 
 test("override", () => {
-  const schema = z.toJSONSchema(z.string(), {
+  const schema = z.z.toJSONSchema(z.string(), {
     override: (ctx) => {
       ctx.zodSchema;
       ctx.jsonSchema;
@@ -1003,7 +1125,7 @@ test("override", () => {
   });
   expect(schema).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "type": "string",
       "whatever": "sup",
     }
@@ -1020,7 +1142,7 @@ test("override: do not run on references", () => {
     .pipe(z.date())
     .meta({ c: true })
     .brand("dateIn");
-  z.toJSONSchema(schema, {
+  z.z.toJSONSchema(schema, {
     unrepresentable: "any",
     io: "input",
     override(_) {
@@ -1033,7 +1155,7 @@ test("override: do not run on references", () => {
 
 test("override with refs", () => {
   const a = z.string().optional();
-  const result = z.toJSONSchema(a, {
+  const result = z.z.toJSONSchema(a, {
     override(ctx) {
       if (ctx.zodSchema._zod.def.type === "string") {
         ctx.jsonSchema.type = "STRING";
@@ -1043,7 +1165,7 @@ test("override with refs", () => {
 
   expect(result).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "type": "STRING",
     }
   `);
@@ -1052,7 +1174,7 @@ test("override with refs", () => {
 test("override execution order", () => {
   const schema = z.union([z.string(), z.number()]);
   let unionSchema!: any;
-  z.toJSONSchema(schema, {
+  z.z.toJSONSchema(schema, {
     override(ctx) {
       if (ctx.zodSchema._zod.def.type === "union") {
         unionSchema = ctx.jsonSchema;
@@ -1081,19 +1203,19 @@ test("pipe", () => {
     .pipe(z.number());
   // ZodPipe
 
-  const a = z.toJSONSchema(mySchema);
+  const a = z.z.toJSONSchema(mySchema);
   expect(a).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "type": "number",
     }
   `);
   // => { type: "number" }
 
-  const b = z.toJSONSchema(mySchema, { io: "input" });
+  const b = z.z.toJSONSchema(mySchema, { io: "input" });
   expect(b).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "type": "string",
     }
   `);
@@ -1115,13 +1237,14 @@ test("passthrough schemas", () => {
     e: z.pipe(Internal, Internal),
   });
 
-  const result = z.toJSONSchema(External, {
+  const result = z.z.toJSONSchema(External, {
     reused: "ref",
   });
   expect(result).toMatchInlineSnapshot(`
     {
       "$defs": {
         "__schema0": {
+          "additionalProperties": false,
           "properties": {
             "num": {
               "type": "number",
@@ -1137,7 +1260,8 @@ test("passthrough schemas", () => {
           "type": "object",
         },
       },
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
+      "additionalProperties": false,
       "properties": {
         "a": {
           "$ref": "#/$defs/__schema0",
@@ -1168,7 +1292,7 @@ test("passthrough schemas", () => {
 
 test("extract schemas with id", () => {
   const name = z.string().meta({ id: "name" });
-  const result = z.toJSONSchema(
+  const result = z.z.toJSONSchema(
     z.object({
       first_name: name,
       last_name: name.nullable(),
@@ -1188,7 +1312,8 @@ test("extract schemas with id", () => {
           "type": "string",
         },
       },
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
+      "additionalProperties": false,
       "properties": {
         "age": {
           "$ref": "#/$defs/age",
@@ -1221,10 +1346,10 @@ test("extract schemas with id", () => {
 });
 
 test("unrepresentable literal values are ignored", () => {
-  const a = z.toJSONSchema(z.literal(["hello", null, 5, BigInt(1324), undefined]), { unrepresentable: "any" });
+  const a = z.z.toJSONSchema(z.literal(["hello", null, 5, BigInt(1324), undefined]), { unrepresentable: "any" });
   expect(a).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "enum": [
         "hello",
         null,
@@ -1234,10 +1359,10 @@ test("unrepresentable literal values are ignored", () => {
     }
   `);
 
-  const b = z.toJSONSchema(z.literal([undefined, null, 5, BigInt(1324)]), { unrepresentable: "any" });
+  const b = z.z.toJSONSchema(z.literal([undefined, null, 5, BigInt(1324)]), { unrepresentable: "any" });
   expect(b).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "enum": [
         null,
         5,
@@ -1246,10 +1371,10 @@ test("unrepresentable literal values are ignored", () => {
     }
   `);
 
-  const c = z.toJSONSchema(z.literal([undefined]), { unrepresentable: "any" });
+  const c = z.z.toJSONSchema(z.literal([undefined]), { unrepresentable: "any" });
   expect(c).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
     }
   `);
 });
@@ -1257,7 +1382,7 @@ test("unrepresentable literal values are ignored", () => {
 test("describe with id", () => {
   const jobId = z.string().meta({ id: "jobId" });
 
-  const a = z.toJSONSchema(
+  const a = z.z.toJSONSchema(
     z.object({
       current: jobId.describe("Current job"),
       previous: jobId.describe("Previous job"),
@@ -1271,7 +1396,8 @@ test("describe with id", () => {
           "type": "string",
         },
       },
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
+      "additionalProperties": false,
       "properties": {
         "current": {
           "$ref": "#/$defs/jobId",
@@ -1294,7 +1420,7 @@ test("describe with id", () => {
 test("overwrite id", () => {
   const jobId = z.string().meta({ id: "aaa" });
 
-  const a = z.toJSONSchema(
+  const a = z.z.toJSONSchema(
     z.object({
       current: jobId,
       previous: jobId.meta({ id: "bbb" }),
@@ -1312,7 +1438,8 @@ test("overwrite id", () => {
           "id": "bbb",
         },
       },
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
+      "additionalProperties": false,
       "properties": {
         "current": {
           "$ref": "#/$defs/aaa",
@@ -1329,7 +1456,7 @@ test("overwrite id", () => {
     }
   `);
 
-  const b = z.toJSONSchema(
+  const b = z.z.toJSONSchema(
     z.object({
       current: jobId,
       previous: jobId.meta({ id: "ccc" }),
@@ -1350,7 +1477,8 @@ test("overwrite id", () => {
           "id": "ccc",
         },
       },
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
+      "additionalProperties": false,
       "properties": {
         "current": {
           "$ref": "#/$defs/aaa",
@@ -1371,7 +1499,7 @@ test("overwrite id", () => {
 test("overwrite descriptions", () => {
   const field = z.string().describe("a").describe("b").describe("c");
 
-  const a = z.toJSONSchema(
+  const a = z.z.toJSONSchema(
     z.object({
       d: field.describe("d"),
       e: field.describe("e"),
@@ -1379,7 +1507,8 @@ test("overwrite descriptions", () => {
   );
   expect(a).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
+      "additionalProperties": false,
       "properties": {
         "d": {
           "description": "d",
@@ -1398,7 +1527,7 @@ test("overwrite descriptions", () => {
     }
   `);
 
-  const b = z.toJSONSchema(
+  const b = z.z.toJSONSchema(
     z.object({
       d: field.describe("d"),
       e: field.describe("e"),
@@ -1415,7 +1544,8 @@ test("overwrite descriptions", () => {
           "type": "string",
         },
       },
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
+      "additionalProperties": false,
       "properties": {
         "d": {
           "$ref": "#/$defs/__schema0",
@@ -1456,11 +1586,12 @@ test("top-level readonly", () => {
     .readonly()
     .meta({ id: "B" });
 
-  const result = z.toJSONSchema(A);
+  const result = z.z.toJSONSchema(A);
   expect(result).toMatchInlineSnapshot(`
     {
       "$defs": {
         "B": {
+          "additionalProperties": false,
           "id": "B",
           "properties": {
             "a": {
@@ -1478,7 +1609,8 @@ test("top-level readonly", () => {
           "type": "object",
         },
       },
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
+      "additionalProperties": false,
       "id": "A",
       "properties": {
         "b": {
@@ -1518,12 +1650,13 @@ test("basic registry", () => {
   myRegistry.add(User, { id: "User" });
   myRegistry.add(Post, { id: "Post" });
 
-  const result = z.toJSONSchema(myRegistry);
+  const result = z.z.toJSONSchema(myRegistry);
   expect(result).toMatchInlineSnapshot(`
     {
       "schemas": {
         "Post": {
-          "$schema": "https://json-schema.org/draft-2020-12/schema",
+          "$schema": "https://json-schema.org/draft/2020-12/schema",
+          "additionalProperties": false,
           "properties": {
             "author": {
               "$ref": "User",
@@ -1543,7 +1676,8 @@ test("basic registry", () => {
           "type": "object",
         },
         "User": {
-          "$schema": "https://json-schema.org/draft-2020-12/schema",
+          "$schema": "https://json-schema.org/draft/2020-12/schema",
+          "additionalProperties": false,
           "properties": {
             "name": {
               "type": "string",
@@ -1568,28 +1702,28 @@ test("basic registry", () => {
 
 test("_ref", () => {
   // const a = z.promise(z.string().describe("a"));
-  const a = z.toJSONSchema(z.promise(z.string().describe("a")));
+  const a = z.z.toJSONSchema(z.promise(z.string().describe("a")));
   expect(a).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "description": "a",
       "type": "string",
     }
   `);
 
-  const b = z.toJSONSchema(z.lazy(() => z.string().describe("a")));
+  const b = z.z.toJSONSchema(z.lazy(() => z.string().describe("a")));
   expect(b).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "description": "a",
       "type": "string",
     }
   `);
 
-  const c = z.toJSONSchema(z.optional(z.string().describe("a")));
+  const c = z.z.toJSONSchema(z.optional(z.string().describe("a")));
   expect(c).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "description": "a",
       "type": "string",
     }
@@ -1605,44 +1739,44 @@ test("defaults/prefaults", () => {
   const c = a.default(1234);
 
   // a
-  expect(toJSONSchema(a)).toMatchInlineSnapshot(`
+  expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "type": "number",
     }
   `);
-  expect(toJSONSchema(a, { io: "input" })).toMatchInlineSnapshot(`
+  expect(z.toJSONSchema(a, { io: "input" })).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "type": "string",
     }
   `);
 
   // b
-  expect(toJSONSchema(b)).toMatchInlineSnapshot(`
+  expect(z.toJSONSchema(b)).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "type": "number",
     }
   `);
-  expect(toJSONSchema(b, { io: "input" })).toMatchInlineSnapshot(`
+  expect(z.toJSONSchema(b, { io: "input" })).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "default": "hello",
       "type": "string",
     }
   `);
   // c
-  expect(toJSONSchema(c)).toMatchInlineSnapshot(`
+  expect(z.toJSONSchema(c)).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "default": 1234,
       "type": "number",
     }
   `);
-  expect(toJSONSchema(c, { io: "input" })).toMatchInlineSnapshot(`
+  expect(z.toJSONSchema(c, { io: "input" })).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "default": 1234,
       "type": "string",
     }
@@ -1657,9 +1791,9 @@ test("input type", () => {
     d: z.string().nullable(),
     e: z.string().prefault("hello"),
   });
-  expect(toJSONSchema(schema, { io: "input" })).toMatchInlineSnapshot(`
+  expect(z.toJSONSchema(schema, { io: "input" })).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "properties": {
         "a": {
           "type": "string",
@@ -1693,9 +1827,10 @@ test("input type", () => {
       "type": "object",
     }
   `);
-  expect(toJSONSchema(schema, { io: "output" })).toMatchInlineSnapshot(`
+  expect(z.toJSONSchema(schema, { io: "output" })).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
+      "additionalProperties": false,
       "properties": {
         "a": {
           "type": "string",
@@ -1740,20 +1875,20 @@ test("examples on pipe", () => {
     // .pipe(z.transform(Number).meta({ examples: [4] }))
     .meta({ examples: [4] });
 
-  const i = z.toJSONSchema(schema, { io: "input", unrepresentable: "any" });
+  const i = z.z.toJSONSchema(schema, { io: "input", unrepresentable: "any" });
   expect(i).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "examples": [
         "test",
       ],
       "type": "string",
     }
   `);
-  const o = z.toJSONSchema(schema, { io: "output", unrepresentable: "any" });
+  const o = z.z.toJSONSchema(schema, { io: "output", unrepresentable: "any" });
   expect(o).toMatchInlineSnapshot(`
     {
-      "$schema": "https://json-schema.org/draft-2020-12/schema",
+      "$schema": "https://json-schema.org/draft/2020-12/schema",
       "examples": [
         4,
       ],
@@ -1762,21 +1897,21 @@ test("examples on pipe", () => {
 });
 
 // test("number checks", () => {
-//   expect(z.toJSONSchema(z.number().int())).toMatchInlineSnapshot(`
+//   expect(z.z.toJSONSchema(z.number().int())).toMatchInlineSnapshot(`
 //     {
 //       "maximum": 9007199254740991,
 //       "minimum": -9007199254740991,
 //       "type": "integer",
 //     }
 //   `);
-//   expect(z.toJSONSchema(z.int())).toMatchInlineSnapshot(`
+//   expect(z.z.toJSONSchema(z.int())).toMatchInlineSnapshot(`
 //     {
 //       "maximum": 9007199254740991,
 //       "minimum": -9007199254740991,
 //       "type": "integer",
 //     }
 //   `);
-//   expect(z.toJSONSchema(z.int().positive())).toMatchInlineSnapshot(`
+//   expect(z.z.toJSONSchema(z.int().positive())).toMatchInlineSnapshot(`
 //     {
 //       "exclusiveMinimum": 0,
 //       "maximum": 9007199254740991,
@@ -1784,14 +1919,14 @@ test("examples on pipe", () => {
 //       "type": "integer",
 //     }
 //   `);
-//   expect(z.toJSONSchema(z.int().nonnegative())).toMatchInlineSnapshot(`
+//   expect(z.z.toJSONSchema(z.int().nonnegative())).toMatchInlineSnapshot(`
 //     {
 //       "maximum": 9007199254740991,
 //       "minimum": 0,
 //       "type": "integer",
 //     }
 //   `);
-//   expect(z.toJSONSchema(z.int().gt(0))).toMatchInlineSnapshot(`
+//   expect(z.z.toJSONSchema(z.int().gt(0))).toMatchInlineSnapshot(`
 //     {
 //       "exclusiveMinimum": 0,
 //       "maximum": 9007199254740991,
@@ -1799,7 +1934,7 @@ test("examples on pipe", () => {
 //       "type": "integer",
 //     }
 //   `);
-//   expect(z.toJSONSchema(z.int().gte(0))).toMatchInlineSnapshot(`
+//   expect(z.z.toJSONSchema(z.int().gte(0))).toMatchInlineSnapshot(`
 //     {
 //       "maximum": 9007199254740991,
 //       "minimum": 0,
diff --git a/packages/zod/src/v4/classic/tests/literal.test.ts b/packages/zod/src/v4/classic/tests/literal.test.ts
index 904fb514..e769dcd8 100644
--- a/packages/zod/src/v4/classic/tests/literal.test.ts
+++ b/packages/zod/src/v4/classic/tests/literal.test.ts
@@ -80,3 +80,8 @@ test("literal bigint default error message", () => {
   expect(result.error!.issues.length).toEqual(1);
   expect(result.error!.issues[0].message).toEqual(`Invalid input: expected 12n`);
 });
+
+test(".value getter", () => {
+  expect(z.literal("tuna").value).toEqual("tuna");
+  expect(() => z.literal([1, 2, 3]).value).toThrow();
+});
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/registries.test.ts b/packages/zod/src/v4/classic/tests/registries.test.ts
index 2b93f0ae..cf210c9f 100644
--- a/packages/zod/src/v4/classic/tests/registries.test.ts
+++ b/packages/zod/src/v4/classic/tests/registries.test.ts
@@ -157,3 +157,13 @@ test("inherit across clone", () => {
   const C = B.describe("hello");
   expect(C.meta()).toEqual({ a: true, b: true, description: "hello" });
 });
+
+test("register with replace", () => {
+  z.string().register(z.globalRegistry, {
+    examples: ["example"],
+  });
+  z.string().register(z.globalRegistry, {
+    // @ts-expect-error
+    examples: [1234],
+  });
+});
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");