`;
}
const contactHtml = `
`;
livePreview.innerHTML = `
${heroHtml}
${projects.title}
${projectsHtml}
${skills.title}
${skillsHtml}
${contact.title}
${contactHtml}
`;
}
function updateConfigAndRender() {
portfolioConfig.global.font = controls.font.value;
portfolioConfig.hero.headline = controls.heroHeadline.value;
portfolioConfig.hero.subheading = controls.heroSubheading.value;
portfolioConfig.hero.layout = controls.heroLayout.value;
portfolioConfig.projects.title = controls.projectsTitle.value;
portfolioConfig.projects.layout = controls.projectsLayout.value;
portfolioConfig.projects.count = parseInt(controls.projectsCount.value, 10);
portfolioConfig.skills.title = controls.skillsTitle.value;
portfolioConfig.skills.list = controls.skillsList.value;
portfolioConfig.skills.layout = controls.skillsLayout.value;
portfolioConfig.contact.title = controls.contactTitle.value;
portfolioConfig.contact.text = controls.contactText.value;
renderPreview();
}
Object.values(controls).forEach(control => {
if (control.id !== 'palette-selector' && control.id !== 'download-plan') {
control.addEventListener('input', updateConfigAndRender);
}
});
controls.palette.addEventListener('click', (e) => {
if (e.target.classList.contains('color-swatch')) {
controls.palette.querySelectorAll('.color-swatch').forEach(sw => sw.classList.remove('selected'));
e.target.classList.add('selected');
portfolioConfig.global.palette.bg = e.target.dataset.bg;
portfolioConfig.global.palette.primary = e.target.dataset.primary;
renderPreview();
}
});
document.querySelectorAll('.accordion-button').forEach(button => {
button.addEventListener('click', () => {
const isActive = button.classList.contains('active');
document.querySelectorAll('.accordion-button').forEach(btn => btn.classList.remove('active'));
if (!isActive) {
button.classList.add('active');
}
});
});
controls.downloadBtn.addEventListener('click', () => {
if (typeof jspdf === 'undefined' || !jspdf.jsPDF) {
alert("PDF library not loaded. Cannot download plan.");
return;
}
const { jsPDF } = jspdf;
const doc = new jsPDF();
let y = 20;
const addTitle = (title) => {
doc.setFontSize(18);
doc.setTextColor(40, 40, 40);
doc.text(title, 15, y);
y += 10;
};
const addDetail = (key, value) => {
doc.setFontSize(11);
doc.setTextColor(80, 80, 80);
doc.text(`${key}:`, 20, y);
doc.setTextColor(0, 0, 0);
doc.text(value, 55, y);
y += 7;
};
doc.setFontSize(24);
doc.text("Portfolio Layout Plan", 105, 15, { align: 'center' });
addTitle("Global Styles");
addDetail("Font", portfolioConfig.global.font);
addDetail("Palette", `Primary: ${portfolioConfig.global.palette.primary}, Background: ${portfolioConfig.global.palette.bg}`);
y += 5;
addTitle("Hero Section");
addDetail("Layout", portfolioConfig.hero.layout);
addDetail("Headline", portfolioConfig.hero.headline);
addDetail("Subheading", portfolioConfig.hero.subheading);
y += 5;
addTitle("Projects Section");
addDetail("Title", portfolioConfig.projects.title);
addDetail("Layout", portfolioConfig.projects.layout);
addDetail("Count", String(portfolioConfig.projects.count));
y += 5;
addTitle("Skills Section");
addDetail("Title", portfolioConfig.skills.title);
addDetail("Display Style", portfolioConfig.skills.layout);
doc.text("Skills List:", 20, y);
y += 7;
doc.setFontSize(10);
const skillsText = doc.splitTextToSize(portfolioConfig.skills.list, 160);
doc.text(skillsText, 25, y);
y += skillsText.length * 5 + 5;
addTitle("Contact Section");
addDetail("Title", portfolioConfig.contact.title);
doc.text("Message:", 20, y);
y += 7;
doc.setFontSize(10);
const contactText = doc.splitTextToSize(portfolioConfig.contact.text, 160);
doc.text(contactText, 25, y);
doc.save('Portfolio-Layout-Plan.pdf');
});
document.querySelector('.accordion-button[data-target="content-global"]').classList.add('active');
renderPreview();
});