Guide

Theming

Every visible color in the library is a CSS custom property. Override a single variable to re-skin the whole UI.

Palette tokens

The theme exposes a semantic palette: primary, secondary, background, surface, error, success, warning, info, each paired with a *contrast color for text. Two extras — border, shadow, highlight — control structural details.

Theme tokens
:root {
    --palette-primary: #c41236;
    --palette-primary-contrast: #ffffff;
    --palette-secondary: #2f1a1f;
    --palette-background: #fbf7f6;
    --palette-background-contrast: #1a0c0e;
    --palette-surface: #ffffff;
    --palette-surface-contrast: #1a0c0e;
    --palette-error: #b42318;
    --palette-success: #15803d;
    --palette-warning: #b45309;
    --palette-info:  #0369a1;
    --palette-border: #e8ddde;
    --palette-shadow: #1a0c0e;
    --palette-highlight: #c41236;
}

Switching light / dark

The data-theme attribute on a parent element selects the active theme. Drop a BOBThemeSelector anywhere to toggle it interactively:

ThemeSelector.razor
<BOBThemeSelector Variant="BOBThemeSelectorVariant.SunMoon" />

Under the hood, the selector writes to localStorage and sets data-theme on <html>. You can also set it yourself:

Manual theme switch
<html data-theme="dark">

Custom palette

The simplest way to re-skin the library is to override the CSS custom properties in your own stylesheet, scoped to :root or a specific data-theme:

wwwroot/css/my-theme.css
/* Scoped to the light theme */
[data-theme="light"] {
    --palette-primary: #c41236;       /* dark red */
    --palette-primary-contrast: #fff;
    --palette-background: #fbf7f6;
    --palette-surface: #ffffff;
}

/* And the dark variant */
[data-theme="dark"] {
    --palette-primary: #ff4d6d;
    --palette-primary-contrast: #1a0c0e;
    --palette-background: #120508;
    --palette-surface: #1e0c10;
}
🎨
This very site uses #c41236 as its primary color — achieved by overriding --palette-primary and a handful of companion tokens. See wwwroot/css/docs.css in the repository.

Component-level overrides

Each component exposes per-instance parameters for Color, BackgroundColor, Border, Shadow, etc. These become --bob-inline-* CSS variables on the element — so a one-off can be set without touching theme files:

InstanceOverride.razor
<BOBButton Text="Custom"
           BackgroundColor="rgba(26,12,14,1)"
           Color="rgba(255,255,255,1)" />

Semantic colors

Use PaletteColor to feed theme-aware values into component parameters. It renders to var(--palette-*) so the color follows the active theme:

PaletteColors.razor
<BOBButton Text="Primary"
           BackgroundColor="@PaletteColor.Primary"
           Color="@PaletteColor.PrimaryContrast" />
<BOBButton Text="Success"
           BackgroundColor="@PaletteColor.Success"
           Color="@PaletteColor.SuccessContrast" />
<BOBButton Text="Warning"
           BackgroundColor="@PaletteColor.Warning"
           Color="@PaletteColor.WarningContrast" />