Skip to main content
@fanvue/ui has no compiled stylesheet. The published package contains JavaScript, type declarations, and two source stylesheets written in Tailwind v4 syntax. Your app’s Tailwind build is what turns the components’ class names into CSS, so it must be configured to see them.

What the package ships

Both stylesheets use Tailwind v4 at-rules (@theme, @utility, @variant, @custom-variant). They are inputs to a Tailwind build, not ready-to-serve CSS, so linking them straight into a page from a CDN does nothing.

The CSS entry point

Three lines in your app’s CSS entry point, in this order. Overlay animations add a fourth, which is why Installation shows four:
app.css
1

@import "tailwindcss"

Loads Tailwind v4 itself. It must come first: theme.css extends Tailwind’s theme and defines utilities, so Tailwind has to be loaded before it is read.
2

@source with the path to the package

Registers @fanvue/ui as a source Tailwind should scan for class names. Tailwind v4 auto-detects sources in your project but excludes node_modules, so without this line it never sees the classes the components render, and they generate no CSS.The path is resolved relative to the CSS file it appears in. From src/app.css in a typical project that is ../node_modules/@fanvue/ui. From src/styles/app.css it is ../../node_modules/@fanvue/ui. In a pnpm workspace or a monorepo the real package directory may sit at the workspace root, so point the path at wherever the installed package actually resolves.
3

@import "@fanvue/ui/styles/theme.css"

Loads the tokens, the typography utilities, and the light and dark palettes. The styles/* subpath maps to dist/styles/*, so any bundler that resolves package exports finds it. This is the only stylesheet you import; it pulls in base.css itself.
Components render unstyled when @source is missing or wrong
A missing or mis-resolved @source path fails silently: Tailwind emits no error, and your components render with correct markup and no styling. Check that line first whenever a component looks unstyled. Confirm the path by checking that node_modules/@fanvue/ui/dist exists at the location it points to.

What importing the theme changes in your app

theme.css is not namespaced. Importing it into your Tailwind build changes some of the utilities your own code generates. Three changes are worth knowing before you import it.

Breakpoints are replaced, not extended

The stylesheet resets Tailwind’s breakpoint scale with --breakpoint-*: initial and defines Fanvue’s: Tailwind’s defaults (sm: at 640px, md: at 768px, lg: at 1024px) no longer apply, and xl: and 2xl: no longer exist. Audit existing responsive classes when you add the library to an app that already uses Tailwind. Define your own extra breakpoints after the import if you need them:
app.css

The dark: variant becomes class-based

The stylesheet redefines the variant as @variant dark (&:where(.dark, .dark *)). Tailwind v4’s default dark: follows the operating system through prefers-color-scheme; after this import, dark: in your own components matches only inside an element carrying the dark class. That is what keeps your app and the library in one theme. See Theming for how to drive the class.

Radius and shadow scales are redefined

--radius-* and --shadow-* are set to Fanvue’s values, so rounded-md is 16px and shadow-sm, shadow-md, and shadow-lg render Fanvue’s elevation. Colour utilities are additive: the token colours are added under names like bg-background-primary, and Tailwind’s own palette (bg-red-500) still works. Spacing is deliberately untouched. The spacing tokens are defined in :root rather than @theme specifically so that p-*, m-*, and gap-* keep Tailwind’s default scale.

Enter and exit animations for overlays

Dialog, Drawer, Select, DropdownMenu, Autocomplete, and Toast animate open and closed with animate-in, animate-out, fade-in-0, slide-in-from-*, and zoom-in-95 classes applied through data-[state=open] and data-[state=closed] variants. Those utilities are not part of Tailwind v4 core. Without a package that provides them the classes are inert, and because Radix waits for a CSS animation before unmounting, closing an overlay removes its content instantly with no exit motion. Add tw-animate-css to supply them:
app.css

Cascade layer order

You do not have to declare it. Tailwind v4’s own entry point opens with the declaration, so importing it registers the order before anything else in your file is read:
Repeating @layer theme, base, components, utilities; in your own stylesheet is therefore a no-op as long as @import "tailwindcss" comes first. Declare it yourself only if you import Tailwind’s parts individually (tailwindcss/theme.css, tailwindcss/preflight.css, tailwindcss/utilities.css) instead of the single entry point. One consequence is worth knowing. @fanvue/ui’s base.css puts its reset rules in the base layer, so an unlayered rule of your own outranks them, with one reversal: for !important declarations the layer order runs backwards, so the !important rules in base.css (it uses them to neutralise the browser’s autofill highlight) beat an unlayered !important of yours.

Typography utilities

The stylesheet defines the type scale as utilities you can use in your own markup, not only inside components. Each one sets font-size, font-weight, line-height, letter-spacing, and font-family together:
theme.css generates 16 of them from the design tokens, across five families: Every one of them declares font-family: Inter, which is why Installation has a step for loading the typeface. base.css adds one more that is maintained by hand rather than generated from a token, typography-medium-caption-xs (10px / 12px, weight 500). Storybook’s Foundations section renders the scale if you want to see the sizes side by side.

Frameworks

Any bundler with Tailwind v4 support works. The library makes no build-tool assumptions beyond a Tailwind v4 pipeline that resolves package exports for the @import of theme.css.
Use @tailwindcss/postcss in your PostCSS config. The @import "@fanvue/ui/styles/theme.css" line is resolved by PostCSS against the installed package, so no path alias is needed for it. The @source line still needs a real filesystem path.
A bundler that restricts filesystem access to the project root can reject an @source path that points outside it, which happens in monorepos where node_modules is hoisted above the app directory. Generate the @source rules from your PostCSS config, or configure the bundler’s root to include the directory the package resolves from.

Next steps

Theming

Drive the dark class, read the tokens, and override them.

Subpath exports

Charts, date picker, flags, and animated icons live on their own entry points.