# Timebank.cc Style Guide This document outlines the styling conventions and theme system for the Timebank.cc application. It serves as the authoritative reference for all UI styling patterns used throughout the application. **Reference Implementation:** `resources/views/mailings/manage.blade.php` and `resources/views/livewire/mailings/manage.blade.php` demonstrate all core UI patterns and should be consulted when building new views. ## Theme System Overview The application uses a sophisticated configuration-based multi-theme system that allows different installations to have unique visual identities. The system is built on four core components: ### Core Architecture 1. **Theme Configuration**: `config/themes.php` - Centralized theme definitions with colors, typography, and metadata 2. **Theme Helpers**: `app/Helpers/ThemeHelper.php` - PHP functions for accessing theme data throughout the application 3. **CSS Custom Properties**: `resources/css/app.css` - Automatically generated theme-aware CSS variables 4. **Tailwind Integration**: `tailwind.config.js` - Theme-aware utility classes using CSS custom properties ### Available Themes 1. **timebank_cc** (default) - Gray, black and white professional theme 2. **uuro** - Black, white and cyan theme with vibrant accents (inspired by buuro.net) 3. **vegetable** - Green, natural theme with earth tones (inspired by lekkernassuh.org) 4. **yellow** - High-contrast yellow and black theme (inspired by yellowbrick.nl) Themes are activated via the `TIMEBANK_THEME` environment variable and can be switched per installation without code changes. ## Theme Configuration Structure Each theme in `config/themes.php` follows this standardized structure: ```php 'theme_name' => [ 'name' => 'Display Name', 'description' => 'Theme description', 'colors' => [ // Primary color scale (required) 'primary' => [ 50 => '#F6F8F9', // Lightest 100 => '#EBEDEE', 200 => '#DCDEDF', 300 => '#CDCFD0', // Border colors 400 => '#B8BABB', // Muted elements 500 => '#999B9C', // Main brand color 600 => '#6E6F70', 700 => '#434343', 800 => '#242424', 900 => '#1A1A1A', // Darkest, headers ], // Semantic colors (required) 'secondary' => '#6B7280', // Secondary brand color 'accent' => '#434343', // Accent color for highlights 'brand' => '#000000', // Brand/header backgrounds 'logo' => '#000000', // Logo and icon colors 'background' => '#FFFFFF', // Page background 'surface' => '#F9FAFB', // Card/surface backgrounds // Text colors (required) 'text' => [ 'primary' => '#111827', // Main text 'secondary' => '#6B7280', // Secondary text, subtitles 'light' => '#9CA3AF', // Muted text, placeholders ], // Theme-specific colors (optional) 'success' => '#00D084', // Uuro: success states 'danger' => '#CF2E2E', // Uuro: error states 'warning' => '#FF6900', // Uuro: warning states 'info' => '#0693E3', // Uuro: info states 'surface_alt' => '#E2E2C7', // Vegetable: alternative surface 'neutral' => [ // Yellow: neutral color scale 'dark' => '#2F2E2E', 'medium' => '#5D5B5B', 'light' => '#EFEFEF', ], 'surface_dark' => '#000000', // Yellow: dark surface 'accent_dark' => '#001B2F', // Yellow: dark accent ], 'typography' => [ // Base typography (required) 'font_family_body' => 'Roboto, sans-serif', 'font_family_heading' => 'Oswald, sans-serif', 'font_size_base' => '16px', 'line_height_base' => '1.5', 'heading_transform' => 'uppercase', // or 'none' // Theme-specific typography (optional) 'font_family_quote' => 'Georgia, serif', // Yellow theme 'line_height_heading' => '1.4', // Vegetable theme 'font_sizes' => [ // Uuro theme 'small' => '13px', 'medium' => '20px', 'large' => '36px', 'x-large' => '42px', ], 'heading_sizes' => [ // Vegetable theme 'h1' => '23px', 'h2' => '36px', 'h3' => '18px', 'h4' => '17px', ], 'font_weights' => [ // Yellow theme 'regular' => '400', 'medium' => '500', 'semibold' => '600', 'bold' => '700', 'extrabold' => '800', ], ], ] ``` ## PHP Theme Helper Functions The `app/Helpers/ThemeHelper.php` file provides convenient functions for accessing theme data throughout the application: ### Core Functions ```php // Get current theme data $theme = theme(); // Returns full theme array with 'id' key added $themeName = theme_name(); // Returns theme display name (e.g., "Uuro") $themeId = theme_id(); // Returns theme identifier (e.g., "uuro") // Get specific theme values $color = theme_color('primary.500'); // Returns '#64748B' (hex value) $logoColor = theme_color('logo'); // Returns logo color $bodyFont = theme_font('font_family_body'); // Returns typography setting // Get theme values with defaults $customColor = theme_color('custom.color', '#000000'); // Returns default if not found $customFont = theme_font('custom_font', 'Arial'); // Returns default if not found // Theme checking if (is_theme('vegetable')) { // Vegetable theme specific logic } // Access nested values $textColor = theme('colors.text.primary'); // Direct config access $fontWeight = theme('typography.font_weights.bold'); // Access nested arrays ``` ### Dynamic CSS Variable Generation ```php // Generate CSS custom properties for current theme $cssVars = theme_css_vars(); // Returns: "--color-primary-500: 100 116 139; --color-brand: 25 2 54; --font-family-body: system-ui, -apple-system, sans-serif; ..." // Helper function for color conversion $rgbValue = hexToRgb('#64748B'); // Returns "100 116 139" (space-separated RGB) ``` ## CSS Architecture ### Automatic CSS Custom Property Generation Colors from `config/themes.php` are automatically converted to CSS custom properties in RGB format (enabling alpha transparency): ```css /* Generated automatically via theme_css_vars() function */ [data-theme="uuro"] { --color-primary-50: 248 250 252; /* From #F8FAFC */ --color-primary-500: 100 116 139; /* From #64748B */ --color-primary-900: 15 23 42; /* From #0F172A */ --color-brand: 25 2 54; /* From #190236 */ --color-logo: 25 2 54; /* From #190236 */ --color-background: 255 255 255; /* From #FFFFFF */ --color-text-primary: 0 0 0; /* From #000000 */ /* Typography variables */ --font-family-body: system-ui, -apple-system, sans-serif; --font-family-heading: system-ui, -apple-system, sans-serif; --line-height-base: 1.6; --heading-transform: none; } ``` ### Tailwind CSS Integration Theme colors integrate with Tailwind using RGB format with alpha value support: ```javascript // tailwind.config.js colors: { // Primary color scale primary: { 50: 'rgb(var(--color-primary-50) / )', 500: 'rgb(var(--color-primary-500) / )', 900: 'rgb(var(--color-primary-900) / )', }, // Semantic theme colors 'theme-secondary': 'rgb(var(--color-secondary) / )', 'theme-accent': 'rgb(var(--color-accent) / )', 'theme-brand': 'rgb(var(--color-brand) / )', 'theme-logo': 'rgb(var(--color-logo) / )', 'theme-background': 'rgb(var(--color-background) / )', 'theme-surface': 'rgb(var(--color-surface) / )', 'theme-text': { primary: 'rgb(var(--color-text-primary) / )', secondary: 'rgb(var(--color-text-secondary) / )', light: 'rgb(var(--color-text-light) / )', }, } ``` ### CSS Utility Classes Additional utility classes are defined in `resources/css/app.css`: ```css .bg-theme-brand { background-color: rgb(var(--color-brand)); } .fill-theme-logo { fill: rgb(var(--color-logo)); } .text-theme-logo { color: rgb(var(--color-logo)); } .border-theme-border { border-color: rgb(var(--color-primary-300)); } ``` ## Color Usage Guidelines ### Primary Color Scale Usage - **50-200**: Light backgrounds, subtle accents, hover states - **300-400**: Borders, muted elements, disabled states - **500**: Main brand color, primary buttons, links - **600-900**: Text colors, dark backgrounds, headers ### Semantic Color Guidelines #### Background Colors - `theme-background`: Main page background (typically white) - `theme-surface`: Card backgrounds, modal backgrounds, raised surfaces - `theme-brand`: Strong brand elements, page headers, primary buttons #### Text Colors - `theme-text-primary`: Main body text, headings - `theme-text-secondary`: Secondary text, captions, metadata - `theme-text-light`: Muted text, placeholders, disabled text #### Accent Colors - `theme-secondary`: Secondary brand elements, alternative buttons - `theme-accent`: Highlights, badges, accent elements - `theme-logo`: Logos, icons, brand symbols ### Theme-Specific Color Usage #### Uuro Theme Status Colors ```php // Available via theme_color() function $success = theme_color('success'); // '#00D084' - vivid green cyan $danger = theme_color('danger'); // '#CF2E2E' - vivid red $warning = theme_color('warning'); // '#FF6900' - luminous orange $info = theme_color('info'); // '#0693E3' - vivid cyan blue ``` #### Vegetable Theme Natural Colors ```php $surfaceAlt = theme_color('surface_alt'); // '#E2E2C7' - light beige alternative ``` #### Yellow Theme Neutral System ```php $darkNeutral = theme_color('neutral.dark'); // '#2F2E2E' $mediumNeutral = theme_color('neutral.medium'); // '#5D5B5B' $lightNeutral = theme_color('neutral.light'); // '#EFEFEF' $surfaceDark = theme_color('surface_dark'); // '#000000' $accentDark = theme_color('accent_dark'); // '#001B2F' ``` ## UI Component Patterns This section documents the standard UI patterns used throughout the application, based on the reference implementation in `resources/views/livewire/mailings/manage.blade.php`. ### Page Layout Structure #### Standard Management Page Layout ```html {{ __('Page Title') }}
{{ __('Page Heading') }}
{{ __('Page description text...') }}
@livewire('component.name')
@push('scripts') @endpush
``` **Key Patterns:** - Header slot: `text-xl text-theme-light leading-tight` - Container: `max-w-7xl mx-auto sm:px-6 lg:px-8` - Card wrapper: `bg-theme-background overflow-hidden shadow-xl sm:rounded-lg` - Inner padding: `p-12 px-6 sm:px-20 bg-theme-background` - Page title: `mt-4 text-2xl` - Description: `mt-6 text-theme-secondary` ### Action Buttons Section #### Top Action Bar with Primary and Danger Actions ```html
{{ __('Create Item') }} {{ __('Delete') }} {{ __('selection') }}
``` **Key Patterns:** - Container: `mb-6 flex items-center justify-between` - Primary button: `bg-theme-brand hover:bg-opacity-80` - Icon spacing: `mr-3 h-5 w-5` - Use `wire:click` for Livewire actions - Use `:disabled` for reactive disabling ### Search and Filters #### Search Input with Clear Button ```html
@if ($search) @endif
``` **Key Patterns:** - Search container: `relative w-1/3` - Input classes: `w-full rounded-md border border-theme-primary px-3 py-1 pr-10 text-theme-primary shadow-sm focus:border-theme-primary focus:outline-none focus:ring focus:ring-theme-primary sm:text-sm` - Clear button: positioned absolutely, `inset-y-0 right-0`, with `text-theme-secondary hover:text-theme-primary` - Use `wire:model.live` for real-time search #### Filter Dropdowns Row ```html
``` **Key Patterns:** - Container: `mb-4 flex items-center space-x-3` - Select width: `!w-60` (use `!` to override default) - Always use `:clearable="true"` for filters - Use `wire:model.live` for immediate filtering ### Data Tables #### Complete Table Structure ```html
@forelse($items as $item) @empty @endforelse
{{ __('Title') }} @if($sortField === 'title') @if($sortDirection === 'asc') ↑ @else ↓ @endif @endif
{{ __('Column Name') }} {{ __('Actions') }}
{{ $item->title }}
{{ $item->subtitle }}
{{ $item->description }} {{ ucfirst($item->status) }} @if($item->date)
{{ $item->date->format('M j') }}
{{ $item->date->format('Y') }}
{{ $item->date->format('H:i') }}
@else - @endif
@if($item->user)
profile
@else - @endif
{{ __('No items found.') }}
@if($items->hasPages())
{{ $items->links('livewire.long-paginator') }}
@endif
``` **Key Patterns:** - Table wrapper: `bg-white shadow-sm rounded-lg overflow-hidden` - Table: `min-w-full divide-y divide-gray-200` - Header: `bg-gray-50`, headers use `px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider align-middle` - Sortable headers: add `cursor-pointer` and `wire:click="sortBy('field')"` - Sort indicators: `text-gray-400` with ↑/↓ characters - Body: `bg-white divide-y divide-gray-200` - Cells: `px-3 py-4` (standard), `px-6 py-3` (checkbox column) - Action buttons: `space-x-1` between buttons - Empty state: full colspan, `px-6 py-12 text-center text-gray-500` - Pagination wrapper: `px-6 py-3 border-t border-gray-200` #### Status Badge Patterns ```html {{ __('Active') }} {{ __('Pending') }} {{ __('Draft') }} {{ __('Processing') }} {{ __('Failed') }} ``` **Key Patterns:** - Base classes: `inline-flex px-2 py-1 text-xs font-medium rounded-full` - Use semantic colors: green (success), yellow (warning), gray (neutral), theme-danger (error) ### Modals #### Standard Dialog Modal Structure ```html {{ __('Modal Title') }}
{{ __('Cancel') }} {{ __('Save') }}
``` **Key Patterns:** - Use `wire:model.live` for modal visibility - Add `wire:key` to prevent state issues - Standard sizes: `sm`, `md`, `lg`, `xl`, `2xl` - Footer buttons: Cancel (secondary) on left, Primary action on right with `ml-3` - Primary actions use `bg-theme-brand` #### Confirmation Modal Pattern ```html {{ __('Confirm Action') }} {{ __('Are you sure you want to perform this action?') }}
{{ __('This action cannot be undone.') }}

