Tailwind CSS Setup

Introduction

ReeWeb uses Tailwind CSS v4 for styling. Tailwind is configured as a dev dependency - the SSG pipeline builds your source CSS into a minified output file that's served alongside your static pages. There is no runtime dependency and no client-side style computation.

How It Works

Tailwind v4 runs as a standalone CLI tool. It scans your template and markdown files for class names, generates only the CSS those classes reference, and outputs a single minified stylesheet. The pipeline is:

  1. Source CSS lives in src/css/style.css
  2. Tailwind processes it against src/public/ (templates and markdown)
  3. Output goes to src/public/css/style.css (both css:build and css:watch)
  4. bun ssg includes the CSS build and writes a style.css variant as part of its css:build step

The source file imports the framework and declares the theme:

@import "tailwindcss";
@source not ".git/**/*";
@source not ".vscode/**/*";
@source not "node_modules/**/*";

@source "../lib/**/*";

@theme {
    --color-brand: #b40000;
    --color-bg-page: #fafafa;
    --color-bg-card: #fefefe;
}

The @source directives tell Tailwind where to scan for class name usage. Templates live in src/public/, and project helpers in src/lib/. Directories like .git and node_modules are explicitly excluded to keep the scan fast.

Commands

# Build CSS once (minified) - output to src/public/css/style.css
bun css:build

# Watch mode for development
bun css:watch

# Full production SSG: fresh CSS build + static site + sitemap + RSS
bun ssg

Note: bun ssg includes the CSS build, sitemap generation, and RSS generation for a complete production-ready generation pass.

The scripts in package.json map to:

# Minified CSS - css:build and css:watch both output to style.css
tailwindcss -i ./src/css/style.css -o ./src/public/css/style.css --minify

# Watch mode for development (same output path, no --minify)
tailwindcss -i ./src/css/style.css -o ./src/public/css/style.css --watch --verbose

In development (bun dev), the Tailwind watcher runs concurrently with the dev server. Changes to your CSS source or template files trigger a recompilation automatically.

Theme Customization

The @theme directive in your source CSS defines project-specific design tokens. These extend Tailwind's default theme:

@theme {
    /* Brand colours */
    --color-brand: #b40000;
    --color-bg-page: #fafafa;
    --color-bg-card: #fefefe;

    /* Typography */
    --font-display: "Instrument Serif", serif;
    --font-sans: "Montserrat", system-ui, sans-serif;
    --font-mono: "DM Mono", monospace;
}

Custom colours become available as Tailwind utilities - bg-brand, text-brand, bg-bg-page, and so on. The --color- prefix is Tailwind's convention for mapping to bg-, text-, border-, etc.

Utility Layers

Tailwind v4 supports @layer directives for organising your custom CSS:

@layer base {
    /* Base styles applied to HTML elements */
    html { scrollbar-gutter: stable; }
}

@layer components {
    /* Component-specific styles extracted from repeated patterns */
    .btn { ... }
}

@layer utilities {
    /* Custom utility classes */
    .scroll-mt-30 { scroll-margin-top: 7.5rem; }
}

ReeWeb's process_docs_markdown post-processor also injects Tailwind classes directly into rendered HTML - headings, tables, code blocks, and links all receive classes during static site generation, so your documentation gets styled without manual class annotations. Those class strings live in src/lib/markdown_styles.ts (a project-owned file you can edit freely); the post-processor pipeline in lib/markdown_docs.ts stays style-free, so all your styling stays isolated in that one project-owned file. See the Markdown Docs Processor reference for the full list.

Best Practices

  • Use Tailwind utilities directly in .ree templates - class="text-lg font-bold text-brand" is the idiomatic approach.
  • Extract repeated patterns into @layer components when the same combination of utilities appears in more than three places.
  • Keep custom CSS in src/css/style.css - this is the single source file Tailwind processes.
  • For page-specific overrides, add a src/public/css/style.css that your layout loads after the main stylesheet.
  • Preview the generated site (bun preview) to verify styles look correct - the dev server applies Tailwind's output, but the production CSS build may use slightly different optimisation.