document.addEventListener('DOMContentLoaded', () => { // Initialize app createSnowflakes(); initializeStory(); setupNavigation(); // Event listeners document.getElementById('continue-story')?.addEventListener('click', continueStory); document.getElementById('ask-question')?.addEventListener('click', askQuestion); // Location buttons document.querySelectorAll('.location-btn').forEach(btn => { btn.addEventListener('click', () => { const location = btn.dataset.location; showLocation(location); }); }); // Back buttons document.querySelectorAll('[data-back]').forEach(btn => { btn.addEventListener('click', showHomeView); }); }); function setupNavigation() { // Handle bottom nav clicks document.querySelectorAll('.nav-btn').forEach(btn => { btn.addEventListener('click', () => { const view = btn.dataset.view; showView(view); // Update active state document.querySelectorAll('.nav-btn').forEach(navBtn => { navBtn.classList.remove('active'); }); btn.classList.add('active'); }); }); } function showView(viewName) { // Hide all views document.querySelectorAll('.view').forEach(view => { view.classList.add('hidden'); view.classList.remove('active'); }); // Show selected view const view = document.getElementById(`${viewName}-view`); if (view) { view.classList.remove('hidden'); view.classList.add('active'); } } function showHomeView() { showView('home'); document.querySelector('[data-view="home"]').classList.add('active'); } function showLocation(location) { showView(location); } function initializeStory() { const currentDay = 1; document.getElementById('current-day').textContent = currentDay; const chapterTitles = [ "Chapter 1: The Arrival", "Chapter 2: The Baker's Secret", "Chapter 3: Market Mystery", "Chapter 4: Getting Around", "Chapter 5: Hotel Check-in", "Chapter 6: Café Culture", "Chapter 7: Weekly Review", "Chapter 8: Grocery Shopping", "Chapter 9: Post Office Visit", "Chapter 10: Doctor's Visit", "Chapter 11: Public Transport", "Chapter 12: Restaurant Night", "Chapter 13: Shopping Spree", "Chapter 14: Weekly Review", "Chapter 15: Carol Singing", "Chapter 16: Tree Decorating", "Chapter 17: Gift Wrapping", "Chapter 18: Winter Sports", "Chapter 19: Holiday Cooking", "Chapter 20: Town Celebration", "Chapter 21: Weekly Review", "Chapter 22: Storytelling", "Chapter 23: Local Legends", "Chapter 24: Christmas Eve", "Chapter 25: Farewell" ]; if (document.getElementById('chapter-title')) { document.getElementById('chapter-title').textContent = chapterTitles[currentDay - 1] || "Chapter 1: The Arrival"; } } function generateCalendar() { const calendarDays = document.getElementById('calendar-days'); if (!calendarDays) return; calendarDays.innerHTML = ''; for (let day = 1; day <= 25; day++) { const dayElement = document.createElement('div'); dayElement.className = `text-center p-3 rounded-lg cursor-pointer transition ${day === 1 ? 'bg-primary text-white' : day <= 1 ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-400'}`; dayElement.innerHTML = `
${day}
${day === 1 ? 'Today' : 'Day ' + day}
`; if (day <= 1) { dayElement.addEventListener('click', () => { alert(`You're on Day ${day}! ${day === 1 ? 'Continue your adventure.' : 'This day will unlock soon.'}`); }); } calendarDays.appendChild(dayElement); } } function loadCharacters() { const characterContainer = document.getElementById('character-profiles'); if (!characterContainer) return; const characters = [ { name: "Pierre", role: "The Baker", description: "Friendly local who loves teaching phrases about food.", img: "http://static.photos/people/200x200/10" }, { name: "Claire", role: "Market Vendor", description: "Sells Christmas ornaments and knows all the holiday vocabulary.", img: "http://static.photos/people/200x200/11" }, { name: "Luc", role: "Town Musician", description: "Teaches French through Christmas carols.", img: "http://static.photos/people/200x200/12" }, { name: "Monsieur Lefevre", role: "Mayor", description: "Speaks formal French - great for learning polite expressions.", img: "http://static.photos/people/200x200/13" } ]; characterContainer.innerHTML = ''; characters.forEach(char => { const charElement = document.createElement('div'); charElement.className = 'text-center'; charElement.innerHTML = ` ${char.name}

${char.name}

${char.role}

${char.description}

`; characterContainer.appendChild(charElement); }); } function continueStory() { const storyChat = document.getElementById('story-chat'); if (!storyChat) return; const storySteps = [ { speaker: "ai", text: "You walk toward the town square and see a beautiful Christmas market. A vendor calls out: 'Venez voir nos décorations!' (Come see our decorations!)", character: "Market Vendor" }, { speaker: "user", text: "Je voudrais acheter une décoration. (I would like to buy a decoration.)", character: "You" }, { speaker: "ai", text: "'Très bien! Celle-ci coûte cinq euros,' she says with a smile. You've just completed your first transaction in French!", character: "Claire" } ]; storySteps.forEach((step, index) => { setTimeout(() => { const messageDiv = document.createElement('div'); messageDiv.className = 'flex items-start space-x-3 mb-4'; if (step.speaker === 'user') { messageDiv.innerHTML = `

${step.text}

${step.character}

`; } else { messageDiv.innerHTML = `

${step.text}

${step.character}

`; } storyChat.appendChild(messageDiv); storyChat.scrollTop = storyChat.scrollHeight; feather.replace(); }, (index + 1) * 1500); }); // Update mission text after story progresses setTimeout(() => { const missionElement = document.getElementById('daily-mission'); if (missionElement) { missionElement.textContent = "Visit the Christmas market and buy a decoration using French."; } }, 5000); } function askQuestion() { const storyChat = document.getElementById('story-chat'); if (!storyChat) return; const questionDiv = document.createElement('div'); questionDiv.className = 'flex items-start space-x-3 mb-4'; questionDiv.innerHTML = `

How do I say 'How much does this cost?' in French?

You asked

`; storyChat.appendChild(questionDiv); setTimeout(() => { const answerDiv = document.createElement('div'); answerDiv.className = 'flex items-start space-x-3 mb-4'; answerDiv.innerHTML = `

You say: 'Combien ça coûte?' (kɔm.bjɛ̃ sa kut). Try repeating it!

Pierre helps

`; storyChat.appendChild(answerDiv); storyChat.scrollTop = storyChat.scrollHeight; feather.replace(); }, 1000); } function createSnowflakes() { const snowContainer = document.getElementById('snow-overlay'); if (!snowContainer) return; for (let i = 0; i < 100; i++) { const snowflake = document.createElement('div'); snowflake.className = 'snowflake'; snowflake.innerHTML = '❄'; snowflake.style.left = Math.random() * 100 + 'vw'; snowflake.style.top = -20 + 'px'; snowflake.style.fontSize = (Math.random() * 10 + 8) + 'px'; snowflake.style.opacity = Math.random(); snowflake.style.animationDuration = `${Math.random() * 5 + 5}s, ${Math.random() * 5 + 5}s`; snowflake.style.animationDelay = `${Math.random() * 5}s`; snowContainer.appendChild(snowflake); } } function visitLocation(location) { const locations = { bakery: { title: "Pierre's Bakery", description: "The sweet smell of fresh pastries fills the air as you enter the cozy bakery. Pierre greets you warmly." }, market: { title: "Christmas Market", description: "Colorful stalls line the square, selling handmade ornaments and holiday treats. Claire waves as you approach." }, hotel: { title: "Town Hotel", description: "The grand hotel entrance welcomes you with twinkling lights. The concierge stands ready to assist." } }; const storyPanel = document.querySelector('.story-panel'); if (storyPanel) { storyPanel.querySelector('#chapter-title').textContent = locations[location].title; storyPanel.querySelector('#story-text').textContent = locations[location].description; } } });