diff --git a/htdocs/modules/system/themes/modern/docs/DEVELOPER_GUIDE.md b/htdocs/modules/system/themes/modern/docs/DEVELOPER_GUIDE.md
new file mode 100644
index 000000000..c69ca0991
--- /dev/null
+++ b/htdocs/modules/system/themes/modern/docs/DEVELOPER_GUIDE.md
@@ -0,0 +1,1308 @@
+# Modern Admin Theme — Developer & Designer Guide
+
+An in-depth technical reference for designers and developers who want to understand, customize, or extend the Modern admin theme.
+
+## Table of Contents
+
+- [Architecture Overview](#architecture-overview)
+- [File Structure](#file-structure)
+- [Request Lifecycle](#request-lifecycle)
+- [Template System](#template-system)
+- [CSS Architecture](#css-architecture)
+- [JavaScript Architecture](#javascript-architecture)
+- [The Widget System](#the-widget-system)
+- [Data Flow Reference](#data-flow-reference)
+- [Customization Recipes](#customization-recipes)
+- [Creating a New Color Preset](#creating-a-new-color-preset)
+- [Adding a Dashboard Section](#adding-a-dashboard-section)
+- [Adding a Sidebar Section](#adding-a-sidebar-section)
+- [Replacing Emoji Icons with SVG](#replacing-emoji-icons-with-svg)
+- [Adding a New Chart](#adding-a-new-chart)
+- [Modifying the Header](#modifying-the-header)
+- [Adding a New Template Partial](#adding-a-new-template-partial)
+- [Creating Module Widgets](#creating-module-widgets)
+- [Internationalization](#internationalization)
+- [Performance Considerations](#performance-considerations)
+- [Testing](#testing)
+- [Compatibility Notes](#compatibility-notes)
+
+---
+
+## Architecture Overview
+
+The Modern theme is a XOOPS admin GUI theme that extends `XoopsSystemGui`. It consists of:
+
+```mermaid
+block-beta
+ columns 1
+ block:php["PHP Layer — modern.php"]
+ columns 3
+ p1["Extends XoopsSystemGui"]
+ p2["Queries DB for stats, charts, widgets"]
+ p3["Assigns all Smarty template variables"]
+ end
+ block:tpl["Template Layer — theme.tpl + xotpl/*.tpl"]
+ columns 3
+ t1["Smarty 3 with <{ }> delimiters"]
+ t2["Modular partials (head, sidebar, dashboard)"]
+ t3["Data bridge: PHP → JSON → JavaScript"]
+ end
+ block:css["CSS Layer — css/*.css"]
+ columns 3
+ c1["Design tokens via CSS custom properties"]
+ c2["Light mode defaults, dark mode overrides"]
+ c3["fixes.css for XOOPS core !important rules"]
+ end
+ block:js["JavaScript Layer — js/*.js"]
+ columns 3
+ j1["jQuery-based, no build step"]
+ j2["theme.js / charts.js"]
+ j3["customizer.js + cookies"]
+ end
+ block:wid["Widget Layer — class/ + widgets/"]
+ columns 3
+ w1["ModernThemeWidgetInterface contract"]
+ w2["WidgetLoader: auto-discovery + sort"]
+ w3["11 pre-built module widgets"]
+ end
+
+ php --> tpl --> css --> js --> wid
+```
+
+Key design principles:
+- **No build tooling** — Plain CSS, plain JS, no Sass/Webpack/npm required
+- **CSS custom properties** — All colors, spacing, and shadows use `var()` tokens
+- **Progressive enhancement** — Works without JavaScript (charts and customizer degrade gracefully)
+- **Cookie-based persistence** — No database tables, no module configs, no server-side storage
+- **Auto-discovery** — Widgets load automatically from module directories
+
+---
+
+## File Structure
+
+```text
+modern/
+├── modern.php # Theme class (XoopsGuiModern extends XoopsSystemGui)
+├── theme.tpl # Root HTML document template
+├── menu.php # System admin menu builder
+│
+├── class/
+│ ├── ModuleWidgetInterface.php # Widget contract (3 methods)
+│ └── WidgetLoader.php # Widget auto-discovery engine
+│
+├── css/
+│ ├── modern.css # Design tokens + full light-mode styles (~1200 lines)
+│ ├── dark.css # Dark mode variable overrides (~200 lines)
+│ └── fixes.css # !important overrides for XOOPS core CSS (~300 lines)
+│
+├── js/
+│ ├── theme.js # Core: sidebar toggle, dark mode, help, messages
+│ ├── charts.js # Chart.js initialization, dark mode sync, content filter
+│ ├── customizer.js # Settings panel, color presets, cookie management
+│ └── dashboard.js # Table hover, refresh button
+│
+├── xotpl/ # Smarty template partials
+│ ├── xo_metas.tpl #
meta tags + $xoops_module_header
+│ ├── xo_scripts.tpl # Placeholder for inline scripts
+│ ├── xo_head.tpl # Header bar (brand, services, dark mode toggle)
+│ ├── xo_sidebar.tpl # Left sidebar navigation
+│ ├── xo_toolbar.tpl # Placeholder for breadcrumb/toolbar
+│ ├── xo_dashboard.tpl # Dashboard: KPIs, charts, widgets, system info
+│ ├── xo_widgets.tpl # Widget card renderer (iterates $module_widgets)
+│ ├── xo_page.tpl # Module content area + admin links bar
+│ ├── xo_customizer.tpl # Slide-in settings panel + FAB button
+│ └── xo_footer.tpl # Footer bar
+│
+├── language/english/
+│ ├── main.php # ~63 language constants (_MODERN_* prefix)
+│ └── index.php # Security guard
+│
+├── widgets/ # Pre-built widget files (copy to module dirs)
+│ ├── alumni/class/ModernThemeWidget.php
+│ ├── jobs/class/ModernThemeWidget.php
+│ ├── newbb/class/ModernThemeWidget.php
+│ ├── news/class/ModernThemeWidget.php
+│ ├── pedigree/class/ModernThemeWidget.php
+│ ├── protector/class/ModernThemeWidget.php
+│ ├── publisher/class/ModernThemeWidget.php
+│ ├── realestate/class/ModernThemeWidget.php
+│ ├── tdmdownloads/class/ModernThemeWidget.php
+│ ├── vision2026/class/ModernThemeWidget.php
+│ └── xblog/class/ModernThemeWidget.php
+│
+├── icons/ # System service icons (PNG)
+├── images/ # Theme images
+├── docs/ # Documentation
+└── tests/ # Compatibility tests
+```
+
+---
+
+## Request Lifecycle
+
+When an admin page loads, execution flows through:
+
+```mermaid
+flowchart TD
+ A["1. XOOPS Bootstrap
include/common.php"] --> B["2. admin.php dispatches
to active admin GUI"]
+ B --> C["3. XoopsSystemGui loads
modern.php"]
+ C --> D["4. xoops_loadLanguage()
Defines all _MODERN_* constants"]
+ D --> E["5. XoopsGuiModern::header()"]
+
+ E --> E1["parent::header()"]
+ E --> E2["Asset injection
Chart.js, jQuery, CSS/JS"]
+ E --> E3["getSystemInfo()"]
+ E --> E4["getEnhancedStats()"]
+ E --> E5["getUserStats()"]
+ E --> E6["getModuleStats()"]
+ E --> E7["getContentStats()"]
+ E --> E8["loadModuleWidgets()"]
+ E --> E9["ComposerInfo::getComposerInfo()"]
+ E --> E10["buildMenu()"]
+
+ E10 --> F["6. Smarty renders theme.tpl"]
+
+ F --> F1["xo_metas.tpl
‹head› + CSS/JS"]
+ F --> F2["xo_head.tpl
Header bar"]
+ F --> F3["xo_sidebar.tpl
Navigation"]
+ F --> F4["xo_dashboard.tpl
KPIs, charts, widgets"]
+ F4 -.-> F4a["Emits
window.XOOPS_DASHBOARD_DATA"]
+ F --> F5["xo_page.tpl
Module content"]
+ F --> F6["xo_footer.tpl"]
+ F --> F7["xo_customizer.tpl
Settings panel"]
+
+ F7 --> G["7. JavaScript executes"]
+
+ G --> G1["theme.js
Dark mode, sidebar, messages"]
+ G --> G2["dashboard.js
Table interactions"]
+ G --> G3["charts.js
Builds Chart.js instances"]
+ G --> G4["customizer.js
Restores cookie preferences"]
+```
+
+### Component Interaction
+
+The same lifecycle viewed as inter-component communication:
+
+```mermaid
+sequenceDiagram
+ participant Admin as Admin User
+ participant Browser as Browser
+ participant Theme as XoopsGuiModern
+ participant WidgetLoader as ModernThemeWidgetLoader
+ participant Module as Module ModernThemeWidget
+ participant DB as Database
+ participant Chart as Chart.js
+
+ Admin->>Browser: Open admin dashboard
+ Browser->>Theme: Request header()/render
+ Theme->>DB: collect system/user/module/content stats
+ Theme->>WidgetLoader: loadWidgets()
+ WidgetLoader->>DB: enumerate active modules
+ WidgetLoader->>Module: include & instantiate ModernThemeWidget
+ Module->>DB: getWidgetData() queries
+ Module-->>WidgetLoader: widget array or false
+ WidgetLoader->>WidgetLoader: validate, augment (priority, module), sort
+ WidgetLoader-->>Theme: aggregated widgets
+ Theme-->>Browser: render dashboard + window.XOOPS_DASHBOARD_DATA
+ Browser->>Chart: charts.js initializes with data
+ Browser->>Browser: customizer interactions persist cookies
+ Browser->>Chart: call XOOPS_CHARTS.rebuildContentChart(selected)
+ Chart-->>Browser: update chart visuals
+```
+
+---
+
+## Template System
+
+### Smarty Delimiters
+
+XOOPS uses custom Smarty delimiters. **Never** use standard `{` `}` delimiters:
+
+```smarty
+<{$variable}> ← Variable output
+<{$variable|escape:'html'}> ← Escaped output (XSS prevention)
+<{foreach from=$items item=row}> ← Control structure
+<{if $condition}>...<{/if}> ← Conditional
+<{include file="$theme_tpl/xo_head.tpl"}> ← Partial include
+<{$smarty.const._MODERN_LABEL}> ← Language constant
+```
+
+### Template Hierarchy
+
+`theme.tpl` is the root document. It includes all partials via the `$theme_tpl` variable:
+
+```mermaid
+graph TD
+ ROOT["theme.tpl\nRoot HTML document"] --> META["xo_metas.tpl\nmeta tags, CSS, JS links"]
+ ROOT --> HEAD["xo_head.tpl\nFixed header bar"]
+ ROOT --> SIDE["xo_sidebar.tpl\nLeft navigation"]
+ ROOT --> DASH["xo_dashboard.tpl\nKPIs, charts, widgets, sysinfo"]
+ ROOT --> PAGE["xo_page.tpl\nModule content + admin links"]
+ ROOT --> FOOT["xo_footer.tpl\nFooter bar"]
+ ROOT --> CUST["xo_customizer.tpl\nSettings panel + FAB"]
+
+ DASH --> WID["xo_widgets.tpl\nWidget card renderer"]
+ DASH --> SCRIPT["Inline script block\nwindow.XOOPS_DASHBOARD_DATA"]
+
+ HEAD --> SERV["System service icons\nfrom mod_options"]
+ SIDE --> CTRL["Control panel nav\nHome, Dashboard, Logout"]
+ SIDE --> MODS["Module nav\nActive modules list"]
+ SIDE --> SYS["System nav\nSystem services"]
+
+ style ROOT fill:#2563eb,color:#fff
+ style DASH fill:#10b981,color:#fff
+ style HEAD fill:#8b5cf6,color:#fff
+ style SIDE fill:#f59e0b,color:#fff
+```
+
+All partials are included via `<{include file="$theme_tpl/xo_*.tpl"}>`. The `$theme_tpl` variable resolves to the `xotpl/` directory path, making it easy to override individual templates.
+
+### Key Smarty Variables
+
+These variables are assigned by `modern.php` and available in all templates:
+
+| Variable | Type | Source |
+|----------|------|--------|
+| `$xoops_sitename` | string | Site configuration |
+| `$xoops_dirname` | string | Current module dirname |
+| `$dark_mode` | string | Cookie value ('0' or '1') |
+| `$theme_url` | string | URL to theme directory |
+| `$enhanced_stats` | array | User statistics |
+| `$user_chart_data` | JSON string | Registration chart data |
+| `$group_stats` | JSON string | Group distribution data |
+| `$content_stats` | JSON string | Content per module |
+| `$module_widgets` | array | Widget data keyed by dirname |
+| `$control_menu` | array | Control panel nav items |
+| `$module_menu` | array | Module nav items |
+| `$mod_options` | array | Current module admin icons |
+| `$system_services` | array | System admin service icons |
+| `$modules` | array | Module list for dashboard grid |
+| `$composerPackages` | array | Installed Composer packages |
+
+### Adding a Template Partial
+
+1. Create `xotpl/xo_mypartial.tpl`
+1. Include it in `theme.tpl`:
+
+```smarty
+<{include file="$theme_tpl/xo_mypartial.tpl"}>
+```
+
+1. Assign any needed variables in `modern.php`:
+
+```php
+$tpl->assign('my_data', $data);
+```
+
+---
+
+## CSS Architecture
+
+### Design Token System
+
+All visual properties flow from CSS custom properties defined in `:root`. This means changing one variable propagates everywhere:
+
+```css
+:root {
+ /* Layout */
+ --sidebar-width: 260px;
+ --header-height: 64px;
+
+ /* Border Radius */
+ --radius-sm: 4px; /* Badges, small elements */
+ --radius: 8px; /* Cards, inputs, buttons */
+ --radius-lg: 12px; /* Large containers, panels */
+
+ /* Shadows */
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
+
+ /* Brand Colors */
+ --primary: #2563eb; /* Main accent (Blue 600) */
+ --primary-dark: #1e40af; /* Hover/active (Blue 800) */
+ --primary-light: #3b82f6; /* Light accent (Blue 500) */
+ --secondary: #64748b; /* Secondary UI (Slate 500) */
+ --success: #10b981; /* Success states (Emerald 500) */
+ --warning: #f59e0b; /* Warnings (Amber 500) */
+ --danger: #ef4444; /* Errors (Red 500) */
+ --info: #06b6d4; /* Info (Cyan 500) */
+
+ /* Backgrounds */
+ --bg-primary: #f8fafc; /* Page background (Slate 50) */
+ --bg-secondary: #ffffff; /* Cards, sidebar, header */
+ --bg-tertiary: #f1f5f9; /* Hover states, alt rows (Slate 100) */
+
+ /* Text */
+ --text-primary: #0f172a; /* Main text (Slate 900) */
+ --text-secondary: #475569;/* Subdued text (Slate 600) */
+ --text-tertiary: #94a3b8; /* Placeholders (Slate 400) */
+
+ /* Borders */
+ --border: #e2e8f0; /* Standard borders (Slate 200) */
+ --border-light: #f1f5f9; /* Subtle separators (Slate 100) */
+}
+```
+
+### Three-File Strategy
+
+```mermaid
+flowchart LR
+ subgraph Layer1["Layer 1: Design System"]
+ M["modern.css\n~1200 lines\nTokens + all components"]
+ end
+ subgraph Layer2["Layer 2: Dark Mode"]
+ D["dark.css\n~200 lines\nVariable overrides on\nbody.dark-mode"]
+ end
+ subgraph Layer3["Layer 3: Core Fixes"]
+ F["fixes.css\n~300 lines\n!important overrides for\nXOOPS core inline styles"]
+ end
+
+ M --> D --> F
+
+ M -. ":root vars" .-> D
+ D -. "same vars,\ndark values" .-> F
+```
+
+| File | Purpose | Uses `!important`? |
+|------|---------|-------------------|
+| `modern.css` | Design tokens, layout, all components | No |
+| `dark.css` | Dark mode variable overrides on `body.dark-mode` | No |
+| `fixes.css` | Overrides for XOOPS core inline styles | Yes (required) |
+
+**Why `fixes.css` exists:** XOOPS core and some modules inject inline styles and CSS rules that can't be overridden through normal cascade. `fixes.css` uses `!important` surgically on specific selectors to fix these conflicts. It's organized into numbered sections with comments explaining each override.
+
+### Dark Mode
+
+```mermaid
+sequenceDiagram
+ actor User
+ participant TJS as theme.js
+ participant Cookie as Browser Cookie
+ participant Body as document.body
+ participant CSS as dark.css
+ participant Charts as charts.js
+
+ User->>TJS: Click moon/sun icon
+ TJS->>Cookie: setCookie('xoops_dark_mode', '1')
+ TJS->>Body: classList.toggle('dark-mode')
+ Body->>CSS: body.dark-mode selector activates
+ CSS->>CSS: All CSS variables reassigned to dark values
+ Note over CSS: --bg-primary: #0f172a
--text-primary: #f1f5f9
etc.
+ CSS->>Body: Every var() reference updates instantly
+ Body->>Charts: MutationObserver detects class change
+ Charts->>Charts: updateChartsForTheme()
+ Note over Charts: Grid lines, labels, legends
switch to light-on-dark colors
+```
+
+Dark mode is implemented by reassigning all CSS custom properties on the `body.dark-mode` selector in `dark.css`:
+
+```css
+body.dark-mode {
+ --bg-primary: #0f172a; /* Deep navy */
+ --bg-secondary: #1e293b; /* Card backgrounds */
+ --bg-tertiary: #334155; /* Hover states */
+ --text-primary: #f1f5f9; /* Light text */
+ --text-secondary: #cbd5e1;
+ --text-tertiary: #94a3b8;
+ --border: #334155;
+ --border-light: #475569;
+ /* ... shadows, brand colors adjusted for dark */
+}
+```
+
+Because all components use `var()` tokens, dark mode works automatically without per-component overrides.
+
+### Responsive Breakpoints
+
+| Breakpoint | Behavior |
+|------------|----------|
+| `> 1024px` | Full desktop layout. Sidebar visible, collapsible to 80px icon-only mode. |
+| `≤ 1024px` | Sidebar hidden by default, slides in as overlay via `body.sidebar-open`. Footer and main content span full width. |
+| `≤ 768px` | KPIs and charts collapse to single column. Header text shrinks. Customizer panel goes full-width. |
+
+### Sidebar State Machine
+
+```mermaid
+stateDiagram-v2
+ state "Desktop (> 1024px)" as Desktop {
+ [*] --> Expanded
+ Expanded --> Collapsed: Click hamburger icon
+ Collapsed --> Expanded: Click hamburger icon
+ state Expanded {
+ note right of Expanded: 260px wide\nIcons + labels\nmargin-left: 260px
+ }
+ state Collapsed {
+ note right of Collapsed: 80px wide\nIcons only (tooltips)\nmargin-left: 80px
+ }
+ }
+
+ state "Tablet/Mobile (≤ 1024px)" as Mobile {
+ [*] --> Hidden
+ Hidden --> Overlay: Click hamburger icon
+ Overlay --> Hidden: Click outside / hamburger
+ state Hidden {
+ note right of Hidden: Sidebar off-screen\nmargin-left: 0
+ }
+ state Overlay {
+ note right of Overlay: Sidebar slides in\nDim backdrop behind\nbody.sidebar-open
+ }
+ }
+```
+
+### Page Layout Structure
+
+```mermaid
+block-beta
+ columns 5
+
+ block:header:5
+ columns 5
+ hamburger["Hamburger"]
+ brand["Site Name"]
+ icons["Service Icons"]
+ space3:1
+ actions["Dark Mode Toggle"]
+ end
+
+ block:sidebar:1
+ columns 1
+ ctrl["Control Panel\nHome | Dashboard | Logout"]
+ mods["Modules\nPublisher | News | ..."]
+ sys["System\nUsers | Groups | Blocks | ..."]
+ end
+
+ block:main:4
+ columns 1
+ content["Main Content Area\nDashboard or Module Admin"]
+ end
+
+ block:footer:5
+ columns 1
+ foot["Footer: Powered by XOOPS | Execution time"]
+ end
+
+ style header fill:#2563eb,color:#fff
+ style sidebar fill:#1e293b,color:#fff
+ style main fill:#f8fafc,color:#0f172a
+ style footer fill:#f1f5f9,color:#475569
+```
+
+### Key Layout Selectors
+
+```css
+.modern-header { position: fixed; height: var(--header-height); z-index: 1000; }
+.modern-sidebar { width: var(--sidebar-width); position: fixed; z-index: 999; }
+.modern-main { margin-left: var(--sidebar-width); padding-top: var(--header-height); }
+.modern-footer { margin-left: var(--sidebar-width); }
+```
+
+When the sidebar collapses (`body.sidebar-open` on desktop), `--sidebar-width` effectively becomes `80px` through explicit rules that override `margin-left`.
+
+---
+
+## JavaScript Architecture
+
+All JavaScript is ES2015+ (uses `const`, `let`, arrow functions) with jQuery. No build step or transpilation — scripts are loaded directly by the browser. Each file is a self-contained IIFE or plain script.
+
+### Load Order
+
+Scripts are injected by `modern.php` via `$xoTheme->addScript()`:
+
+```mermaid
+flowchart LR
+ subgraph Dependencies["External Dependencies"]
+ JQ["jQuery\nXOOPS core Frameworks"]
+ CJ["Chart.js\nLocal file or CDN fallback"]
+ end
+
+ subgraph Theme["Theme Scripts"]
+ TH["theme.js\nDark mode, sidebar,\nhelp, messages"]
+ DA["dashboard.js\nTable hover,\nrefresh button"]
+ CH["charts.js\nChart.js init,\ndark mode sync"]
+ CU["customizer.js\nSettings panel,\ncookie management"]
+ end
+
+ CJ --> JQ --> TH --> DA --> CH --> CU
+
+ style JQ fill:#f59e0b,color:#fff
+ style CJ fill:#f59e0b,color:#fff
+```
+
+1. `Chart.js` (local via `browse.php` or CDN fallback)
+1. `jQuery` (from XOOPS core Frameworks)
+1. `theme.js` — Core UI behaviors
+1. `dashboard.js` — Table interactions
+1. `charts.js` — Chart initialization
+1. `customizer.js` — Settings panel
+
+### theme.js — Core Behaviors
+
+```text
+initDarkMode() → Reads/writes xoops_dark_mode cookie, toggles body.dark-mode
+initSidebarToggle() → Toggles body.sidebar-open on hamburger click
+initHelpToggle() → Shows/hides .tips and .xo-help-content, persists in cookie
+initMessages() → Moves .errorMsg/.warningMsg to top of .modern-main,
+ auto-dismisses after 5 seconds
+setCookie(name, val, days) → SameSite=Lax, conditional Secure flag
+getCookie(name) → Standard cookie reader
+```
+
+### charts.js — Chart.js Integration
+
+```text
+initCharts() → Entry point, waits for Chart.js to load (500ms retry)
+initUserRegistrationChart() → Line chart from window.XOOPS_DASHBOARD_DATA.userChart
+initUserGroupChart() → Doughnut chart from .groupStats
+initContentChart() → Bar chart from .contentStats (filtered by cookie)
+rebuildContentChart(sel) → Live rebuild when customizer changes module selection
+updateChartsForTheme() → Updates all chart colors for dark/light mode
+```
+
+**PHP → JS data bridge:** `xo_dashboard.tpl` emits a `