Superbridge
Start typing to search...
You need a Rollie to use the Superbridge Widget.

Guides

Theming

Customise the widget appearance with CSS variables, fonts, and images

The widget is themed entirely through CSS variables. Pass an object of overrides to the cssVariables prop — they're written onto the widget's host element, so everything inside reacts.

import { Widget } from "@superbridge/widget";

<Widget
  cssVariables={{
    "--color-foreground": "hsl(240 10% 4%)",
    "--color-card": "hsl(0 0% 100%)",
    "--color-card-foreground": "hsl(240 10% 4%)",
    "--color-primary": "hsl(240 6% 10%)",
    "--color-primary-foreground": "hsl(0 0% 98%)",
    "--radius": "0.75rem",
    "--sb-card-corner": "squircle",
    "--sb-card-shadow": "0 1px 2px rgba(0,0,0,0.06)",
  }}
/>

The cssVariables object is fully typed via WidgetCssVariables — your editor autocompletes every available token, so the reference list below is intentionally high-level.

Variable groups

The variables fall into a few categories:

Colors

Semantic color roles, each with a background, a -foreground for text/icons on top, and an -outline for the border ring.

  • --color-foreground — default body text
  • --color-card / --color-popover — main surfaces and floating menus
  • --color-primary / --color-secondary / --color-muted / --color-accent / --color-destructive — action roles
  • --color-border, --color-input, --color-ring — separators, input borders, focus rings

Typography

  • --font-heading, --font-button, --font-body — font families per role
  • --tracking-heading, --tracking-button, --tracking-body — letter-spacing per role

See Styling fonts below.

Radius

  • --radius — base radius. The full --radius-2xs--radius-4xl scale is derived from this via calc(), so retuning the base retunes everything.

Styling fonts

Font variables accept any valid CSS font-family value. To use a custom font, load it yourself with @font-face (or a <link> to a hosted provider) and then point the variables at it:

/* your-app.css */
@font-face {
  font-family: "Acme Display";
  src: url("/fonts/acme-display.woff2") format("woff2");
  font-display: swap;
}

@font-face {
  font-family: "Acme Text";
  src: url("/fonts/acme-text.woff2") format("woff2");
  font-display: swap;
}
<Widget
  cssVariables={{
    "--font-heading": '"Acme Display", ui-sans-serif, system-ui, sans-serif',
    "--font-button":  '"Acme Display", ui-sans-serif, system-ui, sans-serif',
    "--font-body":    '"Acme Text", ui-sans-serif, system-ui, sans-serif',
    "--tracking-heading": "-0.01em",
    "--tracking-body":    "0em",
  }}
/>

Tips:

  • Always include a system fallback stack — the widget renders before your font finishes loading.
  • Prefer woff2 and font-display: swap to avoid invisible text during load.
  • Hosted fonts (Google Fonts, Fontsource, etc.) work the same way — load the stylesheet, then reference the family name.
  • If --font-button is unset it inherits whatever the surrounding role uses; set it explicitly when you want buttons to look distinct from headings.