Anti-Aging Skincare Routine Planner

Step 1: Tell Us About Your Skin

What is your skin type?

What are your main concerns? (Select up to 3)

This tool provides a general guideline. For personalized medical advice, please consult a board-certified dermatologist.

• ${note}

`).join(''); resultsPlaceholder.classList.add('hidden'); resultsContent.classList.remove('hidden'); } function downloadPDF() { if (resultsContent.classList.contains('hidden')) { alert('Please generate your plan first.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF({ unit: 'pt', format: 'a4' }); const pageW = doc.internal.pageSize.getWidth(); const margin = 40; let currentY = 0; const primaryColor = [37, 99, 235], grayColor = [107, 114, 128], blackColor = [17, 24, 39]; // --- HEADER --- doc.setFillColor(...primaryColor); doc.rect(0, 0, pageW, 80, 'F'); doc.setFont('helvetica', 'bold'); doc.setFontSize(24); doc.setTextColor(255, 255, 255); doc.text('Your Anti-Aging Skincare Plan', margin, 50); // --- REPORT INFO --- currentY = 110; const reportDate = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); doc.setFont('helvetica', 'normal'); doc.setFontSize(9); doc.setTextColor(...grayColor); doc.text(`Generated on: ${reportDate}`, pageW - margin, currentY, { align: 'right' }); currentY += 20; // --- ROUTINE TABLES --- const amRoutine = Array.from(document.querySelectorAll('#am-routine-steps > div')).map(el => [ el.querySelector('.font-bold').textContent, el.querySelector('.font-semibold').textContent, el.querySelector('.text-sm').textContent ]); const pmRoutine = Array.from(document.querySelectorAll('#pm-routine-steps > div')).map(el => [ el.querySelector('.font-bold').textContent, el.querySelector('.font-semibold').textContent, el.querySelector('.text-sm').textContent ]); doc.setFont('helvetica', 'bold'); doc.setFontSize(16); doc.setTextColor(...blackColor); doc.text('☀️ Morning Routine', margin, currentY); currentY += 5; doc.autoTable({ startY: currentY, head: [['Step', 'Product Type', 'Notes']], body: amRoutine, theme: 'striped', headStyles: { fillColor: [59, 130, 246] }, styles: { font: 'helvetica', fontSize: 9 } }); currentY = doc.lastAutoTable.finalY + 30; doc.setFont('helvetica', 'bold'); doc.setFontSize(16); doc.setTextColor(...blackColor); doc.text('🌙 Evening Routine', margin, currentY); currentY += 5; doc.autoTable({ startY: currentY, head: [['Step', 'Product Type', 'Notes']], body: pmRoutine, theme: 'striped', headStyles: { fillColor: [79, 70, 229] }, styles: { font: 'helvetica', fontSize: 9 } }); currentY = doc.lastAutoTable.finalY + 20; // --- NOTES --- const notes = Array.from(document.querySelectorAll('#routine-notes p')).map(el => el.innerHTML.replace(//g, '').replace(/<\/strong>/g, '')); if(notes.length > 0) { doc.setFont('helvetica', 'bold'); doc.setFontSize(12); doc.text('Important Considerations', margin, currentY); currentY += 15; doc.setFont('helvetica', 'normal'); doc.setFontSize(9); notes.forEach(note => { const noteLines = doc.splitTextToSize(`• ${note}`, pageW - (margin * 2)); doc.text(noteLines, margin, currentY); currentY += (noteLines.length * 10) + 5; }); } // --- FOOTER --- const pageH = doc.internal.pageSize.getHeight(); doc.setDrawColor(...grayColor); doc.line(margin, pageH - 60, pageW - margin, pageH - 60); doc.setFont('helvetica', 'normal'); doc.setFontSize(8); doc.setTextColor(...grayColor); const footerText = 'This planner provides a general guideline based on your selections. It is not a substitute for professional medical advice. For personalized recommendations and to address specific skin conditions, please consult a board-certified dermatologist.'; doc.text(doc.splitTextToSize(footerText, pageW - (margin * 2)), margin, pageH - 45); doc.save('My-Skincare-Plan.pdf'); } // --- EVENT LISTENERS --- prevBtn.addEventListener('click', () => { if (currentTab > 1) { currentTab--; updateUI(); } }); nextBtn.addEventListener('click', () => { if (currentTab === 1) { currentTab++; } else if (currentTab === 2) { generatePlan(); } updateUI(); }); pdfDownloadBtn.addEventListener('click', downloadPDF); // --- KICKOFF --- populateOptions(); updateUI(); });
Scroll to Top