<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Event Management Tracker (Local Storage)</title>
    <!-- Load Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        /* Custom styles for mobile view */
        body {
            /* Ensures space for the fixed nav bar on mobile */
            padding-bottom: 70px; 
            margin: 0;
            min-height: 100vh;
        }
        .data-switch {
            /* Styling for the custom toggle switch */
            box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
            transition: transform 200ms ease;
            padding: 2px;
        }
        .data-switch:checked {
            background-color: #4f46e5; /* indigo-600 */
        }
        .data-switch::before {
            content: '';
            display: block;
            width: 1rem;
            height: 1rem;
            background-color: white;
            border-radius: 9999px;
            transition: transform 200ms ease;
        }
        .data-switch:checked::before {
            transform: translateX(100%);
        }
        /* Ensure the main container is centered and takes up available space */
        .app-wrapper {
            max-width: 480px; /* Mobile width constraint */
            margin-left: auto;
            margin-right: auto;
            /* Give a little padding below the top for message box */
            padding-top: 1rem; 
        }
        /* Style the appearance-none switch for mobile responsiveness */
        .data-switch {
            -webkit-appearance: none;
            -moz-appearance: none;
            appearance: none;
            cursor: pointer;
        }
    </style>
    
    <script>
        // --- IMPORTANT: INITIAL DATA SETUP ---
        // Since we removed the backend, you must paste your CSV data here,
        // converted into a JavaScript Array of Objects (JSON format).
        // Each object MUST have a unique 'id' field.
        const MOCK_PARTICIPANTS = [
            { id: "p1", NAME: "Jane Doe", ROLE: "Model", WALKING_FOR: "Charity A", ARRIVAL: "9:00 AM", ROOM: "R101", NEEDS_GLAM_TRACKING: true, NEEDS_FITTING: true, CHECKED_IN: false, CHECK_IN_TIME: null, HAIR_DONE: false, MAKEUP_DONE: false, FITTING_DONE: false, ISSUED_BY: '', HONORARIUM_ISSUE_TIME: null },
            { id: "p2", NAME: "John Smith", ROLE: "Volunteer", WALKING_FOR: "Operations", ARRIVAL: "8:30 AM", ROOM: "HQ", NEEDS_GLAM_TRACKING: false, NEEDS_FITTING: false, CHECKED_IN: true, CHECK_IN_TIME: new Date().toISOString(), HAIR_DONE: false, MAKEUP_DONE: false, FITTING_DONE: false, ISSUED_BY: 'SH', HONORARIUM_ISSUE_TIME: new Date().toISOString() },
            { id: "p3", NAME: "Sarah Connor", ROLE: "Model", WALKING_FOR: "Charity B", ARRIVAL: "10:00 AM", ROOM: "R102", NEEDS_GLAM_TRACKING: true, NEEDS_FITTING: false, CHECKED_IN: false, CHECK_IN_TIME: null, HAIR_DONE: false, MAKEUP_DONE: false, FITTING_DONE: false, ISSUED_BY: '', HONORARIUM_ISSUE_TIME: null },
            // PASTE YOUR CONVERTED CSV/JSON DATA HERE
        ];
        
        // --- IMPORTANT: LOCAL STORAGE KEYS ---
        const PARTICIPANTS_STORAGE_KEY = 'eventTrackerParticipants';
        const MESSAGES_STORAGE_KEY = 'eventTrackerMessages';
        const STAFF_INITIALS = ["SH", "NC", "JE", "DB", "MT"]; // Staff initials for the Honorarium dropdown

        // --- State management ---
        const state = {
            participants: [],
            messages: [],
            currentParticipant: null,
            currentTab: 'participants' // 'participants' or 'messages'
        };
        let currentParticipantId = null;


        // --- Utility Functions ---

        function showMessage(message, isError = false) {
            const messageBox = document.getElementById('messageBox');
            const messageText = document.getElementById('messageText');
            messageText.textContent = message;
            messageBox.classList.remove('hidden', 'bg-green-100', 'bg-red-100', 'text-green-800', 'text-red-800');
            
            if (isError) {
                messageBox.classList.add('bg-red-100', 'text-red-800');
            } else {
                messageBox.classList.add('bg-green-100', 'text-green-800');
            }
            
            // Auto-hide after 3 seconds
            setTimeout(() => {
                messageBox.classList.add('hidden');
            }, 3000);
        }

        function formatDate(timestamp) {
            if (!timestamp) return 'N/A';
            const date = new Date(timestamp);
            // Check if date is valid
            if (isNaN(date.getTime())) return 'N/A';
            return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
        }

        function getParticipantById(id) {
            return state.participants.find(p => p.id === id);
        }

        function navigateTo(tab) {
            if (tab !== 'participants') {
                 currentParticipantId = null;
            }
            state.currentTab = tab;
            renderApp();
        }

        function navigateToDetail(participantId) {
            currentParticipantId = participantId;
            renderApp();
        }

        // --- Local Storage Data Handlers ---

        function loadInitialData() {
            // Load Participants
            const storedParticipants = localStorage.getItem(PARTICIPANTS_STORAGE_KEY);
            if (storedParticipants) {
                try {
                    state.participants = JSON.parse(storedParticipants);
                    // Ensure dates stored as strings are converted back if needed, but for simplicity, we keep ISO strings
                } catch (e) {
                    console.error("Error parsing stored participants, using mock data.", e);
                    state.participants = MOCK_PARTICIPANTS;
                }
            } else {
                // If no data exists, use the mock data and save it
                state.participants = MOCK_PARTICIPANTS;
                saveParticipants();
            }
            
            // Load Messages
            const storedMessages = localStorage.getItem(MESSAGES_STORAGE_KEY);
            if (storedMessages) {
                 try {
                    state.messages = JSON.parse(storedMessages);
                } catch (e) {
                    console.error("Error parsing stored messages, starting fresh.", e);
                    state.messages = [];
                }
            }
            
            // Sort participants once loaded
            state.participants.sort((a, b) => a.NAME.localeCompare(b.NAME));
        }
        
        function saveParticipants() {
            localStorage.setItem(PARTICIPANTS_STORAGE_KEY, JSON.stringify(state.participants));
        }

        function saveMessages() {
            localStorage.setItem(MESSAGES_STORAGE_KEY, JSON.stringify(state.messages));
        }

        function updateLocalParticipant(data) {
            if (!currentParticipantId) return;
            
            const index = state.participants.findIndex(p => p.id === currentParticipantId);
            if (index !== -1) {
                // Merge new data into the existing participant object
                state.participants[index] = { ...state.participants[index], ...data };
                saveParticipants();
                // Re-render to reflect changes
                renderApp(); 
                showMessage('Update successful!');
            }
        }


        // --- Rendering Functions ---

        function renderApp() {
            // Ensure data is loaded
            if (state.participants.length === 0) {
                 loadInitialData();
            }

            // Render the navigation bar first
            renderNavigation();

            const appContainer = document.getElementById('appContainer');

            if (currentParticipantId) {
                renderDetailView(appContainer);
            } else if (state.currentTab === 'messages') {
                renderMessageBoard(appContainer);
            } else {
                renderListView(appContainer);
            }
            
            // Hide the loading spinner once rendered
            document.getElementById('loading').classList.add('hidden');
            appContainer.classList.remove('hidden');
        }
        
        function renderNavigation() {
            const nav = document.getElementById('navBar');
            nav.innerHTML = `
                <button onclick="navigateTo('participants')" class="flex-1 p-2 text-center transition duration-150 ease-in-out ${state.currentTab === 'participants' ? 'text-indigo-600 border-t-2 border-indigo-600 bg-indigo-50' : 'text-gray-500 hover:bg-gray-100'}">
                    <svg class="w-6 h-6 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20h-5v-2a3 3 0 00-5.356-1.857M9 20H4V6a2 2 0 012-2h4a2 2 0 012 2v14zm0 0l-1.5-1.5M15 15l-1.5-1.5m0 0l-1.5 1.5"></path></svg>
                    <span class="text-xs font-medium">Participants</span>
                </button>
                <button onclick="navigateTo('messages')" class="flex-1 p-2 text-center transition duration-150 ease-in-out ${state.currentTab === 'messages' ? 'text-indigo-600 border-t-2 border-indigo-600 bg-indigo-50' : 'text-gray-500 hover:bg-gray-100'}">
                    <svg class="w-6 h-6 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-4l-4 4v-4z"></path></svg>
                    <span class="text-xs font-medium">Messages</span>
                </button>
            `;
        }


        function renderListView(container) {
            container.innerHTML = `
                <div class="p-4 bg-white shadow-xl rounded-xl space-y-4">
                    <h2 class="text-2xl font-extrabold text-indigo-700">Event Participant List</h2>
                    <input type="text" id="searchBar" placeholder="Search by name, role, or walking for..." class="w-full p-3 border border-gray-300 rounded-xl focus:ring-indigo-500 focus:border-indigo-500 shadow-sm">
                    <div id="participantList" class="space-y-3">
                        ${state.participants.length === 0 ? '<p class="text-center text-gray-500 py-4">No participants loaded. Check the MOCK_PARTICIPANTS data.</p>' : ''}
                        <!-- List items will be injected here -->
                    </div>
                </div>
            `;
            document.getElementById('searchBar').addEventListener('input', filterList);
            updateParticipantList();
        }

        function filterList() {
            const searchTerm = document.getElementById('searchBar').value.toLowerCase();
            const listContainer = document.getElementById('participantList');
            if (!listContainer) return;
            listContainer.innerHTML = '';
            
            // Filter against mandatory fields from the CSV/JSON
            const filtered = state.participants.filter(p => 
                p.NAME.toLowerCase().includes(searchTerm) || 
                p.ROLE.toLowerCase().includes(searchTerm) ||
                p.WALKING_FOR.toLowerCase().includes(searchTerm)
            );

            filtered.forEach(p => {
                listContainer.appendChild(createListItem(p));
            });
        }

        function updateParticipantList() {
            const listContainer = document.getElementById('participantList');
            if (!listContainer) return;
            // Only update if not currently searching (search function calls filterList directly)
            if (document.getElementById('searchBar').value === '') {
                listContainer.innerHTML = '';
                state.participants.forEach(p => {
                    listContainer.appendChild(createListItem(p));
                });
            } else {
                 filterList(); // Re-apply filter if search is active
            }
        }

        function createListItem(participant) {
            const item = document.createElement('div');
            const checkedIn = participant.CHECKED_IN;
            const statusColor = checkedIn ? 'bg-green-100 border-green-500' : 'bg-gray-100 border-gray-300';
            const icon = checkedIn ? '✅' : '⚪';

            item.className = `flex justify-between items-center p-4 border-l-4 rounded-xl shadow-sm cursor-pointer transition duration-150 ease-in-out hover:bg-indigo-50 ${statusColor}`;
            item.innerHTML = `
                <div>
                    <p class="font-semibold text-gray-800">${participant.NAME}</p>
                    <p class="text-sm text-gray-600">${participant.ROLE} / ${participant.WALKING_FOR}</p>
                </div>
                <span class="text-2xl">${icon}</span>
            `;
            item.addEventListener('click', () => navigateToDetail(participant.id));
            return item;
        }

        function renderDetailView(container) {
            state.currentParticipant = getParticipantById(currentParticipantId);
            if (!state.currentParticipant) {
                currentParticipantId = null;
                renderListView(container);
                return;
            }

            const p = state.currentParticipant;
            const isCheckedIn = p.CHECKED_IN;
            // Ensure boolean flags from CSV are handled correctly (true/false)
            const needsGlam = p.NEEDS_GLAM_TRACKING === true || p.NEEDS_GLAM_TRACKING === 'TRUE';
            const needsFitting = p.NEEDS_FITTING === true || p.NEEDS_FITTING === 'TRUE';
            const honorariumIssued = p.ISSUED_BY;
            const honorariumTime = p.HONORARIUM_ISSUE_TIME;

            container.innerHTML = `
                <div class="p-5 bg-white shadow-2xl rounded-xl">
                    <div class="flex justify-between items-start mb-4">
                        <h2 class="text-3xl font-extrabold text-indigo-800">${p.NAME}</h2>
                        <button id="backButton" class="p-2 text-gray-500 hover:text-indigo-600 rounded-full bg-gray-50 transition duration-150 focus:outline-none">
                            <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path></svg>
                        </button>
                    </div>
                    
                    <!-- General Details -->
                    <div class="space-y-2 mb-6 p-4 bg-indigo-50 rounded-lg text-gray-700">
                        <p><strong>Role:</strong> ${p.ROLE}</p>
                        <p><strong>Walking For:</strong> ${p.WALKING_FOR}</p>
                        <p><strong>Arrival:</strong> ${p.ARRIVAL}</p>
                        <p><strong>Room:</strong> ${p.ROOM}</p>
                    </div>

                    <!-- Main Check-In Button -->
                    ${!isCheckedIn ? `
                        <button id="checkInButton" class="w-full py-3 mb-6 font-bold text-white bg-green-600 rounded-xl shadow-lg hover:bg-green-700 transition duration-150 ease-in-out">
                            ✅ Check In Now
                        </button>` : `
                        <div class="p-4 mb-6 font-bold text-center text-green-700 bg-green-200 rounded-xl shadow-inner">
                            Checked In at: ${formatDate(p.CHECK_IN_TIME)}
                        </div>
                    `}

                    <!-- Glam & Fitting Tracking (Conditional Visibility Logic) -->
                    <div class="space-y-4 p-4 bg-gray-50 rounded-xl shadow-inner">
                        <h3 class="text-xl font-bold text-indigo-700 border-b pb-2">Tracking Milestones</h3>
                        ${(needsGlam || needsFitting) ? `
                            ${needsGlam ? createSwitch('Hair Complete', 'HAIR_DONE', p.HAIR_DONE) : ''}
                            ${needsGlam ? createSwitch('Makeup Complete', 'MAKEUP_DONE', p.MAKEUP_DONE) : ''}
                            ${needsFitting ? createSwitch('Fitting Complete', 'FITTING_DONE', p.FITTING_DONE) : ''}
                        ` : '<p class="text-sm text-gray-500">No glam or fitting tracking required.</p>'}
                    </div>

                    <!-- Honorarium Tracking -->
                    <div class="space-y-4 mt-6 p-4 bg-yellow-50 rounded-xl shadow-inner border border-yellow-200">
                        <h3 class="text-xl font-bold text-yellow-700 border-b border-yellow-200 pb-2">Honorarium Payment</h3>
                        
                        <div class="flex flex-col space-y-1">
                            <label for="issuedBy" class="text-sm font-medium text-gray-700">Issued By (Staff Initials)</label>
                            <select id="issuedBy" class="p-3 border border-yellow-300 rounded-lg focus:ring-yellow-500 focus:border-yellow-500 shadow-sm">
                                <option value="" ${!honorariumIssued ? 'selected' : ''}>-- Select Staff --</option>
                                ${STAFF_INITIALS.map(initial => `
                                    <option value="${initial}" ${honorariumIssued === initial ? 'selected' : ''}>${initial}</option>
                                `).join('')}
                            </select>
                        </div>
                        
                        <div id="honorariumTimeDisplay" class="text-sm text-gray-600 p-2 bg-yellow-100 rounded-md">
                            <strong>Issue Time:</strong> ${honorariumTime ? formatDate(honorariumTime) : 'Not Yet Stamped'}
                        </div>

                        <div class="space-y-2">
                            <button id="stampTimeButton" class="w-full py-2 font-semibold text-white bg-yellow-600 rounded-xl shadow-md hover:bg-yellow-700 transition duration-150 ease-in-out ${!honorariumIssued ? 'opacity-50 cursor-not-allowed' : ''}" ${!honorariumIssued ? 'disabled' : ''}>
                                ${honorariumIssued ? 'Update Stamp Time' : 'Select Staff to Stamp Time'}
                            </button>
                            <button id="resetHonorariumButton" class="w-full py-2 font-semibold text-gray-700 border border-gray-300 bg-white rounded-xl shadow-md hover:bg-gray-100 transition duration-150 ease-in-out ${!honorariumIssued ? 'hidden' : ''}">
                                Reset Honorarium Data
                            </button>
                        </div>
                    </div>
                </div>
            `;
            
            // --- Attach Detail View Listeners ---
            document.getElementById('backButton').addEventListener('click', () => {
                currentParticipantId = null;
                renderApp();
            });

            if (!isCheckedIn) {
                document.getElementById('checkInButton').addEventListener('click', handleCheckIn);
            }
            
            if (needsGlam || needsFitting) {
                document.querySelectorAll('.data-switch').forEach(switchEl => {
                    switchEl.addEventListener('change', (e) => handleSwitchToggle(e.target.dataset.field, e.target.checked));
                });
            }

            document.getElementById('issuedBy').addEventListener('change', handleIssuedByChange);

            if (honorariumIssued) {
                document.getElementById('stampTimeButton').addEventListener('click', handleStampTime);
                document.getElementById('resetHonorariumButton').addEventListener('click', handleResetHonorarium);
            }
        }

        function createSwitch(label, field, checked) {
            return `
                <div class="flex items-center justify-between p-3 bg-white rounded-lg shadow-sm border border-gray-200">
                    <label for="${field}" class="text-gray-700 font-medium">${label}</label>
                    <input type="checkbox" id="${field}" data-field="${field}" ${checked ? 'checked' : ''} class="data-switch h-6 w-11 appearance-none rounded-full bg-gray-300 transition duration-200 ease-in-out checked:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2">
                </div>
            `;
        }
        
        function renderMessageBoard(container) {
             container.innerHTML = `
                <div class="p-4 bg-white shadow-xl rounded-xl space-y-4">
                    <h2 class="text-2xl font-extrabold text-indigo-700">Team Message Board</h2>
                    
                    <!-- Message Submission Form -->
                    <div class="p-4 border-b border-gray-200 space-y-3 bg-indigo-50 rounded-lg shadow-inner">
                        <input type="text" id="authorInput" placeholder="Your Name/Initials" value="${localStorage.getItem('messageAuthor') || ''}" class="w-full p-2 border border-gray-300 rounded-lg focus:ring-indigo-500 focus:border-indigo-500 text-sm shadow-sm">
                        <textarea id="messageInput" rows="3" placeholder="Type your message here..." class="w-full p-2 border border-gray-300 rounded-lg focus:ring-indigo-500 focus:border-indigo-500 text-sm shadow-sm"></textarea>
                        <button id="postMessageButton" class="w-full py-2 font-bold text-white bg-indigo-600 rounded-xl shadow-md hover:bg-indigo-700 transition duration-150 ease-in-out">
                            Post Message
                        </button>
                    </div>

                    <!-- Message List -->
                    <div id="messageList" class="space-y-4 pt-2 max-h-[60vh] overflow-y-auto">
                        ${state.messages.length === 0 ? '<p class="text-center text-gray-500 py-4">No messages yet. Be the first!</p>' : ''}
                        ${state.messages.map(m => `
                            <div class="p-3 bg-gray-50 rounded-xl shadow-sm border border-gray-200">
                                <p class="text-gray-800">${m.MESSAGE_TEXT}</p>
                                <p class="mt-1 text-xs text-gray-500 font-semibold">${m.AUTHOR_NAME} - ${formatDate(m.TIMESTAMP)}</p>
                            </div>
                        `).join('')}
                    </div>
                </div>
            `;
            document.getElementById('postMessageButton').addEventListener('click', handleAddMessage);
            document.getElementById('authorInput').addEventListener('change', (e) => {
                localStorage.setItem('messageAuthor', e.target.value);
            });
        }


        // --- Event Handlers (Updates) ---

        function handleAddMessage() {
            const author = document.getElementById('authorInput').value.trim();
            const message = document.getElementById('messageInput').value.trim();

            if (!author || !message) {
                showMessage('Please enter your name and a message.', true);
                return;
            }

            try {
                // Save author name locally
                localStorage.setItem('messageAuthor', author);
                
                const newMessage = {
                    AUTHOR_NAME: author,
                    MESSAGE_TEXT: message,
                    TIMESTAMP: new Date().toISOString()
                };
                
                // Add message to state and save
                state.messages.unshift(newMessage); // Add to the beginning
                saveMessages();
                
                document.getElementById('messageInput').value = ''; // Clear input field
                showMessage('Message posted successfully! (Only visible on this device/browser)');
                renderApp(); // Re-render message board
                
            } catch (error) {
                console.error("Error posting message:", error);
                showMessage('Error posting message: ' + error.message, true);
            }
        }

        // --- Event Handlers (Participant Details) ---

        function handleCheckIn() {
            const data = {
                CHECKED_IN: true,
                CHECK_IN_TIME: new Date().toISOString(), // Store as ISO string
            };
            updateLocalParticipant(data);
        }

        function handleSwitchToggle(field, value) {
            const data = {};
            data[field] = value;
            updateLocalParticipant(data);
        }

        function handleIssuedByChange(event) {
            const value = event.target.value;
            const participant = getParticipantById(currentParticipantId);
            const timestampData = {};
            
            // If staff is assigned and time is NOT set yet, stamp it
            if (value && !participant.HONORARIUM_ISSUE_TIME) {
                timestampData.HONORARIUM_ISSUE_TIME = new Date().toISOString();
                showMessage('Honorarium assigned and time stamped.');
            } else if (!value) {
                // If staff is removed, clear time
                timestampData.HONORARIUM_ISSUE_TIME = null;
            }
            
            updateLocalParticipant({ ISSUED_BY: value, ...timestampData });
            // Re-render to update button state (Stamp/Reset)
            renderApp();
        }

        function handleStampTime() {
            updateLocalParticipant({ HONORARIUM_ISSUE_TIME: new Date().toISOString() });
            showMessage('Honorarium time stamped!');
        }

        function handleResetHonorarium() {
            const data = {
                ISSUED_BY: '', // Clear initials
                HONORARIUM_ISSUE_TIME: null // Clear timestamp
            };
            updateLocalParticipant(data);
            showMessage('Honorarium data reset!');
        }


        // --- Initialization ---

        function initApp() {
            // Load all data from localStorage or mock if non-existent
            loadInitialData();
            // Initial Render
            renderApp();
        }

        // Expose functions globally for HTML event handlers
        window.onload = initApp;
        window.navigateTo = navigateTo;
        window.navigateToDetail = navigateToDetail;
    </script>
