Skip to content

Tailwind in a Foundry package ​

Tailwind works inside a Foundry system or module once you change a few defaults.

Turn preflight off ​

Tailwind's reset restyles every element on the page. Inside Foundry that means the sidebar, the chat log and every other package's sheet, because your stylesheet loads into the same document.

js
// tailwind.config.mjs
export default {
  content: ['./scripts/**/*.{ts,mjs}', './templates/**/*.hbs'],
  corePlugins: { preflight: false },
};

@vttforge/styles already ships a reset scoped to its own layer.

Scope the utilities ​

Even without preflight, a utility like .flex is global. Two packages that both ship Tailwind fight over it. Give yours a prefix, or scope the whole build under your package class:

js
export default {
  prefix: 'my-',            // <div class="my-flex my-gap-2">
  important: '.my-system',  // or: every rule becomes .my-system .flex
};

The prefix is the safer of the two, because important raises specificity.

Point content at the templates ​

Tailwind only emits the classes it finds. Handlebars templates are where most of yours live, so list them, and list the scripts that build markup by hand.

Wire it up ​

Vite runs PostCSS on its own, so the plugin needs no extra config:

js
// postcss.config.mjs
export default { plugins: { tailwindcss: {}, autoprefixer: {} } };
css
/* styles/main.css */
@import '@vttforge/styles';
@tailwind utilities;

Import only utilities: base is preflight under another name, and components is empty until you add to it.

Keep the tokens ​

Tailwind's colour scale and VTTForge's tokens can coexist. Map the ones you use so a theme change reaches your utilities too:

js
theme: {
  extend: {
    colors: {
      ember: 'var(--vttf-ember)',
      surface: 'var(--vttf-surface)',
    },
  },
},

Now my-bg-surface follows the theme, and a custom theme built the way the theme recipe describes restyles it too.

MIT licensed.