@bsuite/theme
v0.3.3
Published
BSuite Universal theme — D2C Neon Electric + Braden Corporate baselines. Tailwind v4 preset, CSS vars (5-layer), role aliases, colourblind-safe tokens, eye-strain-safe text scale, BrandingProvider (runtime white-label). Used by BSU, CRM7, conduit, R80.3,
Readme
@bsuite/theme
Universal D2C Neon Electric theme for the BSuite monorepo. Ships the canonical palette, Tailwind tokens, CSS variables, React ThemeProvider, and a framework-agnostic FOUC-prevention script.
What's inside
- CSS variables — 11 neon electric colours + light/dark surface tokens + WCAG AA-compliant text tokens
- Tailwind v3 preset — drop-in
presets: [require('@bsuite/theme/tailwind-preset')] - Tailwind v4
@themeblock —@import '@bsuite/theme/preset-v4.css' <ThemeProvider>+useTheme()with localStorage persistence + system preference<BrandingProvider>+useBranding()for runtime tenant brandingusePlatformLogo()andresolvePlatformLogo()for shared light/dark/mark/favicon logo fallback selectiongetThemeInitScript()— stringified JS for inline<script>tags to prevent FOUC
Install
pnpm add @bsuite/themeConsumer setup
Vite (v4 Tailwind) — BSU / CRM7 / R80.3
1. src/index.css or equivalent global stylesheet:
@import 'tailwindcss';
@import '@bsuite/theme/preset-v4.css';
@import '@bsuite/theme/css';
/* your app-specific @theme {} overrides below */2. src/main.tsx:
import { ThemeProvider } from '@bsuite/theme/react'
ReactDOM.createRoot(document.getElementById('root')!).render(
<ThemeProvider>
<App />
</ThemeProvider>
)3. index.html — FOUC prevention:
Paste the result of getThemeInitScript() into <head> before stylesheets.
Next.js 16 (v4 Tailwind) — conduit
1. src/app/globals.css:
@import 'tailwindcss';
@import '@bsuite/theme/preset-v4.css';
@import '@bsuite/theme/css';2. src/app/layout.tsx — inline theme-init script in <head>:
import Script from 'next/script'
import { getThemeInitScript } from '@bsuite/theme/ssr'
import { ThemeProvider } from '@bsuite/theme/react'
export default function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<head>
<Script id="bsuite-theme-init" strategy="beforeInteractive">
{getThemeInitScript()}
</Script>
</head>
<body>
<ThemeProvider>{children}</ThemeProvider>
</body>
</html>
)
}Vite (v3 Tailwind) — throughput
1. tailwind.config.js:
module.exports = {
presets: [require('@bsuite/theme/tailwind-preset')],
content: ['./src/**/*.{js,ts,jsx,tsx}'],
}2. Global stylesheet:
@tailwind base;
@tailwind components;
@tailwind utilities;
@import '@bsuite/theme/css';3. src/main.tsx + index.html — same as the v4 Vite setup above.
Using the hook
import { useTheme } from '@bsuite/theme/react'
export function ThemeToggleButton() {
const { theme, resolvedTheme, isDark, setTheme } = useTheme()
return (
<button onClick={() => setTheme(isDark ? 'light' : 'dark')}>
{isDark ? '☀️' : '🌙'}
</button>
)
}The resolvedTheme always returns 'light' or 'dark' — use this when you need the effective theme (it resolves 'system' for you).
Runtime branding and platform logos
Wrap BSuite apps in BrandingProvider when tenant/platform branding should be resolved from Supabase. Braden Corporate can pass brand="braden" to keep using static corporate tokens.
import { BrandingProvider, usePlatformLogo } from '@bsuite/theme/react'
function HeaderLogo() {
const { src, alt, isLoading } = usePlatformLogo({
slot: 'header',
scheme: 'light',
fallback: '/logos/bsuite.svg',
})
if (isLoading || !src) return null
return <img src={src} alt={alt} />
}Use resolvePlatformLogo() in non-React code or tests when you already have a branding payload and need the same fallback order without mounting a provider.
Palette
All 11 canonical electric colours are available via Tailwind classes:
| Token | Hex | Use |
|---|---|---|
| neon-electric-blue | #2563eb | Primary, highlights |
| neon-electric-cyan | #00cec9 | Accents, borders |
| neon-electric-indigo | #4f46e5 | Secondary actions |
| neon-electric-purple | #6c5ce7 | Gradients, effects |
| neon-electric-magenta | #fd79a8 | Interactive |
| neon-electric-pink | #ec4899 | Hover states |
| neon-electric-coral | #ff4757 | Alerts, destructive |
| neon-electric-orange | #ff7675 | Warnings |
| neon-electric-yellow | #fdcb6e | Info |
| neon-electric-green | #22c55e | Success |
| neon-electric-lavender | #a29bfe | Subtle accents |
WCAG AA compliance: use text-color-accent-text and text-color-primary-text for text on light backgrounds. These are the accessible equivalents of cyan and blue — same visual identity, 5:1+ contrast on #f2f2f2.
License
UNLICENSED — internal BSuite use only.
