Visual Aesthetics: ${escapeHTML(data.charAesthetics)}
Phoneme Needs: ${escapeHTML(data.phonemeInventory)}
III. Structure and Writing Rules
Writing Direction: ${escapeHTML(data.writingDirection)}
Word Separation: ${escapeHTML(data.wordSeparation)}
Punctuation/Naming Rules: ${escapeHTML(data.punctuationRules)}
Complex/Hidden Rules: ${escapeHTML(data.complexRules)}
`; }; const downloadTxt = () => { const data = getReportData(); let content = `FICTIONAL SCRIPT DESIGN SHEET: ${data.scriptName.toUpperCase()}\n`; content += `===========================================================\n\n`; content += `I. ORIGIN AND HISTORY\n`; content += `Script Name: ${data.scriptName}\n`; content += `Creator/Culture: ${data.creator}\n`; content += `Base Language: ${data.baseLanguage}\n`; content += `Origin Story: ${data.originStory}\n\n`; content += "II. SCRIPT CLASSIFICATION & AESTHETICS\n"; content += `Script Type: ${data.scriptType}\n`; content += `Character Count: ${data.charCount}\n`; content += `Visual Aesthetics: ${data.charAesthetics}\n`; content += `Phoneme Needs: ${data.phonemeInventory}\n\n`; content += "III. STRUCTURE AND WRITING RULES\n"; content += `Writing Direction: ${data.writingDirection}\n`; content += `Word Separation: ${data.wordSeparation}\n`; content += `Punctuation/Naming Rules: ${data.punctuationRules}\n`; content += `Complex/Hidden Rules: ${data.complexRules}\n\n`; const blob = new Blob([content], { type: 'text/plain;charset=utf-8' }); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = `${data.scriptName.replace(/ /g, '_')}_design.txt`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(a.href); }; const downloadPDF = () => { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('Error: jsPDF library not loaded.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); const data = getReportData(); const margin = 15; const pageWidth = doc.internal.pageSize.getWidth(); const usableWidth = pageWidth - margin * 2; let yPos = 20; const addWrappedText = (text, size, style, color = [52, 73, 94], align = 'left', indent = 0, isKeyPoint = false) => { doc.setFontSize(size); doc.setFont(undefined, style); doc.setTextColor(color[0], color[1], color[2]); const splitText = doc.splitTextToSize(text, usableWidth - indent); if (yPos + (splitText.length * 5) > 280) { doc.addPage(); yPos = 20; } doc.text(splitText, margin + indent, yPos); yPos += (splitText.length * 5) + (isKeyPoint ? 2 : 5); }; const addSectionHeader = (title) => { yPos += 5; doc.setFontSize(14); doc.setFont(undefined, 'bold'); doc.setTextColor(26, 115, 232); // Blue doc.text(title, margin, yPos); doc.setDrawColor(224, 224, 224); doc.line(margin, yPos + 1, pageWidth - margin, yPos + 1); yPos += 8; }; // --- Build PDF Document --- // 1. Title Block doc.setFontSize(18); doc.setFont(undefined, 'bold'); doc.setTextColor(44, 62, 80); doc.text(`Fictional Script Design Sheet`, pageWidth / 2, yPos, { align: 'center' }); yPos += 8; addWrappedText(data.scriptName, 12, 'bold', [26, 115, 232], 'center'); addWrappedText(`Creator: ${data.creator} | Base Language: ${data.baseLanguage}`, 10, 'italic', [108, 117, 125], 'center'); yPos += 10; // 2. Origin and History addSectionHeader("I. Origin and History"); addWrappedText("Origin Story:", 10, 'bold', [52, 73, 94]); addWrappedText(data.originStory, 10, 'normal', [52, 73, 94], 'left', 5); // 3. Classification & Aesthetics addSectionHeader("II. Script Classification & Aesthetics"); addWrappedText(`Script Type: ${data.scriptType} | Character Count: ${data.charCount}`, 10, 'bold', [52, 73, 94]); addWrappedText("Visual Aesthetics:", 10, 'bold', [52, 73, 94]); addWrappedText(data.charAesthetics, 10, 'normal', [52, 73, 94], 'left', 5); addWrappedText("Phoneme Inventory Highlights:", 10, 'bold', [52, 73, 94]); addWrappedText(data.phonemeInventory, 10, 'normal', [52, 73, 94], 'left', 5); // 4. Structure & Rules addSectionHeader("III. Structure and Writing Rules"); addWrappedText(`Writing Direction: ${data.writingDirection}`, 10, 'bold', [52, 73, 94]); addWrappedText("Word/Sentence Separation:", 10, 'bold', [52, 73, 94]); addWrappedText(data.wordSeparation, 10, 'normal', [52, 73, 94], 'left', 5); addWrappedText("Punctuation/Naming Rules:", 10, 'bold', [52, 73, 94]); addWrappedText(data.punctuationRules, 10, 'normal', [52, 73, 94], 'left', 5); addWrappedText("Complex/Hidden Rules:", 10, 'bold', [52, 73, 94]); addWrappedText(data.complexRules, 10, 'normal', [52, 73, 94], 'left', 5); doc.save('script_design_sheet.pdf'); }; // --- Event Listeners --- // Global Navigation tabButtons.forEach((btn, index) => { btn.addEventListener('click', () => showTab(index + 1)); }); nextBtn.addEventListener('click', () => showTab(currentTab + 1)); prevBtn.addEventListener('click', () => showTab(currentTab - 1)); // Tab 4 Actions refreshBtn.addEventListener('click', generatePreview); downloadPdfBtn.addEventListener('click', downloadPDF); downloadTxtBtn.addEventListener('click', downloadTxt); // --- Initialization --- showTab(1); // Set initial state });