# Form

## Overview

The form composition layer normalizes native form grouping patterns that combine multiple controls into one horizontal affordance.

Use it for semantic search forms and grouped control wrappers. Individual controls still come from the input, button, select, checkbox, radio, switch, and related component stylesheets.

## Usage

```html
<form role="search">
  <input type="search" name="q" placeholder="Search" />
  <button type="submit">Search</button>
</form>
```

Use `role="search"` on every form whose purpose is search unless an application has an explicit reason to expose different semantics. A compact search input and button do not need a fieldset. For an advanced search form where the query controls form a meaningfully labeled subset alongside filters, use a native fieldset and concise visible legend:

```html
<form role="search" class="flow">
  <fieldset role="group">
    <legend>Search governed knowledge</legend>
    <input type="search" name="q" />
    <button type="submit">Search</button>
  </fieldset>
  <!-- Search filters -->
</form>
```

```html
<fieldset role="group">
  <legend>Amount</legend>
  <input type="number" name="amount" />
  <button type="button">Apply</button>
</fieldset>
```

Use `form[role="search"]` for compact search bars. A grouped search row consists of one `input[type="search"]` followed by one `button[type="submit"]`; a preceding legend does not count as a grouped control or alter the input's outer corners. Use `fieldset[role="group"]` when grouped controls need a native legend. Use `div[role="group"]` only when a fieldset would be semantically incorrect.

Button-styled links can also form a group when the actions navigate to related destinations:

```html
<div role="group" aria-label="Source actions">
  <a class="button outline" href="/source">View source</a>
  <a class="button outline icon" href="/edit" aria-label="Edit source">edit</a>
</div>
```

Unlike most component styles, labels and legends do not map these values through component-specific variables. They consume the shared `--form-label-*` variables directly. This is intentional: customize these variables on the form or a containing region so every label and legend in that form retains the same visual treatment.

## Behavior

- FRM-001: A compact `form[role="search"]`, `fieldset[role="group"]`, and `div[role="group"]` render native buttons, button-styled links, and supported inputs as single horizontal control groups. A search form containing a grouped control row remains a normal block container so it can include filters.
- FRM-002: Adjacent controls overlap one border width so joins read as one divider.
- FRM-003: Interior control corners are square; only the first and last grouped controls keep the outer radius. A fieldset legend does not count when determining the first grouped control.
- FRM-004: `fieldset[role="group"]` resets native border, margin, and padding so it behaves like the other group wrappers.
- FRM-005: Inputs and text buttons or button-styled links in grouped controls grow and shrink together, while icon-only actions retain the square width defined by the shared control height.
- FRM-006: Native fieldsets that keep their border chrome derive their corner radius from `--form-control-radius`.
- FRM-007: Group wrappers fill their available inline space and contain their children’s intrinsic sizing so they do not force page-level horizontal overflow.
- FRM-008: Visible field labels and native legends consume the shared `--form-label-*` variables directly so their color, font size, and line height remain consistent across form control types.

## Accessibility

- Give every search form `role="search"` unless the application explicitly requires different semantics, and do not use it for non-search behavior.
- Use the search landmark itself for a compact bar. Use `<fieldset>` and `<legend>` when an advanced search form's query controls need a shared visible label that distinguishes them from filters; do not add the grouping when the individual controls are already sufficiently clear.
- Prefer `fieldset[role="group"]` with a visible `legend` when controls need a shared label.
- Keep grouped controls in logical source order.

## Variables

| Variable | Type | Description |
| --- | --- | --- |
| `--form-control-border-width` | `<length>` | Sets the border width used to join adjacent controls in semantic form groups; change it when grouped controls need to match a different control border rhythm. |
| `--form-control-radius` | `<length>` | Sets the fallback outer corner radius for grouped form controls; change it when a grouped control does not provide its own radius hook. |
| `--form-icon-button-inline-size` | `<length>` | Sets the square inline size of icon-only buttons inside grouped controls; change it when their typography or control padding requires a different footprint. |
| `--form-label-color` | `<color>` | Shared color for field labels and native legends. |
| `--form-label-font-size` | `<length>` | Shared font size for field labels and native legends. |
| `--form-label-line-height` | `<number>` | Shared line height for field labels and native legends. |
| `--grouped-control-radius` | `<length>` | Corner radius hook for controls inside native form groups. Buttons and inputs map this hook back to their component radius aliases so grouped controls keep compatible outer corners. |

## Depends On

- `--color-text-accent`
- `--font-line-height-body`
- `--font-size`
- `--layout-control-border-width`
- `--layout-control-min-height`
- `--layout-control-radius`