{{ __('Details') }}: {{ $itemName }}
{{ __('Cancel') }} {{ __('Confirm') }}
``` **Key Patterns:** - Destructive actions use `danger-button` - Include warning text and action details - Use `$set('property', value)` for simple state changes #### Preview Modal with Iframe ```html {{ __('Preview') }}

{{ __('Additional Options') }}

{{ __('Close') }}
``` **Key Patterns:** - Mobile preview: `width: 322px; height: 570px` in `rounded-3xl` container - Sections separated by: `border-t border-gray-200 pt-6` - Section headers: `text-sm font-medium text-gray-700 mb-3` ### Form Elements #### Standard Input with Label ```html
@error('fieldName')

{{ $message }}

@enderror
``` **Key Patterns:** - Label: `block text-sm text-gray-700 mb-2` - Error message: `mt-1 text-sm text-red-600` - Always include `@error` directives below inputs #### Checkbox with Label ```html ``` **Key Patterns:** - Container: `flex items-center space-x-3` - Checkbox classes: `rounded border-gray-300 text-theme-brand shadow-sm focus:border-theme-brand focus:ring focus:ring-theme-brand focus:ring-opacity-50` - Label text: `text-sm text-gray-700` #### Info Box Pattern ```html

{{ __('Label:') }} {{ $value }}

