Decode kitty language and uncover your kitty's hidden desires and needs.
Available 24/7
Story Page Builder v4 Final

Story Page Builder v6 FINAL

Workflow v6: najprv vytvor osnovu celej stránky a rozmiestni custom médiá podľa ich textových popisov. Až potom sa každý headline, subheadline, body, tabuľka, quote, transition a ďalší element generuje vlastným phase/section/element promptom.
`; downloadText("storytelling-sales-page.html",clean,"text/html"); }function downloadText(name,text,type){ const blob=new Blob([text],{type}); const a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=name; document.body.appendChild(a); a.click(); setTimeout(()=>{URL.revokeObjectURL(a.href);a.remove()},100); }function renderMediaLibrary(){ const root=$("mediaList"); if(!root) return; root.innerHTML=""; if(!state.mediaAssets.length){ root.innerHTML=`
Zatiaľ bez custom assetov.
`; return; } for(const asset of state.mediaAssets){ const item=document.createElement("div"); item.className="media-item"; const preview=asset.type.startsWith("video/") ? `` : ``; const options=[''] .concat(SECTION_SCHEMA.flatMap(p=>p.sections.map(s=>``))) .join(""); item.innerHTML=` ${preview}
${escapeHtml(asset.name)}
${escapeHtml(asset.type)}
Do AI requestu pôjde iba tento textový popis + ID/názov/typ. Base64 obsah obrázka/videa sa neposiela.
`; root.appendChild(item); } root.querySelectorAll("[data-media-desc]").forEach(n=>n.addEventListener("input",()=>{ const a=mediaAssetById(n.dataset.mediaDesc); if(a) a.description=n.value; })); root.querySelectorAll("[data-media-section]").forEach(n=>n.addEventListener("change",()=>{ const a=mediaAssetById(n.dataset.mediaSection); if(a) a.preferredSection=n.value; })); root.querySelectorAll("[data-media-reuse]").forEach(n=>n.addEventListener("change",()=>{ const a=mediaAssetById(n.dataset.mediaReuse); if(a) a.allowReuse=n.checked; })); root.querySelectorAll("[data-media-delete]").forEach(n=>n.addEventListener("click",()=>{ state.mediaAssets=state.mediaAssets.filter(a=>a.id!==n.dataset.mediaDelete); renderMediaLibrary(); })); }function fileToDataUrl(file){ return new Promise((resolve,reject)=>{ const r=new FileReader(); r.onload=()=>resolve(String(r.result||"")); r.onerror=()=>reject(r.error||new Error("FileReader zlyhal")); r.readAsDataURL(file); }); }async function addMediaFiles(files){ for(const file of files){ const dataUrl=await fileToDataUrl(file); state.mediaAssets.push({ id:`media_${Date.now()}_${Math.random().toString(36).slice(2,8)}`, name:file.name, type:file.type||"application/octet-stream", size:file.size||0, description:"", preferredSection:"auto", allowReuse:false, dataUrl }); } renderMediaLibrary(); }function saveProject(){ const project={ schema_version:"1.0", saved_at:new Date().toISOString(), settings:{ model:$("model").value, publicationName:$("publicationName").value, pageLanguage:$("pageLanguage").value, ctaUrl:$("ctaUrl").value, imageModel:$("imageModel").value, autoGenerateImages:$("autoGenerateImages").checked, globalInstruction:$("globalInstruction").value }, contexts:{ product:$("productContext").value, persona:$("personaContext").value, angle:$("angleContext").value, story:$("storyContext").value }, page_state:state.sections, histories:state.histories, prompt_logs:state.promptLogs, media_assets:state.mediaAssets, section_plans:state.sectionPlans, outline_meta:state.outlineMeta }; downloadText("story-page-project.json",JSON.stringify(project,null,2),"application/json"); }function loadDetectedObject(obj){ const s=obj||{}; if(s.settings){ if(s.settings.model) $("model").value=s.settings.model; if(s.settings.publicationName) $("publicationName").value=s.settings.publicationName; if(s.settings.pageLanguage) $("pageLanguage").value=s.settings.pageLanguage; if(s.settings.ctaUrl) $("ctaUrl").value=s.settings.ctaUrl; if(s.settings.imageModel) $("imageModel").value=s.settings.imageModel; if(s.settings.autoGenerateImages!==undefined) $("autoGenerateImages").checked=!!s.settings.autoGenerateImages; if(s.settings.globalInstruction!==undefined) $("globalInstruction").value=s.settings.globalInstruction; } if(s.contexts){ if(s.contexts.product!==undefined) $("productContext").value=typeof s.contexts.product==="string"?s.contexts.product:JSON.stringify(s.contexts.product,null,2); if(s.contexts.persona!==undefined) $("personaContext").value=typeof s.contexts.persona==="string"?s.contexts.persona:JSON.stringify(s.contexts.persona,null,2); if(s.contexts.angle!==undefined) $("angleContext").value=typeof s.contexts.angle==="string"?s.contexts.angle:JSON.stringify(s.contexts.angle,null,2); if(s.contexts.story!==undefined) $("storyContext").value=typeof s.contexts.story==="string"?s.contexts.story:JSON.stringify(s.contexts.story,null,2); }// auto-detect common combined keys const product=s.PRODUCT_CONTEXT||s.product_context||s.productContext; const persona=s.PERSONA_CONTEXT||s.persona_context||s.personaContext; const angle=s.ANGLE_CONTEXT||s.angle_context||s.angleContext; const story=s.STORY_CONTEXT||s.story_context||s.storyContext;if(product) $("productContext").value=JSON.stringify(product,null,2); if(persona) $("personaContext").value=JSON.stringify(persona,null,2); if(angle) $("angleContext").value=JSON.stringify(angle,null,2); if(story) $("storyContext").value=JSON.stringify(story,null,2);// If the uploaded JSON itself looks like a Story Context if(!story && s.story_id && (s.present_day_hook||s.story_strategy||s.first_person_story)){ $("storyContext").value=JSON.stringify(s,null,2); } // If itself looks like Persona if(!persona && s.persona && s.problem && s.funnel_variables){ $("personaContext").value=JSON.stringify(s,null,2); } // If itself looks like Angle if(!angle && s.angle_name && s.angle_type){ $("angleContext").value=JSON.stringify(s,null,2); }if(s.page_state) state.sections=clone(s.page_state); if(s.histories) state.histories=clone(s.histories); if(s.prompt_logs) state.promptLogs=clone(s.prompt_logs); if(s.media_assets) state.mediaAssets=clone(s.media_assets); if(s.section_plans) state.sectionPlans=clone(s.section_plans); if(s.outline_meta) state.outlineMeta=clone(s.outline_meta); normalizeOutlineAssetAssignments(); applyOutlineMediaAssignments(); buildBuilder(); renderMediaLibrary(); updateOutlineStatus(); }$("mediaFiles").addEventListener("change",async ev=>{ const files=Array.from(ev.target.files||[]); if(!files.length) return; try{ await addMediaFiles(files); ev.target.value=""; setStatus($("globalStatus"),`${files.length} médií pridaných.`,"ok"); }catch(err){ setStatus($("globalStatus"),`Media upload: ${err.message}`,"err"); } });$("contextFile").addEventListener("change",async ev=>{ const file=ev.target.files?.[0]; if(!file) return; try{ const txt=await file.text(); const obj=JSON.parse(txt); loadDetectedObject(obj); setStatus($("contextStatus"),"Súbor načítaný.","ok"); }catch(err){ setStatus($("contextStatus"),`Súbor: ${err.message}`,"err"); } });$("detectContext").addEventListener("click",()=>{ try{ const candidates=[$("storyContext").value,$("personaContext").value,$("angleContext").value,$("productContext").value].filter(v=>v.trim()); if(!candidates.length) throw new Error("Nie je čo detegovať."); for(const raw of candidates){ try{loadDetectedObject(JSON.parse(raw));}catch{} } setStatus($("contextStatus"),"Auto-detect dokončený.","ok"); }catch(err){setStatus($("contextStatus"),err.message,"err")} });$("validateContext").addEventListener("click",()=>{ try{ const c=getContexts(); if(!c.story) throw new Error("STORY_CONTEXT je povinný."); setStatus($("contextStatus"),"Context je validný. STORY_CONTEXT nájdený.","ok"); }catch(err){setStatus($("contextStatus"),err.message,"err")} });$("clearContext").addEventListener("click",()=>{ ["productContext","personaContext","angleContext","storyContext"].forEach(id=>$(id).value=""); setStatus($("contextStatus"),""); });$("resetPage").addEventListener("click",()=>{ if(!confirm("Vymazať vygenerovanú page state? Context ostane.")) return; state.sections={};state.histories={}; buildBuilder(); setStatus($("globalStatus"),"Page resetnutá.","ok"); });$("generateOutline").addEventListener("click",generateOutline); $("generateOutlineSide").addEventListener("click",generateOutline); $("clearOutline").addEventListener("click",()=>{ state.sectionPlans={}; state.outlineMeta=null; for(const section of SECTION_SCHEMA.flatMap(p=>p.sections)){ if(state.sections[section.id] && String(state.sections[section.id].image_url||"").startsWith("asset:")){ state.sections[section.id].image_url=""; } } updateOutlineStatus(); buildBuilder(); setStatus($("globalStatus"),"Osnova vymazaná."); }); $("generateAll").addEventListener("click",generateAll); $("generateAllImages").addEventListener("click",generateAllImages); $("previewBtn").addEventListener("click",()=>switchTab("preview")); $("exportBtn").addEventListener("click",exportHtml); $("saveProjectBtn").addEventListener("click",saveProject); document.querySelectorAll(".tab").forEach(btn=>btn.addEventListener("click",()=>switchTab(btn.dataset.tab)));buildBuilder();