<?php
/**
 * Projet                    : MageStock
 * Logiciel                  : MageStock
 * Rôle du fichier           : Shell principal, navigation, titres, styles et scripts
 * Version générale          : 2.6.123
 * Lot                       : MAGESTOCK FOOTER MAGEKORP IDENTITY CONTACT1
 * Base cumulative requise   : MageStock 2.6.123
 * Date de création          : 2026-02-21
 * Date de modification      : 2026-07-30
 * Dépendances               : config.php, vues, assets CSS/JS, catalogues linguistiques
 * Données persistantes      : aucune directement
 * Permissions requises      : navigation filtrée par permissions effectives
 * Contraintes de sécurité   : encodage HTML, CSRF exposé en méta, chargements locaux contrôlés
 * Compatibilité             : ordinateur, smartphone, tablette, clair et sombre
 * Résumé des modifications  : footer MageKorp unifié, logos officiels, contact public et responsive complet.
 *

 * Fichier  : views/layout.php
 * Auteur   : KREMER Régis
 * Version  : 2.6.123
 * Date     : 2026-07-30
 * Description : Vue — Layout principal (header, nav, scripts globaux)
 *
 * Changelog :
 *   v2.6.123 (2026-07-30) — Footer MageKorp unifié, logos officiels et liens contact sur ordinateur, tablette et smartphone.
 *   v2.6.119 (2026-07-25) — Footer versionné et identité publique harmonisée avec la passerelle MageStock.
 *   v2.1.0 (2026-02-21) — Version initiale auditée et sécurisée
 *   v2.1.1 (2026-02-21) — Corrections sécurité (CSRF, MIME, session, migrateSuppliers)
 *   v2.2.0 (2026-02-21) — Permissions magasins, bons de commande, rapport d'écart,
 *   v2.3.0 (2026-02-26) — Lot 1: menu conditionné par permissions + page Emplacements.
 *                      import CSV, historique prix, bon de livraison multi-lignes
 *   v2.4.0 (2026-07-08) — Chargement de refonte.css (refonte UI/UX). Aucun autre changement.
 *   v2.5.1 (2026-07-08) — Intertitres de section dans le menu (sidebar + slide) comme la maquette.
 *   v2.6.0 (2026-07-08) — Menu regroupé par sections contiguës (corrige les intertitres en double).
 *   v2.6.2 (2026-07-08) — Alignement global maquette : police, header, avatar utilisateur et cache-busting refonte.
 *   v2.6.4 (2026-07-08) — Chargement refonte.css v2.6.4 pour parcours terrain mobile/tablette.
 *   v2.6.6 (2026-07-08) — Manifest PWA, cache-busting v2.6.6 et repli companyName MageStock.
 *   v2.6.7 (2026-07-08) — Cache-busting final de recette.
 *   v2.6.8 (2026-07-08) — Correctif menu replié, modèle d’impression A4, PWA installable et aide push mobile/tablette.
 *   v2.6.10 (2026-07-08) — Injection MageStockRuntime et URLs assets/pages portables APP_BASE_PATH.
 *   v2.6.12 (2026-07-08) — Affichage utilisateur unifié Nom Prénom dans le header et l’accueil.
 *   v2.6.13 (2026-07-08) — Branding global : favicons, liens PWA, icônes installables et aide d’installation.
 *   v2.6.14 (2026-07-08) — Logo entreprise prioritaire dans les zones de marque adaptées.
 *   v2.6.15 (2026-07-08) — Runtime impression enrichi : entreprise, logo, éditeur et trame A4.
 *   v2.6.17 (2026-07-08) — Logo entreprise prioritaire dans le shell et cache print/images corrigé.
 *   v2.6.18 (2026-07-08) — Cache-busting impression/logo et logo entreprise via proxy image.
 *   v2.6.23 (2026-07-08) — Cache-busting trame impression mouvements/BL.
 *   v2.6.24 (2026-07-08) — Cohérence finale : logo menu mobile, cache-busting final et runtime marque.
 *   v2.6.25 (2026-07-09) — PLAN 1 : navigation Plans, titre et chargement du module plans.js.
 *   v2.6.26 (2026-07-09) — PLAN 2 : chargement de plans.css pour l’éditeur visuel SVG.
 *   v2.6.33 (2026-07-09) — PLANS UX2 : titre et activation menu pour la page dédiée d’édition plans-edit.
 *   v2.6.70 (2026-07-11) — I18N CORE LOCALE CURRENCY1 : runtime langue/locale/pays/devise et cache-busting du noyau Intl.
 *   v2.6.73 (2026-07-11) — I18N MODULES SAFE ARCHI1 : shell/navigation par clés explicites, sans balayage DOM global.
 *   v2.6.74 (2026-07-17) — INVENTORY MOBILE FLOW1 : cache CSS responsive inventaire actualisé.
 *   v2.6.78 (2026-07-17) — MOBILE FLOW FOUNDATION2 : chargement du socle mobile commun et dialogues accessibles.
 *   v2.6.79 (2026-07-17) — MOVEMENTS TERRAIN FLOW3 : chargement conditionnel du rendu terrain Mouvements.
 *   v2.6.80 (2026-07-17) — ORDERS MOBILE FLOW4 : chargement conditionnel de l’assistant et des cartes Commandes.
 *   v2.6.81 (2026-07-17) — PRODUCTS MOBILE FLOW5 : chargement conditionnel des cartes et parcours Produits.
 *   v2.6.82 (2026-07-17) — PLANS MOBILE POLICY6 : chargement conditionnel de la politique Plans par appareil.
 *   v2.6.83 (2026-07-20) — BARCODES WIZARD7 : chargement conditionnel de l’assistant Codes-barres.
 *   v2.6.84 (2026-07-20) — ADMIN COMPLEX FORMS8 : chargement conditionnel des interfaces Administration adaptatives.
 *   v2.6.102 (2026-07-21) — Chargement conditionnel des assets LDAP sécurisés.
 *   v2.6.106 (2026-07-21) — Centre de mise à jour, état prioritaire et assets de reprise/rollback.
 *   v2.6.85 (2026-07-20) — REPORTS MOBILE CARDS9 : chargement conditionnel des cartes et graphiques Rapports.
 *   v2.6.86 (2026-07-20) — CRUD MOBILE CARDS10 : chargement conditionnel des cartes CRUD et du gestionnaire magasin.
 *   v2.6.87 (2026-07-20) — MOBILE FULL FIELD RECETTE11 : chargement des finitions tactiles, thème sombre et accessibilité finale.
 *   v2.6.88 (2026-07-20) — SCANNER CORE UNIFICATION1 : chargement cache-busté du noyau scanner unique.
 *   v2.6.90 (2026-07-20) — SCANNER CONSUMERS MIGRATION3 : chargement du composant scanner commun pour tous les parcours.
 *   v2.6.99 (2026-07-20) — Distribution propre : retrait temporaire des chargements `plans-mobile.*` absents du ZIP source.
 *   v2.6.100 (2026-07-20) — PLANS MOBILE POLICY6 restauré : chargement conditionnel des fichiers tactiles reconstruits et contrôlés.
 *   v2.6.109 (2026-07-22) — Navigation et actions administratives alignées sur le droit effectif admin.access.
 *   v2.6.112 (2026-07-22) — Ajout du centre de documentation administrateur.
 *   v2.6.114 (2026-07-22) — URL de secours portable pour Documentation et Licence.
 *   v2.6.113 (2026-07-22) — Navigation et libellé dédiés au rôle Magasinier.
 */
