Theming

Ten tokens restyle both widgets at once. They resolve to CSS variables at runtime, so a theme change is a re-render, not a rebuild.

Setting a theme

Pass theme to RoastnestProvider and every widget beneath it picks it up. Any token you leave out keeps its default.

app.tsx
<RoastnestProvider
  mode="cloud"
  projectId="YOUR_PROJECT_ID"
  theme={{
    primaryColor: "#18181b",
    accentColor: "#2563eb",
    successColor: "#16a34a",
    backgroundColor: "#ffffff",
    textColor: "#111111",
    mutedTextColor: "#6b7280",
    borderColor: "#e5e7eb",
    codeBoxColor: "#fefce8",
    borderRadius: "12px",
    fontFamily: "inherit",
  }}
>
  <YourMainApp />
</RoastnestProvider>

Tokens

PropTypeDefaultDescription
primaryColorstring"#5e2f1d"Trigger buttons and primary actions — the submit button, the referral button, the copy action.
accentColorstring"#2563eb"Secondary emphasis and highlighted details.
successColorstring"#16a34a"Confirmation states, including the copied-to-clipboard flash.
backgroundColorstring"#ffffff"Surface behind the form and the invite card.
textColorstring"#111111"Primary text.
mutedTextColorstring"#6b7280"Secondary text, labels and placeholders.
borderColorstring"#e5e7eb"Borders and dividers.
codeBoxColorstring"#fefce8"Background of the referral code and link boxes.
borderRadiusstring"12px"Corner radius across both widgets. Any CSS length works.
fontFamilystring"inherit"Typeface for widget text. The default inherits from your page.

Start with three tokens

primaryColor, borderRadius and fontFamily do most of the work of making the widgets look like they belong to your product. Adjust the rest only if something still reads as foreign.

Per-widget overrides

ReferralWidget accepts its own theme, which merges over the provider's. This is useful when the referral card sits on a differently-styled marketing page.

Widget-level theme
<ReferralWidget
  mode="self-hosted"
  referralLink="https://myapp.com/invite"
  onEvent={handleEvent}
  theme={{ primaryColor: "#7c3aed", borderRadius: "4px" }}
/>

Cloud mode themes come from the dashboard

A widget explicitly typed with mode="cloud" rejects a local theme prop, because the server-side configuration is authoritative. Set the theme in your project settings instead — it applies without a redeploy. See Modes.

How tokens are applied

Each token becomes a CSS custom property on the widget's root element — --rrn-ref-primary, --rrn-ref-bg, --rrn-ref-radius and so on. Nothing is written to :root, so the widgets cannot collide with your own variables, and a token change repaints immediately without remounting.

Dark mode

The widgets have no built-in dark theme; they follow the tokens you give them. Wire the theme to whatever drives dark mode in your app and both widgets switch with the rest of the page.

Providers.tsx
function Providers({ children }) {
  const { resolvedTheme } = useTheme();

  return (
    <RoastnestProvider
      mode="cloud"
      projectId="YOUR_PROJECT_ID"
      theme={
        resolvedTheme === "dark"
          ? {
              backgroundColor: "#09090b",
              textColor: "#fafafa",
              mutedTextColor: "#a1a1aa",
              borderColor: "#27272a",
              codeBoxColor: "#18181b",
            }
          : undefined
      }
    >
      {children}
    </RoastnestProvider>
  );
}

Beyond tokens

For adjustments the tokens do not reach, ReferralWidget accepts a customCSS string injected scoped to the widget, and buttonStyle for inline trigger styles. The feedback widget's customize object takes a className on the form, the submit and cancel buttons, the textarea and the trigger.

Scoped custom CSS
<ReferralWidget
  customCSS={`
    .rrn-ref-card { box-shadow: 0 20px 40px rgba(0,0,0,.18); }
  `}
/>

Fonts

fontFamily only names a family — it does not load one. Keep the default so the widget inherits a typeface your page has already loaded, or make sure the family you name is available on the page.

Recommended default
theme={{ fontFamily: "inherit" }}