Skip to main content
196

Search Lumen

Find components, APIs, guides, and recipes.

GitHub
Web docs
Web integration · Tailwind CSS v4

Tailwind CSS

Keep Lumen's accessible controls and semantic themes. Add Tailwind for responsive composition and focused presentation changes through class or className.

1. Connect your styles

The optional tailwind.css bridge is available from Lumen 4.3. It adds semantic color utilities to an existing Tailwind v4 build. Lumen's standalone stylesheet continues to work without Tailwind.

Install your Lumen adapter, then set up Tailwind using its Vite integration for Astro or React with Vite, or its PostCSS integration for Next.js. In Astro, register tailwindcss() in vite.plugins.

bash
pnpm add @santi020k/lumen-astro
pnpm add -D tailwindcss @tailwindcss/vite
pnpm add @santi020k/lumen-astro
pnpm add -D tailwindcss @tailwindcss/vite

Keep all four imports in one global CSS entry, in this order. Load that file once from your root layout or app entry. Choose the adapter you installed:

css
@import "@santi020k/lumen-astro/layers.css";
@import "tailwindcss";
@import "@santi020k/lumen-astro/styles.css";
@import "@santi020k/lumen-astro/tailwind.css";

The first import establishes the cascade before Tailwind's reset. Lumen's components then retain their defaults, while the final utilities layer can override presentation. The bridge maps colors; it does not import Tailwind, reset styles, or component CSS.

Keep the usual runtime setup: mount UIPrimitives once in an Astro root layout; use React components normally; call defineLumenElements() once for Elements. Follow the Astro, React, or Elements guide. The CLI also prints this setup with lumen init --framework astro --tailwind.

2. Compose with utilities

Use component props for variants, sizes, disabled states, and behavior. Use utilities for local spacing, width, responsive layout, and presentation. Astro and Elements accept class; React accepts className.

Your next project

Accessible components, your layout.

Explore components
astro
---
import { ButtonLink, Card } from '@santi020k/lumen-astro'
---

<Card class="rounded-none p-6 sm:p-8">
  <h3 class="text-xl font-bold text-ink">Your next project</h3>
  <p class="text-ink-soft">Accessible components, your layout.</p>
  <ButtonLink href="/projects" class="w-full sm:w-auto sm:self-start">
    View projects
  </ButtonLink>
</Card>

The live card has square corners and responsive padding. Its link fills the available width on phones. Tailwind changes those properties while Lumen still supplies the component structure and keyboard focus treatment.

3. Share one semantic palette

The bridge exposes canvas, surface, surface-muted, surface-strong, line, ink, ink-soft, ink-muted, brand, brand-solid, brand-soft, on-brand, accent, success, warning, danger, and on-danger.

Use them anywhere Tailwind accepts a color: bg-surface, text-ink, border-line, ring-brand, or bg-brand/10. Pair bg-brand-solid with text-on-brand and bg-danger with text-on-danger; check contrast for your theme overrides.

Light surface

The same utility names follow this card's theme.

Explore themes

Dark surface

The same utility names follow this card's theme.

Explore themes
astro
<Card data-theme="lumen-dark" class="bg-surface text-ink">
  <p class="text-ink-soft">This surface follows its local Lumen theme.</p>
</Card>
<Card data-theme="lumen-dark" class="bg-surface text-ink">
  <p class="text-ink-soft">This surface follows its local Lumen theme.</p>
</Card>

Aliases use @theme inline, so colors resolve where the utility is used, including nested data-theme scopes. Set your theme on the root for the whole app. Semantic color utilities already follow that theme without dark: classes. The bridge does not change Tailwind's dark variant; configure that variant separately if you use it for structural changes.

Customize through public hooks

Prefer props and semantic tokens first, then documented component variables or stable data-slot parts. For example, tune the card's padding with a custom property utility:

astro
<Card class="[--ui-card-padding:2rem]">
  Content with the documented Card padding hook.
</Card>
<Card class="[--ui-card-padding:2rem]">
  Content with the documented Card padding hook.
</Card>

For compound components, place utilities on the public part you want to style. With Elements, a host class styles the custom element; it does not automatically style an internal input or button. Consult the component's public parts instead of targeting private .ui-* selectors. Preserve visible focus, readable contrast, and usable touch targets.

Choose whether to include Preflight

The standard Tailwind import includes Preflight, which resets native headings, lists, borders, and form styles across your app. If you already own a reset, omit Preflight and import Tailwind's theme and utilities separately:

css
@import "@santi020k/lumen-astro/layers.css";
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/utilities.css" layer(utilities);
@import "@santi020k/lumen-astro/styles.css";
@import "@santi020k/lumen-astro/tailwind.css";
@import "@santi020k/lumen-astro/layers.css";
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/utilities.css" layer(utilities);
@import "@santi020k/lumen-astro/styles.css";
@import "@santi020k/lumen-astro/tailwind.css";

Keep the Lumen layer prelude first in either setup. Follow Tailwind's Preflight guide when choosing the reset for your application.

When a utility does not apply

  • Missing color utilities: confirm that the matching tailwind.css bridge is imported and your CSS passes through Tailwind v4. It is a build-time stylesheet, not a browser-only import.
  • Utilities lose to defaults: put layers.css before the first Tailwind or Lumen stylesheet. Keep imports together and remove duplicate component stylesheet imports from JavaScript.
  • Utilities are absent: keep complete class names in source. Use a map of literal classes instead of building names such as `bg-${color}`. In a monorepo, configure @source for your own shared UI files.
  • Should I scan Lumen's package? No. Lumen ships its component CSS. Tailwind only needs to scan the consumer files where you write utilities.
  • An override still loses: inline styles, unlayered app CSS, and important declarations can take precedence. Inspect the computed style and use a documented hook where the component owns that value.
  • Using Tailwind v3? This bridge uses v4's @theme directive. Keep standalone Lumen CSS and your existing v3 setup, or migrate Tailwind before adopting the bridge.

See Tailwind theme aliases and source detection for the underlying build behavior.

Web docsFull catalog