<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}" data-theme="{{ request()->cookie('nimuli_theme') ?? auth()->user()?->theme ?? 'dark' }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>{{ ($title ?? '') ? $title . ' — Nimuli' : 'Nimuli' }}</title>

    <!-- Favicon -->
    <link rel="icon" type="image/svg+xml" href="/favicon.svg">
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
    <link rel="manifest" href="/site.webmanifest">
    <meta name="theme-color" content="#0a0a0f" media="(prefers-color-scheme: dark)">
    <meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">

    <!-- Sidebar-init: set collapsed attribute before first paint — eliminates width flash -->
    <script>
        (function () {
            try {
                if (localStorage.getItem('sidebarCollapsed') === 'true') {
                    document.documentElement.dataset.sidebarCollapsed = '1';
                }
            } catch (e) {}
        })();
    </script>

    <!-- Theme-init: runs synchronously before any paint — eliminates FOUC -->
    <script>
        (function () {
            try {
                var saved = localStorage.getItem('nimuli_theme') || '{{ request()->cookie('nimuli_theme') ?? auth()->user()?->theme ?? 'dark' }}';
                var theme = saved === 'system'
                    ? (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
                    : saved;
                document.documentElement.setAttribute('data-theme', theme);
            } catch (e) {}
        })();
    </script>

    <!-- Critical CSS: paint baseline before Vite/Tailwind loads -->
    <style>
        :root {
            --c-bg: #0a0a0f; --c-s1: #111117; --c-s2: #16161e;
            --c-b1: rgba(255,255,255,0.08); --c-accent: #7c3aed;
            --c-t1: #f0f0f5; --c-t2: #b8b8d0;
        }
        [data-theme="light"] {
            --c-bg: #ffffff; --c-s1: #ffffff; --c-s2: #f9fafb;
            --c-b1: #e5e7eb; --c-accent: #7c3aed;
            --c-t1: #111827; --c-t2: #6b7280;
        }
        html { background: var(--c-bg); }
        body {
            margin: 0; padding: 0;
            background: var(--c-bg); color: var(--c-t1);
            font-family: 'Inter', system-ui, -apple-system, sans-serif;
            -webkit-font-smoothing: antialiased;
            opacity: 0;
            transition: opacity 120ms ease-in;
            min-height: 100vh;
        }
        body.app-ready { opacity: 1; }
        /* Skeleton sidebar & topbar */
        .skel-sidebar {
            position: fixed; top: 0; left: 0; bottom: 0;
            width: 240px; background: var(--c-s1);
            border-right: 1px solid var(--c-b1); z-index: 1;
        }
        .skel-topbar {
            position: fixed; top: 0; left: 240px; right: 0;
            height: 57px; background: var(--c-s1);
            border-bottom: 1px solid var(--c-b1); z-index: 1;
        }
        @media (max-width: 768px) {
            .skel-sidebar { display: none; }
            .skel-topbar { left: 0; }
        }
        .app-spinner {
            position: fixed; top: 50%; left: 50%;
            transform: translate(-50%, -50%);
            width: 28px; height: 28px;
            border: 2.5px solid var(--c-b1);
            border-top-color: var(--c-accent);
            border-radius: 50%;
            animation: nim-spin 0.55s linear infinite;
            z-index: 10;
        }
        html[data-sidebar-collapsed] .skel-sidebar { width: 64px; }
        html[data-sidebar-collapsed] .skel-topbar { left: 64px; }
        @media (min-width: 768px) {
            .nim-content { margin-left: 210px; }
            html[data-sidebar-collapsed] .nim-content { margin-left: 55px; }
        }
        body.app-ready .app-spinner,
        body.app-ready .skel-sidebar,
        body.app-ready .skel-topbar { display: none; }
        @keyframes nim-spin { to { transform: translate(-50%, -50%) rotate(360deg); } }
    </style>

    @vite(['resources/js/app.js'])
    @livewireStyles
</head>
<body>
    <!-- Skeleton: visible during JS load -->
    <div class="skel-sidebar" aria-hidden="true"></div>
    <div class="skel-topbar" aria-hidden="true"></div>
    <div class="app-spinner" aria-hidden="true"></div>

    <div class="bg-bg text-t1 font-sans antialiased min-h-screen">
        <!-- Mobile Sidebar Overlay -->
        <div
            class="fixed inset-0 z-30 bg-black/60 md:hidden"
            x-show="$store.sidebar?.mobileOpen"
            x-transition:enter="transition ease-out duration-200"
            x-transition:enter-start="opacity-0"
            x-transition:enter-end="opacity-100"
            x-transition:leave="transition ease-in duration-150"
            x-transition:leave-start="opacity-100"
            x-transition:leave-end="opacity-0"
            @click="$store.sidebar.closeMobile()"
            aria-hidden="true"
            x-cloak
        ></div>

        <!-- Sidebar: persisted across wire:navigate to prevent re-render -->
        @persist('sidebar')
            <x-sidebar />
        @endpersist

        <!-- Main content area: shifts right based on sidebar width -->
        <div
            class="nim-content flex flex-col min-h-screen transition-[margin-left] duration-200 ease-in-out"
            :class="$store.sidebar?.collapsed ? 'md:ml-16' : 'md:ml-60'"
        >
            @persist('topbar')
                <x-topbar :title="$title ?? ''" />
            @endpersist

            <main class="flex-1 overflow-y-auto p-6">
                {{ $slot }}
            </main>
        </div>
    </div>

    @livewire('wire-elements-modal')
    @livewire('components.toaster')
    @livewireScripts

    <script>
        (function () {
            function markReady() { document.body.classList.add('app-ready'); }
            if (document.readyState === 'complete') {
                markReady();
            } else {
                window.addEventListener('load', markReady);
                setTimeout(markReady, 600);
            }
            document.addEventListener('livewire:navigated', markReady);

            // Close mobile sidebar after SPA navigation
            document.addEventListener('livewire:navigated', function () {
                if (window.Alpine && Alpine.store('sidebar')) {
                    Alpine.store('sidebar').closeMobile();
                }
            });

            // Highlight active nav link after SPA navigation
            function updateActiveNav() {
                var path = window.location.pathname;
                document.querySelectorAll('[data-nav-link]').forEach(function (el) {
                    var href = new URL(el.href, location.origin).pathname;
                    var isActive = href && (path === href || (! el.dataset.navExact && path.startsWith(href + '/')));
                    el.classList.toggle('bg-blue/10', isActive);
                    el.classList.toggle('text-blue', isActive);
                    el.classList.toggle('text-t2', !isActive);
                    el.classList.toggle('hover:text-t1', !isActive);
                    el.classList.toggle('hover:bg-s2', !isActive);
                    // Also update icon span — sidebar is persisted so server classes stay stale
                    var icon = el.querySelector('span.flex-shrink-0');
                    if (icon) {
                        icon.classList.toggle('text-blue', isActive);
                        icon.classList.toggle('text-t3', !isActive);
                    }
                });
            }
            document.addEventListener('DOMContentLoaded', updateActiveNav);
            document.addEventListener('livewire:navigated', updateActiveNav);

            // Sync server-saved theme to Alpine store + DOM
            document.addEventListener('livewire:init', function () {
                Livewire.on('theme-changed-server', function (event) {
                    var theme = event.theme ?? (Array.isArray(event) ? event[0]?.theme : null);
                    if (theme && window.Alpine && Alpine.store('theme')) {
                        Alpine.store('theme').apply(theme);
                    }
                });
            });

            // copy-to-clipboard Livewire event
            document.addEventListener('livewire:init', function () {
                Livewire.on('copy-to-clipboard', function (event) {
                    var text = event.text ?? (Array.isArray(event) ? event[0]?.text : null);
                    if (text) {
                        navigator.clipboard.writeText(text).catch(function () {
                            var ta = document.createElement('textarea');
                            ta.value = text;
                            document.body.appendChild(ta);
                            ta.select();
                            document.execCommand('copy');
                            document.body.removeChild(ta);
                        });
                    }
                });
            });
        })();
    </script>
</body>
</html>
