Wedding Vow Writing Assistant
Craft the perfect words for your special day.
Your Generated Vows
Your beautifully crafted vows will appear here once you complete the steps.
Set the Tone & Style
Make Your Promises
Share a Personal Memory
Dream About Your Future
Error: Could not find all input fields.
'; return; } const partnerName = partnerNameEl.value.trim() || "my love"; const vowTone = vowToneEl.value; const personalStory = personalStoryEl.value.trim(); const futureHopes = futureHopesEl.value.trim(); let selectedPromises = Array.from(document.querySelectorAll('.promise-checkbox:checked')).map(cb => `I promise ${cb.value}.`); const customPromisesEl = document.getElementById('customPromises'); if (customPromisesEl) { const customPromises = customPromisesEl.value.trim().split('\n').filter(p => p); selectedPromises.push(...customPromises.map(p => `I promise ${p.trim()}.`)); } let vow = ""; // Construct vow based on tone switch(vowTone) { case 'romantic': vow += `My dearest ${partnerName},\n\nFrom the moment you walked into my life, I knew my world had changed forever. You are the poetry my heart was always trying to write.\n\n`; break; case 'modern': vow += `${partnerName},\n\nStanding here with you today feels like coming home. You are my anchor, my inspiration, and my very best friend.\n\n`; break; case 'humorous': vow += `${partnerName}, my favorite human,\n\nThey say you should marry your best friend, and I can't imagine a better, funnier, or weirder person to spend my life with.\n\n`; break; case 'traditional': vow += `I, [Your Name], take you, ${partnerName}, to be my lawfully wedded partner, to have and to hold, from this day forward.\n\n`; break; } if (personalStory) { vow += `I will never forget ${personalStory.startsWith('the time') ? '' : 'the time '}${personalStory}. It was then I knew how deeply I loved you.\n\n`; } if (selectedPromises.length > 0) { vow += selectedPromises.join('\n') + '\n\n'; } else { vow += "With all that I am, I promise to love and cherish you through everything.\n\n"; } if (futureHopes) { vow += `I cannot wait to ${futureHopes.toLowerCase().startsWith('to ') ? futureHopes.substring(3) : futureHopes}. Our future is an adventure I'm so excited to begin.\n\n`; } vow += `You are my everything, and I choose you, today and for all of my tomorrows.`; vowOutputContent.innerText = vow; downloadPdfBtn.classList.remove('hidden'); } /** * Downloads the vow output as a PDF file. */ function downloadPdf() { const { jsPDF } = window.jspdf; // Temporarily remove border for screenshot vowOutputContent.style.border = 'none'; html2canvas(vowOutputContent, { scale: 2, // Higher scale for better quality backgroundColor: '#f7fafc' }).then(canvas => { // Restore border after screenshot vowOutputContent.style.border = '1px dashed var(--secondary-color)'; const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'portrait', unit: 'px', format: [canvas.width, canvas.height] }); pdf.addImage(imgData, 'PNG', 0, 0, canvas.width, canvas.height); pdf.save('My_Wedding_Vows.pdf'); }); } // --- Event Listeners --- tabs.forEach((tab, index) => { tab.addEventListener('click', () => { // Allow navigating to output tab only if vows are generated. // For input tabs, update the current index. if (index === 0 && vowOutputContent.querySelector('p')) { // If output tab is clicked before generation, do nothing or show a message return; } if (index > 0) { currentTabIndex = index; } showTab(index); }); }); nextBtn.addEventListener('click', () => { if (currentTabIndex < totalInputTabs) { currentTabIndex++; showTab(currentTabIndex); } else { // This is the "Generate Vows" click generateVow(); showTab(0); // Switch to output tab } }); prevBtn.addEventListener('click', () => { if (currentTabIndex > 1) { currentTabIndex--; showTab(currentTabIndex); } }); if (downloadPdfBtn) { downloadPdfBtn.addEventListener('click', downloadPdf); } // --- Initial State --- showTab(currentTabIndex); });