// ================================================================
// MageStock v2.6.100 — LAYOUT DISTRIBUTION + PLANS MOBILE + SCANNER COMMUN
// Desktop: menu gauche conservé
// Tablette: rail icônes via refonte.css
// Mobile: bottom nav + slide menu
// ================================================================
$settings   = getSettings();
$company    = $settings['companyName'] ?? 'MageStock';
$companyLogoUrl = appCompanyLogoUrl($settings);
$appLogoUrl = assetUrl('img/sm.png');
$appPrintLogoUrl = file_exists(APP_ROOT . '/assets/img/magestock-print-logo.jpg') ? assetUrl('img/magestock-print-logo.jpg') : assetUrl('img/sm_logo.png');
$user       = currentUser();
$role       = $user['role'] ?? 'user';
// ────────────────────────────────────────────────────────────────
// Langue UI (cookie > user > fr) — nécessaire car i18n.js prend
// _SM_LANG_PHP comme source de vérité.
// ────────────────────────────────────────────────────────────────
$supportedLangs = appSupportedLanguages();
$lang = appResolveLanguage($user);

$effectiveLocale = appEffectiveLocale($lang, $settings);
$country = appCountry($settings);
$currency = appCurrency($settings);

$isAdminArea = hasAdminAccess($user);
$userName   = appUserDisplayName($user);
$userInitials = appUserInitials($user);

// ── Traductions PHP par clés sémantiques explicites ─────────────
$tr = static fn(string $key, string $fallback = '', array $params = []): string
    => appTranslate($key, $lang, $params, $fallback !== '' ? $fallback : null);

// Helper pour générer les URLs propres
function pageUrl($pageId) {
    $pageId = (string)$pageId;
    // Documentation et Licence doivent rester accessibles même si mod_rewrite
    // ou la prise en compte de .htaccess n'est pas disponible sur l'hébergement.
    if (in_array($pageId, ['license'], true)) {
        return appUrl('index.php') . '?page=' . rawurlencode($pageId);
    }
    return appUrl($pageId);
}

$navDefinitions = [
    ['id'=>'dashboard',    'key'=>'nav.dashboard',    'fallback'=>'Accueil',       'icon'=>'home',      'group'=>'operations'],
    ['id'=>'scanner',      'key'=>'nav.scanner',      'fallback'=>'Scanner',       'icon'=>'scan',      'group'=>'operations'],
    ['id'=>'movements',    'key'=>'nav.movements',    'fallback'=>'Mouvements',    'icon'=>'move',      'group'=>'operations'],
    ['id'=>'products',     'key'=>'nav.products',     'fallback'=>'Produits',      'icon'=>'box',       'group'=>'operations'],
    ['id'=>'kits',         'key'=>'nav.kits',         'fallback'=>'Kits',          'icon'=>'box',       'group'=>'operations'],
    ['id'=>'reservations', 'key'=>'nav.reservations', 'fallback'=>'Réservations',  'icon'=>'check',     'group'=>'operations'],
    ['id'=>'warehouse-manager', 'key'=>'nav.warehouse_manager', 'fallback'=>'Gestion des magasins', 'icon'=>'gear', 'group'=>'organization'],
    ['id'=>'locations',    'key'=>'nav.locations',    'fallback'=>'Emplacements',  'icon'=>'pin',       'group'=>'organization'],
    ['id'=>'plans',        'key'=>'nav.plans',        'fallback'=>'Plans',         'icon'=>'warehouse', 'group'=>'organization'],
    ['id'=>'suppliers',    'key'=>'nav.suppliers',    'fallback'=>'Fournisseurs',  'icon'=>'users',     'group'=>'organization'],
    ['id'=>'brands',       'key'=>'nav.brands',       'fallback'=>'Marques',       'icon'=>'tag',       'group'=>'organization'],
    ['id'=>'orders',       'key'=>'nav.orders',       'fallback'=>'Commandes',     'icon'=>'clipboard', 'group'=>'organization'],
    ['id'=>'inventory',    'key'=>'nav.inventory',    'fallback'=>'Inventaires',   'icon'=>'check',     'group'=>'organization'],
    ['id'=>'alerts',       'key'=>'nav.alerts',       'fallback'=>'Alertes',       'icon'=>'bell',      'group'=>'monitoring'],
    ['id'=>'barcodes',     'key'=>'nav.barcodes',     'fallback'=>'Codes-barres',  'icon'=>'barcode',   'group'=>'monitoring'],
    ['id'=>'reports',      'key'=>'nav.reports',      'fallback'=>'Rapports',      'icon'=>'report',    'group'=>'monitoring'],
    ['id'=>'analytics',    'key'=>'nav.analytics',    'fallback'=>'Pilotage',      'icon'=>'chart',     'group'=>'monitoring'],
    ['id'=>'users',        'key'=>'nav.users',        'fallback'=>'Utilisateurs',  'icon'=>'users',     'group'=>'administration'],
    ['id'=>'settings',     'key'=>'nav.settings',     'fallback'=>'Paramètres',    'icon'=>'gear',      'group'=>'administration'],
    ['id'=>'help',         'key'=>'nav.help',         'fallback'=>'Aides',         'icon'=>'info',      'group'=>'administration'],
];

$navAll = array_map(static function(array $item) use ($lang): array {
    $item['label'] = appTranslate($item['key'], $lang, [], $item['fallback']);
    return $item;
}, $navDefinitions);

if(!$isAdminArea){
    $navAll = array_values(array_filter($navAll, static fn(array $n): bool => in_array($n['id'], ['dashboard','scanner','movements','products','plans'], true)));
} else {
    $navAll = array_values(array_filter($navAll, static function(array $n) use ($navPermissionMap): bool {
        $permission = $navPermissionMap[$n['id']] ?? null;
        return $permission === null || hasPerm($permission);
    }));
}

$sectionLabels = [
    'operations'     => $tr('nav.section.operations', 'Exploitation'),
    'organization'   => $tr('nav.section.organization', 'Organisation'),
    'monitoring'     => $tr('nav.section.monitoring', 'Suivi & pilotage'),
    'administration' => $tr('nav.section.administration', 'Administration'),
];

$groupOrder = ['operations'=>1,'organization'=>2,'monitoring'=>3,'administration'=>4];
usort($navAll, static fn(array $a, array $b): int => (($groupOrder[$a['group']] ?? 9) <=> ($groupOrder[$b['group']] ?? 9)));

$navById = [];
foreach ($navAll as $navItem) $navById[$navItem['id']] = $navItem;
$bottomIds = $isAdminArea
    ? ['dashboard','scanner','products','movements','more']
    : ['dashboard','scanner','products','movements'];
$bottomNav = [];
foreach ($bottomIds as $bottomId) {
    if ($bottomId === 'more') {
        $bottomNav[] = ['id'=>'more','label'=>$tr('nav.more','Plus'),'icon'=>'dots'];
        continue;
    }
    if (isset($navById[$bottomId])) {
        $bottomNav[] = [
            'id'=>$bottomId,
            'label'=>$navById[$bottomId]['label'],
            'icon'=>$navById[$bottomId]['icon'],
        ];
    }
}

$pageTitleKeys = [
    'dashboard'=>'page.dashboard','update'=>'page.update','products'=>'page.products',
    'movements'=>'page.movements','inventory'=>'page.inventory','scanner'=>'page.scanner',
    'barcodes'=>'page.barcodes','reports'=>'page.reports','settings'=>'page.settings',
    'users'=>'page.users','alerts'=>'page.alerts','suppliers'=>'page.suppliers','brands'=>'page.brands',
    'orders'=>'page.orders','locations'=>'page.locations','lots'=>'page.lots','kits'=>'page.kits',
    'reservations'=>'page.reservations','analytics'=>'page.analytics','warehouse-manager'=>'page.warehouse_manager',
    'plans'=>'page.plans','plans-edit'=>'page.plans_edit','help'=>'page.help',
];
$pageTitleFallbacks = [
    'dashboard'=>'Tableau de bord','update'=>'Mises à jour','products'=>'Produits','movements'=>'Mouvements',
    'inventory'=>'Inventaires','scanner'=>'Scanner','barcodes'=>'Codes-barres','reports'=>'Rapports',
    'settings'=>'Paramètres','users'=>'Utilisateurs','alerts'=>'Alertes','suppliers'=>'Fournisseurs',
    'brands'=>'Marques','orders'=>'Bons de commande','locations'=>'Emplacements','lots'=>'Lots','kits'=>'Kits',
    'reservations'=>'Réservations','analytics'=>'Pilotage','warehouse-manager'=>'Gestion des magasins',
    'plans'=>'Plans d’emplacements','plans-edit'=>'Édition d’un plan','help'=>'Aides',
];
$pageTitleKey = $pageTitleKeys[$page] ?? 'page.dashboard';
$pageTitle = $tr($pageTitleKey, $pageTitleFallbacks[$page] ?? 'Page');
$roleLabel = $role === 'admin'
    ? $tr('shell.role.admin','Administrateur')
    : ($role === 'magasinier'
        ? $tr('shell.role.storekeeper','Magasinier')
        : ($isAdminArea ? $tr('shell.role.delegated_admin','Utilisateur — accès administrateur') : $tr('shell.role.user','Utilisateur')));

// Count active alerts for badge
$alertBadge = 0;
if($isAdminArea){
    $alerts   = loadData('alerts');
    $stock    = loadData('stock');
    foreach($alerts as $a){
        foreach($stock as $s){
            if((string)($s['productId']??'')===(string)($a['productId']??'')
            && (string)($s['warehouseId']??'')===(string)($a['warehouseId']??'')){
                $qty = (int)($s['quantity']??0);
                if(($a['type']??'')==='min' && $qty<=(int)($a['threshold']??0)) $alertBadge++;
                if(($a['type']??'')==='max' && $qty>=(int)($a['threshold']??0)) $alertBadge++;
            }
        }
    }
}
?>
<!DOCTYPE html>
<html lang="<?= htmlspecialchars($lang ?? 'fr') ?>" data-theme="<?= htmlspecialchars($theme) ?>" dir="<?= in_array($lang??'fr', ['ar']) ? 'rtl' : 'ltr' ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover">
<meta name="theme-color" content="#0f172a" id="metaThemeColor">
<meta name="application-name" content="MageStock">
<meta name="description" content="<?= htmlspecialchars($tr('shell.meta_description', 'MageStock — gestion de stock multi-magasins, scanner, mouvements, inventaires et alertes.')) ?>">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="MageStock">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="msapplication-TileColor" content="#0f172a">
<meta name="msapplication-TileImage" content="<?= htmlspecialchars(assetUrl('img/icon-180.png')) ?>">
<link rel="manifest" href="<?= htmlspecialchars(appUrl('app.webmanifest?v=2.6.13')) ?>">
<link rel="icon" href="<?= htmlspecialchars(appUrl('favicon.ico?v=2.6.13')) ?>" sizes="any">
<link rel="icon" type="image/svg+xml" href="<?= htmlspecialchars(assetUrl('img/favicon.svg?v=2.6.13')) ?>">
<link rel="icon" type="image/png" sizes="32x32" href="<?= htmlspecialchars(assetUrl('img/favicon-32.png?v=2.6.13')) ?>">
<link rel="icon" type="image/png" sizes="16x16" href="<?= htmlspecialchars(assetUrl('img/favicon-16.png?v=2.6.13')) ?>">
<link rel="apple-touch-icon" sizes="180x180" href="<?= htmlspecialchars(assetUrl('img/apple-touch-icon.png?v=2.6.13')) ?>">
<meta name="csrf-token" content="<?= csrfToken() ?>">
<title><?= htmlspecialchars($pageTitle) ?> — <?= htmlspecialchars($company) ?></title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;600;700&display=swap" rel="stylesheet">

