# Website Builder V2 — Full Implementation Spec

## Current State Summary

The website builder is a single-page scrollable site per academy at `/site/{slug}`. It has 16 section types, 4 color pickers, 2 font selectors, 3 navbar styles, and a `template` column with 3 values (`bold_athletic`, `clean_professional`, `vibrant_playful`) that is **NOT implemented in rendering** — only one template renders regardless.

### Current DB Tables
- `website_settings` — one row per academy (colors, fonts, navbar_style, social_links JSON, custom_css, analytics IDs, is_published)
- `website_sections` — per-academy sections (section_key, title/title_en, subtitle/subtitle_en, content/content_en, settings JSON, sort_order, is_enabled)
- `website_testimonials` — name, role, content, rating, is_featured, sort_order
- `website_faqs` — question, answer, is_published, sort_order
- `website_news` — title, body, excerpt, slug, is_featured, published_at
- `website_partners` — name, website_url, sort_order, is_active
- `contact_submissions` — name, phone, email, message, status
- `media` — polymorphic (mediable_type/mediable_id), collection enum, disk_path, dimensions

### Current Files
- **Models**: `app/Domain/Website/Models/` — WebsiteSetting, WebsiteSection, WebsiteTestimonial, WebsiteNews, WebsiteFaq, WebsitePartner, ContactSubmission, Media
- **Services**: `app/Domain/Website/Services/` — WebsiteSettingService, WebsiteSectionService, WebsiteDataService, WebsiteCacheService, MediaService
- **Enums**: `app/Domain/Website/Enums/` — SectionKey (16 cases), MediaCollection (13 cases), ContactSubmissionStatus
- **Livewire Admin**: `app/Livewire/Website/` — SectionManager, ThemeEditor, GalleryManager, NewsManager, FaqManager, TestimonialManager, PartnerManager, ContactSubmissionList
- **Public Views**: `resources/views/website/` — layout.blade.php, index.blade.php, navbar.blade.php, footer.blade.php, + `sections/` (16 partials)
- **CSS**: `resources/css/website.css` (481 lines, Tailwind v4, CSS variables)
- **JS**: `resources/js/website.js` (104 lines, scroll effects, counters, smooth scroll)
- **Controller**: `app/Http/Controllers/PublicWebsiteController.php` — renders using WebsiteDataService
- **Routes**: `/site/{slug}` with `ResolveAcademyFromSlug` middleware

### Current CSS Variables (in layout.blade.php)
```css
:root {
    --site-primary: {{ $settings->primary_color }};
    --site-secondary: {{ $settings->secondary_color }};
    --site-accent: {{ $settings->accent_color }};
    --site-text: {{ $settings->text_color }};
    --site-bg: {{ $settings->background_color ?? '#ffffff' }};
    --site-heading-font: '{{ $settings->heading_font }}', 'Noto Sans Arabic', sans-serif;
    --site-body-font: '{{ $settings->body_font }}', 'Noto Sans Arabic', sans-serif;
}
```

