# Kutby Footer Engine

**Status:** Architecture reference (Phase 1)  
**Version:** 2.7.0  
**Mirrors:** `HEADER-ENGINE.md` (frozen Header pattern)

**Related:** `ARCHITECTURE.md`, `PERFORMANCE.md`, `DESIGN_SYSTEM.md`, `HEADER-ENGINE.md`

---

## 1. Rendering flow

```
footer.php
  → closes </main>
  → FooterRenderer::render()
       → FooterManager::layout()          // selected id + fallback classic
            → FooterRegistry::make($id)
       → FooterContext::from_request()    // memoized options bag
       → $layout->render($ctx)
            → Component::render($ctx, $args)
       → Dispatcher::emit('footer_rendered')
  → site wrapper close + wp_footer
```

There is **no** `switch ( $layout )` in Renderer or `footer.php`.

| Concern | Owner |
|---------|--------|
| Layout body class `kutby-footer-layout-{id}` | `FooterModule::body_classes` |
| Schema layout labels | `FooterModule::filter_layout_options` |
| Document close / `wp_footer` | `footer.php` |

---

## 2. Responsibilities

| Unit | Does | Must not |
|------|------|----------|
| **FooterRegistry** | Map id → layout class | Read options; echo HTML |
| **FooterManager** | Resolve active layout + fallback | Echo HTML |
| **FooterRenderer** | Orchestrate render + event | Selection trees |
| **FooterContext** | Immutable footer (+ social) options | Render |
| **FooterVisibility** | Admin/save visible field keys | Render |
| **Layouts** | Compose components | Call `Manager::get` / duplicate component HTML |
| **Components** | One visual unit | Know layout id |
| **FooterModule** | Register layouts, schema labels, body class | Layout markup |

---

## 3. How to add a layout

1. Create `inc/Footer/Layouts/YourFooter.php` implementing `FooterLayoutInterface`.
2. Implement `id()`, `label()` (Arabic), `option_keys()`, `render(FooterContext)`.
3. Register:

```php
add_action( 'kutby_footer_register_layouts', function ( \Kutby\Footer\Services\FooterRegistry $r ) {
    $r->add( 'shop', \Kutby\Footer\Layouts\ShopFooter::class );
});
```

4. Add new Schema keys under `footer()` once; list them in `option_keys()`.
5. Add `assets/css/components/footer/layout-your.css` and `@import` from `src/css/main.css` + `assets/css/main.css`.
6. **Do not edit:** `FooterRenderer`, `FooterManager`, `Theme`, `functions.php`.

---

## 4. Component rules

```text
Component::render( FooterContext $ctx, array $args = [] ): void
```

- Visibility from `$ctx` or early return.
- Presentation-only `$args` (`class`, `id`, `depth`).
- No layout id checks inside components.
- Tokens / Utils icons only — no hardcoded hex.

**Production components:** Logo, Navigation, WidgetArea, Newsletter (shell), SocialIcons, Copyright, PaymentIcons (text labels), BackToTop  

---

## 5. Layout rules

| Layout | Composition |
|--------|-------------|
| **Classic** | Top (Logo + Nav) → Widgets → Bottom (Copyright + Social) → BackToTop |
| **Modern** | Top (Logo/Nav + Newsletter) → Widgets → Bottom (Copyright + Social + Payment) → BackToTop |
| **Minimal** | Bottom centered (Copyright + Social) → BackToTop |

Each layout declares `option_keys()`. Always-on Admin key: `layout` (`FooterVisibility::ALWAYS_VISIBLE`).

---

## 6. Theme Options integration

- Group key: `footer` (BC preserved; extended with `layout` + layout-scoped keys).
- Panel: **الفوتر** via `FooterPage`.
- Visibility SSOT: `FooterVisibility` (also used by `Dashboard` save normalization).
- Existing keys kept: `columns`, `copyright`, `show_social`, `back_to_top`.

---

## 7. CSS

| File | Contents |
|------|----------|
| `assets/css/layout/footer.css` | Shared chrome |
| `assets/css/components/footer/layout-*.css` | Per-layout modifiers |

JS: `assets/js/footer.js` (back-to-top + newsletter shell guard).

---

## 8. Registration API

Built-ins registered in `FooterModule::register()`:

- `classic` → `ClassicFooter`
- `modern` → `ModernFooter`
- `minimal` → `MinimalFooter`

Then `do_action( 'kutby_footer_register_layouts', $registry )`.