<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/app.css?v=' . filemtime(__DIR__.'/../assets/css/app.css'))) ?>">
<!-- IMPORTANT: styles utilitaires (ex: onglets Rapports, correctifs UI) -->
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/addons.css')) ?>">
<?php if($page === 'update'): ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/update.css?v=' . filemtime(__DIR__.'/../assets/css/update.css'))) ?>">
<?php endif; ?>
<!-- Scroll-to-top (isolé, sans dépendre de app.js / App) -->
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/scrolltop.css')) ?>">
<!-- Harmonisation design v2.3.0 -->
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/enhancements.css')) ?>">
<!-- Page d'aide -->
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/help.css')) ?>">
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/slide-menu.css')) ?>">
<!-- Refonte UI/UX v2.6.2 — DOIT rester en DERNIER (surcharge par cascade). Réversible : retirer cette ligne. -->
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/refonte.css?v=2.6.74')) ?>">
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/print-template.css?v=2.6.24')) ?>">
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/plans.css?v=' . filemtime(__DIR__.'/../assets/css/plans.css'))) ?>">
<?php if(in_array($page, ['plans', 'plans-edit'], true)): ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/plans-mobile.css?v=' . filemtime(__DIR__.'/../assets/css/plans-mobile.css'))) ?>">
<?php endif; ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/mobile-flow.css?v=' . filemtime(__DIR__.'/../assets/css/mobile-flow.css'))) ?>">
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/scanner-consumer.css?v=' . filemtime(__DIR__.'/../assets/css/scanner-consumer.css'))) ?>">
<?php if($page === 'movements'): ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/movements-terrain.css?v=' . filemtime(__DIR__.'/../assets/css/movements-terrain.css'))) ?>">
<?php endif; ?>
<?php if($page === 'orders'): ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/orders-mobile.css?v=' . filemtime(__DIR__.'/../assets/css/orders-mobile.css'))) ?>">
<?php endif; ?>
<?php if($page === 'products'): ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/products-mobile.css?v=' . filemtime(__DIR__.'/../assets/css/products-mobile.css'))) ?>">
<?php endif; ?>
<?php if($page === 'barcodes'): ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/barcodes-mobile.css?v=' . filemtime(__DIR__.'/../assets/css/barcodes-mobile.css'))) ?>">
<?php endif; ?>
<?php if(in_array($page, ['users', 'suppliers', 'settings'], true)): ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/admin-mobile.css?v=' . filemtime(__DIR__.'/../assets/css/admin-mobile.css'))) ?>">
<?php endif; ?>
<?php if(in_array($page, ['users', 'settings'], true)): ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/ldap.css?v=' . filemtime(__DIR__.'/../assets/css/ldap.css'))) ?>">
<?php endif; ?>
<?php if($page === 'reports'): ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/reports-mobile.css?v=' . filemtime(__DIR__.'/../assets/css/reports-mobile.css'))) ?>">
<?php endif; ?>
<?php if(in_array($page, ['kits', 'reservations', 'lots', 'locations', 'warehouse-manager', 'alerts', 'brands'], true)): ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/crud-mobile.css?v=' . filemtime(__DIR__.'/../assets/css/crud-mobile.css'))) ?>">
<?php endif; ?>
<link rel="stylesheet" href="<?= htmlspecialchars(assetUrl('css/mobile-recette.css?v=' . filemtime(__DIR__.'/../assets/css/mobile-recette.css'))) ?>">
</head>
<body>

