Skip to main content
A widget styles itself with utility classes in its ui.tsx. There is no styles.css at any level of an app folder, and nothing imports one:
text-ink-muted comes from the distribution template’s src/index.css, which is the Tailwind entry and the design system in one file:
src/index.css
Every entry under @theme becomes a utility, so --color-ink gives you text-ink and bg-ink. Rebranding every app on the template is a matter of editing those four values in the template repo. The generator writes one import of that file into each src/views/<widget>.tsx entry, and since each view is its own bundle, Tailwind emits only the utilities that view’s source uses.

The dark class

A view is mounted alone in its own iframe, so there is no shared ancestor to hang the variant off. Each widget puts the class on its own root, driven by the theme the host reports:

The stylesheet’s origins

src/index.css pulls Inter from Google Fonts, and a host that enforces the widget CSP drops undeclared requests without erroring, so the font falls back and the widget looks subtly wrong. Codegen reads the origins off the stylesheet and the runtime merges them into every widget’s resourceDomains, alongside whatever the widget declares itself. fonts.googleapis.com brings fonts.gstatic.com with it, since the second is only reachable by following the first.

Why app-level CSS is refused

Tailwind v4 rejects @apply in any file that has not imported Tailwind itself:
Fixing that from an app folder means writing a @reference at a path into the generated tree, which does not exist in the author’s own repo. One place for a class name beats two, so the build check names a stray styles.css rather than letting it sit there doing nothing: