Default (auto-fit, cell-min 16rem)
Cell 1
Cell 2
Cell 3
Cell 4
Cell 5
Cell 6
data-cols="3" (max 3 columns)
data-cols="4" tight gap
/*
* Grid-layout — section
*
* N-column grid that adapts via auto-fit + minmax. Container-aware:
* the cell-min token controls when columns merge as the container
* shrinks. data-cols pins a maximum column count.
*
* <section class="grid-layout">
* <div>Cell 1</div>
* <div>Cell 2</div>
* <div>Cell 3</div>
* </section>
*
* <section class="grid-layout" data-cols="4">
* <!-- max 4 cols, auto-collapse below -->
* </section>
*/
@layer malevich.components {
.grid-layout {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(var(--grid-layout-cell-min), 1fr));
gap: var(--space-gap-blocks-m);
padding-block: var(--space-inset-section-m);
padding-inline: var(--space-inset-section-m);
inline-size: 100%;
box-sizing: border-box;
}
/* data-cols pins a MAX column count by combining auto-fit with a
* larger min via the standard "grid-line-trick": specifying a
* second column-template-columns with explicit fr. We use the
* simpler pattern: data-cols overrides the auto-fit with explicit
* grid-template-columns above the cell-min, falls back below.
*/
.grid-layout[data-cols="2"] {
grid-template-columns: repeat(auto-fit, minmax(max(var(--grid-layout-cell-min), calc(50% - var(--space-gap-blocks-m))), 1fr));
}
.grid-layout[data-cols="3"] {
grid-template-columns: repeat(auto-fit, minmax(max(var(--grid-layout-cell-min), calc(33.33% - var(--space-gap-blocks-m))), 1fr));
}
.grid-layout[data-cols="4"] {
grid-template-columns: repeat(auto-fit, minmax(max(var(--grid-layout-cell-min), calc(25% - var(--space-gap-blocks-m))), 1fr));
}
.grid-layout[data-cols="6"] {
grid-template-columns: repeat(auto-fit, minmax(max(var(--grid-layout-cell-min), calc(16.66% - var(--space-gap-blocks-m))), 1fr));
}
/* Gap variants */
.grid-layout.-tight {
gap: var(--space-gap-elements-m);
}
.grid-layout.-loose {
gap: var(--space-gap-sections-s);
}
}
This component is pure CSS — no JavaScript required.
# Grid-Layout — AGENTS.md
> Auto-generated from `grid-layout.docs.md` + the modifier applicability matrix.
> Edit those source files; this file regenerates on build.
## Identity
- **Component:** `grid-layout`
- **Layer:** sections
- **Status:** stable
- **Last updated:** 2026-05-19
## Summary
- Card grids, feature grids, pricing tables.
## Variants
| Variant | Behavior |
|---------|----------|
| Default | `auto-fit` cells of min 16rem |
| `data-cols="2"` | Up to 2 columns |
| `data-cols="3"` | Up to 3 columns |
| `data-cols="4"` | Up to 4 columns |
| `data-cols="6"` | Up to 6 columns |
| `.-tight` | Compact gap |
| `.-loose` | Larger gap |
## Modifier applicability
Per ADR-0007. Modifiers attach via `data-{category}="value"` attributes.
| Category | Accepts |
|---|---|
| `background` | — |
| `surface` | — |
| `effect` | — |
| `shader` | — |
| `rhythm` | `compact`, `regular`, `spacious` |
| `motion` | any value |
| `behavior` | — |
## Anatomy
```html
<!-- Auto-fit: cells reflow based on container width -->
<section class="grid-layout">
<article>Cell 1</article>
<article>Cell 2</article>
<article>Cell 3</article>
</section>
<!-- Max 4 columns -->
<section class="grid-layout" data-cols="4">
<!-- ... -->
</section>
```
## Tokens consumed
- `--space-gap-blocks-m` — default gap
- `--space-gap-elements-m` — tight gap
- `--space-gap-sections-s` — loose gap
- `--space-inset-section-m` — outer padding
### Component-tier (generated)
- `--grid-layout-cell-min` (16rem) — minimum cell width