<div class="app-shell">
    <!-- ═══════════════════════════════════════════════════════════
         SIDEBAR (Desktop only)
         ═══════════════════════════════════════════════════════════ -->
    <aside class="sidebar" id="sidebar">
        <div class="sidebar-header">
            <div class="sidebar-logo<?= $companyLogoUrl ? ' sidebar-logo--with-company-logo' : '' ?>">
                <div class="logo-icon" id="sidebarToggle" role="button" tabindex="0" title="<?= htmlspecialchars($tr('shell.menu.toggle', 'Ouvrir/Fermer le menu')) ?>" aria-label="<?= htmlspecialchars($tr('shell.menu.toggle', 'Ouvrir/Fermer le menu')) ?>"><img src="<?= htmlspecialchars($appLogoUrl) ?>" alt="MageStock" class="logo-img"></div>
                <?php if($companyLogoUrl): ?>
                    <span class="logo-text logo-text--company-logo"><img src="<?= htmlspecialchars($companyLogoUrl) ?>" alt="<?= htmlspecialchars($company) ?>" class="company-wordmark-img"></span>
                <?php else: ?>
                    <span class="logo-text"><?= htmlspecialchars($company) ?></span>
                <?php endif; ?>
            </div>
        </div>

        <nav class="sidebar-nav">
            <?php $__grp=null; foreach($navAll as $n): ?>
            <?php $__g = $n['group'] ?? ''; if($__g !== $__grp): $__grp=$__g; if($__g!==''): ?>
            <div class="sidebar-section"><?= htmlspecialchars($sectionLabels[$__g] ?? '') ?></div>
            <?php endif; endif; ?>
            <a href="<?= pageUrl($n['id']) ?>" class="sidebar-link <?= (($page===$n['id']) || ($page==='plans-edit' && $n['id']==='plans'))?'active':'' ?>" title="<?= htmlspecialchars($n['label']) ?>" data-label="<?= htmlspecialchars($n['label']) ?>">
                <?php if($n['icon'] === 'clipboard'): ?>
                <span class="sidebar-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:100%;height:100%"><path d="M16 4h2a2 2 0 012 2v14a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2h2"/><rect x="8" y="2" width="8" height="4" rx="1" ry="1"/><line x1="9" y1="12" x2="15" y2="12"/><line x1="9" y1="16" x2="13" y2="16"/></svg></span>
                <?php else: ?>
                <span class="sidebar-icon" data-icon="<?= $n['icon'] ?>"></span>
                <?php endif; ?>
                <span class="sidebar-label"><?= htmlspecialchars($n['label']) ?></span>
                <?php if($n['id']==='alerts' && $alertBadge>0): ?>
                    <span class="sidebar-badge"><?= min($alertBadge,99) ?></span>
                <?php endif; ?>
            </a>
            <?php endforeach; ?>
        </nav>

	        <div class="sidebar-footer">
	            <img class="sidebar-footer-logo" src="<?= htmlspecialchars(assetUrl('img/sm_logo.png')) ?>" alt="MageStock">
	        </div>
    </aside>

    <!-- ═══════════════════════════════════════════════════════════
         MAIN AREA
         ═══════════════════════════════════════════════════════════ -->
    <div class="main-area">
        <!-- Top Header -->
        <header class="top-header" id="appHeader">
            <div class="header-left">
                <button class="header-btn mobile-menu-btn" id="btnHamburger" title="<?= htmlspecialchars($tr('shell.menu.open', 'Ouvrir le menu')) ?>" aria-label="<?= htmlspecialchars($tr('shell.menu.open', 'Ouvrir le menu')) ?>">
                    <svg viewBox="0 0 24 24"><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
                </button>
                <h1 class="header-title"><?= htmlspecialchars($pageTitle) ?></h1>
            </div>
            <div class="header-right">
                <!-- Sélecteur de langue -->
                <div class="lang-picker" id="langPicker">
                    <button class="header-btn lang-picker-btn" id="langPickerBtn" title="<?= htmlspecialchars($tr('shell.language', 'Langue / Language')) ?>" aria-label="<?= htmlspecialchars($tr('shell.language', 'Langue / Language')) ?>">
                        <span id="langFlag">🌐</span>
                    </button>
                    <div class="lang-picker-dropdown" id="langPickerDropdown"></div>
                </div>
                <button class="header-btn" id="btnTheme" title="<?= htmlspecialchars($tr('shell.theme.change', 'Changer de thème')) ?>" aria-label="<?= htmlspecialchars($tr('shell.theme.change', 'Changer de thème')) ?>">
                    <svg class="icon-sun" viewBox="0 0 24 24"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
                    <svg class="icon-moon" viewBox="0 0 24 24"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg>
                </button>
                <?php if($isAdminArea && $alertBadge > 0): ?>
                <a href="<?= pageUrl('alerts') ?>" class="header-btn header-alerts" title="<?= htmlspecialchars($tr('shell.alerts', 'Alertes')) ?>" aria-label="<?= htmlspecialchars($tr('shell.alerts', 'Alertes')) ?>">
                    <svg viewBox="0 0 24 24"><path d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 01-3.46 0"/></svg>
                    <span class="header-badge"><?= min($alertBadge,99) ?></span>
                </a>
                <?php endif; ?>
                <!-- Utilisateur (en haut à droite, à côté de la déconnexion) -->
                <div class="header-user" title="<?= htmlspecialchars($userName) ?>">
                    <span class="header-avatar" aria-hidden="true"><?= htmlspecialchars($userInitials) ?></span>
                    <div class="header-user-meta">
                        <div class="header-user-name"><?= htmlspecialchars($userName) ?></div>
                        <div class="header-user-role"><?= htmlspecialchars($roleLabel) ?></div>
                    </div>
                </div>
            
                <a href="<?= htmlspecialchars(appUrl('logout')) ?>" class="header-btn" id="btnLogout" title="<?= htmlspecialchars($tr('shell.logout', 'Déconnexion')) ?>" aria-label="<?= htmlspecialchars($tr('shell.logout', 'Déconnexion')) ?>">
                    <svg viewBox="0 0 24 24"><path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
                </a>
</div>
        </header>

        <!-- Page Content -->
        <main class="main-content" id="appContent">
            <?php require_once APP_ROOT.'/views/'.$page.'.php'; ?>
        </main>

        <!-- Footer MageKorp -->
        <footer class="main-footer" aria-label="MageStock">
            <div class="main-footer__inner">
                <a class="main-footer__brand"
                   href="https://magekorp.com/contact"
                   target="_blank"
                   rel="noopener noreferrer external"
                   aria-label="<?= htmlspecialchars($tr('shell.footer.contact', 'Contacter MageKorp')) ?>">
                    <picture>
                        <source media="(max-width: 640px)" srcset="<?= htmlspecialchars(assetUrl('img/magekorp-mark.png')) ?>">
                        <img src="<?= htmlspecialchars(assetUrl('img/magekorp-logo-horizontal.png')) ?>" alt="MageKorp">
                    </picture>
                </a>

                <div class="main-footer__meta">
                    <span><?= htmlspecialchars($tr('shell.footer.developed_by', 'Développé par')) ?> <strong>Régis KREMER</strong></span>
                    <span class="footer-sep" aria-hidden="true">•</span>
                    <strong>MageStock</strong>
                    <span class="main-footer__version">v<?= htmlspecialchars(APP_VER) ?></span>
                    <span class="footer-sep" aria-hidden="true">•</span>
                    <a href="https://magekorp.com/contact"
                       target="_blank"
                       rel="noopener noreferrer external"
                       class="main-footer__magekorp-link"><?= htmlspecialchars($tr('shell.footer.magekorp_app', 'une application web MageKorp')) ?></a>
                    <span class="footer-sep" aria-hidden="true">•</span>
                    <span>&copy; <?= date('Y') ?></span>
                    <span class="footer-sep" aria-hidden="true">•</span>
                    <a href="<?= htmlspecialchars(pageUrl('license')) ?>" class="footer-license-link"><?= htmlspecialchars($tr('shell.footer.license', 'Licence d’utilisation')) ?></a>
                </div>

                <a class="main-footer__contact"
                   href="https://magekorp.com/contact"
                   target="_blank"
                   rel="noopener noreferrer external">
                    <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 5h16v14H4z"></path><path d="m4 7 8 6 8-6"></path></svg>
                    <span><?= htmlspecialchars($tr('shell.footer.contact', 'Contacter MageKorp')) ?></span>
                </a>
            </div>
        </footer>
    </div>

    <!-- ═══════════════════════════════════════════════════════════
         BOTTOM NAV (Mobile)
         ═══════════════════════════════════════════════════════════ -->
    <nav class="bottom-nav" id="bottomNav">
    <?php foreach($bottomNav as $bn):
        $isMore = ($bn['id']==='more');
        $isActive = (!$isMore && (($page===$bn['id']) || ($page==='plans-edit' && $bn['id']==='plans')));
    ?>
        <button class="bnav-item <?= $isActive?'active':'' ?> <?= $isMore?'bnav-more':'' ?>"
                <?= !$isMore ? 'onclick="location.href=\''.pageUrl($bn['id']).'\'"' : 'id="btnBnavMore"' ?>>
            <?php if($bn['icon'] === 'clipboard'): ?>
        <span class="bnav-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:100%;height:100%"><path d="M16 4h2a2 2 0 012 2v14a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2h2"/><rect x="8" y="2" width="8" height="4" rx="1" ry="1"/><line x1="9" y1="12" x2="15" y2="12"/><line x1="9" y1="16" x2="13" y2="16"/></svg></span>
        <?php else: ?>
        <span class="bnav-icon" data-icon="<?= $bn['icon'] ?>"></span>
        <?php endif; ?>
            <span class="bnav-label"><?= htmlspecialchars($bn['label']) ?></span>
        </button>
    <?php endforeach; ?>
    </nav>

    <!-- ═══════════════════════════════════════════════════════════
         SLIDE MENU (Mobile)
         ═══════════════════════════════════════════════════════════ -->
    <div class="slide-menu-backdrop" id="slideBackdrop"></div>
    <nav class="slide-menu" id="slideMenu">
        <div class="slide-menu-head">
            <div class="slide-menu-brand<?= $companyLogoUrl ? ' slide-menu-brand--with-company-logo' : '' ?>">
                <?php if(file_exists(APP_ROOT.'/assets/img/sm.png')): ?>
                    <img src="<?= htmlspecialchars($appLogoUrl) ?>" alt="MageStock" class="slide-menu-logo">
                <?php else: ?>
                    <div class="slide-menu-logo-ph">M</div>
                <?php endif; ?>
                <?php if($companyLogoUrl): ?>
                    <span class="slide-menu-title slide-menu-title--company-logo"><img src="<?= htmlspecialchars($companyLogoUrl) ?>" alt="<?= htmlspecialchars($company) ?>" class="company-wordmark-img"></span>
                <?php else: ?>
                    <span class="slide-menu-title"><?= htmlspecialchars($company) ?></span>
                <?php endif; ?>
            </div>
            <button class="slide-menu-close" id="btnSlideClose" title="<?= htmlspecialchars($tr('shell.menu.close', 'Fermer le menu')) ?>" aria-label="<?= htmlspecialchars($tr('shell.menu.close', 'Fermer le menu')) ?>">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
            </button>
        </div>
        <div class="slide-menu-body">
        <?php $__sgrp=null; foreach($navAll as $n): ?>
            <?php $__sg = $n['group'] ?? ''; if($__sg !== $__sgrp): $__sgrp=$__sg; if($__sg!==''): ?>
            <div class="slide-section"><?= htmlspecialchars($sectionLabels[$__sg] ?? '') ?></div>
            <?php endif; endif; ?>
            <a href="<?= pageUrl($n['id']) ?>" class="slide-item <?= (($page===$n['id']) || ($page==='plans-edit' && $n['id']==='plans'))?'active':'' ?>">
                <?php if($n['icon'] === 'clipboard'): ?>
                <span class="slide-item-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:100%;height:100%"><path d="M16 4h2a2 2 0 012 2v14a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2h2"/><rect x="8" y="2" width="8" height="4" rx="1" ry="1"/><line x1="9" y1="12" x2="15" y2="12"/><line x1="9" y1="16" x2="13" y2="16"/></svg></span>
                <?php else: ?>
                <span class="slide-item-icon" data-icon="<?= $n['icon'] ?>"></span>
                <?php endif; ?>
                <span><?= htmlspecialchars($n['label']) ?></span>
                <?php if($n['id']==='alerts' && $alertBadge>0): ?>
                    <span class="slide-badge"><?= min($alertBadge,99) ?></span>
                <?php endif; ?>
            </a>
        <?php endforeach; ?>
            <a href="<?= htmlspecialchars(appUrl('logout')) ?>" class="slide-item slide-logout">
                <span class="slide-item-icon" data-icon="logout"></span>
                <span><?= htmlspecialchars($tr('nav.logout', 'Déconnexion')) ?></span>
            </a>
        </div>
    </nav>
</div>

<!-- ═══════════════════════════════════════════════════════════
     MODAL
     ═══════════════════════════════════════════════════════════ -->
