Styles
The admin of Pluto has its own CSS. Core compiles it when your app builds. Your site does not need Tailwind, and your site's theme does not change the admin.
Two builds
An app that uses Pluto has at most two Tailwind builds:
- The admin build. Core makes it. It styles the admin pages, the admin bar, and their menus and modals. Its rules apply only inside the admin, so they do not change your site. It loads only when the admin or the admin bar shows: a visitor does not download it.
- The site build. Your CSS entry, if your site uses Tailwind. Core does not add one for you.
No Pluto layer registers a Tailwind entry of its own.
A site with Tailwind
If your pages use Tailwind or Nuxt UI, start your CSS entry with these imports. Add your own theme after them.
@import 'tailwindcss';
@import '@nuxt/ui';
@import '@plutocms/css';
@import '@plutocms/css/base';
@theme {
/* your site's tokens */
}
Register the file in nuxt.config.ts:
export default defineNuxtConfig({
css: ['~/assets/css/main.css']
})
@nuxt/uiis for the Nuxt UI components on your pages.@plutocms/cssgives your site the Pluto UI tokens and the tokens of your Pluto layers. It is optional.@plutocms/css/basegives the look of the Pluto components for your public site. It is optional.
@plutocms/css is not an npm package, and you do not install it. Core makes it: it is a Nuxt alias of a file that core writes for your app. So it works with every package manager.
A site with no Tailwind
Write your CSS as you like. Pluto adds no Tailwind, no reset, and no utilities to your pages. The admin and the admin bar keep their look.
The Pluto components for public pages have no Tailwind classes, so they work on your site. For their look, import the base CSS in a CSS entry. It is plain CSS:
@import '@plutocms/css/base';
The pluto-css module
The module pluto-css is part of core. It does these things:
- It finds the
pluto-layer.cssfile of every layer. - It writes
#build/pluto.css, which imports each layer file. The base layer comes first, so a higher layer wins.@plutocms/cssis an alias of this file, and@plutocms/css/siteis an alias of the site theme. - It writes the base CSS of the public components: one import of the
pluto-base.cssfile of each layer.@plutocms/css/baseis an alias of this file. - It makes the admin build: Tailwind, Nuxt UI,
@plutocms/css, and@plutocms/css/base, with every rule limited to the admin. - It reads your CSS entries and warns about problems.
The module has one option, plutoCss.check. The default is true. Set it to false to turn the warnings off. The module prints nothing during nuxt prepare.
The build prints a pluto-css warning, once for each problem, when:
- A layer registers its own Tailwind build.
- Your app has more than one Tailwind build.
Rules for a layer
A layer can ship app/assets/css/pluto-layer.css. The admin build and the site build of a Tailwind site both import it, through @plutocms/css.
- Never import
tailwindcssor@nuxt/uiin it. - Use only
@theme,@custom-variant,@utility, unlayered rules, and imports of plain CSS files next to it. - Add no
@sourcefor theapp/directory of the layer. - Register no
cssentry in thenuxt.configof the layer.
A layer with components for public pages can also ship app/assets/css/pluto-base.css, for their look. Use plain CSS only, with no Tailwind directive. Put each selector in :where() and each rule in @layer components, so the CSS of the site wins.
Check the build
- Open a public page as a visitor. In the network panel of the browser, no file with a name that starts with
PlutoAdminThemeloads. - Open the admin. It keeps its look, also when your
@themechanges the spacing, the fonts, or the radius. - The build log has no
pluto-csswarning.
Editor setup
The Tailwind CSS IntelliSense extension for VS Code makes a project of each CSS file that it finds, and the generated files in .nuxt/ are CSS files too. If a generated file wins over your CSS entry, the editor does not know your @theme: your own colors show no color swatch, and your own classes show no hover.
Tell the extension to ignore the generated files. Add this to .vscode/settings.json:
{
"files.associations": {
"*.css": "tailwindcss"
},
"tailwindCSS.files.exclude": [
"**/.git/**",
"**/node_modules/**",
"**/.hg/**",
"**/.svn/**",
"**/.nuxt/**",
"**/.output/**"
]
}
The first four patterns are the defaults of the extension. The setting replaces them, so keep them in the list. Then reload the editor window.
text-muted or bg-default, show no swatch. Their values are CSS variables that change with the color mode and with app.config, so the extension cannot show one color. Hover shows their CSS.The Pluto UI tokens
Core has the official palette and fonts of Pluto. A Tailwind site gets them as Tailwind tokens through @plutocms/css, so you can use them in your site:
| Token | Use |
|---|---|
tholin-50 to tholin-950 | The red-orange of Pluto's surface. The action color. |
haze-50 to haze-950 | The blue of Pluto's atmosphere. |
heart-50 to heart-950 | The tan and cream of the planet's heart. |
kuiper-50 to kuiper-950 | A cool, deep neutral for text, borders, and dark surfaces. |
font-pluto | Public Sans. |
font-pluto-display | Fredoka, the rounded face of the wordmark. |
<span class="bg-tholin-600 font-pluto-display text-white">Launch</span>
The tokens add new names only. They do not change the colors or the fonts of your site. To use the Pluto colors for Nuxt UI, set them in app.config: ui: { colors: { primary: 'tholin', neutral: 'kuiper' } }.
The Pluto site theme
To give your site the look of these docs, import the site theme after the core CSS:
@import 'tailwindcss';
@import '@nuxt/ui';
@import '@plutocms/css';
@import '@plutocms/css/site';
And set the Pluto colors in app.config:
export default defineAppConfig({
ui: {
colors: { primary: 'tholin', secondary: 'haze', neutral: 'kuiper' },
},
})
The site theme gives:
- Public Sans for text, and Fredoka for the page titles (
h1) and thefont-displayutility. - The shades of your colors that read well: primary 600 in light mode, primary 400 in dark mode.
- A dark mode of deep space (neutral 950).
- The
heartcolor for selected text. pluto-sky: a soft sky for the top of a page.pluto-site-header: put it on a sticky header, and the header moves below the admin bar while a signed-in editor sees the bar.
The theme does not choose your colors, so it works with your own palette too. It does not change the admin. The shop template uses it.
The admin theme
The admin has its own look, made from the Pluto UI tokens. Your app.config colors and @theme tokens do not change it. To give the admin your brand, see White label.
| Role | Color |
|---|---|
| primary | tholin |
| secondary | haze |
| success | green |
| info | haze |
| warning | amber |
| error | rose |
| neutral | kuiper |
Errors use rose, not red, so an error does not look like the red-orange primary. The admin uses one font, Public Sans. Page titles are semibold. Fredoka is for the site only. The admin radius is 0.25rem.
The theme applies under two selectors:
:root[data-pluto-admin]. The composableusePlutoAdminTheme()setsdata-pluto-adminon<html>while an admin layout is mounted. Overlays such as modals and menus also get the theme.[data-pluto-admin-scope]. It is for admin chrome that shows on the public site, such as the navbar of a signed-in admin.
Every value is a literal OKLCH color, so an app cannot redefine it.
Surfaces
In dark mode, the surfaces go from the darkest at the top to the lightest in the content: navbar, sidebar, canvas, cards. The navbar is near black in both modes. The navbar and the sidebar have no border between them and the page. They read as one shape, and the page has a rounded corner where they meet.
The admin bar height
The token --pluto-admin-bar-height is 2.5rem on :root, also on a site with no Tailwind. While the bar shows on a public page, PlutoRoot moves the page down by this height. A public site can use it to offset its own sticky or fixed header under the admin bar. PlutoRoot sets data-pluto-admin-bar on <html> while the bar shows. See Admin shell.
Rules for admin code
- Use Nuxt UI semantic classes such as
bg-default,text-muted, andborder-default. Do not use raw Tailwind colors such asbg-zinc-100orbg-tholin-600. Raw colors do not follow the admin theme. - Call
usePlutoAdminTheme()in every new admin layout. - Put
data-pluto-admin-scopeon admin chrome that renders outside an admin layout. - Never put the admin radius in
@theme. It would reach the public site.
app.config, such as ui.button.slots.base, still merge across layers and reach the admin. Only colors, tokens, surfaces, and the font are isolated.