/**
* Content Loader — Fetches messaging.json and injects ALL visitor-facing content.
* No hardcoded copy in index.html — everything comes from the JSON.
* Falls back gracefully if fetch fails (empty sections, no crash).
*/
(async function loadContent() {
let data;
try {
const res = await fetch('/strategy/messaging.json');
if (!res.ok) throw new Error(res.status);
data = await res.json();
} catch (e) {
console.warn('Content loader: messaging.json unavailable.');
return;
}
// --- Hero ---
setText('[data-content="hero-headline"]', data.brand.hero_headline);
setText('[data-content="hero-subheading"]', data.brand.hero_subheading);
setText('[data-content="urgency-line"]', data.brand.urgency_line);
// --- Problem ---
setText('[data-content="problem-headline"]', data.problem.short_headline);
setText('[data-content="problem-description"]', data.problem.short_description);
// --- How It Works ---
const howSteps = document.querySelectorAll('[data-content="how-step"]');
howSteps.forEach((el, i) => {
if (data.how_it_works[i]) {
setText('[data-content="step-title"]', data.how_it_works[i].title, el);
setText('[data-content="step-description"]', data.how_it_works[i].description, el);
}
});
// --- Use Cases (dynamic generation) ---
const useCasesGrid = document.getElementById('use-cases-grid');
if (useCasesGrid && data.use_cases) {
useCasesGrid.innerHTML = data.use_cases.map(uc => `
${esc(uc.title)}
${esc(uc.description)}
`).join('');
}
// --- Chat Demo (tabbed: whatsapp_screening + checkin) ---
const demoKeys = ['whatsapp_screening', 'checkin'];
const demos = demoKeys.map(k => data.chat_examples[k]).filter(Boolean);
if (demos.length) {
// Build tabs
const tabsContainer = document.getElementById('chat-demo-tabs');
if (tabsContainer) {
tabsContainer.innerHTML = demos.map((demo, i) => `
`).join('');
}
function renderDemo(index) {
const demo = demos[index];
// Update tab styles
document.querySelectorAll('.demo-tab').forEach((tab, i) => {
tab.className = `demo-tab px-5 py-2 rounded-full text-sm font-semibold transition ${i === index ? 'bg-black text-white' : 'bg-gray-200 text-gray-600 hover:bg-gray-300'}`;
});
// Render chat
const container = document.getElementById('chat-demo-container');
if (container) {
container.innerHTML = `
`;
demo.messages.forEach(msg => {
const div = document.createElement('div');
div.className = msg.sender === 'sophie' ? 'flex justify-start' : 'flex justify-end';
const bubble = document.createElement('div');
bubble.className = msg.sender === 'sophie'
? 'chat-bubble-sophie text-gray-700 text-[15px]'
: 'chat-bubble-user text-[15px]';
bubble.textContent = msg.text;
div.appendChild(bubble);
container.appendChild(div);
});
container.scrollTop = 0;
}
// Render signals
const signalsLabel = document.getElementById('chat-demo-signals-label');
if (signalsLabel) signalsLabel.textContent = demo.signals_label || '';
const signalsContainer = document.getElementById('chat-demo-signals');
if (signalsContainer && demo.signals) {
const colors = ['bg-green-100 text-green-700', 'bg-blue-100 text-blue-700', 'bg-amber-100 text-amber-700', 'bg-purple-100 text-purple-700', 'bg-rose-100 text-rose-700'];
const icons = ['✓', '★', '⚡', '●', '◆'];
signalsContainer.innerHTML = demo.signals.map((signal, i) => `
${icons[i % icons.length]}
${esc(signal)}
`).join('');
}
const signalCount = document.getElementById('chat-demo-signal-count');
if (signalCount && demo.signals) {
signalCount.textContent = `${demo.signals.length} signals`;
}
}
// Initial render
renderDemo(0);
// Tab click handlers
document.querySelectorAll('.demo-tab').forEach(tab => {
tab.addEventListener('click', () => renderDemo(parseInt(tab.dataset.demoIndex)));
});
}
// --- Intelligence Routing ---
const routePaths = document.querySelectorAll('[data-content="route-path"]');
routePaths.forEach((el, i) => {
if (data.intelligence_routing[i]) {
setText('[data-content="route-title"]', data.intelligence_routing[i].title, el);
setText('[data-content="route-description"]', data.intelligence_routing[i].description, el);
setText('[data-content="route-emoji"]', data.intelligence_routing[i].emoji, el);
}
});
// --- Math of Scale ---
setText('[data-content="math-headline"]', data.math_of_scale.headline);
setText('[data-content="math-tagline"]', data.math_of_scale.tagline);
setText('[data-content="human-stat"]', data.math_of_scale.human.stat);
setText('[data-content="human-unit"]', data.math_of_scale.human.unit);
setText('[data-content="sophie-stat"]', data.math_of_scale.sophie.stat);
setText('[data-content="sophie-unit"]', data.math_of_scale.sophie.unit);
// --- FAQ (dynamic generation with accordion) ---
const faqContainer = document.getElementById('faq-container');
if (faqContainer && data.faq) {
faqContainer.innerHTML = data.faq.map((item, i) => `
`).join('');
// Attach accordion behavior
faqContainer.querySelectorAll('.faq-button').forEach(button => {
button.addEventListener('click', function() {
const target = this.getAttribute('data-target');
const content = document.getElementById(target);
const toggleIcon = this.querySelector('.toggle-icon');
faqContainer.querySelectorAll('.faq-content').forEach(item => {
if (item.id !== target) {
item.classList.add('hidden');
item.previousElementSibling.querySelector('.toggle-icon').textContent = '+';
}
});
content.classList.toggle('hidden');
toggleIcon.textContent = content.classList.contains('hidden') ? '+' : '−';
});
});
}
// --- Integrations ---
setText('[data-content="integrations-headline"]', data.integrations.headline);
setText('[data-content="integrations-subheading"]', data.integrations.subheading);
setText('[data-content="integrations-description"]', data.integrations.description);
// --- CTA ---
document.querySelectorAll('[data-content="cta-primary"]').forEach(btn => {
btn.textContent = data.cta.primary_text;
});
setText('[data-content="footer-headline"]', data.cta.footer_headline);
// --- Testimonials ---
const cards = document.querySelectorAll('[data-content="testimonial-card"]');
cards.forEach((el, i) => {
const idx = i % data.testimonials.length;
const t = data.testimonials[idx];
setText('[data-content="testimonial-quote"]', t.quote, el);
setText('[data-content="testimonial-rating"]', '⭐ ' + t.rating, el);
const img = el.querySelector('[data-content="testimonial-image"]');
if (img) img.src = t.image;
});
// --- Helpers ---
function setText(selector, text, parent) {
const el = (parent || document).querySelector(selector);
if (el) el.textContent = text;
}
function esc(str) {
const d = document.createElement('div');
d.textContent = str;
return d.innerHTML;
}
})();