<div class="modal-overlay" id="modalOverlay" aria-hidden="true">
    <div class="modal" id="modalBox" role="dialog" aria-modal="true" aria-labelledby="modalTitle" aria-describedby="modalSub" tabindex="-1">
        <div class="modal-hdr">
            <div class="modal-hdr-icon" id="modalIcon"></div>
            <div class="modal-hdr-text">
                <h3 id="modalTitle" tabindex="-1"><?= htmlspecialchars($tr('shell.modal.title', 'Titre')) ?></h3>
                <p id="modalSub"></p>
            </div>
            <button type="button" class="modal-close" id="modalCloseBtn" title="<?= htmlspecialchars($tr('shell.print.close', 'Fermer')) ?>" aria-label="<?= htmlspecialchars($tr('shell.print.close', 'Fermer')) ?>">
                <svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
            </button>
        </div>
        <div class="modal-body" id="modalBody"></div>
        <div class="modal-footer" id="modalFooter"></div>
    </div>
</div>


<!-- ═══════════════════════════════════════════════════════════
     PWA INSTALL PROMPT
     ═══════════════════════════════════════════════════════════ -->
<div class="pwa-install-card" id="pwaInstallCard" hidden role="region" aria-label="<?= htmlspecialchars($tr('shell.pwa.title', 'Installer MageStock')) ?>">
    <div class="pwa-install-mark"><img src="<?= htmlspecialchars(assetUrl('img/icon-192.png')) ?>" alt="" aria-hidden="true"></div>
    <div class="pwa-install-body">
        <strong data-pwa-title><?= htmlspecialchars($tr('shell.pwa.title', 'Installer MageStock')) ?></strong>
        <span data-pwa-text><?= htmlspecialchars($tr('shell.pwa.text', 'Ajoutez MageStock comme application sur cet appareil. Le message s’adapte au navigateur.')) ?></span>
    </div>
    <button class="pwa-install-action" type="button" data-pwa-action><?= htmlspecialchars($tr('shell.pwa.install', 'Installer')) ?></button>
    <button class="pwa-install-close" type="button" data-pwa-close aria-label="<?= htmlspecialchars($tr('shell.pwa.dismiss', 'Masquer')) ?>" title="<?= htmlspecialchars($tr('shell.pwa.dismiss', 'Masquer')) ?>">×</button>
</div>

<!-- Zones d’annonce globales pour les composants mobiles et les erreurs de formulaire -->
<div id="msLiveRegionPolite" class="ms-sr-only" aria-live="polite" aria-atomic="true"></div>
<div id="msLiveRegionAssertive" class="ms-sr-only" aria-live="assertive" aria-atomic="true"></div>

<!-- ═══════════════════════════════════════════════════════════
     TOAST CONTAINER
     ═══════════════════════════════════════════════════════════ -->
<div class="toast-wrap" id="toastWrap"></div>

<!-- ═══════════════════════════════════════════════════════════
     PRINT OVERLAY
     ═══════════════════════════════════════════════════════════ -->
<div class="print-overlay" id="printOverlay" style="display:none">
    <div class="print-hdr">
        <h2 id="printTitle"><?= htmlspecialchars($tr('shell.print.barcodes', 'Codes-barres')) ?></h2>
        <div class="print-hdr-btns">
            <button class="btn btn-primary" onclick="window.print()"><?= htmlspecialchars($tr('shell.print.print', 'Imprimer')) ?></button>
            <button class="btn btn-secondary" id="btnClosePrint"><?= htmlspecialchars($tr('shell.print.close', 'Fermer')) ?></button>
        </div>
    </div>
    <div class="print-grid" id="printGrid"></div>
</div>

<!-- ═══════════════════════════════════════════════════════════
     SCRIPTS
     ═══════════════════════════════════════════════════════════ -->
