feat(theme): add semantic/layouts — the container system - #884
Open
gabriel-lisboa-azion wants to merge 3 commits into
Open
feat(theme): add semantic/layouts — the container system#884gabriel-lisboa-azion wants to merge 3 commits into
gabriel-lisboa-azion wants to merge 3 commits into
Conversation
Ten tokens and nine `@utility` classes: how far content sits from the app chrome (BOUNDARY), how far things sit from each other (RHYTHM), and how wide a reading column may get (MEASURE). A DERIVED group: every token is a var() reference to --spacing-* / --container-*, never a literal length. That is why none carries a breakpoint map — the spacing scale is already fluid and var() is substituted at use time on the element, so a layout token follows the override for free. Duplicating the scale into layout would only let the two drift. Emitting them as `@utility` rather than `@layer components` is what gives them variants (`md:layout-column`), the same reason the typography utilities are emitted that way. Generalizes the utility emitter into emitUtilities(map) with a thin emitLayoutUtilities caller, so the shape is reusable. Regenerating dist also picks up one line main was stale on: an emitted comment that still read `bg-[var(--x)]` where the source has said `bg-(--x)` since ENG-47001.
The catalog's token allowlists are scraped from the built theme, so adding semantic/layouts adds ten --layout-* entries. Regenerated rather than hand-edited, which is what catalog:check verifies.
herbert-julio-azion
approved these changes
Aug 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The layout system every console page is built on, as a theme token group: ten tokens and nine
@utilityclasses, covering three decisions expressed once — how far content sits from the app chrome (boundary), how far things sit from each other (rhythm), and how wide a reading column may get (measure).Four container types, picked by what the page is:
.layout-column.layout-column-focused.layout-column-form.layout-form-create--layout-measure-control)Plus
.layout-boundary/.layout-boundary-inline, the two rhythm steps (--layout-section-gap,--layout-group-gap) with their.layout-section-start/.layout-group-startmargin forms, and.layout-field-controlfor the control side of a settings row.A derived group
Every token is a
var()reference to--spacing-*/--container-*, never a literal length, and that is why none of them carries a breakpoint map. The spacing scale is already fluid (--spacing-lgis1rem, then1.5remfromsm), andvar()is substituted at use time on the element — so a layout token follows the breakpoint override for free. Giving it its own map would duplicate the spacing scale into layout and let the two drift.Why
@utilityand not@layer componentsSame reason the typography utilities are emitted that way:
@layer componentsclasses are opaque to v4's variant resolver, and their modifiers silently drop. A layout class is exactly the kind you want behind a variant —md:layout-column.Two things worth a reviewer's eye
.layout-field-controlcarries a:not(#\#)specificity pin. It is applied toItem.Actions, whose own root already declaresshrink-0, and Vue merges both class lists onto one element. Custom@utilityblocks sort before the core utilities, so without the pinshrink-0wins and the control side can no longer yield to a long field name. Measured, not assumed —.layout-field-controlat byte 19079 vs.shrink-0at 31336 in a built bundle.#\#is an id no element can carry, so the selector always matches while reading (1,1,0); it is Tailwind's own important-strategy idiom and stays variant-safe. Only this one of the nine has it, because only this one has a live conflict.The boundary widening nests on the column, not the boundary. Specificity is (0,2,0) either way, so correctness does not decide it. Nesting on the column keeps both declarations that can set
max-widthin one block, keeps.layout-boundaryto the three padding declarations its name promises, and keeps "a fifth column class costs one line" true — they are generated from aCOLUMN_MEASUREmap and the nested rule comes along.Also in the diff
emitIllustrationUtilities-style emission generalized intoemitUtilities(map)with a thinemitLayoutUtilitiescaller.distpicks up one line main was stale on: an emitted comment still readingbg-[var(--x)]where the source has saidbg-(--x)since ENG-47001.DESIGN.md, a Layout row in Get Started, and the derived-group note in the theme's token README.DESIGN.mdships here rather than separately because that section is the catalog for these tokens — documenting them before they exist would be the drift the rule guards against.Verification
build:tokensclean,assertNoZeroWithUnitpassing, theme suite 12/12.git diff dist/v4/globals.cssis additions only apart from the stale comment: 10--layout-*lines in:root, no new@medialines (every token is a barevar()), 9 new@utilityblocks.validate-story-source --allreports 91/91 compliant.