โš™๏ธ Demo Builder Settings

1 ยท Project
โš ๏ธ NO PHI: Do not enter resident names, medical conditions, medications, or any protected health information. General script content only.
2 ยท Scenes
3 ยท Generate
4 ยท Share / Embed
Click "Generate Embed Code" to create a shareable embed.

Title22 Product Video

Voiceover by thelo.fyi ยท Daniel voice ยท 9 scenes ยท NO PHI

1 / 9
โ€”
No scenes yet
โ€”
'; } function copyEmbed() { navigator.clipboard.writeText(document.getElementById("embedBox").textContent).then(() => { const btn = event.target; btn.textContent = "โœ… Copied"; setTimeout(() => btn.textContent = "๐Ÿ“‹ Copy Embed Code", 2000); }); } let aiSceneCache = []; let aiThinking = false; function toggleAIPanel() { document.getElementById("aiPanel").classList.toggle("collapsed"); } function addAIMessage(text, isUser, isScenes, sceneData) { const container = document.getElementById("aiMessages"); const msg = document.createElement("div"); msg.className = "ai-msg " + (isUser ? "user" : "bot") + (isScenes ? " scenes" : ""); if (isScenes && sceneData) { let html = '
๐Ÿ“‹ Generated Scenes:
'; sceneData.scenes.forEach(function(s, i) { html += '
Scene ' + (i+1) + ': ' + s.title + '
' + s.script + '
Caption: ' + s.caption + '
'; }); if (sceneData.voiceSuggestion) html += '
๐ŸŽ™๏ธ Suggested voice: ' + sceneData.voiceSuggestion + '
'; html += ''; msg.innerHTML = html; } else { msg.textContent = text; } container.appendChild(msg); container.scrollTop = container.scrollHeight; } async function sendAIMessage(text) { if (!text || !text.trim() || aiThinking) return; addAIMessage(text, true); document.getElementById("aiInput").value = ""; aiThinking = true; document.getElementById("aiSend").disabled = true; const typing = document.createElement("div"); typing.className = "ai-typing"; typing.id = "aiTyping"; typing.innerHTML = ""; document.getElementById("aiMessages").appendChild(typing); document.getElementById("aiMessages").scrollTop = document.getElementById("aiMessages").scrollHeight; try { const context = scenes.length > 0 ? "Current project: " + document.getElementById("projectName").value + ". Current scenes: " + JSON.stringify(scenes.map(s => ({title: s.title, script: s.script, caption: s.caption}))) : "No scenes yet."; const response = await fetch("/api/assist", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ message: text, context: context }) }); if (!response.ok) { const err = await response.json().catch(() => ({ error: "Failed" })); throw new Error(err.error || err.detail || "AI request failed"); } const data = await response.json(); document.getElementById("aiTyping")?.remove(); let parsed = null; try { const match = data.response.match(/\{[\s\S]*\}/); if (match) { parsed = JSON.parse(match[0]); if (parsed.scenes && Array.isArray(parsed.scenes)) { parsed._index = aiSceneCache.length; aiSceneCache.push(parsed); addAIMessage("", false, true, parsed); aiThinking = false; document.getElementById("aiSend").disabled = false; return; } } } catch (e) {} addAIMessage(data.response, false); } catch (err) { document.getElementById("aiTyping")?.remove(); addAIMessage("โš ๏ธ " + (err.message || "AI assistant error"), false); } finally { aiThinking = false; document.getElementById("aiSend").disabled = false; } } function applyAIScenes(cacheIndex) { const data = aiSceneCache[cacheIndex]; if (!data || !data.scenes) return; scenes = []; audioUrls = {}; generating = {}; sceneCounter = 0; data.scenes.forEach(function(s) { sceneCounter++; scenes.push({ id: sceneCounter, title: s.title || ("Scene " + sceneCounter), script: s.script || "", caption: s.caption || "", visualType: "broll" }); }); if (data.voiceSuggestion) { const voiceMap = { Daniel: "onwK4e9ZLuTAKqWW03F9", Rachel: "21m00Tcm4TlvDq8ikWAM", Bella: "EXAVITQu4vr4xnSDxMaL", Antoni: "ErXwobaYiN019PkySvjV", Josh: "TxGEqnHWrfWFTfGW9XjX", Arnold: "VR6AewLTigWG4xSOAaLJ", Adam: "pNInz6obpgDQGcFmaJgB" }; const voiceId = voiceMap[data.voiceSuggestion]; if (voiceId) document.getElementById("voiceSelect").value = voiceId; } renderSceneList(); renderSceneNav(); renderVisual(); updateMainInfo(); addAIMessage("โœ… Applied " + data.scenes.length + " scenes! Click 'Generate All Voiceover' to create the audio.", false); } document.getElementById("aiSend").onclick = function() { sendAIMessage(document.getElementById("aiInput").value); }; document.getElementById("aiInput").addEventListener("keydown", function(e) { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); sendAIMessage(this.value); } }); document.querySelectorAll(".ai-suggestion-chip").forEach(function(chip) { chip.onclick = function() { sendAIMessage(this.textContent); }; }); // โ”€โ”€ Init: Pre-load all 9 Title22 storyboard scenes โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ const TITLE22_SCENES = [ { title: "The Compliance Problem", script: "Every Residential Care Facility in California must meet Title 22 training requirements. But tracking who completed what, when, and whether it's still valid โ€” that's a full-time job on its own.", caption: "Every RCFE in California must meet Title 22 training requirements.", visualType: "broll" }, { title: "The Cost of Chaos", script: "Expired certifications. Missed deadlines. Lost paperwork. And when the inspector arrives, there's nothing to show but a pile of binders and a sinking feeling.", caption: "Expired certifications, missed deadlines, lost paperwork.", visualType: "broll" }, { title: "Explore with Sandbox Data", script: "One click. That's all it takes. Explore with Sandbox Data boots you into a fully populated compliance dashboard โ€” no setup, no spreadsheets, no stress.", caption: "One click โ€” Explore with Sandbox Data.", visualType: "transition" }, { title: "Inspection Readiness Score", script: "Your Inspection Readiness Score updates in real time. Watch it climb from sixty-seven percent to ninety-four as your team completes modules. Every point earned, every gap closed โ€” visible instantly.", caption: "Inspection Readiness Score climbs in real time.", visualType: "software" }, { title: "Staff Certification Alerts", script: "Countdown alerts for every certification that matters. TB test expiring in twelve days. CPR expiring in three. LiveScan in forty-five. Color-coded. Impossible to miss. Impossible to forget.", caption: "Countdown alerts for TB, CPR, and LiveScan certifications.", visualType: "software" }, { title: "Immutable Ledger", script: "Every action โ€” every training completed, every certificate earned โ€” is written to an immutable ledger. Timestamped. Hashed. Tamper-proof. When the inspector asks for proof, you hand them a link.", caption: "Immutable ledger โ€” every action timestamped and hashed.", visualType: "software" }, { title: "Simulate a DSS Inspection", script: "Type one prompt: Simulate a DSS inspection. Tello AI scans your entire facility profile and returns a sharp, bulleted compliance gap summary in seconds.", caption: "Type: Simulate a DSS inspection โ€” Tello AI returns a gap summary.", visualType: "ai" }, { title: "Compliance Gap Summary", script: "Two staff members have expired CPR. One TB test expires in three days. LiveScan renewal overdue for one staff member. But dementia care training โ€” one hundred percent complete. Medication management โ€” one hundred percent. Residents' rights โ€” one hundred percent. Risk level: moderate. Three recommended actions, ready to assign.", caption: "AI identifies every gap โ€” and what's already done right.", visualType: "ai" }, { title: "Run a Facility DSS Is Proud to Inspect", script: "Run a facility DSS is proud to inspect. Launch your risk-free sandbox pilot today at Title22.app.", caption: "Run a facility DSS is proud to inspect. Launch your risk-free sandbox pilot today at Title22.app.", visualType: "closing" }, ]; TITLE22_SCENES.forEach(function(s) { sceneCounter++; scenes.push({ id: sceneCounter, title: s.title, script: s.script, caption: s.caption, visualType: s.visualType }); }); renderSceneList(); renderSceneNav(); updateMainInfo(); document.getElementById("sceneTitle").textContent = scenes[0].title; document.getElementById("sceneTitleOverlay").textContent = scenes[0].title; document.getElementById("captionOverlay").textContent = scenes[0].caption;