This guide covers platform-level theme configuration for self-hosted CheckTick deployments. These settings control the default appearance for all users and can be overridden by organization owners.
Overview
CheckTick uses a 3-tier theme hierarchy:
- Platform defaults (this guide) - Set by superusers via Branding Configuration UI (
/branding/) - Organization themes - Set by organization owners via Profile page (see Branding and Theme Settings)
- Survey themes - Set by survey creators for individual surveys
This guide focuses on platform-level configuration for deployment administrators.
Recommended Configuration Method
โ Use the Branding Configuration UI (Recommended for self-hosted deployments):
- Log in as a superuser
- Navigate to your Profile page and click "Configure Branding"
- Or go directly to
/branding/ - Configure themes, logos, and fonts through the web interface
- Changes apply instantly without container restarts
Alternative methods:
- CLI: python manage.py configure_branding --show (see command options below)
- Django Admin: /admin/core/sitebranding/ (still available)
- Environment variables: Optional fallbacks only (not recommended for active configuration)
Enterprise Features in Self-Hosted Mode
All self-hosted CheckTick deployments automatically include Enterprise tier features:
- Custom Branding: Superusers can configure platform branding via:
- Web UI: Navigate to
/branding/from your profile page - CLI:
python manage.py configure_branding --theme nord --logo path/to/logo.png - No Limits: All users get unlimited surveys and full collaboration features
- Full Control: Complete control over data and infrastructure
See Branding and Theme Settings for details on using the branding configuration UI.
Configuration Options
Option 1: Branding Configuration UI (Recommended)
The web interface at /branding/ provides the easiest way to configure platform branding:
Features: - Visual theme preview - Logo upload (light and dark modes) - Font selection - Instant changes (no container restart) - Form validation
CLI Alternative:
# Show current configuration
python manage.py configure_branding --show
# Set theme presets
python manage.py configure_branding --theme-light nord --theme-dark business
# Upload logos
python manage.py configure_branding --logo path/to/logo.png --logo-dark path/to/logo-dark.png
# Configure fonts
python manage.py configure_branding --font-heading "Inter, sans-serif" --font-body "Open Sans, sans-serif"
# Reset to defaults
python manage.py configure_branding --reset
Option 2: Environment Variables (Optional Fallbacks)
Note: Environment variables are fallback values only. The Branding Configuration UI (or Django admin) values take precedence. These are useful for setting initial defaults on first deployment but are not recommended for ongoing configuration changes.
Set these in your deployment configuration (e.g., .env file, Docker Compose, Kubernetes secrets) only if you want fallback defaults:
Required Environment Variables (Infrastructure)
These are always required for any deployment:
# Django settings (required)
DEBUG=False
SECRET_KEY=your-secret-key-here
ALLOWED_HOSTS=checktick.example.com,www.checktick.example.com
CSRF_TRUSTED_ORIGINS=https://checktick.example.com,https://www.checktick.example.com
# Database (required)
DATABASE_URL=postgres://user:password@db:5432/checktick
# Email (required for user registration/notifications)
EMAIL_HOST=smtp.example.com
EMAIL_PORT=587
[email protected]
EMAIL_HOST_PASSWORD=your-smtp-password
EMAIL_USE_TLS=True
[email protected]
# Media/Static files (required for production)
AWS_STORAGE_BUCKET_NAME=your-bucket-name # If using S3
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
See Self-Hosting Configuration for full list of required variables.
Optional Branding Variables (Fallbacks Only)
These are optional and only used if not configured via UI:
# Site title (shown in navbar and browser tab)
BRAND_TITLE="CheckTick"
# Icon URLs (optional - can also upload via Django admin)
BRAND_ICON_URL="/static/icons/checktick_brand_favicon.svg"
BRAND_ICON_URL_DARK="/static/icons/checktick_brand_favicon_dark.svg"
# Icon accessibility
BRAND_ICON_ALT="CheckTick"
BRAND_ICON_TITLE="CheckTick"
# Icon size (Tailwind classes or numeric)
BRAND_ICON_SIZE_CLASS="w-6 h-6"
# OR
BRAND_ICON_SIZE=6 # Converts to w-6 h-6
Theme Preset Variables
CheckTick uses daisyUI v5.4.7 with 32 built-in theme presets:
# Default logical theme (checktick-light or checktick-dark)
BRAND_THEME="checktick-light"
# Light mode preset (default: nord)
# Available: light, cupcake, bumblebee, emerald, corporate, retro,
# cyberpunk, valentine, garden, lofi, pastel, fantasy, nord,
# cmyk, autumn, acid, lemonade, winter, nord, sunset
BRAND_THEME_PRESET_LIGHT="nord"
# Dark mode preset (default: business)
# Available: dark, synthwave, halloween, forest, aqua, black,
# luxury, dracula, business, night, coffee, dim
BRAND_THEME_PRESET_DARK="business"
Font Variables
# Heading font stack
BRAND_FONT_HEADING="'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, 'Apple Color Emoji', 'Segoe UI Emoji'"
# Body font stack
BRAND_FONT_BODY="Merriweather, ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif"
# Optional external font CSS URL
BRAND_FONT_CSS_URL="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;600;700&family=Merriweather:wght@300;400;700&display=swap"
Advanced: Custom Theme CSS
For advanced deployments requiring custom brand colors beyond presets:
# Custom CSS variables for light theme (from daisyUI Theme Generator)
BRAND_THEME_CSS_LIGHT="--color-primary: oklch(65% 0.21 25); --radius-selector: 1rem;"
# Custom CSS variables for dark theme
BRAND_THEME_CSS_DARK="--color-primary: oklch(45% 0.18 25); --radius-selector: 1rem;"
Note: Most deployments should use preset themes only. Custom CSS requires understanding of daisyUI Theme Generator variables.
Option 3: Django Admin (Alternative)
The Django admin interface is still available as an alternative to the Branding Configuration UI. Both interfaces manage the same SiteBranding database model.
Accessing SiteBranding Admin:
- Log in as a superuser
- Navigate to
/admin/ - Click on Site Branding under Core
SiteBranding Model Fields
The admin interface provides access to all platform theme settings:
Theme Presets:
- default_theme - Logical theme name (checktick-light/checktick-dark)
- theme_preset_light - daisyUI preset for light mode (dropdown with 20 options)
- theme_preset_dark - daisyUI preset for dark mode (dropdown with 12 options)
Icons:
- icon_file - Upload light mode icon (SVG/PNG)
- icon_url - Or provide URL for light mode icon
- icon_file_dark - Upload dark mode icon (optional)
- icon_url_dark - Or provide URL for dark mode icon
Fonts:
- font_heading - CSS font stack for headings
- font_body - CSS font stack for body text
- font_css_url - External font CSS URL (e.g., Google Fonts)
Advanced Custom CSS:
- theme_light_css - Custom CSS variables for light theme
- theme_dark_css - Custom CSS variables for dark theme
Configuration Precedence
The system checks configuration sources in this order:
- Database values (SiteBranding model via UI/CLI/Admin) - Highest priority
- Environment variables (
.envfile) - Fallback only - Built-in defaults (hardcoded in settings) - Last resort
Recommended workflow:
1. Set environment variables only for initial deployment defaults (optional)
2. Use Branding Configuration UI (/branding/) for all ongoing changes
3. Changes via UI/CLI take precedence and persist across container restarts
4. No need to modify environment variables after initial setup
CSS Build Process
CheckTick uses Tailwind CSS v4 with CSS-based configuration (no tailwind.config.js).
When to Rebuild CSS
Rebuild CSS when you: - Change Tailwind/daisyUI configuration in CSS files - Add new templates with utility classes - Update custom theme CSS - Modify component styles
How to Rebuild
In development (Docker):
docker compose exec web npm run build:css
In production (local):
npm run build:css
Build details:
- Input: checktick_app/static/css/daisyui_themes.css
- Output: checktick_app/static/build/styles.css (minified)
- Build time: ~250ms
- Output size: ~192KB (includes all 39 daisyUI themes)
Tailwind v4 Architecture
Key differences from Tailwind v3:
- No JavaScript config file - Uses
@import,@plugin,@themedirectives in CSS - Separate CLI package - Uses
@tailwindcss/cliinstead of main package - CSS-first configuration - All config in
daisyui_themes.css
Configuration example:
@import "tailwindcss";
@plugin "daisyui" {
themes: all; /* Loads all 39 themes */
}
@plugin "@tailwindcss/typography";
Theme Architecture
Logical vs Physical Theme Names
CheckTick uses a logical naming system to separate user preferences from actual daisyUI presets:
Logical names (stored in user preferences):
- checktick-light - User's light mode preference
- checktick-dark - User's dark mode preference
- system - Follow OS preference
Physical names (actual daisyUI presets applied to DOM):
- nord, business, cupcake, etc.
- Applied via <html data-theme="nord">
Why? This allows changing the platform's default light/dark themes without breaking user preferences. Users who selected "light mode" will automatically get the new light preset.
How Theme Selection Works
- User preference stored in browser localStorage (
checktick-theme) - JavaScript (
theme-toggle.js) maps logical name to physical preset - Platform config determines which preset each logical name maps to
- DOM updated with
<html data-theme="nord">(physical name)
Theme Cascade Logic
The context processor (context_processors.py) implements the cascade:
# Check for organization theme
if user_org and (user_org.theme_preset_light or user_org.theme_preset_dark):
# Use organization theme
preset_light = user_org.theme_preset_light
preset_dark = user_org.theme_preset_dark
else:
# Fall back to platform theme
preset_light = platform_preset_light
preset_dark = platform_preset_dark
Result: Organization members see their org's custom theme, while users without an organization see platform defaults.
Custom Theme CSS
For deployments requiring brand-specific colors beyond presets, use the daisyUI Theme Generator.
Using the Theme Generator
- Visit daisyui.com/theme-generator
- Customize colors, border radius, etc.
- Copy the generated CSS variables
- Paste into
BRAND_THEME_CSS_LIGHTandBRAND_THEME_CSS_DARK
Acceptable CSS Format
Only paste CSS variable declarations:
--color-primary: oklch(65% 0.21 25);
--color-secondary: oklch(70% 0.15 200);
--radius-selector: 1rem;
--depth: 0;
Do not paste:
- CSS selectors (:root, [data-theme="..."])
- Rule blocks with { }
- Arbitrary CSS rules
The system automatically normalizes and injects variables under the correct theme selectors.
How Custom CSS Works
- Generator variables normalized to daisyUI runtime variables
- Injected into
<style>block in page<head> - Applied under
[data-theme="checktick-light"]and[data-theme="checktick-dark"] - Merged with base preset (custom variables override preset values)
Production Deployment
Docker Environment Variables
In docker-compose.yml or .env:
environment:
- BRAND_TITLE=MyOrganization CheckTick
- BRAND_THEME_PRESET_LIGHT=corporate
- BRAND_THEME_PRESET_DARK=luxury
- BRAND_ICON_URL=/static/icons/custom-logo.svg
Kubernetes ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: checktick-config
data:
BRAND_TITLE: "MyOrganization CheckTick"
BRAND_THEME_PRESET_LIGHT: "corporate"
BRAND_THEME_PRESET_DARK: "luxury"
Static Files
After changing themes, collect static files in production:
python manage.py collectstatic --noinput
In Docker:
docker compose exec web python manage.py collectstatic --noinput
Security Considerations
Superuser-Only Access
- Only superusers can access
/admin/and modify SiteBranding - Regular users cannot change platform defaults
- Organization owners can only theme their own organization
- Survey creators can only theme their own surveys
CSS Injection Protection
- Custom CSS fields are sanitized to prevent XSS
- Only CSS variable declarations are accepted
- JavaScript and external resources are blocked
- Validation occurs on save
Icon Upload Security
- File type validation (SVG, PNG, JPG, WebP only)
- File size limits enforced
- Files stored in MEDIA_ROOT with restricted permissions
- Served via Django's media URL (not executable)
Troubleshooting
Theme Not Applying
Check precedence: 1. Database SiteBranding overrides environment variables 2. Organization themes override platform defaults 3. Survey themes override organization themes
Clear caches:
# Browser localStorage
localStorage.removeItem('checktick-theme')
# Django cache (if using)
docker compose exec web python manage.py clear_cache
Custom CSS Not Working
Verify format: - Only variable declarations allowed - No CSS selectors or rule blocks - Check browser DevTools console for errors
Rebuild CSS:
docker compose exec web npm run build:css
Icons Not Showing
Check file paths:
- Uploaded files: /media/icons/...
- Static files: /static/icons/...
- External URLs: Must be absolute and accessible
Verify media configuration:
# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
Colors Look Wrong
Check theme preset:
- Verify BRAND_THEME_PRESET_LIGHT and BRAND_THEME_PRESET_DARK
- Ensure preset name matches daisyUI options
- Test both light and dark modes
Check custom CSS: - Verify OKLCH color values (not hex) - Ensure percentage and decimal formats correct - Test in daisyUI Theme Generator first
Related Documentation
- Branding and Theme Settings - User guide for theme hierarchy and organization-level theming
- Themes - Technical implementation details for developers
- Self-Hosting Configuration - General deployment configuration
Support
For deployment assistance: - Check Getting Help - Review Issues vs Discussions - Join community discussions on GitHub