<script src="<?= htmlspecialchars(appUrl('libs/jsbarcode.all.min.js')) ?>"></script>
<script src="<?= htmlspecialchars(appUrl('libs/qrcode.js')) ?>"></script>
<script src="<?= htmlspecialchars(appUrl('libs/quagga2.min.js')) ?>"></script>
<script src="<?= htmlspecialchars(appUrl('libs/html5-qrcode.min.js')) ?>"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pagination.js')) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/validator.js')) ?>"></script>
<!-- Runtime APP_BASE_PATH injecté AVANT les scripts globaux -->
<script>
window.MageStockRuntime = <?= json_encode([
    'basePath' => appBasePath(),
    'cookiePath' => appCookiePath(),
    'apiBase' => apiUrl(),
    'assetBase' => assetUrl(),
    'appName' => APP_NAME,
    'companyName' => $company,
    'companyLogoUrl' => $companyLogoUrl,
    'appLogoUrl' => $appLogoUrl,
    'appPrintLogoUrl' => $appPrintLogoUrl,
    'currentUserDisplayName' => $userName,
    'language' => $lang,
    'configuredLocale' => $settings['locale'] ?? 'auto',
    'locale' => $effectiveLocale,
    'effectiveLocale' => $effectiveLocale,
    'country' => $country,
    'currency' => $currency,
    'version' => APP_VER,
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?>;
</script>
<!-- Langue PHP injectée AVANT i18n.js — priorité absolue sur localStorage -->
<script>window._SM_LANG_PHP='<?= htmlspecialchars($lang) ?>';window.SM_LANG=window._SM_LANG_PHP;</script>
<script src="<?= htmlspecialchars(assetUrl('js/i18n.js?v=' . filemtime(__DIR__.'/../assets/js/i18n.js'))) ?>"></script>

<script src="<?= htmlspecialchars(assetUrl('js/api.js?v=' . filemtime(__DIR__.'/../assets/js/api.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/utils.js?v=' . filemtime(__DIR__.'/../assets/js/utils.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/table-sort.js?v=2.6.12')) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/scanner/ScannerService.js?v=' . filemtime(__DIR__.'/../assets/js/scanner/ScannerService.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/infinite-scroll.js')) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/print-template.js?v=2.6.24')) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pwa-install.js?v=2.6.24')) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/app.js?v=' . filemtime(__DIR__.'/../assets/js/app.js'))) ?>"></script>

<script src="<?= htmlspecialchars(assetUrl('js/mobile-flow.js?v=' . filemtime(__DIR__.'/../assets/js/mobile-flow.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/scanner/ScannerConsumer.js?v=' . filemtime(__DIR__.'/../assets/js/scanner/ScannerConsumer.js'))) ?>"></script>

<script src="<?= htmlspecialchars(assetUrl('js/pages/dashboard.js?v=' . filemtime(__DIR__.'/../assets/js/pages/dashboard.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pages/products.js?v=' . filemtime(__DIR__.'/../assets/js/pages/products.js'))) ?>"></script>
<?php if($page === 'products'): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/products-mobile.js?v=' . filemtime(__DIR__.'/../assets/js/pages/products-mobile.js'))) ?>"></script>
<?php endif; ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/movements.js?v=' . filemtime(__DIR__.'/../assets/js/pages/movements.js'))) ?>"></script>
<?php if($page === 'movements'): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/movements-terrain.js?v=' . filemtime(__DIR__.'/../assets/js/pages/movements-terrain.js'))) ?>"></script>
<?php endif; ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/inventory.js?v=' . filemtime(__DIR__.'/../assets/js/pages/inventory.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pages/scanner.js?v=' . filemtime(__DIR__.'/../assets/js/pages/scanner.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pages/barcodes.js?v=' . filemtime(__DIR__.'/../assets/js/pages/barcodes.js'))) ?>"></script>
<?php if($page === 'barcodes'): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/barcodes-mobile.js?v=' . filemtime(__DIR__.'/../assets/js/pages/barcodes-mobile.js'))) ?>"></script>
<?php endif; ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/reports.js?v=' . filemtime(__DIR__.'/../assets/js/pages/reports.js'))) ?>"></script>
<?php if($page === 'reports'): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/reports-mobile.js?v=' . filemtime(__DIR__.'/../assets/js/pages/reports-mobile.js'))) ?>"></script>
<?php endif; ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/settings.js?v=' . filemtime(__DIR__.'/../assets/js/pages/settings.js'))) ?>"></script>
<?php if($page === 'update'): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/update.js?v=' . filemtime(__DIR__.'/../assets/js/pages/update.js'))) ?>"></script>
<?php endif; ?>
<?php if($page === 'settings'): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/ldap-settings.js?v=' . filemtime(__DIR__.'/../assets/js/pages/ldap-settings.js'))) ?>"></script>
<?php endif; ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/users.js?v=' . filemtime(__DIR__.'/../assets/js/pages/users.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pages/alerts.js?v=' . filemtime(__DIR__.'/../assets/js/pages/alerts.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pages/suppliers.js?v=' . filemtime(__DIR__.'/../assets/js/pages/suppliers.js'))) ?>"></script>
<?php if(in_array($page, ['users', 'suppliers', 'settings'], true)): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/admin-mobile.js?v=' . filemtime(__DIR__.'/../assets/js/pages/admin-mobile.js'))) ?>"></script>
<?php endif; ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/orders.js?v=' . filemtime(__DIR__.'/../assets/js/pages/orders.js'))) ?>"></script>
<?php if($page === 'orders'): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/orders-mobile.js?v=' . filemtime(__DIR__.'/../assets/js/pages/orders-mobile.js'))) ?>"></script>
<?php endif; ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/brands.js?v=' . filemtime(__DIR__.'/../assets/js/pages/brands.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pages/locations.js?v=' . filemtime(__DIR__.'/../assets/js/pages/locations.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pages/plans.js?v=' . filemtime(__DIR__.'/../assets/js/pages/plans.js'))) ?>"></script>
<?php if(in_array($page, ['plans', 'plans-edit'], true)): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/plans-mobile.js?v=' . filemtime(__DIR__.'/../assets/js/pages/plans-mobile.js'))) ?>"></script>
<?php endif; ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/lots.js?v=' . filemtime(__DIR__.'/../assets/js/pages/lots.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pages/kits.js?v=' . filemtime(__DIR__.'/../assets/js/pages/kits.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/pages/reservations.js?v=' . filemtime(__DIR__.'/../assets/js/pages/reservations.js'))) ?>"></script>
<?php if($page === 'warehouse-manager'): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/warehouse-manager.js?v=' . filemtime(__DIR__.'/../assets/js/pages/warehouse-manager.js'))) ?>"></script>
<?php endif; ?>
<?php if(in_array($page, ['kits', 'reservations', 'lots', 'locations', 'warehouse-manager', 'alerts', 'brands'], true)): ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/crud-mobile.js?v=' . filemtime(__DIR__.'/../assets/js/pages/crud-mobile.js'))) ?>"></script>
<?php endif; ?>
<script src="<?= htmlspecialchars(assetUrl('js/pages/analytics.js?v=' . filemtime(__DIR__.'/../assets/js/pages/analytics.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/mobile-recette.js?v=' . filemtime(__DIR__.'/../assets/js/mobile-recette.js'))) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/push-notifications.js?v=2.6.12')) ?>"></script>
<script src="<?= htmlspecialchars(assetUrl('js/slide-menu.js')) ?>"></script>

<script>
window.SM_PAGE = '<?= $page ?>';
window.SM_ACCOUNT_ROLE = '<?= $role ?>';
window.SM_EFFECTIVE_ADMIN = <?= $isAdminArea ? 'true' : 'false' ?>;
window.SM_ROLE = <?= $isAdminArea ? "'admin'" : "'user'" ?>;
window.USER_ROLE = window.SM_ROLE;
window.CSRF_TOKEN = '<?= csrfToken() ?>';
window.__CSRF_TOKEN__ = window.CSRF_TOKEN;
document.addEventListener('DOMContentLoaded', () => (window._i18nReady ? window._i18nReady.finally(() => App.init()) : App.init()));
</script>

<!-- Scroll-to-top (global, isolé) -->
<div id="scrollTopProgress" aria-label="<?= htmlspecialchars($tr('shell.scroll_top', 'Retour en haut')) ?>">
  <svg viewBox="0 0 60 60">
    <circle class="bg" cx="30" cy="30" r="24"></circle>
    <circle class="progress" cx="30" cy="30" r="24"></circle>
  </svg>
  <div class="arrow">↑</div>
</div>
<script src="<?= htmlspecialchars(assetUrl('js/scrolltop.js')) ?>"></script>
</body>
</html>
