template-kit/css-reason
The template-kit/css-reason authoring rule — what it enforces, why, and how to fix it.
Hand-written CSS is the escape hatch from Tailwind, so every stylesheet must open with a comment saying what it escapes for.
Every hand-written .css file — a section’s styles.css, any other .css in a section
folder, and the template’s own styles.css — must begin with a block comment
containing the token css-reason:.
Three ways to get this wrong:
- The comment is not first. The token must be in the file’s leading comment.
Mentioning
css-reason:further down, after a rule, does not pass. - The comment is a
//line.//does not open a comment in CSS. It is not a comment at all — it is a parse error waiting to happen, and it does not satisfy this check. - The file is in a subdirectory and you assumed it was exempt. CSS is collected by
path, not by import: the build walks the whole section folder. A stylesheet at
sections/map/styles/markers.cssis gated — and published — exactly likestyles.css.
The token is all that is checked, but the sentence after it is the point. Write it for the next author.
Reason
Section titled “Reason”Tailwind is the default, and it is the default for a reason: a utility class is scoped to the element it sits on, participates in the cascade layers the platform already orders, and cannot leak into another section on the same page. Hand-written CSS gives all of that up.
There is exactly one thing utilities cannot do: style DOM that Tailwind’s scanner never sees. Markup an island builds at runtime has no class in your source for the scanner to find, and a third-party widget’s own DOM was never yours to put classes on. Those are the cases hand-CSS exists for.
We cannot cheaply prove that a given rule is inexpressible as a utility — so the check enforces the half of the bar that is checkable: you have to say which un-scannable DOM you are styling. A stylesheet that cannot name one is almost always a stylesheet whose rules should have been utility classes, and a reasonless file leaves the next author unable to tell the difference.
Make the first thing in the file a block comment that names the DOM Tailwind cannot see. If you find you cannot name one, that is the answer: delete the CSS and use utility classes on the markup.
Before
Section titled “Before”.tr-map-marker { display: grid; place-items: center; border-radius: var(--tr-radius-full); background: var(--tr-color-primary);}/* css-reason: styles the marker DOM the neighborhood-map island builds at runtime — the nodes are created by the map library after hydration, so Tailwind's scanner never sees a class to compile. */.tr-map-marker { display: grid; place-items: center; border-radius: var(--tr-radius-full); background: var(--tr-color-primary);}And the case where the fix is not a comment at all — this rule is expressible as utilities, so the stylesheet goes away and the classes move onto the element:
<div className="grid place-items-center rounded-full bg-primary" />See also
Section titled “See also”- Theme and CSS — the token namespace utilities compile from, and the layer order hand-CSS lands in.
no-bare-css-import— the other constraint on a hand-written stylesheet: no@import, ever.unlayered-fence— the escape hatch within the escape hatch.