</head>
<body class="bg-gray-100 min-h-screen font-sans antialiased">

    <!-- Message Box (Top, Fixed) -->
    <div id="messageBox" class="hidden fixed top-0 left-0 right-0 max-w-md mx-auto p-4 text-center text-sm font-semibold z-50 rounded-b-lg shadow-lg">
        <span id="messageText"></span>
    </div>
    
    <!-- Main Application Container (Centered, Mobile-First) -->
    <div id="appContainer" class="app-wrapper mb-2 hidden">
        <!-- Content will be injected here -->
    </div>
    
    <!-- Loading Spinner -->
    <div id="loading" class="app-wrapper p-8 text-center text-gray-500">
        <svg class="animate-spin h-8 w-8 text-indigo-500 mx-auto" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
            <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
        </svg>
        <p class="mt-3">Loading application...</p>
    </div>
    
    <!-- Fixed Bottom Navigation Bar (Centered) -->
    <nav id="navBar" class="fixed bottom-0 left-0 right-0 max-w-md mx-auto h-16 bg-white border-t border-gray-200 flex shadow-2xl z-40 rounded-t-xl">
        <!-- Navigation Buttons will be injected here -->
    </nav>

</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Event Management Tracker</title>
    <!-- Load Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        /* Custom styles for mobile view */
        body {
            /* Ensures space for the fixed nav bar on mobile */
            padding-bottom: 70px; 
            margin: 0;
        }
        .data-switch {
            /* Styling for the custom toggle switch */
            box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
            transition: transform 200ms ease;
            padding: 2px;
        }
        .data-switch:checked {
            background-color: #4f46e5; /* indigo-600 */
        }
        .data-switch::before {
            content: '';
            display: block;
            width: 1rem;
            height: 1rem;
            background-color: white;
            border-radius: 9999px;
            transition: transform 200ms ease;
        }
        .data-switch:checked::before {
            transform: translateX(100%);
        }
        /* Ensure the main container is centered and takes up available space */
        .app-wrapper {
            max-width: 480px; /* Mobile width constraint */
            margin-left: auto;
            margin-right: auto;
            /* Give a little padding below the top for message box */
            padding-top: 1rem; 
        }
    </style>
    <!-- Load Firebase SDKs -->
    <script type="module">
        import { initializeApp } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-app.js";
        import { getAuth, signInAnonymously, signInWithCustomToken, onAuthStateChanged } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-auth.js";
        import { getFirestore, doc, onSnapshot, collection, query, updateDoc, setLogLevel, addDoc, orderBy, limit } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-firestore.js";

        // Global variables provided by the environment
        const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-event-app';
        const firebaseConfig = JSON.parse(typeof __firebase_config !== 'undefined' ? __firebase_config : '{}');
        const initialAuthToken = typeof __initial_auth_token !== 'undefined' ? __initial_auth_token : null;

        let db, auth, userId = null;
        let unsubscribeParticipants = null;
        let unsubscribeMessages = null;
        let currentParticipantId = null;

        // --- Core Data Model ---
        // Firestore Collection References (Public Data)
        const getParticipantsCollectionRef = () => collection(db, `artifacts/${appId}/public/data/participants`);
        const getMessagesCollectionRef = () => collection(db, `artifacts/${appId}/public/data/messages`);

        // Staff initials for the Honorarium dropdown
        const STAFF_INITIALS = ["SH", "NC", "JE", "DB", "MT"]; // Expanded initials

        // State management
        const state = {
            participants: [],
            messages: [],
            currentParticipant: null,
            currentTab: 'participants' // 'participants' or 'messages'
        };

        // --- Utility Functions ---

        function showMessage(message, isError = false) {
            const messageBox = document.getElementById('messageBox');
            const messageText = document.getElementById('messageText');
            messageText.textContent = message;
            messageBox.classList.remove('hidden', 'bg-green-100', 'bg-red-100', 'text-green-800', 'text-red-800');
            
            if (isError) {
                messageBox.classList.add('bg-red-100', 'text-red-800');
            } else {
                messageBox.classList.add('bg-green-100', 'text-green-800');
            }
            
            // Auto-hide after 3 seconds
            setTimeout(() => {
                messageBox.classList.add('hidden');
            }, 3000);
        }

        function formatDate(timestamp) {
            if (!timestamp) return 'N/A';
            const date = timestamp.toDate ? timestamp.toDate() : new Date(timestamp);
            return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
        }

        function getParticipantById(id) {
            return state.participants.find(p => p.id === id);
        }

        function navigateTo(tab) {
            // Only clear detail view if navigating away from participants tab
            if (tab !== 'participants') {
                 currentParticipantId = null;
            }
            state.currentTab = tab;
            renderApp();
        }

        function navigateToDetail(participantId) {
            currentParticipantId = participantId;
            renderApp();
        }

        // --- Rendering Functions ---

        function renderApp() {
            if (!userId) return; // Wait for authentication
            
            // Render the navigation bar first
            renderNavigation();

            const appContainer = document.getElementById('appContainer');

            if (currentParticipantId) {
                renderDetailView(appContainer);
            } else if (state.currentTab === 'messages') {
                renderMessageBoard(appContainer);
            } else {
                renderListView(appContainer);
            }
        }
        
        function renderNavigation() {
            const nav = document.getElementById('navBar');
            nav.innerHTML = `
                <button onclick="navigateTo('participants')" class="flex-1 p-2 text-center transition duration-150 ease-in-out ${state.currentTab === 'participants' ? 'text-indigo-600 border-t-2 border-indigo-600 bg-indigo-50' : 'text-gray-500 hover:bg-gray-100'}">
                    <svg class="w-6 h-6 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20h-5v-2a3 3 0 00-5.356-1.857M9 20H4V6a2 2 0 012-2h4a2 2 0 012 2v14zm0 0l-1.5-1.5M15 15l-1.5-1.5m0 0l-1.5 1.5"></path></svg>
                    <span class="text-xs font-medium">Participants</span>
                </button>
                <button onclick="navigateTo('messages')" class="flex-1 p-2 text-center transition duration-150 ease-in-out ${state.currentTab === 'messages' ? 'text-indigo-600 border-t-2 border-indigo-600 bg-indigo-50' : 'text-gray-500 hover:bg-gray-100'}">
                    <svg class="w-6 h-6 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-4l-4 4v-4z"></path></svg>
                    <span class="text-xs font-medium">Messages</span>
                </button>
            `;
        }


        function renderListView(container) {
            container.innerHTML = `
                <div class="p-4 bg-white shadow-xl rounded-xl space-y-4">
                    <h2 class="text-2xl font-extrabold text-indigo-700">Event Participant List</h2>
                    <input type="text" id="searchBar" placeholder="Search by name, role, or walking for..." class="w-full p-3 border border-gray-300 rounded-xl focus:ring-indigo-500 focus:border-indigo-500 shadow-sm">
                    <div id="participantList" class="space-y-3">
                        ${state.participants.length === 0 ? '<p class="text-center text-gray-500 py-4">No participants loaded yet. Check your CSV import.</p>' : ''}
                        <!-- List items will be injected here -->
                    </div>
                </div>
            `;
            document.getElementById('searchBar').addEventListener('input', filterList);
            updateParticipantList();
        }

        function filterList() {
            const searchTerm = document.getElementById('searchBar').value.toLowerCase();
            const listContainer = document.getElementById('participantList');
            if (!listContainer) return;
            listContainer.innerHTML = '';
            
            const filtered = state.participants.filter(p => 
                p.NAME.toLowerCase().includes(searchTerm) || 
                p.ROLE.toLowerCase().includes(searchTerm) ||
                p.WALKING_FOR.toLowerCase().includes(searchTerm)
            );

            filtered.forEach(p => {
                listContainer.appendChild(createListItem(p));
            });
        }

        function updateParticipantList() {
            const listContainer = document.getElementById('participantList');
            if (!listContainer) return;
            // Only update if not currently searching (search function calls filterList directly)
            if (document.getElementById('searchBar').value === '') {
                listContainer.innerHTML = '';
                state.participants.forEach(p => {
                    listContainer.appendChild(createListItem(p));
                });
            } else {
                 filterList(); // Re-apply filter if search is active
            }
        }

        function createListItem(participant) {
            const item = document.createElement('div');
            const checkedIn = participant.CHECKED_IN;
            const statusColor = checkedIn ? 'bg-green-100 border-green-500' : 'bg-gray-100 border-gray-300';
            const icon = checkedIn ? '✅' : '⚪';

            item.className = `flex justify-between items-center p-4 border-l-4 rounded-xl shadow-sm cursor-pointer transition duration-150 ease-in-out hover:bg-indigo-50 ${statusColor}`;
            item.innerHTML = `
                <div>
                    <p class="font-semibold text-gray-800">${participant.NAME}</p>
                    <p class="text-sm text-gray-600">${participant.ROLE} / ${participant.WALKING_FOR}</p>
                </div>
                <span class="text-2xl">${icon}</span>
            `;
            item.addEventListener('click', () => navigateToDetail(participant.id));
            return item;
        }

        function renderDetailView(container) {
            state.currentParticipant = getParticipantById(currentParticipantId);
            if (!state.currentParticipant) {
                currentParticipantId = null;
                renderListView(container);
                return;
            }

            const p = state.currentParticipant;
            const isCheckedIn = p.CHECKED_IN;
            const needsGlam = p.NEEDS_GLAM_TRACKING;
            const needsFitting = p.NEEDS_FITTING;
            const honorariumIssued = p.ISSUED_BY;
            const honorariumTime = p.HONORARIUM_ISSUE_TIME;

            container.innerHTML = `
                <div class="p-5 bg-white shadow-2xl rounded-xl">
                    <div class="flex justify-between items-start mb-4">
                        <h2 class="text-3xl font-extrabold text-indigo-800">${p.NAME}</h2>
                        <button id="backButton" class="p-2 text-gray-500 hover:text-indigo-600 rounded-full bg-gray-50 transition duration-150 focus:outline-none">
                            <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path></svg>
                        </button>
                    </div>
                    
                    <!-- General Details -->
                    <div class="space-y-2 mb-6 p-4 bg-indigo-50 rounded-lg text-gray-700">
                        <p><strong>Role:</strong> ${p.ROLE}</p>
                        <p><strong>Walking For:</strong> ${p.WALKING_FOR}</p>
                        <p><strong>Arrival:</strong> ${p.ARRIVAL}</p>
                        <p><strong>Room:</strong> ${p.ROOM}</p>
                    </div>

                    <!-- Main Check-In Button -->
                    ${!isCheckedIn ? `
                        <button id="checkInButton" class="w-full py-3 mb-6 font-bold text-white bg-green-600 rounded-xl shadow-lg hover:bg-green-700 transition duration-150 ease-in-out">
                            ✅ Check In Now
                        </button>` : `
                        <div class="p-4 mb-6 font-bold text-center text-green-700 bg-green-200 rounded-xl shadow-inner">
                            Checked In at: ${formatDate(p.CHECK_IN_TIME)}
                        </div>
                    `}

                    <!-- Glam & Fitting Tracking (Conditional Visibility Logic) -->
                    <div class="space-y-4 p-4 bg-gray-50 rounded-xl shadow-inner">
                        <h3 class="text-xl font-bold text-indigo-700 border-b pb-2">Tracking Milestones</h3>
                        ${(needsGlam || needsFitting) ? `
                            ${needsGlam ? createSwitch('Hair Complete', 'HAIR_DONE', p.HAIR_DONE) : ''}
                            ${needsGlam ? createSwitch('Makeup Complete', 'MAKEUP_DONE', p.MAKEUP_DONE) : ''}
                            ${needsFitting ? createSwitch('Fitting Complete', 'FITTING_DONE', p.FITTING_DONE) : ''}
                        ` : '<p class="text-sm text-gray-500">No glam or fitting tracking required.</p>'}
                    </div>

                    <!-- Honorarium Tracking -->
                    <div class="space-y-4 mt-6 p-4 bg-yellow-50 rounded-xl shadow-inner border border-yellow-200">
                        <h3 class="text-xl font-bold text-yellow-700 border-b border-yellow-200 pb-2">Honorarium Payment</h3>
                        
                        <div class="flex flex-col space-y-1">
                            <label for="issuedBy" class="text-sm font-medium text-gray-700">Issued By (Staff Initials)</label>
                            <select id="issuedBy" class="p-3 border border-yellow-300 rounded-lg focus:ring-yellow-500 focus:border-yellow-500 shadow-sm">
                                <option value="" ${!honorariumIssued ? 'selected' : ''}>-- Select Staff --</option>
                                ${STAFF_INITIALS.map(initial => `
                                    <option value="${initial}" ${honorariumIssued === initial ? 'selected' : ''}>${initial}</option>
                                `).join('')}
                            </select>
                        </div>
                        
                        <div id="honorariumTimeDisplay" class="text-sm text-gray-600 p-2 bg-yellow-100 rounded-md">
                            <strong>Issue Time:</strong> ${honorariumTime ? formatDate(honorariumTime) : 'Not Yet Stamped'}
                        </div>

                        <div class="space-y-2">
                            ${honorariumIssued ? `
                                <button id="stampTimeButton" class="w-full py-2 font-semibold text-white bg-yellow-600 rounded-xl shadow-md hover:bg-yellow-700 transition duration-150 ease-in-out">
                                    Update Stamp Time
                                </button>
                                <button id="resetHonorariumButton" class="w-full py-2 font-semibold text-gray-700 border border-gray-300 bg-white rounded-xl shadow-md hover:bg-gray-100 transition duration-150 ease-in-out">
                                    Reset Honorarium Data
                                </button>
                            ` : ''}
                        </div>
                    </div>
                </div>
            `;
            
            // --- Attach Detail View Listeners ---
            document.getElementById('backButton').addEventListener('click', () => {
                currentParticipantId = null;
                renderListView(container);
            });

            if (!isCheckedIn) {
                document.getElementById('checkInButton').addEventListener('click', handleCheckIn);
            }
            
            if (needsGlam || needsFitting) {
                document.querySelectorAll('.data-switch').forEach(switchEl => {
                    switchEl.addEventListener('change', (e) => handleSwitchToggle(e.target.dataset.field, e.target.checked));
                });
            }

            document.getElementById('issuedBy').addEventListener('change', handleIssuedByChange);

            if (honorariumIssued) {
                document.getElementById('stampTimeButton').addEventListener('click', handleStampTime);
                document.getElementById('resetHonorariumButton').addEventListener('click', handleResetHonorarium);
            }
            
            // Re-render immediately if the Issued By value changes to update buttons
            document.getElementById('issuedBy').addEventListener('change', () => {
                // Short delay to allow Firestore update to potentially fire, though we rely on onSnapshot
                setTimeout(renderDetailView.bind(null, container), 50); 
            });
        }

        function createSwitch(label, field, checked) {
            return `
                <div class="flex items-center justify-between p-3 bg-white rounded-lg shadow-sm border border-gray-200">
                    <label for="${field}" class="text-gray-700 font-medium">${label}</label>
                    <input type="checkbox" id="${field}" data-field="${field}" ${checked ? 'checked' : ''} class="data-switch h-6 w-11 appearance-none rounded-full bg-gray-300 transition duration-200 ease-in-out checked:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2">
                </div>
            `;
        }
        
        function renderMessageBoard(container) {
             container.innerHTML = `
                <div class="p-4 bg-white shadow-xl rounded-xl space-y-4">
                    <h2 class="text-2xl font-extrabold text-indigo-700">Team Message Board</h2>
                    
                    <!-- Message Submission Form -->
                    <div class="p-4 border-b border-gray-200 space-y-3 bg-indigo-50 rounded-lg shadow-inner">
                        <input type="text" id="authorInput" placeholder="Your Name/Initials" value="${localStorage.getItem('messageAuthor') || ''}" class="w-full p-2 border border-gray-300 rounded-lg focus:ring-indigo-500 focus:border-indigo-500 text-sm shadow-sm">
                        <textarea id="messageInput" rows="3" placeholder="Type your message here..." class="w-full p-2 border border-gray-300 rounded-lg focus:ring-indigo-500 focus:border-indigo-500 text-sm shadow-sm"></textarea>
                        <button id="postMessageButton" class="w-full py-2 font-bold text-white bg-indigo-600 rounded-xl shadow-md hover:bg-indigo-700 transition duration-150 ease-in-out">
                            Post Message
                        </button>
                    </div>

                    <!-- Message List -->
                    <div id="messageList" class="space-y-4 pt-2 max-h-[60vh] overflow-y-auto">
                        ${state.messages.length === 0 ? '<p class="text-center text-gray-500 py-4">No messages yet. Be the first!</p>' : ''}
                        ${state.messages.map(m => `
                            <div class="p-3 bg-gray-50 rounded-xl shadow-sm border border-gray-200">
                                <p class="text-gray-800">${m.MESSAGE_TEXT}</p>
                                <p class="mt-1 text-xs text-gray-500 font-semibold">${m.AUTHOR_NAME} - ${formatDate(m.TIMESTAMP)}</p>
                            </div>
                        `).join('')}
                    </div>
                </div>
            `;
            document.getElementById('postMessageButton').addEventListener('click', handleAddMessage);
            document.getElementById('authorInput').addEventListener('change', (e) => {
                localStorage.setItem('messageAuthor', e.target.value);
            });
        }


        // --- Firestore Handlers (Updates) ---

        async function updateParticipant(data) {
            try {
                const docRef = doc(db, getParticipantsCollectionRef().id, currentParticipantId);
                await updateDoc(docRef, data);
                showMessage('Update successful!');
            } catch (error) {
                console.error("Error updating document:", error);
                showMessage('Error saving data: ' + error.message, true);
            }
        }

        async function handleAddMessage() {
            const author = document.getElementById('authorInput').value.trim();
            const message = document.getElementById('messageInput').value.trim();

            if (!author || !message) {
                showMessage('Please enter your name and a message.', true);
                return;
            }

            try {
                // Save author name locally
                localStorage.setItem('messageAuthor', author);
                
                await addDoc(getMessagesCollectionRef(), {
                    AUTHOR_NAME: author,
                    MESSAGE_TEXT: message,
                    TIMESTAMP: new Date()
                });
                
                document.getElementById('messageInput').value = ''; // Clear input field
                showMessage('Message posted successfully!');
            } catch (error) {
                console.error("Error posting message:", error);
                showMessage('Error posting message: ' + error.message, true);
            }
        }

        // --- Event Handlers (Participant Details) ---

        async function handleCheckIn() {
            const data = {
                CHECKED_IN: true,
                CHECK_IN_TIME: new Date(),
            };
            await updateParticipant(data);
        }

        async function handleSwitchToggle(field, value) {
            const data = {};
            data[field] = value;
            await updateParticipant(data);
        }

        async function handleIssuedByChange(event) {
            const value = event.target.value;
            // Only update time if staff is assigned and time is not set
            const timestampData = {};
            if (value && !state.currentParticipant.HONORARIUM_ISSUE_TIME) {
                timestampData.HONORARIUM_ISSUE_TIME = new Date();
                showMessage('Honorarium assigned and time stamped.');
            } else if (!value) {
                // If staff is removed, clear time as well (full reset recommended via button)
                // This is just for safety/consistency on change
                timestampData.HONORARIUM_ISSUE_TIME = null;
            }
            await updateParticipant({ ISSUED_BY: value, ...timestampData });
        }

        async function handleStampTime() {
            await updateParticipant({ HONORARIUM_ISSUE_TIME: new Date() });
            showMessage('Honorarium time stamped!');
        }

        async function handleResetHonorarium() {
            const data = {
                ISSUED_BY: '', // Clear initials
                HONORARIUM_ISSUE_TIME: null // Clear timestamp
            };
            await updateParticipant(data);
            showMessage('Honorarium data reset!');
        }


        // --- Initialization ---

        async function initFirebase() {
            if (!firebaseConfig || !firebaseConfig.apiKey) {
                console.error("Firebase configuration is missing or invalid.");
                document.getElementById('appContainer').innerHTML = `<div class="p-4 bg-red-100 text-red-800 rounded-lg app-wrapper">Error: Firebase config is missing. Please check the environment variables.</div>`;
                return;
            }

            try {
                const app = initializeApp(firebaseConfig);
                db = getFirestore(app);
                auth = getAuth(app);
                setLogLevel('error'); 

                // 1. Authenticate
                if (initialAuthToken) {
                    await signInWithCustomToken(auth, initialAuthToken);
                } else {
                    await signInAnonymously(auth);
                }

                // 2. Wait for Auth State and get User ID
                await new Promise((resolve) => {
                    onAuthStateChanged(auth, (user) => {
                        if (user) {
                            userId = user.uid;
                        }
                        resolve();
                    });
                });
                
                // 3. Start Firestore Listeners
                startParticipantsListener();
                startMessagesListener();

                // 4. Initial Render
                renderApp();

            } catch (error) {
                console.error("Firebase initialization failed:", error);
                document.getElementById('appContainer').innerHTML = `<div class="p-4 bg-red-100 text-red-800 rounded-lg app-wrapper">Critical Error: ${error.message}</div>`;
            }
        }

        function startParticipantsListener() {
            if (unsubscribeParticipants) unsubscribeParticipants();

            const q = query(getParticipantsCollectionRef());

            unsubscribeParticipants = onSnapshot(q, (snapshot) => {
                const updatedParticipants = snapshot.docs.map(doc => {
                    const data = doc.data();
                    // Ensure all fields are present and correctly typed (default to safe values)
                    return {
                        id: doc.id,
                        NAME: data.NAME || 'Untitled',
                        ROLE: data.ROLE || 'N/A',
                        WALKING_FOR: data.WALKING_FOR || 'N/A',
                        ARRIVAL: data.ARRIVAL || 'N/A',
                        ROOM: data.ROOM || 'N/A',
                        CHECKED_IN: !!data.CHECKED_IN,
                        CHECK_IN_TIME: data.CHECK_IN_TIME || null,
                        HAIR_DONE: !!data.HAIR_DONE,
                        MAKEUP_DONE: !!data.MAKEUP_DONE,
                        FITTING_DONE: !!data.FITTING_DONE,
                        // Ensure CSV boolean flags are treated as booleans
                        NEEDS_GLAM_TRACKING: data.NEEDS_GLAM_TRACKING === 'TRUE' || data.NEEDS_GLAM_TRACKING === true,
                        NEEDS_FITTING: data.NEEDS_FITTING === 'TRUE' || data.NEEDS_FITTING === true,
                        ISSUED_BY: data.ISSUED_BY || '',
                        HONORARIUM_ISSUE_TIME: data.HONORARIUM_ISSUE_TIME || null,
                    };
                });
                
                updatedParticipants.sort((a, b) => a.NAME.localeCompare(b.NAME));
                state.participants = updatedParticipants;
                renderApp();

            }, (error) => {
                console.error("Firestore snapshot error (Participants):", error);
                showMessage('Error loading participant data: ' + error.message, true);
            });
        }
        
        function startMessagesListener() {
            if (unsubscribeMessages) unsubscribeMessages();

            // Order by timestamp descending and limit to latest 50 for performance
            const q = query(getMessagesCollectionRef(), orderBy('TIMESTAMP', 'desc'), limit(50));

            unsubscribeMessages = onSnapshot(q, (snapshot) => {
                state.messages = snapshot.docs.map(doc => ({
                    id: doc.id,
                    AUTHOR_NAME: doc.data().AUTHOR_NAME || 'Unknown',
                    MESSAGE_TEXT: doc.data().MESSAGE_TEXT || 'No Content',
                    TIMESTAMP: doc.data().TIMESTAMP,
                }));
                renderApp();
            }, (error) => {
                console.error("Firestore snapshot error (Messages):", error);
                showMessage('Error loading message data: ' + error.message, true);
            });
        }

        // Expose functions globally for HTML event handlers
        window.onload = initFirebase;
        window.navigateTo = navigateTo;
        window.navigateToDetail = navigateToDetail;
    </script>
</head>
<body class="bg-gray-100 min-h-screen font-sans antialiased">

    <!-- Message Box (Top, Fixed) -->
    <div id="messageBox" class="hidden fixed top-0 left-0 right-0 max-w-md mx-auto p-4 text-center text-sm font-semibold z-50 rounded-b-lg shadow-lg">
        <span id="messageText"></span>
    </div>
    
    <!-- Main Application Container (Centered, Mobile-First) -->
    <div id="appContainer" class="app-wrapper mb-2">
        <div class="p-8 text-center text-gray-500">
            <svg class="animate-spin h-8 w-8 text-indigo-500 mx-auto" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
            </svg>
            <p class="mt-3">Loading application...</p>
        </div>
    </div>
    
    <!-- Fixed Bottom Navigation Bar (Centered) -->
    <nav id="navBar" class="fixed bottom-0 left-0 right-0 max-w-md mx-auto h-16 bg-white border-t border-gray-200 flex shadow-2xl z-40 rounded-t-xl">
        <!-- Navigation Buttons will be injected here by renderNavigation() -->
    </nav>

</body>
</html>