Overview
The TendSocial frontend uses a semantic theming system that supports:
- Dark Mode (Default)
- Light Mode
- Brand Match (Dynamic user-defined colors)
Architecture
The system is built on three pillars:
- CSS Variables: Defined in
index.css(e.g.,--color-bg-primary). - Tailwind Configuration: Mapped in
tailwind.config.jsto semantic utility classes (e.g.,bg-theme-base). - React Context:
ThemeContextmanages the state and persists it tolocalStorage.
Semantic Tokens
We use semantic naming rather than descriptive naming to ensure the theme adapts correctly across modes.
Backgrounds
| Token | Class | Description |
|---|---|---|
--color-bg-primary | bg-theme-base | Main page background |
--color-bg-secondary | bg-theme-surface | Cards, sidebars, headers |
--color-bg-tertiary | bg-theme-surface-highlight | Hover states, active items |
Text
| Token | Class | Description |
|---|---|---|
--color-text-primary | text-theme-primary | Main headings, body text |
--color-text-secondary | text-theme-secondary | Subtitles, metadata |
--color-text-tertiary | text-theme-tertiary | Low-contrast labels, placeholders |
Borders
| Token | Class | Description |
|---|---|---|
--color-border | border-theme-base | Default hairline borders |
--color-border-strong | border-theme-strong | Higher contrast borders |
Brand Match
When "Brand Match" is selected, the useBrandTheme hook dynamically overrides the CSS variables on the :root element with colors derived from the user's BrandProfile.
Usage Guidelines
✅ DO:
- Use semantic classes:
<div className="bg-theme-surface text-theme-primary"> - Use
opacitymodifiers if needed:<div className="bg-theme-base/50">
❌ DON'T:
- Use hardcoded grays:
bg-gray-900(Breaks light mode) - Use white/black directly:
text-theme-primary(Unless on a permanently dark element like a button)