diff --git a/.changeset/adapter-test-kit.md b/.changeset/adapter-test-kit.md
new file mode 100644
index 0000000..fed57ba
--- /dev/null
+++ b/.changeset/adapter-test-kit.md
@@ -0,0 +1,5 @@
+---
+"@javaabu/forms": minor
+---
+
+New `@javaabu/forms/testing`: `testAdapter(myAdapter)` runs conformance tests that render every component through an adapter and check labels, values, native submission, errors and ARIA. The adapter contract is typed (`defineAdapter`, `FormsComponents` and a `…SlotProps` type per slot) and documented in `docs/advanced-usage/adapters.md`. `@testing-library/react` is an optional peer dependency.
diff --git a/.changeset/automatic-errors.md b/.changeset/automatic-errors.md
new file mode 100644
index 0000000..bb94c4b
--- /dev/null
+++ b/.changeset/automatic-errors.md
@@ -0,0 +1,5 @@
+---
+"@javaabu/forms": minor
+---
+
+Validation errors are now handled by the core, for every adapter. Errors come from Inertia page props, `useForm()`, a JSON 422 response, the `errors` prop or `FormsProvider errors`. Fields match them in dot or bracket notation, and array fields (`tags[]`) also collect their items' errors (`tags.0`). Error bags work with `errorBag`. New: `ErrorSummary`, `ValidationError`, `errorsFor`, `selectErrorBag` and `useFormState()`. Invalid fields get `aria-invalid` and `aria-describedby`, and the first one is focused when errors arrive.
diff --git a/.changeset/binding-tests.md b/.changeset/binding-tests.md
new file mode 100644
index 0000000..9c12eab
--- /dev/null
+++ b/.changeset/binding-tests.md
@@ -0,0 +1,5 @@
+---
+"@javaabu/forms": patch
+---
+
+Fields are controlled by the core and still submit natively. Model binding, old input (including `null` old values), nested and array names, checkbox groups, radio groups, relations and date formats follow javaabu/forms. Radios in a group now update together when one is picked.
diff --git a/.changeset/docs-and-hidden-panels.md b/.changeset/docs-and-hidden-panels.md
new file mode 100644
index 0000000..2802ed4
--- /dev/null
+++ b/.changeset/docs-and-hidden-panels.md
@@ -0,0 +1,5 @@
+---
+"@javaabu/forms": patch
+---
+
+Tab panels stay mounted in every adapter (and accordion items in the HTML and shadcn adapters), so fields in other tabs keep their values and submit, as in Blade. The tab or item with an invalid field opens when errors arrive. New for adapters: `TabPanel` and `useReveal`. `Textarea wysiwyg` passes `className` and `onChange` on. The docs are rewritten for the adapter-based API, with `llms.txt`, an API reference, an upgrade guide from `@javaabu/react-forms`, and a Laravel Boost guideline and skill (`javaabu-react-forms`).
diff --git a/.changeset/i18n-strings.md b/.changeset/i18n-strings.md
new file mode 100644
index 0000000..caaf9c2
--- /dev/null
+++ b/.changeset/i18n-strings.md
@@ -0,0 +1,5 @@
+---
+"@javaabu/forms": minor
+---
+
+Strings now come from `@javaabu/i18n` under the Blade package's keys (`forms::strings.nothing_selected`), so apps change them in `lang/vendor/forms/{locale}/strings.php` as they do for the Blade components. Generated labels go through `__()` by default. The locale follows `@javaabu/i18n` (``, `setLocale()`) instead of Onu's. `FormsProvider messages` is gone, and the string keys are now snake_case like Blade's (`t("nothing_selected")`).
diff --git a/.changeset/inertia.md b/.changeset/inertia.md
new file mode 100644
index 0000000..67669eb
--- /dev/null
+++ b/.changeset/inertia.md
@@ -0,0 +1,5 @@
+---
+"@javaabu/forms": minor
+---
+
+New `@javaabu/forms/inertia`. `` submits every form as an Inertia visit, with files, method spoofing, error bags, progress, `preserveScroll` / `preserveState` (default `"errors"`) and `resetOnSuccess`. Errors and old input come from the page props. `
}}
>
- Contact us.
-
+
+ Contact us.
+
+
```
-Panel ids follow Blade: the key for named items, `-item--collapse` for list items.
+`items` is an object keyed by panel name, or a list. `slots` are Blade's named slots: `applicationStatus` (or `application-status`) for a panel's body, `applicationStatusHeader` for its header, and `item-0` for list items. Panel ids follow Blade: the key for named items, `-item--collapse` for list items. `show` opens a panel; with several open, more than one can be open at a time. `AccordionItem` takes `name`, `title`, `header`, `content` or children, `show`, `disabled` and `id`.
+
+Fields inside a closed item keep their values and are submitted, and an item opens when a field inside has an error. That holds with the HTML and shadcn adapters. With the Onu adapter, closed items are unmounted until [Javaabu/onu#60](https://github.com/Javaabu/onu/issues/60) lands, so put fields in `Tabs` or a fieldset instead.
-## Tabs and NavTabs
+# Tabs and NavTabs
```tsx
-
- …
- …
-
+import { NavTabs, Tabs, TabsPane } from "@javaabu/forms"
-
+
+ …
+ …
+
+
+
```
-## Modal, Status, ConditionalLink
+Every pane stays mounted, so a form split across tabs submits all its fields, as in Blade, and the tab with the first invalid field opens when errors arrive.
+
+`Tabs` takes `tabs` (`name`, `title`, `disabled`, `url`, `content`), `active` (default: the first), `slots` (pane content by slot name) and `onValueChange`. A tab with `url` navigates to it. When a field with errors is in a hidden tab, the tab opens so the field can take focus (HTML adapter). `NavTabs` are tabs that are links to pages (`title`, `url`, `active`, `disabled`, `icon`).
+
+# Modal
```tsx
-Edit}>…
-
-
+import { Button, Modal } from "@javaabu/forms"
+
+Edit}>
+ …
+
+```
+
+Open it with `trigger`, or control it with `open` and `onOpenChange` (`defaultOpen` for an uncontrolled start). `modalSizeClass` takes Bootstrap's size classes (`modal-sm`, `modal-lg`, `modal-xl`, `modal-fullscreen`; default `modal-lg`), or pass `size` (`sm`, `md`, `lg`, `xl`, `full`). It also takes `description`, `footer` and `id`.
+
+# Status
+
+```tsx
+
+ބާތިލް
+```
+
+`color` is a Bootstrap colour (default `primary`), mapped to a tone: `success`, `danger`, `warning`, `info` (`info` and `primary`), or neutral.
+
+# Conditional link
+
+```tsx
+import { ConditionalLink } from "@javaabu/forms"
+
+
```
-`ConditionalLink` links when `showLink` is true. Otherwise it links when `FormsProvider authorize(can, arg, guard)` allows it, and shows plain text when it doesn't.
+It links when `showLink` is true. Without `showLink`, it links when `FormsProvider authorize(can, arg, guard)` allows it, and shows plain text otherwise. The text is `children`, `value`, or the bound value of `name`.
+
+# How it renders
+
+The HTML adapter renders plain elements: `` for accordions, a tab list with ARIA roles, a `