Theming skill
The bestax-theming
skill teaches an agent to customize colors, branding, and dark mode of an app built with
@allxsmith/bestax-bulma. Bulma 1.x is themed through --bulma-* CSS variables; recolor a brand
color by overriding its hue/saturation/lightness trio with the exported Theme component.
Install
npx skills add https://github.com/allxsmith/bestax --skill bestax-theming
Custom brand theme
Prompt
Set up a custom brand theme for an app built with @allxsmith/bestax-bulma —
override the brand colors and the corner radius — following the bestax theming
skill.
Live result
The wrapped section below recolors via a scoped <Theme> (no isRoot), so the override
applies only to its children.
function example() { return ( <Theme infoH="291" infoS="70%" infoL="50%" linkH="291" linkS="70%" linkL="50%" bulmaVars={{ '--bulma-radius': '9999px' }} > <div style={{ display: 'flex', gap: '0.75rem', flexWrap: 'wrap', alignItems: 'center', }} > <Button color="info">Info button</Button> <Button color="link">Link button</Button> <Tag color="info">Themed tag</Tag> </div> </Theme> ); }
This live preview pins --bulma-primary-*, so the demo recolors info/link to show the effect.
In a real app, override primaryH/primaryS/primaryL the same way to recolor the brand primary.
Generated code
- App root (global)
- Scoped override
import { Theme } from '@allxsmith/bestax-bulma';
// Wrap the app once. `isRoot` writes the variables to :root globally.
export function ThemedApp({ children }: { children: React.ReactNode }) {
return (
<Theme
isRoot
primaryH="265"
primaryS="65%"
primaryL="55%"
linkH="200"
linkS="80%"
linkL="45%"
bulmaVars={{
'--bulma-radius': '0.75rem',
'--bulma-family-primary': "'Inter', system-ui, sans-serif",
}}
>
{children}
</Theme>
);
}
import { Theme, Box, Button } from '@allxsmith/bestax-bulma';
// Theme one section; the rest of the app is untouched (no `isRoot`).
export function PromoPanel() {
return (
<Theme primaryH="16" primaryS="85%" primaryL="55%">
<Box>
<Button color="primary">Warm primary, only here</Button>
</Box>
</Theme>
);
}
Bulma derives every shade and the light/dark/invert variants from the --bulma-<color>-h/-s/-l
trio, so overriding the trio recolors the whole palette. Non-color tokens (radius, fonts, sizes)
go through bulmaVars, keyed by their real --bulma-* names.
Dark mode
Prompt
Add a light/dark mode toggle to an app built with @allxsmith/bestax-bulma —
there is no shipped dark-mode component — following the bestax theming skill.
Generated code
The Theme component drives dark mode via its colorMode prop — no manual DOM work.
import { useState } from 'react';
import {
Theme,
Box,
Button,
Title,
Notification,
} from '@allxsmith/bestax-bulma';
type Mode = 'light' | 'dark' | 'system';
export function DarkModeToggle() {
const [mode, setMode] = useState<Mode>('system');
return (
<Theme isRoot colorMode={mode}>
<Box>
<Title size="5">Color mode: {mode}</Title>
<Notification color="info">
Components follow the current Bulma color scheme.
</Notification>
<Button color="primary" onClick={() => setMode('light')}>
Light
</Button>
<Button color="primary" onClick={() => setMode('dark')}>
Dark
</Button>
<Button onClick={() => setMode('system')}>System</Button>
</Box>
</Theme>
);
}
How it works
Theme's colorMode prop ('light' | 'dark' | 'system') writes Bulma's data-theme attribute on
<html>, so the whole document follows the chosen scheme — global, even on a scoped Theme.
'system' removes the attribute so Bulma follows the OS prefers-color-scheme. Brand overrides
from <Theme isRoot> still apply on top of either scheme.
colorMode flips the page-level data-theme on <html> — the same attribute this documentation
site uses for its own light/dark mode, and the embedded previews are sandboxed to the site theme.
A live toggle would flip the entire site, not a contained example. To see it: toggle this site's
dark mode (top-right of the navbar) to view components in dark, or run the Helpers / Theme →
DarkMode story in Storybook.