Files
timebank-cc-public/references/BRANDING_CUSTOMIZATION.md
Ronald Huynen 2547717edb Initial commit
2026-03-23 21:37:59 +01:00

1107 lines
28 KiB
Markdown

# Branding Customization Guide
Complete guide for creating and customizing branded instances of the Timebank platform with unique visual identity, configuration, content, and protected deployment.
---
## Table of Contents
1. [Overview](#overview)
2. [Configuration Protection System](#configuration-protection-system)
3. [Theme Customization](#theme-customization)
4. [Logo Customization](#logo-customization)
5. [Platform Configuration](#platform-configuration)
6. [Footer Customization](#footer-customization)
7. [Custom Content Pages](#custom-content-pages)
8. [Database Updates](#database-updates)
9. [Complete Setup Workflow](#complete-setup-workflow)
10. [Deployment & Updates](#deployment--updates)
11. [Troubleshooting](#troubleshooting)
12. [Best Practices](#best-practices)
---
## Overview
The platform supports complete branding through four main customization layers:
1. **Theme System** - Visual styling (colors, fonts, spacing)
2. **Logo System** - Theme-specific branding assets
3. **Platform Configuration** - Behavior, limits, translations, footer structure
4. **Content Seeding** - Custom pages and navigation links
All customizations are protected from git overwrites during deployments using a **config template system**.
---
## Configuration Protection System
### How It Works
**The Problem:**
When running `deploy.sh`, `git pull` would overwrite customized configuration files with defaults from the repository.
**The Solution:**
- **`.example` files** are tracked in git (templates with defaults)
- **Actual config files** are gitignored (safe from overwrites)
- **`deploy.sh`** automatically creates configs from templates if they don't exist
- **Custom changes persist** through all deployment updates
### Protected Configuration Files
The following files are protected from git overwrites:
| File | Purpose | Template |
|------|---------|----------|
| `config/themes.php` | Theme configuration (colors, fonts, logos) | `config/themes.php.example` |
| `config/timebank-default.php` | Default platform configuration | `config/timebank-default.php.example` |
| `config/timebank_cc.php` | Platform-specific overrides | Create as needed |
### Initial Migration
**Run once per repository** to enable the protection system:
```bash
# From repository root
./scripts/migrate-to-example-configs.sh
```
This will:
1. Remove config files from git tracking (keeps your local files intact)
2. Add .example template files to git
3. Update .gitignore
4. Create a commit with all changes
5. Ready to push to repository
**After migration:**
```bash
git push origin main
```
### Configuration Workflow
#### New Installation
```bash
git clone <repo>
cd timebank_cc_2
./deploy.sh
```
What happens:
1. No config files exist yet
2. `deploy.sh` creates them from `.example` templates
3. Customize configs with your branding
4. Customizations are now protected
#### Updating Existing Installation
```bash
./deploy.sh
```
What happens:
1. Config check runs BEFORE git pull
2. Your custom configs exist → Preserved
3. Git pulls latest `.example` templates (updated defaults)
4. Your custom configs remain unchanged
5. Review `.example` files for new features to merge manually
### Merging Updates from Templates
**Option 1: Manual Review (Recommended)**
```bash
# Compare your config with latest template
diff config/themes.php config/themes.php.example
# Review changes and merge relevant updates
nano config/themes.php
```
**Option 2: Regenerate from Template**
⚠️ **Warning:** This erases all customizations!
```bash
# Backup first
cp config/themes.php config/themes.php.backup
# Delete and regenerate
rm config/themes.php
./deploy.sh
# Re-apply customizations from backup
```
---
## Theme Customization
### Setting Up a Theme
**Location:** `config/themes.php`
**Activation:** Set `TIMEBANK_THEME` in `.env`
```bash
TIMEBANK_THEME=your_brand_name
```
### Creating a New Theme
Add your theme definition to `config/themes.php`:
```php
'your_brand_name' => [
'name' => 'Your Brand Name',
'description' => 'Description of your brand theme',
// Logo Configuration
'logos' => [
'svg_inline' => 'logos.your_brand_name',
'email_logo' => 'app-images/your_brand_name_mail_logo.png',
],
// Color Palette
'colors' => [
// Brand Colors
'brand' => '#FF5733',
'secondary' => '#EBEDEE',
'accent' => '#434343',
// Primary Palette (9 shades)
'primary' => [
50 => '#fef2f2',
100 => '#fee2e2',
200 => '#fecaca',
300 => '#fca5a5',
400 => '#f87171',
500 => '#ef4444', // Main primary color
600 => '#dc2626',
700 => '#b91c1c',
800 => '#991b1b',
900 => '#7f1d1d',
],
// Functional Colors
'danger-dark' => '#b91c1c',
'danger' => '#ef4444',
'danger-light' => '#fecaca',
'reaction' => '#eab308',
'reaction-hover' => '#ca8a04',
// UI Elements
'background' => '#FFFFFF',
'border' => '#CDCFD0',
'surface' => '#F9FAFB',
// Text Colors
'text' => [
'primary' => '#111827',
'secondary' => '#6E6F70',
'light' => '#9CA3AF',
'surface' => '#F9FAFB',
'background' => '#FFFFFF',
],
// Logo Color (for SVG fill)
'logo' => '#000000',
],
// Typography
'typography' => [
'font_family_body' => 'Roboto, sans-serif',
'font_family_heading' => 'Oswald, sans-serif',
'font_size_base' => '16px',
'line_height_base' => '1.7',
'heading_transform' => 'uppercase', // or 'none'
'heading_sizes' => [
'h1' => '30px',
'h2' => '24px',
'h3' => '20px',
'h4' => '16px',
],
'links' => [
'text_decoration' => 'underline',
'text_decoration_hover' => 'underline',
'font_weight' => '600',
],
],
],
```
### Using Theme Colors in Views
**CSS Classes (Recommended):**
```blade
<div class="bg-theme-brand text-white">
<h1 class="text-theme-primary-600">Title</h1>
<p class="text-theme-text-medium">Body text</p>
<button class="border-theme-border bg-theme-primary-500">Click</button>
</div>
```
**PHP Helper Functions:**
```php
// In Livewire components or controllers
$brandColor = theme_color('brand');
$primaryColor = theme_color('primary.500');
$fontFamily = theme_font('font_family_body');
$logoView = theme_logo('svg_inline');
$emailLogo = theme_logo('email_logo');
```
**Important:** Always use theme-aware classes/functions. Never hardcode colors like `bg-blue-500` or `text-gray-600`.
### Testing Themes
Switch themes by changing `.env`:
```bash
TIMEBANK_THEME=timebank_cc
TIMEBANK_THEME=uuro
TIMEBANK_THEME=vegetable
TIMEBANK_THEME=yellow
```
After changing theme:
```bash
php artisan config:clear
npm run build
```
Test all UI components across themes to ensure consistency.
---
## Logo Customization
### Logo System Overview
Each theme can have unique branding through two types of logos:
1. **SVG Logos** - Inline SVG for website (navigation, auth pages)
2. **Email/PDF Logos** - PNG format for emails and PDF reports
### Logo File Locations
**SVG Logos (Website):**
- **Location:** `resources/views/logos/`
- **Files:**
- `timebank_cc.blade.php` - Default theme
- `uuro.blade.php` - Uuro theme
- `vegetable.blade.php` - Vegetable theme
- `yellow.blade.php` - Yellow theme
- `your_brand.blade.php` - Your custom theme
- **Format:** Blade template with inline SVG
- **Git Tracking:** Yes (tracked as defaults)
**Email/PDF Logos:**
- **Location:** `storage/app/public/app-images/`
- **Files:**
- `timebank_cc_mail_logo.png`
- `uuro_mail_logo.png`
- `vegetable_mail_logo.png`
- `yellow_mail_logo.png`
- `your_brand_mail_logo.png`
- **Format:** PNG image
- **Git Tracking:** No (gitignored, safe from overwrites)
### Creating Custom Logos
#### 1. SVG Logo (Website)
**Create logo file:**
```bash
cp resources/views/logos/timebank_cc.blade.php resources/views/logos/your_brand.blade.php
```
**Edit the SVG:**
```blade
{{-- your_brand.blade.php --}}
<svg width="160" height="112" viewBox="0 0 52.92 37.04" xmlns="http://www.w3.org/2000/svg"
class="fill-theme-logo">
<title>{{ config('app.name') . ' ' . __('logo') }}</title>
<!-- Your custom SVG paths here -->
<path d="..." />
</svg>
```
**Important:**
- Keep `class="fill-theme-logo"` for theme-aware coloring
- Include title tag for accessibility
- Adjust viewBox and dimensions as needed
#### 2. Email/PDF Logo (PNG)
**Upload your logo:**
```bash
# Upload to storage/app/public/app-images/
cp /path/to/your/logo.png storage/app/public/app-images/your_brand_mail_logo.png
```
**Recommended specifications:**
- Format: PNG with transparency
- Size: 300-400px width (maintains quality in emails)
- Aspect ratio: Similar to your website logo
#### 3. Configure Theme Logos
**In `config/themes.php`:**
```php
'your_brand' => [
'name' => 'Your Brand',
'logos' => [
'svg_inline' => 'logos.your_brand', // Website logo
'email_logo' => 'app-images/your_brand_mail_logo.png', // Email/PDF logo
],
// ... rest of theme config
],
```
### Logo Helper Functions
```php
// Get SVG view name
theme_logo('svg_inline') // Returns: 'logos.your_brand'
// Get email logo path
theme_logo('email_logo') // Returns: 'app-images/your_brand_mail_logo.png'
```
### Logo Usage in Code
The logo system is automatically integrated:
- **Navigation menu** - Uses `application-mark.blade.php` (compact logo)
- **Authentication pages** - Uses `authentication-card-logo.blade.php` (full logo)
- **Email templates** - Uses theme email logo
- **PDF reports** - Uses theme email logo
All automatically switch based on `TIMEBANK_THEME` setting.
### Logo Deployment Protection
**SVG logos** are tracked in git as theme-specific defaults
**Email logos** are in `storage/` (gitignored, safe from git pull)
No conflicts when deploying updates
Each installation maintains unique branding
---
## Platform Configuration
### Setting Up Platform Config
**Location:** `config/` directory
**Activation:** Set `TIMEBANK_CONFIG` in `.env`
```bash
TIMEBANK_CONFIG=your_platform_name
```
### Creating a New Platform Configuration
1. **Copy the default config:**
```bash
cp config/timebank-default.php config/your-platform.php
```
2. **Customize settings in `config/your-platform.php`:**
```php
return [
// Platform Identity
'platform_name' => 'Your Platform Name',
'currency_name' => 'TimeCredits',
'currency_symbol' => 'TC',
// Email Addresses
'mail' => [
'system_admin' => [
'email' => 'admin@yourplatform.com',
'name' => 'System Admin',
],
'user_admin' => [
'email' => 'users@yourplatform.com',
'name' => 'User Admin',
],
'content_admin' => [
'email' => 'content@yourplatform.com',
'name' => config('app.name'),
],
],
// Account Limits (in minutes)
'accounts' => [
'user' => [
'min_balance' => -300, // -5 hours
'max_balance' => 2400, // 40 hours
],
'organization' => [
'min_balance' => -3000, // -50 hours
'max_balance' => 24000, // 400 hours
],
],
// Transaction Types & Permissions
'transactions' => [
'types' => [
'worked_time' => true,
'gift' => true,
'donation' => true,
'currency_creation' => true,
'currency_removal' => true,
'migration' => false,
],
'permissions' => [
'user_can_create_currency' => false,
'organization_can_create_currency' => false,
'bank_can_create_currency' => true,
],
],
// Profile Visibility
'profiles' => [
'show_public_balances' => true,
'allow_private_profiles' => true,
],
// Search Configuration
'search' => [
'boost_factors' => [
'name' => 3.0,
'description' => 1.5,
'tags' => 2.0,
],
],
// Footer Configuration (see next section)
'footer' => [
// ...
],
];
```
### Accessing Configuration Values
**PHP Helper Function:**
```php
// Anywhere in the application
$platformName = timebank_config('platform_name');
$minBalance = timebank_config('accounts.user.min_balance');
$canCreateCurrency = timebank_config('transactions.permissions.bank_can_create_currency');
```
**In Blade Views:**
```blade
<h1>{{ timebank_config('platform_name') }}</h1>
<span>{{ timebank_config('currency_symbol') }}</span>
```
---
## Footer Customization
### Footer Configuration Structure
The footer is defined in your platform config file under the `footer` key:
```php
'footer' => [
'tagline' => 'Your time is currency', // Translation key
'sections' => [
[
'title' => 'Who we are', // Translation key
'order' => 1, // Display order (lower = left)
'visible' => true, // Show/hide entire section
'links' => [
[
'route' => 'static-whyjoin', // Laravel route name
'title' => 'Why join', // Translation key
'order' => 1, // Display order (lower = top)
'visible' => true, // Show/hide link
],
[
'route' => 'static-association',
'title' => 'Timebank Organization',
'order' => 2,
'visible' => true,
],
// Custom URL example
[
'url' => 'https://example.com',
'title' => 'External Resource',
'order' => 3,
'visible' => true,
],
// Auth-required example
[
'route' => 'static-messenger',
'title' => 'Chat messenger',
'order' => 4,
'visible' => true,
'auth_required' => true, // Only show to logged-in users
],
],
],
[
'title' => 'Help',
'order' => 2,
'visible' => true,
'links' => [
// ... more links
],
],
],
],
```
### Footer Link Types
**1. Internal Route Links (most common):**
```php
[
'route' => 'static-whyjoin', // Must match route name in routes/web.php
'title' => 'Why join', // Translation key from lang files
'order' => 1,
'visible' => true,
]
```
**2. External URL Links:**
```php
[
'url' => 'https://external-site.com/page',
'title' => 'External Resource',
'order' => 2,
'visible' => true,
]
```
**3. Authenticated Links:**
```php
[
'route' => 'dashboard',
'title' => 'Dashboard',
'order' => 3,
'visible' => true,
'auth_required' => true, // Only visible when logged in
]
```
### Common Footer Customizations
**Reorder sections:**
```php
['title' => 'Help', 'order' => 1, ...],
['title' => 'Who we are', 'order' => 2, ...],
['title' => 'Policies', 'order' => 3, ...],
```
**Hide specific links:**
```php
['route' => 'static-research', 'title' => 'Research', 'visible' => false],
```
**Add email contact:**
```php
['url' => 'mailto:hello@yourplatform.com', 'title' => 'Email Us', 'order' => 5, 'visible' => true],
```
**Add new section:**
```php
[
'title' => 'Community',
'order' => 4,
'visible' => true,
'links' => [
['url' => 'https://forum.example.com', 'title' => 'Forum', 'order' => 1, 'visible' => true],
['url' => 'https://blog.example.com', 'title' => 'Blog', 'order' => 2, 'visible' => true],
],
],
```
---
## Custom Content Pages
### Adding New Static Pages
To add new pages that appear in the footer or navigation, seed the database with categories and translations.
#### Step 1: Add Category Type
**File:** `database/seeders/ExtendCategoriesSeeder.php`
```php
$categories = [
// Existing categories...
// Add your new category
['type' => 'SiteContents\\Static\\YourNewPage'],
];
```
**Naming Convention:**
- Static pages: `SiteContents\\Static\\PageName`
- Manage pages: `SiteContents\\Manage\\PageName`
- Error pages: `SiteContents\\Errors\\ErrorCode`
#### Step 2: Add Translations
**File:** `database/seeders/ExtendCategoryTranslationsSeeder.php`
```php
$translations = [
// Existing translations...
'SiteContents\\Static\\YourNewPage' => [
'en' => [
'name' => 'Your New Page',
'slug' => 'your-new-page',
],
'nl' => [
'name' => 'Jouw Nieuwe Pagina',
'slug' => 'jouw-nieuwe-pagina',
],
'de' => [
'name' => 'Deine Neue Seite',
'slug' => 'deine-neue-seite',
],
'es' => [
'name' => 'Tu Nueva Página',
'slug' => 'tu-nueva-pagina',
],
'fr' => [
'name' => 'Votre Nouvelle Page',
'slug' => 'votre-nouvelle-page',
],
],
];
```
#### Step 3: Run Seeders
```bash
php artisan db:seed --class=ExtendCategoriesSeeder
php artisan db:seed --class=ExtendCategoryTranslationsSeeder
```
#### Step 4: Add Route
**File:** `routes/web.php`
```php
Route::get('/your-new-page', [StaticController::class, 'yourNewPage'])
->name('static-yournewpage');
```
#### Step 5: Add to Footer
**File:** `config/your-platform.php`
```php
'footer' => [
'sections' => [
[
'title' => 'Who we are',
'links' => [
[
'route' => 'static-yournewpage',
'title' => 'Your New Page',
'order' => 10,
'visible' => true,
],
],
],
],
],
```
---
## Database Updates
### When to Use Database Updates
Use the `DatabaseUpdate` command when:
- Renaming seeded categories across all installations
- Updating category slugs or translations globally
- Migrating data structures affecting seeded content
- Making breaking changes to existing static pages
**DO NOT use for:**
- Adding new categories (use seeders)
- Platform-specific configs (use config files)
- Theme changes (use themes.php)
### Adding a Database Update
**File:** `app/Console/Commands/DatabaseUpdate.php`
```php
private function updateYourFeature()
{
$this->info('Updating your feature...');
try {
DB::beginTransaction();
// Update category type
$updated = DB::table('categories')
->where('type', 'SiteContents\\Old\\Name')
->update(['type' => 'SiteContents\\New\\Name']);
if ($updated > 0) {
$this->info(" ✓ Updated {$updated} category record(s)");
}
// Update translations
$category = DB::table('categories')
->where('type', 'SiteContents\\New\\Name')
->first();
if ($category) {
DB::table('category_translations')
->where('category_id', $category->id)
->update([
'name' => 'New Name',
'slug' => 'new-slug',
]);
}
DB::commit();
$this->info(' ✓ Update completed successfully');
} catch (\Exception $e) {
DB::rollBack();
$this->error(' ✗ Failed to update: ' . $e->getMessage());
}
}
```
**Call in handle() method:**
```php
public function handle()
{
$this->info('Starting database updates...');
$this->updateYourFeature();
$this->info('Database updates completed!');
return 0;
}
```
**Run updates:**
```bash
php artisan database:update
```
---
## Complete Setup Workflow
### Initial Branded Instance Setup
```bash
# 1. Clone repository
git clone <repository-url>
cd timebank_cc_2
# 2. Run first deployment (creates configs from templates)
./deploy.sh
# 3. Configure environment variables
# Edit .env:
TIMEBANK_THEME=mybrand
TIMEBANK_CONFIG=mybrand
# 4. Create theme in config/themes.php
# Add 'mybrand' theme definition with colors, fonts, logos
# 5. Create platform config
cp config/timebank-default.php config/mybrand.php
# Edit config/mybrand.php with your settings
# 6. Create theme logos
# SVG logo:
cp resources/views/logos/timebank_cc.blade.php resources/views/logos/mybrand.blade.php
# Edit mybrand.blade.php with your logo
# Email logo:
cp your-logo.png storage/app/public/app-images/mybrand_mail_logo.png
# 7. Add custom content pages (if needed)
# Edit database/seeders/ExtendCategoriesSeeder.php
# Edit database/seeders/ExtendCategoryTranslationsSeeder.php
# 8. Seed custom content
php artisan db:seed --class=ExtendCategoriesSeeder
php artisan db:seed --class=ExtendCategoryTranslationsSeeder
# 9. Apply database updates
php artisan database:update
# 10. Clear caches and build assets
php artisan config:clear
npm run build
# 11. Test
php artisan serve
```
---
## Deployment & Updates
### Protected Files During Deployment
When you run `./deploy.sh`, these files are protected from git overwrites:
**Protected (gitignored):**
- `config/themes.php` - Your custom theme configuration
- `config/timebank-default.php` - Your platform configuration
- `config/mybrand.php` - Your brand-specific configuration
- `storage/app/public/app-images/*.png` - Your email/PDF logos
**Updated from git (templates):**
- `config/themes.php.example` - Latest theme defaults
- `config/timebank-default.php.example` - Latest platform defaults
- `resources/views/logos/*.blade.php` - SVG logo defaults
### Deployment Process
```bash
./deploy.sh
```
**What happens:**
1. **Config Check (NEW):**
```
===========================================================
CHECKING CONFIGURATION FILES
===========================================================
✓ config/themes.php exists (custom installation config)
✓ config/timebank-default.php exists (custom installation config)
```
2. **Git Pull:**
- Pulls latest code
- Updates `.example` templates
- Your custom configs untouched
3. **Dependencies:**
- `composer install`
- `npm install`
4. **Database:**
- Migrations
- Database updates
- Seeders
5. **Build Assets:**
- `npm run build`
- Theme-specific compilation
### After Deployment
**Review new features:**
```bash
# Check for new theme options
diff config/themes.php config/themes.php.example
# Check for new platform config options
diff config/timebank-default.php config/timebank-default.php.example
```
**Merge beneficial updates manually** into your custom configs.
### Emergency Config Recovery
If configs were accidentally overwritten:
```bash
# Restore from git (if committed before migration)
git checkout HEAD~1 config/themes.php
# Or regenerate from backup
cp config/themes.php.backup config/themes.php
```
---
## Troubleshooting
### Theme not applying
- Verify `TIMEBANK_THEME` in `.env` matches theme name in `config/themes.php`
- Run `php artisan config:clear`
- Run `npm run build`
- Check browser console for CSS errors
### Platform config not loading
- Verify `TIMEBANK_CONFIG` in `.env` matches filename (without `.php`)
- Ensure config file exists in `config/` directory
- Run `php artisan config:clear`
### Logos not displaying
- **SVG logos:** Verify logo file exists in `resources/views/logos/`
- **Email logos:** Verify PNG exists in `storage/app/public/app-images/`
- Check theme config `logos` section points to correct files
- Run `php artisan config:clear`
### Footer links not appearing
- Check `visible` is set to `true` in footer config
- Verify route name exists in `routes/web.php`
- Check translation keys exist in language files
- Clear cache: `php artisan config:clear`
### Custom page not found
- Verify category seeded: check `categories` table
- Verify translations seeded: check `category_translations` table
- Verify route exists and matches `route` in footer config
- Check category type matches exactly (including backslashes)
### Config files overwritten by git
**Symptom:** Customizations disappeared after `git pull`
**Cause:** Migration to .example system not completed
**Solution:**
```bash
# Run migration script
./scripts/migrate-to-example-configs.sh
# Push changes
git push origin main
```
### Database updates not applying
- Check database connection
- Verify update method called in `handle()`
- Check database permissions
- Look for transaction rollback messages
---
## Best Practices
### Configuration Management
1. **Always use .example files** as templates for new installations
2. **Document your customizations** in comments within config files
3. **Review .example files** after each deployment for new features
4. **Backup configs** before major changes
5. **Never commit actual config files** (only .example versions)
### Theme Development
1. **Test across all themes** after making UI changes
2. **Use theme-aware classes exclusively** (`bg-theme-brand` not `bg-blue-500`)
3. **Define complete color palettes** (all 9 shades for primary)
4. **Test logo visibility** on light and dark backgrounds
5. **Verify email logos** render correctly in email clients
### Platform Configuration
1. **Keep configs focused** on behavior, not styling
2. **Version control custom configs** locally (gitignored from repo)
3. **Document custom pages** in config file comments
4. **Follow naming conventions** for category types consistently
5. **Provide all 5 language translations** for new content
### Deployment
1. **Run ./deploy.sh** regularly to stay updated
2. **Review .example diffs** after deployment
3. **Test in staging** before production deployment
4. **Clear caches** after configuration changes
5. **Monitor deployment logs** for config file status
### Content Management
1. **Use DatabaseUpdate** for breaking changes to seeded data
2. **Test footer configuration** in all languages
3. **Clear caches** after seeding new categories
4. **Verify routes** before adding to footer config
5. **Keep slugs** URL-friendly and consistent
---
## Quick Reference
### Environment Variables
```bash
TIMEBANK_THEME=your_brand_name
TIMEBANK_CONFIG=your_platform_name
```
### Helper Functions
```php
// Theme
theme_color('brand')
theme_color('primary.500')
theme_font('font_family_body')
theme_logo('svg_inline')
theme_logo('email_logo')
// Config
timebank_config('platform_name')
timebank_config('accounts.user.min_balance')
timebank_config('footer.sections')
```
### Artisan Commands
```bash
# Configuration
php artisan config:clear
# Database
php artisan db:seed --class=ExtendCategoriesSeeder
php artisan db:seed --class=ExtendCategoryTranslationsSeeder
php artisan database:update
# Assets
npm run build
# Deployment
./deploy.sh
./scripts/migrate-to-example-configs.sh
```
### File Locations
```
Themes: config/themes.php (protected)
config/themes.php.example (tracked)
Configs: config/{platform}.php (protected)
config/{platform}.php.example (tracked)
SVG Logos: resources/views/logos/{theme}.blade.php
Email Logos: storage/app/public/app-images/{theme}_mail_logo.png (gitignored)
Seeders: database/seeders/ExtendCategoriesSeeder.php
database/seeders/ExtendCategoryTranslationsSeeder.php
DB Updates: app/Console/Commands/DatabaseUpdate.php
Translations: lang/{locale}/messages.php
Routes: routes/web.php
```
### Git Tracking
```bash
# Tracked in git (defaults/templates)
git ls-files config/*.example
git ls-files resources/views/logos/
# Gitignored (custom/protected)
git check-ignore config/themes.php
git check-ignore storage/app/public/app-images/*.png
```
---
## Additional Resources
- **Theme System Details:** `references/THEME_IMPLEMENTATION.md`
- **Logo Customization:** `resources/views/logos/README.md`
- **Migration Script:** `scripts/migrate-to-example-configs.sh`
- **Main Documentation:** `CLAUDE.md`
---
This guide covers all aspects of creating and maintaining a branded Timebank instance with full protection from deployment overwrites.