Styling
xoong ships design tokens as custom properties and the default look of its parts as plain CSS in cascade layers. There is nothing to build and nothing to eject: your own CSS wins without specificity fights.
Tokens
Everything in xoong.css is read from --xo-* properties. Change them on :root for the whole app, or on any element for a region. Move the controls to try it on the sample panel (they set the properties on that panel only).
| Name | Role |
|---|---|
| Ada Lovelace | admin |
| Grace Hopper | editor |
A hint in the muted colour, and a link in the accent colour.
:root {
--xo-color-accent: #0a7; /* links, focus ring, primary actions */
--xo-radius: 0; /* corners of buttons, fields, panels */
--xo-font: "Inter", system-ui, sans-serif;
}
.sidebar { /* or a region: its children follow */
--xo-color-surface: #fafafa;
--xo-space-3: 0.75rem;
}--xo-font, --xo-font-mono, --xo-text, --xo-text-small
--xo-space-1 … --xo-space-4, --xo-radius, --xo-form-max-width
--xo-color-bg, --xo-color-surface, --xo-color-text, --xo-color-muted
--xo-color-border, --xo-color-accent, --xo-color-accent-text, --xo-color-danger
--xo-focusLayers
The default styles live in three layers, xoong.tokens, xoong.base and xoong.components. Unlayered CSS beats any layered CSS, so a plain rule in your stylesheet overrides the default without !important and without matching its specificity. Light and dark come from light-dark() and color-scheme.
/* your stylesheet: no layer, so it wins */
.xo-table th { text-transform: uppercase; letter-spacing: 0.04em; }
xo-dialog > dialog { max-width: 40rem; }
/* or order the layers yourself */
@layer reset, xoong.tokens, xoong.base, xoong.components, app;The admin shell
Put class="xo-admin" on the body (or on <xo-router>) with a <header>, a <nav> and a <main>, and you have a header, a sidebar and a content area that folds into one column on a phone.
<body class="xo-admin">
<header>My admin</header>
<nav><a href="/people" aria-current="page">People</a></nav>
<main>...</main>
</body>