# Layout Family

Canonical: https://socra.design/layout/layout-family

The direct intent-based layout family — Center, Column, Page, and Row — structure says what it is, never how many pixels.

Import Center, Column, Page, and Row directly from @socra/ui-web-layout for product screen structure: Page is the one page frame (h1, description, gutters, scroll region), Row and Column are the only flex intents (closed gap and padding scales, grow for the flexible cell), and Center is the pending/centered region. Margins do not exist — parents own the space between children.

Status: ready. Center, Column, Page, and Row ship as direct named exports from @socra/ui-web-layout with MUI as the internal rendering engine and executable public-API, behavior, and tree-shake contracts.

Library: @socra/ui-web-layout

## Anatomy

- Page — the standard page frame: required h1 title, optional description (aria-describedby) and accessory, finite standard | medium | narrow width; the scroll region, responsive gutters, and content rhythm are under the hood.
- Row — one horizontal intent: gap (none/tight/compact/regular/relaxed/spacious), align (center default), justify (start/center/end/between), padding steps, grow; wrap XOR collapse at the type level.
- Column — one vertical intent: gap, align (stretch default), padding, grow (the flexible cell — min-size 0 baked in so truncation works).
- Center — both-axis centering; height="section" reserves the standard pending-region height.

## States

- **Rest:** Shows the stable, enabled component without implied activity.
- **Hover:** Adds pointer affordance without moving content or changing meaning.
- **Focus:** Shows the shared visible focus treatment without depending on hover.
- **Pressed:** Acknowledges active input immediately and returns cleanly on release.
- **Selected:** Uses a neutral surface plus native selected semantics when selection applies.
- **Disabled:** Remains legible, unavailable, and absent from misleading interaction feedback.
- **Loading:** Preserves context while honestly identifying work that has not completed.
- **Error:** Places the failure and recovery path beside the action or content that failed.

## Motion

Stable state changes respond immediately. Appearance, expansion, and morphing begin at the triggering origin and use an interruptible spring that can retarget from its live position and velocity. When spatial motion is not meaningful, the component changes without decorative travel.

## Usage

- Say the intent, never the pixels. The closed gap scale (0/4/8/16/24/32) and padding steps are the only lengths — deviation dies at the type level.
- Use Page for the product page frame. ScrollContainer/Container/margin arithmetic never appears in product page code again; structure is never the call site’s job.
- Mark the flexible cell with grow. grow bakes in flex:1 + min-size 0, so `flex:1, minWidth:0` can never be hand-rolled and truncation always works.
- Use collapse for rows that stack on compact widths. One named intent replaces every per-breakpoint direction object; alignment is standardized in both states.

## Avoid

- Do not add margins or raw lengths to children. Parents own spacing; margins do not exist anywhere in the family.
- Do not reach for the deprecated Stack/Box/Flex/Container/ScrollContainer. Those open-styled predecessors are deprecated in favor of direct @socra/ui-web-layout components — two blessed ways must not coexist.
- Do not use layout components to rebuild dividers or cards. A divided collection is list.List/list.Item and a card is Surface — Column stays pure.
- Do not pass styling props — there are none. sx/className/style/polymorphism are rejected at the type level.

## Tokens

- `designTokens.color[mode].color.brand.primary`: Primary action role.
- `designTokens.color[mode].color.surface.secondary`: Working surface role.
- `designTokens.color[mode].color.content.primary`: Primary content role.
- `designTokens.spacing.role.contentGap`: Spacing relationship.
- `designTokens.shape.role.control`: Shape relationship.

## Example

```tsx
<Page
  title="Billing"
  description="Subscription, payment, and billing details for this account."
>
  <Column gap="regular">
    <Caption>Payment method</Caption>
    <Row collapse gap="regular">
      <Column grow gap="tight">
        <Title>Visa ending in 4242</Title>
        <Detail>Expires 04/28</Detail>
      </Column>
      <Button variant="outlined" onClick={changeCard}>Change</Button>
    </Row>
  </Column>
  <Column gap="regular">
    <Caption>Available plans</Caption>
    {pending ? (
      <Center height="section">
        <feedback.Spinner />
      </Center>
    ) : (
      plans
    )}
  </Column>
</Page>
```
