# @spark-web/box — AI Context

## What this is

The foundational layout primitive. Every Spark component is built on `Box`. It
exposes a prop-based API for applying theme-constrained styles to any HTML
element. Use it when no higher-level layout component (`Stack`, `Row`,
`Columns`) fits the shape of what you need.

## What this is NOT

- Not a text component — use `Text` for any rendered text content
- Not a layout shorthand — for vertical stacks use `Stack`, for horizontal rows
  use `Row`, for CSS grid use `Columns`
- Not a button — use `Button` or `ButtonLink` for interactive elements

## Props interface

`Box` accepts all `BoxStyleProps` (see below) plus:

| Prop        | Type                          | Notes                                            |
| ----------- | ----------------------------- | ------------------------------------------------ |
| `as`        | `keyof HTMLElementTagNameMap` | Changes the rendered element; defaults to `div`  |
| `asElement` | `keyof HTMLElementTagNameMap` | Tells the reset system what element `as` renders |
| `children`  | `ReactNode`                   | —                                                |
| `data`      | `DataAttributeMap`            | Test/analytics attributes                        |
| `id`        | `string`                      | —                                                |
| `css`       | `CSSObject`                   | Escape hatch for styles not covered by props     |

### BoxStyleProps — commonly used

Spacing values map to `SparkTheme['spacing']` keys:
`none | xsmall | small | medium | large | xlarge | xxlarge`

Sizing values map to `SparkTheme['sizing']` keys:
`xxsmall | xsmall | small | medium | large | xlarge | xxlarge | full`

| Prop                              | Values                                                                       |
| --------------------------------- | ---------------------------------------------------------------------------- |
| `padding`                         | spacing token (responsive)                                                   |
| `paddingX`                        | spacing token (responsive)                                                   |
| `paddingY`                        | spacing token (responsive)                                                   |
| `paddingTop/Bottom/Left/Right`    | spacing token (responsive)                                                   |
| `margin`                          | spacing token (responsive)                                                   |
| `marginX/Y/Top/Bottom/Left/Right` | spacing token (responsive)                                                   |
| `gap`                             | spacing token (responsive, excludes `none` and `full`)                       |
| `width`                           | sizing token or `'full'` (responsive)                                        |
| `height`                          | sizing token (responsive)                                                    |
| `display`                         | `'block' \| 'inline' \| 'inline-block' \| 'inline-flex' \| 'flex' \| 'none'` |
| `flexDirection`                   | `'row' \| 'rowReverse' \| 'column' \| 'columnReverse'`                       |
| `flexWrap`                        | `'wrap' \| 'nowrap'`                                                         |
| `alignItems`                      | `'center' \| 'flexStart' \| 'flexEnd' \| 'stretch'`                          |
| `justifyContent`                  | `'start' \| 'center' \| 'end' \| 'spaceBetween' \| 'stretch'`                |
| `flexShrink`                      | `0 \| 1`                                                                     |
| `position`                        | `'relative' \| 'absolute' \| 'fixed' \| 'sticky'`                            |
| `top/bottom/left/right`           | `number` (responsive)                                                        |
| `overflow`                        | `'hidden' \| 'auto' \| 'scroll' \| 'visible'`                                |
| `background`                      | background token (e.g. `'surface' \| 'primary' \| 'primarySoft'`)            |
| `border`                          | border color token (e.g. `'standard' \| 'primary'`)                          |
| `borderRadius`                    | `'small' \| 'medium' \| 'large' \| 'full'`                                   |
| `cursor`                          | `'default' \| 'pointer'`                                                     |

## Token usage

All values come from the theme — never raw hex, px, or Tailwind. Use
`useTheme()` from `@spark-web/theme` for any value not expressible as a Box prop
(e.g. inline color from `theme.color.foreground.muted`).

The `background` prop automatically pushes a background context so child `Text`
components can invert their color tone when placed on dark backgrounds.

## Composition

`Box` is the leaf — it does not compose other Spark components. Every other
Spark component composes `Box` internally.

## Do NOTs

- NEVER use raw hex, px, em, rem, or Tailwind classes
- NEVER use `Box` for text content — use `Text`
- NEVER use `Box` when `Stack`, `Row`, or `Columns` fits the layout — those
  components encode the correct flex/grid setup automatically
- NEVER pass `display`, `alignItems`, `flexDirection`, or `justifyContent` to
  `Stack` or `Row` — those are locked internally; use `Box` if you need custom
  flex control
- NEVER use `style={{}}` for theme values — use Box props or `css` prop with
  theme tokens