{{ __('Additional information text.') }}

``` **Key Patterns:** - Container: `p-3 bg-theme-surface rounded-md border border-theme-border` - Primary text: `text-sm text-theme-primary` - Secondary text: `text-sm text-theme-secondary mt-1` ### Notification Banners and Alerts #### Informational Banner (Grayscale) ```html

{{ __('Banner Heading') }}

{{ __('Informational message content goes here. This is a neutral notification.') }}

``` **Key Patterns:** - Background: `bg-gray-50` (professional, non-alarming) - Border: `border border-gray-300` (subtle, matches table styling) - Icon: `h-5 w-5 text-gray-400` (muted) - Heading: `text-sm font-medium text-gray-800` - Body text: `text-sm text-gray-600` - Use for: maintenance notices, informational messages, neutral alerts #### Warning Banner (Grayscale with Warning Icon) ```html

{{ __('Site Under Maintenance') }}

{{ __('The site is currently undergoing maintenance. Only users with administrator access can log in at this time.') }}

``` **Key Patterns:** - Same styling as informational banner - Use warning triangle icon for cautionary messages - Keep grayscale to avoid alarm - Use for: system notices, maintenance messages, non-critical warnings #### Error Message (Red) ```html

{{ __('Login is currently disabled due to site maintenance.') }}

