Styles, font and dark mode
Three things make the components look right: the stylesheet, the font and, if you want it, the dark theme.
Import the stylesheet once
Section titled “Import the stylesheet once”Import @beyul/sulmu-ui/styles.css once, at the root of the app, before the app’s own CSS:
import '@beyul/sulmu-ui/styles.css'The stylesheet is precompiled. It contains the design tokens as CSS variables
(--su-colors-brand-600) and the classes of every variant of every component (.su-button).
Nothing is generated at runtime.
In a Module Federation app, import it in the host only.
What the stylesheet does not do
Section titled “What the stylesheet does not do”- It has no CSS reset. It does not touch
body, headings, links or any element that is not a library component. Components set their own margins and font. - It only sets
box-sizing: border-boxon its own elements (those with ansu-class), so components size themselves the same way with or without a reset in the app. - Everything is inside CSS cascade layers (
reset, base, tokens, recipes, utilities). Styles that are not in a layer always win over layered styles, so the app’s own CSS overrides the library without any specificity tricks. See Styling and extending.
Load the font
Section titled “Load the font”The components use Plus Jakarta Sans. The library does not load it; the app does. The font
token is "Plus Jakarta Sans Variable", "Plus Jakarta Sans", ui-sans-serif, system-ui, ...,
so either name works.
With Fontsource (what the Tourism Suite shell uses):
npm install @fontsource-variable/plus-jakarta-sansimport '@fontsource-variable/plus-jakarta-sans'Or with Google Fonts, in the HTML head:
<link rel="preconnect" href="https://fonts.googleapis.com" /><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /><link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>Library components set their own font family. To use the same font for the rest of the app:
body { font-family: var(--su-fonts-sans); color: var(--su-colors-fg-default); background: var(--su-colors-bg-canvas);}Dark mode
Section titled “Dark mode”The dark theme is switched on by data-theme="dark" on an ancestor of the components:
<html data-theme="dark">document.documentElement.dataset.theme = isDark ? 'dark' : 'light'- Put the attribute on
<html>. Dialogs, menus, selects, popovers, tooltips and toasts are rendered in a portal at the end of<body>, so an attribute on a wrapper inside the app would not reach them. - Only the semantic colours change. The colour ramps reverse (
brand.100becomes the darkest shade), and every purpose colour such asbg.surfacefollows. - The library does not read
prefers-color-scheme. Decide in the app and set the attribute.
This site uses the same switch: the theme picker in the header sets data-theme on <html>,
and every example follows it.
Using the tokens with Panda CSS (optional)
Section titled “Using the tokens with Panda CSS (optional)”An app that uses Panda CSS for its own layout can share the tokens by adding the preset:
import { defineConfig } from '@pandacss/dev'import { sulmuPreset } from '@beyul/sulmu-ui/preset'
export default defineConfig({ presets: ['@pandacss/preset-base', sulmuPreset], prefix: 'su',})This is optional. Without Panda, use the CSS variables directly.
Next: build a first screen.