### What Does NOT Exist (must build from scratch)
- No WYSIWYG / rich text editor
- No visual page builder / drag-drop blocks
- No live side-by-side preview
- No template switcher UI (DB column exists, rendering doesn't branch)
- No per-section background/color customization
- No typography size/weight/spacing controls
- No spacing/padding controls
- No animation controls
- No multi-page support
- No video embed support
- No map integration
- No custom domain support
- No blog detail page (model has slug but no public show route)
- No language switcher on public site

---

## The 30 Upgrades

---

### UPGRADE 1: Template Switcher (3 → 8 Themes)

**What**: Implement the template system that already has a DB column but no UI or rendering logic. Add 5 more templates beyond the 3 in the CHECK constraint.

**Database Changes**:
```sql
-- Migration: alter website_settings template CHECK constraint
ALTER TABLE website_settings DROP CONSTRAINT website_settings_template_check;
ALTER TABLE website_settings ADD CONSTRAINT website_settings_template_check
    CHECK (template IN (
        'bold_athletic', 'clean_professional', 'vibrant_playful',
        'dark_sport', 'minimal_corporate', 'gradient_modern',
        'neon_energy', 'earth_natural'
    ));
```

**Files to Modify**:
- `app/Livewire/Website/ThemeEditor.php` — add `$template` property, add template picker UI with preview thumbnails
- `resources/views/livewire/website/theme-editor.blade.php` — add template selection grid at top
- `resources/views/website/layout.blade.php` — add `data-template="{{ $settings->template }}"` to `<html>` tag
- `resources/css/website.css` — add template-specific CSS overrides using `[data-template="..."]` selectors

**Template Definitions** (each sets default colors + spacing + border-radius + shadow philosophy):

| Template | Primary | Secondary | Accent | BG | Border Radius | Shadows | Vibe |
|----------|---------|-----------|--------|-----|---------------|---------|------|
| bold_athletic | #1a1a2e | #16213e | #e94560 | #0f0f1a | 12px | heavy | Dark, dramatic, stadium lights |
| clean_professional | #ffffff | #f8fafc | #2563eb | #ffffff | 8px | subtle | Light, corporate, trustworthy |
| vibrant_playful | #fef3c7 | #ecfccb | #f59e0b | #fffbeb | 16px | colored | Bright, fun, kids-focused |
| dark_sport | #0a0a0a | #1c1c1c | #22c55e | #000000 | 4px | none | Ultra-dark, neon accent, sleek |
| minimal_corporate | #f9fafb | #ffffff | #6366f1 | #ffffff | 2px | xs | Ultra-clean, lots of whitespace |
| gradient_modern | #1e1b4b | #312e81 | #a78bfa | #0f0b2e | 20px | glow | Gradients everywhere, glass |
| neon_energy | #18181b | #27272a | #facc15 | #09090b | 0px | neon | Cyberpunk, electric, bold |
| earth_natural | #fefce8 | #f0fdf4 | #65a30d | #fafaf9 | 24px | soft | Organic, warm, nature |

**When applying a template**: Pre-fill the 4 colors + set CSS variables. User can still override individual colors after.

**Implementation Notes**:
- Template selection triggers `$this->primary_color = $presets[$template]['primary']` etc. in ThemeEditor
- Each template loads additional CSS class on `<body>` that overrides spacing, radius, shadow tokens
- Preview thumbnails: store as static images in `public/images/templates/` (screenshot each theme at 400x250)

---

### UPGRADE 2: Advanced Color Palette (4 → 8 Colors + Auto-Generate)

**What**: Expand from 4 color pickers to 8, add auto-palette generation from a single accent color.

**Database Changes**:
```sql
-- Migration: add columns to website_settings
ALTER TABLE website_settings ADD COLUMN background_color VARCHAR(7) DEFAULT '#ffffff';
ALTER TABLE website_settings ADD COLUMN surface_color VARCHAR(7) DEFAULT '#f8fafc';
ALTER TABLE website_settings ADD COLUMN border_color VARCHAR(7) DEFAULT '#e2e8f0';
ALTER TABLE website_settings ADD COLUMN muted_text_color VARCHAR(7) DEFAULT '#64748b';
```

**Files to Modify**:
- `app/Domain/Website/Models/WebsiteSetting.php` — add to $fillable: `background_color`, `surface_color`, `border_color`, `muted_text_color`
- `app/Livewire/Website/ThemeEditor.php` — add 4 new color properties, add `generatePalette()` method
- `resources/views/livewire/website/theme-editor.blade.php` — add 4 more color pickers + "Auto-generate from accent" button
- `resources/views/website/layout.blade.php` — add CSS variables: `--site-surface`, `--site-border`, `--site-muted`, `--site-bg`
- `resources/css/website.css` — replace hardcoded colors with new variables

**Auto-Generate Algorithm** (in ThemeEditor.php):
```php
public function generatePalette(): void
{
    // From accent color, derive full palette
    $accent = $this->accent_color; // e.g. '#e94560'
    $hsl = $this->hexToHsl($accent);

    // Dark mode (hue preserved, saturation reduced for backgrounds)
    $this->primary_color = $this->hslToHex($hsl[0], max(10, $hsl[1] - 40), 12);
    $this->secondary_color = $this->hslToHex($hsl[0], max(10, $hsl[1] - 35), 16);
    $this->background_color = $this->hslToHex($hsl[0], max(5, $hsl[1] - 50), 8);
    $this->surface_color = $this->hslToHex($hsl[0], max(8, $hsl[1] - 42), 14);
    $this->text_color = '#ffffff';
    $this->muted_text_color = $this->hslToHex($hsl[0], 10, 60);
    $this->border_color = $this->hslToHex($hsl[0], 10, 22);
}
```

Provide a toggle: "Dark mode" vs "Light mode" which reverses the palette generation (light = white bg, dark text; dark = navy bg, white text).

---

### UPGRADE 3: Typography System (Font Size + Weight + Spacing)

**What**: Add font size scale, line height, letter spacing, and heading weight controls.

**Database Changes**:
```sql
-- Migration: add typography columns to website_settings
ALTER TABLE website_settings ADD COLUMN font_size_scale VARCHAR(10) DEFAULT 'medium';
ALTER TABLE website_settings ADD COLUMN heading_weight VARCHAR(10) DEFAULT '700';
ALTER TABLE website_settings ADD COLUMN line_height VARCHAR(10) DEFAULT 'normal';
ALTER TABLE website_settings ADD COLUMN letter_spacing VARCHAR(10) DEFAULT 'normal';

ALTER TABLE website_settings ADD CONSTRAINT website_settings_font_size_scale_check
    CHECK (font_size_scale IN ('small', 'medium', 'large', 'xlarge'));
ALTER TABLE website_settings ADD CONSTRAINT website_settings_heading_weight_check
    CHECK (heading_weight IN ('400', '500', '600', '700', '800', '900'));
ALTER TABLE website_settings ADD CONSTRAINT website_settings_line_height_check
    CHECK (line_height IN ('tight', 'normal', 'relaxed', 'loose'));
ALTER TABLE website_settings ADD CONSTRAINT website_settings_letter_spacing_check
    CHECK (letter_spacing IN ('tight', 'normal', 'wide'));
```

**Font Size Scale Mapping** (CSS variables):
```css
/* small */  --site-text-base: 14px; --site-h1: 2rem; --site-h2: 1.6rem; --site-h3: 1.3rem;
/* medium */ --site-text-base: 16px; --site-h1: 2.5rem; --site-h2: 2rem; --site-h3: 1.5rem;
/* large */  --site-text-base: 18px; --site-h1: 3rem; --site-h2: 2.4rem; --site-h3: 1.75rem;
/* xlarge */ --site-text-base: 20px; --site-h1: 3.5rem; --site-h2: 2.8rem; --site-h3: 2rem;
```

**Files to Modify**:
- `app/Domain/Website/Models/WebsiteSetting.php` — add to $fillable
- `app/Livewire/Website/ThemeEditor.php` — add properties + dropdown options
- `resources/views/livewire/website/theme-editor.blade.php` — add 4 new selects in Typography section
- `resources/views/website/layout.blade.php` — emit CSS variables from these settings
- `resources/css/website.css` — use the variables for all text sizing

**Additional Fonts to Add** (expand from 8 to 15):
Cairo, Tajawal, IBM Plex Sans Arabic, Noto Sans Arabic, Almarai, Readex Pro, Rubik, El Messiri, Changa, Noto Kufi Arabic, Amiri, Lateef, Baloo Bhaijaan 2, Scheherazade New, Alexandria

---

### UPGRADE 4: Section Backgrounds (Per-Section Customization)

**What**: Each section can have its own background: solid color, gradient, image with overlay, or video.

**Database Changes**:
```sql
-- Migration: add columns to website_sections
ALTER TABLE website_sections ADD COLUMN bg_type VARCHAR(20) DEFAULT 'inherit';
ALTER TABLE website_sections ADD COLUMN bg_color VARCHAR(7);
ALTER TABLE website_sections ADD COLUMN bg_gradient_from VARCHAR(7);
ALTER TABLE website_sections ADD COLUMN bg_gradient_to VARCHAR(7);
ALTER TABLE website_sections ADD COLUMN bg_gradient_angle SMALLINT DEFAULT 180;
ALTER TABLE website_sections ADD COLUMN bg_image_path VARCHAR(500);
ALTER TABLE website_sections ADD COLUMN bg_overlay_opacity SMALLINT DEFAULT 60;
ALTER TABLE website_sections ADD COLUMN bg_video_url VARCHAR(500);

ALTER TABLE website_sections ADD CONSTRAINT website_sections_bg_type_check
    CHECK (bg_type IN ('inherit', 'solid', 'gradient', 'image', 'video'));
```

**Files to Modify**:
- `app/Domain/Website/Models/WebsiteSection.php` — add to $fillable + $casts
- `app/Livewire/Website/SectionManager.php` — add bg editing fields to section editor modal
- `resources/views/livewire/website/section-manager.blade.php` — add background config panel (shown per-section in edit mode)
- All 16 section partials in `resources/views/website/sections/*.blade.php` — wrap content in a container that applies the background

**Rendering Logic** (create a shared partial `resources/views/website/partials/section-bg.blade.php`):
```blade
@php
    $bgStyle = match($section->bg_type) {
        'solid' => "background-color: {$section->bg_color};",
        'gradient' => "background: linear-gradient({$section->bg_gradient_angle}deg, {$section->bg_gradient_from}, {$section->bg_gradient_to});",
        'image' => "background-image: url('" . Storage::disk('public')->url($section->bg_image_path) . "'); background-size: cover; background-position: center;",
        default => '',
    };
@endphp
<div style="{{ $bgStyle }}" class="relative">
    @if($section->bg_type === 'image' && $section->bg_overlay_opacity > 0)
        <div class="absolute inset-0 bg-black" style="opacity: {{ $section->bg_overlay_opacity / 100 }}"></div>
    @endif
    @if($section->bg_type === 'video' && $section->bg_video_url)
        <video autoplay muted loop playsinline class="absolute inset-0 w-full h-full object-cover">
            <source src="{{ $section->bg_video_url }}" type="video/mp4">
        </video>
        <div class="absolute inset-0 bg-black" style="opacity: {{ $section->bg_overlay_opacity / 100 }}"></div>
    @endif
    <div class="relative z-10">
        {{ $slot }}
    </div>
</div>
```

---

### UPGRADE 5: Spacing & Density Control

**What**: Global density slider + per-section padding override.

**Database Changes**:
```sql
-- Migration: add to website_settings
ALTER TABLE website_settings ADD COLUMN density VARCHAR(10) DEFAULT 'comfortable';
ALTER TABLE website_settings ADD CONSTRAINT website_settings_density_check
    CHECK (density IN ('compact', 'comfortable', 'spacious'));

-- Add to website_sections
ALTER TABLE website_sections ADD COLUMN padding_y VARCHAR(10) DEFAULT 'inherit';
ALTER TABLE website_sections ADD CONSTRAINT website_sections_padding_y_check
    CHECK (padding_y IN ('inherit', 'none', 'small', 'medium', 'large', 'xlarge'));
```

**Density CSS Mapping**:
```css
[data-density="compact"]    { --section-py: 3rem; --card-gap: 1rem; --element-gap: 0.5rem; }
[data-density="comfortable"]{ --section-py: 5rem; --card-gap: 1.5rem; --element-gap: 1rem; }
[data-density="spacious"]   { --section-py: 8rem; --card-gap: 2.5rem; --element-gap: 1.5rem; }
```

**Per-section padding_y override**:
```css
.section-pad-none   { padding-top: 0; padding-bottom: 0; }
.section-pad-small  { padding-top: 2rem; padding-bottom: 2rem; }
.section-pad-medium { padding-top: 4rem; padding-bottom: 4rem; }
.section-pad-large  { padding-top: 6rem; padding-bottom: 6rem; }
.section-pad-xlarge { padding-top: 10rem; padding-bottom: 10rem; }
```

**Files to Modify**:
- `app/Domain/Website/Models/WebsiteSetting.php` — add `density` to $fillable
- `app/Domain/Website/Models/WebsiteSection.php` — add `padding_y` to $fillable
- `app/Livewire/Website/ThemeEditor.php` — add density radio group
- `app/Livewire/Website/SectionManager.php` — add padding_y select in section editor
- `resources/views/website/layout.blade.php` — add `data-density="{{ $settings->density }}"` to `<body>`
- `resources/views/website/index.blade.php` — add padding class to each section wrapper

---

### UPGRADE 6: Border & Shape System

**What**: Global border-radius preset, card styles, section dividers, image shapes.

**Database Changes**:
```sql
-- Migration: add to website_settings
ALTER TABLE website_settings ADD COLUMN border_radius_preset VARCHAR(10) DEFAULT 'rounded';
ALTER TABLE website_settings ADD COLUMN card_style VARCHAR(10) DEFAULT 'raised';
ALTER TABLE website_settings ADD COLUMN section_divider VARCHAR(10) DEFAULT 'none';
ALTER TABLE website_settings ADD COLUMN image_shape VARCHAR(10) DEFAULT 'rounded';

ALTER TABLE website_settings ADD CONSTRAINT website_settings_border_radius_preset_check
    CHECK (border_radius_preset IN ('sharp', 'subtle', 'rounded', 'pill'));
ALTER TABLE website_settings ADD CONSTRAINT website_settings_card_style_check
    CHECK (card_style IN ('flat', 'raised', 'bordered', 'glass'));
ALTER TABLE website_settings ADD CONSTRAINT website_settings_section_divider_check
    CHECK (section_divider IN ('none', 'line', 'wave', 'angle', 'curve'));
ALTER TABLE website_settings ADD CONSTRAINT website_settings_image_shape_check
    CHECK (image_shape IN ('square', 'rounded', 'circle', 'blob'));
```

**CSS Token Mapping**:
```css
[data-radius="sharp"]   { --site-radius: 0px; --site-radius-lg: 0px; }
[data-radius="subtle"]  { --site-radius: 4px; --site-radius-lg: 8px; }
[data-radius="rounded"] { --site-radius: 12px; --site-radius-lg: 20px; }
[data-radius="pill"]    { --site-radius: 9999px; --site-radius-lg: 9999px; }

[data-card="flat"]     { --card-shadow: none; --card-border: none; --card-bg: transparent; }
[data-card="raised"]   { --card-shadow: 0 4px 20px rgba(0,0,0,0.15); --card-border: none; }
[data-card="bordered"] { --card-shadow: none; --card-border: 1px solid var(--site-border); }
[data-card="glass"]    { --card-shadow: 0 8px 32px rgba(0,0,0,0.1); --card-border: 1px solid rgba(255,255,255,0.1); --card-bg: rgba(255,255,255,0.05); backdrop-filter: blur(10px); }
```

**Section Dividers**: SVG shapes rendered between sections. Create `resources/views/website/partials/divider.blade.php`:
```blade
@if($settings->section_divider !== 'none')
    @include("website.partials.dividers.{$settings->section_divider}")
@endif
```

Each divider is an SVG: `wave.blade.php`, `angle.blade.php`, `curve.blade.php`, `line.blade.php`.

**Files to Modify**:
- `app/Domain/Website/Models/WebsiteSetting.php` — add 4 new columns to $fillable
- `app/Livewire/Website/ThemeEditor.php` — add 4 new properties with select options
- `resources/views/website/layout.blade.php` — add data attributes to body
- `resources/css/website.css` — use CSS tokens throughout
- `resources/views/website/index.blade.php` — include divider between sections
- Create: `resources/views/website/partials/dividers/{wave,angle,curve,line}.blade.php`

---

### UPGRADE 7: Animation & Motion Control

**What**: Per-section entrance animations with timing control + global motion toggle.

**Database Changes**:
```sql
-- Migration: add to website_settings
ALTER TABLE website_settings ADD COLUMN animations_enabled BOOLEAN DEFAULT true;
ALTER TABLE website_settings ADD COLUMN animation_speed VARCHAR(10) DEFAULT 'normal';
ALTER TABLE website_settings ADD CONSTRAINT website_settings_animation_speed_check
    CHECK (animation_speed IN ('slow', 'normal', 'fast'));

-- Add to website_sections
ALTER TABLE website_sections ADD COLUMN animation VARCHAR(20) DEFAULT 'fade-up';
ALTER TABLE website_sections ADD CONSTRAINT website_sections_animation_check
    CHECK (animation IN ('none', 'fade-up', 'fade-down', 'fade-left', 'fade-right', 'zoom-in', 'flip', 'bounce'));
```

**Animation Speed CSS**:
```css
[data-anim-speed="slow"]   { --anim-duration: 1.2s; --anim-delay-step: 200ms; }
[data-anim-speed="normal"] { --anim-duration: 0.8s; --anim-delay-step: 100ms; }
[data-anim-speed="fast"]   { --anim-duration: 0.4s; --anim-delay-step: 50ms; }
```

**Files to Modify**:
- `app/Domain/Website/Models/WebsiteSetting.php` — add to $fillable
- `app/Domain/Website/Models/WebsiteSection.php` — add `animation` to $fillable
- `app/Livewire/Website/ThemeEditor.php` — add animations_enabled toggle + speed select
- `app/Livewire/Website/SectionManager.php` — add animation select per section
- `resources/views/website/index.blade.php` — add `data-animation="{{ $section->animation }}"` to section wrapper
- `resources/js/website.js` — refactor IntersectionObserver to read animation type from data attr, respect `animations_enabled` via `data-animations` on body
- `resources/css/website.css` — define keyframes for each animation type

---

### UPGRADE 8: Hero Section Variants (1 → 8 Layouts)

**What**: Multiple hero layout options selectable from admin.

**Implementation**: Store hero variant in section settings JSON (no migration needed — `settings` is already JSONB).

**Settings JSON for hero section**:
```json
{
    "variant": "split_right",
    "overlay_opacity": 60,
    "cta_text": "ابدأ الآن",
    "cta_link": "#contact",
    "show_scroll_indicator": true,
    "text_alignment": "start"
}
```

**Variants**:
| Variant | Description |
|---------|-------------|
| `fullscreen` | Full viewport bg image, centered text overlay, CTA (current default) |
| `split_right` | Text left 50%, image right 50% |
| `split_left` | Image left 50%, text right 50% |
| `centered_minimal` | No image, centered text on solid/gradient bg, large typography |
| `video_bg` | Video background with text overlay |
| `slideshow` | Multiple images auto-rotating (images from gallery with tag 'hero') |
| `text_typing` | Animated typing effect on subtitle, minimal bg |
| `countdown` | Event-focused with countdown timer to a date |

**Files to Create**:
- `resources/views/website/sections/hero/fullscreen.blade.php`
- `resources/views/website/sections/hero/split_right.blade.php`
- `resources/views/website/sections/hero/split_left.blade.php`
- `resources/views/website/sections/hero/centered_minimal.blade.php`
- `resources/views/website/sections/hero/video_bg.blade.php`
- `resources/views/website/sections/hero/slideshow.blade.php`
- `resources/views/website/sections/hero/text_typing.blade.php`
- `resources/views/website/sections/hero/countdown.blade.php`

**Files to Modify**:
- `resources/views/website/sections/hero.blade.php` — change to: `@include("website.sections.hero.{$section->getSetting('variant', 'fullscreen')}")`
- `app/Livewire/Website/SectionManager.php` — add variant picker when editing hero section

---

### UPGRADE 9: Multi-Column Layout Per Section

**What**: Each content section gets a layout picker for how its items are arranged.

**Implementation**: Store in section `settings` JSON under key `layout`.

**Available Layouts** (per section type that shows multiple items: activities, programs, branches, trainers, news, pricing, partners):
```json
{
    "layout": "grid_3",
    "items_per_row": 3
}
```

| Layout | Description |
|--------|-------------|
| `grid_2` | 2-column grid |
| `grid_3` | 3-column grid (current default) |
| `grid_4` | 4-column grid |
| `list` | Single column, horizontal cards |
| `masonry` | Pinterest-style staggered |
| `carousel` | Horizontal slider with arrows |
| `alternating` | Zigzag left-right |

**Files to Modify**:
- `app/Livewire/Website/SectionManager.php` — add layout select for applicable sections
- `resources/views/website/sections/activities.blade.php` — switch grid class based on `$section->getSetting('layout', 'grid_3')`
- Same for: `programs.blade.php`, `branches.blade.php`, `trainers.blade.php`, `news.blade.php`, `pricing.blade.php`
- `resources/css/website.css` — add masonry and carousel styles

**Grid CSS**:
```css
.site-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); }
.site-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); }
.site-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); }
.site-list   { display: flex; flex-direction: column; }
.site-masonry { columns: 3; column-gap: var(--card-gap); }
.site-carousel { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; }
```
All grids collapse to 1 column on mobile (< 640px) and 2 on tablet (< 1024px).

---

### UPGRADE 10: Navbar Variants (3 → 8 Styles)

**What**: Expand navbar options with more visual styles and configuration.

**Database Changes**:
```sql
-- Migration: update CHECK constraint
ALTER TABLE website_settings DROP CONSTRAINT website_settings_navbar_style_check;
ALTER TABLE website_settings ADD CONSTRAINT website_settings_navbar_style_check
    CHECK (navbar_style IN ('solid', 'transparent', 'floating', 'centered', 'hamburger_always', 'side_drawer', 'minimal', 'mega'));

ALTER TABLE website_settings ADD COLUMN navbar_cta_text VARCHAR(100);
ALTER TABLE website_settings ADD COLUMN navbar_cta_link VARCHAR(500);
ALTER TABLE website_settings ADD COLUMN navbar_show_language BOOLEAN DEFAULT true;
ALTER TABLE website_settings ADD COLUMN navbar_show_social BOOLEAN DEFAULT false;
ALTER TABLE website_settings ADD COLUMN navbar_logo_position VARCHAR(10) DEFAULT 'start';
ALTER TABLE website_settings ADD CONSTRAINT website_settings_navbar_logo_position_check
    CHECK (navbar_logo_position IN ('start', 'center'));
```

**Navbar Variants**:
| Style | Description |
|-------|-------------|
| `solid` | Solid background always visible (current) |
| `transparent` | Transparent on hero, solid on scroll (current) |
| `floating` | Detached from top with margin and rounded corners (current) |
| `centered` | Logo centered, nav links split left/right |
| `hamburger_always` | Always shows hamburger menu even on desktop |
| `side_drawer` | Permanent sidebar navigation |
| `minimal` | Only logo + CTA button, no section links |
| `mega` | Full-width dropdown with rich content panels |

**Files to Create**:
- `resources/views/website/navbars/solid.blade.php`
- `resources/views/website/navbars/transparent.blade.php`
- `resources/views/website/navbars/floating.blade.php`
- `resources/views/website/navbars/centered.blade.php`
- `resources/views/website/navbars/hamburger_always.blade.php`
- `resources/views/website/navbars/side_drawer.blade.php`
- `resources/views/website/navbars/minimal.blade.php`
- `resources/views/website/navbars/mega.blade.php`

**Files to Modify**:
- `resources/views/website/navbar.blade.php` — change to: `@include("website.navbars.{$settings->navbar_style}")`
- `app/Livewire/Website/ThemeEditor.php` — add new navbar config fields
- `app/Domain/Website/Models/WebsiteSetting.php` — add new columns to $fillable

---

### UPGRADE 11: Footer Builder

**What**: Configurable footer with column layout and content blocks.

**Database Changes**:
```sql
-- Migration: add to website_settings
ALTER TABLE website_settings ADD COLUMN footer_columns SMALLINT DEFAULT 4;
ALTER TABLE website_settings ADD COLUMN footer_blocks JSONB DEFAULT '[]';
ALTER TABLE website_settings ADD COLUMN footer_bottom_text VARCHAR(500);
ALTER TABLE website_settings ADD COLUMN footer_style VARCHAR(10) DEFAULT 'dark';
ALTER TABLE website_settings ADD CONSTRAINT website_settings_footer_style_check
    CHECK (footer_style IN ('dark', 'light', 'accent', 'transparent'));
```

**Footer Blocks JSON Schema**:
```json
[
    {"type": "about", "content": "نبذة مختصرة عن الأكاديمية..."},
    {"type": "links", "title": "روابط سريعة", "links": [{"label": "الرئيسية", "url": "#hero"}, ...]},
    {"type": "contact", "title": "تواصل معنا"},
    {"type": "social", "title": "تابعنا"},
    {"type": "hours", "title": "ساعات العمل", "hours": [{"day": "السبت - الخميس", "time": "8ص - 10م"}]},
    {"type": "newsletter", "title": "النشرة البريدية"}
]
```

Block types: `about`, `links`, `contact`, `social`, `hours`, `newsletter`, `map_embed`

**Files to Create**:
- `resources/views/website/footers/dark.blade.php`
- `resources/views/website/footers/light.blade.php`
- `resources/views/website/footers/accent.blade.php`
- `resources/views/website/footers/transparent.blade.php`

**Files to Modify**:
- `resources/views/website/footer.blade.php` — change to include footer style variant
- `app/Livewire/Website/ThemeEditor.php` — add footer configuration section
- `app/Domain/Website/Models/WebsiteSetting.php` — add columns to $fillable, cast `footer_blocks` as array

---

### UPGRADE 12: Floating Elements & Overlays

**What**: Configurable floating buttons, announcement bar, and popup modals.

**Database Changes**:
```sql
-- Migration: add to website_settings
ALTER TABLE website_settings ADD COLUMN floating_elements JSONB DEFAULT '{}';
ALTER TABLE website_settings ADD COLUMN announcement_bar JSONB DEFAULT '{}';
ALTER TABLE website_settings ADD COLUMN popup_config JSONB DEFAULT '{}';
```

**Floating Elements JSON**:
```json
{
    "whatsapp": {"enabled": true, "number": "+201012345678", "message": "مرحبا، أريد الاستفسار عن..."},
    "scroll_to_top": {"enabled": true, "style": "circle"},
    "custom_button": {"enabled": false, "text": "سجل الآن", "url": "#contact", "color": "#e94560", "icon": "phone"}
}
```

**Announcement Bar JSON**:
```json
{
    "enabled": true,
    "text": "خصم 20% على التسجيل المبكر!",
    "link": "#pricing",
    "bg_color": "#e94560",
    "text_color": "#ffffff",
    "dismissible": true,
    "show_until": "2026-08-01"
}
```

**Popup Config JSON**:
```json
{
    "enabled": false,
    "trigger": "timer",
    "delay_seconds": 5,
    "title": "لا تفوت العرض!",
    "body": "سجل الآن واحصل على خصم...",
    "cta_text": "سجل الآن",
    "cta_link": "#contact",
    "image_path": null,
    "show_once": true
}
```

**Files to Create**:
- `resources/views/website/partials/announcement-bar.blade.php`
- `resources/views/website/partials/popup-modal.blade.php`
- `resources/views/website/partials/floating-elements.blade.php`

**Files to Modify**:
- `resources/views/website/layout.blade.php` — include the 3 partials
- `app/Livewire/Website/ThemeEditor.php` — add sections for floating elements, announcement bar, popup
- `app/Domain/Website/Models/WebsiteSetting.php` — add to $fillable, cast as array
- `resources/js/website.js` — popup trigger logic (timer, scroll %, exit-intent)

---

### UPGRADE 13: Statistics/Counters Section Enhancement

**What**: Allow manual counter values with icons + auto-pull from system data.

**Implementation**: Enhance the existing `stats` section settings JSON.

**Current state**: Stats section already exists and auto-pulls (participants, trainers, branches, programs, activities) from `WebsiteDataService::getStats()`.

**Upgrade**: Allow admin to define custom counters OR override auto values.

**Settings JSON for stats section**:
```json
{
    "mode": "custom",
    "counters": [
        {"icon": "users", "value": 500, "label": "لاعب مسجل", "suffix": "+"},
        {"icon": "trophy", "value": 15, "label": "بطولة", "suffix": ""},
        {"icon": "map-pin", "value": 4, "label": "فرع", "suffix": ""},
        {"icon": "calendar", "value": 8, "label": "سنوات خبرة", "suffix": "+"}
    ],
    "auto_counters": ["participants", "trainers", "branches", "programs"]
}
```

Mode: `auto` (pulls from DB), `custom` (admin enters numbers), `mixed` (some auto + some custom).

**Files to Modify**:
- `app/Livewire/Website/SectionManager.php` — add counter CRUD UI when editing stats section
- `resources/views/livewire/website/section-manager.blade.php` — add counter list with add/remove/edit
- `resources/views/website/sections/stats.blade.php` — render based on mode, support custom icons

**Available Icons** (heroicons solid names): `users`, `trophy`, `map-pin`, `calendar`, `academic-cap`, `heart`, `star`, `bolt`, `clock`, `globe-alt`, `building-office`, `shield-check`

---

### UPGRADE 14: Schedule/Timetable Widget Enhancement

**What**: Replace the raw JSON table with a proper visual timetable that can auto-pull from training group schedules.

**Implementation**: Add auto-pull mode from actual `group_schedules` table.

**Settings JSON for schedule section**:
```json
{
    "mode": "auto",
    "display": "weekly_grid",
    "filter_by_branch": null,
    "show_age_groups": true,
    "color_by": "activity"
}
```

Display modes: `weekly_grid` (calendar-like), `list` (simple table like current), `cards_by_day`

**When mode = "auto"**:
- Query `training_groups` with status='active', join `group_schedules` for day_of_week + start_time + end_time
- Group by day, show activity name + time + trainer + age range
- Respect branch filter if set

**Files to Modify**:
- `app/Domain/Website/Services/WebsiteDataService.php` — add `getScheduleData()` method that queries real group_schedules
- `app/Livewire/Website/SectionManager.php` — add schedule config options
- `resources/views/website/sections/schedule.blade.php` — rewrite with 3 display modes
- `resources/css/website.css` — add timetable grid styles

---

### UPGRADE 15: Pricing Section Enhancement

**What**: Proper CRUD UI for pricing plans (currently raw JSON in settings), toggle period options, connect to real pricing engine data.

**Current state**: Pricing section stores plans in `settings` JSON as a raw JSON string that admin types. No proper form UI.

**Upgrade**: Build a proper plan editor with form fields.

**Settings JSON for pricing section**:
```json
{
    "mode": "manual",
    "show_period_toggle": true,
    "periods": ["monthly", "quarterly", "annual"],
    "plans": [
        {
            "name": "البرنامج الأساسي",
            "prices": {"monthly": 150000, "quarterly": 400000, "annual": 1400000},
            "features": ["3 حصص أسبوعيًا", "زي التمرين", "شهادة إتمام"],
            "highlighted": false,
            "badge": null,
            "cta_text": "اشترك الآن",
            "cta_link": "#contact"
        }
    ]
}
```

Note: prices stored in piasters (integer). Display with `format_money()`.

Mode `auto`: pull from `base_prices` table + `training_programs` and display active program prices.

**Files to Modify**:
- `app/Livewire/Website/SectionManager.php` — build Alpine.js plan editor (add/remove plans, add/remove features, price inputs per period)
- `resources/views/livewire/website/section-manager.blade.php` — plan editor UI
- `resources/views/website/sections/pricing.blade.php` — add period toggle, badge, and proper rendering
- `resources/js/website.js` — period toggle interaction

---

### UPGRADE 16: Trainers/Team Section Enhancement

**What**: Proper team CRUD (currently raw JSON) with photo upload and linking to actual system trainers.

**Current state**: Trainers section stores team in `settings` JSON. No photo upload.

**Upgrade**: Two modes — manual (admin enters) or auto (pull from `employees` table where role = trainer).

**Settings JSON**:
```json
{
    "mode": "auto",
    "max_display": 8,
    "show_bio": true,
    "show_certifications": false,
    "layout": "grid_4",
    "card_style": "hover_reveal"
}
```

Card styles: `simple` (photo + name + role), `hover_reveal` (bio shows on hover), `full_card` (always shows everything)

**When mode = "auto"**:
- Query employees with active trainer_profile, join person for name/photo
- Use team_photo media collection for images
- Show: name, role/specialization, certifications if enabled

**Files to Modify**:
- `app/Domain/Website/Services/WebsiteDataService.php` — add `getTrainersData()` method
- `app/Livewire/Website/SectionManager.php` — add team mode toggle + config
- `resources/views/website/sections/trainers.blade.php` — rewrite with auto/manual modes + card styles

---

### UPGRADE 17: Gallery Section Enhancement

**What**: Filterable gallery with categories, lightbox improvements, video support, and layout options.

**Database Changes**:
```sql
-- Migration: add category to media
ALTER TABLE media ADD COLUMN gallery_category VARCHAR(50);
```

**Implementation**:
- Gallery images get optional `gallery_category` (e.g., "تدريبات", "بطولات", "معسكرات")
- Public view shows filter tabs
- Support video items (YouTube/MP4 URL stored in media alt_text_ar field or a new json metadata column)

**Settings JSON for gallery section**:
```json
{
    "layout": "masonry",
    "show_filters": true,
    "categories": ["تدريبات", "بطولات", "معسكرات", "الفريق"],
    "show_captions": false,
    "items_per_page": 12,
    "lightbox_style": "full"
}
```

Layouts: `masonry`, `grid`, `slider`, `justified`

**Files to Modify**:
- `app/Domain/Website/Models/Media.php` — add `gallery_category` to $fillable
- `app/Livewire/Website/GalleryManager.php` — add category assignment per image, caption editing, video URL field
- `resources/views/livewire/website/gallery-manager.blade.php` — add category dropdown per image
- `resources/views/website/sections/gallery.blade.php` — add filter tabs + layout variants + video support
- `resources/css/website.css` — masonry, justified, slider styles
- `resources/js/website.js` — filter tab click handler, video lightbox

---

### UPGRADE 18: Testimonials Section Enhancement

**What**: Multiple display layouts, video testimonials, avatar upload in admin.

**Current state**: Testimonial model exists with CRUD. Public renders as carousel. Avatar morphOne exists but no upload UI.

**Upgrade**:

**Settings JSON for testimonials section**:
```json
{
    "layout": "carousel",
    "show_rating": true,
    "show_avatar": true,
    "auto_rotate": true,
    "rotate_speed": 5000
}
```

Layouts: `carousel` (current), `grid`, `wall_of_love` (masonry of quotes), `featured_quote` (one big + smaller ones), `video_carousel`

**Database Changes**:
```sql
-- Migration: add video_url to website_testimonials
ALTER TABLE website_testimonials ADD COLUMN video_url VARCHAR(500);
```

**Files to Modify**:
- `app/Domain/Website/Models/WebsiteTestimonial.php` — add `video_url` to $fillable
- `app/Livewire/Website/TestimonialManager.php` — add avatar upload (use MediaService), add video_url field
- `resources/views/livewire/website/testimonial-manager.blade.php` — add avatar upload + video URL input
- `resources/views/website/sections/testimonials.blade.php` — switch layout variants, render video embeds
- `app/Livewire/Website/SectionManager.php` — add testimonial section layout settings

---

### UPGRADE 19: FAQ Section Enhancement

**What**: Categorized FAQs, search within FAQs, multiple visual styles.

**Database Changes**:
```sql
-- Migration: add category to website_faqs
ALTER TABLE website_faqs ADD COLUMN category VARCHAR(100);
ALTER TABLE website_faqs ADD COLUMN category_en VARCHAR(100);
```

**Settings JSON for FAQ section**:
```json
{
    "layout": "accordion",
    "show_categories": true,
    "show_search": true,
    "expand_first": true
}
```

Layouts: `accordion` (current), `two_column`, `tabbed_categories`, `cards`

**Files to Modify**:
- `app/Domain/Website/Models/WebsiteFaq.php` — add `category`, `category_en` to $fillable
- `app/Livewire/Website/FaqManager.php` — add category field
- `resources/views/website/sections/faq.blade.php` — add search input (Alpine.js x-model filter), category tabs, layout variants
- `resources/js/website.js` — FAQ search filtering logic (client-side)

---

### UPGRADE 20: News/Blog Section Enhancement

**What**: Blog detail pages, featured image upload, excerpt display, categories.

**Database Changes**:
```sql
-- Migration: add category to website_news
ALTER TABLE website_news ADD COLUMN category VARCHAR(100);
ALTER TABLE website_news ADD COLUMN category_en VARCHAR(100);
```

**Routes to Add** (in web.php under the public site group):
```php
Route::get('/site/{slug}/news', [PublicWebsiteController::class, 'newsList'])->name('website.news.index');
Route::get('/site/{slug}/news/{newsSlug}', [PublicWebsiteController::class, 'newsShow'])->name('website.news.show');
```

**Files to Create**:
- `resources/views/website/news-list.blade.php` — paginated news listing page
- `resources/views/website/news-show.blade.php` — single article detail page with image, body, related articles

**Files to Modify**:
- `app/Http/Controllers/PublicWebsiteController.php` — add `newsList()` and `newsShow()` methods
- `app/Domain/Website/Models/WebsiteNews.php` — add `category`, `category_en` to $fillable
- `app/Livewire/Website/NewsManager.php` — add featured image upload (use MediaService), category field
- `resources/views/website/sections/news.blade.php` — add "View All" link to news listing page
- `resources/views/website/navbar.blade.php` — add conditional "News" nav link

---

### UPGRADE 21: Contact Section Enhancement

**What**: Multiple form layouts, configurable fields, map embed, branch selector.

**Current state**: Fixed form with name, phone, email, message fields. Alpine.js AJAX submit.

**Upgrade**:

**Settings JSON for contact section**:
```json
{
    "layout": "split",
    "show_map": true,
    "map_embed_url": "https://maps.google.com/maps?q=...",
    "show_branch_selector": true,
    "fields": [
        {"key": "name", "type": "text", "label": "الاسم", "required": true},
        {"key": "phone", "type": "tel", "label": "الهاتف", "required": true},
        {"key": "email", "type": "email", "label": "البريد", "required": false},
        {"key": "sport", "type": "select", "label": "الرياضة", "required": false, "options": ["كرة قدم", "سباحة", "كاراتيه"]},
        {"key": "message", "type": "textarea", "label": "الرسالة", "required": true}
    ],
    "success_message": "شكرًا! سنتواصل معك قريبًا"
}
```

Layouts: `split` (form left + info right, current), `centered` (form only, centered), `full_width` (form + map side by side), `cards` (form in a card with branch cards)

**Files to Modify**:
- `resources/views/website/sections/contact.blade.php` — rewrite with dynamic field rendering, layout switch, map embed
- `app/Livewire/Website/SectionManager.php` — add contact form field builder (add/remove fields, set type/required)
- `app/Http/Controllers/ContactFormController.php` — validate dynamically based on section settings fields config
- `resources/js/website.js` — update AJAX handler to collect dynamic fields

---

### UPGRADE 22: Multi-Page Support

**What**: Allow academies to have multiple pages beyond the single scrolling homepage.

**Database Changes**:
```sql
-- New table: website_pages
CREATE TABLE website_pages (
    id BIGSERIAL PRIMARY KEY,
    uuid UUID UNIQUE NOT NULL,
    academy_id BIGINT NOT NULL REFERENCES academies(id),
    title VARCHAR(255) NOT NULL,
    title_en VARCHAR(255),
    slug VARCHAR(100) NOT NULL,
    page_type VARCHAR(20) NOT NULL DEFAULT 'custom',
    sections JSONB DEFAULT '[]',
    seo_title VARCHAR(255),
    seo_description TEXT,
    og_image_path VARCHAR(500),
    is_in_nav BOOLEAN DEFAULT true,
    nav_order SMALLINT DEFAULT 0,
    is_published BOOLEAN DEFAULT true,
    created_at TIMESTAMP,
    updated_at TIMESTAMP,
    deleted_at TIMESTAMP,
    UNIQUE(academy_id, slug)
);

ALTER TABLE website_pages ADD CONSTRAINT website_pages_page_type_check
    CHECK (page_type IN ('home', 'custom', 'about', 'gallery', 'team', 'contact', 'blank'));
```

**Sections column**: Array of section_key strings that appear on this page. The existing `website_sections` table remains the source of section content — pages just reference which sections to show and in what order.

**For homepage**: `page_type = 'home'`, uses existing section ordering from `website_sections.sort_order`.

**Routes to Add**:
```php
Route::get('/site/{slug}/{pageSlug}', [PublicWebsiteController::class, 'page'])->name('website.page');
```

**Files to Create**:
- `app/Domain/Website/Models/WebsitePage.php`
- `app/Livewire/Website/PageManager.php` — CRUD for pages, section assignment, nav order
- `resources/views/livewire/website/page-manager.blade.php`
- `resources/views/website/page.blade.php` — renders a custom page with its assigned sections

**Files to Modify**:
- `app/Http/Controllers/PublicWebsiteController.php` — add `page()` method
- `resources/views/website/navbar.blade.php` — dynamically render nav links from `website_pages` where `is_in_nav = true`
- `routes/web.php` — add page route

---

### UPGRADE 23: Video Embed Support

**What**: Allow embedding YouTube/Vimeo videos in any section + a dedicated video section.

**Database Changes**:
```sql
-- Add new section_key
-- Migration: update CHECK constraint on website_sections.section_key
ALTER TABLE website_sections DROP CONSTRAINT website_sections_section_key_check;
ALTER TABLE website_sections ADD CONSTRAINT website_sections_section_key_check
    CHECK (section_key IN (
        'hero', 'about', 'activities', 'programs', 'branches', 'schedule',
        'trainers', 'gallery', 'testimonials', 'pricing', 'partners',
        'contact', 'faq', 'cta', 'stats', 'news', 'video'
    ));
```

**Add to SectionKey enum**: `Video` case with label "فيديو" and icon "play-circle".

**Settings JSON for video section**:
```json
{
    "layout": "featured",
    "videos": [
        {"url": "https://youtube.com/watch?v=...", "title": "حفل التكريم", "thumbnail": null},
        {"url": "https://youtube.com/watch?v=...", "title": "ملخص الموسم", "thumbnail": null}
    ],
    "autoplay": false,
    "show_titles": true
}
```

Layouts: `featured` (one big + thumbnails below), `grid` (equal-size grid), `carousel`, `single` (just one video, full-width)

**Helper to extract YouTube/Vimeo embed URL**:
```php
function video_embed_url(string $url): ?string
{
    // YouTube
    if (preg_match('/(?:youtube\.com\/watch\?v=|youtu\.be\/)([\w-]+)/', $url, $m)) {
        return "https://www.youtube.com/embed/{$m[1]}";
    }
    // Vimeo
    if (preg_match('/vimeo\.com\/(\d+)/', $url, $m)) {
        return "https://player.vimeo.com/video/{$m[1]}";
    }
    return null;
}
```

**Files to Create**:
- `resources/views/website/sections/video.blade.php`

**Files to Modify**:
- `app/Domain/Website/Enums/SectionKey.php` — add `Video` case
- `app/Domain/Website/Services/WebsiteSectionService.php` — include video in seedDefaults
- `app/Livewire/Website/SectionManager.php` — add video URL list editor for video section
- Potentially `app/helpers.php` — add `video_embed_url()` helper

---

### UPGRADE 24: Branch Locator with Map

**What**: Interactive branch display with map, directions, and per-branch details.

**Current state**: Branches section exists and pulls from `branches` table (name, address, phone via WebsiteDataService).

**Upgrade**:

**Database Changes**:
```sql
-- Migration: add lat/lng to branches if not exists
ALTER TABLE branches ADD COLUMN IF NOT EXISTS latitude DECIMAL(10, 8);
ALTER TABLE branches ADD COLUMN IF NOT EXISTS longitude DECIMAL(11, 8);
ALTER TABLE branches ADD COLUMN IF NOT EXISTS operating_hours JSONB DEFAULT '{}';
```

**Settings JSON for branches section**:
```json
{
    "layout": "map_and_cards",
    "show_map": true,
    "show_hours": true,
    "show_phone": true,
    "show_directions_link": true,
    "map_zoom": 12,
    "map_style": "default"
}
```

Layouts: `cards` (current), `map_and_cards` (map on one side + card list), `map_fullwidth` (map top + cards below), `list`

**Map Implementation**: Use Leaflet.js (free, no API key) with OpenStreetMap tiles. Markers for each branch with lat/lng.

**Files to Modify**:
- `resources/views/website/sections/branches.blade.php` — add map div + cards layout variant
- `resources/js/website.js` — add Leaflet map initialization (conditionally loaded)
- `resources/views/website/layout.blade.php` — conditionally load Leaflet CSS/JS
- `app/Domain/Website/Services/WebsiteDataService.php` — include lat/lng/hours in branch data

---

### UPGRADE 25: Social Proof & Trust Signals Enhancement

**What**: Upgrade partners section with animated carousel, add achievements/awards display, media mentions.

**Current state**: Partners section shows logo images in a static/animated track.

**Upgrade**:

**Settings JSON for partners section**:
```json
{
    "layout": "auto_scroll",
    "scroll_speed": 30,
    "show_names": false,
    "grayscale_until_hover": true,
    "rows": 1,
    "achievements": [
        {"icon": "trophy", "title": "بطل الجمهورية", "year": "2024"},
        {"icon": "medal", "title": "أفضل أكاديمية", "year": "2023"}
    ],
    "certifications": [
        {"name": "وزارة الشباب والرياضة", "image_path": null}
    ]
}
```

Layouts: `auto_scroll` (infinite horizontal scroll), `grid` (static grid), `carousel` (with arrows), `featured` (one large + others small)

**Files to Modify**:
- `resources/views/website/sections/partners.blade.php` — add grayscale effect, layout variants, achievements subsection
- `resources/css/website.css` — grayscale hover effect, scroll animation speed variable
- `app/Livewire/Website/SectionManager.php` — add achievements CRUD in partners section settings
- `app/Livewire/Website/PartnerManager.php` — ensure logo upload works (currently logo morphOne exists but verify upload UI)

---

### UPGRADE 26: Language Switcher on Public Site

**What**: Add a functional AR/EN language toggle on the public website.

**Current state**: Content is stored bilingually (title + title_en, etc.) but the public site always renders Arabic. The English URL `oc-sport.com/en` comes from their external WordPress — NOT from our system.

**Implementation**:

**Routes**:
```php
Route::get('/site/{slug}', ...); // Default (Arabic)
Route::get('/site/{slug}/en', [PublicWebsiteController::class, 'show'])->name('website.show.en');
```

Or simpler: use query param `?lang=en` and session storage.

**Rendering Logic** (in all section views):
```blade
@php $isEn = app()->getLocale() === 'en'; @endphp
{{ $isEn ? ($section->title_en ?: $section->title) : $section->title }}
```

**Files to Modify**:
- `app/Http/Controllers/PublicWebsiteController.php` — detect locale from route/query/session, set `app()->setLocale()`
- `resources/views/website/navbar.blade.php` — add language toggle button (AR/EN)
- All 16+ section views — use locale-aware field rendering
- `resources/views/website/layout.blade.php` — set `dir` and `lang` based on locale
- `routes/web.php` — add English variant route or middleware-based locale detection

**Language Toggle UI**:
```html
<button onclick="window.location.search = '?lang=' + (currentLang === 'ar' ? 'en' : 'ar')">
    {{ app()->getLocale() === 'ar' ? 'EN' : 'عربي' }}
</button>
```

---

### UPGRADE 27: SEO & Performance Controls

**What**: Per-section SEO controls, auto sitemap, structured data enhancement, image optimization toggle.

**Database Changes**:
```sql
-- Migration: add SEO columns to website_settings
ALTER TABLE website_settings ADD COLUMN seo_keywords TEXT;
ALTER TABLE website_settings ADD COLUMN og_image_path VARCHAR(500);
ALTER TABLE website_settings ADD COLUMN favicon_path VARCHAR(500);
ALTER TABLE website_settings ADD COLUMN structured_data_type VARCHAR(20) DEFAULT 'SportsActivityLocation';
ALTER TABLE website_settings ADD CONSTRAINT website_settings_structured_data_type_check
    CHECK (structured_data_type IN ('SportsActivityLocation', 'SportsClub', 'Organization', 'LocalBusiness'));
```

**Files to Create**:
- `resources/views/website/partials/seo-head.blade.php` — consolidated SEO meta tags partial

**Files to Modify**:
- `app/Livewire/Website/ThemeEditor.php` — add SEO section (OG image upload, keywords, favicon upload, structured data type)
- `resources/views/website/layout.blade.php` — use seo-head partial, favicon, conditional structured data
- `app/Http/Controllers/PublicWebsiteController.php` — add `sitemap()` method that generates XML sitemap
- `routes/web.php` — add `/site/{slug}/sitemap.xml` route

**Auto-sitemap includes**: homepage, news articles (if blog pages exist), event pages.

---

### UPGRADE 28: Mobile-Specific Overrides

**What**: Hide sections on mobile, different content on mobile, responsive preview in admin.

**Database Changes**:
```sql
-- Migration: add to website_sections
ALTER TABLE website_sections ADD COLUMN hidden_on_mobile BOOLEAN DEFAULT false;
ALTER TABLE website_sections ADD COLUMN mobile_sort_order SMALLINT;
```

**Files to Modify**:
- `app/Domain/Website/Models/WebsiteSection.php` — add to $fillable, $casts
- `app/Livewire/Website/SectionManager.php` — add "hide on mobile" toggle, mobile sort order
- `resources/views/website/index.blade.php` — add `class="{{ $section->hidden_on_mobile ? 'hidden md:block' : '' }}"` to section wrapper
- `resources/views/livewire/website/section-manager.blade.php` — add mobile visibility toggle icon per section

**Admin Preview**: Add a device toggle (phone/tablet/desktop) that wraps the preview iframe in a sized container:
```html
<div x-data="{ device: 'desktop' }">
    <button @click="device = 'phone'">📱</button>
    <button @click="device = 'tablet'">📋</button>
    <button @click="device = 'desktop'">🖥️</button>
    <iframe :style="{ width: device === 'phone' ? '375px' : device === 'tablet' ? '768px' : '100%' }"
            src="{{ route('website.preview') }}" class="mx-auto border"></iframe>
</div>
```

---

### UPGRADE 29: Custom Code Injection (Advanced Mode)

**What**: Header/footer code injection for tracking pixels, custom HTML blocks, enhanced custom CSS.

**Database Changes**:
```sql
-- Migration: add to website_settings
ALTER TABLE website_settings ADD COLUMN head_code TEXT;
ALTER TABLE website_settings ADD COLUMN body_start_code TEXT;
ALTER TABLE website_settings ADD COLUMN body_end_code TEXT;
```

**Current state**: `custom_css`, `google_analytics_id`, `facebook_pixel_id` already exist.

**Upgrade**: Add generic code injection areas that replace the specific GA/FB fields (keep those for backward compat but mark as "legacy" in UI).

**Custom HTML Block Section** — add new section_key:
```sql
ALTER TABLE website_sections DROP CONSTRAINT website_sections_section_key_check;
ALTER TABLE website_sections ADD CONSTRAINT website_sections_section_key_check
    CHECK (section_key IN (
        'hero', 'about', 'activities', 'programs', 'branches', 'schedule',
        'trainers', 'gallery', 'testimonials', 'pricing', 'partners',
        'contact', 'faq', 'cta', 'stats', 'news', 'video', 'custom_html'
    ));
```

The `custom_html` section renders its `content` field as raw HTML (admin responsibility for correctness).

**Files to Modify**:
- `app/Domain/Website/Models/WebsiteSetting.php` — add to $fillable
- `app/Livewire/Website/ThemeEditor.php` — add code injection textareas (head_code, body_start_code, body_end_code)
- `resources/views/website/layout.blade.php` — inject: `{!! $settings->head_code !!}` in `<head>`, `{!! $settings->body_start_code !!}` after `<body>`, `{!! $settings->body_end_code !!}` before `</body>`
- `app/Domain/Website/Enums/SectionKey.php` — add `CustomHtml` case
- Create: `resources/views/website/sections/custom_html.blade.php` — `{!! $section->content !!}`

**Security Note**: Only users with `settings.manage` permission can edit these fields. Display a warning: "الكود المخصص يُحقن مباشرة — تأكد من مصدره".

---

### UPGRADE 30: Live Preview (Side-by-Side Editor)

**What**: Replace the current "open preview in new tab" with an inline side-by-side editor that shows changes in real-time.

**Implementation**: Embed an iframe of the public site next to the editor, refresh it on save.

**Files to Create**:
- `app/Livewire/Website/LiveEditor.php` — a combined component that shows section list + theme options on one side and preview iframe on the other
- `resources/views/livewire/website/live-editor.blade.php`

**Route**:
```php
Route::get('/website/editor', \App\Livewire\Website\LiveEditor::class)->name('website.live-editor')
    ->middleware('permission:settings.manage');
```

**Component Logic**:
```php
class LiveEditor extends Component
{
    public string $previewUrl;
    public string $device = 'desktop'; // phone, tablet, desktop

    public function mount(): void
    {
        $this->authorize('settings.manage');
        $academy = app('current_academy');
        $this->previewUrl = route('website.preview');
    }

    public function refreshPreview(): void
    {
        // Dispatch browser event to reload iframe
        $this->dispatch('refresh-preview');
    }
}
```

**View Layout**:
```html
<div class="flex h-screen">
    <!-- Left: Editor Panel (scrollable) -->
    <div class="w-1/3 overflow-y-auto border-e p-4">
        <!-- Section list, theme controls, inline edits -->
        <livewire:website.section-manager :inline="true" />
    </div>
    <!-- Right: Preview -->
    <div class="flex-1 flex flex-col">
        <div class="flex items-center gap-2 p-2 border-b">
            <!-- Device toggles -->
        </div>
        <iframe id="preview-frame" src="{{ $previewUrl }}"
                @refresh-preview.window="$el.src = $el.src"
                class="flex-1 mx-auto border-0"
                :style="{ width: device === 'phone' ? '375px' : device === 'tablet' ? '768px' : '100%' }">
        </iframe>
    </div>
</div>
```

**SectionManager modification**: Add an `$inline` property. When `true`, render a compact version suitable for the side panel (no full page layout). On every save action, dispatch `refresh-preview` event.

---

## Migration Consolidation

All database changes should be in ONE migration file per upgrade phase:

**Phase A Migration** (Upgrades 1-7):
- `database/migrations/2026_07_25_000001_website_builder_v2_theme_and_visuals.php`

**Phase B Migration** (Upgrades 8-14):
- `database/migrations/2026_07_25_000002_website_builder_v2_sections_and_layouts.php`

**Phase C Migration** (Upgrades 15-21):
- `database/migrations/2026_07_25_000003_website_builder_v2_content_enhancements.php`

**Phase D Migration** (Upgrades 22-26):
- `database/migrations/2026_07_25_000004_website_builder_v2_interactive_features.php`

**Phase E Migration** (Upgrades 27-30):
- `database/migrations/2026_07_25_000005_website_builder_v2_pro_features.php`

---

## Build Order (Phases)

| Phase | Upgrades | Description | Est. Effort |
|-------|----------|-------------|-------------|
| A | 1, 2, 3, 5, 6 | Theme engine + typography + spacing + shapes | 2 weeks |
| B | 4, 7, 8, 9, 10, 11 | Backgrounds + animations + hero variants + layouts + navbars + footer | 3 weeks |
| C | 13, 14, 15, 16, 17, 18, 19, 20, 21 | All section content enhancements | 3 weeks |
| D | 12, 22, 23, 24, 25, 26 | Floating elements + multi-page + video + map + social proof + language | 3 weeks |
| E | 27, 28, 29, 30 | SEO + mobile overrides + code injection + live editor | 2 weeks |

---

## Important Rules for Implementation

1. **NEVER break existing sites** — all new columns have defaults. Existing sections render exactly as before until admin changes settings.
2. **CSS variables are the theming backbone** — every visual property that can change must be a CSS variable set in `layout.blade.php`.
3. **Settings JSON is for section-specific config** — don't add DB columns for things that only apply to one section type. Use the existing `settings` JSONB column.
4. **Respect the BelongsToAcademy scope** — all new models/queries must be tenant-scoped.
5. **Cache invalidation** — every save in admin must call `WebsiteCacheService::invalidateAll()`.
6. **No JavaScript frameworks** — Alpine.js only for interactivity. No React/Vue.
7. **Tailwind CSS only** — no Bootstrap, no custom CSS frameworks.
8. **Mobile-first** — all layouts must be responsive. Test at 375px width.
9. **RTL-first** — use logical properties (ms/me/ps/pe), never ml/mr/pl/pr.
10. **Bilingual** — every user-facing string uses `__()`. Every content field has `_en` variant.
11. **Piasters for money** — pricing plans store integers (piasters). Display with `format_money()`.
12. **No external API dependencies** — maps use Leaflet+OSM (free), no Google Maps API key needed.
13. **Image optimization** — all uploaded images should be processed (resize to max 1920px width, compress to 80% quality) via `MediaService`.
14. **Lazy loading** — all images below the fold get `loading="lazy"`.
15. **Existing section partials** — when adding layout variants, keep the existing view as the default. Add new variants as sub-partials, selected by settings.
