# Hairline grid (goodtabs UI)

A rounded frame whose cells share 1px hairlines, with no rounding inside.

## Install

```bash
npx shadcn@latest add https://ui.goodtabs.co/r/hairline-grid.json
```

Or, with the @goodtabs namespace configured in components.json: `npx shadcn@latest add @goodtabs/hairline-grid`

## Usage

```tsx
import { HairlineGrid, HairlineCell } from "@/components/ui/hairline-grid"

<HairlineGrid columns={3}>
  <HairlineCell>First</HairlineCell>
  <HairlineCell>Second</HairlineCell>
  <HairlineCell>Third</HairlineCell>
</HairlineGrid>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| columns | `2 | 3 | 4` | `3` | Columns from sm up on HairlineGrid. Always one column below sm. |
| equalRows | `boolean` | `false` | Give every row the height of the tallest one. |
| padding | `"none" | "sm" | "default" | "lg"` | `"default"` | Inner padding on HairlineCell: 0, 12, 16 or 24px. |

## When to use

- Feature grids, stat strips and category tiles on marketing pages
- Any set of equal items that should read as one surface, not many cards
- Bento layouts where the lines, not shadows, separate the parts

## When not to use

- A single item: use a card
- Items that need their own hover, link or shadow: use separate cards with gap
- Tabular data with headers: use a table

## Notes for agents

- Server component with no dependencies; cells are plain divs, so pass className for flex or text styles
- Columns go 1, then 2 from sm, then the chosen count from lg; a partial last row is fine
- Each cell draws its own right and bottom hairline and the grid hangs 1px over the frame, so never add borders to cells
- Use padding="none" for images or anything that should run edge to edge

Docs: https://ui.goodtabs.co/components/hairline-grid