## AirForm 0.5.0: Excludes, save_data(), and built-in styles

Forms start with all fields and subtract what they don't need. `excludes` controls what renders and what saves, with scoped tuples for fine-grained control. `save_data()` returns a dict ready for `await MyModel.create()`. And `default_css()` makes forms look good without a CSS framework.

```sh
uv add AirForm --upgrade
```

### What's new

- **Scoped excludes.** A bare string like `"created_at"` hides the field from both rendering and saving. A tuple like `("finish", "display")` hides it from the form but keeps it in `save_data()`. PrimaryKey fields are display-excluded by default.

```python
class ArticleForm(AirForm[Article]):
    excludes = ("created_at", ("slug", "display"))
```

- **`save_data()` method.** Returns `form.data.model_dump()` minus save-excluded fields. The pattern for database persistence is now one line:

```python
await Article.create(**form.save_data())
```

- **`default_css()` built-in stylesheet.** AirForm ships CSS that styles every element it renders: field layout, input borders, focus rings, error states, help text, and checkbox alignment. Load it with `airform.default_css()`.

### What's changed

- **`includes` is removed.** Forms are subtractive only. Use `excludes` to hide fields instead of `includes` to show them. Custom widgets that accepted an `includes` parameter should accept `excludes` instead.

- **CSRF validation simplified.** The Pydantic wrapper model is replaced with a pre-check that pops the token and verifies the HMAC before Pydantic runs. `form.data` is now a properly validated instance of the user's model with all their validators run.

### Contributors

[@audreyfeldroy](https://github.com/audreyfeldroy) (Audrey M. Roy Greenfeld) built this release.
