Skip to Content
GuidesTheme the sign-in UI

Theme the sign-in UI

Synq’s default <SignIn> and <SignInSheet> are designed to look correct in 90% of apps with zero customization — but you almost certainly want them to look like your app, not Synq’s. This guide walks through the four levels of theming from least to most invasive. Stop at the first one that gets you what you want.

Works the same way across @synqid/react, @synqid/nextjs, and @synqid/react-native. The token names are identical; the values are CSS strings on web and native numbers/strings on RN.

Level 0 — pick a preset (10 seconds)

Five built-in presets cover the most common visual languages.

<SynqProvider {...config} theme="dark" /> // default <SynqProvider {...config} theme="light" /> <SynqProvider {...config} theme="glass" /> // dark + heavy blur <SynqProvider {...config} theme="monochrome" /> // grayscale <SynqProvider {...config} theme="brutalist" /> // hard edges, yellow

On @synqid/react-native, the prop is uiTheme with the same value shape.

Level 1 — pick a preset and tweak (30 seconds)

Layer overrides on top of a preset. Anything you do not set keeps the preset’s value.

<SynqProvider {...config} theme={{ preset: 'light', primary: '#FF7B56', primaryHover: '#E85A2D', radius: '14px', // sugar — sets all radius* scales fontFamilyDisplay: '"Cal Sans", system-ui', }} />

The full token set for fine-grained control:

GroupTokens
Colorsprimary, primaryForeground, primaryHover, surface, surfaceElevated, border, borderHover, textPrimary, textMuted, textOnPrimary, danger, success, warning, backdrop
TypographyfontFamily, fontFamilyDisplay, fontFamilyMono, fontWeightHeadline, fontWeightButton
SpacingspacingXs, spacingSm, spacingMd, spacingLg, spacingXl
RadiiradiusSm, radiusMd, radiusLg, radiusFull, radius (sugar)
Effects (web only)shadowSm, shadowMd, shadowLg, glow, backdropBlur
Motion (web only)durationFast, durationBase, easingStandard

The RN-native token set is identical minus the web-only Effects and Motion groups, and adds sheetHandle (the bottom-sheet drag bar color).

Level 2 — light + dark with system follow

When your app has its own dark/light toggle, hand Synq both branches and a colorScheme strategy. system follows the OS preference and re-renders on change.

<SynqProvider {...config} colorScheme="system" // 'light' | 'dark' | 'system' theme={{ light: { preset: 'light', primary: '#0A6E5E' }, dark: { preset: 'dark', primary: '#5FD8CA' }, }} />

colorScheme="system" watches prefers-color-scheme on web and useColorScheme() on RN — no extra wiring.

Level 3 — provider icons + slot-level classNames

Rebrand the provider buttons or hit specific slots without dropping into compound parts.

import { GoogleMark, AppleMark } from '@/components/brand-icons' <SynqProvider {...config} providerIcons={{ google: <GoogleMark className="size-5" />, // React component apple: 'https://cdn.acme.com/apple.svg', // URL → <img> matrica: '<svg viewBox="0 0 24 24">…</svg>', // inline SVG (web only) }} signInClassNames={{ content: 'rounded-3xl bg-zinc-950/95 backdrop-blur-xl', title: 'font-display text-2xl', provider: 'rounded-xl ring-1 ring-zinc-800 hover:ring-zinc-600', walletButton: 'rounded-xl bg-purple-600 hover:bg-purple-500', }} />

Web slot names: backdrop, content, header, logo, title, description, closeButton, providerList, provider, providerIcon, providerLabel, emailInput, otpInput, walletButton, divider, errorBanner, loadingOverlay, terms, footer. The connectClassNames prop targets the wallet-only <Connect> modal with its own slot set.

On RN, use signInSheetStyles / connectSheetStyles with object styles instead of classNames — slots are background, handle, container, title, providerButton, providerButtonText, walletButton, walletButtonText.

Level 4 — compound parts or render-prop (your markup)

When nothing above is enough, drop into the compound API or fully headless render-prop. You bring the JSX; Synq brings the auth behavior. See the @synqid/react or @synqid/react-native compound section.

Recipes

Match Tailwind’s design system

Wire --synq-* CSS variables to your tokens once and the modal inherits everything else from Tailwind utilities.

.synq-modal { --synq-primary: theme('colors.brand.500'); --synq-primary-foreground: theme('colors.white'); --synq-surface: theme('colors.zinc.950'); --synq-text-primary: theme('colors.zinc.100'); --synq-radius-lg: theme('borderRadius.2xl'); }

Custom font in 3 lines

<SynqProvider {...config} theme={{ fontFamilyDisplay: '"Cal Sans", system-ui', fontFamily: '"Inter", system-ui', }} />

The display font is used on the modal title; the body font on everything else.

Disable the glow + backdrop blur

Some apps look better without the brand glow behind the modal or the backdrop blur (cheap on desktop, expensive on older mobile GPUs).

<SynqProvider {...config} theme={{ preset: 'dark', glow: 'none', backdropBlur: '0' }} />

Per-route theme override

Nest a second <SynqProvider> underneath the root with a different theme to override per route. The auth state is shared — only the visual tokens differ.

<SynqProvider {...config} theme="dark"> <App /> <Route path="/checkout"> <SynqProvider {...config} theme={{ preset: 'light', primary: '#000' }}> <Checkout /> </SynqProvider> </Route> </SynqProvider>
Last updated on