:root. A page-level value reaches every FrogBot component on the page, including menus and dialogs, which render outside your layout.
@theme static:
@theme values that no utility uses, so these tokens need static.
Color tokens
The tokens come in two levels:- Ramps are the raw palette, such as
--ramp-grey-100to--ramp-grey-900,--ramp-blue-500or--ramp-green-600. Override a ramp to retint everything built on it. - Semantic tokens say what a color is for. Components only read these:
@frogbotai/ui/styles.css defines every token with the admin panel’s default values, so pages outside the admin look like the admin. In the admin, the admin’s own values apply.
The brand tokens default to FrogBot green, in the admin and on your own pages:
Text and icons on a brand fill (
--color-text-onbrand, --color-icon-onbrand) stay white. Focus rings and selected rows use the separate --color-*-selected tokens, which stay blue.
For example, to give every grey surface a navy tint, and make brand accents blue:
:root and dark on [data-theme='dark'], or they keep FrogBot’s green.
Token names your app may already use
The tokens use common names such as--color-bg, --color-text and --color-border. If your app defines a token with the same name for its own use, it restyles FrogBot too. Rename your token or scope it to your own elements. On admin pages, overriding one restyles the admin as well as FrogBot.
Fonts
FrogBot’s text uses one token,--font-body. Set it on :root to change the font of every FrogBot component, in the admin panel and on your own pages:
Inter, sans-serif. Inter only loads if you import @frogbotai/ui/fonts.css; without it, the browser’s sans-serif font shows. In the admin panel, Inter is already loaded and --font-body already set.
FrogBot sets the regular text size to 14px, in the admin panel (where it raises the admin’s 12px default) and on your own pages. To change it, set the text tokens on :root:
fonts.css. On pages outside the admin, set --font-family-mono on :root to use another code font.
Glow
The composer’s animated rainbow ring is a reusable block. Putfb-glow on a wrapper and fb-glow__ring on the element inside it; the ring shows in a 5px band around that element’s child, with 20px corners. Add fb-glow--active for the brighter glow the composer shows while you type.
@frogbotai/ui/styles.css includes it. @frogbotai/ui/glow.css is the block on its own, with its colors set on .fb-glow, so it also works where FrogBot’s tokens don’t reach, such as a page’s shadow root. With reduced motion the ring stops turning.
Light and dark modes
Light values are set on:root and dark values on [data-theme='dark']. A value you set on :root applies in light mode, and in dark mode too unless dark mode sets that token. To set a dark value, set it on [data-theme='dark']:
:root applies in both modes, because the dark tokens read the same ramps.
On your own pages, <html data-theme="dark"> turns on dark mode for the whole page. ThemeProvider sets it for you.
ThemeProvider
ThemeProvider sets the light, dark, or system mode. Without mode, it themes the whole page by setting data-theme on <html>. With mode, it themes only its children and the menus and dialogs opened inside it. It doesn’t set colors.
useTheme() returns mode, resolvedMode (light or dark), and setMode.
Place ThemeScript before themed content during server rendering. It reads the stored preference, or the operating system’s mode for system, and sets data-theme on <html> before hydration to avoid a mode flash. Pass the same storageKey to ThemeScript and ThemeProvider when using a custom key.
Sections
A section of a page can use its own mode: wrap it inThemeProvider with mode, and its menus and dialogs follow. Colors set on a section, such as .billing { --color-bg-secondary: … }, apply to the section’s own content but not to its menus and dialogs, which render at the end of the page. Set colors page-wide instead. A section sets its mode’s tokens again, so a semantic token you change on :root alone doesn’t reach a light section; set it on :root, [data-theme='light'] (and dark values on [data-theme='dark']). Ramps and the brand fills (--color-bg-brand, -hover, -pressed, -secondary) set on :root reach every section.
Override FrogBot styles
All FrogBot styles are in a CSS cascade layer namedfrogbot. You can override them three ways:
- Write CSS that isn’t in a layer. It beats FrogBot whatever its selector.
- Add a Tailwind CSS utility to the component, with one of the Tailwind setups.
- Put your rules in a layer declared after
frogbot.
button { background: none } removes FrogBot’s button backgrounds, and a { text-decoration: underline } underlines link buttons. Scope these rules to your own content if you don’t want that.
Admin panel styles
In the FrogBot admin panel, FrogBot UI components and theme tokens work in every custom component, including views, fields, document controls, drawers, menus, and dialogs, with no wrapper. They follow the admin’s light and dark setting and update as soon as a user switches theme. UseThemeProvider on your application’s own pages outside the admin panel. Inside the admin, add one only when a section needs its own mode; it overrides the admin theme for its children.
The admin orders its styles like this, from weakest to strongest:
payload-default: the admin’s base styles.frogbot: FrogBot components and screens.payload: an empty layer for your admin overrides.- Layers your CSS declares, such as Tailwind’s.
- CSS that isn’t in a layer.
payload-default and frogbot.
To use Tailwind CSS in the admin, import only its theme and utilities, after @frogbotai/next/css. Don’t import Preflight (@import "tailwindcss" includes it): it resets the admin’s own controls and FrogBot’s.
Upgrade from the theme and brand props
ThemeProvider no longer accepts theme or brand, and @frogbotai/ui/theme no longer exports ThemeTokens or BrandTheme. BrandConfig no longer has tokens. Passing either prop is a TypeScript error. Move the values into CSS:
document.documentElement yourself.