// Dark mode functionality
function toggleDarkMode() {
const body = document.body;
const toggle = document.querySelector(".dark-mode-toggle");
const sunIcon = toggle.querySelector(".sun-icon");
const moonIcon = toggle.querySelector(".moon-icon");
body.classList.toggle("dark-mode");
const isDarkMode = body.classList.contains("dark-mode");
localStorage.setItem("dark-mode", isDarkMode);
sunIcon.style.display = isDarkMode ? "none" : "block";
moonIcon.style.display = isDarkMode ? "block" : "none";
}
// Add these new functions at the top
function extractVariables(text) {
const regex = /\${([^}]+)}/g;
const variables = [];
let match;
while ((match = regex.exec(text)) !== null) {
const [variable, defaultValue] = match[1].split(":").map((s) => s.trim());
variables.push({ name: variable, default: defaultValue || "" });
}
return [...new Set(variables.map((v) => JSON.stringify(v)))].map((v) =>
JSON.parse(v)
); // Remove duplicates
}
function createVariableInputs(variables, container) {
const form = document.createElement("div");
form.className = "variable-form";
variables.forEach((variable) => {
const wrapper = document.createElement("div");
wrapper.className = "variable-input-wrapper";
const label = document.createElement("label");
label.textContent = variable.name;
label.style.fontWeight = "600";
const input = document.createElement("input");
input.type = "text";
input.className = "variable-input";
input.placeholder = variable.default || `Enter ${variable.name}`;
input.dataset.variable = variable.name;
input.dataset.default = variable.default || "";
wrapper.appendChild(label);
wrapper.appendChild(input);
form.appendChild(wrapper);
});
container.appendChild(form);
return form;
}
// Function to update the prompt preview with user input or default values
function updatePromptPreview(promptText, form) {
const variables = extractVariables(promptText);
if (variables.length === 0) {
return promptText; // Return original text if no variables found
}
let previewText = promptText;
// Replace variables with their default values without editting (for prompt cards, copy buttons, chat)
if (!form) {
variables.forEach(variable => {
const pattern = new RegExp(`\\$\{${variable.name}[^}]*\}`, 'g');
const replacement = variable.default || `${variable.name}`;
previewText = previewText.replace(pattern, replacement);
});
}
// Replace variables according to the user inputs.
else {
const inputs = form.querySelectorAll(".variable-input");
inputs.forEach((input) => {
const value = input.value.trim();
const variable = input.dataset.variable;
const defaultValue = input.dataset.default;
const pattern = new RegExp(`\\$\{${variable}[^}]*\}`, 'g');
let replacement;
if (value) {
// User entered value
replacement = value;
} else if (defaultValue) {
// Show default value with highlight
replacement = defaultValue;
} else {
// No value or default, show variable name
replacement = variable;
}
replacement = `${replacement}`;
previewText = previewText.replace(pattern, replacement);
});
}
return previewText;
}
// Initialize everything after DOM loads
document.addEventListener("DOMContentLoaded", () => {
// Initialize audience selector and dev mode
const audienceSelect = document.getElementById('audienceSelect');
const initialAudience = localStorage.getItem('audience') || 'everyone';
audienceSelect.value = initialAudience;
document.body.classList.toggle('dev-mode', initialAudience === 'developers');
// Handle audience changes
audienceSelect.addEventListener('change', (e) => {
const isDevMode = e.target.value === 'developers';
document.body.classList.toggle('dev-mode', isDevMode);
localStorage.setItem('audience', e.target.value);
// Update chat button icons
updateChatButtonIcons(isDevMode);
// Check if we should show Copilot suggestion
if (isDevMode) {
const currentPlatform = document.querySelector(".platform-tag.active");
const shouldNotShow = localStorage.getItem("copilot-suggestion-hidden") === "true";
if (currentPlatform &&
currentPlatform.dataset.platform !== "github-copilot" &&
!shouldNotShow) {
showCopilotSuggestion();
}
}
// Trigger prompt filtering
filterPrompts();
});
// Fetch GitHub stars
fetch("https://api.github.com/repos/f/awesome-chatgpt-prompts")
.then((response) => response.json())
.then((data) => {
const stars = data.stargazers_count;
document.getElementById("starCount").textContent = stars.toLocaleString();
})
.catch((error) => {
console.error("Error fetching star count:", error);
document.getElementById("starCount").textContent = "50k+";
});
// Create prompt cards
createPromptCards();
// Initialize dark mode
const isDarkMode = localStorage.getItem("dark-mode");
const toggle = document.querySelector(".dark-mode-toggle");
const sunIcon = toggle.querySelector(".sun-icon");
const moonIcon = toggle.querySelector(".moon-icon");
// Set dark mode by default if not set
if (isDarkMode === null) {
localStorage.setItem("dark-mode", "true");
document.body.classList.add("dark-mode");
sunIcon.style.display = "none";
moonIcon.style.display = "block";
} else if (isDarkMode === "true") {
document.body.classList.add("dark-mode");
sunIcon.style.display = "none";
moonIcon.style.display = "block";
} else {
sunIcon.style.display = "block";
moonIcon.style.display = "none";
}
// Initialize search functionality
initializeSearch();
// Initialize language and tone selectors
initializeLanguageAndTone();
});
// Search functionality
async function initializeSearch() {
try {
const response = await fetch("/prompts.csv");
const csvText = await response.text();
const prompts = parseCSV(csvText);
// Sort prompts alphabetically by act
prompts.sort((a, b) => a.act.localeCompare(b.act));
const searchInput = document.getElementById("searchInput");
const searchResults = document.getElementById("searchResults");
const promptCount = document.getElementById("promptCount");
const isDevMode = document.getElementById("audienceSelect").value === "developers";
// Update prompt count
const totalPrompts = isDevMode
? prompts.filter((p) => p.for_devs === true).length
: prompts.length;
updatePromptCount(totalPrompts, totalPrompts);
// Show filtered prompts initially
const filteredPrompts = isDevMode
? prompts.filter((p) => p.for_devs === true)
: prompts;
displaySearchResults(filteredPrompts);
searchInput.addEventListener("input", (e) => {
const searchTerm = e.target.value.toLowerCase();
const isDevMode = document.getElementById("audienceSelect").value === "developers";
const filteredPrompts = prompts.filter((prompt) => {
const matchesSearch =
prompt.act.toLowerCase().includes(searchTerm) ||
prompt.prompt.toLowerCase().includes(searchTerm);
return isDevMode
? matchesSearch && prompt.for_devs === true
: matchesSearch;
});
// Update count with filtered results
const totalPrompts = isDevMode
? prompts.filter((p) => p.for_devs === true).length
: prompts.length;
updatePromptCount(filteredPrompts.length, totalPrompts);
displaySearchResults(filteredPrompts);
});
} catch (error) {
console.error("Error loading prompts:", error);
}
}
function updatePromptCount(filteredCount, totalCount) {
const promptCount = document.getElementById("promptCount");
const countLabel = promptCount.querySelector(".count-label");
const countNumber = promptCount.querySelector(".count-number");
if (filteredCount === totalCount) {
promptCount.classList.remove("filtered");
countLabel.textContent = "All Prompts";
countNumber.textContent = totalCount;
} else {
promptCount.classList.add("filtered");
countLabel.textContent = `Found ${filteredCount} of ${totalCount}`;
countNumber.textContent = filteredCount;
}
}
function parseCSV(csv) {
const lines = csv.split("\n");
const headers = lines[0]
.split(",")
.map((header) => header.replace(/"/g, "").trim());
return lines
.slice(1)
.map((line) => {
const values = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || [];
const entry = {};
headers.forEach((header, index) => {
let value = values[index] ? values[index].replace(/"/g, "").trim() : "";
// Remove backticks from the act/title
if (header === "act") {
value = value.replace(/`/g, "");
}
// Convert 'TRUE'/'FALSE' strings to boolean for for_devs
if (header === "for_devs") {
value = value.toUpperCase() === "TRUE";
}
entry[header] = value;
});
return entry;
})
.filter((entry) => entry.act && entry.prompt);
}
function displaySearchResults(results) {
const searchResults = document.getElementById("searchResults");
const searchInput = document.getElementById("searchInput");
const isDevMode = document.getElementById("audienceSelect").value === "developers";
// Filter results based on dev mode
if (isDevMode) {
results = results.filter((result) => result.for_devs === true);
}
searchResults.innerHTML = "";
if (window.innerWidth <= 768 && !searchInput.value.trim()) {
return;
}
if (results.length === 0) {
const li = document.createElement("li");
li.className = "search-result-item add-prompt";
li.innerHTML = `
Add this prompt
`;
searchResults.appendChild(li);
return;
}
results.forEach((result) => {
const li = document.createElement("li");
li.className = "search-result-item";
li.textContent = result.act;
li.addEventListener("click", () => {
// Find the prompt card with matching title
const cards = document.querySelectorAll(".prompt-card");
const targetCard = Array.from(cards).find((card) => {
const cardTitle = card
.querySelector(".prompt-title")
.textContent.replace(/\s+/g, " ") // Normalize whitespace
.replace(/[\n\r]/g, "") // Remove newlines
.trim();
const searchTitle = result.act
.replace(/\s+/g, " ") // Normalize whitespace
.replace(/[\n\r]/g, "") // Remove newlines
.trim();
return (
cardTitle.toLowerCase().includes(searchTitle.toLowerCase()) ||
searchTitle.toLowerCase().includes(cardTitle.toLowerCase())
);
});
if (targetCard) {
// Remove highlight from all cards
cards.forEach((card) => {
card.style.transition = "all 0.3s ease";
card.style.transform = "none";
card.style.boxShadow = "none";
card.style.borderColor = "";
});
// Different scroll behavior for mobile and desktop
const isMobile = window.innerWidth <= 768;
const headerHeight =
document.querySelector(".site-header").offsetHeight;
if (isMobile) {
// On mobile, scroll the window
const cardRect = targetCard.getBoundingClientRect();
const scrollTop =
window.pageYOffset + cardRect.top - headerHeight - 20;
window.scrollTo({
top: scrollTop,
behavior: "smooth",
});
} else {
// On desktop, scroll the main-content container
const mainContent = document.querySelector(".main-content");
const cardRect = targetCard.getBoundingClientRect();
const scrollTop =
mainContent.scrollTop + cardRect.top - headerHeight - 20;
mainContent.scrollTo({
top: scrollTop,
behavior: "smooth",
});
}
// Add highlight effect after scrolling completes
setTimeout(() => {
targetCard.style.transform = "scale(1.02)";
targetCard.style.boxShadow = "0 0 0 2px var(--accent-color)";
targetCard.style.borderColor = "var(--accent-color)";
// Remove highlight after animation
setTimeout(() => {
targetCard.style.transform = "none";
targetCard.style.boxShadow = "none";
targetCard.style.borderColor = "";
}, 2000);
}, 500); // Wait for scroll to complete
} else {
console.log("Card not found for:", result.act);
}
});
searchResults.appendChild(li);
});
}
// Function to filter prompts based on dev mode
function filterPrompts() {
const isDevMode = document.getElementById("audienceSelect").value === "developers";
const searchInput = document.getElementById("searchInput");
const searchTerm = searchInput.value.toLowerCase();
// Re-fetch and filter prompts
fetch("/prompts.csv")
.then((response) => response.text())
.then((csvText) => {
const prompts = parseCSV(csvText);
const filteredPrompts = prompts.filter((prompt) => {
const matchesSearch =
!searchTerm ||
prompt.act.toLowerCase().includes(searchTerm) ||
prompt.prompt.toLowerCase().includes(searchTerm);
return isDevMode
? matchesSearch && prompt.for_devs === true
: matchesSearch;
});
// Update count with filtered results
updatePromptCount(
filteredPrompts.length,
isDevMode
? prompts.filter((p) => p.for_devs === true).length
: prompts.length
);
displaySearchResults(filteredPrompts);
// Update prompt cards visibility
const promptsGrid = document.querySelector(".prompts-grid");
if (promptsGrid) {
const cards = promptsGrid.querySelectorAll(
".prompt-card:not(.contribute-card)"
);
cards.forEach((card) => {
const title = card.querySelector(".prompt-title").textContent.trim();
const matchingPrompt = prompts.find((p) => {
const pTitle = p.act
.replace(/\s+/g, " ")
.replace(/[\n\r]/g, "")
.trim();
const cardTitle = title
.replace(/\s+/g, " ")
.replace(/[\n\r]/g, "")
.trim();
return (
pTitle.toLowerCase() === cardTitle.toLowerCase() ||
pTitle.toLowerCase().includes(cardTitle.toLowerCase()) ||
cardTitle.toLowerCase().includes(pTitle.toLowerCase())
);
});
// Show card if not in dev mode or if it's a dev prompt in dev mode
card.style.display =
!isDevMode || (matchingPrompt && matchingPrompt.for_devs === true)
? ""
: "none";
});
}
});
}
// Update the modal initialization and event listeners
function createPromptCards() {
const container = document.querySelector(".container-lg.markdown-body");
const promptsGrid = document.createElement("div");
promptsGrid.className = "prompts-grid";
// Add contribute box
const contributeCard = document.createElement("div");
contributeCard.className = "prompt-card contribute-card";
contributeCard.innerHTML = `
Share your creative prompts with the community! Submit a pull request to add your prompts to the collection.
${updatePromptPreview(content)}
@${contributor} `; // Add click event for showing modal card.addEventListener("click", (e) => { if ( !e.target.closest(".copy-button") && !e.target.closest(".contributor-badge") ) { showModal(title, content); } }); const copyButton = card.querySelector(".copy-button"); copyButton.addEventListener("click", async (e) => { e.stopPropagation(); try { await navigator.clipboard.writeText(updatePromptPreview(content)); copyButton.innerHTML = ` `; setTimeout(() => { copyButton.innerHTML = ` `; }, 2000); } catch (err) { alert("Failed to copy prompt to clipboard"); } }); promptsGrid.appendChild(card); }); container.innerHTML = ""; container.appendChild(promptsGrid); // Initialize modal event listeners initializeModalListeners(); }) .catch((error) => { console.error("Error loading prompts:", error); }); } function initializeModalListeners() { const modalOverlay = document.getElementById("modalOverlay"); const modalClose = document.querySelector(".modal-close"); if (!modalOverlay || !modalClose) return; modalClose.addEventListener("click", hideModal); modalOverlay.addEventListener("click", (e) => { if (e.target === modalOverlay) { hideModal(); } }); } // Add global event listener for Escape key document.addEventListener("keydown", (e) => { if (e.key === "Escape") { hideModal(); } }); function createModal() { const modalHTML = ` `; document.body.insertAdjacentHTML("beforeend", modalHTML); initializeModalListeners(); } // Modify the existing showModal function function showModal(title, content) { let modalOverlay = document.getElementById("modalOverlay"); if (!modalOverlay) { createModal(); modalOverlay = document.getElementById("modalOverlay"); } const modalTitle = modalOverlay.querySelector(".modal-title"); const modalContent = modalOverlay.querySelector(".modal-content"); // Extract variables from content const variables = extractVariables(content); // Create variable inputs container if variables exist if (variables.length > 0) { const variableContainer = document.createElement("div"); variableContainer.className = "variable-container"; const form = createVariableInputs(variables, variableContainer); // Initialize the modal content with updated prompt preview if variables exist const previewText = updatePromptPreview(content, form); modalContent.innerHTML = previewText; // Add event listeners for real-time updates form.addEventListener("input", () => { const previewText = updatePromptPreview(content, form); modalContent.innerHTML = previewText; // Update chat button data const modalChatButton = modalOverlay.querySelector(".modal-chat-button"); if (modalChatButton) { modalChatButton.dataset.content = previewText; } }); // Insert variable container before content modalContent.parentElement.insertBefore(variableContainer, modalContent); } else { modalTitle.textContent = title; modalContent.textContent = content; } const modalCopyButton = modalOverlay.querySelector(".modal-copy-button"); const modalContributor = modalOverlay.querySelector(".modal-contributor"); const modalChatButton = modalOverlay.querySelector(".modal-chat-button"); if (!modalTitle || !modalContent) return; // Update chat button text with platform name and handle visibility const platform = document.querySelector(".platform-tag.active"); const isDevMode = document.getElementById("audienceSelect").value === "developers"; if (platform) { const shouldHideChat = ["gemini", "llama"].includes( platform.dataset.platform ); modalChatButton.style.display = shouldHideChat ? "none" : "flex"; if (!shouldHideChat) { const chatIcon = modalChatButton.querySelector(".chat-icon"); const terminalIcon = modalChatButton.querySelector(".terminal-icon"); if (chatIcon && terminalIcon) { chatIcon.style.display = isDevMode ? "none" : "block"; terminalIcon.style.display = isDevMode ? "block" : "none"; } modalChatButton.innerHTML = ` Chat with ${platform.textContent} `; } } // Store content for chat button modalChatButton.dataset.content = modalContent.textContent; // Find the contributor for this prompt const promptCard = Array.from(document.querySelectorAll(".prompt-card")).find( (card) => card.querySelector(".prompt-title").textContent.trim() === title.trim() ); if (promptCard) { const contributorBadge = promptCard.querySelector(".contributor-badge"); if (contributorBadge) { modalContributor.href = contributorBadge.href; modalContributor.textContent = `Contributed by ${contributorBadge.textContent}`; } } // Add copy functionality modalCopyButton.addEventListener("click", async () => { try { copyPrompt(modalCopyButton, modalContent.textContent); modalCopyButton.innerHTML = ` `; setTimeout(() => { modalCopyButton.innerHTML = ` `; }, 2000); } catch (err) { alert("Failed to copy prompt to clipboard"); } }); modalOverlay.style.display = "block"; document.body.style.overflow = "hidden"; } function hideModal() { const modalOverlay = document.getElementById("modalOverlay"); if (!modalOverlay) return; modalOverlay.style.display = "none"; document.body.style.overflow = ""; // Optional: Remove modal from DOM when hidden modalOverlay.remove(); } let selectedPlatform = localStorage.getItem("selected-platform") || "github-copilot"; // Get from localStorage or default to github // Platform toggle functionality document.querySelectorAll(".platform-tag").forEach((button) => { button.addEventListener("click", () => { document .querySelectorAll(".platform-tag") .forEach((btn) => btn.classList.remove("active")); button.classList.add("active"); selectedPlatform = button.dataset.platform; localStorage.setItem("selected-platform", selectedPlatform); // Hide/show chat buttons based on platform const chatButtons = document.querySelectorAll( ".chat-button, .modal-chat-button" ); const shouldHideChat = ["gemini", "llama"].includes(selectedPlatform); chatButtons.forEach((btn) => { btn.style.display = shouldHideChat ? "none" : "flex"; }); // Auto-select technical tone and developers audience for GitHub Copilot if (selectedPlatform === "github-copilot") { const toneSelect = document.getElementById('toneSelect'); const audienceSelect = document.getElementById('audienceSelect'); // Set tone to technical toneSelect.value = 'technical'; localStorage.setItem('selected-tone', 'technical'); // Set audience to developers audienceSelect.value = 'developers'; localStorage.setItem('audience', 'developers'); // Update dev mode class on body document.body.classList.add('dev-mode'); // Update chat button icons updateChatButtonIcons(true); // Trigger prompt filtering for dev mode filterPrompts(); } }); }); // Set active platform from localStorage and handle initial button visibility const platformToActivate = document.querySelector(`[data-platform="${selectedPlatform}"]`) || document.querySelector('[data-platform="github-copilot"]'); platformToActivate.classList.add("active"); // Set initial chat button visibility const shouldHideChat = ["gemini", "llama"].includes(selectedPlatform); document.querySelectorAll(".chat-button, .modal-chat-button").forEach((btn) => { btn.style.display = shouldHideChat ? "none" : "flex"; }); // Function to open prompt in selected AI chat platform function openInChat(button, encodedPrompt) { const promptText = buildPrompt(encodedPrompt); const platform = document.querySelector(".platform-tag.active"); if (!platform) return; const baseUrl = platform.dataset.url; let url; switch (platform.dataset.platform) { case "github-copilot": url = `${baseUrl}?prompt=${encodeURIComponent(promptText)}`; break; case "chatgpt": url = `${baseUrl}?prompt=${encodeURIComponent(promptText)}`; break; case "claude": url = `${baseUrl}?q=${encodeURIComponent(promptText)}`; break; case "perplexity": url = `${baseUrl}/search?q=${encodeURIComponent(promptText)}`; break; case "mistral": url = `${baseUrl}?q=${encodeURIComponent(promptText)}`; break; default: url = `${baseUrl}?q=${encodeURIComponent(promptText)}`; } window.open(url, "_blank"); } function buildPrompt(encodedPrompt) { let promptText = decodeURIComponent(encodedPrompt); // If there's a modal open, use the current state of variables const modalContent = document.querySelector(".modal-content"); if (modalContent) { // Get all variable inputs const form = document.querySelector(".variable-form"); if (form) { const inputs = form.querySelectorAll(".variable-input"); inputs.forEach((input) => { const value = input.value.trim(); const variable = input.dataset.variable; const defaultValue = input.dataset.default; const pattern = new RegExp(`\\$\{${variable}[^}]*\}`, "g"); // Use value or default value const replacement = value || defaultValue || variable; promptText = promptText.replace(pattern, replacement); }); } } // Clean up newlines and normalize whitespace promptText = promptText.replace(/\s+/g, ' ').trim(); // Get language, tone and audience preferences const languageSelect = document.getElementById('languageSelect'); const customLanguage = document.getElementById('customLanguage'); const toneSelect = document.getElementById('toneSelect'); const customTone = document.getElementById('customTone'); const audienceSelect = document.getElementById('audienceSelect'); const language = languageSelect.value === 'custom' ? customLanguage.value : languageSelect.value; const tone = toneSelect.value === 'custom' ? customTone.value : toneSelect.value; const audience = audienceSelect.value; // Append preferences as a new line promptText += ` Reply in ${language} using ${tone} tone for ${audience}.`; return promptText; } // Existing copy function async function copyPrompt(button, encodedPrompt) { try { const promptText = buildPrompt(encodedPrompt); await navigator.clipboard.writeText(promptText); const originalHTML = button.innerHTML; button.innerHTML = ` `; setTimeout(() => { button.innerHTML = originalHTML; }, 2000); } catch (err) { console.error("Failed to copy text: ", err); } } // Function to handle chat button click in modal function openModalChat() { const modalContent = document.querySelector(".modal-content"); if (modalContent) { const content = modalContent.textContent; openInChat(null, encodeURIComponent(content.trim())); } } // Add these functions before the closing script tag function showCopilotSuggestion() { const modal = document.getElementById("copilotSuggestionModal"); const backdrop = document.querySelector(".copilot-suggestion-backdrop"); if (modal) { if (!backdrop) { const backdropDiv = document.createElement("div"); backdropDiv.className = "copilot-suggestion-backdrop"; document.body.appendChild(backdropDiv); } modal.style.display = "block"; backdrop.style.display = "block"; document.body.style.overflow = "hidden"; } } function hideCopilotSuggestion(switchToCopilot) { const modal = document.getElementById("copilotSuggestionModal"); const backdrop = document.querySelector(".copilot-suggestion-backdrop"); const doNotShowCheckbox = document.getElementById("doNotShowAgain"); if (doNotShowCheckbox && doNotShowCheckbox.checked) { localStorage.setItem("copilot-suggestion-hidden", "true"); } if (switchToCopilot) { const copilotButton = document.querySelector( '[data-platform="github-copilot"]' ); if (copilotButton) { copilotButton.click(); } } if (modal) { modal.style.display = "none"; if (backdrop) { backdrop.style.display = "none"; } document.body.style.overflow = ""; } } // Function to update chat button icons based on dev mode function updateChatButtonIcons(isDevMode) { document .querySelectorAll(".chat-button, .modal-chat-button") .forEach((button) => { const chatIcon = button.querySelector(".chat-icon"); const terminalIcon = button.querySelector(".terminal-icon"); if (chatIcon && terminalIcon) { chatIcon.style.display = isDevMode ? "none" : "block"; terminalIcon.style.display = isDevMode ? "block" : "none"; } }); } // Language and Tone Selection function initializeLanguageAndTone() { const languageSelect = document.getElementById('languageSelect'); const customLanguage = document.getElementById('customLanguage'); const toneSelect = document.getElementById('toneSelect'); const customTone = document.getElementById('customTone'); // Load saved preferences const savedLanguage = localStorage.getItem('selected-language'); const savedCustomLanguage = localStorage.getItem('custom-language'); const savedTone = localStorage.getItem('selected-tone'); const savedCustomTone = localStorage.getItem('custom-tone'); if (savedLanguage) { languageSelect.value = savedLanguage; if (savedLanguage === 'custom' && savedCustomLanguage) { customLanguage.value = savedCustomLanguage; customLanguage.style.display = 'inline-block'; } } if (savedTone) { toneSelect.value = savedTone; if (savedTone === 'custom' && savedCustomTone) { customTone.value = savedCustomTone; customTone.style.display = 'inline-block'; } } // Language select handler languageSelect.addEventListener('change', (e) => { const isCustom = e.target.value === 'custom'; customLanguage.style.display = isCustom ? 'inline-block' : 'none'; localStorage.setItem('selected-language', e.target.value); if (!isCustom) { customLanguage.value = ''; localStorage.removeItem('custom-language'); } }); // Custom language input handler customLanguage.addEventListener('input', (e) => { localStorage.setItem('custom-language', e.target.value); }); // Tone select handler toneSelect.addEventListener('change', (e) => { const isCustom = e.target.value === 'custom'; customTone.style.display = isCustom ? 'inline-block' : 'none'; localStorage.setItem('selected-tone', e.target.value); if (!isCustom) { customTone.value = ''; localStorage.removeItem('custom-tone'); } }); // Custom tone input handler customTone.addEventListener('input', (e) => { localStorage.setItem('custom-tone', e.target.value); }); }