Spaces:
Running
Running
Manual changes saved
Browse files- scorecard.html +143 -187
scorecard.html
CHANGED
|
@@ -193,248 +193,208 @@
|
|
| 193 |
|
| 194 |
<script>
|
| 195 |
document.addEventListener('DOMContentLoaded', function() {
|
| 196 |
-
// --- UI ELEMENTS & SETUP ---
|
| 197 |
AOS.init({ once: true, duration: 600 });
|
| 198 |
feather.replace();
|
| 199 |
|
| 200 |
-
// Mobile Menu Toggle
|
| 201 |
-
const mobileMenuButton = document.getElementById('mobileMenuButton');
|
| 202 |
-
const mobileMenu = document.getElementById('mobileMenu');
|
| 203 |
-
mobileMenuButton.addEventListener('click', () => {
|
| 204 |
-
mobileMenu.classList.toggle('hidden');
|
| 205 |
-
mobileMenuButton.classList.toggle('open');
|
| 206 |
-
});
|
| 207 |
-
|
| 208 |
-
// Theme Toggle
|
| 209 |
-
const themeToggle = document.getElementById('themeToggle');
|
| 210 |
-
const html = document.documentElement;
|
| 211 |
-
themeToggle.addEventListener('click', () => {
|
| 212 |
-
html.classList.toggle('dark');
|
| 213 |
-
localStorage.theme = html.classList.contains('dark') ? 'dark' : 'light';
|
| 214 |
-
feather.replace();
|
| 215 |
-
});
|
| 216 |
-
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
| 217 |
-
html.classList.add('dark');
|
| 218 |
-
} else {
|
| 219 |
-
html.classList.remove('dark');
|
| 220 |
-
}
|
| 221 |
-
|
| 222 |
-
// Set active nav link
|
| 223 |
-
const currentPage = window.location.pathname.split('/').pop() || 'index.html';
|
| 224 |
-
document.querySelectorAll('.nav-link').forEach(link => {
|
| 225 |
-
if (link.getAttribute('href') === currentPage) {
|
| 226 |
-
link.classList.add('active');
|
| 227 |
-
} else {
|
| 228 |
-
link.classList.remove('active');
|
| 229 |
-
}
|
| 230 |
-
});
|
| 231 |
-
|
| 232 |
// --- DATA & STATE MANAGEMENT ---
|
| 233 |
const questions = [
|
| 234 |
-
{
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 244 |
];
|
| 245 |
|
| 246 |
-
const industryInsights = {
|
| 247 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 248 |
};
|
| 249 |
|
| 250 |
-
const industrySpecificAdvice = {
|
| 251 |
-
'FSI': { 'IDENTIFIED PAIN': 'Frame the pain in terms of regulatory compliance, risk mitigation, or fraud detection. FSI buyers are heavily motivated by these pressures.', 'METRICS & MOTIVES': 'Focus on metrics like ROI, reduction in compliance penalties, and cost of capital. The Economic Buyer will need a business case built on these specific KPIs.', 'PAPER PROCESS': 'The legal and compliance review in FSI is rigorous. Proactively provide security documentation and compliance certificates to accelerate this stage.' }, 'Healthcare': { 'IDENTIFIED PAIN': 'Pain in Healthcare is often tied to patient data privacy (HIPAA), interoperability with EHR/EMR systems, or improving patient outcomes. Your solution must align with these critical areas.', 'CHAMPIONS': 'A strong champion in Healthcare is often a clinical leader who feels the pain directly, not just an IT manager. Find someone whose goals are tied to patient care or operational efficiency.', 'DECISION CRITERIA': 'Criteria will heavily weigh on data security and HIPAA compliance. Ensure you are positioned as the most secure and compliant option against competitors.' }, 'Tech (SaaS)': { 'COMPETITION': 'The SaaS market is crowded. Your competitive advantage must be crystal clear—is it developer-friendly APIs, better integration capabilities, or a superior UX? Hammer this point with your champion.', 'ECONOMIC BUYER': 'Confirm the budget source. Is it coming from an operational budget, or does it require a new capital expenditure request? This dramatically impacts the timeline in fast-moving tech companies.', 'GO LIVE PLAN': 'Offer a "quick start" or phased implementation plan. SaaS buyers value rapid time-to-value and want to see an impact quickly.' }
|
| 252 |
-
};
|
| 253 |
-
|
| 254 |
-
const summarySnippets = {
|
| 255 |
-
'IDENTIFIED PAIN': 'Clarify and quantify the business pain with the Economic Buyer.', 'CHAMPIONS': 'Develop a stronger relationship with your champion or find a new one closer to the EB.', 'GO LIVE PLAN': 'Formalize the implementation plan and get stakeholder buy-in.', 'METRICS & MOTIVES': 'Agree on measurable success metrics (QBC) that align with business goals.', 'DECISION CRITERIA': 'Influence the decision criteria to favor your unique strengths.', 'DECISION PROCESS': 'Establish a compelling event to create urgency.', 'COMPETITION': 'Set competitive traps and clearly articulate your unique differentiators.', 'BLOCKERS?': 'Identify all potential blockers and create a mitigation plan.', 'ECONOMIC BUYER': 'Secure access to the Economic Buyer and confirm budget.', 'PAPER PROCESS': 'De-risk the procurement stage by engaging with legal and security early.'
|
| 256 |
-
};
|
| 257 |
-
|
| 258 |
-
// DOM elements
|
| 259 |
-
const industryScreen = document.getElementById('industry-screen');
|
| 260 |
-
const industrySelect = document.getElementById('industry');
|
| 261 |
-
const salesStageSelect = document.getElementById('sales-stage');
|
| 262 |
-
const startBtn = document.getElementById('start-btn');
|
| 263 |
-
const questionScreens = document.getElementById('question-screens');
|
| 264 |
-
const progressBar = document.getElementById('progress-bar');
|
| 265 |
-
const resultsScreen = document.getElementById('results-screen');
|
| 266 |
-
const scorePercentage = document.getElementById('score-percentage');
|
| 267 |
-
const scoreMessage = document.getElementById('score-message');
|
| 268 |
-
const industryInsightsDiv = document.getElementById('industry-insights');
|
| 269 |
-
const scoreBreakdown = document.getElementById('score-breakdown');
|
| 270 |
-
const executiveSummary = document.getElementById('executive-summary');
|
| 271 |
-
const restartQuizBtn = document.getElementById('restart-quiz');
|
| 272 |
-
|
| 273 |
-
// App state
|
| 274 |
-
let currentQuestion = 0;
|
| 275 |
-
let selectedIndustry = '';
|
| 276 |
-
let selectedSalesStage = '';
|
| 277 |
-
let userAnswers = [];
|
| 278 |
-
const maxPossibleScore = questions.length * 9;
|
| 279 |
-
|
| 280 |
// --- EVENT LISTENERS ---
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
}
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
startBtn.addEventListener('click', function() {
|
| 288 |
-
industryScreen.classList.add('hidden');
|
| 289 |
-
questionScreens.classList.remove('hidden');
|
| 290 |
-
renderQuestion(currentQuestion);
|
| 291 |
-
});
|
| 292 |
-
|
| 293 |
-
restartQuizBtn.addEventListener('click', resetQuiz);
|
| 294 |
|
| 295 |
// --- CORE FUNCTIONS ---
|
| 296 |
function resetQuiz() {
|
| 297 |
-
currentQuestion = 0;
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
startBtn.disabled = true;
|
| 304 |
-
|
| 305 |
-
|
| 306 |
AOS.refresh();
|
| 307 |
}
|
| 308 |
|
| 309 |
function renderQuestion(index) {
|
| 310 |
-
if (index >= questions.length) {
|
| 311 |
-
showResults();
|
| 312 |
-
return;
|
| 313 |
-
}
|
| 314 |
|
| 315 |
const question = questions[index];
|
| 316 |
-
|
| 317 |
-
progressBar.style.width = `${progress}%`;
|
| 318 |
|
| 319 |
const questionScreen = document.createElement('div');
|
| 320 |
questionScreen.className = `question-screen flex flex-col pt-16 p-6 bg-gray-100 dark:bg-gray-900 fade-in`;
|
| 321 |
|
| 322 |
-
const backButtonHTML = `<button id="back-btn
|
| 323 |
-
|
|
|
|
| 324 |
questionScreen.innerHTML = `
|
| 325 |
<div class="max-w-2xl mx-auto w-full">
|
| 326 |
<div class="mb-4 text-center">
|
| 327 |
-
|
|
|
|
| 328 |
<h2 class="text-2xl font-bold mt-1 mb-2">${question.question}</h2>
|
| 329 |
</div>
|
| 330 |
<div class="mb-6">
|
| 331 |
-
<div class="relative">
|
| 332 |
-
<select id="answer-${index}" class="w-full p-3 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-purple-500 focus:outline-none">
|
| 333 |
-
<option value="" disabled selected>Select an answer</option>
|
| 334 |
-
${question.answers.map(a => `<option value="${a.score}">${a.text}</option>`).join('')}
|
| 335 |
-
</select>
|
| 336 |
-
</div>
|
| 337 |
-
</div>
|
| 338 |
-
<div class="flex items-center gap-4">
|
| 339 |
-
${backButtonHTML}
|
| 340 |
-
<button id="next-btn-${index}" disabled class="w-2/3 py-3 bg-purple-600 text-white font-semibold rounded-lg shadow-md hover:bg-purple-700 transition disabled:opacity-50 disabled:cursor-not-allowed">
|
| 341 |
-
${index === questions.length - 1 ? 'Finish Qualification' : 'Next Question'}
|
| 342 |
-
</button>
|
| 343 |
</div>
|
|
|
|
| 344 |
</div>
|
| 345 |
`;
|
| 346 |
|
| 347 |
-
|
| 348 |
-
|
| 349 |
feather.replace();
|
| 350 |
|
| 351 |
-
const answerSelect = document.getElementById(
|
| 352 |
-
const nextBtn = document.getElementById(
|
| 353 |
-
const backBtn = document.getElementById(
|
| 354 |
|
| 355 |
answerSelect.addEventListener('change', () => { nextBtn.disabled = !answerSelect.value; });
|
| 356 |
|
| 357 |
nextBtn.addEventListener('click', () => {
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
score: parseInt(answerSelect.value),
|
| 362 |
-
section: question.section
|
| 363 |
-
});
|
| 364 |
-
currentQuestion++;
|
| 365 |
-
renderQuestion(currentQuestion);
|
| 366 |
});
|
| 367 |
|
| 368 |
backBtn.addEventListener('click', () => {
|
| 369 |
-
if (index > 0) {
|
| 370 |
-
currentQuestion--;
|
| 371 |
-
userAnswers.pop();
|
| 372 |
-
renderQuestion(currentQuestion);
|
| 373 |
-
} else {
|
| 374 |
-
resetQuiz();
|
| 375 |
-
}
|
| 376 |
});
|
| 377 |
}
|
| 378 |
|
| 379 |
function showResults() {
|
| 380 |
-
|
| 381 |
-
|
| 382 |
AOS.refresh();
|
| 383 |
|
| 384 |
-
const totalScore =
|
| 385 |
-
const
|
| 386 |
-
const maxNormalizedScore = maxPossibleScore + (questions.length * 5);
|
| 387 |
-
const percentage = Math.round((normalizedScore / maxNormalizedScore) * 100);
|
| 388 |
-
|
| 389 |
-
scorePercentage.textContent = `${percentage}%`;
|
| 390 |
|
| 391 |
-
|
| 392 |
-
else if (percentage >= 60) scoreMessage.textContent = 'Good chance of winning. Focus on improving weaker areas.';
|
| 393 |
-
else if (percentage >= 40) scoreMessage.textContent = 'Moderate chance. Significant improvements needed in several areas.';
|
| 394 |
-
else scoreMessage.textContent = 'Low probability. Re-evaluate if this opportunity is worth pursuing.';
|
| 395 |
|
| 396 |
-
|
|
|
|
|
|
|
|
|
|
| 397 |
|
| 398 |
-
|
| 399 |
-
|
| 400 |
-
|
|
|
|
|
|
|
| 401 |
let scoreColor = 'text-red-600 dark:text-red-400', recommendationHTML = '';
|
| 402 |
|
| 403 |
if (scoreRatio >= 0.7) scoreColor = 'text-green-600 dark:text-green-400';
|
| 404 |
else if (scoreRatio >= 0.4) scoreColor = 'text-yellow-600 dark:text-yellow-400';
|
| 405 |
|
| 406 |
if (answer.score < 5) {
|
| 407 |
-
let advice =
|
| 408 |
-
const genericAdvice = { 'IDENTIFIED PAIN': 'Work with the customer to better define their business pain and how your solution addresses it.', 'CHAMPIONS': 'Identify and engage with champions who can influence the economic buyer.', 'GO LIVE PLAN': 'Develop a clear implementation plan with agreed timelines and milestones.', 'METRICS & MOTIVES': 'Establish clear metrics for success that are agreed by all stakeholders.', 'DECISION CRITERIA': 'Ensure your solution meets the customer\'s decision criteria or work to influence those criteria.', 'DECISION PROCESS': 'Identify and document the compelling reason for the customer to act now.', 'COMPETITION': 'Differentiate your solution and establish why you\'re the preferred choice.', 'BLOCKERS?': 'Proactively identify and address any potential blockers to the deal progressing.', 'ECONOMIC BUYER': 'Confirm budget availability and secure commitment from the economic buyer.', 'PAPER PROCESS': 'Advance discussions on pricing and contractual terms to avoid last-minute hurdles.' };
|
| 409 |
-
|
| 410 |
-
if (industrySpecificAdvice[selectedIndustry] && industrySpecificAdvice[selectedIndustry][answer.section]) {
|
| 411 |
-
advice = industrySpecificAdvice[selectedIndustry][answer.section];
|
| 412 |
-
} else if (genericAdvice[answer.section]) {
|
| 413 |
-
advice = genericAdvice[answer.section];
|
| 414 |
-
}
|
| 415 |
recommendationHTML = `<div class="mt-3 pt-3 border-t border-red-200 dark:border-gray-700 bg-red-50 dark:bg-red-900/20 p-3 rounded-b-lg -m-4 mt-4"><p class="text-sm font-medium text-red-800 dark:text-red-200"><strong>Recommendation:</strong> ${advice}</p></div>`;
|
| 416 |
}
|
| 417 |
const sectionScore = `<div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-sm"><div class="flex justify-between items-start mb-2"><h4 class="font-medium">${answer.section}</h4><span class="font-bold ${scoreColor}">${answer.score}/9</span></div><p class="text-sm text-gray-600 dark:text-gray-400">${answer.answer}</p>${recommendationHTML}</div>`;
|
| 418 |
-
scoreBreakdown.insertAdjacentHTML('beforeend', sectionScore);
|
| 419 |
});
|
| 420 |
|
| 421 |
-
generateExecutiveSummary(
|
| 422 |
-
|
| 423 |
feather.replace();
|
| 424 |
}
|
| 425 |
|
| 426 |
function generateExecutiveSummary(answers, overallScore, salesStage) {
|
| 427 |
let weaknesses = [];
|
| 428 |
-
const metricsMotiveAnswer = answers.find(a => a.section === '
|
| 429 |
const sortedAnswers = [...answers].sort((a, b) => a.score - b.score);
|
| 430 |
|
| 431 |
if (metricsMotiveAnswer && metricsMotiveAnswer.score < 5) {
|
| 432 |
weaknesses.push(metricsMotiveAnswer);
|
| 433 |
-
const nextWeakest = sortedAnswers.find(a => a.section !== '
|
| 434 |
-
if (nextWeakest) weaknesses.push(nextWeakest);
|
| 435 |
-
} else {
|
| 436 |
-
weaknesses = sortedAnswers.slice(0, 2);
|
| 437 |
-
}
|
| 438 |
|
| 439 |
const strength = sortedAnswers[sortedAnswers.length - 1];
|
| 440 |
let summaryHTML = '<ul class="space-y-3 text-gray-700 dark:text-gray-300">';
|
|
@@ -445,20 +405,19 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
| 445 |
|
| 446 |
weaknesses.forEach(weakness => {
|
| 447 |
const snippet = summarySnippets[weakness.section] || 'This area needs to be addressed.';
|
| 448 |
-
|
| 449 |
});
|
| 450 |
summaryHTML += '</ul>';
|
| 451 |
|
| 452 |
let strategicMessage = '';
|
| 453 |
-
if (overallScore <= 19)
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
if (salesStage === '
|
| 457 |
-
else
|
| 458 |
-
else strategicMessage = "Be cautious. A deal this underqualified should not be seen as ready to close.";
|
| 459 |
} else if (overallScore <= 59) {
|
| 460 |
-
if (salesStage === 'Early Stage') strategicMessage = "Very good
|
| 461 |
-
else if (salesStage === 'Evaluation / PoC') strategicMessage = "
|
| 462 |
else strategicMessage = "Look for blockers. Can the champion access the Economic Buyer? Is this a champion or a coach?";
|
| 463 |
} else if (overallScore <= 79) {
|
| 464 |
strategicMessage = salesStage === 'Evaluation / PoC' ? "Very strong for a PoC. Start preparing success metrics and crafting the proposal." : "Focus on differentiation and beware of the buyer ghosting as you move to close.";
|
|
@@ -466,15 +425,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
| 466 |
strategicMessage = "The finish line is in sight, but it's not over until it's signed. Verbally discuss pricing/contracts with champions/buyers and expect negotiations.";
|
| 467 |
}
|
| 468 |
|
| 469 |
-
summaryHTML += `
|
| 470 |
-
|
| 471 |
-
<p class="text-base font-medium text-purple-700 dark:text-purple-400">${strategicMessage}</p>
|
| 472 |
-
</div>
|
| 473 |
-
`;
|
| 474 |
-
|
| 475 |
-
executiveSummary.innerHTML = summaryHTML;
|
| 476 |
}
|
| 477 |
|
|
|
|
|
|
|
| 478 |
});
|
| 479 |
</script>
|
| 480 |
|
|
|
|
| 193 |
|
| 194 |
<script>
|
| 195 |
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
| 196 |
AOS.init({ once: true, duration: 600 });
|
| 197 |
feather.replace();
|
| 198 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
// --- DATA & STATE MANAGEMENT ---
|
| 200 |
const questions = [
|
| 201 |
+
{
|
| 202 |
+
section: 'PAIN & METRICS',
|
| 203 |
+
subheading: 'Section 1: The Opportunity',
|
| 204 |
+
question: 'What is the quantifiable business pain?',
|
| 205 |
+
answers: [
|
| 206 |
+
{ text: 'EB agrees on a top-priority pain with a quantified business case (QBC)', score: 9 },
|
| 207 |
+
{ text: 'Champion agrees on the pain and we are building the business case', score: 6 },
|
| 208 |
+
{ text: 'Pain is defined but lacks clear metrics and EB involvement', score: 3 },
|
| 209 |
+
{ text: 'Pain is vague and no metrics have been discussed', score: 0 }
|
| 210 |
+
]
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
section: 'CHAMPION & EB',
|
| 214 |
+
subheading: 'Section 1: The Opportunity',
|
| 215 |
+
question: 'How strong is our relationship with the key personas?',
|
| 216 |
+
answers: [
|
| 217 |
+
{ text: 'Our Champion is selling on our behalf and we have EB engagement', score: 9 },
|
| 218 |
+
{ text: 'We have a tested Champion who is providing access to power', score: 6 },
|
| 219 |
+
{ text: 'We have a potential Champion but they are not yet tested', score: 3 },
|
| 220 |
+
{ text: 'No Champion or Economic Buyer identified', score: 0 }
|
| 221 |
+
]
|
| 222 |
+
},
|
| 223 |
+
{
|
| 224 |
+
section: 'DECISION PROCESS & CRITERIA',
|
| 225 |
+
subheading: 'Section 2: The Decision',
|
| 226 |
+
question: 'How will the decision be made and what are the requirements?',
|
| 227 |
+
answers: [
|
| 228 |
+
{ text: 'We influenced the criteria and the process is confirmed with the EB', score: 9 },
|
| 229 |
+
{ text: 'We know the process and criteria and believe we are aligned', score: 6 },
|
| 230 |
+
{ text: 'The decision process or criteria are partially understood', score: 3 },
|
| 231 |
+
{ text: 'The process and criteria are a black box', score: 0 }
|
| 232 |
+
]
|
| 233 |
+
},
|
| 234 |
+
{
|
| 235 |
+
section: 'COMPETITION & BLOCKERS',
|
| 236 |
+
subheading: 'Section 2: The Decision',
|
| 237 |
+
question: 'What internal and external forces can stop this deal?',
|
| 238 |
+
answers: [
|
| 239 |
+
{ text: 'We are seen as the preferred vendor and all blockers have a mitigation plan', score: 9 },
|
| 240 |
+
{ text: 'Competition is known, traps are set, and some blockers are identified', score: 6 },
|
| 241 |
+
{ text: 'We know of competitors but have not identified potential blockers', score: 3 },
|
| 242 |
+
{ text: 'Competitive landscape and internal blockers are unknown', score: 0 }
|
| 243 |
+
]
|
| 244 |
+
},
|
| 245 |
+
{
|
| 246 |
+
section: 'PAPER PROCESS',
|
| 247 |
+
subheading: 'Section 3: The Logistics',
|
| 248 |
+
question: 'How aligned are we on the procurement and legal process?',
|
| 249 |
+
answers: [
|
| 250 |
+
{ text: 'Pricing, contract, and security review process are fully confirmed', score: 9 },
|
| 251 |
+
{ text: 'We have had initial discussions on budget and the paper process', score: 6 },
|
| 252 |
+
{ text: 'A budget is confirmed but the paper process has not been discussed', score: 3 },
|
| 253 |
+
{ text: 'Budget and procurement process are unknown', score: 0 }
|
| 254 |
+
]
|
| 255 |
+
},
|
| 256 |
+
{
|
| 257 |
+
section: 'IMPLEMENTATION PLAN',
|
| 258 |
+
subheading: 'Section 3: The Logistics',
|
| 259 |
+
question: 'Is there a clear, agreed-upon plan for success after signing?',
|
| 260 |
+
answers: [
|
| 261 |
+
{ text: 'All stakeholders have agreed to a formal, joint implementation plan', score: 9 },
|
| 262 |
+
{ text: 'We have shared a draft implementation plan with our Champion', score: 6 },
|
| 263 |
+
{ text: 'Implementation has been discussed but no formal plan exists', score: 3 },
|
| 264 |
+
{ text: 'The post-sale process has not been discussed', score: 0 }
|
| 265 |
+
]
|
| 266 |
+
}
|
| 267 |
];
|
| 268 |
|
| 269 |
+
const industryInsights = { 'FSI': 'FSI buyers prioritize regulatory compliance, data security, and low latency for transactions and fraud detection.', 'Healthcare': 'Healthcare focuses on HIPAA/GDPR compliance, interoperability with EHR systems, and patient data privacy.', 'Public Sector & Education': 'Public Sector buyers value cost efficiency, scalability, and adherence to government/educational data policies.', 'Retail and Ecommerce': 'Retail needs omnichannel integration, AI-powered personalization, and real-time inventory/analytics.', 'Tech (SaaS)': 'SaaS companies look for developer-friendly APIs, scalability, and AI/ML tools for product innovation.', 'Cyber': 'Cyber security teams require advanced threat detection, zero-trust architecture, and AI-driven automation for incident response.', 'Media and Entertainment': 'Media firms need high-performance content delivery, AI for recommendation engines, and scalable storage.', 'Manufacturing': 'Manufacturing values predictive maintenance, IoT integration, and AI for supply chain optimization.', 'Energy': 'The Energy sector focuses on AI for predictive analytics, regulatory compliance, and operational resilience.', 'Logistics': 'Logistics companies prioritize real-time tracking, AI for route optimization, and supply chain integration.', 'Transport': 'Transportation firms need AI for fleet management, real-time analytics for safety/compliance, and IoT integration.', 'Startups': 'Startups look for pay-as-you-go pricing, rapid deployment, and AI tools to accelerate MVP development.' };
|
| 270 |
+
const summarySnippets = { 'PAIN & METRICS': 'Solidify the business case by quantifying the pain with the Economic Buyer.', 'CHAMPION & EB': 'Test your Champion and leverage them for greater access to the Economic Buyer.', 'DECISION PROCESS & CRITERIA': 'Influence the decision criteria and get the formal process in writing.', 'COMPETITION & BLOCKERS': 'Set competitive traps and proactively identify all potential deal blockers.', 'PAPER PROCESS': 'De-risk the closing stage by confirming the budget source and procurement process early.', 'IMPLEMENTATION PLAN': 'Co-create a success plan with the customer to show value beyond the signature.' };
|
| 271 |
+
const industrySpecificAdvice = { 'FSI': { 'PAIN & METRICS': 'Frame the pain in terms of regulatory compliance (e.g., GDPR), risk mitigation, or fraud detection. FSI buyers are heavily motivated by these.', 'PAPER PROCESS': 'The legal and compliance review in FSI is rigorous. Proactively provide security documentation to accelerate this stage.' }, 'Healthcare': { 'PAIN & METRICS': 'Pain in Healthcare is often tied to patient data privacy (HIPAA) or interoperability with EHR/EMR systems. Align with these.', 'DECISION PROCESS & CRITERIA': 'Criteria will heavily weigh on data security and HIPAA compliance. Position yourself as the most secure option.' }, 'Tech (SaaS)': { 'COMPETITION & BLOCKERS': 'The SaaS market is crowded. Your competitive advantage must be crystal clear—is it APIs, integrations, or UX?', 'IMPLEMENTATION PLAN': 'Offer a "quick start" or phased implementation plan. SaaS buyers value rapid time-to-value.' } };
|
| 272 |
+
|
| 273 |
+
// --- DOM & STATE ---
|
| 274 |
+
const app = {
|
| 275 |
+
screens: { industry: document.getElementById('industry-screen'), questions: document.getElementById('question-screens'), results: document.getElementById('results-screen') },
|
| 276 |
+
inputs: { industry: document.getElementById('industry'), salesStage: document.getElementById('sales-stage'), startBtn: document.getElementById('start-btn') },
|
| 277 |
+
ui: { progressBar: document.getElementById('progress-bar'), scorePercentage: document.getElementById('score-percentage'), scoreMessage: document.getElementById('score-message'), industryInsights: document.getElementById('industry-insights'), scoreBreakdown: document.getElementById('score-breakdown'), executiveSummary: document.getElementById('executive-summary') },
|
| 278 |
+
buttons: { restart: document.getElementById('restart-quiz'), themeToggle: document.getElementById('themeToggle'), mobileMenu: document.getElementById('mobileMenuButton') },
|
| 279 |
+
state: { currentQuestion: 0, industry: '', salesStage: '', answers: [], maxScore: questions.length * 9 }
|
| 280 |
};
|
| 281 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 282 |
// --- EVENT LISTENERS ---
|
| 283 |
+
app.inputs.industry.addEventListener('change', (e) => { app.state.industry = e.target.value; checkSelections(); });
|
| 284 |
+
app.inputs.salesStage.addEventListener('change', (e) => { app.state.salesStage = e.target.value; checkSelections(); });
|
| 285 |
+
app.inputs.startBtn.addEventListener('click', () => { app.screens.industry.classList.add('hidden'); app.screens.questions.classList.remove('hidden'); renderQuestion(app.state.currentQuestion); });
|
| 286 |
+
app.buttons.restart.addEventListener('click', resetQuiz);
|
| 287 |
+
|
| 288 |
+
function checkSelections() { app.inputs.startBtn.disabled = !(app.state.industry && app.state.salesStage); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 289 |
|
| 290 |
// --- CORE FUNCTIONS ---
|
| 291 |
function resetQuiz() {
|
| 292 |
+
app.state.currentQuestion = 0;
|
| 293 |
+
app.state.industry = '';
|
| 294 |
+
app.state.salesStage = '';
|
| 295 |
+
app.state.answers = [];
|
| 296 |
+
app.inputs.industry.value = "";
|
| 297 |
+
app.inputs.salesStage.value = "";
|
| 298 |
+
app.inputs.startBtn.disabled = true;
|
| 299 |
+
app.screens.results.classList.add('hidden');
|
| 300 |
+
app.screens.industry.classList.remove('hidden');
|
| 301 |
AOS.refresh();
|
| 302 |
}
|
| 303 |
|
| 304 |
function renderQuestion(index) {
|
| 305 |
+
if (index >= questions.length) { return showResults(); }
|
|
|
|
|
|
|
|
|
|
| 306 |
|
| 307 |
const question = questions[index];
|
| 308 |
+
app.ui.progressBar.style.width = `${(index / questions.length) * 100}%`;
|
|
|
|
| 309 |
|
| 310 |
const questionScreen = document.createElement('div');
|
| 311 |
questionScreen.className = `question-screen flex flex-col pt-16 p-6 bg-gray-100 dark:bg-gray-900 fade-in`;
|
| 312 |
|
| 313 |
+
const backButtonHTML = `<button id="back-btn" class="w-1/3 py-3 bg-gray-300 dark:bg-gray-700 text-gray-800 dark:text-gray-200 font-semibold rounded-lg shadow-md hover:bg-gray-400 dark:hover:bg-gray-600 transition">Back</button>`;
|
| 314 |
+
const subheadingHTML = `<p class="text-xs font-bold tracking-wider uppercase text-purple-400 mb-2">${question.subheading}</p>`;
|
| 315 |
+
|
| 316 |
questionScreen.innerHTML = `
|
| 317 |
<div class="max-w-2xl mx-auto w-full">
|
| 318 |
<div class="mb-4 text-center">
|
| 319 |
+
${subheadingHTML}
|
| 320 |
+
<span class="text-sm font-medium text-gray-500 dark:text-gray-400">${question.section}</span>
|
| 321 |
<h2 class="text-2xl font-bold mt-1 mb-2">${question.question}</h2>
|
| 322 |
</div>
|
| 323 |
<div class="mb-6">
|
| 324 |
+
<div class="relative"><select id="answer-select" class="w-full p-3 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-purple-500 focus:outline-none"><option value="" disabled selected>Select an answer</option>${question.answers.map(a => `<option value="${a.score}">${a.text}</option>`).join('')}</select></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 325 |
</div>
|
| 326 |
+
<div class="flex items-center gap-4">${backButtonHTML}<button id="next-btn" disabled class="w-2/3 py-3 bg-purple-600 text-white font-semibold rounded-lg shadow-md hover:bg-purple-700 transition disabled:opacity-50 disabled:cursor-not-allowed">${index === questions.length - 1 ? 'Finish Qualification' : 'Next Question'}</button></div>
|
| 327 |
</div>
|
| 328 |
`;
|
| 329 |
|
| 330 |
+
app.screens.questions.innerHTML = '';
|
| 331 |
+
app.screens.questions.appendChild(questionScreen);
|
| 332 |
feather.replace();
|
| 333 |
|
| 334 |
+
const answerSelect = document.getElementById('answer-select');
|
| 335 |
+
const nextBtn = document.getElementById('next-btn');
|
| 336 |
+
const backBtn = document.getElementById('back-btn');
|
| 337 |
|
| 338 |
answerSelect.addEventListener('change', () => { nextBtn.disabled = !answerSelect.value; });
|
| 339 |
|
| 340 |
nextBtn.addEventListener('click', () => {
|
| 341 |
+
app.state.answers.push({ section: question.section, answer: answerSelect.options[answerSelect.selectedIndex].text, score: parseInt(answerSelect.value) });
|
| 342 |
+
app.state.currentQuestion++;
|
| 343 |
+
renderQuestion(app.state.currentQuestion);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
});
|
| 345 |
|
| 346 |
backBtn.addEventListener('click', () => {
|
| 347 |
+
if (index > 0) { app.state.currentQuestion--; app.state.answers.pop(); renderQuestion(app.state.currentQuestion); } else { resetQuiz(); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 348 |
});
|
| 349 |
}
|
| 350 |
|
| 351 |
function showResults() {
|
| 352 |
+
app.screens.questions.classList.add('hidden');
|
| 353 |
+
app.screens.results.classList.remove('hidden');
|
| 354 |
AOS.refresh();
|
| 355 |
|
| 356 |
+
const totalScore = app.state.answers.reduce((sum, ans) => sum + ans.score, 0);
|
| 357 |
+
const percentage = Math.round((totalScore / app.state.maxScore) * 100);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 358 |
|
| 359 |
+
app.ui.scorePercentage.textContent = `${percentage}%`;
|
|
|
|
|
|
|
|
|
|
| 360 |
|
| 361 |
+
if (percentage >= 80) app.ui.scoreMessage.textContent = 'High probability of winning! This opportunity is well-qualified.';
|
| 362 |
+
else if (percentage >= 60) app.ui.scoreMessage.textContent = 'Good chance of winning. Focus on improving weaker areas.';
|
| 363 |
+
else if (percentage >= 40) app.ui.scoreMessage.textContent = 'Moderate chance. Significant improvements needed.';
|
| 364 |
+
else app.ui.scoreMessage.textContent = 'Low probability. Re-evaluate if this opportunity is worth pursuing.';
|
| 365 |
|
| 366 |
+
app.ui.industryInsights.innerHTML = `<p>${industryInsights[app.state.industry]}</p>`;
|
| 367 |
+
app.ui.scoreBreakdown.innerHTML = '';
|
| 368 |
+
|
| 369 |
+
app.state.answers.forEach(answer => {
|
| 370 |
+
const scoreRatio = answer.score / 9;
|
| 371 |
let scoreColor = 'text-red-600 dark:text-red-400', recommendationHTML = '';
|
| 372 |
|
| 373 |
if (scoreRatio >= 0.7) scoreColor = 'text-green-600 dark:text-green-400';
|
| 374 |
else if (scoreRatio >= 0.4) scoreColor = 'text-yellow-600 dark:text-yellow-400';
|
| 375 |
|
| 376 |
if (answer.score < 5) {
|
| 377 |
+
let advice = industrySpecificAdvice[app.state.industry]?.[answer.section] || summarySnippets[answer.section] || 'Focus on improving this area.';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 378 |
recommendationHTML = `<div class="mt-3 pt-3 border-t border-red-200 dark:border-gray-700 bg-red-50 dark:bg-red-900/20 p-3 rounded-b-lg -m-4 mt-4"><p class="text-sm font-medium text-red-800 dark:text-red-200"><strong>Recommendation:</strong> ${advice}</p></div>`;
|
| 379 |
}
|
| 380 |
const sectionScore = `<div class="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-sm"><div class="flex justify-between items-start mb-2"><h4 class="font-medium">${answer.section}</h4><span class="font-bold ${scoreColor}">${answer.score}/9</span></div><p class="text-sm text-gray-600 dark:text-gray-400">${answer.answer}</p>${recommendationHTML}</div>`;
|
| 381 |
+
app.ui.scoreBreakdown.insertAdjacentHTML('beforeend', sectionScore);
|
| 382 |
});
|
| 383 |
|
| 384 |
+
generateExecutiveSummary(app.state.answers, percentage, app.state.salesStage);
|
|
|
|
| 385 |
feather.replace();
|
| 386 |
}
|
| 387 |
|
| 388 |
function generateExecutiveSummary(answers, overallScore, salesStage) {
|
| 389 |
let weaknesses = [];
|
| 390 |
+
const metricsMotiveAnswer = answers.find(a => a.section === 'PAIN & METRICS');
|
| 391 |
const sortedAnswers = [...answers].sort((a, b) => a.score - b.score);
|
| 392 |
|
| 393 |
if (metricsMotiveAnswer && metricsMotiveAnswer.score < 5) {
|
| 394 |
weaknesses.push(metricsMotiveAnswer);
|
| 395 |
+
const nextWeakest = sortedAnswers.find(a => a.section !== 'PAIN & METRICS');
|
| 396 |
+
if (nextWeakest && weaknesses.length < 2) weaknesses.push(nextWeakest);
|
| 397 |
+
} else { weaknesses = sortedAnswers.slice(0, 2); }
|
|
|
|
|
|
|
| 398 |
|
| 399 |
const strength = sortedAnswers[sortedAnswers.length - 1];
|
| 400 |
let summaryHTML = '<ul class="space-y-3 text-gray-700 dark:text-gray-300">';
|
|
|
|
| 405 |
|
| 406 |
weaknesses.forEach(weakness => {
|
| 407 |
const snippet = summarySnippets[weakness.section] || 'This area needs to be addressed.';
|
| 408 |
+
summaryHTML += `<li class="flex items-start"><span class="mr-2 text-red-500">🔴</span><span><strong>Urgent Focus: ${weakness.section}</strong>. ${snippet}</span></li>`;
|
| 409 |
});
|
| 410 |
summaryHTML += '</ul>';
|
| 411 |
|
| 412 |
let strategicMessage = '';
|
| 413 |
+
if (overallScore <= 19) strategicMessage = salesStage === 'Evaluation / PoC' ? "Dangerous if considering an Eval/PoC with this low score." : "Okay if early, but more qualification is required.";
|
| 414 |
+
else if (overallScore <= 39) {
|
| 415 |
+
if (salesStage === 'Early Stage') strategicMessage = "Good news for an early stage deal. Now attach the offer to a mutually agreed business outcome.";
|
| 416 |
+
else if (salesStage === 'Evaluation / PoC') strategicMessage = "Be cautious. The business case for this PoC is not strong enough. Why now? Why us?";
|
| 417 |
+
else strategicMessage = "Be worried. A deal this weak should not be in the closing stage.";
|
|
|
|
| 418 |
} else if (overallScore <= 59) {
|
| 419 |
+
if (salesStage === 'Early Stage') strategicMessage = "Very good news for an early stage deal. A solid foundation to build upon.";
|
| 420 |
+
else if (salesStage === 'Evaluation / PoC') strategicMessage = "This looks good. Now, what are the blockers? Confirm timeline and budget.";
|
| 421 |
else strategicMessage = "Look for blockers. Can the champion access the Economic Buyer? Is this a champion or a coach?";
|
| 422 |
} else if (overallScore <= 79) {
|
| 423 |
strategicMessage = salesStage === 'Evaluation / PoC' ? "Very strong for a PoC. Start preparing success metrics and crafting the proposal." : "Focus on differentiation and beware of the buyer ghosting as you move to close.";
|
|
|
|
| 425 |
strategicMessage = "The finish line is in sight, but it's not over until it's signed. Verbally discuss pricing/contracts with champions/buyers and expect negotiations.";
|
| 426 |
}
|
| 427 |
|
| 428 |
+
summaryHTML += `<div class="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700"><p class="text-base font-medium text-purple-700 dark:text-purple-400">${strategicMessage}</p></div>`;
|
| 429 |
+
app.ui.executiveSummary.innerHTML = summaryHTML;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 430 |
}
|
| 431 |
|
| 432 |
+
// --- Mobile & Theme Handlers ---
|
| 433 |
+
app.buttons.mobileMenu.addEventListener('click', () => { document.getElementById('mobileMenu').classList.toggle('hidden'); app.buttons.mobileMenu.classList.toggle('open'); });
|
| 434 |
});
|
| 435 |
</script>
|
| 436 |
|