Admin theming — the --cb- token layer, light / dark / auto
- Version
- 4.0 preview
- Updated
Scope: how the CBX backend decides its colour scheme and where its colours come from — the
data-bs-themeanchor,getAdminColorScheme()per platform, the--cb-*token set, the vendor overrides, and the rules custom admin CSS has to follow · Last reviewed: 2026-08-25
The CBX backend follows a light / dark / auto colour scheme, and every colour in it comes from one
token layer: assets/css/admin-theme.css. This page is the reference for that layer. For the other
admin stylesheet mechanism — the per-host anti-bleed files that adapt CBX to each host's chrome — see
com_configbox_host_stylesheets.md; host stylesheets consume
these tokens and do not define them.
1. The anchor: data-bs-theme
CBX's namespaced Bootstrap 5.3 uses the standard data-bs-theme="light|dark" colour-mode
attribute and defines its --bs-* variables per scheme. The --cb-* tokens hang off the same
attribute, so CBX's colours and Bootstrap's flip together rather than drifting apart.
There is no JavaScript in the decision. Three cases cover everything:
| Situation | What sets the scheme |
|---|---|
An ancestor carries data-bs-theme="dark" | The explicit-dark block applies |
An ancestor carries data-bs-theme="light" | Nothing overrides the light defaults — and the OS fallback is suppressed |
| No attribute at all (auto) | @media (prefers-color-scheme: dark) applies the dark tokens |
The auto block is guarded as :root:not([data-bs-theme="light"]) …:not([data-bs-theme="light"]), so an
explicit light choice beats a dark OS. That mirrors Bootstrap's own media-query colour-mode strategy.
2. How each platform resolves it — getAdminColorScheme()
KenedoPlatform::getAdminColorScheme() is the platform contract, and the answers differ because the
hosts differ:
| Host | Returns | Why |
|---|---|---|
| Joomla | the resolved scheme | The Atum admin template already stamps data-bs-theme on <html> from its own light/dark/auto setting, and CBX renders inside it — so it inherits for free. The method still reports the resolved value (an explicit userColorScheme cookie first, then the user's colorScheme profile parameter) for callers that need it server-side. |
| WordPress | 'light' | The WP backend is light-only and gives no light/dark signal. Its admin colour schemes only restyle the menu, toolbar and accents; the content area CBX renders into stays light in all of them. |
| Magento 2 | 'light' | The Magento backend theme is light-only and has no dark mode. |
| standalone | 'auto' | No host chrome and no host signal, so CBX follows the OS. |
Why the two light-only hosts pin rather than report auto: reporting auto would let
prefers-color-scheme darken CBX alone, leaving a dark CBX panel sitting inside permanently light
host chrome. Pinning light keeps the two in step. On those hosts
KenedoView
stamps data-bs-theme="light" on the admin view wrapper, which also suppresses the OS fallback in
admin-theme.css.
If WordPress or Magento ever ships an admin dark mode, that platform's
getAdminColorScheme()is the one place to read its signal.
3. The tokens
Tokens are defined on four roots, not one: .cb-content (every CBX view wrapper, and where the
namespaced Bootstrap is scoped), body.admin.com_configbox and .configbox-admin-index (host page
wrappers that admin.css paints with --cb-body-bg, and which sit above .cb-content), and
.kenedo-popup.
.kenedo-popup is a token root of its own for a reason. KenedoPopup.open() clones the popup out
of the view wrapper and appends it to <body>, so it cannot inherit tokens from .cb-content — and on
a host where the body itself carries tokens, it would otherwise pick up the body's scheme instead of the
one its origin resolved to. kenedo.js stamps the origin's effective data-bs-theme onto the clone;
unstamped means auto, and the media block takes over.
The set, by group:
| Group | Tokens |
|---|---|
| Surfaces | --cb-body-bg (tracks Joomla Atum's grey via --template-bg-light), --cb-surface, --cb-surface-2, --cb-surface-3, --cb-overlay |
| Text | --cb-text, --cb-text-strong, --cb-text-muted, --cb-text-faint, --cb-text-inverse |
| Borders | --cb-border, --cb-border-strong, --cb-border-subtle |
| Brand & links | --cb-brand, --cb-brand-contrast, --cb-link, --cb-link-hover, --cb-accent |
| Semantic | --cb-success, --cb-warning, --cb-danger, --cb-info, --cb-required, each with a -bg twin |
| Form fields | --cb-input-bg, --cb-input-text, --cb-input-border, --cb-input-focus-border |
| Buttons | --cb-primary (+ -border, -hover, -hover-border), --cb-btn-bg, --cb-btn-text, --cb-btn-border, --cb-btn-hover-bg, --cb-btn-hover-border |
| Elevation | --cb-shadow-sm, --cb-shadow, --cb-inset-shadow |
| Editor palette | node/token fills for the calc, rule and matrix editors, tuned to stay legible on both schemes |
One token is not a colour and catches people out: --cb-select-caret is Tom Select's
single-select caret as a background-image SVG with the stroke colour baked into the data URI — it
cannot reference a variable, so it is swapped wholesale per scheme. Its stroke mirrors
--cb-text-muted; change one and change the other.
4. Vendor chrome
Two vendored widgets do not read CSS variables and need explicit per-scheme rules, which
admin-theme.css carries for both the explicit-dark and the auto-dark cases: Tom Select (the
enhanced dropdowns — control, dropdown, options, multi-select items, the remove button) and
jQuery UI (the availability datepicker and any sortable/dialog chrome).
Also here: the CBX heading logo is dark artwork, so it gets a legibility treatment on dark surfaces.
5. Rules for custom admin CSS
- Reference the tokens, never hardcode. A hex value in custom admin CSS is a light-mode bug
waiting for someone to switch to dark. Use
--cb-*(and--bs-*where Bootstrap owns the component). - Do not restyle in a
[data-bs-theme]or media block. Define your component once against the tokens; the tokens already flip. A colour whose only definition sits inside a dark block will not apply in the unstamped auto state. - Edit values here, not in the consuming file.
admin-theme.cssis the single source of colour;admin.css,general.css, the calc/rule/matrix editors and the per-property CSS all consume it. - Check both schemes before calling it done. Everything in the admin can be viewed light and dark; an interactive state that was only ever seen in one is only half-checked.
.min.csstwins are build artifacts — regenerated by the packager, not edited.
- Adding your own admin CSS and JS
- Overriding views and templates
- Adding a custom property type — including its per-property stylesheet
6. See also
com_configbox_host_stylesheets.md— the per-host anti-bleed stylesheets, which consume these tokenscom_configbox_kenedo_view.md— the view wrapper that stampsdata-bs-themewhere the host does notassets/css/admin-theme.css— the token layer itself, documented inline