';
});
return html;
}
/* ── SCORE ── */
function scoreCard(name) {
var n = name.toLowerCase();
var score = 70;
if (n.length <= 6) score += 15;
else if (n.length <= 9) score += 8;
else if (n.length > 14) score -= 10;
if (!/[aeiou]/.test(n)) score -= 8;
var availCount = TLD_LIST.filter(function(t){ return !simulateDomain(name, t); }).length;
score += availCount * 3;
return Math.min(Math.max(score, 30), 99);
}
function scoreBadge(score) {
if (score >= 80) return '
Score ' + score + ' ';
if (score >= 60) return '
Score ' + score + ' ';
return '
Score ' + score + ' ';
}
/* ── RENDER CARD ── */
function renderCard(item, idx) {
var name = (item.name || '').trim();
var tagline = (item.tagline || '').trim();
var style = (item.style || '').trim();
var score = scoreCard(name);
var isSaved = savedNames.indexOf(name) !== -1;
return '
' +
'
' +
'
' + escHtml(name) + '
' +
'
' + escHtml(tagline) + '
' +
'
' +
(style ? '' + escHtml(style) + ' ' : '') +
scoreBadge(score) +
(TLD_LIST.filter(function(t){ return !simulateDomain(name,t); }).length > 2
? 'Domains free '
: '') +
'
' +
'
' +
'
' + buildDomainRows(name) + '
' +
'
' +
'' +
(isSaved ? '✓ Saved' : 'Save name') +
' ' +
'Copy name ' +
'
' +
'
';
}
/* ── GENERATE ── */
async function generate() {
var what = document.getElementById('inp-what').value.trim();
var sector = document.getElementById('inp-sector').value;
var audience = document.getElementById('inp-audience').value.trim();
var tone = document.getElementById('inp-tone').value;
var keywords = document.getElementById('inp-keywords').value.trim();
var count = parseInt(document.getElementById('inp-count').value) || 9;
var styles = getActiveStyles();
if (!what) {
showError('Please describe what your startup does before generating names.');
return;
}
hideError();
setLoading(true);
var prompt =
'You are a world-class startup naming expert specialising in the Indian market. ' +
'Generate exactly ' + count + ' creative, memorable startup name ideas based on these details:\n\n' +
'What it does: ' + what + '\n' +
'Sector: ' + sector + '\n' +
(audience ? 'Target audience: ' + audience + '\n' : '') +
'Brand personality: ' + tone + '\n' +
(keywords ? 'Keywords guidance: ' + keywords + '\n' : '') +
'Preferred name styles (use a mix): ' + styles.join(', ') + '\n\n' +
'Requirements for each name:\n' +
'- Maximum 12 characters (shorter is better, aim for 5-9)\n' +
'- Easy to pronounce in Hindi, English, and South Indian languages\n' +
'- No generic suffixes like "ify", "ly", "hub", "tech" unless creative\n' +
'- Avoid names that sound negative or mean something bad in Indian languages\n' +
'- Be creative: try Sanskrit roots, portmanteaus, invented words, metaphors\n' +
'- Each name must feel distinctive and ownable as a brand\n\n' +
'Respond ONLY with a valid JSON array. No markdown, no backticks, no explanation. Format:\n' +
'[\n' +
' {"name": "Kiraana", "tagline": "Your neighbourhood, digitised", "style": "Hindi-inspired"},\n' +
' ...\n' +
']\n\n' +
'Generate ' + count + ' names now:';
try {
var resp = await fetch('https://startupindiax.com/gemini-proxy.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: prompt })
});
if (!resp.ok) {
var errData = await resp.json().catch(function(){ return {}; });
throw new Error(errData.error || 'API error ' + resp.status);
}
var data = await resp.json();
if (data.error) throw new Error(data.error);
var raw = data.text || '';
var cleaned = raw.replace(/```json|```/g, '').trim();
var firstBracket = cleaned.indexOf('[');
var lastBracket = cleaned.lastIndexOf(']');
if (firstBracket === -1 || lastBracket === -1) throw new Error('Could not parse response. Please try again.');
cleaned = cleaned.slice(firstBracket, lastBracket + 1);
var names = JSON.parse(cleaned);
if (!Array.isArray(names) || names.length === 0) throw new Error('No names returned. Please try again.');
renderResults(names, sector);
} catch (err) {
showError('Generation failed: ' + err.message + '. Please check your connection and try again.');
} finally {
setLoading(false);
}
}
function renderResults(names, sector) {
var grid = document.getElementById('name-grid');
grid.innerHTML = names.map(function(item, i){ return renderCard(item, i); }).join('');
document.getElementById('results-title').textContent = names.length + ' names for your ' + sector + ' startup';
document.getElementById('results-meta').textContent = 'Domain availability is indicative — verify before buying';
document.getElementById('results-section').classList.add('visible');
document.getElementById('results-section').scrollIntoView({ behavior: 'smooth', block: 'start' });
}
/* ── SAVE / COPY ── */
function toggleSave(name, btn) {
var idx = savedNames.indexOf(name);
if (idx === -1) {
savedNames.push(name);
btn.textContent = '\u2713 Saved';
btn.classList.add('saved');
} else {
savedNames.splice(idx, 1);
btn.textContent = 'Save name';
btn.classList.remove('saved');
}
renderSaved();
}
function renderSaved() {
var sec = document.getElementById('saved-section');
var chips = document.getElementById('saved-chips');
if (savedNames.length === 0) { sec.classList.remove('visible'); return; }
sec.classList.add('visible');
chips.innerHTML = savedNames.map(function(n) {
return '
' + escHtml(n) +
'×
';
}).join('');
}
function removeSaved(name) {
savedNames = savedNames.filter(function(n){ return n !== name; });
document.querySelectorAll('.save-btn').forEach(function(btn) {
if (btn.closest('.name-card') && btn.closest('.name-card').querySelector('.name-display') &&
btn.closest('.name-card').querySelector('.name-display').textContent === name) {
btn.textContent = 'Save name';
btn.classList.remove('saved');
}
});
renderSaved();
}
function clearSaved() {
savedNames = [];
document.querySelectorAll('.save-btn.saved').forEach(function(btn) {
btn.textContent = 'Save name';
btn.classList.remove('saved');
});
renderSaved();
}
function copyName(name, btn) {
navigator.clipboard.writeText(name).then(function() {
var orig = btn.textContent;
btn.textContent = 'Copied!';
setTimeout(function(){ btn.textContent = orig; }, 1500);
}).catch(function() {
btn.textContent = name;
setTimeout(function(){ btn.textContent = 'Copy name'; }, 2000);
});
}
/* ── HELPERS ── */
function setLoading(on) {
document.getElementById('loading-strip').classList.toggle('visible', on);
document.getElementById('gen-btn').disabled = on;
if (on) document.getElementById('results-section').classList.remove('visible');
}
function showError(msg) {
var el = document.getElementById('error-box');
el.textContent = msg;
el.classList.add('visible');
el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
function hideError() {
document.getElementById('error-box').classList.remove('visible');
}
function escHtml(s) {
return String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"');
}
function escAttr(s) {
return String(s).replace(/'/g, '\\\'').replace(/"/g, '"');
}
/* Allow Enter key in text fields */
['inp-what','inp-audience','inp-keywords'].forEach(function(id) {
var el = document.getElementById(id);
if (el) el.addEventListener('keydown', function(e){ if (e.key === 'Enter') generate(); });
});