template-kit/no-bare-css-import
The template-kit/no-bare-css-import authoring rule — what it enforces, why, and how to fix it.
No
@importin hand-written CSS. Not even a package’s — the browser drops it silently, and the styles simply never ship.
A hand-written stylesheet may not contain a top-level @import. That means the
stylesheets the CSS build collects out of your section and template folders — a section’s
styles.css, any other .css in a section folder, and a template’s own hand-written
stylesheet.
There is no carve-out for a package specifier. @import "swiper/css"; is exactly as
illegal here as @import "./tokens.css";. Both are reported, at the 1-based line of the
first offender.
The scan is comment-aware, so an @import written about rather than as code is prose
and passes:
/* css-reason: … *//* Never @import here — see template-kit/no-bare-css-import. */ ← fine, it's a commentYour Tailwind entry is not one of these files. The file that carries
@import "tailwindcss"; and @import "@homepages/template-kit/styles.css"; is a Tailwind
entry: it is compiled by Tailwind, its @imports are resolved at build time, and it is
never wrapped in a cascade layer. It is not hand-written section or template CSS, and this
rule does not reach it.
Reason
Section titled “Reason”Every hand-CSS file the build collects is concatenated into a cascade layer:
@layer sections { /* your styles.css, pasted in here */}That is how a section’s CSS lands in the layer order (theme, base, components, sections, template, utilities) instead of fighting Tailwind’s utilities for specificity.
@import is invalid inside a @layer block. And CSS’s error handling for an invalid
at-rule is not an error — it is a shrug. The browser drops the statement and parses on.
Nothing throws. Nothing warns. Your build succeeds, your preview looks plausible because
the package’s own styling is missing in a way you have learned to read as “unstyled yet”,
and the published page ships without the rules you imported. This is the quietest failure
in the whole kit: the only signal is that the styles are not there.
Delete the @import.
A package’s stylesheet is reached from the code that needs it, not from CSS. Write
import "swiper/css"; in the component or island that renders the thing — the CSS build
bundles your Renderer.tsx and everything it imports, transitively, precisely to harvest
those imports, and it compiles what they pull in into this section’s cascade layer.
Package CSS goes in first and your own hand-CSS second, so at equal specificity your rules
win.
Two things authors get wrong immediately after:
- Bare specifiers only. A CSS import that resolves outside
node_modulesis an error, not a fallback. Your own stylesheets are discovered by filename — importing one from code would ship it twice. Seeno-css-import-from-render-path. - Importing is not installing.
import "swiper/css"does not addswiperto yourpackage.json. Add the dependency, or the install that builds your submission has nothing to resolve.
Before
Section titled “Before”/* css-reason: styles the slide DOM the Swiper carousel builds at runtime. */@import "swiper/css"; /* template-kit/no-bare-css-import — silently dropped */
.tr-gallery .swiper-pagination-bullet-active { background: var(--tr-color-primary);}The pagination override ships. Swiper’s own layout CSS does not — and no error says so.
The @import is gone from the stylesheet:
/* css-reason: overrides the Swiper pagination DOM the carousel builds at runtime — those nodes carry the library's own classes, which Tailwind's scanner never sees. */.tr-gallery .swiper-pagination-bullet-active { background: var(--tr-color-primary);}…and the package’s CSS is imported from the module that needs it, which is what routes it into this section’s layer:
"use client";
import Swiper from "swiper";import "swiper/css"; // ← the sanctioned channel: the CSS build harvests this import
export default function Carousel({ slides }: { slides: { id: string; url: string }[] }) { // …}See also
Section titled “See also”no-css-import-from-render-path— the other half of this mental model. Hand-written CSS: no@imports at all, package or otherwise. Render path: no local CSS imports, but a package’s bare specifier is exactly right. An author who reads only one of the two pages will be confused by the other.css-reason— the comment every hand-written stylesheet opens with.- Theme and CSS — the cascade-layer order, and the one file that
legitimately does
@import "tailwindcss".