Layout System — Specification
Standardised layout attributes for grid and section runes, page-level breakout, showcase effects, background media Tint Rune Specification, Community Runes Specification, Vite Plugin Specification
Problem
Layout control in refrakt.md is currently fragmented. The grid rune uses layout for column ratios. The feature rune uses split and mirror for two-column arrangement. Other section runes have no layout control — their arrangement is entirely theme-determined. Authors who want a hero with a side-by-side layout, a testimonial with a reversed image position, or a feature section that breaks out of the content column have no consistent way to express these choices.
This creates three problems. First, authors lack control over how their content is spatially arranged. Second, each rune reinvents layout attributes independently, leading to inconsistent naming (split vs layout, mirror vs reverse). Third, themes must implement split layout separately for every section rune that supports it, duplicating CSS.
Design Principles
Standardised attributes. The same attribute names mean the same thing across all runes that support them. layout, ratio, align, gap, width — each has one meaning regardless of which rune it appears on.
Section runes own their zones. A feature rune knows it has a content zone and a media zone. The hr delimiter separates them. Layout attributes control how those zones are arranged. The rune stays self-contained — all content is inside the rune tag.
Theme interprets, author directs. The author says layout="split" and align="center". The theme decides the exact column widths, gap sizes, breakpoint behaviour, and visual treatment. Named presets keep authoring simple while giving themes full control over the specifics.
Progressive enhancement. Every layout attribute is optional. A section rune with no layout attributes renders in its default stacked arrangement. Attributes add control incrementally. A theme that doesn't support a particular attribute ignores it gracefully.
Page Grid
The page uses a CSS Grid layout with named column lines that define three width tracks: content, wide, and full. All block-level runes are direct children of this grid.
.rf-page-content > article {
display: grid;
grid-template-columns:
[full-start] 1fr
[wide-start] minmax(0, var(--rf-wide-inset, 8rem))
[content-start] min(var(--rf-content-max, 80rem), 100% - var(--rf-content-gutter, 1.5rem) * 2)
[content-end] minmax(0, var(--rf-wide-inset, 8rem))
[wide-end] 1fr
[full-end];
}
/* Default: all children sit in the content column */
.rf-page-content > article > * {
grid-column: content;
}
This upgrades the current 3-column grid (1fr | content | 1fr) to a 5-track grid with named lines. The current grid-column: 1 / -1 full-bleed pattern continues to work during migration. The named lines add the wide track and make [data-width] selectors possible.
Width Attribute (base attribute, all block runes)
Every block rune accepts a width attribute that controls which page grid track it occupies:
| Value | Grid column | Purpose |
|---|---|---|
content (default) | content | Standard content width |
wide | wide | Wider than content, narrower than viewport |
full | full | Full viewport width |
{% hero width="full" %} <!-- full-bleed hero -->
{% gallery width="wide" %} <!-- wider gallery -->
{% datatable width="content" %} <!-- default, explicit -->
{% sandbox width="wide" %} <!-- wider sandbox -->