# ProductFrame

> Window or device chrome around a product screenshot or staged UI, optionally set on a tinted stage.

```ts
import { ProductFrame } from "@sdxc/ui/landing";
```

Wraps children in soft window or device chrome so a landing media slot reads
as a product surface rather than a bare image; `stage` sets it on a tinted
panel with room around it.

## Examples

```tsx
<ProductFrame lights title={t("frame.app")} url="app.example.com">
	<img src={shot} alt={t("frame.alt")} />
</ProductFrame>
```

```tsx
<ProductFrame stage="panel" shadow="tinted" footer={t("frame.caption")}>{ui}</ProductFrame>
```

## Props

| Prop | Type | Description |
| --- | --- | --- |
| `variant?` | `"window" \| "device"` | Outer chrome. Defaults to DEFAULT_VARIANT. |
| `stage?` | `"none" \| "panel" \| "backdrop"` | Panel the frame is staged on, centred at 86% of its width, and at full width under a thin pad below the `md` container. Host props and `mix` land on the stage. Defaults to DEFAULT_STAGE. |
| `backdrop?` | `RemixNode` | Image or gradient painted behind the frame on `stage="backdrop"`; a radial brand glow fills the stage when omitted. Always `aria-hidden`. |
| `shadow?` | `"stage" \| "tinted"` | Lift under the frame. Defaults to `"stage"`, and to a deep drop shadow on the device variant. |
| `lights?` | `boolean \| "color"` | Draws three decorative `aria-hidden` dots in the title bar: neutral ink with `true`, the red/amber/green set with `"color"`. |
| `title?` | `RemixNode` | Optional window title shown in the chrome bar. |
| `url?` | `RemixNode` | Optional URL or path shown as a quiet mono field in the chrome bar. |
| `footer?` | `RemixNode` | Optional caption row under the body, set as a 12px muted strip. |
| `designWidth?` | `string` | Narrowest width the framed UI lays out at, such as `"56rem"`. A narrower body keeps the desktop composition and shows it through `fit`, so nothing inside reflows or truncates on a phone. |
| `fit?` | `"crop" \| "scale"` | How a body narrower than `designWidth` shows it. Defaults to `"crop"`. |
| `parts?` | `PartsProps` | Per-part styling for frame, chrome, body and footer. |
| `children` | `RemixNode` | Product UI, screenshot, or staged sample inside the frame. |

Also accepts everything in `Omit<TagProps<"div">, "title">`.


## Types

| Name | Values | What it decides |
| --- | --- | --- |
| `Variant` | `"window" \| "device"` | Outer chrome: a desktop window with a title bar, or a phone-proportioned device rim. |
| `Stage` | `"none" \| "panel" \| "backdrop"` | What the frame sits on: the band itself, a tinted panel, or a panel with a backdrop image or brand glow behind the frame. |
| `Shadow` | `"stage" \| "tinted"` | Lift under the frame: the neutral stage shadow, or a brand-tinted two-layer lift that suits brand and inverse bands. |
| `Fit` | `"crop" \| "scale"` | How a body narrower than `designWidth` shows its content: cropped at the end edge under a fade, or scaled down whole. |
