Skip to main content

Decoration

Foundations

The decoration dial: one 0–10 setting that adds or removes background texture and chart-fill expressiveness across a whole subtree, without touching controls.

Examples

5 live examples

Fade

The GROUND FADE (`data-decoration-fade`) — an opt-in region gesture that fades the ambient graph paper out instead of ruling a region edge to edge. It paints the SAME `--deco-grid` on a decorative `::before` layer and masks THAT, so the ink still rides the dial (inert at decoration 0) and the region's own content is never masked — the text in each panel stays at full opacity. The fade OWNS its region's ground. Opaque surfaces are never ruled themselves — the ambient sheet is painted once, behind the page — so a nested surface can't punch a crisp, full-strength rectangle into the field that was just faded out (the third panel below nests a `bg-card`). Budget: it spends the region's one focal drafting gesture. For a one-off fade on a single element, use Tailwind's own `mask-t-from-*` / `mask-radial-*` utilities. Shipped in anger on `Patterns/Templates/Starters/Marketing`, whose hero band carries `data-decoration-fade="top"` so the sheet fades in behind the headline instead of starting on a hard ruled edge — that template, not this matrix, is the surface to judge the gesture on. Sweep it with the **Decoration** toolbar (this story pins the dial to 10 so the gesture is visible on every theme; at 0 the mask has nothing to reveal).

Ambient Ground

The AMBIENT GROUND, as an executable lock. The sheet is painted exactly once — on a fixed, masked layer behind the page — so this asserts the three properties a static reading of the CSS cannot: the layer exists and carries the dial-driven grid, it is MASKED (never flat), and no opaque surface re-rules it on top. The dial is set from the toolbar global, which writes `data-decoration` on the preview root exactly as `ThemeProvider` does — a `DecorationProvider` wrapper would NOT reach `body`, which is why `Dial` above cannot stand in for this.

Controls Are Untouched

The control invariant, as an executable lock: at FULL decoration the dial must not have painted anything into a control. A `Button` keeps its solid role fill (no `background-image`), an `Input` keeps a clean ground, and a `Badge` keeps its own tone rather than collapsing to a drawn outline. This is the story to run when someone reintroduces a "drawn-not-filled" rule: it fails on the hatch, not on a screenshot review three weeks later.

Hairlines

THE HAIRLINE FAMILY — the quiet line-work of a calm product page, as opt-in utilities (`packages/tokens`, the `--hairline-*` block). Like the paper grounds it is NOT on the dial: you ask for one gesture on one element and get it at any decoration level, in any theme. Lines take the theme's own rule ink (`--rule` / `--rule-strong`); the hatch is a translucent tint of `--foreground`, so a brand re-tints all of it by doing nothing. | utility | the gesture | | --- | --- | | `bg-hairline-hatch` | a faded diagonal hatch — the recessed WELL behind media (`CardMedia` default) | | `bg-hairline-stripes` | stripes streaming out of one corner, thinning as they fade — a hero / header ground | | `hairline-stack` | two sheet edges stacked under a card (`<Card stacked>`) | | `hairline-slot` | a dashed placeholder outline | | `hairline-frame` | dashed rails that run past a box's corners and fade | | `hairline-rails` | the same for a full-bleed section: rails down the content column, inked only near the corners (`hairline-rails-full` for whole lines) | | `hairline-corners` | crop marks on the focal item | | `hairline-ticks-y` / `-x` | a tick ruler along an edge | | `hairline-rule` / `-y` | a dashed separator | Surfaces and the space between them only — never a control. One focal gesture per region; each utility owns its host's pseudo-elements, so nest a wrapper to combine two.