# Kutby Header Engine

**Status:** Production reference (maintenance mode)  
**Version:** 2.6.1  
**Audience:** Contributors building Footer, Hero, and other Layout Engines  

This document is the **canonical pattern** for Kutby layout engines. Copy this structure for Footer unless a critical architectural flaw is found.

**Related:** `ARCHITECTURE.md`, `PERFORMANCE.md`, `DESIGN_SYSTEM.md`

---

## 1. Rendering flow

```
header.php
  → HeaderRenderer::render()
       → HeaderManager::layout()          // selected id + fallback classic
            → HeaderRegistry::make($id)
       → HeaderContext::from_request()    // memoized options bag
       → $layout->render($ctx)
            → Component::render($ctx, $args)
       → Dispatcher::emit('header_rendered')
```

**Chrome outside Renderer:**

| Concern | Owner |
|---------|--------|
| Sticky body class `kutby-header-sticky` | `HeaderModule::body_classes` |
| Layout body class `kutby-header-layout-{id}` | `HeaderModule::body_classes` |
| `--kutby-header-height` token | `HeaderModule::filter_css_variables` → Design Tokens |
| Skip link / document shell | `header.php` |

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

---

## 2. Responsibilities

| Unit | Does | Must not |
|------|------|----------|
| **HeaderRegistry** | Map id → layout class; `add` / `make` / `labels` | Read options; echo HTML |
| **HeaderManager** | Resolve active layout + fallback | Echo HTML |
| **HeaderRenderer** | Orchestrate render + event | Business rules / selection trees |
| **HeaderContext** | Immutable header (+ social) options | Render |
| **HeaderVisibility** | Single source for Admin/save field keys | Render |
| **Layouts** | Compose components | Call `Manager::get` / duplicate logo HTML |
| **Components** | One visual unit | Know layout id |
| **HeaderModule** | Register layouts, schema labels, tokens, sticky class | Implement layout markup |

---

## 3. How to add a layout

1. Create `inc/Header/Layouts/YourHeader.php` implementing `HeaderLayoutInterface`.
2. Implement `id()`, `label()` (Arabic Admin), `option_keys()`, `render(HeaderContext)`.
3. Register:

```php
add_action( 'kutby_header_register_layouts', function ( \Kutby\Header\Services\HeaderRegistry $r ) {
    $r->add( 'minimal', \Kutby\Header\Layouts\MinimalHeader::class );
});
```

Or add a built-in in `HeaderModule::register()` if it is a core layout.

4. Add any **new** Theme Options keys under Schema `header()` once.
5. List those keys in `option_keys()` (plus shared keys appear via `HeaderVisibility::ALWAYS_VISIBLE`).
6. Add `assets/css/components/header/layout-your.css` and `@import` it from `src/css/main.css` + `assets/css/main.css`.
7. **Do not edit:** `HeaderRenderer`, `HeaderManager`, `Theme`, `functions.php`, `ModuleManager` (except registering a new core module is N/A).

---

## 4. Component rules

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

- Visibility from `$ctx` (`bool`, `string`) or early return.
- Presentation-only args: `class`, `id`, `position`, `controls`.
- No layout id checks inside components.
- Reuse Design Tokens / Icon helper — no hardcoded hex.
- Incomplete features must be **gated** (`apply_filters( 'kutby_header_experimental_*', false )`) and listed in `HeaderVisibility` experimental denylist — never shown as finished Admin controls.

**Production components:** Logo, Navigation, Search, CTAButton, AnnouncementBar, MobileToggle  

**Experimental (gated, unwired):** ThemeToggle, AccountLink, SocialIcons  

---

## 5. Theme Options integration

- Group key: `header` (BC).
- Panel: **الهيدر** via `HeaderPage`.
- Always visible: `layout`, `sticky` (`HeaderVisibility::ALWAYS_VISIBLE`).
- Layout-scoped: `option_keys()` on the active layout.
- Save path: `Dashboard` uses `HeaderVisibility::visible_keys_from_values()` so hidden toggles are **not** wiped.
- Height: Schema `header.height` → Tokens `--kutby-header-height` only (no inline styles on `<header>`).

---

## 6. CSS rules

| File | Contents |
|------|----------|
| `assets/css/layout/header.css` | Shared chrome, nav, search, announcement, sticky, mobile base |
| `assets/css/components/header/layout-*.css` | Per-layout modifiers only |

Tokens only. Layout files stay isolated; both Vite (`src/css/main.css`) and legacy (`assets/css/main.css`) import them.

---

## 7. Developer notes (Footer template)

When building Footer Engine, mirror:

```
inc/Footer/{Contracts,Components,Layouts,Services,Support}
FooterModule → Registry / Manager / Renderer / Context / Visibility
footer.php → FooterRenderer::render()
```

Same: no switch in Renderer, layout `option_keys()`, experimental gates, module-owned sticky/chrome classes, Tokens for dimensions.

---

## 8. Maintenance mode

Header enters **maintenance mode** after 2.6.1 finalization.

Change only for:

- critical bugs  
- security  
- BC breaks that block Footer patterns  

Do **not** redesign Registry → Manager → Renderer → Layout → Components without a documented architecture exception.
