Skip to main content
The widget ships unopinionated styles you control with CSS. There are three levels, from a few variables to a fully custom shell.

Import the styles

Without this import the widget renders unstyled. Import it once, near your app root.

1. Re-theme with CSS variables

Override the --ff-* custom properties on :root (or any ancestor of the widget):
Dark mode toggles with a data attribute:

2. Override class hooks

Every part of the widget has a stable class name. Target them in your own CSS for finer control: ff-widget, ff-widget__header, ff-block, ff-block__title, ff-block__body, ff-cta, ff-quick-reply, ff-option, ff-scale__dot, and more.

3. Build your own shell

For complete control over markup, skip FirstflowWidget and render BlockRenderer inside your own component, driven by useFirstflow:
The runtime state, triggers, navigation, and persistence keep working you only replace the shell. See Blocks & custom shells.