``` **Key Patterns:** - Background: `bg-red-50` - Border: `border border-red-200` - Icon: `h-5 w-5 text-red-400` (X circle for errors) - Text: `text-sm text-red-800` - Use for: actual errors, failed actions, critical issues #### Success Message (Green) ```html

{{ __('Your changes have been saved successfully.') }}

``` **Key Patterns:** - Background: `bg-green-50` - Border: `border border-green-200` - Icon: `h-5 w-5 text-green-400` (checkmark circle) - Text: `text-sm text-green-800` - Use for: successful operations, confirmations **Banner/Alert Usage Guidelines:** - **Grayscale**: Default for informational, maintenance, or neutral system messages - **Red**: Only for actual errors or failed actions - **Green**: Only for successful completions - **Yellow**: Avoid; use grayscale for warnings instead (more professional) - Icon size: Always `h-5 w-5` - Icon position: Always in flex-shrink-0 container with `ml-3` for text - Common SVG icons: info circle, warning triangle, X circle, checkmark circle ### Buttons and Actions #### Button Component Usage ```html {{ __('Primary Action') }} {{ __('Delete') }} {{ __('Light Action') }} ``` **Key Patterns:** - Primary buttons: `bg-theme-brand hover:bg-opacity-80` - Icon-only buttons: use `title` attribute for accessibility - Icons with text: `mr-3` for spacing - Icon size: `h-5 w-5` (standard), `h-6 w-6` (large) - Use `:disabled` for reactive disable state #### Loading State Pattern ```html {{ __('Submit') }} {{ __('Processing...') }} ``` OR with spinner: ```html ``` **Key Patterns:** - Use `wire:loading.attr="disabled"` to prevent double-clicks - Use `wire:target` to scope loading state to specific action - Provide text feedback OR spinner during loading - Spinner classes: `animate-spin h-5 w-5 text-white` ### Spacing and Layout #### Standard Spacing Scale - **Section spacing:** `mt-12` (top margin for major sections) - **Element spacing:** `mb-6` (bottom margin for groups), `mb-4` (between related items) - **Inline spacing:** `space-x-1` (tight), `space-x-3` (standard), `mr-3` (icon before text) - **Content spacing:** `space-y-6` (form sections), `space-y-3` (form fields) - **Padding:** `p-3` (small boxes), `p-6` (standard), `p-12` (page content) ## Styling Best Practices ### 1. Use Theme-Aware Classes ✅ **Recommended:** ```html
``` ### Event Cards Full-height cards with image backgrounds: ```html

