Tailwind

Import the stylesheet into a layer, and Tailwind's utilities can override any component.

Set it up

/* app/globals.css */
@import "tailwindcss";
@import "alpenglow/styles.css" layer(components);
@import "alpenglow/tailwind-theme.css";

Why a layer

Tailwind keeps its rules in cascade layers: its reset in base, utilities in utilities. A rule in no layer beats every layered rule, whatever its selector. Alpenglow's stylesheet ships in no layer on purpose, so that an app's global rules cannot unstyle a component — which, in a Tailwind app, also means className="rounded-none" on a button does nothing.

layer(components) puts the stylesheet between the two: above the reset, so preflight cannot strip a button, and below the utilities, so your classes win.

<Button className="rounded-none mt-6">Save</Button>

What the layer costs

Once the components are in a layer, a rule of your own that is in none beats them too. A global button { background: none } would empty every Alpenglow button. Keep resets in @layer base, where Tailwind keeps its own.

Without the layer

Import alpenglow/styles.css plainly and everything still works. An override then needs Tailwind's important modifier: rounded-none!.

Import it from CSS, not from JavaScript, either way. A layer chosen in CSS is fixed; the order of stylesheets imported from JavaScript is decided by the bundler.

The theme

tailwind-theme.css turns the tokens into utilities: 54 colours, 22 spacing steps, 10 radii, 13 text styles and 4 weights, generated from the same source as everything else. The colours point at the custom properties the components use, so they follow light and dark without a dark: of their own. The doubled name — text-text-primary — is Tailwind's: the utility is text- and the token is text/primary, and bg-surface-raised reads the same way.

<section className="rounded-lg bg-surface-raised p-300 text-text-primary">
  <p className="text-text-secondary">Due today</p>
</section>

When something should differ in dark, dark: follows the components' rule: data-theme="dark", or the system preference when no theme is set. Dark mode covers setting it.

<img className="dark:opacity-80" src="/chart.png" alt="Bookings this week" />

Choosing a utility

Utilities are for the layout around the components — the grid, the gap, the margin a button needs from the edge of its card — and for the text and surfaces of your own pages, through the theme's names. A component's own colour is not a place for one: a bg- on a Button repaints a fill whose label was measured against the fill it had, and a text- on a Badge does the same to its tone. If a component needs a colour it does not have, the answer is a tone or a token, not a class.

Tailwind's own palette stays available beside the theme — bg-blue-500 still compiles. Nothing in the system is measured against it, and it does not follow the light, so a page that uses it has left the system at that element. The theme's pairs are the ones on Colour and Accessibility: text-text-tertiary on bg-surface-raised is a measured pair, and a class from the raw palette is not.

Two utilities to keep away from a component. outline-none removes the focus ring, which is the only thing telling a keyboard where it is; the components draw their own and need nothing added. And a transition- of your own on something that moves belongs under motion-safe:, as the components' own motion sits under the reduced-motion query.