Event Title

``` ## Typography System ### Font Family Configuration Access theme fonts using helper functions: ```php // In PHP/Livewire components $bodyFont = theme_font('font_family_body'); // 'Roboto, sans-serif' $headingFont = theme_font('font_family_heading'); // 'Oswald, sans-serif' $quoteFont = theme_font('font_family_quote'); // 'Georgia, serif' (Yellow theme) ``` ### Text Transform Rules - **Timebank_cc**: Uppercase headings (`heading_transform: 'uppercase'`) - **Other themes**: Normal case headings (`heading_transform: 'none'`) ```php // Conditional styling based on theme if (is_theme('timebank_cc')) { $headingClass = 'uppercase'; } else { $headingClass = 'normal-case'; } ``` ## Development Workflow ### Adding New Theme Colors 1. **Add color to theme configuration** in `config/themes.php`: ```php 'themes' => [ 'theme_name' => [ 'colors' => [ 'new-color' => '#FF0000', // Single color 'new-scale' => [ // Color scale 50 => '#FFF5F5', 500 => '#FF0000', 900 => '#7F1D1D', ], ], ], ] ``` 2. **CSS custom properties are automatically generated** via `theme_css_vars()` function (no manual CSS needed) 3. **Add Tailwind utility classes** in `tailwind.config.js`: ```javascript colors: { 'theme-new-color': 'rgb(var(--color-new-color) / )', 'new-scale': { 50: 'rgb(var(--color-new-scale-50) / )', 500: 'rgb(var(--color-new-scale-500) / )', 900: 'rgb(var(--color-new-scale-900) / )', }, } ``` 4. **Create additional CSS utility classes** if needed in `resources/css/app.css`: ```css .bg-theme-new-color { background-color: rgb(var(--color-new-color)); } .border-new-color-500 { border-color: rgb(var(--color-new-scale-500)); } ``` 5. **Use in PHP/Livewire components**: ```php $newColor = theme_color('new-color'); // Returns '#FF0000' $lightShade = theme_color('new-scale.50'); // Returns '#FFF5F5' $darkShade = theme_color('new-scale.900'); // Returns '#7F1D1D' ``` ### Testing Themes Test theme functionality using helper functions: ```bash # Test individual theme colors TIMEBANK_THEME=timebank_cc php artisan tinker --execute="echo 'Timebank_cc primary: ' . theme_color('primary.500');" TIMEBANK_THEME=uuro php artisan tinker --execute="echo 'Uuro primary: ' . theme_color('primary.500');" TIMEBANK_THEME=vegetable php artisan tinker --execute="echo 'Vegetable primary: ' . theme_color('primary.500');" TIMEBANK_THEME=yellow php artisan tinker --execute="echo 'Yellow primary: ' . theme_color('primary.500');" # Test theme metadata php artisan tinker --execute="echo 'Current theme: ' . theme_name() . ' (' . theme_id() . ')';" # Test theme-specific colors TIMEBANK_THEME=uuro php artisan tinker --execute="echo 'Uuro success: ' . theme_color('success');" TIMEBANK_THEME=vegetable php artisan tinker --execute="echo 'Vegetable surface_alt: ' . theme_color('surface_alt');" # Test typography php artisan tinker --execute="echo 'Body font: ' . theme_font('font_family_body');" # Required after config changes php artisan config:clear ``` ### Environment Setup ```bash # Set theme in .env file TIMEBANK_THEME=uuro # Clear Laravel config cache (required after .env changes) php artisan config:clear # Rebuild frontend assets with theme npm run build ``` ### Theme Switching Workflow ```bash # Switch to different theme echo "TIMEBANK_THEME=vegetable" >> .env # Clear caches php artisan config:clear php artisan view:clear # Rebuild assets npm run build # Test theme colors php artisan tinker --execute="echo theme_name() . ': ' . theme_color('primary.500');" ``` ## File Structure ``` config/ themes.php # Main theme configuration file app/ Helpers/ ThemeHelper.php # Theme helper functions and utilities resources/ css/ app.css # CSS custom properties and utility classes views/ layouts/ app.blade.php # Theme data-attribute integration components/ jetstream/ application-logo.blade.php # Theme-aware main logo authentication-card-logo.blade.php # Theme-aware auth logo tailwind.config.js # Tailwind theme color integration references/ THEME_IMPLEMENTATION.md # Detailed implementation documentation ``` ## Migration from Hard-coded Styles ### 1. Identify Hard-coded Colors **Class Name Conversions:** - `bg-black` → `bg-theme-brand` - `text-gray-900` → `text-theme-text-primary` - `border-gray-300` → `border-primary-300` - `bg-white` → `bg-theme-background` - `bg-gray-50` → `bg-theme-surface` ### 2. Use Theme Helper Functions in PHP Replace hard-coded values with theme helpers: ```php // Before: Hard-coded values $primaryColor = '#999B9C'; $backgroundColor = '#FFFFFF'; $textColor = '#111827'; // After: Theme helpers $primaryColor = theme_color('primary.500'); $backgroundColor = theme_color('background'); $textColor = theme_color('text.primary'); ``` ### 3. Conditional Theme Logic Handle theme-specific differences: ```php // Theme-specific behavior if (is_theme('vegetable')) { $surfaceColor = theme_color('surface_alt'); // Light beige $lineHeight = theme_font('line_height_base'); // 1.8 for readability } else { $surfaceColor = theme_color('surface'); // Standard surface $lineHeight = theme_font('line_height_base'); // Theme default } // Theme-specific status colors if (is_theme('uuro')) { $successColor = theme_color('success'); // Vivid green cyan $dangerColor = theme_color('danger'); // Vivid red } else { $successColor = '#22c55e'; // Fallback green $dangerColor = '#ef4444'; // Fallback red } ``` ### 4. Component Migration Process 1. **Audit component** for hard-coded colors and styles 2. **Replace classes** with theme-aware equivalents 3. **Add PHP logic** for theme-specific behavior using helper functions 4. **Test across all themes** using environment variable switching 5. **Verify accessibility** and contrast ratios ## Accessibility Guidelines ### Color Contrast Requirements - Maintain WCAG AA contrast ratios (4.5:1) across all themes - Test text readability on all background combinations - Verify logo visibility on different header backgrounds ### Theme Testing Checklist - [ ] Form elements clearly distinguishable in all themes - [ ] Focus states visible with theme colors - [ ] Error states readable with theme danger colors - [ ] Interactive elements have sufficient contrast - [ ] Logo/icons visible on theme backgrounds ## Performance Considerations ### CSS Custom Properties Benefits - Efficient theme switching without rebuilding CSS - Single CSS bundle supports all themes - Runtime theme changes possible (if needed) - Excellent browser support and performance ### Optimization Guidelines - Use shared utility classes when possible - Minimize theme-specific CSS overrides - Leverage Tailwind's purging for unused theme classes - Keep theme configurations lean and focused ### Build Performance - Themes are compiled at build time for optimal performance - CSS custom properties enable single bundle for all themes - No runtime theme computation overhead